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
@@ -1,21 +1,17 @@
1
1
  module Sequel
2
2
  module Access
3
3
  module DatabaseMethods
4
+ # Access uses type :access as the database_type
4
5
  def database_type
5
6
  :access
6
7
  end
7
8
 
8
- def dataset(opts = nil)
9
- ds = super
10
- ds.extend(DatasetMethods)
11
- ds
12
- end
13
-
14
9
  # Doesn't work, due to security restrictions on MSysObjects
15
10
  def tables
16
11
  from(:MSysObjects).filter(:Type=>1, :Flags=>0).select_map(:Name).map{|x| x.to_sym}
17
12
  end
18
13
 
14
+ # Access uses type Counter for an autoincrementing keys
19
15
  def serial_primary_key_options
20
16
  {:primary_key => true, :type=>:Counter}
21
17
  end
@@ -32,18 +28,45 @@ module Sequel
32
28
  end
33
29
 
34
30
  module DatasetMethods
35
- SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'limit distinct columns from join where group order having compounds')
31
+ SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'select limit distinct columns from join where group order having compounds')
32
+ DATE_FORMAT = '#%Y-%m-%d#'.freeze
33
+ TIMESTAMP_FORMAT = '#%Y-%m-%d %H:%M:%S#'.freeze
34
+ TOP = " TOP ".freeze
35
+ BRACKET_CLOSE = Dataset::BRACKET_CLOSE
36
+ BRACKET_OPEN = Dataset::BRACKET_OPEN
36
37
 
38
+ # Access doesn't support INTERSECT or EXCEPT
37
39
  def supports_intersect_except?
38
40
  false
39
41
  end
40
42
 
41
43
  private
42
44
 
43
- def quoted_identifier(v)
44
- "[#{v}]"
45
+ # Access uses # to quote dates
46
+ def literal_date(d)
47
+ d.strftime(DATE_FORMAT)
48
+ end
49
+
50
+ # Access uses # to quote datetimes
51
+ def literal_datetime(t)
52
+ t.strftime(TIMESTAMP_FORMAT)
53
+ end
54
+ alias literal_time literal_datetime
55
+
56
+ # Access uses TOP for limits
57
+ def select_limit_sql(sql)
58
+ if l = @opts[:limit]
59
+ sql << TOP
60
+ literal_append(sql, l)
61
+ end
62
+ end
63
+
64
+ # Access uses [] for quoting identifiers
65
+ def quoted_identifier_append(sql, v)
66
+ sql << BRACKET_OPEN << v.to_s << BRACKET_CLOSE
45
67
  end
46
68
 
69
+ # Access requires the limit clause come before other clauses
47
70
  def select_clause_methods
48
71
  SELECT_CLAUSE_METHODS
49
72
  end
@@ -0,0 +1,343 @@
1
+ Sequel.require 'adapters/utils/emulate_offset_with_row_number'
2
+
3
+ module Sequel
4
+ module DB2
5
+ @use_clob_as_blob = true
6
+
7
+ class << self
8
+ # Whether to use clob as the generic File type, true by default.
9
+ attr_accessor :use_clob_as_blob
10
+ end
11
+
12
+ module DatabaseMethods
13
+ AUTOINCREMENT = 'GENERATED ALWAYS AS IDENTITY'.freeze
14
+ NOT_NULL = ' NOT NULL'.freeze
15
+ NULL = ''.freeze
16
+
17
+ # DB2 always uses :db2 as it's database type
18
+ def database_type
19
+ :db2
20
+ end
21
+
22
+ # Return the database version as a string. Don't rely on this,
23
+ # it may return an integer in the future.
24
+ def db2_version
25
+ return @db2_version if @db2_version
26
+ @db2_version = metadata_dataset.with_sql("select service_level from sysibmadm.env_inst_info").first[:service_level]
27
+ end
28
+ alias_method :server_version, :db2_version
29
+
30
+ # Use SYSIBM.SYSCOLUMNS to get the information on the tables.
31
+ def schema_parse_table(table, opts = {})
32
+ m = output_identifier_meth(opts[:dataset])
33
+ im = input_identifier_meth(opts[:dataset])
34
+ metadata_dataset.with_sql("SELECT * FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = #{literal(im.call(table))} ORDER BY COLNO").
35
+ collect do |column|
36
+ column[:db_type] = column.delete(:typename)
37
+ if column[:db_type] == "DECIMAL"
38
+ column[:db_type] << "(#{column[:longlength]},#{column[:scale]})"
39
+ end
40
+ column[:allow_null] = column.delete(:nulls) == 'Y'
41
+ column[:primary_key] = column.delete(:identity) == 'Y' || !column[:keyseq].nil?
42
+ column[:type] = schema_column_type(column[:db_type])
43
+ [ m.call(column.delete(:name)), column]
44
+ end
45
+ end
46
+
47
+ # Use SYSCAT.TABLES to get the tables for the database
48
+ def tables
49
+ metadata_dataset.
50
+ with_sql("SELECT TABNAME FROM SYSCAT.TABLES WHERE TYPE='T' AND OWNER = #{literal(input_identifier_meth.call(opts[:user]))}").
51
+ all.map{|h| output_identifier_meth.call(h[:tabname]) }
52
+ end
53
+
54
+ # Use SYSCAT.TABLES to get the views for the database
55
+ def views
56
+ metadata_dataset.
57
+ with_sql("SELECT TABNAME FROM SYSCAT.TABLES WHERE TYPE='V' AND OWNER = #{literal(input_identifier_meth.call(opts[:user]))}").
58
+ all.map{|h| output_identifier_meth.call(h[:tabname]) }
59
+ end
60
+
61
+ # Use SYSCAT.INDEXES to get the indexes for the table
62
+ def indexes(table, opts = {})
63
+ m = output_identifier_meth
64
+ indexes = {}
65
+ metadata_dataset.
66
+ from(:syscat__indexes).
67
+ select(:indname, :uniquerule, :colnames).
68
+ where(:tabname=>input_identifier_meth.call(table), :system_required=>0).
69
+ each do |r|
70
+ indexes[m.call(r[:indname])] = {:unique=>(r[:uniquerule]=='U'), :columns=>r[:colnames][1..-1].split('+').map{|v| m.call(v)}}
71
+ end
72
+ indexes
73
+ end
74
+
75
+ private
76
+
77
+ # Handle DB2 specific alter table operations.
78
+ def alter_table_sql(table, op)
79
+ case op[:op]
80
+ when :add_column
81
+ if op[:primary_key] && op[:auto_increment] && op[:type] == Integer
82
+ [
83
+ "ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op.merge(:auto_increment=>false, :primary_key=>false, :default=>0, :null=>false))}",
84
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} DROP DEFAULT",
85
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} SET #{AUTOINCREMENT}"
86
+ ]
87
+ else
88
+ "ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
89
+ end
90
+ when :drop_column
91
+ "ALTER TABLE #{quote_schema_table(table)} DROP #{column_definition_sql(op)}"
92
+ when :rename_column # renaming is only possible after db2 v9.7
93
+ "ALTER TABLE #{quote_schema_table(table)} RENAME COLUMN #{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
94
+ when :set_column_type
95
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET DATA TYPE #{type_literal(op)}"
96
+ when :set_column_default
97
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET DEFAULT #{literal(op[:default])}"
98
+ when :add_constraint
99
+ if op[:type] == :unique
100
+ sqls = op[:columns].map{|c| ["ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(c)} SET NOT NULL", reorg_sql(table)]}
101
+ sqls << super
102
+ sqls.flatten
103
+ else
104
+ super
105
+ end
106
+ else
107
+ super
108
+ end
109
+ end
110
+
111
+ # DB2 uses an identity column for autoincrement.
112
+ def auto_increment_sql
113
+ AUTOINCREMENT
114
+ end
115
+
116
+ # Add null/not null SQL fragment to column creation SQL.
117
+ def column_definition_null_sql(sql, column)
118
+ null = column.fetch(:null, column[:allow_null])
119
+ null = false if column[:primary_key]
120
+
121
+ sql << NOT_NULL if null == false
122
+ sql << NULL if null == true
123
+ end
124
+
125
+ # Supply columns with NOT NULL if they are part of a composite
126
+ # primary/foreign key
127
+ def column_list_sql(g)
128
+ ks = []
129
+ g.constraints.each{|c| ks = c[:columns] if [:primary_key, :foreign_key].include? c[:type]}
130
+ g.columns.each{|c| c[:null] = false if ks.include?(c[:name]) }
131
+ super
132
+ end
133
+
134
+ # Insert data from the current table into the new table after
135
+ # creating the table, since it is not possible to do it in one step.
136
+ def create_table_as(name, sql, options)
137
+ super
138
+ from(name).insert(sql.is_a?(Dataset) ? sql : dataset.with_sql(sql))
139
+ end
140
+
141
+ # DB2 requires parens around the SELECT, and DEFINITION ONLY at the end.
142
+ def create_table_as_sql(name, sql, options)
143
+ "#{create_table_prefix_sql(name, options)} AS (#{sql}) DEFINITION ONLY"
144
+ end
145
+
146
+ # Here we use DGTT which has most backward compatibility, which uses
147
+ # DECLARE instead of CREATE. CGTT can only be used after version 9.7.
148
+ # http://www.ibm.com/developerworks/data/library/techarticle/dm-0912globaltemptable/
149
+ def create_table_prefix_sql(name, options)
150
+ if options[:temp]
151
+ "DECLARE GLOBAL TEMPORARY TABLE #{quote_identifier(name)}"
152
+ else
153
+ super
154
+ end
155
+ end
156
+
157
+ # DB2 has issues with quoted identifiers, so
158
+ # turn off database quoting by default.
159
+ def quote_identifiers_default
160
+ false
161
+ end
162
+
163
+ # DB2 uses RENAME TABLE to rename tables.
164
+ def rename_table_sql(name, new_name)
165
+ "RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
166
+ end
167
+
168
+ # Run the REORG TABLE command for the table, necessary when
169
+ # the table has been altered.
170
+ def reorg(table)
171
+ synchronize(opts[:server]){|c| c.execute(reorg_sql(table))}
172
+ end
173
+
174
+ # The SQL to use for REORGing a table.
175
+ def reorg_sql(table)
176
+ "CALL ADMIN_CMD(#{literal("REORG TABLE #{table}")})"
177
+ end
178
+
179
+ # We uses the clob type by default for Files.
180
+ # Note: if user select to use blob, then insert statement should use
181
+ # use this for blob value:
182
+ # cast(X'fffefdfcfbfa' as blob(2G))
183
+ def type_literal_generic_file(column)
184
+ ::Sequel::DB2::use_clob_as_blob ? :clob : :blob
185
+ end
186
+
187
+ # DB2 uses smallint to store booleans.
188
+ def type_literal_generic_trueclass(column)
189
+ :smallint
190
+ end
191
+ alias type_literal_generic_falseclass type_literal_generic_trueclass
192
+ end
193
+
194
+ module DatasetMethods
195
+ include EmulateOffsetWithRowNumber
196
+
197
+ PAREN_CLOSE = Dataset::PAREN_CLOSE
198
+ PAREN_OPEN = Dataset::PAREN_OPEN
199
+ BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR, :'B~'=>:BITNOT}
200
+ EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
201
+ BOOL_TRUE = '1'.freeze
202
+ BOOL_FALSE = '0'.freeze
203
+ CAST_STRING_OPEN = "RTRIM(CHAR(".freeze
204
+ CAST_STRING_CLOSE = "))".freeze
205
+ FETCH_FIRST_ROW_ONLY = " FETCH FIRST ROW ONLY".freeze
206
+ FETCH_FIRST = " FETCH FIRST ".freeze
207
+ ROWS_ONLY = " ROWS ONLY".freeze
208
+ EMPTY_FROM_TABLE = ' FROM "SYSIBM"."SYSDUMMY1"'.freeze
209
+
210
+ # DB2 casts strings using RTRIM and CHAR instead of VARCHAR.
211
+ def cast_sql_append(sql, expr, type)
212
+ if(type == String)
213
+ sql << CAST_STRING_OPEN
214
+ literal_append(sql, expr)
215
+ sql << CAST_STRING_CLOSE
216
+ else
217
+ super
218
+ end
219
+ end
220
+
221
+ # Handle DB2 specific LIKE and bitwise operator support, and
222
+ # emulate the extract method, which DB2 doesn't natively support.
223
+ def complex_expression_sql_append(sql, op, args)
224
+ case op
225
+ when :ILIKE
226
+ super(sql, :LIKE, [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1)) ])
227
+ when :"NOT ILIKE"
228
+ super(sql, :"NOT LIKE", [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1)) ])
229
+ when :&, :|, :^
230
+ # works with db2 v9.5 and after
231
+ op = BITWISE_METHOD_MAP[op]
232
+ sql << complex_expression_arg_pairs(args){|a, b| literal(SQL::Function.new(op, a, b))}
233
+ when :<<
234
+ sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * POWER(2, #{literal(b)}))"}
235
+ when :>>
236
+ sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / POWER(2, #{literal(b)}))"}
237
+ when :%
238
+ sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
239
+ when :'B~'
240
+ literal_append(sql, SQL::Function.new(:BITNOT, *args))
241
+ when :extract
242
+ sql << args.at(0).to_s
243
+ sql << PAREN_OPEN
244
+ literal_append(sql, args.at(1))
245
+ sql << PAREN_CLOSE
246
+ else
247
+ super
248
+ end
249
+ end
250
+
251
+ # DB2 supports GROUP BY CUBE
252
+ def supports_group_cube?
253
+ true
254
+ end
255
+
256
+ # DB2 supports GROUP BY ROLLUP
257
+ def supports_group_rollup?
258
+ true
259
+ end
260
+
261
+ # DB2 does not support IS TRUE.
262
+ def supports_is_true?
263
+ false
264
+ end
265
+
266
+ # DB2 does not support multiple columns in IN.
267
+ def supports_multiple_column_in?
268
+ false
269
+ end
270
+
271
+ # DB2 only allows * in SELECT if it is the only thing being selected.
272
+ def supports_select_all_and_column?
273
+ false
274
+ end
275
+
276
+ # DB2 does not support fractional seconds in timestamps.
277
+ def supports_timestamp_usecs?
278
+ false
279
+ end
280
+
281
+ # DB2 supports window functions
282
+ def supports_window_functions?
283
+ true
284
+ end
285
+
286
+ # DB2 does not support WHERE 1.
287
+ def supports_where_true?
288
+ false
289
+ end
290
+
291
+ private
292
+
293
+ # DB2 needs the standard workaround to insert all default values into
294
+ # a table with more than one column.
295
+ def insert_supports_empty_values?
296
+ false
297
+ end
298
+
299
+ # Use 0 for false on DB2
300
+ def literal_false
301
+ BOOL_FALSE
302
+ end
303
+
304
+ # Use 1 for true on DB2
305
+ def literal_true
306
+ BOOL_TRUE
307
+ end
308
+
309
+ # Add a fallback table for empty from situation
310
+ def select_from_sql(sql)
311
+ @opts[:from] ? super : (sql << EMPTY_FROM_TABLE)
312
+ end
313
+
314
+ # Modify the sql to limit the number of rows returned
315
+ # Note:
316
+ #
317
+ # After db2 v9.7, MySQL flavored "LIMIT X OFFSET Y" can be enabled using
318
+ #
319
+ # db2set DB2_COMPATIBILITY_VECTOR=MYSQL
320
+ # db2stop
321
+ # db2start
322
+ #
323
+ # Support for this feature is not used in this adapter however.
324
+ def select_limit_sql(sql)
325
+ if l = @opts[:limit]
326
+ if l == 1
327
+ sql << FETCH_FIRST_ROW_ONLY
328
+ else
329
+ sql << FETCH_FIRST
330
+ literal_append(sql, l)
331
+ sql << ROWS_ONLY
332
+ end
333
+ end
334
+ end
335
+
336
+ def _truncate_sql(table)
337
+ # "TRUNCATE #{table} IMMEDIATE" is only for newer version of db2, so we
338
+ # use the following one
339
+ "ALTER TABLE #{quote_schema_table(table)} ACTIVATE NOT LOGGED INITIALLY WITH EMPTY TABLE"
340
+ end
341
+ end
342
+ end
343
+ end
@@ -0,0 +1,221 @@
1
+ module Sequel
2
+ module Firebird
3
+ module DatabaseMethods
4
+ AUTO_INCREMENT = ''.freeze
5
+ TEMPORARY = 'GLOBAL TEMPORARY '.freeze
6
+
7
+ def clear_primary_key(*tables)
8
+ tables.each{|t| @primary_keys.delete(dataset.send(:input_identifier, t))}
9
+ end
10
+
11
+ def create_trigger(*args)
12
+ self << create_trigger_sql(*args)
13
+ end
14
+
15
+ def database_type
16
+ :firebird
17
+ end
18
+
19
+ def drop_sequence(name)
20
+ self << drop_sequence_sql(name)
21
+ end
22
+
23
+ # Return primary key for the given table.
24
+ def primary_key(table)
25
+ t = dataset.send(:input_identifier, table)
26
+ @primary_keys.fetch(t) do
27
+ pk = fetch("SELECT RDB$FIELD_NAME FROM RDB$INDEX_SEGMENTS NATURAL JOIN RDB$RELATION_CONSTRAINTS WHERE RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' AND RDB$RELATION_NAME = ?", t).single_value
28
+ @primary_keys[t] = dataset.send(:output_identifier, pk.rstrip) if pk
29
+ end
30
+ end
31
+
32
+ def restart_sequence(*args)
33
+ self << restart_sequence_sql(*args)
34
+ end
35
+
36
+ def sequences(opts={})
37
+ ds = self[:"rdb$generators"].server(opts[:server]).filter(:"rdb$system_flag" => 0).select(:"rdb$generator_name")
38
+ block_given? ? yield(ds) : ds.map{|r| ds.send(:output_identifier, r[:"rdb$generator_name"])}
39
+ end
40
+
41
+ def tables(opts={})
42
+ tables_or_views(0, opts)
43
+ end
44
+
45
+ def views(opts={})
46
+ tables_or_views(1, opts)
47
+ end
48
+
49
+ private
50
+
51
+ # Use Firebird specific syntax for add column
52
+ def alter_table_sql(table, op)
53
+ case op[:op]
54
+ when :add_column
55
+ "ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
56
+ when :drop_column
57
+ "ALTER TABLE #{quote_schema_table(table)} DROP #{column_definition_sql(op)}"
58
+ when :rename_column
59
+ "ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TO #{quote_identifier(op[:new_name])}"
60
+ when :set_column_type
61
+ "ALTER TABLE #{quote_schema_table(table)} ALTER #{quote_identifier(op[:name])} TYPE #{type_literal(op)}"
62
+ else
63
+ super(table, op)
64
+ end
65
+ end
66
+
67
+ def auto_increment_sql()
68
+ AUTO_INCREMENT
69
+ end
70
+
71
+ def create_sequence_sql(name, opts={})
72
+ "CREATE SEQUENCE #{quote_identifier(name)}"
73
+ end
74
+
75
+ # Firebird gets an override because of the mess of creating a
76
+ # sequence and trigger for auto-incrementing primary keys.
77
+ def create_table_from_generator(name, generator, options)
78
+ drop_statement, create_statements = create_table_sql_list(name, generator, options)
79
+ (execute_ddl(drop_statement) rescue nil) if drop_statement
80
+ create_statements.each{|sql| execute_ddl(sql)}
81
+ end
82
+
83
+ def create_table_sql_list(name, generator, options={})
84
+ statements = [create_table_sql(name, generator, options)]
85
+ drop_seq_statement = nil
86
+ generator.columns.each do |c|
87
+ if c[:auto_increment]
88
+ c[:sequence_name] ||= "seq_#{name}_#{c[:name]}"
89
+ unless c[:create_sequence] == false
90
+ drop_seq_statement = drop_sequence_sql(c[:sequence_name])
91
+ statements << create_sequence_sql(c[:sequence_name])
92
+ statements << restart_sequence_sql(c[:sequence_name], {:restart_position => c[:sequence_start_position]}) if c[:sequence_start_position]
93
+ end
94
+ unless c[:create_trigger] == false
95
+ c[:trigger_name] ||= "BI_#{name}_#{c[:name]}"
96
+ c[:quoted_name] = quote_identifier(c[:name])
97
+ trigger_definition = <<-END
98
+ begin
99
+ if ((new.#{c[:quoted_name]} is null) or (new.#{c[:quoted_name]} = 0)) then
100
+ begin
101
+ new.#{c[:quoted_name]} = next value for #{c[:sequence_name]};
102
+ end
103
+ end
104
+ END
105
+ statements << create_trigger_sql(name, c[:trigger_name], trigger_definition, {:events => [:insert]})
106
+ end
107
+ end
108
+ end
109
+ [drop_seq_statement, statements]
110
+ end
111
+
112
+ def create_trigger_sql(table, name, definition, opts={})
113
+ events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
114
+ whence = opts[:after] ? 'AFTER' : 'BEFORE'
115
+ inactive = opts[:inactive] ? 'INACTIVE' : 'ACTIVE'
116
+ position = opts.fetch(:position, 0)
117
+ sql = <<-end_sql
118
+ CREATE TRIGGER #{quote_identifier(name)} for #{quote_identifier(table)}
119
+ #{inactive} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} position #{position}
120
+ as #{definition}
121
+ end_sql
122
+ sql
123
+ end
124
+
125
+ def drop_sequence_sql(name)
126
+ "DROP SEQUENCE #{quote_identifier(name)}"
127
+ end
128
+
129
+ def remove_cached_schema(table)
130
+ clear_primary_key(table)
131
+ super
132
+ end
133
+
134
+ def restart_sequence_sql(name, opts={})
135
+ seq_name = quote_identifier(name)
136
+ "ALTER SEQUENCE #{seq_name} RESTART WITH #{opts[:restart_position]}"
137
+ end
138
+
139
+ def tables_or_views(type, opts)
140
+ ds = self[:"rdb$relations"].server(opts[:server]).filter(:"rdb$relation_type" => type, Sequel::SQL::Function.new(:COALESCE, :"rdb$system_flag", 0) => 0).select(:"rdb$relation_name")
141
+ ds.map{|r| ds.send(:output_identifier, r[:"rdb$relation_name"].rstrip)}
142
+ end
143
+
144
+ def type_literal_generic_string(column)
145
+ column[:text] ? :"BLOB SUB_TYPE TEXT" : super
146
+ end
147
+ end
148
+
149
+ module DatasetMethods
150
+ BOOL_TRUE = '1'.freeze
151
+ BOOL_FALSE = '0'.freeze
152
+ NULL = LiteralString.new('NULL').freeze
153
+ SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'with select distinct limit columns from join where group having compounds order')
154
+ INSERT_CLAUSE_METHODS = Dataset.clause_methods(:insert, %w'insert into columns values returning')
155
+ FIRST = " FIRST ".freeze
156
+ SKIP = " SKIP ".freeze
157
+
158
+ # Insert given values into the database.
159
+ def insert(*values)
160
+ if @opts[:sql] || @opts[:returning]
161
+ super
162
+ else
163
+ returning(insert_pk).insert(*values){|r| return r.values.first}
164
+ end
165
+ end
166
+
167
+ # Insert a record returning the record inserted
168
+ def insert_select(*values)
169
+ returning.insert(*values){|r| return r}
170
+ end
171
+
172
+ def requires_sql_standard_datetimes?
173
+ true
174
+ end
175
+
176
+ def supports_insert_select?
177
+ true
178
+ end
179
+
180
+ # Firebird does not support INTERSECT or EXCEPT
181
+ def supports_intersect_except?
182
+ false
183
+ end
184
+
185
+ private
186
+
187
+ def insert_clause_methods
188
+ INSERT_CLAUSE_METHODS
189
+ end
190
+
191
+ def insert_pk(*values)
192
+ pk = db.primary_key(opts[:from].first)
193
+ pk ? Sequel::SQL::Identifier.new(pk) : NULL
194
+ end
195
+
196
+ def literal_false
197
+ BOOL_FALSE
198
+ end
199
+
200
+ def literal_true
201
+ BOOL_TRUE
202
+ end
203
+
204
+ # The order of clauses in the SELECT SQL statement
205
+ def select_clause_methods
206
+ SELECT_CLAUSE_METHODS
207
+ end
208
+
209
+ def select_limit_sql(sql)
210
+ if l = @opts[:limit]
211
+ sql << FIRST
212
+ literal_append(sql, l)
213
+ end
214
+ if o = @opts[:offset]
215
+ sql << SKIP
216
+ literal_append(sql, o)
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,53 @@
1
+ module Sequel
2
+ module Informix
3
+ module DatabaseMethods
4
+ TEMPORARY = 'TEMP '.freeze
5
+
6
+ # Informix uses the :informix database type
7
+ def database_type
8
+ :informix
9
+ end
10
+
11
+ private
12
+
13
+ # Informix has issues with quoted identifiers, so
14
+ # turn off database quoting by default.
15
+ def quote_identifiers_default
16
+ false
17
+ end
18
+
19
+ # SQL fragment for showing a table is temporary
20
+ def temporary_table_sql
21
+ TEMPORARY
22
+ end
23
+ end
24
+
25
+ module DatasetMethods
26
+ SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'select limit distinct columns from join where having group compounds order')
27
+ FIRST = " FIRST ".freeze
28
+ SKIP = " SKIP ".freeze
29
+
30
+ private
31
+
32
+ # Informix does not support INTERSECT or EXCEPT
33
+ def supports_intersect_except?
34
+ false
35
+ end
36
+
37
+ def select_clause_methods
38
+ SELECT_CLAUSE_METHODS
39
+ end
40
+
41
+ def select_limit_sql(sql)
42
+ if o = @opts[:offset]
43
+ sql << SKIP
44
+ literal_append(sql, o)
45
+ end
46
+ if l = @opts[:limit]
47
+ sql << FIRST
48
+ literal_append(sql, l)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end