sequel 4.46.0 → 4.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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