sequel 3.21.0 → 3.39.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 (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
@@ -0,0 +1,325 @@
1
+ Sequel.require 'adapters/jdbc/transactions'
2
+
3
+ module Sequel
4
+ module JDBC
5
+ # Database and Dataset support for Derby databases accessed via JDBC.
6
+ module Derby
7
+ # Instance methods for Derby Database objects accessed via JDBC.
8
+ module DatabaseMethods
9
+ PRIMARY_KEY_INDEX_RE = /\Asql\d+\z/i.freeze
10
+
11
+ include ::Sequel::JDBC::Transactions
12
+
13
+ # Derby doesn't support casting integer to varchar, only integer to char,
14
+ # and char(254) appears to have the widest support (with char(255) failing).
15
+ # This does add a bunch of extra spaces at the end, but those will be trimmed
16
+ # elsewhere.
17
+ def cast_type_literal(type)
18
+ (type == String) ? 'CHAR(254)' : super
19
+ end
20
+
21
+ # Derby uses the :derby database type.
22
+ def database_type
23
+ :derby
24
+ end
25
+
26
+ # Derby uses an IDENTITY sequence for autoincrementing columns.
27
+ def serial_primary_key_options
28
+ {:primary_key => true, :type => :integer, :identity=>true, :start_with=>1}
29
+ end
30
+
31
+ # The SVN version of the database.
32
+ def svn_version
33
+ @svn_version ||= begin
34
+ v = synchronize{|c| c.get_meta_data.get_database_product_version}
35
+ v =~ /\((\d+)\)\z/
36
+ $1.to_i
37
+ end
38
+ end
39
+
40
+ # Derby supports transaction DDL statements.
41
+ def supports_transactional_ddl?
42
+ true
43
+ end
44
+
45
+ private
46
+
47
+ # Derby optimizes away Sequel's default check of SELECT NULL FROM table,
48
+ # so use a SELECT * FROM table there.
49
+ def _table_exists?(ds)
50
+ ds.first
51
+ end
52
+
53
+ # Derby-specific syntax for renaming columns and changing a columns type/nullity.
54
+ def alter_table_sql(table, op)
55
+ case op[:op]
56
+ when :rename_column
57
+ "RENAME COLUMN #{quote_schema_table(table)}.#{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
58
+ when :set_column_type
59
+ # Derby is very limited in changing a columns type, so adding a new column and then dropping the existing column is
60
+ # the best approach, as mentioned in the Derby documentation.
61
+ temp_name = :x_sequel_temp_column_x
62
+ [alter_table_sql(table, op.merge(:op=>:add_column, :name=>temp_name)),
63
+ from(table).update_sql(temp_name=>::Sequel::SQL::Cast.new(op[:name], op[:type])),
64
+ alter_table_sql(table, op.merge(:op=>:drop_column)),
65
+ alter_table_sql(table, op.merge(:op=>:rename_column, :name=>temp_name, :new_name=>op[:name]))]
66
+ when :set_column_null
67
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{op[:null] ? 'NULL' : 'NOT NULL'}"
68
+ else
69
+ super
70
+ end
71
+ end
72
+
73
+ # Derby doesn't allow specifying NULL for columns, only NOT NULL.
74
+ def column_definition_null_sql(sql, column)
75
+ sql << " NOT NULL" if column.fetch(:null, column[:allow_null]) == false
76
+ end
77
+
78
+ # Add NOT LOGGED for temporary tables to improve performance.
79
+ def create_table_sql(name, generator, options)
80
+ s = super
81
+ s << ' NOT LOGGED' if options[:temp]
82
+ s
83
+ end
84
+
85
+ # Insert data from the current table into the new table after
86
+ # creating the table, since it is not possible to do it in one step.
87
+ def create_table_as(name, sql, options)
88
+ super
89
+ from(name).insert(sql.is_a?(Dataset) ? sql : dataset.with_sql(sql))
90
+ end
91
+
92
+ # Derby currently only requires WITH NO DATA, with a separate insert
93
+ # to import data.
94
+ def create_table_as_sql(name, sql, options)
95
+ "#{create_table_prefix_sql(name, options)} AS #{sql} WITH NO DATA"
96
+ end
97
+
98
+ # Temporary table creation on Derby uses DECLARE instead of CREATE.
99
+ def create_table_prefix_sql(name, options)
100
+ if options[:temp]
101
+ "DECLARE GLOBAL TEMPORARY TABLE #{quote_identifier(name)}"
102
+ else
103
+ super
104
+ end
105
+ end
106
+
107
+ # Use IDENTITY_VAL_LOCAL() to get the last inserted id.
108
+ def last_insert_id(conn, opts={})
109
+ statement(conn) do |stmt|
110
+ sql = 'SELECT IDENTITY_VAL_LOCAL() FROM sysibm.sysdummy1'
111
+ rs = log_yield(sql){stmt.executeQuery(sql)}
112
+ rs.next
113
+ rs.getInt(1)
114
+ end
115
+ end
116
+
117
+ # Handle nil values by using setNull with the correct parameter type.
118
+ def set_ps_arg_nil(cps, i)
119
+ cps.setNull(i, cps.getParameterMetaData.getParameterType(i))
120
+ end
121
+
122
+ # Derby uses RENAME TABLE syntax to rename tables.
123
+ def rename_table_sql(name, new_name)
124
+ "RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
125
+ end
126
+
127
+ # Primary key indexes appear to be named sqlNNNN on Derby
128
+ def primary_key_index_re
129
+ PRIMARY_KEY_INDEX_RE
130
+ end
131
+
132
+ # Treat clob as string instead of blob
133
+ def schema_column_type(db_type)
134
+ db_type.downcase == 'clob' ? :string : super
135
+ end
136
+
137
+ # If an :identity option is present in the column, add the necessary IDENTITY SQL.
138
+ def type_literal(column)
139
+ if column[:identity]
140
+ sql = "#{super} GENERATED BY DEFAULT AS IDENTITY"
141
+ if sw = column[:start_with]
142
+ sql << " (START WITH #{sw.to_i}"
143
+ sql << " INCREMENT BY #{column[:increment_by].to_i}" if column[:increment_by]
144
+ sql << ")"
145
+ end
146
+ sql
147
+ else
148
+ super
149
+ end
150
+ end
151
+ end
152
+
153
+ # Dataset class for Derby datasets accessed via JDBC.
154
+ class Dataset < JDBC::Dataset
155
+ PAREN_CLOSE = Dataset::PAREN_CLOSE
156
+ PAREN_OPEN = Dataset::PAREN_OPEN
157
+ OFFSET = Dataset::OFFSET
158
+ CAST_STRING_OPEN = "RTRIM(".freeze
159
+ BITCOMP_OPEN = "((0 - ".freeze
160
+ BITCOMP_CLOSE = ") - 1)".freeze
161
+ BLOB_OPEN = "CAST(X'".freeze
162
+ BLOB_CLOSE = "' AS BLOB)".freeze
163
+ HSTAR = "H*".freeze
164
+ TIME_FORMAT = "'%H:%M:%S'".freeze
165
+ DEFAULT_FROM = " FROM sysibm.sysdummy1".freeze
166
+ ROWS = " ROWS".freeze
167
+ FETCH_FIRST = " FETCH FIRST ".freeze
168
+ ROWS_ONLY = " ROWS ONLY".freeze
169
+ BOOL_TRUE_OLD = '(1 = 1)'.freeze
170
+ BOOL_FALSE_OLD = '(1 = 0)'.freeze
171
+ BOOL_TRUE = 'TRUE'.freeze
172
+ BOOL_FALSE = 'FALSE'.freeze
173
+ SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit lock')
174
+ EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
175
+
176
+ # Derby doesn't support an expression between CASE and WHEN,
177
+ # so emulate it by using an equality statement for all of the
178
+ # conditions.
179
+ def case_expression_sql_append(sql, ce)
180
+ if ce.expression?
181
+ e = ce.expression
182
+ case_expression_sql_append(sql, ::Sequel::SQL::CaseExpression.new(ce.conditions.map{|c, r| [::Sequel::SQL::BooleanExpression.new(:'=', e, c), r]}, ce.default))
183
+ else
184
+ super
185
+ end
186
+ end
187
+
188
+ # If the type is String, trim the extra spaces since CHAR is used instead
189
+ # of varchar. This can cause problems if you are casting a char/varchar to
190
+ # a string and the ending whitespace is important.
191
+ def cast_sql_append(sql, expr, type)
192
+ if type == String
193
+ sql << CAST_STRING_OPEN
194
+ super
195
+ sql << PAREN_CLOSE
196
+ else
197
+ super
198
+ end
199
+ end
200
+
201
+ # Handle Derby specific LIKE, extract, and some bitwise compliment support.
202
+ def complex_expression_sql_append(sql, op, args)
203
+ case op
204
+ when :ILIKE
205
+ super(sql, :LIKE, [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1))])
206
+ when :"NOT ILIKE"
207
+ super(sql, :"NOT LIKE", [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1))])
208
+ when :%
209
+ sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
210
+ when :&, :|, :^, :<<, :>>
211
+ raise Error, "Derby doesn't support the #{op} operator"
212
+ when :'B~'
213
+ sql << BITCOMP_OPEN
214
+ literal_append(sql, args.at(0))
215
+ sql << BITCOMP_CLOSE
216
+ when :extract
217
+ sql << args.at(0).to_s << PAREN_OPEN
218
+ literal_append(sql, args.at(1))
219
+ sql << PAREN_CLOSE
220
+ else
221
+ super
222
+ end
223
+ end
224
+
225
+ # Derby supports GROUP BY ROLLUP (but not CUBE)
226
+ def supports_group_rollup?
227
+ true
228
+ end
229
+
230
+ # Derby does not support IS TRUE.
231
+ def supports_is_true?
232
+ false
233
+ end
234
+
235
+ # Derby does not support IN/NOT IN with multiple columns
236
+ def supports_multiple_column_in?
237
+ false
238
+ end
239
+
240
+ private
241
+
242
+ JAVA_SQL_CLOB = Java::JavaSQL::Clob
243
+
244
+ class ::Sequel::JDBC::Dataset::TYPE_TRANSLATOR
245
+ def derby_clob(v) v.getSubString(1, v.length) end
246
+ end
247
+
248
+ DERBY_CLOB_METHOD = TYPE_TRANSLATOR_INSTANCE.method(:derby_clob)
249
+
250
+ # Handle clobs on Derby as strings.
251
+ def convert_type_proc(v)
252
+ if v.is_a?(JAVA_SQL_CLOB)
253
+ DERBY_CLOB_METHOD
254
+ else
255
+ super
256
+ end
257
+ end
258
+
259
+ # Derby needs a hex string casted to BLOB for blobs.
260
+ def literal_blob_append(sql, v)
261
+ sql << BLOB_OPEN << v.unpack(HSTAR).first << BLOB_CLOSE
262
+ end
263
+
264
+ # Derby needs the standard workaround to insert all default values into
265
+ # a table with more than one column.
266
+ def insert_supports_empty_values?
267
+ false
268
+ end
269
+
270
+ # Derby uses an expression yielding false for false values.
271
+ # Newer versions can use the FALSE literal, but the latest gem version cannot.
272
+ def literal_false
273
+ if db.svn_version >= 1040133
274
+ BOOL_FALSE
275
+ else
276
+ BOOL_FALSE_OLD
277
+ end
278
+ end
279
+
280
+ # Derby handles fractional seconds in timestamps, but not in times
281
+ def literal_sqltime(v)
282
+ v.strftime(TIME_FORMAT)
283
+ end
284
+
285
+ # Derby uses an expression yielding true for true values.
286
+ # Newer versions can use the TRUE literal, but the latest gem version cannot.
287
+ def literal_true
288
+ if db.svn_version >= 1040133
289
+ BOOL_TRUE
290
+ else
291
+ BOOL_TRUE_OLD
292
+ end
293
+ end
294
+
295
+ # Derby doesn't support common table expressions.
296
+ def select_clause_methods
297
+ SELECT_CLAUSE_METHODS
298
+ end
299
+
300
+ # Use a default FROM table if the dataset does not contain a FROM table.
301
+ def select_from_sql(sql)
302
+ if @opts[:from]
303
+ super
304
+ else
305
+ sql << DEFAULT_FROM
306
+ end
307
+ end
308
+
309
+ # Offset comes before limit in Derby
310
+ def select_limit_sql(sql)
311
+ if o = @opts[:offset]
312
+ sql << OFFSET
313
+ literal_append(sql, o)
314
+ sql << ROWS
315
+ end
316
+ if l = @opts[:limit]
317
+ sql << FETCH_FIRST
318
+ literal_append(sql, l)
319
+ sql << ROWS_ONLY
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end
325
+ end
@@ -0,0 +1,24 @@
1
+ Sequel.require 'adapters/shared/firebird'
2
+ Sequel.require 'adapters/jdbc/transactions'
3
+
4
+ module Sequel
5
+ module JDBC
6
+ # Database and Dataset instance methods for Firebird specific
7
+ # support via JDBC.
8
+ module Firebird
9
+ # Database instance methods for Firebird databases accessed via JDBC.
10
+ module DatabaseMethods
11
+ include Sequel::Firebird::DatabaseMethods
12
+ include Sequel::JDBC::Transactions
13
+
14
+ # Add the primary_keys and primary_key_sequences instance variables,
15
+ # so we can get the correct return values for inserted rows.
16
+ def self.extended(db)
17
+ db.instance_eval do
18
+ @primary_keys = {}
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -17,11 +17,6 @@ module Sequel
17
17
  :h2
18
18
  end
19
19
 
20
- # Return Sequel::JDBC::H2::Dataset object with the given opts.
21
- def dataset(opts=nil)
22
- Sequel::JDBC::H2::Dataset.new(self, opts)
23
- end
24
-
25
20
  # Rollback an existing prepared transaction with the given transaction
26
21
  # identifier string.
27
22
  def rollback_prepared_transaction(transaction_id)
@@ -30,9 +25,14 @@ module Sequel
30
25
 
31
26
  # H2 uses an IDENTITY type
32
27
  def serial_primary_key_options
33
- {:primary_key => true, :type => :identity}
28
+ {:primary_key => true, :type => :identity, :identity=>true}
34
29
  end
35
30
 
31
+ # H2 supports CREATE TABLE IF NOT EXISTS syntax.
32
+ def supports_create_table_if_not_exists?
33
+ true
34
+ end
35
+
36
36
  # H2 supports prepared transactions
37
37
  def supports_prepared_transactions?
38
38
  true
@@ -48,8 +48,8 @@ module Sequel
48
48
  # If the :prepare option is given and we aren't in a savepoint,
49
49
  # prepare the transaction for a two-phase commit.
50
50
  def commit_transaction(conn, opts={})
51
- if opts[:prepare] && Thread.current[:sequel_transaction_depth] <= 1
52
- log_connection_execute(conn, "PREPARE COMMIT #{opts[:prepare]}")
51
+ if (s = opts[:prepare]) && _trans(conn)[:savepoint_level] <= 1
52
+ log_connection_execute(conn, "PREPARE COMMIT #{s}")
53
53
  else
54
54
  super
55
55
  end
@@ -75,7 +75,16 @@ module Sequel
75
75
  when :set_column_null
76
76
  "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET#{' NOT' unless op[:null]} NULL"
77
77
  when :set_column_type
78
- "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(op)}"
78
+ if sch = schema(table)
79
+ if cs = sch.each{|k, v| break v if k == op[:name]; nil}
80
+ cs = cs.dup
81
+ cs[:default] = cs[:ruby_default]
82
+ op = cs.merge!(op)
83
+ end
84
+ end
85
+ sql = "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(op)}"
86
+ column_definition_order.each{|m| send(:"column_definition_#{m}_sql", sql, op)}
87
+ sql
79
88
  else
80
89
  super(table, op)
81
90
  end
@@ -90,7 +99,8 @@ module Sequel
90
99
  # Use IDENTITY() to get the last inserted id.
91
100
  def last_insert_id(conn, opts={})
92
101
  statement(conn) do |stmt|
93
- rs = stmt.executeQuery('SELECT IDENTITY();')
102
+ sql = 'SELECT IDENTITY();'
103
+ rs = log_yield(sql){stmt.executeQuery(sql)}
94
104
  rs.next
95
105
  rs.getInt(1)
96
106
  end
@@ -99,28 +109,47 @@ module Sequel
99
109
  def primary_key_index_re
100
110
  PRIMARY_KEY_INDEX_RE
101
111
  end
112
+
113
+ # Treat clob as string instead of blob
114
+ def schema_column_type(db_type)
115
+ db_type.downcase == 'clob' ? :string : super
116
+ end
117
+
118
+ # Use BIGINT IDENTITY for identity columns that use bigint, fixes
119
+ # the case where primary_key :column, :type=>Bignum is used.
120
+ def type_literal_generic_bignum(column)
121
+ column[:identity] ? 'BIGINT IDENTITY' : super
122
+ end
102
123
  end
103
124
 
104
125
  # Dataset class for H2 datasets accessed via JDBC.
105
126
  class Dataset < JDBC::Dataset
106
- SELECT_CLAUSE_METHODS = clause_methods(:select, %w'distinct columns from join where group having compounds order limit')
127
+ SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit')
107
128
  BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR}
129
+ APOS = Dataset::APOS
130
+ HSTAR = "H*".freeze
131
+ BITCOMP_OPEN = "((0 - ".freeze
132
+ BITCOMP_CLOSE = ") - 1)".freeze
133
+ ILIKE_PLACEHOLDER = ["CAST(".freeze, " AS VARCHAR_IGNORECASE)".freeze].freeze
134
+ TIME_FORMAT = "'%H:%M:%S'".freeze
108
135
 
109
- # Work around H2's lack of a case insensitive LIKE operator
110
- def complex_expression_sql(op, args)
136
+ # Emulate the case insensitive LIKE operator and the bitwise operators.
137
+ def complex_expression_sql_append(sql, op, args)
111
138
  case op
112
- when :ILIKE
113
- super(:LIKE, [SQL::PlaceholderLiteralString.new("CAST(? AS VARCHAR_IGNORECASE)", [args.at(0)]), args.at(1)])
114
- when :"NOT ILIKE"
115
- super(:"NOT LIKE", [SQL::PlaceholderLiteralString.new("CAST(? AS VARCHAR_IGNORECASE)", [args.at(0)]), args.at(1)])
139
+ when :ILIKE, :"NOT ILIKE"
140
+ super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), [SQL::PlaceholderLiteralString.new(ILIKE_PLACEHOLDER, [args.at(0)]), args.at(1)])
116
141
  when :&, :|, :^
117
- literal(SQL::Function.new(BITWISE_METHOD_MAP[op], *args))
142
+ sql << complex_expression_arg_pairs(args){|a, b| literal(SQL::Function.new(BITWISE_METHOD_MAP[op], a, b))}
118
143
  when :<<
119
- "(#{literal(args[0])} * POWER(2, #{literal(args[1])}))"
144
+ sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * POWER(2, #{literal(b)}))"}
120
145
  when :>>
121
- "(#{literal(args[0])} / POWER(2, #{literal(args[1])}))"
146
+ sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / POWER(2, #{literal(b)}))"}
147
+ when :'B~'
148
+ sql << BITCOMP_OPEN
149
+ literal_append(sql, args.at(0))
150
+ sql << BITCOMP_CLOSE
122
151
  else
123
- super(op, args)
152
+ super
124
153
  end
125
154
  end
126
155
 
@@ -145,21 +174,34 @@ module Sequel
145
174
  end
146
175
 
147
176
  private
148
-
149
- # H2 expects hexadecimal strings for blob values
150
- def literal_blob(v)
151
- literal_string v.unpack("H*").first
177
+
178
+ #JAVA_H2_CLOB = Java::OrgH2Jdbc::JdbcClob
179
+
180
+ class ::Sequel::JDBC::Dataset::TYPE_TRANSLATOR
181
+ def h2_clob(v) v.getSubString(1, v.length) end
152
182
  end
153
-
154
- def convert_type(v)
155
- case v
156
- when Java::OrgH2Jdbc::JdbcClob
157
- convert_type(v.getSubString(1, v.length))
183
+
184
+ H2_CLOB_METHOD = TYPE_TRANSLATOR_INSTANCE.method(:h2_clob)
185
+
186
+ # Handle H2 specific clobs as strings.
187
+ def convert_type_proc(v)
188
+ if v.is_a?(Java::OrgH2Jdbc::JdbcClob)
189
+ H2_CLOB_METHOD
158
190
  else
159
- super(v)
191
+ super
160
192
  end
161
193
  end
162
194
 
195
+ # H2 expects hexadecimal strings for blob values
196
+ def literal_blob_append(sql, v)
197
+ sql << APOS << v.unpack(HSTAR).first << APOS
198
+ end
199
+
200
+ # H2 handles fractional seconds in timestamps, but not in times
201
+ def literal_sqltime(v)
202
+ v.strftime(TIME_FORMAT)
203
+ end
204
+
163
205
  def select_clause_methods
164
206
  SELECT_CLAUSE_METHODS
165
207
  end