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
@@ -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