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
@@ -5,89 +5,20 @@ Sequel.require 'adapters/shared/postgres'
5
5
  begin
6
6
  require 'pg'
7
7
 
8
+ Sequel::Postgres::PGError = PG::Error if defined?(PG::Error)
9
+ Sequel::Postgres::PGconn = PG::Connection if defined?(PG::Connection)
10
+ Sequel::Postgres::PGresult = PG::Result if defined?(PG::Result)
11
+
8
12
  # Work around postgres-pr 0.7.0+ which ships with a pg.rb file
9
- raise LoadError unless defined?(PGconn::CONNECTION_OK)
13
+ unless defined?(PG::Connection)
14
+ raise LoadError unless defined?(PGconn::CONNECTION_OK)
15
+ end
10
16
 
11
17
  Sequel::Postgres::USES_PG = true
12
18
  rescue LoadError => e
13
- Sequel::Postgres::USES_PG = false
14
19
  begin
15
- require 'postgres'
16
- # Attempt to get uniform behavior for the PGconn object no matter
17
- # if pg, postgres, or postgres-pr is used.
18
- class PGconn
19
- unless method_defined?(:escape_string)
20
- if self.respond_to?(:escape)
21
- # If there is no escape_string instance method, but there is an
22
- # escape class method, use that instead.
23
- def escape_string(str)
24
- Sequel::Postgres.force_standard_strings ? str.gsub("'", "''") : self.class.escape(str)
25
- end
26
- else
27
- # Raise an error if no valid string escaping method can be found.
28
- def escape_string(obj)
29
- if Sequel::Postgres.force_standard_strings
30
- str.gsub("'", "''")
31
- else
32
- raise Sequel::Error, "string escaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
33
- end
34
- end
35
- end
36
- end
37
- unless method_defined?(:escape_bytea)
38
- if self.respond_to?(:escape_bytea)
39
- # If there is no escape_bytea instance method, but there is an
40
- # escape_bytea class method, use that instead.
41
- def escape_bytea(obj)
42
- self.class.escape_bytea(obj)
43
- end
44
- else
45
- begin
46
- require 'postgres-pr/typeconv/conv'
47
- require 'postgres-pr/typeconv/bytea'
48
- extend Postgres::Conversion
49
- # If we are using postgres-pr, use the encode_bytea method from
50
- # that.
51
- def escape_bytea(obj)
52
- self.class.encode_bytea(obj)
53
- end
54
- instance_eval{alias unescape_bytea decode_bytea}
55
- rescue
56
- # If no valid bytea escaping method can be found, create one that
57
- # raises an error
58
- def escape_bytea(obj)
59
- raise Sequel::Error, "bytea escaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
60
- end
61
- # If no valid bytea unescaping method can be found, create one that
62
- # raises an error
63
- def self.unescape_bytea(obj)
64
- raise Sequel::Error, "bytea unescaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
65
- end
66
- end
67
- end
68
- end
69
- alias_method :finish, :close unless method_defined?(:finish)
70
- alias_method :async_exec, :exec unless method_defined?(:async_exec)
71
- unless method_defined?(:block)
72
- def block(timeout=nil)
73
- end
74
- end
75
- unless defined?(CONNECTION_OK)
76
- CONNECTION_OK = -1
77
- end
78
- unless method_defined?(:status)
79
- def status
80
- CONNECTION_OK
81
- end
82
- end
83
- end
84
- class PGresult
85
- alias_method :nfields, :num_fields unless method_defined?(:nfields)
86
- alias_method :ntuples, :num_tuples unless method_defined?(:ntuples)
87
- alias_method :ftype, :type unless method_defined?(:ftype)
88
- alias_method :fname, :fieldname unless method_defined?(:fname)
89
- alias_method :cmd_tuples, :cmdtuples unless method_defined?(:cmd_tuples)
90
- end
20
+ require 'postgres-pr/postgres-compat'
21
+ Sequel::Postgres::USES_PG = false
91
22
  rescue LoadError
92
23
  raise e
93
24
  end
@@ -95,14 +26,11 @@ end
95
26
 
96
27
  module Sequel
97
28
  module Postgres
98
- CONVERTED_EXCEPTIONS << PGError
99
-
29
+ # SEQUEL5: Remove
100
30
  TYPE_CONVERTOR = Class.new do
101
31
  def bytea(s) ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s)) end
102
32
  end.new
103
-
104
- # SEQUEL5: Remove
105
- PG_TYPES[17] = TYPE_CONVERTOR.method(:bytea)
33
+ Sequel::Deprecation.deprecate_constant(self, :TYPE_CONVERTOR)
106
34
 
107
35
  if Sequel::Postgres::USES_PG
108
36
  # Whether the given sequel_pg version integer is supported.
@@ -111,18 +39,22 @@ module Sequel
111
39
  end
112
40
  end
113
41
 
42
+ # SEQUEL5: Remove
114
43
  @use_iso_date_format = true
115
-
116
44
  class << self
117
- # As an optimization, Sequel sets the date style to ISO, so that PostgreSQL provides
118
- # the date in a known format that Sequel can parse faster. This can be turned off
119
- # if you require a date style other than ISO.
120
- attr_accessor :use_iso_date_format
45
+ def use_iso_date_format
46
+ Sequel::Deprecation.deprecate("Sequel::Postgres.use_iso_date_format", "Use the :use_iso_date_format Database option instead")
47
+ @use_iso_date_format
48
+ end
49
+ def use_iso_date_format=(v)
50
+ Sequel::Deprecation.deprecate("Sequel::Postgres.use_iso_date_format=", "Use the :use_iso_date_format Database option instead")
51
+ @use_iso_date_format = v
52
+ end
121
53
  end
122
54
 
123
55
  # PGconn subclass for connection specific methods used with the
124
- # pg, postgres, or postgres-pr driver.
125
- class Adapter < ::PGconn
56
+ # pg or postgres-pr driver.
57
+ class Adapter < PGconn
126
58
  # The underlying exception classes to reraise as disconnect errors
127
59
  # instead of regular database errors.
128
60
  DISCONNECT_ERROR_CLASSES = [IOError, Errno::EPIPE, Errno::ECONNRESET]
@@ -145,10 +77,49 @@ module Sequel
145
77
  # errors.
146
78
  DISCONNECT_ERROR_RE = /\A#{Regexp.union(disconnect_errors)}/
147
79
 
148
- # Hash of prepared statements for this connection. Keys are
149
- # string names of the server side prepared statement, and values
150
- # are SQL strings.
151
- attr_reader(:prepared_statements) if USES_PG
80
+ if USES_PG
81
+ # Hash of prepared statements for this connection. Keys are
82
+ # string names of the server side prepared statement, and values
83
+ # are SQL strings.
84
+ attr_reader :prepared_statements
85
+ else
86
+ # Make postgres-pr look like pg
87
+ CONNECTION_OK = -1
88
+
89
+ # Escape bytea values. Uses historical format instead of hex
90
+ # format for maximum compatibility.
91
+ def escape_bytea(str)
92
+ # each_byte used instead of [] for 1.9 compatibility
93
+ str.gsub(/[\000-\037\047\134\177-\377]/n){|b| "\\#{sprintf('%o', b.each_byte{|x| break x}).rjust(3, '0')}"}
94
+ end
95
+
96
+ # Escape strings by doubling apostrophes. This only works if standard
97
+ # conforming strings are used.
98
+ def escape_string(str)
99
+ str.gsub("'", "''")
100
+ end
101
+
102
+ alias finish close
103
+
104
+ def async_exec(sql)
105
+ PGresult.new(@conn.query(sql))
106
+ end
107
+
108
+ def block(timeout=nil)
109
+ end
110
+
111
+ def status
112
+ CONNECTION_OK
113
+ end
114
+
115
+ class PGresult < ::PGresult
116
+ alias nfields num_fields
117
+ alias ntuples num_tuples
118
+ alias ftype type
119
+ alias fname fieldname
120
+ alias cmd_tuples cmdtuples
121
+ end
122
+ end
152
123
 
153
124
  # Raise a Sequel::DatabaseDisconnectError if a one of the disconnect
154
125
  # error classes is raised, or a PGError is raised and the connection
@@ -247,7 +218,8 @@ module Sequel
247
218
  :user => opts[:user],
248
219
  :password => opts[:password],
249
220
  :connect_timeout => opts[:connect_timeout] || 20,
250
- :sslmode => opts[:sslmode]
221
+ :sslmode => opts[:sslmode],
222
+ :sslrootcert => opts[:sslrootcert]
251
223
  }.delete_if { |key, value| blank_object?(value) }
252
224
  connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
253
225
  conn = Adapter.connect(connection_params)
@@ -258,6 +230,10 @@ module Sequel
258
230
  conn.set_notice_receiver(&receiver)
259
231
  end
260
232
  else
233
+ unless typecast_value_boolean(@opts.fetch(:force_standard_strings, Postgres.instance_variable_get(:@force_standard_strings))) # , true)) # SEQUEL5
234
+ raise Error, "Cannot create connection using postgres-pr unless force_standard_strings is set"
235
+ end
236
+
261
237
  conn = Adapter.connect(
262
238
  (opts[:host] unless blank_object?(opts[:host])),
263
239
  opts[:port] || 5432,
@@ -311,7 +287,7 @@ module Sequel
311
287
  end
312
288
  end
313
289
  end
314
- conversion_procs[1082] = pr
290
+ add_conversion_proc(1082, pr)
315
291
  end
316
292
 
317
293
  # Disconnect given connection
@@ -390,8 +366,12 @@ module Sequel
390
366
  b << buf while buf = conn.get_copy_data
391
367
  b
392
368
  end
369
+ rescue => e
370
+ raise_error(e, :disconnect=>true)
393
371
  ensure
394
- raise DatabaseDisconnectError, "disconnecting as a partial COPY may leave the connection in an unusable state" if buf
372
+ if buf && !e
373
+ raise DatabaseDisconnectError, "disconnecting as a partial COPY may leave the connection in an unusable state"
374
+ end
395
375
  end
396
376
  end
397
377
  end
@@ -544,10 +524,10 @@ module Sequel
544
524
  # Add the primary_keys and primary_key_sequences instance variables,
545
525
  # so we can get the correct return values for inserted rows.
546
526
  def adapter_initialize
547
- @use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.use_iso_date_format))
527
+ @use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.instance_variable_get(:@use_iso_date_format))) # , true)) # SEQUEL5
548
528
  initialize_postgres_adapter
549
- conversion_procs[17] = TYPE_CONVERTOR.method(:bytea)
550
- conversion_procs[1082] = TYPE_TRANSLATOR.method(:date) if @use_iso_date_format
529
+ add_conversion_proc(17, method(:unescape_bytea)) if USES_PG
530
+ add_conversion_proc(1082, TYPE_TRANSLATOR.method(:date)) if @use_iso_date_format
551
531
  self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
552
532
  end
553
533
 
@@ -556,7 +536,7 @@ module Sequel
556
536
  begin
557
537
  yield
558
538
  rescue => e
559
- raise_error(e, :classes=>CONVERTED_EXCEPTIONS)
539
+ raise_error(e, :classes=>database_error_classes)
560
540
  end
561
541
  end
562
542
 
@@ -567,8 +547,15 @@ module Sequel
567
547
  sqls
568
548
  end
569
549
 
550
+ if USES_PG
551
+ def unescape_bytea(s)
552
+ ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s))
553
+ end
554
+ end
555
+
556
+ DATABASE_ERROR_CLASSES = [PGError].freeze
570
557
  def database_error_classes
571
- [PGError]
558
+ DATABASE_ERROR_CLASSES
572
559
  end
573
560
 
574
561
  def disconnect_error?(exception, opts)
@@ -579,7 +566,7 @@ module Sequel
579
566
 
580
567
  def database_exception_sqlstate(exception, opts)
581
568
  if exception.respond_to?(:result) && (result = exception.result)
582
- result.error_field(::PGresult::PG_DIAG_SQLSTATE)
569
+ result.error_field(PGresult::PG_DIAG_SQLSTATE)
583
570
  end
584
571
  end
585
572
 
@@ -885,3 +872,4 @@ end
885
872
 
886
873
  # SEQUEL5: Remove
887
874
  SEQUEL_POSTGRES_USES_PG = Sequel::Postgres::USES_PG
875
+ Sequel::Deprecation.deprecate_constant(Object, :SEQUEL_POSTGRES_USES_PG)
@@ -6,11 +6,17 @@ module Sequel
6
6
  module DB2
7
7
  Sequel::Database.set_shared_adapter_scheme(:db2, self)
8
8
 
9
+ # SEQUEL5: Remove
9
10
  @use_clob_as_blob = false
10
-
11
11
  class << self
12
- # Whether to use clob as the generic File type, true by default.
13
- attr_accessor :use_clob_as_blob
12
+ def use_clob_as_blob
13
+ Sequel::Deprecation.deprecate("Sequel::DB2.use_clob_as_blob", "Call this method on the Database instance")
14
+ @use_clob_as_blob
15
+ end
16
+ def use_clob_as_blob=(v)
17
+ Sequel::Deprecation.deprecate("Sequel::DB2.use_clob_as_blob=", "Call this method on the Database instance")
18
+ @use_clob_as_blob = v
19
+ end
14
20
  end
15
21
 
16
22
  module DatabaseMethods
@@ -21,6 +27,16 @@ module Sequel
21
27
  NULL = ''.freeze
22
28
  Sequel::Deprecation.deprecate_constant(self, :NULL)
23
29
 
30
+ # Whether to use clob as the generic File type, false by default.
31
+ #attr_accessor :use_clob_as_blob # SEQUEL5
32
+
33
+ # SEQUEL5: Remove
34
+ attr_writer :use_clob_as_blob
35
+ def use_clob_as_blob
36
+ v = @use_clob_as_blob
37
+ v.nil? ? Sequel::DB2.instance_variable_get(:@use_clob_as_blob) : v
38
+ end
39
+
24
40
  # DB2 always uses :db2 as it's database type
25
41
  def database_type
26
42
  :db2
@@ -250,7 +266,7 @@ module Sequel
250
266
 
251
267
  # Treat clob as blob if use_clob_as_blob is true
252
268
  def schema_column_type(db_type)
253
- (::Sequel::DB2::use_clob_as_blob && db_type.downcase == 'clob') ? :blob : super
269
+ (use_clob_as_blob && db_type.downcase == 'clob') ? :blob : super
254
270
  end
255
271
 
256
272
  # SQL to set the transaction isolation level
@@ -263,7 +279,7 @@ module Sequel
263
279
  # use this for blob value:
264
280
  # cast(X'fffefdfcfbfa' as blob(2G))
265
281
  def type_literal_generic_file(column)
266
- ::Sequel::DB2::use_clob_as_blob ? :clob : :blob
282
+ use_clob_as_blob ? :clob : :blob
267
283
  end
268
284
 
269
285
  # DB2 uses smallint to store booleans.
@@ -433,7 +449,7 @@ module Sequel
433
449
 
434
450
  # DB2 uses a literal hexidecimal number for blob strings
435
451
  def literal_blob_append(sql, v)
436
- if ::Sequel::DB2.use_clob_as_blob
452
+ if db.use_clob_as_blob
437
453
  super
438
454
  else
439
455
  sql << "BLOB(X'" << v.unpack("H*").first << "')"
@@ -540,7 +540,6 @@ module Sequel
540
540
  CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}#.freeze # SEQUEL5
541
541
  EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}#.freeze # SEQUEL5
542
542
  #EXTRACT_MAP.each_value(&:freeze) # SEQUEL5
543
- NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output, :mssql_unicode_strings]).freeze
544
543
  LIMIT_ALL = Object.new.freeze
545
544
 
546
545
  BOOL_TRUE = '1'.freeze
@@ -629,6 +628,8 @@ module Sequel
629
628
  Sequel::Deprecation.deprecate_constant(self, :ROWS_ONLY)
630
629
  FETCH_NEXT = " FETCH NEXT ".freeze
631
630
  Sequel::Deprecation.deprecate_constant(self, :FETCH_NEXT)
631
+ NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output, :mssql_unicode_strings]).freeze
632
+ Sequel::Deprecation.deprecate_constant(self, :NON_SQL_OPTIONS)
632
633
 
633
634
  Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
634
635
  Dataset.def_sql_method(self, :delete, %w'with delete limit from output from2 where')
@@ -637,6 +638,7 @@ module Sequel
637
638
 
638
639
  # Allow overriding of the mssql_unicode_strings option at the dataset level.
639
640
  def mssql_unicode_strings=(v)
641
+ Sequel::Deprecation.deprecate("Dataset#mssql_unicode_strings=", "Switch to using with_mssql_unicode_strings, which returns a modified copy")
640
642
  @opts[:mssql_unicode_strings] = v
641
643
  end
642
644
 
@@ -1048,9 +1050,8 @@ module Sequel
1048
1050
  is_2008_or_later? ? :values : :union
1049
1051
  end
1050
1052
 
1051
- # Dataset options that do not affect the generated SQL.
1052
- def non_sql_options
1053
- NON_SQL_OPTIONS
1053
+ def non_sql_option?(key)
1054
+ super || key == :disable_insert_output || key == :mssql_unicode_strings
1054
1055
  end
1055
1056
 
1056
1057
  def select_into_sql(sql)
@@ -12,32 +12,54 @@ module Sequel
12
12
  end
13
13
  end
14
14
 
15
+ # SEQUEL5: Remove
15
16
  @convert_tinyint_to_bool = true
16
-
17
+ @default_charset = nil
18
+ @default_collate = nil
19
+ @default_engine = nil
17
20
  class << self
18
- # Sequel converts the column type tinyint(1) to a boolean by default when
19
- # using the native MySQL or Mysql2 adapter. You can turn off the conversion by setting
20
- # this to false. This setting is ignored when connecting to MySQL via the do or jdbc
21
- # adapters, both of which automatically do the conversion.
22
- attr_accessor :convert_tinyint_to_bool
21
+ def convert_tinyint_to_bool
22
+ Sequel::Deprecation.deprecate("Sequel::MySQL.convert_tinyint_to_bool", "Call this method on the Database instance")
23
+ @convert_tinyint_to_bool
24
+ end
25
+ def convert_tinyint_to_bool=(v)
26
+ Sequel::Deprecation.deprecate("Sequel::MySQL.convert_tinyint_to_bool=", "Call this method on the Database instance")
27
+ @convert_tinyint_to_bool = v
28
+ end
23
29
 
24
- # Set the default charset used for CREATE TABLE. You can pass the
25
- # :charset option to create_table to override this setting.
26
- attr_accessor :default_charset
30
+ def default_charset
31
+ Sequel::Deprecation.deprecate("Sequel::MySQL.default_charset", "Call this method on the Database instance")
32
+ @default_charset
33
+ end
34
+ def default_charset=(v)
35
+ Sequel::Deprecation.deprecate("Sequel::MySQL.default_charset=", "Call this method on the Database instance")
36
+ @default_charset = v
37
+ end
27
38
 
28
- # Set the default collation used for CREATE TABLE. You can pass the
29
- # :collate option to create_table to override this setting.
30
- attr_accessor :default_collate
39
+ def default_collate
40
+ Sequel::Deprecation.deprecate("Sequel::MySQL.default_collate", "Call this method on the Database instance")
41
+ @default_collate
42
+ end
43
+ def default_collate=(v)
44
+ Sequel::Deprecation.deprecate("Sequel::MySQL.default_collate=", "Call this method on the Database instance")
45
+ @default_collate = v
46
+ end
31
47
 
32
- # Set the default engine used for CREATE TABLE. You can pass the
33
- # :engine option to create_table to override this setting.
34
- attr_accessor :default_engine
48
+ def default_engine
49
+ Sequel::Deprecation.deprecate("Sequel::MySQL.default_engine", "Call this method on the Database instance")
50
+ @default_engine
51
+ end
52
+ def default_engine=(v)
53
+ Sequel::Deprecation.deprecate("Sequel::MySQL.default_engine=", "Call this method on the Database instance")
54
+ @default_engine = v
55
+ end
35
56
  end
36
57
 
37
58
  # Methods shared by Database instances that connect to MySQL,
38
59
  # currently supported by the native and JDBC adapters.
39
60
  module DatabaseMethods
40
61
  include UnmodifiedIdentifiers::DatabaseMethods
62
+ include Sequel::Database::SplitAlterTable
41
63
 
42
64
  AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
43
65
  Sequel::Deprecation.deprecate_constant(self, :AUTO_INCREMENT)
@@ -49,8 +71,36 @@ module Sequel
49
71
  CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}#.freeze # SEQUEL5
50
72
  COLUMN_DEFINITION_ORDER = [:collate, :null, :default, :unique, :primary_key, :auto_increment, :references]#.freeze # SEQUEL5
51
73
 
52
- include Sequel::Database::SplitAlterTable
53
74
 
75
+ # Set the default charset used for CREATE TABLE. You can pass the
76
+ # :charset option to create_table to override this setting.
77
+ #attr_accessor :default_charset # SEQUEL5
78
+
79
+ # Set the default collation used for CREATE TABLE. You can pass the
80
+ # :collate option to create_table to override this setting.
81
+ #attr_accessor :default_collate # SEQUEL5
82
+
83
+ # Set the default engine used for CREATE TABLE. You can pass the
84
+ # :engine option to create_table to override this setting.
85
+ #attr_accessor :default_engine # SEQUEL5
86
+
87
+ # SEQUEL5: Remove
88
+ attr_writer :default_charset
89
+ def default_charset
90
+ v = @default_charset
91
+ v.nil? ? Sequel::MySQL.instance_variable_get(:@default_charset) : v
92
+ end
93
+ attr_writer :default_collate
94
+ def default_collate
95
+ v = @default_collate
96
+ v.nil? ? Sequel::MySQL.instance_variable_get(:@default_collate) : v
97
+ end
98
+ attr_writer :default_engine
99
+ def default_engine
100
+ v = @default_engine
101
+ v.nil? ? Sequel::MySQL.instance_variable_get(:@default_engine) : v
102
+ end
103
+
54
104
  # MySQL's cast rules are restrictive in that you can't just cast to any possible
55
105
  # database type.
56
106
  def cast_type_literal(type)
@@ -375,9 +425,9 @@ module Sequel
375
425
 
376
426
  # Use MySQL specific syntax for engine type and character encoding
377
427
  def create_table_sql(name, generator, options = OPTS)
378
- engine = options.fetch(:engine, Sequel::MySQL.default_engine)
379
- charset = options.fetch(:charset, Sequel::MySQL.default_charset)
380
- collate = options.fetch(:collate, Sequel::MySQL.default_collate)
428
+ engine = options.fetch(:engine, default_engine)
429
+ charset = options.fetch(:charset, default_charset)
430
+ collate = options.fetch(:collate, default_collate)
381
431
  generator.constraints.sort_by{|c| (c[:type] == :primary_key) ? -1 : 1}
382
432
 
383
433
  # Proc for figuring out the primary key for a given table.
@@ -669,10 +719,11 @@ module Sequel
669
719
  Sequel::Deprecation.deprecate_constant(self, :CURRENT_TIMESTAMP_56)
670
720
  ONLY_OFFSET = ",18446744073709551615".freeze
671
721
  Sequel::Deprecation.deprecate_constant(self, :ONLY_OFFSET)
722
+ NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:insert_ignore, :update_ignore, :on_duplicate_key_update]).freeze
723
+ Sequel::Deprecation.deprecate_constant(self, :NON_SQL_OPTIONS)
672
724
 
673
725
  MATCH_AGAINST = ["MATCH ".freeze, " AGAINST (".freeze, ")".freeze].freeze
674
726
  MATCH_AGAINST_BOOLEAN = ["MATCH ".freeze, " AGAINST (".freeze, " IN BOOLEAN MODE)".freeze].freeze
675
- NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:insert_ignore, :update_ignore, :on_duplicate_key_update]).freeze
676
727
 
677
728
  Dataset.def_sql_method(self, :delete, %w'delete from where order limit')
678
729
  Dataset.def_sql_method(self, :insert, %w'insert ignore into columns values on_duplicate_key_update')
@@ -790,8 +841,11 @@ module Sequel
790
841
  # Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
791
842
  # Raises an error on use of :full_outer type, since MySQL doesn't support it.
792
843
  def join_table(type, table, expr=nil, opts=OPTS, &block)
793
- type = :inner if (type == :cross) && !expr.nil?
794
- raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN") if type == :full_outer
844
+ if (type == :cross) && !expr.nil?
845
+ Sequel::Deprecation.deprecate(":cross join type with conditions being converted to INNER JOIN on MySQL", "Use :inner join type instead")
846
+ type = :inner
847
+ end
848
+ raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN or NATURAL FULL JOIN") if type == :full_outer || type == :natural_full
795
849
  super(type, table, expr, opts, &block)
796
850
  end
797
851
 
@@ -802,6 +856,7 @@ module Sequel
802
856
  when :straight
803
857
  'STRAIGHT_JOIN'
804
858
  when :natural_inner
859
+ Sequel::Deprecation.deprecate(":natural_inner join type being converted to NATURAL LEFT JOIN on MySQL", "Use :natural_left join type for NATURAL LEFT JOIN, or :natural join type for NATURAL JOIN")
805
860
  'NATURAL LEFT JOIN'
806
861
  else
807
862
  super
@@ -1055,9 +1110,8 @@ module Sequel
1055
1110
  :values
1056
1111
  end
1057
1112
 
1058
- # Dataset options that do not affect the generated SQL.
1059
- def non_sql_options
1060
- NON_SQL_OPTIONS
1113
+ def non_sql_option?(key)
1114
+ super || key == :insert_ignore || key == :update_ignore || key == :on_duplicate_key_update
1061
1115
  end
1062
1116
 
1063
1117
  def select_only_offset_sql(sql)
@@ -348,7 +348,7 @@ module Sequel
348
348
  Sequel::Deprecation.deprecate_constant(self, :SKIP_LOCKED)
349
349
 
350
350
  include(Module.new do
351
- Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order lock')
351
+ Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order limit lock')
352
352
  end)
353
353
 
354
354
  def complex_expression_sql_append(sql, op, args)
@@ -421,7 +421,10 @@ module Sequel
421
421
  # Handle LIMIT by using a unlimited subselect filtered with ROWNUM.
422
422
  def select_sql
423
423
  return super if @opts[:sql]
424
- if o = @opts[:offset]
424
+ return super if supports_fetch_next_rows?
425
+
426
+ o = @opts[:offset]
427
+ if o && o != 0
425
428
  columns = clone(:append_sql=>String.new, :placeholder_literal_null=>true).columns
426
429
  dsa1 = dataset_alias(1)
427
430
  rn = row_number_column
@@ -437,7 +440,7 @@ module Sequel
437
440
  subselect_sql_append(sql, ds)
438
441
  sql
439
442
  elsif limit = @opts[:limit]
440
- ds = clone(:limit=>nil)
443
+ ds = unlimited
441
444
  # Lock doesn't work in subselects, so don't use a subselect when locking.
442
445
  # Don't use a subselect if custom SQL is used, as it breaks somethings.
443
446
  ds = ds.from_self unless @opts[:lock]
@@ -449,6 +452,21 @@ module Sequel
449
452
  end
450
453
  end
451
454
 
455
+ def select_limit_sql(sql)
456
+ return unless supports_fetch_next_rows?
457
+
458
+ if offset = @opts[:offset]
459
+ sql << " OFFSET "
460
+ literal_append(sql, offset)
461
+ sql << " ROWS"
462
+ end
463
+
464
+ if limit = @opts[:limit]
465
+ sql << " FETCH NEXT "
466
+ literal_append(sql, limit)
467
+ sql << " ROWS ONLY"
468
+ end
469
+ end
452
470
  # Oracle requires recursive CTEs to have column aliases.
453
471
  def recursive_cte_requires_column_aliases?
454
472
  true
@@ -463,6 +481,11 @@ module Sequel
463
481
  false
464
482
  end
465
483
 
484
+ # Oracle supports FETCH NEXT ROWS since 12c
485
+ def supports_fetch_next_rows?
486
+ server_version >= 12000000 && !(@opts[:lock] || @opts[:skip_locked])
487
+ end
488
+
466
489
  # Oracle supports GROUP BY CUBE
467
490
  def supports_group_cube?
468
491
  true