aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/postgresql/oid/range.rb
Commit message (Collapse)AuthorAgeFilesLines
* Make force equality checking more strictly not to allow serialized attributeRyuta Kamizono2018-05-251-0/+4
| | | | | | | | | | | Since #26074, introduced force equality checking to build a predicate consistently for both `find` and `create` (fixes #27313). But the assumption that only array/range attribute have subtype was wrong. We need to make force equality checking more strictly not to allow serialized attribute. Fixes #32761.
* Correctly handle infinity value in PostgreSQL range typeyuuji.yaginuma2018-01-041-1/+1
| | | | | | | | An empty string is an invalid value in Ruby's range class. So need to handle `Float::INFINITY` as it is and cast it in `encode_range`. Fixes #31612
* `Postgres::OID::Range` serializes to a `Range`, quote in `Quoting`Thomas Cannon2017-09-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PostgreSQL 9.1+ introduced range types, and Rails added support for using this datatype in ActiveRecord. However, the serialization of `PostgreSQL::OID::Range` was incomplete, because it did not properly quote the bounds that make up the range. A clear example of this is a `tsrange`. Normally, ActiveRecord quotes Date/Time objects to include the milliseconds. However, the way `PostgreSQL::OID::Range` serialized its bounds, the milliseconds were dropped. This meant that the value was incomplete and not equal to the submitted value. An example of normal timestamps vs. a `tsrange`. Note how the bounds for the range do not include their milliseconds (they were present in the ruby Range): UPDATE "iterations" SET "updated_at" = $1, "range" = $2 WHERE "iterations"."id" = $3 [["updated_at", "2017-09-23 17:07:01.304864"], ["range", "[2017-09-23 00:00:00 UTC,2017-09-23 23:59:59 UTC]"], ["id", 1234]] `PostgreSQL::OID::Range` serialized the range by interpolating a string for the range, which works for most cases, but does not work for timestamps: def serialize(value) if value.is_a?(::Range) from = type_cast_single_for_database(value.begin) to = type_cast_single_for_database(value.end) "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" else super end end (byebug) from = type_cast_single_for_database(value.begin) 2010-01-01 13:30:00 UTC (byebug) to = type_cast_single_for_database(value.end) 2011-02-02 19:30:00 UTC (byebug) "[#{from},#{to}#{value.exclude_end? ? ')' : ']'}" "[2010-01-01 13:30:00 UTC,2011-02-02 19:30:00 UTC)" @sgrif (the original implementer for Postgres Range support) provided some feedback about where the quoting should occur: Yeah, quoting at all is definitely wrong here. I'm not sure what I was thinking in 02579b5, but what this is doing is definitely in the wrong place. It should probably just be returning a range of subtype.serialize(value.begin) and subtype.serialize(value.end), and letting the adapter handle the rest. `Postgres::OID::Range` now returns a `Range` object, and `ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting` can now encode and quote a `Range`: def encode_range(range) "[#{type_cast(range.first)},#{type_cast(range.last)}#{range.exclude_end? ? ')' : ']'}" end ... encode_range(range) #=> "['2010-01-01 13:30:00.670277','2011-02-02 19:30:00.745125')" This commit includes tests to make sure the milliseconds are preserved in `tsrange` and `tstzrange` columns
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* Remove unneeded requires at active recordRafael Mendonça França2017-01-031-2/+0
|
* normalizes indentation and whitespace across the projectXavier Noria2016-08-061-26/+26
|
* applies new string literal convention in activerecord/libXavier Noria2016-08-061-9/+9
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Refactor tz aware types, add support for PG rangesSean Griffin2016-01-081-1/+8
| | | | | | | | | | | | | | | | | This is an alternate implementation to #22875, that generalizes a lot of the logic that type decorators are going to need, in order to have them work with arrays, ranges, etc. The types have the ability to map over a value, with the default implementation being to just yield that given value. Array and Range give more appropriate definitions. This does not automatically make ranges time zone aware, as they need to be added to the `time_zone_aware` types config, but we could certainly make that change if we feel it is appropriate. I do think this would be a breaking change however, and should at least have a deprecation cycle. Closes #22875. /cc @matthewd
* `type_cast_for_database` -> `serialize`Sean Griffin2015-02-171-2/+2
|
* `Type#type_cast_from_database` -> `Type#deserialize`Sean Griffin2015-02-171-1/+1
|
* Remove most PG specific type subclassesSean Griffin2015-02-111-2/+12
| | | | | | | | | The latest version of the PG gem can actually convert the primitives for us in C code, which gives a pretty substantial speed up. A few cases were only there to add the `infinity` method, which I just put on the range type (which is the only place it was used). Floats also needed to parse `Infinity` and `NaN`, but it felt reasonable enough to put that on the generic form.
* Allow a symbol to be passed to `attribute`, in place of a type objectSean Griffin2015-02-061-1/+7
| | | | | | | | | | | | | | | | | | The same is not true of `define_attribute`, which is meant to be the low level no-magic API that sits underneath. The differences between the two APIs are: - `attribute` - Lazy (the attribute will be defined after the schema has loaded) - Allows either a type object or a symbol - `define_attribute` - Runs immediately (might get trampled by schema loading) - Requires a type object This was the last blocker in terms of public interface requirements originally discussed for this feature back in May. All the implementation blockers have been cleared, so this feature is probably ready for release (pending one more look-over by me).
* remove deprecated support for PG ranges with exclusive lower bounds.Yves Senn2015-01-051-10/+1
| | | | addresses https://github.com/rails/rails/commit/91949e48cf41af9f3e4ffba3e5eecf9b0a08bfc3#commitcomment-9144563
* let's warn with heredocsXavier Noria2014-10-281-4/+7
| | | | | | | | | | | | The current style for warning messages without newlines uses concatenation of string literals with manual trailing spaces where needed. Heredocs have better readability, and with `squish` we can still produce a single line. This is a similar use case to the one that motivated defining `strip_heredoc`, heredocs are super clean.
* Avoid using heredoc for user warningsGodfrey Chan2014-08-281-4/+4
| | | | | | | | | | Using heredoc would enforce line wrapping to whatever column width we decided to use in the code, making it difficult for the users to read on some consoles. This does make the source code read slightly worse and a bit more error-prone, but this seems like a fair price to pay since the primary purpose for these messages are for the users to read and the code will not stick around for too long.
* Use the type object for quoting PG RangesSean Griffin2014-07-051-18/+34
|
* add missing `:nodoc:` for recent refactorings. [ci skip]Yves Senn2014-06-241-1/+1
| | | | | | | | | | Adding `# :nodoc:` to the parent `class` / `module` is not going to ignore nested classes or modules. There is a modifier `# :nodoc: all` but sadly the containing class or module will continue to be in the docs. /cc @sgrif
* Rename `type_cast` to `type_cast_from_database`Sean Griffin2014-06-091-1/+1
| | | | | | | | In some cases there is a difference between the two, we should always be doing one or the other. For convenience, `type_cast` is still a private method on type, so new types that do not need different behavior don't need to implement two methods, but it has been moved to private so it cannot be used accidentally.
* refactor, introduce `Type#type_cast_for_schema` to cast for schema.rbYves Senn2014-05-301-0/+4
| | | | | | | This removes the case statement in `SchemaDumper` and gives every `Type` the possibility to control the SchemaDumper default value output. /cc @sgrif
* Move PG OID types to their own filesSean Griffin2014-05-211-0/+56
As we promote these classes to first class concepts, these classes are starting to gain enough behavior to warrant being moved into their own files. Many of them will become quite large as we move additional behavior to the type objects.