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
@@ -1,25 +1,17 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel.require %w'pg_types unmodified_identifiers', 'adapters/utils'
3
+ Sequel.require %w'adapters/utils/unmodified_identifiers'
4
4
 
5
5
  module Sequel
6
6
  # Top level module for holding all PostgreSQL-related modules and classes
7
- # for Sequel. There are a few module level accessors that are added via
8
- # metaprogramming. These are:
9
- #
10
- # client_min_messages :: Change the minimum level of messages that PostgreSQL will send to the
11
- # the client. The PostgreSQL default is NOTICE, the Sequel default is
12
- # WARNING. Set to nil to not change the server default. Overridable on
13
- # a per instance basis via the :client_min_messages option.
14
- # force_standard_strings :: Set to false to not force the use of standard strings. Overridable
15
- # on a per instance basis via the :force_standard_strings option.
16
- #
17
- # It is not recommened you use these module-level accessors. Instead,
18
- # use the database option to make the setting per-Database.
19
- #
20
- # All adapters that connect to PostgreSQL support the following option in
21
- # addition to those mentioned above:
7
+ # for Sequel. All adapters that connect to PostgreSQL support the following options:
22
8
  #
9
+ # :client_min_messages :: Change the minimum level of messages that PostgreSQL will send to the
10
+ # the client. The PostgreSQL default is NOTICE, the Sequel default is
11
+ # WARNING. Set to nil to not change the server default. Overridable on
12
+ # a per instance basis via the :client_min_messages option.
13
+ # :force_standard_strings :: Set to false to not force the use of standard strings. Overridable
14
+ # on a per instance basis via the :force_standard_strings option.
23
15
  # :search_path :: Set the schema search_path for this Database's connections.
24
16
  # Allows to to set which schemas do not need explicit
25
17
  # qualification, and in which order to check the schemas when
@@ -27,6 +19,88 @@ module Sequel
27
19
  module Postgres
28
20
  Sequel::Database.set_shared_adapter_scheme(:postgres, self)
29
21
 
22
+ NAN = 0.0/0.0
23
+ PLUS_INFINITY = 1.0/0.0
24
+ MINUS_INFINITY = -1.0/0.0
25
+
26
+ NAN_STR = 'NaN'.freeze
27
+ Sequel::Deprecation.deprecate_constant(self, :NAN_STR)
28
+ PLUS_INFINITY_STR = 'Infinity'.freeze
29
+ Sequel::Deprecation.deprecate_constant(self, :PLUS_INFINITY_STR)
30
+ MINUS_INFINITY_STR = '-Infinity'.freeze
31
+ Sequel::Deprecation.deprecate_constant(self, :MINUS_INFINITY_STR)
32
+ TRUE_STR = 't'.freeze
33
+ Sequel::Deprecation.deprecate_constant(self, :TRUE_STR)
34
+ DASH_STR = '-'.freeze
35
+ Sequel::Deprecation.deprecate_constant(self, :DASH_STR)
36
+
37
+ TYPE_TRANSLATOR = tt = Class.new do
38
+ def boolean(s) s == 't' end
39
+ def integer(s) s.to_i end
40
+ def float(s)
41
+ case s
42
+ when 'NaN'
43
+ NAN
44
+ when 'Infinity'
45
+ PLUS_INFINITY
46
+ when '-Infinity'
47
+ MINUS_INFINITY
48
+ else
49
+ s.to_f
50
+ end
51
+ end
52
+ def date(s) ::Date.new(*s.split('-').map(&:to_i)) end
53
+ def bytea(str)
54
+ str = if str =~ /\A\\x/
55
+ # PostgreSQL 9.0+ bytea hex format
56
+ str[2..-1].gsub(/(..)/){|s| s.to_i(16).chr}
57
+ else
58
+ # Historical PostgreSQL bytea escape format
59
+ str.gsub(/\\(\\|'|[0-3][0-7][0-7])/) {|s|
60
+ if s.size == 2 then s[1,1] else s[1,3].oct.chr end
61
+ }
62
+ end
63
+ ::Sequel::SQL::Blob.new(str)
64
+ end
65
+ end.new#.freeze # SEQUEL5
66
+
67
+ # Type OIDs for string types used by PostgreSQL. These types don't
68
+ # have conversion procs associated with them (since the data is
69
+ # already in the form of a string).
70
+ STRING_TYPES = [18, 19, 25, 1042, 1043] # SEQUEL5: Remove
71
+
72
+ # Hash with type name strings/symbols and callable values for converting PostgreSQL types.
73
+ # Non-builtin types that don't have fixed numbers should use this to register
74
+ # conversion procs.
75
+ PG_NAMED_TYPES = {} unless defined?(PG_NAMED_TYPES)
76
+ PG_NAMED__TYPES = PG_NAMED_TYPES
77
+ Sequel::Deprecation.deprecate_constant(self, :PG_NAMED_TYPES)
78
+
79
+ # Hash with integer keys and callable values for converting PostgreSQL types.
80
+ PG_TYPES = {} unless defined?(PG_TYPES)
81
+
82
+ #CONVERSION_PROCS = {} # SEQUEL5
83
+
84
+ {
85
+ [16] => tt.method(:boolean),
86
+ [17] => tt.method(:bytea),
87
+ [20, 21, 23, 26] => tt.method(:integer),
88
+ [700, 701] => tt.method(:float),
89
+ [1700] => ::BigDecimal.method(:new),
90
+ [1083, 1266] => ::Sequel.method(:string_to_time),
91
+ [1082] => ::Sequel.method(:string_to_date),
92
+ [1184, 1114] => ::Sequel.method(:database_to_application_timestamp),
93
+ }.each do |k,v|
94
+ k.each do |n|
95
+ PG_TYPES[n] = v
96
+ #CONVERSION_PROCS[n] = v # SEQUEL5
97
+ end
98
+ end
99
+ PG__TYPES = PG_TYPES
100
+ Sequel::Deprecation.deprecate_constant(self, :PG_TYPES)
101
+
102
+ #CONVERSION_PROCS.freeze # SEQUEL5
103
+
30
104
  module MockAdapterDatabaseMethods
31
105
  def bound_variable_arg(arg, conn)
32
106
  arg
@@ -45,26 +119,30 @@ module Sequel
45
119
  end
46
120
  end
47
121
 
48
- # Array of exceptions that need to be converted. JDBC
49
- # uses NativeExceptions, the native adapter uses PGError.
50
122
  CONVERTED_EXCEPTIONS = []
123
+ Sequel::Deprecation.deprecate_constant(self, :CONVERTED_EXCEPTIONS)
51
124
 
125
+ # SEQUEL5: Remove
52
126
  @client_min_messages = :warning
53
127
  @force_standard_strings = true
54
-
55
128
  class << self
56
- # By default, Sequel sets the minimum level of log messages sent to the client
57
- # to WARNING, where PostgreSQL uses a default of NOTICE. This is to avoid a lot
58
- # of mostly useless messages when running migrations, such as a couple of lines
59
- # for every serial primary key field.
60
- attr_accessor :client_min_messages
61
-
62
- # By default, Sequel forces the use of standard strings, so that
63
- # '\\' is interpreted as \\ and not \. While PostgreSQL <9.1 defaults
64
- # to interpreting plain strings, newer versions use standard strings by
65
- # default. Sequel assumes that SQL standard strings will be used. Setting
66
- # this to false means Sequel will use the database's default.
67
- attr_accessor :force_standard_strings
129
+ def client_min_messages
130
+ Sequel::Deprecation.deprecate("Sequel::Postgres.client_min_messages", "Use the :client_min_messages Database option instead")
131
+ @client_min_messages
132
+ end
133
+ def client_min_messages=(v)
134
+ Sequel::Deprecation.deprecate("Sequel::Postgres.client_min_messages=", "Use the :client_min_messages Database option instead")
135
+ @client_min_messages = v
136
+ end
137
+
138
+ def force_standard_strings
139
+ Sequel::Deprecation.deprecate("Sequel::Postgres.force_standard_strings", "Use the :force_standard_strings Database option instead")
140
+ @force_standard_strings
141
+ end
142
+ def force_standard_strings=(v)
143
+ Sequel::Deprecation.deprecate("Sequel::Postgres.force_standard_strings=", "Use the :force_standard_strings Database option instead")
144
+ @force_standard_strings = v
145
+ end
68
146
  end
69
147
 
70
148
  class CreateTableGenerator < Sequel::Schema::CreateTableGenerator
@@ -179,6 +257,12 @@ module Sequel
179
257
  # having callable values for the conversion proc for that type.
180
258
  attr_reader :conversion_procs
181
259
 
260
+ # Set a conversion proc for the given oid. The callable can
261
+ # be passed either as a argument or a block.
262
+ def add_conversion_proc(oid, callable=Proc.new)
263
+ conversion_procs[oid] = callable
264
+ end
265
+
182
266
  # Add a conversion proc for a named type. This should be used
183
267
  # for types without fixed OIDs, which includes all types that
184
268
  # are not included in a default PostgreSQL installation. If
@@ -190,7 +274,12 @@ module Sequel
190
274
  Sequel::Deprecation.deprecate("Sequel::PG_NAMED_TYPES", "Call Database#add_named_conversion_proc directly for each database you want to support the #{name} type")
191
275
  end
192
276
  end
193
- add_named_conversion_procs(conversion_procs, name=>block)
277
+ add_named_conversion_procs(conversion_procs, name=>block) # SEQUEL5: Remove
278
+ # SEQUEL5:
279
+ #unless oid = from(:pg_type).where(:typtype=>['b', 'e'], :typname=>name.to_s).get(:oid)
280
+ # raise Error, "No matching type in pg_type for #{name.inspect}"
281
+ #end
282
+ #add_conversion_proc(oid, block) # SEQUEL5
194
283
  end
195
284
 
196
285
  # Commit an existing prepared transaction with the given transaction
@@ -316,68 +405,67 @@ module Sequel
316
405
  def foreign_key_list(table, opts=OPTS)
317
406
  m = output_identifier_meth
318
407
  schema, _ = opts.fetch(:schema, schema_and_table(table))
319
- range = 0...32
320
408
  oid = regclass_oid(table)
321
409
 
322
- base_ds = metadata_dataset.
410
+ if server_version >= 90500
411
+ cpos = Sequel.expr{array_position(co[:conkey], att[:attnum])}
412
+ rpos = Sequel.expr{array_position(co[:confkey], att2[:attnum])}
413
+ else
414
+ range = 0...32
415
+ cpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:conkey], [x]), x]}, 32, att[:attnum])}
416
+ rpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:confkey], [x]), x]}, 32, att2[:attnum])}
417
+ end
418
+
419
+ ds = metadata_dataset.
323
420
  from{pg_constraint.as(:co)}.
324
421
  join(Sequel[:pg_class].as(:cl), :oid=>:conrelid).
422
+ join(Sequel[:pg_attribute].as(:att), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
423
+ join(Sequel[:pg_class].as(:cl2), :oid=>Sequel[:co][:confrelid]).
424
+ join(Sequel[:pg_attribute].as(:att2), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:confkey])).
425
+ order{[co[:conname], cpos]}.
325
426
  where{{
326
427
  cl[:relkind]=>'r',
327
428
  co[:contype]=>'f',
328
- cl[:oid]=>oid}}
329
-
330
- # We split the parsing into two separate queries, which are merged manually later.
331
- # This is because PostgreSQL stores both the referencing and referenced columns in
332
- # arrays, and I don't know a simple way to not create a cross product, as PostgreSQL
333
- # doesn't appear to have a function that takes an array and element and gives you
334
- # the index of that element in the array.
335
-
336
- ds = base_ds.
337
- join(Sequel[:pg_attribute].as(:att), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
338
- order{[
339
- co[:conname],
340
- SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:conkey], [x]), x]}, 32, att[:attnum])]}.
429
+ cl[:oid]=>oid,
430
+ cpos=>rpos
431
+ }}.
341
432
  select{[
342
433
  co[:conname].as(:name),
343
434
  att[:attname].as(:column),
344
435
  co[:confupdtype].as(:on_update),
345
436
  co[:confdeltype].as(:on_delete),
346
- SQL::BooleanExpression.new(:AND, co[:condeferrable], co[:condeferred]).as(:deferrable)]}
347
-
348
- ref_ds = base_ds.
349
- join(Sequel[:pg_class].as(:cl2), :oid=>Sequel[:co][:confrelid]).
350
- join(Sequel[:pg_attribute].as(:att2), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:confkey])).
351
- order{[
352
- co[:conname],
353
- SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:confkey], [x]), x]}, 32, att2[:attnum])]}.
354
- select{[
355
- co[:conname].as(:name),
356
437
  cl2[:relname].as(:table),
357
- att2[:attname].as(:refcolumn)]}
438
+ att2[:attname].as(:refcolumn),
439
+ SQL::BooleanExpression.new(:AND, co[:condeferrable], co[:condeferred]).as(:deferrable)
440
+ ]}
358
441
 
359
442
  # If a schema is given, we only search in that schema, and the returned :table
360
443
  # entry is schema qualified as well.
361
444
  if schema
362
- ref_ds = ref_ds.join(Sequel[:pg_namespace].as(:nsp2), :oid=>Sequel[:cl2][:relnamespace]).
445
+ ds = ds.join(Sequel[:pg_namespace].as(:nsp2), :oid=>Sequel[:cl2][:relnamespace]).
363
446
  select_append{nsp2[:nspname].as(:schema)}
364
447
  end
365
448
 
366
449
  h = {}
367
450
  fklod_map = FOREIGN_KEY_LIST_ON_DELETE_MAP
451
+
368
452
  ds.each do |row|
369
453
  if r = h[row[:name]]
370
454
  r[:columns] << m.call(row[:column])
455
+ r[:key] << m.call(row[:refcolumn])
371
456
  else
372
- h[row[:name]] = {:name=>m.call(row[:name]), :columns=>[m.call(row[:column])], :on_update=>fklod_map[row[:on_update]], :on_delete=>fklod_map[row[:on_delete]], :deferrable=>row[:deferrable]}
457
+ h[row[:name]] = {
458
+ :name=>m.call(row[:name]),
459
+ :columns=>[m.call(row[:column])],
460
+ :key=>[m.call(row[:refcolumn])],
461
+ :on_update=>fklod_map[row[:on_update]],
462
+ :on_delete=>fklod_map[row[:on_delete]],
463
+ :deferrable=>row[:deferrable],
464
+ :table=>schema ? SQL::QualifiedIdentifier.new(m.call(row[:schema]), m.call(row[:table])) : m.call(row[:table])
465
+ }
373
466
  end
374
467
  end
375
- ref_ds.each do |row|
376
- r = h[row[:name]]
377
- r[:table] ||= schema ? SQL::QualifiedIdentifier.new(m.call(row[:schema]), m.call(row[:table])) : m.call(row[:table])
378
- r[:key] ||= []
379
- r[:key] << m.call(row[:refcolumn])
380
- end
468
+
381
469
  h.values
382
470
  end
383
471
 
@@ -391,9 +479,18 @@ module Sequel
391
479
  # Use the pg_* system tables to determine indexes on a table
392
480
  def indexes(table, opts=OPTS)
393
481
  m = output_identifier_meth
394
- range = 0...32
395
- attnums = server_version >= 80100 ? SQL::Function.new(:ANY, Sequel[:ind][:indkey]) : range.map{|x| SQL::Subscript.new(Sequel[:ind][:indkey], [x])}
396
482
  oid = regclass_oid(table, opts)
483
+
484
+ if server_version >= 90500
485
+ order = [Sequel[:indc][:relname], Sequel.function(:array_position, Sequel[:ind][:indkey], Sequel[:att][:attnum])]
486
+ else
487
+ range = 0...32
488
+ order = [Sequel[:indc][:relname], SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(Sequel[:ind][:indkey], [x]), x]}, 32, Sequel[:att][:attnum])]
489
+ attnums = range.map{|x| SQL::Subscript.new(Sequel[:ind][:indkey], [x])} unless server_version >= 80100
490
+ end
491
+
492
+ attnums ||= SQL::Function.new(:ANY, Sequel[:ind][:indkey])
493
+
397
494
  ds = metadata_dataset.
398
495
  from{pg_class.as(:tab)}.
399
496
  join(Sequel[:pg_index].as(:ind), :indrelid=>:oid).
@@ -407,7 +504,7 @@ module Sequel
407
504
  :indpred=>nil,
408
505
  :indisvalid=>true,
409
506
  tab[:oid]=>oid}}.
410
- order{[indc[:relname], SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(ind[:indkey], [x]), x]}, 32, att[:attnum])]}.
507
+ order(*order).
411
508
  select{[indc[:relname].as(:name), ind[:indisunique].as(:unique), att[:attname].as(:column), con[:condeferrable].as(:deferrable)]}
412
509
 
413
510
  ds = ds.where(:indisready=>true, :indcheckxmin=>false) if server_version >= 80300
@@ -478,9 +575,9 @@ module Sequel
478
575
  run "REFRESH MATERIALIZED VIEW#{' CONCURRENTLY' if opts[:concurrently]} #{quote_schema_table(name)}"
479
576
  end
480
577
 
481
- # Reset the database's conversion procs, requires a server query if there
482
- # any named types.
578
+ # SEQUEL5: Remove
483
579
  def reset_conversion_procs
580
+ Sequel::Deprecation.deprecate('Database#reset_conversion_procs', 'There should no longer be a need to reset conversion procs')
484
581
  @conversion_procs = get_conversion_procs
485
582
  conversion_procs_updated
486
583
  @conversion_procs
@@ -614,18 +711,19 @@ module Sequel
614
711
  # Array of symbols specifying view names in the current database.
615
712
  #
616
713
  # Options:
714
+ # :materialized :: Return materialized views
617
715
  # :qualify :: Return the views as Sequel::SQL::QualifiedIdentifier instances,
618
716
  # using the schema the view is located in as the qualifier.
619
717
  # :schema :: The schema to search
620
718
  # :server :: The server to use
621
719
  def views(opts=OPTS)
622
- pg_class_relname('v', opts)
720
+ relkind = opts[:materialized] ? 'm' : 'v'
721
+ pg_class_relname(relkind, opts)
623
722
  end
624
723
 
625
724
  private
626
725
 
627
- # Do a type name-to-oid lookup using the database and update the procs
628
- # with the related proc if the database supports the type.
726
+ # SEQUEL5: Remove
629
727
  def add_named_conversion_procs(procs, named_procs)
630
728
  unless (named_procs).empty?
631
729
  convert_named_procs_to_procs(named_procs).each do |oid, pr|
@@ -728,9 +826,10 @@ module Sequel
728
826
  def connection_configuration_sqls
729
827
  sqls = []
730
828
 
731
- sqls << "SET standard_conforming_strings = ON" if typecast_value_boolean(@opts.fetch(:force_standard_strings, Postgres.force_standard_strings))
829
+ sqls << "SET standard_conforming_strings = ON" if typecast_value_boolean(@opts.fetch(:force_standard_strings, Postgres.instance_variable_get(:@force_standard_strings))) # , true)) # SEQUEL5
732
830
 
733
- if (cmm = @opts.fetch(:client_min_messages, Postgres.client_min_messages)) && !cmm.to_s.empty?
831
+ cmm = @opts.fetch(:client_min_messages, Postgres.instance_variable_get(:@client_min_messages)) # , :warning) # SEQUEL5
832
+ if cmm && !cmm.to_s.empty?
734
833
  cmm = cmm.to_s.upcase.strip
735
834
  unless VALID_CLIENT_MIN_MESSAGES.include?(cmm)
736
835
  raise Error, "Unsupported client_min_messages setting: #{cmm}"
@@ -773,12 +872,12 @@ module Sequel
773
872
  end
774
873
  end
775
874
 
776
- # Callback used when conversion procs are updated.
875
+ # SEQUEL5: Remove
777
876
  def conversion_procs_updated
778
877
  nil
779
878
  end
780
879
 
781
- # Convert the hash of named conversion procs into a hash a oid conversion procs.
880
+ # SEQUEL5: Remove
782
881
  def convert_named_procs_to_procs(named_procs)
783
882
  h = {}
784
883
  from(:pg_type).where(:typtype=>['b', 'e'], :typname=>named_procs.keys.map(&:to_s)).select_map([:oid, :typname]).each do |oid, name|
@@ -787,12 +886,12 @@ module Sequel
787
886
  h
788
887
  end
789
888
 
790
- # Copy the conversion procs related to the given oids from PG_TYPES into
791
- # the conversion procs for this instance.
889
+ # SEQUEL5: Remove
792
890
  def copy_conversion_procs(oids)
891
+ Sequel::Deprecation.deprecate("Database#copy_conversion_procs", "There is no reason to use this anymore")
793
892
  procs = conversion_procs
794
893
  oids.each do |oid|
795
- procs[oid] = PG_TYPES[oid]
894
+ procs[oid] = PG__TYPES[oid]
796
895
  end
797
896
  conversion_procs_updated
798
897
  end
@@ -963,11 +1062,6 @@ module Sequel
963
1062
  create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}#{'RECURSIVE ' if options[:recursive]}#{'MATERIALIZED ' if options[:materialized]}VIEW #{quote_schema_table(name)}", options[:columns] || options[:recursive])
964
1063
  end
965
1064
 
966
- # The errors that the main adapters can raise, depends on the adapter being used
967
- def database_error_classes
968
- CONVERTED_EXCEPTIONS
969
- end
970
-
971
1065
  # SQL for dropping a function from the database.
972
1066
  def drop_function_sql(name, opts=OPTS)
973
1067
  "DROP FUNCTION#{' IF EXISTS' if opts[:if_exists]} #{name}#{sql_function_args(opts[:args])}#{' CASCADE' if opts[:cascade]}"
@@ -1015,9 +1109,9 @@ module Sequel
1015
1109
  ds.where{{pg_namespace[:nspname]=>expr}}
1016
1110
  end
1017
1111
 
1018
- # Return a hash with oid keys and callable values, used for converting types.
1112
+ # SEQUEL5: Remove
1019
1113
  def get_conversion_procs
1020
- procs = PG_TYPES.dup
1114
+ procs = PG__TYPES.dup
1021
1115
  procs[1184] = procs[1114] = method(:to_application_timestamp)
1022
1116
  unless PG_NAMED__TYPES.empty?
1023
1117
  Sequel::Deprecation.deprecate("Sequel::PG_NAMED_TYPES", "Call Database#add_named_conversion_proc directly for each Database instance where you want to support the following type(s): #{PG_NAMED__TYPES.keys.join(', ')}")
@@ -1054,8 +1148,10 @@ module Sequel
1054
1148
  @primary_keys = {}
1055
1149
  @primary_key_sequences = {}
1056
1150
  @supported_types = {}
1057
- @conversion_procs = PG_TYPES.dup
1058
- reset_conversion_procs
1151
+ @conversion_procs = get_conversion_procs # SEQUEL5: Remove
1152
+ conversion_procs_updated # SEQUEL5: Remove
1153
+ # @conversion_procs = CONVERSION_PROCS.dup # SEQUEL5
1154
+ # procs[1184] = procs[1114] = method(:to_application_timestamp) # SEQUEL5
1059
1155
  end
1060
1156
 
1061
1157
  # Backbone of the tables and views support.
@@ -1297,16 +1393,24 @@ module Sequel
1297
1393
  AS = ' AS '.freeze
1298
1394
  Sequel::Deprecation.deprecate_constant(self, :AS)
1299
1395
  XOR_OP = ' # '.freeze
1396
+ Sequel::Deprecation.deprecate_constant(self, :XOR_OP)
1300
1397
  CRLF = "\r\n".freeze
1398
+ Sequel::Deprecation.deprecate_constant(self, :CRLF)
1301
1399
  BLOB_RE = /[\000-\037\047\134\177-\377]/n.freeze
1400
+ Sequel::Deprecation.deprecate_constant(self, :BLOB_RE)
1302
1401
  WINDOW = " WINDOW ".freeze
1402
+ Sequel::Deprecation.deprecate_constant(self, :WINDOW)
1303
1403
  SELECT_VALUES = "VALUES ".freeze
1404
+ Sequel::Deprecation.deprecate_constant(self, :SELECT_VALUES)
1304
1405
  EMPTY_STRING = ''.freeze
1406
+ Sequel::Deprecation.deprecate_constant(self, :EMPTY_STRING)
1305
1407
  SKIP_LOCKED = " SKIP LOCKED".freeze
1408
+ Sequel::Deprecation.deprecate_constant(self, :SKIP_LOCKED)
1409
+ NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:cursor, :insert_conflict]).freeze
1410
+ Sequel::Deprecation.deprecate_constant(self, :NON_SQL_OPTIONS)
1306
1411
 
1307
1412
  NULL = LiteralString.new('NULL').freeze
1308
- LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze)
1309
- NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:cursor, :insert_conflict]).freeze
1413
+ LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze)#.freeze # SEQUEL5
1310
1414
 
1311
1415
  Dataset.def_sql_method(self, :delete, [['if server_version >= 90100', %w'with delete from using where returning'], ['else', %w'delete from using where returning']])
1312
1416
  Dataset.def_sql_method(self, :insert, [['if server_version >= 90500', %w'with insert into columns values conflict returning'], ['elsif server_version >= 90100', %w'with insert into columns values returning'], ['else', %w'insert into columns values returning']])
@@ -1766,7 +1870,7 @@ module Sequel
1766
1870
  sql << "'" << v.gsub("'", "''") << "'"
1767
1871
  end
1768
1872
 
1769
- # PostgreSQL uses FALSE for false values
1873
+ # PostgreSQL uses true for true values
1770
1874
  def literal_true
1771
1875
  'true'
1772
1876
  end
@@ -1777,8 +1881,8 @@ module Sequel
1777
1881
  end
1778
1882
 
1779
1883
  # Dataset options that do not affect the generated SQL.
1780
- def non_sql_options
1781
- NON_SQL_OPTIONS
1884
+ def non_sql_option?(key)
1885
+ super || key == :cursor || key == :insert_conflict
1782
1886
  end
1783
1887
 
1784
1888
  # PostgreSQL requires parentheses around compound datasets if they use
@@ -4,12 +4,17 @@ module Sequel
4
4
  module SqlAnywhere
5
5
  Sequel::Database.set_shared_adapter_scheme(:sqlanywhere, self)
6
6
 
7
+ # SEQUEL5: Remove
7
8
  @convert_smallint_to_bool = true
8
-
9
9
  class << self
10
- # Whether to convert smallint values to bool, false by default.
11
- # Can also be overridden per dataset.
12
- attr_accessor :convert_smallint_to_bool
10
+ def convert_smallint_to_bool
11
+ Sequel::Deprecation.deprecate("Sequel::SqlAnywhere.convert_smallint_to_bool", "Call this method on the Database instance")
12
+ @convert_smallint_to_bool
13
+ end
14
+ def convert_smallint_to_bool=(v)
15
+ Sequel::Deprecation.deprecate("Sequel::SqlAnywhere.convert_smallint_to_bool=", "Call this method on the Database instance")
16
+ @convert_smallint_to_bool = v
17
+ end
13
18
  end
14
19
 
15
20
  module DatabaseMethods
@@ -36,7 +41,7 @@ module Sequel
36
41
  # Whether to convert smallint to boolean arguments for this dataset.
37
42
  # Defaults to the SqlAnywhere module setting.
38
43
  def convert_smallint_to_bool
39
- defined?(@convert_smallint_to_bool) ? @convert_smallint_to_bool : (@convert_smallint_to_bool = ::Sequel::SqlAnywhere.convert_smallint_to_bool)
44
+ defined?(@convert_smallint_to_bool) ? @convert_smallint_to_bool : (@convert_smallint_to_bool = ::Sequel::SqlAnywhere.instance_variable_get(:@convert_smallint_to_bool)) # true) # SEQUEL5
40
45
  end
41
46
 
42
47
  # Sysbase Server uses the :sqlanywhere type.
@@ -319,14 +324,22 @@ module Sequel
319
324
  Dataset.def_sql_method(self, :insert, %w'with insert into columns values')
320
325
  Dataset.def_sql_method(self, :select, %w'with select distinct limit columns into from join where group having compounds order lock')
321
326
 
327
+ # Override the default IBMDB.convert_smallint_to_bool setting for this dataset.
328
+ def convert_smallint_to_bool=(v)
329
+ Sequel::Deprecation.deprecate("Sequel::SqlAnywhere::Dataset#convert_smallint_to_bool=", "Call with_convert_smallint_to_bool instead, which returns a modified copy instead of modifying the object")
330
+ @opts[:convert_smallint_to_bool] = v
331
+ end
332
+
322
333
  # Whether to convert smallint to boolean arguments for this dataset.
323
- # Defaults to the SqlAnywhere module setting.
334
+ # Defaults to the IBMDB module setting.
324
335
  def convert_smallint_to_bool
325
- defined?(@convert_smallint_to_bool) ? @convert_smallint_to_bool : (@convert_smallint_to_bool = @db.convert_smallint_to_bool)
336
+ opts.has_key?(:convert_smallint_to_bool) ? opts[:convert_smallint_to_bool] : db.convert_smallint_to_bool
326
337
  end
327
338
 
328
- # Override the default SqlAnywhere.convert_smallint_to_bool setting for this dataset.
329
- attr_writer :convert_smallint_to_bool
339
+ # Return a cloned dataset with the convert_smallint_to_bool option set.
340
+ def with_convert_smallint_to_bool(v)
341
+ clone(:convert_smallint_to_bool=>v)
342
+ end
330
343
 
331
344
  def supports_cte?(type=:select)
332
345
  type == :select || type == :insert
@@ -424,7 +437,7 @@ module Sequel
424
437
  string.gsub(/[\\%_\[]/){|m| "\\#{m}"}
425
438
  end
426
439
 
427
- # Use Date() and Now() for CURRENT_DATE and CURRENT_TIMESTAMP
440
+ # Use today() and Now() for CURRENT_DATE and CURRENT_TIMESTAMP
428
441
  def constant_sql_append(sql, constant)
429
442
  case constant
430
443
  when :CURRENT_DATE