sequel 4.46.0 → 4.49.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +210 -0
  3. data/Rakefile +1 -1
  4. data/doc/advanced_associations.rdoc +1 -1
  5. data/doc/opening_databases.rdoc +3 -2
  6. data/doc/release_notes/4.47.0.txt +56 -0
  7. data/doc/release_notes/4.48.0.txt +293 -0
  8. data/doc/release_notes/4.49.0.txt +222 -0
  9. data/lib/sequel/adapters/ado/access.rb +2 -1
  10. data/lib/sequel/adapters/do/postgres.rb +5 -2
  11. data/lib/sequel/adapters/ibmdb.rb +30 -8
  12. data/lib/sequel/adapters/jdbc/as400.rb +1 -1
  13. data/lib/sequel/adapters/jdbc/db2.rb +12 -3
  14. data/lib/sequel/adapters/jdbc/derby.rb +4 -5
  15. data/lib/sequel/adapters/jdbc/h2.rb +10 -1
  16. data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
  17. data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
  18. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
  19. data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
  20. data/lib/sequel/adapters/jdbc.rb +39 -23
  21. data/lib/sequel/adapters/mock.rb +27 -19
  22. data/lib/sequel/adapters/mysql.rb +17 -16
  23. data/lib/sequel/adapters/mysql2.rb +5 -6
  24. data/lib/sequel/adapters/oracle.rb +5 -9
  25. data/lib/sequel/adapters/postgres.rb +91 -103
  26. data/lib/sequel/adapters/shared/db2.rb +22 -6
  27. data/lib/sequel/adapters/shared/mssql.rb +5 -4
  28. data/lib/sequel/adapters/shared/mysql.rb +79 -25
  29. data/lib/sequel/adapters/shared/oracle.rb +26 -3
  30. data/lib/sequel/adapters/shared/postgres.rb +199 -95
  31. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  32. data/lib/sequel/adapters/shared/sqlite.rb +72 -82
  33. data/lib/sequel/adapters/sqlanywhere.rb +4 -1
  34. data/lib/sequel/adapters/sqlite.rb +5 -3
  35. data/lib/sequel/adapters/swift/postgres.rb +5 -2
  36. data/lib/sequel/adapters/tinytds.rb +0 -5
  37. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  38. data/lib/sequel/adapters/utils/pg_types.rb +2 -76
  39. data/lib/sequel/ast_transformer.rb +1 -1
  40. data/lib/sequel/connection_pool/sharded_single.rb +1 -1
  41. data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
  42. data/lib/sequel/connection_pool/single.rb +2 -2
  43. data/lib/sequel/connection_pool/threaded.rb +2 -2
  44. data/lib/sequel/connection_pool.rb +9 -2
  45. data/lib/sequel/core.rb +2 -2
  46. data/lib/sequel/database/connecting.rb +8 -8
  47. data/lib/sequel/database/dataset.rb +6 -3
  48. data/lib/sequel/database/dataset_defaults.rb +14 -1
  49. data/lib/sequel/database/misc.rb +1 -1
  50. data/lib/sequel/database/query.rb +3 -0
  51. data/lib/sequel/database/schema_methods.rb +1 -1
  52. data/lib/sequel/dataset/actions.rb +72 -10
  53. data/lib/sequel/dataset/dataset_module.rb +58 -0
  54. data/lib/sequel/dataset/graph.rb +1 -1
  55. data/lib/sequel/dataset/misc.rb +1 -0
  56. data/lib/sequel/dataset/prepared_statements.rb +3 -3
  57. data/lib/sequel/dataset/query.rb +22 -11
  58. data/lib/sequel/dataset.rb +1 -1
  59. data/lib/sequel/exceptions.rb +8 -0
  60. data/lib/sequel/extensions/_model_pg_row.rb +5 -2
  61. data/lib/sequel/extensions/core_extensions.rb +4 -1
  62. data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
  63. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  64. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
  65. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
  66. data/lib/sequel/extensions/filter_having.rb +2 -0
  67. data/lib/sequel/extensions/freeze_datasets.rb +2 -0
  68. data/lib/sequel/extensions/from_block.rb +1 -1
  69. data/lib/sequel/extensions/graph_each.rb +2 -2
  70. data/lib/sequel/extensions/hash_aliases.rb +2 -0
  71. data/lib/sequel/extensions/identifier_mangling.rb +0 -7
  72. data/lib/sequel/extensions/meta_def.rb +2 -0
  73. data/lib/sequel/extensions/migration.rb +11 -8
  74. data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
  75. data/lib/sequel/extensions/null_dataset.rb +1 -0
  76. data/lib/sequel/extensions/pagination.rb +1 -1
  77. data/lib/sequel/extensions/pg_array.rb +207 -130
  78. data/lib/sequel/extensions/pg_hstore.rb +38 -20
  79. data/lib/sequel/extensions/pg_inet.rb +18 -6
  80. data/lib/sequel/extensions/pg_interval.rb +19 -12
  81. data/lib/sequel/extensions/pg_json.rb +25 -14
  82. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  83. data/lib/sequel/extensions/pg_range.rb +133 -100
  84. data/lib/sequel/extensions/pg_range_ops.rb +4 -3
  85. data/lib/sequel/extensions/pg_row.rb +68 -39
  86. data/lib/sequel/extensions/pg_row_ops.rb +11 -5
  87. data/lib/sequel/extensions/query_literals.rb +2 -0
  88. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
  89. data/lib/sequel/extensions/s.rb +1 -1
  90. data/lib/sequel/extensions/schema_dumper.rb +29 -25
  91. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
  92. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
  93. data/lib/sequel/extensions/server_block.rb +32 -15
  94. data/lib/sequel/extensions/set_overrides.rb +2 -2
  95. data/lib/sequel/extensions/string_agg.rb +0 -1
  96. data/lib/sequel/extensions/symbol_aref.rb +0 -4
  97. data/lib/sequel/model/associations.rb +35 -7
  98. data/lib/sequel/model/base.rb +113 -87
  99. data/lib/sequel/model/dataset_module.rb +5 -43
  100. data/lib/sequel/model/errors.rb +2 -1
  101. data/lib/sequel/model/inflections.rb +17 -5
  102. data/lib/sequel/model.rb +26 -58
  103. data/lib/sequel/plugins/active_model.rb +2 -2
  104. data/lib/sequel/plugins/association_autoreloading.rb +2 -0
  105. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  106. data/lib/sequel/plugins/association_pks.rb +73 -46
  107. data/lib/sequel/plugins/association_proxies.rb +1 -1
  108. data/lib/sequel/plugins/auto_validations.rb +6 -2
  109. data/lib/sequel/plugins/boolean_readers.rb +2 -2
  110. data/lib/sequel/plugins/boolean_subsets.rb +1 -1
  111. data/lib/sequel/plugins/caching.rb +19 -13
  112. data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
  113. data/lib/sequel/plugins/column_conflicts.rb +7 -2
  114. data/lib/sequel/plugins/column_select.rb +3 -3
  115. data/lib/sequel/plugins/composition.rb +2 -2
  116. data/lib/sequel/plugins/csv_serializer.rb +8 -8
  117. data/lib/sequel/plugins/dataset_associations.rb +25 -13
  118. data/lib/sequel/plugins/defaults_setter.rb +13 -1
  119. data/lib/sequel/plugins/eager_each.rb +1 -1
  120. data/lib/sequel/plugins/force_encoding.rb +2 -2
  121. data/lib/sequel/plugins/hook_class_methods.rb +9 -12
  122. data/lib/sequel/plugins/identifier_columns.rb +2 -0
  123. data/lib/sequel/plugins/instance_filters.rb +3 -1
  124. data/lib/sequel/plugins/instance_hooks.rb +17 -9
  125. data/lib/sequel/plugins/json_serializer.rb +19 -12
  126. data/lib/sequel/plugins/lazy_attributes.rb +8 -7
  127. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
  128. data/lib/sequel/plugins/modification_detection.rb +3 -0
  129. data/lib/sequel/plugins/nested_attributes.rb +6 -2
  130. data/lib/sequel/plugins/pg_array_associations.rb +5 -0
  131. data/lib/sequel/plugins/pg_row.rb +4 -2
  132. data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
  133. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  134. data/lib/sequel/plugins/rcte_tree.rb +4 -24
  135. data/lib/sequel/plugins/serialization.rb +9 -15
  136. data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
  137. data/lib/sequel/plugins/split_values.rb +6 -5
  138. data/lib/sequel/plugins/static_cache.rb +31 -25
  139. data/lib/sequel/plugins/subset_conditions.rb +3 -1
  140. data/lib/sequel/plugins/table_select.rb +1 -1
  141. data/lib/sequel/plugins/touch.rb +4 -2
  142. data/lib/sequel/plugins/validation_class_methods.rb +5 -6
  143. data/lib/sequel/plugins/validation_helpers.rb +14 -8
  144. data/lib/sequel/plugins/xml_serializer.rb +4 -4
  145. data/lib/sequel/sql.rb +18 -9
  146. data/lib/sequel/version.rb +1 -1
  147. data/spec/adapters/db2_spec.rb +115 -14
  148. data/spec/adapters/mssql_spec.rb +4 -4
  149. data/spec/adapters/mysql_spec.rb +83 -29
  150. data/spec/adapters/oracle_spec.rb +28 -24
  151. data/spec/adapters/postgres_spec.rb +40 -24
  152. data/spec/adapters/sqlanywhere_spec.rb +88 -86
  153. data/spec/adapters/sqlite_spec.rb +29 -24
  154. data/spec/bin_spec.rb +7 -1
  155. data/spec/core/connection_pool_spec.rb +45 -14
  156. data/spec/core/database_spec.rb +155 -0
  157. data/spec/core/dataset_spec.rb +219 -36
  158. data/spec/core/schema_spec.rb +16 -0
  159. data/spec/core/spec_helper.rb +1 -0
  160. data/spec/core_extensions_spec.rb +6 -2
  161. data/spec/extensions/active_model_spec.rb +1 -1
  162. data/spec/extensions/arbitrary_servers_spec.rb +1 -1
  163. data/spec/extensions/association_pks_spec.rb +34 -2
  164. data/spec/extensions/auto_literal_strings_spec.rb +5 -1
  165. data/spec/extensions/auto_validations_spec.rb +2 -0
  166. data/spec/extensions/boolean_readers_spec.rb +1 -1
  167. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  168. data/spec/extensions/class_table_inheritance_spec.rb +106 -19
  169. data/spec/extensions/column_conflicts_spec.rb +11 -0
  170. data/spec/extensions/column_select_spec.rb +1 -0
  171. data/spec/extensions/composition_spec.rb +13 -0
  172. data/spec/extensions/connection_validator_spec.rb +1 -1
  173. data/spec/extensions/dataset_associations_spec.rb +20 -8
  174. data/spec/extensions/defaults_setter_spec.rb +15 -1
  175. data/spec/extensions/filter_having_spec.rb +5 -3
  176. data/spec/extensions/hash_aliases_spec.rb +3 -1
  177. data/spec/extensions/identifier_columns_spec.rb +3 -1
  178. data/spec/extensions/implicit_subquery_spec.rb +4 -2
  179. data/spec/extensions/json_serializer_spec.rb +18 -0
  180. data/spec/extensions/lazy_attributes_spec.rb +3 -3
  181. data/spec/extensions/many_through_many_spec.rb +4 -4
  182. data/spec/extensions/meta_def_spec.rb +9 -0
  183. data/spec/extensions/migration_spec.rb +3 -3
  184. data/spec/extensions/nested_attributes_spec.rb +14 -3
  185. data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
  186. data/spec/extensions/null_dataset_spec.rb +1 -1
  187. data/spec/extensions/pg_array_associations_spec.rb +29 -18
  188. data/spec/extensions/pg_array_spec.rb +44 -25
  189. data/spec/extensions/pg_hstore_spec.rb +10 -0
  190. data/spec/extensions/pg_inet_spec.rb +26 -0
  191. data/spec/extensions/pg_interval_spec.rb +20 -0
  192. data/spec/extensions/pg_json_spec.rb +24 -0
  193. data/spec/extensions/pg_range_spec.rb +98 -14
  194. data/spec/extensions/pg_row_spec.rb +14 -4
  195. data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
  196. data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
  197. data/spec/extensions/query_literals_spec.rb +3 -1
  198. data/spec/extensions/schema_dumper_spec.rb +108 -94
  199. data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
  200. data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
  201. data/spec/extensions/serialization_spec.rb +1 -1
  202. data/spec/extensions/server_block_spec.rb +7 -0
  203. data/spec/extensions/single_table_inheritance_spec.rb +17 -1
  204. data/spec/extensions/spec_helper.rb +7 -1
  205. data/spec/extensions/static_cache_spec.rb +75 -24
  206. data/spec/extensions/string_agg_spec.rb +1 -1
  207. data/spec/extensions/touch_spec.rb +9 -0
  208. data/spec/extensions/validation_helpers_spec.rb +10 -5
  209. data/spec/extensions/whitelist_security_spec.rb +26 -0
  210. data/spec/integration/associations_test.rb +8 -0
  211. data/spec/integration/dataset_test.rb +45 -44
  212. data/spec/integration/model_test.rb +53 -4
  213. data/spec/integration/plugin_test.rb +28 -4
  214. data/spec/integration/prepared_statement_test.rb +3 -0
  215. data/spec/integration/schema_test.rb +21 -1
  216. data/spec/integration/transaction_test.rb +40 -40
  217. data/spec/model/association_reflection_spec.rb +43 -1
  218. data/spec/model/associations_spec.rb +29 -9
  219. data/spec/model/class_dataset_methods_spec.rb +20 -4
  220. data/spec/model/dataset_methods_spec.rb +12 -3
  221. data/spec/model/eager_loading_spec.rb +8 -8
  222. data/spec/model/model_spec.rb +45 -1
  223. data/spec/model/plugins_spec.rb +34 -0
  224. data/spec/model/record_spec.rb +1 -1
  225. data/spec/spec_config.rb +2 -0
  226. metadata +11 -4
  227. data/spec/adapters/firebird_spec.rb +0 -405
  228. data/spec/adapters/informix_spec.rb +0 -100
@@ -40,10 +40,7 @@
40
40
  # If you specify the range database type, Sequel will automatically cast
41
41
  # the value to that type when literalizing.
42
42
  #
43
- # If you would like to use range columns in your model objects, you
44
- # probably want to modify the schema parsing/typecasting so that it
45
- # recognizes and correctly handles the range type columns, which you can
46
- # do by:
43
+ # To use this extension, load it into the Database instance:
47
44
  #
48
45
  # DB.extension :pg_range
49
46
  #
@@ -52,11 +49,10 @@
52
49
  #
53
50
  # This extension makes it easy to add support for other range types. In
54
51
  # general, you just need to make sure that the subtype is handled and has the
55
- # appropriate converter installed in Sequel::Postgres::PG_TYPES or the Database
56
- # instance's conversion_procs usingthe appropriate type OID. For user defined
52
+ # appropriate converter installed. For user defined
57
53
  # types, you can do this via:
58
54
  #
59
- # DB.conversion_procs[subtype_oid] = lambda{|string| }
55
+ # DB.add_conversion_proc(subtype_oid){|string| }
60
56
  #
61
57
  # Then you can call
62
58
  # Sequel::Postgres::PGRange::DatabaseMethods#register_range_type
@@ -66,18 +62,6 @@
66
62
  #
67
63
  # DB.register_range_type('timerange')
68
64
  #
69
- # You can also register range types on a global basis using
70
- # Sequel::Postgres::PGRange.register. In this case, you'll have
71
- # to specify the type oids:
72
- #
73
- # Sequel::Postgres::PG_TYPES[1234] = lambda{|string| }
74
- # Sequel::Postgres::PGRange.register('foo', :oid=>4321, :subtype_oid=>1234)
75
- #
76
- # Both Sequel::Postgres::PGRange::DatabaseMethods#register_range_type
77
- # and Sequel::Postgres::PGRange.register support many options to
78
- # customize the range type handling. See the Sequel::Postgres::PGRange.register
79
- # method documentation.
80
- #
81
65
  # This extension integrates with the pg_array extension. If you plan
82
66
  # to use arrays of range types, load the pg_array extension before the
83
67
  # pg_range extension:
@@ -86,54 +70,45 @@
86
70
  #
87
71
  # Related module: Sequel::Postgres::PGRange
88
72
 
89
- Sequel.require 'adapters/utils/pg_types'
73
+ Sequel.require 'adapters/shared/postgres'
90
74
 
91
75
  module Sequel
92
76
  module Postgres
93
77
  class PGRange
94
78
  include Sequel::SQL::AliasMethods
95
79
 
96
- # Map of string database type names to type symbols (e.g. 'int4range' => :int4range),
97
- # used in the schema parsing.
80
+ # SEQUEL5: Remove
98
81
  RANGE_TYPES = {}
99
82
 
100
83
  EMPTY = 'empty'.freeze
84
+ Sequel::Deprecation.deprecate_constant(self, :EMPTY)
101
85
  EMPTY_STRING = ''.freeze
86
+ Sequel::Deprecation.deprecate_constant(self, :EMPTY_STRING)
102
87
  COMMA = ','.freeze
88
+ Sequel::Deprecation.deprecate_constant(self, :COMMA)
103
89
  QUOTED_EMPTY_STRING = '""'.freeze
90
+ Sequel::Deprecation.deprecate_constant(self, :QUOTED_EMPTY_STRING)
104
91
  OPEN_PAREN = "(".freeze
92
+ Sequel::Deprecation.deprecate_constant(self, :OPEN_PAREN)
105
93
  CLOSE_PAREN = ")".freeze
94
+ Sequel::Deprecation.deprecate_constant(self, :CLOSE_PAREN)
106
95
  OPEN_BRACKET = "[".freeze
96
+ Sequel::Deprecation.deprecate_constant(self, :OPEN_BRACKET)
107
97
  CLOSE_BRACKET = "]".freeze
98
+ Sequel::Deprecation.deprecate_constant(self, :CLOSE_BRACKET)
108
99
  ESCAPE_RE = /("|,|\\|\[|\]|\(|\))/.freeze
100
+ Sequel::Deprecation.deprecate_constant(self, :ESCAPE_RE)
109
101
  ESCAPE_REPLACE = '\\\\\1'.freeze
102
+ Sequel::Deprecation.deprecate_constant(self, :ESCAPE_REPLACE)
110
103
  CAST = '::'.freeze
104
+ Sequel::Deprecation.deprecate_constant(self, :CAST)
111
105
 
112
- # Registers a range type that the extension should handle. Makes a Database instance that
113
- # has been extended with DatabaseMethods recognize the range type given and set up the
114
- # appropriate typecasting. Also sets up automatic typecasting for the native postgres
115
- # adapter, so that on retrieval, the values are automatically converted to PGRange instances.
116
- # The db_type argument should be the name of the range type. Accepts the following options:
117
- #
118
- # :converter :: A callable object (e.g. Proc), that is called with the start or end of the range
119
- # (usually a string), and should return the appropriate typecasted object.
120
- # :oid :: The PostgreSQL OID for the range type. This is used by the Sequel postgres adapter
121
- # to set up automatic type conversion on retrieval from the database.
122
- # :subtype_oid :: Should be the PostgreSQL OID for the range's subtype. If given,
123
- # automatically sets the :converter option by looking for scalar conversion
124
- # proc.
125
- # :type_procs :: A hash mapping oids to conversion procs, used for setting the default :converter
126
- # for :subtype_oid. Defaults to the global Sequel::Postgres::PG_TYPES.
127
- # :typecast_method_map :: The map in which to place the database type string to type symbol mapping.
128
- # Defaults to RANGE_TYPES.
129
- # :typecast_methods_module :: If given, a module object to add the typecasting method to. Defaults
130
- # to DatabaseMethods.
131
- #
132
- # If a block is given, it is treated as the :converter option.
106
+ # SEQUEL5: Remove
133
107
  def self.register(db_type, opts=OPTS, &block)
108
+ Sequel::Deprecation.deprecate("Sequel::Postgres::PGRange.register", "Use Database#register_range_type on a Database instance using the pg_range extension") unless opts[:skip_deprecation_warning]
134
109
  db_type = db_type.to_s.dup.freeze
135
110
 
136
- type_procs = opts[:type_procs] || PG_TYPES
111
+ type_procs = opts[:type_procs] || PG__TYPES
137
112
  mod = opts[:typecast_methods_module] || DatabaseMethods
138
113
  typecast_method_map = opts[:typecast_method_map] || RANGE_TYPES
139
114
 
@@ -155,14 +130,19 @@ module Sequel
155
130
  define_range_typecast_method(mod, db_type, parser)
156
131
 
157
132
  if oid = opts[:oid]
133
+ if opts[:skip_deprecation_warning]
134
+ def parser.call(s)
135
+ Sequel::Deprecation.deprecate("Conversion proc for #{db_type} added globally by pg_range extension", "Load the pg_range extension into the Database instance")
136
+ super
137
+ end
138
+ end
158
139
  type_procs[oid] = parser
159
140
  end
160
141
 
161
142
  nil
162
143
  end
163
144
 
164
- # Define a private range typecasting method for the given type that uses
165
- # the parser argument to do the type conversion.
145
+ # SEQUEL5: Remove
166
146
  def self.define_range_typecast_method(mod, type, parser)
167
147
  mod.class_eval do
168
148
  meth = :"typecast_value_#{type}"
@@ -174,12 +154,12 @@ module Sequel
174
154
 
175
155
  # Creates callable objects that convert strings into PGRange instances.
176
156
  class Parser
177
- # Regexp that parses the full range of PostgreSQL range type output,
178
- # except for empty ranges.
179
- PARSER = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/o
180
-
157
+ PARSER = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/
158
+ Sequel::Deprecation.deprecate_constant(self, :PARSER)
181
159
  REPLACE_RE = /\\(.)/.freeze
160
+ Sequel::Deprecation.deprecate_constant(self, :REPLACE_RE)
182
161
  REPLACE_WITH = '\1'.freeze
162
+ Sequel::Deprecation.deprecate_constant(self, :REPLACE_WITH)
183
163
 
184
164
  # The database range type for this parser (e.g. 'int4range'),
185
165
  # automatically setting the db_type for the returned PGRange instances.
@@ -197,11 +177,11 @@ module Sequel
197
177
 
198
178
  # Parse the range type input string into a PGRange value.
199
179
  def call(string)
200
- if string == EMPTY
180
+ if string == 'empty'
201
181
  return PGRange.empty(db_type)
202
182
  end
203
183
 
204
- raise(InvalidValue, "invalid or unhandled range format: #{string.inspect}") unless matches = PARSER.match(string)
184
+ raise(InvalidValue, "invalid or unhandled range format: #{string.inspect}") unless matches = /\A(\[|\()("((?:\\"|[^"])*)"|[^"]*),("((?:\\"|[^"])*)"|[^"]*)(\]|\))\z/.match(string)
205
185
 
206
186
  exclude_begin = matches[1] == '('
207
187
  exclude_end = matches[6] == ')'
@@ -215,12 +195,12 @@ module Sequel
215
195
  # to always use the quoted output form when characters need to be escaped, so
216
196
  # there isn't a need to unescape unquoted output.
217
197
  if beg = matches[3]
218
- beg.gsub!(REPLACE_RE, REPLACE_WITH)
198
+ beg.gsub!(/\\(.)/, '\1')
219
199
  else
220
200
  beg = matches[2] unless matches[2].empty?
221
201
  end
222
202
  if en = matches[5]
223
- en.gsub!(REPLACE_RE, REPLACE_WITH)
203
+ en.gsub!(/\\(.)/, '\1')
224
204
  else
225
205
  en = matches[4] unless matches[4].empty?
226
206
  end
@@ -241,20 +221,32 @@ module Sequel
241
221
  db.instance_eval do
242
222
  @pg_range_schema_types ||= {}
243
223
  extend_datasets(DatasetMethods)
244
- copy_conversion_procs([3904, 3906, 3912, 3926, 3905, 3907, 3913, 3927])
224
+ register_range_type('int4range', :oid=>3904, :subtype_oid=>23)
225
+ register_range_type('numrange', :oid=>3906, :subtype_oid=>1700)
226
+ register_range_type('tsrange', :oid=>3908, :subtype_oid=>1114)
227
+ register_range_type('tstzrange', :oid=>3910, :subtype_oid=>1184)
228
+ register_range_type('daterange', :oid=>3912, :subtype_oid=>1082)
229
+ register_range_type('int8range', :oid=>3926, :subtype_oid=>20)
230
+ if respond_to?(:register_array_type)
231
+ register_array_type('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
232
+ register_array_type('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
233
+ register_array_type('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
234
+ register_array_type('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange)
235
+ register_array_type('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange)
236
+ register_array_type('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range)
237
+ end
245
238
  [:int4range, :numrange, :tsrange, :tstzrange, :daterange, :int8range].each do |v|
246
239
  @schema_type_classes[v] = PGRange
247
240
  end
248
- end
249
241
 
250
- procs = db.conversion_procs
251
- procs[3908] = Parser.new("tsrange", procs[1114])
252
- procs[3910] = Parser.new("tstzrange", procs[1184])
253
- if defined?(PGArray::Creator)
254
- procs[3909] = PGArray::Creator.new("tsrange", procs[3908])
255
- procs[3911] = PGArray::Creator.new("tstzrange", procs[3910])
242
+ procs = conversion_procs
243
+ add_conversion_proc(3908, Parser.new("tsrange", procs[1114]))
244
+ add_conversion_proc(3910, Parser.new("tstzrange", procs[1184]))
245
+ if defined?(PGArray::Creator)
246
+ add_conversion_proc(3909, PGArray::Creator.new("tsrange", procs[3908]))
247
+ add_conversion_proc(3911, PGArray::Creator.new("tstzrange", procs[3910]))
248
+ end
256
249
  end
257
-
258
250
  end
259
251
 
260
252
  # Handle Range and PGRange values in bound variables
@@ -276,20 +268,62 @@ module Sequel
276
268
  end
277
269
 
278
270
  # Register a database specific range type. This can be used to support
279
- # different range types per Database. Use of this method does not
280
- # affect global state, unlike PGRange.register. See PGRange.register for
281
- # possible options.
271
+ # different range types per Database. Options:
272
+ #
273
+ # :converter :: A callable object (e.g. Proc), that is called with the start or end of the range
274
+ # (usually a string), and should return the appropriate typecasted object.
275
+ # :oid :: The PostgreSQL OID for the range type. This is used by the Sequel postgres adapter
276
+ # to set up automatic type conversion on retrieval from the database.
277
+ # :subtype_oid :: Should be the PostgreSQL OID for the range's subtype. If given,
278
+ # automatically sets the :converter option by looking for scalar conversion
279
+ # proc.
280
+ #
281
+ # If a block is given, it is treated as the :converter option.
282
282
  def register_range_type(db_type, opts=OPTS, &block)
283
- opts = {:type_procs=>conversion_procs, :typecast_method_map=>@pg_range_schema_types, :typecast_methods_module=>(class << self; self; end)}.merge!(opts)
284
- unless (opts.has_key?(:subtype_oid) || block) && opts.has_key?(:oid)
283
+ oid = opts[:oid]
284
+ soid = opts[:subtype_oid]
285
+
286
+ if has_converter = opts.has_key?(:converter)
287
+ raise Error, "can't provide both a block and :converter option to register_range_type" if block
288
+ converter = opts[:converter]
289
+ else
290
+ has_converter = true if block
291
+ converter = block
292
+ end
293
+
294
+ unless (soid || has_converter) && oid
285
295
  range_oid, subtype_oid = from(:pg_range).join(:pg_type, :oid=>:rngtypid).where(:typname=>db_type.to_s).get([:rngtypid, :rngsubtype])
286
- opts[:subtype_oid] = subtype_oid unless opts.has_key?(:subtype_oid) || block
287
- opts[:oid] = range_oid unless opts.has_key?(:oid)
296
+ soid ||= subtype_oid unless has_converter
297
+ oid ||= range_oid
298
+ end
299
+
300
+ db_type = db_type.to_s.dup.freeze
301
+
302
+ if converter = opts[:converter]
303
+ raise Error, "can't provide both a block and :converter option to register" if block
304
+ else
305
+ converter = block
306
+ end
307
+
308
+ if soid
309
+ raise Error, "can't provide both a converter and :subtype_oid option to register" if has_converter
310
+ raise Error, "no conversion proc for :subtype_oid=>#{soid.inspect} in conversion_procs" unless converter = conversion_procs[soid]
311
+ end
312
+
313
+ parser = Parser.new(db_type, converter)
314
+ add_conversion_proc(oid, parser)
315
+
316
+ @pg_range_schema_types[db_type] = db_type.to_sym
317
+
318
+ (class << self; self end).class_eval do
319
+ meth = :"typecast_value_#{db_type}"
320
+ define_method(meth){|v| typecast_value_pg_range(v, parser)}
321
+ private meth
288
322
  end
289
323
 
290
- PGRange.register(db_type, opts, &block)
291
324
  @schema_type_classes[:"#{opts[:type_symbol] || db_type}"] = PGRange
292
- conversion_procs_updated
325
+ conversion_procs_updated # SEQUEL5: Remove
326
+ nil
293
327
  end
294
328
 
295
329
  private
@@ -304,9 +338,7 @@ module Sequel
304
338
  end
305
339
  end
306
340
 
307
- # Manually override the typecasting for tsrange and tstzrange types so that
308
- # they use the database's timezone instead of the global Sequel
309
- # timezone.
341
+ # SEQUEL5: Remove
310
342
  def get_conversion_procs
311
343
  procs = super
312
344
 
@@ -322,7 +354,7 @@ module Sequel
322
354
 
323
355
  # Recognize the registered database range types.
324
356
  def schema_column_type(db_type)
325
- if type = @pg_range_schema_types[db_type] || RANGE_TYPES[db_type]
357
+ if type = @pg_range_schema_types[db_type] || RANGE_TYPES[db_type] # SEQUEL5: Remove || RANGE_TYPES[db_type]
326
358
  type
327
359
  else
328
360
  super
@@ -490,17 +522,17 @@ module Sequel
490
522
  # Append a literalize version of the receiver to the sql.
491
523
  def sql_literal_append(ds, sql)
492
524
  if (s = @db_type) && !empty?
493
- sql << s.to_s << OPEN_PAREN
525
+ sql << s.to_s << "("
494
526
  ds.literal_append(sql, self.begin)
495
- sql << COMMA
527
+ sql << ','
496
528
  ds.literal_append(sql, self.end)
497
- sql << COMMA
498
- ds.literal_append(sql, "#{exclude_begin? ? OPEN_PAREN : OPEN_BRACKET}#{exclude_end? ? CLOSE_PAREN : CLOSE_BRACKET}")
499
- sql << CLOSE_PAREN
529
+ sql << ','
530
+ ds.literal_append(sql, "#{exclude_begin? ? "(" : "["}#{exclude_end? ? ")" : "]"}")
531
+ sql << ")"
500
532
  else
501
533
  ds.literal_append(sql, unquoted_literal(ds))
502
534
  if s
503
- sql << CAST << s.to_s
535
+ sql << '::' << s.to_s
504
536
  end
505
537
  end
506
538
  end
@@ -536,9 +568,9 @@ module Sequel
536
568
  # Separated out for use by the bound argument code.
537
569
  def unquoted_literal(ds)
538
570
  if empty?
539
- EMPTY
571
+ 'empty'
540
572
  else
541
- "#{exclude_begin? ? OPEN_PAREN : OPEN_BRACKET}#{escape_value(self.begin, ds)},#{escape_value(self.end, ds)}#{exclude_end? ? CLOSE_PAREN : CLOSE_BRACKET}"
573
+ "#{exclude_begin? ? "(" : "["}#{escape_value(self.begin, ds)},#{escape_value(self.end, ds)}#{exclude_end? ? ")" : "]"}"
542
574
  end
543
575
  end
544
576
 
@@ -549,7 +581,7 @@ module Sequel
549
581
  def escape_value(k, ds)
550
582
  case k
551
583
  when nil
552
- EMPTY_STRING
584
+ ''
553
585
  when Date, Time
554
586
  ds.literal(k)[1...-1]
555
587
  when Integer, Float
@@ -560,29 +592,30 @@ module Sequel
560
592
  k
561
593
  when String
562
594
  if k.empty?
563
- QUOTED_EMPTY_STRING
595
+ '""'
564
596
  else
565
- k.gsub(ESCAPE_RE, ESCAPE_REPLACE)
597
+ k.gsub(/("|,|\\|\[|\]|\(|\))/, '\\\\\1')
566
598
  end
567
599
  else
568
- ds.literal(k).gsub(ESCAPE_RE, ESCAPE_REPLACE)
600
+ ds.literal(k).gsub(/("|,|\\|\[|\]|\(|\))/, '\\\\\1')
569
601
  end
570
602
  end
571
603
  end
572
604
 
573
- PGRange.register('int4range', :oid=>3904, :subtype_oid=>23)
574
- PGRange.register('numrange', :oid=>3906, :subtype_oid=>1700)
575
- PGRange.register('tsrange', :oid=>3908, :subtype_oid=>1114)
576
- PGRange.register('tstzrange', :oid=>3910, :subtype_oid=>1184)
577
- PGRange.register('daterange', :oid=>3912, :subtype_oid=>1082)
578
- PGRange.register('int8range', :oid=>3926, :subtype_oid=>20)
605
+ # SEQUEL5: Remove
606
+ PGRange.register('int4range', :oid=>3904, :subtype_oid=>23, :skip_deprecation_warning=>true)
607
+ PGRange.register('numrange', :oid=>3906, :subtype_oid=>1700, :skip_deprecation_warning=>true)
608
+ PGRange.register('tsrange', :oid=>3908, :subtype_oid=>1114, :skip_deprecation_warning=>true)
609
+ PGRange.register('tstzrange', :oid=>3910, :subtype_oid=>1184, :skip_deprecation_warning=>true)
610
+ PGRange.register('daterange', :oid=>3912, :subtype_oid=>1082, :skip_deprecation_warning=>true)
611
+ PGRange.register('int8range', :oid=>3926, :subtype_oid=>20, :skip_deprecation_warning=>true)
579
612
  if defined?(PGArray) && PGArray.respond_to?(:register)
580
- PGArray.register('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
581
- PGArray.register('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
582
- PGArray.register('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
583
- PGArray.register('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange)
584
- PGArray.register('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange)
585
- PGArray.register('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range)
613
+ PGArray.register('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range, :skip_deprecation_warning=>true)
614
+ PGArray.register('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange, :skip_deprecation_warning=>true)
615
+ PGArray.register('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange, :skip_deprecation_warning=>true)
616
+ PGArray.register('tstzrange', :oid=>3911, :scalar_oid=>3910, :scalar_typecast=>:tstzrange, :skip_deprecation_warning=>true)
617
+ PGArray.register('daterange', :oid=>3913, :scalar_oid=>3912, :scalar_typecast=>:daterange, :skip_deprecation_warning=>true)
618
+ PGArray.register('int8range', :oid=>3927, :scalar_oid=>3926, :scalar_typecast=>:int8range, :skip_deprecation_warning=>true)
586
619
  end
587
620
  end
588
621
 
@@ -75,13 +75,14 @@ module Sequel
75
75
  :starts_after => ["(".freeze, " &> ".freeze, ")".freeze].freeze,
76
76
  :adjacent_to => ["(".freeze, " -|- ".freeze, ")".freeze].freeze,
77
77
  :overlaps => ["(".freeze, " && ".freeze, ")".freeze].freeze,
78
- }
78
+ }#.freeze # SEQUEL5
79
79
  FUNCTIONS = %w'lower upper isempty lower_inc upper_inc lower_inf upper_inf'
80
+ Sequel::Deprecation.deprecate_constant(self, :FUNCTIONS)
80
81
 
81
- FUNCTIONS.each do |f|
82
+ %w'lower upper isempty lower_inc upper_inc lower_inf upper_inf'.each do |f|
82
83
  class_eval("def #{f}; function(:#{f}) end", __FILE__, __LINE__)
83
84
  end
84
- OPERATORS.keys.each do |f|
85
+ OPERATORS.each_key do |f|
85
86
  class_eval("def #{f}(v); operator(:#{f}, v) end", __FILE__, __LINE__)
86
87
  end
87
88