sequel 5.45.0 → 5.77.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +434 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +59 -27
  5. data/bin/sequel +11 -3
  6. data/doc/advanced_associations.rdoc +16 -14
  7. data/doc/association_basics.rdoc +119 -24
  8. data/doc/cheat_sheet.rdoc +11 -3
  9. data/doc/mass_assignment.rdoc +1 -1
  10. data/doc/migration.rdoc +27 -6
  11. data/doc/model_hooks.rdoc +1 -1
  12. data/doc/object_model.rdoc +8 -8
  13. data/doc/opening_databases.rdoc +28 -12
  14. data/doc/postgresql.rdoc +16 -8
  15. data/doc/querying.rdoc +5 -3
  16. data/doc/release_notes/5.46.0.txt +87 -0
  17. data/doc/release_notes/5.47.0.txt +59 -0
  18. data/doc/release_notes/5.48.0.txt +14 -0
  19. data/doc/release_notes/5.49.0.txt +59 -0
  20. data/doc/release_notes/5.50.0.txt +78 -0
  21. data/doc/release_notes/5.51.0.txt +47 -0
  22. data/doc/release_notes/5.52.0.txt +87 -0
  23. data/doc/release_notes/5.53.0.txt +23 -0
  24. data/doc/release_notes/5.54.0.txt +27 -0
  25. data/doc/release_notes/5.55.0.txt +21 -0
  26. data/doc/release_notes/5.56.0.txt +51 -0
  27. data/doc/release_notes/5.57.0.txt +23 -0
  28. data/doc/release_notes/5.58.0.txt +31 -0
  29. data/doc/release_notes/5.59.0.txt +73 -0
  30. data/doc/release_notes/5.60.0.txt +22 -0
  31. data/doc/release_notes/5.61.0.txt +43 -0
  32. data/doc/release_notes/5.62.0.txt +132 -0
  33. data/doc/release_notes/5.63.0.txt +33 -0
  34. data/doc/release_notes/5.64.0.txt +50 -0
  35. data/doc/release_notes/5.65.0.txt +21 -0
  36. data/doc/release_notes/5.66.0.txt +24 -0
  37. data/doc/release_notes/5.67.0.txt +32 -0
  38. data/doc/release_notes/5.68.0.txt +61 -0
  39. data/doc/release_notes/5.69.0.txt +26 -0
  40. data/doc/release_notes/5.70.0.txt +35 -0
  41. data/doc/release_notes/5.71.0.txt +21 -0
  42. data/doc/release_notes/5.72.0.txt +33 -0
  43. data/doc/release_notes/5.73.0.txt +66 -0
  44. data/doc/release_notes/5.74.0.txt +45 -0
  45. data/doc/release_notes/5.75.0.txt +35 -0
  46. data/doc/release_notes/5.76.0.txt +86 -0
  47. data/doc/release_notes/5.77.0.txt +63 -0
  48. data/doc/schema_modification.rdoc +1 -1
  49. data/doc/security.rdoc +9 -9
  50. data/doc/sharding.rdoc +3 -1
  51. data/doc/sql.rdoc +27 -15
  52. data/doc/testing.rdoc +23 -13
  53. data/doc/transactions.rdoc +6 -6
  54. data/doc/virtual_rows.rdoc +1 -1
  55. data/lib/sequel/adapters/ado/access.rb +1 -1
  56. data/lib/sequel/adapters/ado.rb +1 -1
  57. data/lib/sequel/adapters/amalgalite.rb +3 -5
  58. data/lib/sequel/adapters/ibmdb.rb +3 -3
  59. data/lib/sequel/adapters/jdbc/derby.rb +8 -0
  60. data/lib/sequel/adapters/jdbc/h2.rb +63 -10
  61. data/lib/sequel/adapters/jdbc/hsqldb.rb +8 -0
  62. data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
  63. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
  64. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
  65. data/lib/sequel/adapters/jdbc.rb +24 -22
  66. data/lib/sequel/adapters/mysql.rb +92 -67
  67. data/lib/sequel/adapters/mysql2.rb +56 -51
  68. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  69. data/lib/sequel/adapters/odbc.rb +1 -1
  70. data/lib/sequel/adapters/oracle.rb +4 -3
  71. data/lib/sequel/adapters/postgres.rb +89 -45
  72. data/lib/sequel/adapters/shared/access.rb +11 -1
  73. data/lib/sequel/adapters/shared/db2.rb +42 -0
  74. data/lib/sequel/adapters/shared/mssql.rb +91 -10
  75. data/lib/sequel/adapters/shared/mysql.rb +78 -3
  76. data/lib/sequel/adapters/shared/oracle.rb +86 -7
  77. data/lib/sequel/adapters/shared/postgres.rb +576 -171
  78. data/lib/sequel/adapters/shared/sqlanywhere.rb +21 -5
  79. data/lib/sequel/adapters/shared/sqlite.rb +92 -8
  80. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  81. data/lib/sequel/adapters/sqlite.rb +99 -18
  82. data/lib/sequel/adapters/tinytds.rb +1 -1
  83. data/lib/sequel/adapters/trilogy.rb +117 -0
  84. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  85. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  86. data/lib/sequel/ast_transformer.rb +6 -0
  87. data/lib/sequel/connection_pool/sharded_single.rb +5 -7
  88. data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
  89. data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
  90. data/lib/sequel/connection_pool/single.rb +6 -8
  91. data/lib/sequel/connection_pool/threaded.rb +14 -8
  92. data/lib/sequel/connection_pool/timed_queue.rb +270 -0
  93. data/lib/sequel/connection_pool.rb +57 -31
  94. data/lib/sequel/core.rb +17 -18
  95. data/lib/sequel/database/connecting.rb +27 -3
  96. data/lib/sequel/database/dataset.rb +16 -6
  97. data/lib/sequel/database/misc.rb +70 -14
  98. data/lib/sequel/database/query.rb +73 -2
  99. data/lib/sequel/database/schema_generator.rb +11 -6
  100. data/lib/sequel/database/schema_methods.rb +23 -4
  101. data/lib/sequel/database/transactions.rb +6 -0
  102. data/lib/sequel/dataset/actions.rb +111 -15
  103. data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
  104. data/lib/sequel/dataset/features.rb +20 -1
  105. data/lib/sequel/dataset/misc.rb +12 -2
  106. data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
  107. data/lib/sequel/dataset/query.rb +170 -41
  108. data/lib/sequel/dataset/sql.rb +190 -71
  109. data/lib/sequel/dataset.rb +4 -0
  110. data/lib/sequel/extensions/_model_pg_row.rb +0 -12
  111. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  112. data/lib/sequel/extensions/any_not_empty.rb +2 -2
  113. data/lib/sequel/extensions/async_thread_pool.rb +14 -13
  114. data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
  115. data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
  116. data/lib/sequel/extensions/connection_expiration.rb +15 -9
  117. data/lib/sequel/extensions/connection_validator.rb +16 -11
  118. data/lib/sequel/extensions/constraint_validations.rb +1 -1
  119. data/lib/sequel/extensions/core_refinements.rb +36 -11
  120. data/lib/sequel/extensions/date_arithmetic.rb +36 -8
  121. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  122. data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
  123. data/lib/sequel/extensions/duplicate_columns_handler.rb +11 -10
  124. data/lib/sequel/extensions/index_caching.rb +5 -1
  125. data/lib/sequel/extensions/inflector.rb +1 -1
  126. data/lib/sequel/extensions/is_distinct_from.rb +141 -0
  127. data/lib/sequel/extensions/looser_typecasting.rb +3 -0
  128. data/lib/sequel/extensions/migration.rb +57 -15
  129. data/lib/sequel/extensions/named_timezones.rb +22 -6
  130. data/lib/sequel/extensions/pagination.rb +1 -1
  131. data/lib/sequel/extensions/pg_array.rb +33 -4
  132. data/lib/sequel/extensions/pg_array_ops.rb +2 -2
  133. data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
  134. data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
  135. data/lib/sequel/extensions/pg_enum.rb +1 -2
  136. data/lib/sequel/extensions/pg_extended_date_support.rb +39 -28
  137. data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
  138. data/lib/sequel/extensions/pg_hstore.rb +6 -1
  139. data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
  140. data/lib/sequel/extensions/pg_inet.rb +10 -11
  141. data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
  142. data/lib/sequel/extensions/pg_interval.rb +11 -11
  143. data/lib/sequel/extensions/pg_json.rb +13 -15
  144. data/lib/sequel/extensions/pg_json_ops.rb +125 -2
  145. data/lib/sequel/extensions/pg_multirange.rb +367 -0
  146. data/lib/sequel/extensions/pg_range.rb +13 -26
  147. data/lib/sequel/extensions/pg_range_ops.rb +37 -9
  148. data/lib/sequel/extensions/pg_row.rb +20 -19
  149. data/lib/sequel/extensions/pg_row_ops.rb +1 -1
  150. data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
  151. data/lib/sequel/extensions/round_timestamps.rb +1 -1
  152. data/lib/sequel/extensions/s.rb +2 -1
  153. data/lib/sequel/extensions/schema_caching.rb +1 -1
  154. data/lib/sequel/extensions/schema_dumper.rb +45 -11
  155. data/lib/sequel/extensions/server_block.rb +10 -13
  156. data/lib/sequel/extensions/set_literalizer.rb +58 -0
  157. data/lib/sequel/extensions/sql_comments.rb +110 -3
  158. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  159. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  160. data/lib/sequel/extensions/string_agg.rb +1 -1
  161. data/lib/sequel/extensions/string_date_time.rb +19 -23
  162. data/lib/sequel/extensions/symbol_aref.rb +2 -0
  163. data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
  164. data/lib/sequel/model/associations.rb +286 -92
  165. data/lib/sequel/model/base.rb +53 -33
  166. data/lib/sequel/model/dataset_module.rb +3 -0
  167. data/lib/sequel/model/errors.rb +10 -1
  168. data/lib/sequel/model/exceptions.rb +15 -3
  169. data/lib/sequel/model/inflections.rb +1 -1
  170. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  171. data/lib/sequel/plugins/auto_validations.rb +74 -16
  172. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  173. data/lib/sequel/plugins/column_encryption.rb +29 -8
  174. data/lib/sequel/plugins/composition.rb +3 -2
  175. data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
  176. data/lib/sequel/plugins/constraint_validations.rb +8 -5
  177. data/lib/sequel/plugins/defaults_setter.rb +16 -0
  178. data/lib/sequel/plugins/dirty.rb +1 -1
  179. data/lib/sequel/plugins/enum.rb +124 -0
  180. data/lib/sequel/plugins/finder.rb +4 -2
  181. data/lib/sequel/plugins/insert_conflict.rb +4 -0
  182. data/lib/sequel/plugins/instance_specific_default.rb +1 -1
  183. data/lib/sequel/plugins/json_serializer.rb +2 -2
  184. data/lib/sequel/plugins/lazy_attributes.rb +3 -0
  185. data/lib/sequel/plugins/list.rb +8 -3
  186. data/lib/sequel/plugins/many_through_many.rb +109 -10
  187. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
  188. data/lib/sequel/plugins/nested_attributes.rb +4 -4
  189. data/lib/sequel/plugins/optimistic_locking.rb +9 -42
  190. data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
  191. data/lib/sequel/plugins/paged_operations.rb +181 -0
  192. data/lib/sequel/plugins/pg_array_associations.rb +46 -34
  193. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
  194. data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
  195. data/lib/sequel/plugins/prepared_statements.rb +12 -2
  196. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
  197. data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
  198. data/lib/sequel/plugins/rcte_tree.rb +7 -4
  199. data/lib/sequel/plugins/require_valid_schema.rb +67 -0
  200. data/lib/sequel/plugins/serialization.rb +1 -0
  201. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -0
  202. data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
  203. data/lib/sequel/plugins/sql_comments.rb +189 -0
  204. data/lib/sequel/plugins/static_cache.rb +39 -1
  205. data/lib/sequel/plugins/static_cache_cache.rb +5 -1
  206. data/lib/sequel/plugins/subclasses.rb +28 -11
  207. data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
  208. data/lib/sequel/plugins/timestamps.rb +1 -1
  209. data/lib/sequel/plugins/unused_associations.rb +521 -0
  210. data/lib/sequel/plugins/update_or_create.rb +1 -1
  211. data/lib/sequel/plugins/validate_associated.rb +22 -12
  212. data/lib/sequel/plugins/validation_helpers.rb +41 -11
  213. data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
  214. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  215. data/lib/sequel/sql.rb +1 -1
  216. data/lib/sequel/timezones.rb +12 -14
  217. data/lib/sequel/version.rb +1 -1
  218. metadata +109 -19
data/doc/testing.rdoc CHANGED
@@ -15,7 +15,7 @@ These run each test in its own transaction, the recommended way to test.
15
15
 
16
16
  class Minitest::HooksSpec
17
17
  def around
18
- DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
18
+ DB.transaction(rollback: :always, auto_savepoint: true){super}
19
19
  end
20
20
  end
21
21
 
@@ -24,7 +24,7 @@ These run each test in its own transaction, the recommended way to test.
24
24
 
25
25
  class Minitest::Spec
26
26
  def run(*args, &block)
27
- DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
27
+ DB.transaction(rollback: :always, auto_savepoint: true){super}
28
28
  end
29
29
  end
30
30
 
@@ -34,7 +34,7 @@ These run each test in its own transaction, the recommended way to test.
34
34
  # Use this class as the base class for your tests
35
35
  class SequelTestCase < Minitest::Test
36
36
  def run(*args, &block)
37
- DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
37
+ DB.transaction(rollback: :always, auto_savepoint: true){super}
38
38
  end
39
39
  end
40
40
 
@@ -43,7 +43,7 @@ These run each test in its own transaction, the recommended way to test.
43
43
 
44
44
  RSpec.configure do |c|
45
45
  c.around(:each) do |example|
46
- DB.transaction(:rollback=>:always, :auto_savepoint=>true){example.run}
46
+ DB.transaction(rollback: :always, auto_savepoint: true){example.run}
47
47
  end
48
48
  end
49
49
 
@@ -51,11 +51,11 @@ These run each test in its own transaction, the recommended way to test.
51
51
 
52
52
  You can use the Sequel.transaction method to run a transaction on multiple databases, rolling all of them back. Instead of:
53
53
 
54
- DB.transaction(:rollback=>:always)
54
+ DB.transaction(rollback: :always)
55
55
 
56
56
  Use Sequel.transaction with an array of databases:
57
57
 
58
- Sequel.transaction([DB1, DB2, DB3], :rollback=>:always)
58
+ Sequel.transaction([DB1, DB2, DB3], rollback: :always)
59
59
 
60
60
  == Transactional testing with savepoints
61
61
 
@@ -71,11 +71,11 @@ Example:
71
71
  require 'minitest/hooks/default'
72
72
  class Minitest::HooksSpec
73
73
  def around
74
- DB.transaction(:rollback=>:always, :savepoint=>true, :auto_savepoint=>true){super}
74
+ DB.transaction(rollback: :always, savepoint: true, auto_savepoint: true){super}
75
75
  end
76
76
 
77
77
  def around_all
78
- DB.transaction(:rollback=>:always){super}
78
+ DB.transaction(rollback: :always){super}
79
79
  end
80
80
  end
81
81
 
@@ -113,7 +113,7 @@ The order in which you delete/truncate the tables is important if you are using
113
113
 
114
114
  = Testing Sequel Itself
115
115
 
116
- Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-shared_description extensions.
116
+ Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-global_expectations extensions. To install the dependencies necessary to test Sequel, run <tt>gem install --development sequel</tt>.
117
117
 
118
118
  == rake
119
119
 
@@ -145,6 +145,8 @@ The <tt>spec_<i>adapter</i></tt> specs run against a real database connection wi
145
145
 
146
146
  These specs are broken down into two parts. For each database, there are specific specs that only apply to that database, and these are called the adapter specs. There are also shared specs that apply to all (or almost all) databases, these are called the integration specs. For database types that don't have specific adapter tests, you can use <tt>rake spec_integration</tt> to just run the shared integration tests.
147
147
 
148
+ Each adapter needs a specific gem installed in order to run. Please see the {connecting to a database guide}[rdoc-ref:doc/opening_databases.rdoc] for which gem you need to install for the adapter you are testing.
149
+
148
150
  == Environment variables
149
151
 
150
152
  Sequel uses environment variables when testing to specify either the database to be tested or specify how testing should be done. You can also specify the databases to test by copying <tt>spec/spec_config.rb.example</tt> to <tt>spec/spec_config.rb</tt> and modifying it. See that file for details. It may be necessary to use +spec_config.rb+ as opposed to an environment variable if your database connection cannot be specified by a connection string.
@@ -157,24 +159,32 @@ The SEQUEL_INTEGRATION_URL environment variable specifies the Database connectio
157
159
 
158
160
  === Other
159
161
 
162
+ SEQUEL_AUTO_CAST_DATE_TIME :: Use the auto_cast_date_and_time extension when running the specs
160
163
  SEQUEL_ASYNC_THREAD_POOL :: Use the async_thread_pool extension when running the specs
161
164
  SEQUEL_ASYNC_THREAD_POOL_PREEMPT :: Use the async_thread_pool extension when running the specs, with the :preempt_async_thread option
165
+ SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
162
166
  SEQUEL_COLUMNS_INTROSPECTION :: Use the columns_introspection extension when running the specs
163
- SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when running the specs
164
- SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
165
167
  SEQUEL_CONCURRENT_EAGER_LOADING :: Use the async_thread_pool extension and concurrent_eager_loading plugin when running the specs
168
+ SEQUEL_CONNECTION_VALIDATOR :: Use the connection_validator extension when running the adapter/integration specs
169
+ SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
166
170
  SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
167
- SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
168
171
  SEQUEL_FIBER_CONCURRENCY :: Use the fiber_concurrency extension when running the adapter and integration specs
169
172
  SEQUEL_FREEZE_DATABASE :: Freeze the database before running the integration specs
170
173
  SEQUEL_IDENTIFIER_MANGLING :: Use the identifier_mangling extension when running the specs
174
+ SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
171
175
  SEQUEL_INTEGER64 :: Use the integer64 extension when running the adapter or integration specs
172
176
  SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements plugin when running the specs
173
177
  SEQUEL_MODEL_THROW_FAILURES :: Use the throw_failures plugin when running the specs
174
178
  SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
175
- SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
176
179
  SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
180
+ SEQUEL_PG_AUTO_PARAMETERIZE :: Use the pg_auto_parameterize extension when running the postgres specs. Value can be +in_array+ to test the pg_auto_parameterize_in_array extension, and +in_array_string+ to test the pg_auto_parameterize_in_array extension with the +:treat_in_string_list_as_text_array+ Database option set.
177
181
  SEQUEL_PG_TIMESTAMPTZ :: Use the pg_timestamptz extension when running the postgres specs
182
+ SEQUEL_PRIMARY_KEY_LOOKUP_CHECK_VALUES :: Use the primary_key_lookup_check_values extension when running the adapter or integration specs
183
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_0_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
184
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_1_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
185
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_2_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
186
+ SEQUEL_QUERY_PER_ASSOCIATION_DB_3_URL :: Run query-per-association integration tests with multiple databases (all 4 must be set to run)
178
187
  SEQUEL_SPLIT_SYMBOLS :: Turn on symbol splitting when running the adapter and integration specs
179
188
  SEQUEL_SYNCHRONIZE_SQL :: Use the synchronize_sql extension when running the specs
189
+ SEQUEL_TRANSACTION_CONNECTION_VALIDATOR :: Use the transaction_connection_validator extension when running the adapter/integration specs
180
190
  SEQUEL_TZINFO_VERSION :: Force the given tzinfo version when running the specs (e.g. '>=2')
@@ -127,28 +127,28 @@ Other exceptions, unless rescued inside the outer transaction block, will rollba
127
127
  end # ROLLBACK
128
128
  # ArgumentError raised
129
129
 
130
- If you want the current savepoint to be rolled back when the savepoint block exits instead of being committed (even if an exception is not raised), use <tt>Database#rollback_on_exit(:savepoint=>true)</tt>
130
+ If you want the current savepoint to be rolled back when the savepoint block exits instead of being committed (even if an exception is not raised), use <tt>Database#rollback_on_exit(savepoint: true)</tt>
131
131
 
132
132
  DB.transaction do # BEGIN
133
133
  DB.transaction(savepoint: true) do # SAVEPOINT
134
- DB.rollback_on_exit(:savepoint=>true)
134
+ DB.rollback_on_exit(savepoint: true)
135
135
  end # ROLLBACK TO SAVEPOINT
136
136
  end # COMMIT
137
137
 
138
138
  DB.transaction do # BEGIN
139
139
  DB.transaction(savepoint: true) do # SAVEPOINT
140
140
  DB.transaction(savepoint: true) do # SAVEPOINT
141
- DB.rollback_on_exit(:savepoint=>true)
141
+ DB.rollback_on_exit(savepoint: true)
142
142
  end # ROLLBACK TO SAVEPOINT
143
143
  end # RELEASE SAVEPOINT
144
144
  end # COMMIT
145
145
 
146
- If you want the current savepoint and potentially enclosing savepoints to be rolled back when the savepoint blocks exit (even if an exception is not raised), use <tt>Database#rollback_on_exit(:savepoint=>integer)</tt>
146
+ If you want the current savepoint and potentially enclosing savepoints to be rolled back when the savepoint blocks exit (even if an exception is not raised), use <tt>Database#rollback_on_exit(savepoint: integer)</tt>
147
147
 
148
148
  DB.transaction do # BEGIN
149
149
  DB.transaction(savepoint: true) do # SAVEPOINT
150
150
  DB.transaction(savepoint: true) do # SAVEPOINT
151
- DB.rollback_on_exit(:savepoint=>2)
151
+ DB.rollback_on_exit(savepoint: 2)
152
152
  end # ROLLBACK TO SAVEPOINT
153
153
  end # ROLLBACK TO SAVEPOINT
154
154
  end # COMMIT
@@ -156,7 +156,7 @@ If you want the current savepoint and potentially enclosing savepoints to be rol
156
156
  DB.transaction do # BEGIN
157
157
  DB.transaction(savepoint: true) do # SAVEPOINT
158
158
  DB.transaction(savepoint: true) do # SAVEPOINT
159
- DB.rollback_on_exit(:savepoint=>3)
159
+ DB.rollback_on_exit(savepoint: 3)
160
160
  end # ROLLBACK TO SAVEPOINT
161
161
  end # ROLLBACK TO SAVEPOINT
162
162
  end # ROLLBACK
@@ -23,7 +23,7 @@ With virtual rows, you can use the less verbose:
23
23
  Virtual row blocks behave differently depending on whether the block accepts
24
24
  an argument. If the block accepts an argument, it is called with an instance
25
25
  of Sequel::SQL::VirtualRow. If it does not accept an argument, it is
26
- evaluated in the context of an instance of Sequel::SQL::VirtualRow.
26
+ evaluated in the <em> context of an instance </em> of Sequel::SQL::VirtualRow.
27
27
 
28
28
  ds = DB[:items]
29
29
  # Regular block
@@ -318,7 +318,7 @@ module Sequel
318
318
  conn.OpenSchema(ado_schema.type, ado_schema.criteria)
319
319
  end
320
320
  }
321
- yield(r) if block_given?
321
+ yield(r) if defined?(yield)
322
322
  rescue ::WIN32OLERuntimeError => e
323
323
  raise_error(e)
324
324
  end
@@ -161,7 +161,7 @@ module Sequel
161
161
  begin
162
162
  r = log_connection_yield(sql, conn){conn.Execute(sql)}
163
163
  begin
164
- yield r if block_given?
164
+ yield r if defined?(yield)
165
165
  ensure
166
166
  begin
167
167
  r.close
@@ -118,11 +118,9 @@ module Sequel
118
118
  # Yield an available connection. Rescue
119
119
  # any Amalgalite::Errors and turn them into DatabaseErrors.
120
120
  def _execute(sql, opts)
121
- begin
122
- synchronize(opts[:server]){|conn| yield conn}
123
- rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
124
- raise_error(e)
125
- end
121
+ synchronize(opts[:server]){|conn| yield conn}
122
+ rescue ::Amalgalite::Error, ::Amalgalite::SQLite3::Error => e
123
+ raise_error(e)
126
124
  end
127
125
 
128
126
  # The Amagalite adapter does not need the pool to convert exceptions.
@@ -246,7 +246,7 @@ module Sequel
246
246
  end
247
247
  begin
248
248
  stmt = log_connection_yield(log_sql, conn, args){conn.execute_prepared(ps_name, *args)}
249
- if block_given?
249
+ if defined?(yield)
250
250
  yield(stmt)
251
251
  else
252
252
  stmt.affected
@@ -268,7 +268,7 @@ module Sequel
268
268
  # is given or returning the number of affected rows if not, and ensuring the statement is freed.
269
269
  def _execute(conn, sql, opts)
270
270
  stmt = log_connection_yield(sql, conn){conn.execute(sql)}
271
- if block_given?
271
+ if defined?(yield)
272
272
  yield(stmt)
273
273
  else
274
274
  stmt.affected
@@ -301,7 +301,7 @@ module Sequel
301
301
  end
302
302
 
303
303
  def database_exception_sqlstate(exception, opts)
304
- exception.sqlstate
304
+ exception.sqlstate if exception.respond_to?(:sqlstate)
305
305
  end
306
306
 
307
307
  def dataset_class_default
@@ -2,6 +2,7 @@
2
2
 
3
3
  Sequel::JDBC.load_driver('org.apache.derby.jdbc.EmbeddedDriver', :Derby)
4
4
  require_relative 'transactions'
5
+ require_relative '../utils/columns_limit_1'
5
6
 
6
7
  module Sequel
7
8
  module JDBC
@@ -182,6 +183,8 @@ module Sequel
182
183
  end
183
184
 
184
185
  class Dataset < JDBC::Dataset
186
+ include ::Sequel::Dataset::ColumnsLimit1
187
+
185
188
  # Derby doesn't support an expression between CASE and WHEN,
186
189
  # so remove conditions.
187
190
  def case_expression_sql_append(sql, ce)
@@ -232,6 +235,11 @@ module Sequel
232
235
  false
233
236
  end
234
237
 
238
+ # Derby 10.11+ supports MERGE.
239
+ def supports_merge?
240
+ db.svn_version >= 1616546
241
+ end
242
+
235
243
  # Derby does not support IN/NOT IN with multiple columns
236
244
  def supports_multiple_column_in?
237
245
  false
@@ -1,6 +1,7 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  Sequel::JDBC.load_driver('org.h2.Driver', :H2)
4
+ require_relative '../../extensions/auto_cast_date_and_time'
4
5
 
5
6
  module Sequel
6
7
  module JDBC
@@ -14,6 +15,8 @@ module Sequel
14
15
 
15
16
  module H2
16
17
  module DatabaseMethods
18
+ include AutoCastDateAndTime
19
+
17
20
  def commit_prepared_transaction(transaction_id, opts=OPTS)
18
21
  run("COMMIT TRANSACTION #{transaction_id}", opts)
19
22
  end
@@ -24,6 +27,7 @@ module Sequel
24
27
 
25
28
  def freeze
26
29
  h2_version
30
+ version2?
27
31
  super
28
32
  end
29
33
 
@@ -140,13 +144,36 @@ module Sequel
140
144
  DATABASE_ERROR_REGEXPS
141
145
  end
142
146
 
143
- # Use IDENTITY() to get the last inserted id.
147
+ def execute_statement_insert(stmt, sql)
148
+ stmt.executeUpdate(sql, JavaSQL::Statement::RETURN_GENERATED_KEYS)
149
+ end
150
+
151
+ def prepare_jdbc_statement(conn, sql, opts)
152
+ opts[:type] == :insert ? conn.prepareStatement(sql, JavaSQL::Statement::RETURN_GENERATED_KEYS) : super
153
+ end
154
+
155
+ # Get the last inserted id using getGeneratedKeys, scope_identity, or identity.
144
156
  def last_insert_id(conn, opts=OPTS)
145
- statement(conn) do |stmt|
146
- sql = 'SELECT IDENTITY();'
147
- rs = log_connection_yield(sql, conn){stmt.executeQuery(sql)}
148
- rs.next
149
- rs.getLong(1)
157
+ if stmt = opts[:stmt]
158
+ rs = stmt.getGeneratedKeys
159
+ begin
160
+ if rs.next
161
+ begin
162
+ rs.getLong(1)
163
+ rescue
164
+ rs.getObject(1) rescue nil
165
+ end
166
+ end
167
+ ensure
168
+ rs.close
169
+ end
170
+ elsif !version2?
171
+ statement(conn) do |stmt|
172
+ sql = 'SELECT IDENTITY()'
173
+ rs = log_connection_yield(sql, conn){stmt.executeQuery(sql)}
174
+ rs.next
175
+ rs.getLong(1)
176
+ end
150
177
  end
151
178
  end
152
179
 
@@ -161,7 +188,12 @@ module Sequel
161
188
 
162
189
  # Use BIGINT IDENTITY for identity columns that use :Bignum type
163
190
  def type_literal_generic_bignum_symbol(column)
164
- column[:identity] ? 'BIGINT IDENTITY' : super
191
+ column[:identity] ? 'BIGINT AUTO_INCREMENT' : super
192
+ end
193
+
194
+ def version2?
195
+ return @version2 if defined?(@version2)
196
+ @version2 = h2_version.to_i >= 2
165
197
  end
166
198
  end
167
199
 
@@ -200,6 +232,11 @@ module Sequel
200
232
  false
201
233
  end
202
234
 
235
+ # H2 supports MERGE
236
+ def supports_merge?
237
+ true
238
+ end
239
+
203
240
  # H2 doesn't support multiple columns in IN/NOT IN
204
241
  def supports_multiple_column_in?
205
242
  false
@@ -209,9 +246,21 @@ module Sequel
209
246
 
210
247
  # H2 expects hexadecimal strings for blob values
211
248
  def literal_blob_append(sql, v)
212
- sql << "'" << v.unpack("H*").first << "'"
249
+ if db.send(:version2?)
250
+ super
251
+ else
252
+ sql << "'" << v.unpack("H*").first << "'"
253
+ end
254
+ end
255
+
256
+ def literal_false
257
+ 'FALSE'
213
258
  end
214
259
 
260
+ def literal_true
261
+ 'TRUE'
262
+ end
263
+
215
264
  # H2 handles fractional seconds in timestamps, but not in times
216
265
  def literal_sqltime(v)
217
266
  v.strftime("'%H:%M:%S'")
@@ -223,8 +272,12 @@ module Sequel
223
272
  end
224
273
 
225
274
  def select_only_offset_sql(sql)
226
- sql << " LIMIT -1 OFFSET "
227
- literal_append(sql, @opts[:offset])
275
+ if db.send(:version2?)
276
+ super
277
+ else
278
+ sql << " LIMIT -1 OFFSET "
279
+ literal_append(sql, @opts[:offset])
280
+ end
228
281
  end
229
282
 
230
283
  # H2 supports quoted function names.
@@ -2,6 +2,7 @@
2
2
 
3
3
  Sequel::JDBC.load_driver('org.hsqldb.jdbcDriver', :HSQLDB)
4
4
  require_relative 'transactions'
5
+ require_relative '../../extensions/auto_cast_date_and_time'
5
6
 
6
7
  module Sequel
7
8
  module JDBC
@@ -15,6 +16,7 @@ module Sequel
15
16
 
16
17
  module HSQLDB
17
18
  module DatabaseMethods
19
+ include AutoCastDateAndTime
18
20
  include ::Sequel::JDBC::Transactions
19
21
 
20
22
  def database_type
@@ -179,6 +181,12 @@ module Sequel
179
181
  true
180
182
  end
181
183
 
184
+ # HSQLDB 2.3.4+ supports MERGE. Older versions also support MERGE, but not all
185
+ # features that are in Sequel's tests.
186
+ def supports_merge?
187
+ db.db_version >= 20304
188
+ end
189
+
182
190
  private
183
191
 
184
192
  def empty_from_sql
@@ -35,9 +35,9 @@ module Sequel
35
35
  data = opts[:data]
36
36
  data = Array(data) if data.is_a?(String)
37
37
 
38
- if block_given? && data
38
+ if defined?(yield) && data
39
39
  raise Error, "Cannot provide both a :data option and a block to copy_into"
40
- elsif !block_given? && !data
40
+ elsif !defined?(yield) && !data
41
41
  raise Error, "Must provide either a :data option or a block to copy_into"
42
42
  end
43
43
 
@@ -45,7 +45,7 @@ module Sequel
45
45
  begin
46
46
  copy_manager = org.postgresql.copy.CopyManager.new(conn)
47
47
  copier = copy_manager.copy_in(copy_into_sql(table, opts))
48
- if block_given?
48
+ if defined?(yield)
49
49
  while buf = yield
50
50
  java_bytes = buf.to_java_bytes
51
51
  copier.writeToCopy(java_bytes, 0, java_bytes.length)
@@ -77,7 +77,7 @@ module Sequel
77
77
  copy_manager = org.postgresql.copy.CopyManager.new(conn)
78
78
  copier = copy_manager.copy_out(copy_table_sql(table, opts))
79
79
  begin
80
- if block_given?
80
+ if defined?(yield)
81
81
  while buf = copier.readFromCopy
82
82
  yield(String.from_java_bytes(buf))
83
83
  end
@@ -199,6 +199,7 @@ module Sequel
199
199
  v.strftime("'%H:%M:%S#{sprintf(".%03d", (v.usec/1000.0).round)}'")
200
200
  end
201
201
 
202
+ INTEGER_TYPE = Java::JavaSQL::Types::INTEGER
202
203
  STRING_TYPE = Java::JavaSQL::Types::VARCHAR
203
204
  ARRAY_TYPE = Java::JavaSQL::Types::ARRAY
204
205
  PG_SPECIFIC_TYPES = [Java::JavaSQL::Types::ARRAY, Java::JavaSQL::Types::OTHER, Java::JavaSQL::Types::STRUCT, Java::JavaSQL::Types::TIME_WITH_TIMEZONE, Java::JavaSQL::Types::TIME].freeze
@@ -219,6 +220,8 @@ module Sequel
219
220
  oid = meta.getField(i).getOID
220
221
  if pr = db.oid_convertor_proc(oid)
221
222
  pr
223
+ elsif oid == 28 # XID (Transaction ID)
224
+ map[INTEGER_TYPE]
222
225
  elsif oid == 2950 # UUID
223
226
  map[STRING_TYPE]
224
227
  elsif meta.getPGType(i) == 'hstore'
@@ -36,6 +36,10 @@ module Sequel
36
36
 
37
37
  private
38
38
 
39
+ def database_exception_use_sqlstates?
40
+ false
41
+ end
42
+
39
43
  # Use @@IDENTITY to get the last inserted id
40
44
  def last_insert_id(conn, opts=OPTS)
41
45
  statement(conn) do |stmt|
@@ -52,6 +56,17 @@ module Sequel
52
56
 
53
57
  private
54
58
 
59
+ # JDBC SQLAnywhere driver does not appear to handle fractional
60
+ # times correctly.
61
+ def default_time_format
62
+ "'%H:%M:%S'"
63
+ end
64
+
65
+ # Set to zero to work around JDBC SQLAnywhere driver bug.
66
+ def sqltime_precision
67
+ 0
68
+ end
69
+
55
70
  SMALLINT_TYPE = Java::JavaSQL::Types::SMALLINT
56
71
  BOOLEAN_METHOD = Object.new
57
72
  def BOOLEAN_METHOD.call(r, i)
@@ -79,6 +79,10 @@ module Sequel
79
79
  super.with_extend(MetadataDatasetMethods)
80
80
  end
81
81
 
82
+ def database_exception_use_sqlstates?
83
+ false
84
+ end
85
+
82
86
  def disconnect_error?(exception, opts)
83
87
  super || (exception.message =~ /connection is closed/)
84
88
  end
@@ -32,15 +32,13 @@ module Sequel
32
32
 
33
33
  # Allow loading the necessary JDBC support via a gem.
34
34
  def self.load_gem(name)
35
- begin
36
- require "jdbc/#{name.to_s.downcase}"
37
- rescue LoadError
38
- # jdbc gem not used, hopefully the user has the .jar in their CLASSPATH
39
- else
40
- if defined?(::Jdbc) && ( ::Jdbc.const_defined?(name) rescue nil )
41
- jdbc_module = ::Jdbc.const_get(name) # e.g. Jdbc::SQLite3
42
- jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
43
- end
35
+ require "jdbc/#{name.to_s.downcase}"
36
+ rescue LoadError
37
+ # jdbc gem not used, hopefully the user has the .jar in their CLASSPATH
38
+ else
39
+ if defined?(::Jdbc) && ( ::Jdbc.const_defined?(name) rescue nil )
40
+ jdbc_module = ::Jdbc.const_get(name) # e.g. Jdbc::SQLite3
41
+ jdbc_module.load_driver if jdbc_module.respond_to?(:load_driver)
44
42
  end
45
43
  end
46
44
 
@@ -190,13 +188,13 @@ module Sequel
190
188
  args = opts[:args] || []
191
189
  sql = "{call #{name}(#{args.map{'?'}.join(',')})}"
192
190
  synchronize(opts[:server]) do |conn|
193
- cps = conn.prepareCall(sql)
191
+ begin
192
+ cps = conn.prepareCall(sql)
194
193
 
195
- i = 0
196
- args.each{|arg| set_ps_arg(cps, arg, i+=1)}
194
+ i = 0
195
+ args.each{|arg| set_ps_arg(cps, arg, i+=1)}
197
196
 
198
- begin
199
- if block_given?
197
+ if defined?(yield)
200
198
  yield log_connection_yield(sql, conn){cps.executeQuery}
201
199
  else
202
200
  log_connection_yield(sql, conn){cps.executeUpdate}
@@ -207,7 +205,7 @@ module Sequel
207
205
  rescue *DATABASE_ERROR_CLASSES => e
208
206
  raise_error(e)
209
207
  ensure
210
- cps.close
208
+ cps.close if cps
211
209
  end
212
210
  end
213
211
  end
@@ -398,11 +396,16 @@ module Sequel
398
396
 
399
397
  def database_exception_sqlstate(exception, opts)
400
398
  if database_exception_use_sqlstates?
401
- while exception.respond_to?(:cause)
402
- exception = exception.cause
403
- return exception.getSQLState if exception.respond_to?(:getSQLState)
404
- end
399
+ _database_exception_sqlstate(exception, opts)
405
400
  end
401
+ end
402
+
403
+ def _database_exception_sqlstate(exception, opts)
404
+ 16.times do
405
+ return exception.getSQLState if exception.respond_to?(:getSQLState)
406
+ break unless exception.respond_to?(:cause) && (exception = exception.cause)
407
+ end
408
+
406
409
  nil
407
410
  end
408
411
 
@@ -417,8 +420,7 @@ module Sequel
417
420
 
418
421
  # Raise a disconnect error if the SQL state of the cause of the exception indicates so.
419
422
  def disconnect_error?(exception, opts)
420
- cause = exception.respond_to?(:cause) ? exception.cause : exception
421
- super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
423
+ super || (_database_exception_sqlstate(exception, opts) =~ /^08/)
422
424
  end
423
425
 
424
426
  # Execute the prepared statement. If the provided name is a
@@ -461,7 +463,7 @@ module Sequel
461
463
  msg << ")"
462
464
  end
463
465
  begin
464
- if block_given?
466
+ if defined?(yield)
465
467
  yield log_connection_yield(msg, conn, args){cps.executeQuery}
466
468
  else
467
469
  case opts[:type]