sequel 3.21.0 → 3.36.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 (311) hide show
  1. data/CHANGELOG +855 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +23 -7
  4. data/Rakefile +42 -24
  5. data/bin/sequel +26 -8
  6. data/doc/active_record.rdoc +1 -0
  7. data/doc/advanced_associations.rdoc +171 -11
  8. data/doc/association_basics.rdoc +293 -43
  9. data/doc/dataset_basics.rdoc +5 -5
  10. data/doc/dataset_filtering.rdoc +8 -0
  11. data/doc/mass_assignment.rdoc +56 -0
  12. data/doc/migration.rdoc +85 -552
  13. data/doc/model_hooks.rdoc +78 -27
  14. data/doc/object_model.rdoc +541 -0
  15. data/doc/opening_databases.rdoc +97 -50
  16. data/doc/prepared_statements.rdoc +40 -14
  17. data/doc/querying.rdoc +28 -4
  18. data/doc/reflection.rdoc +30 -4
  19. data/doc/release_notes/3.22.0.txt +39 -0
  20. data/doc/release_notes/3.23.0.txt +172 -0
  21. data/doc/release_notes/3.24.0.txt +420 -0
  22. data/doc/release_notes/3.25.0.txt +88 -0
  23. data/doc/release_notes/3.26.0.txt +88 -0
  24. data/doc/release_notes/3.27.0.txt +82 -0
  25. data/doc/release_notes/3.28.0.txt +304 -0
  26. data/doc/release_notes/3.29.0.txt +459 -0
  27. data/doc/release_notes/3.30.0.txt +135 -0
  28. data/doc/release_notes/3.31.0.txt +146 -0
  29. data/doc/release_notes/3.32.0.txt +202 -0
  30. data/doc/release_notes/3.33.0.txt +157 -0
  31. data/doc/release_notes/3.34.0.txt +671 -0
  32. data/doc/release_notes/3.35.0.txt +144 -0
  33. data/doc/release_notes/3.36.0.txt +245 -0
  34. data/doc/schema_modification.rdoc +572 -0
  35. data/doc/sharding.rdoc +95 -3
  36. data/doc/testing.rdoc +129 -0
  37. data/doc/thread_safety.rdoc +17 -0
  38. data/doc/transactions.rdoc +137 -0
  39. data/doc/virtual_rows.rdoc +51 -2
  40. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  41. data/lib/sequel/adapters/ado.rb +40 -18
  42. data/lib/sequel/adapters/amalgalite.rb +17 -9
  43. data/lib/sequel/adapters/db2.rb +175 -86
  44. data/lib/sequel/adapters/dbi.rb +15 -15
  45. data/lib/sequel/adapters/do/mysql.rb +17 -11
  46. data/lib/sequel/adapters/do/postgres.rb +1 -57
  47. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  48. data/lib/sequel/adapters/do.rb +18 -36
  49. data/lib/sequel/adapters/firebird.rb +27 -208
  50. data/lib/sequel/adapters/ibmdb.rb +453 -0
  51. data/lib/sequel/adapters/informix.rb +6 -23
  52. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  53. data/lib/sequel/adapters/jdbc/db2.rb +47 -0
  54. data/lib/sequel/adapters/jdbc/derby.rb +287 -0
  55. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  56. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  57. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  58. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  59. data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  61. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  62. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +58 -48
  64. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  65. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  66. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  67. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  68. data/lib/sequel/adapters/jdbc.rb +265 -94
  69. data/lib/sequel/adapters/mock.rb +361 -0
  70. data/lib/sequel/adapters/mysql.rb +118 -222
  71. data/lib/sequel/adapters/mysql2.rb +58 -57
  72. data/lib/sequel/adapters/odbc/mssql.rb +15 -7
  73. data/lib/sequel/adapters/odbc.rb +28 -9
  74. data/lib/sequel/adapters/openbase.rb +3 -5
  75. data/lib/sequel/adapters/oracle.rb +349 -53
  76. data/lib/sequel/adapters/postgres.rb +356 -107
  77. data/lib/sequel/adapters/shared/access.rb +32 -9
  78. data/lib/sequel/adapters/shared/db2.rb +342 -0
  79. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  80. data/lib/sequel/adapters/shared/informix.rb +53 -0
  81. data/lib/sequel/adapters/shared/mssql.rb +335 -118
  82. data/lib/sequel/adapters/shared/mysql.rb +340 -76
  83. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  84. data/lib/sequel/adapters/shared/oracle.rb +243 -45
  85. data/lib/sequel/adapters/shared/postgres.rb +524 -279
  86. data/lib/sequel/adapters/shared/progress.rb +5 -8
  87. data/lib/sequel/adapters/shared/sqlite.rb +265 -89
  88. data/lib/sequel/adapters/sqlite.rb +101 -39
  89. data/lib/sequel/adapters/swift/mysql.rb +9 -12
  90. data/lib/sequel/adapters/swift/postgres.rb +9 -74
  91. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  92. data/lib/sequel/adapters/swift.rb +8 -7
  93. data/lib/sequel/adapters/tinytds.rb +161 -21
  94. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  95. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  96. data/lib/sequel/ast_transformer.rb +194 -0
  97. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  98. data/lib/sequel/connection_pool/sharded_threaded.rb +28 -2
  99. data/lib/sequel/connection_pool/single.rb +5 -0
  100. data/lib/sequel/connection_pool/threaded.rb +38 -14
  101. data/lib/sequel/connection_pool.rb +10 -2
  102. data/lib/sequel/core.rb +118 -11
  103. data/lib/sequel/database/connecting.rb +38 -28
  104. data/lib/sequel/database/dataset.rb +4 -4
  105. data/lib/sequel/database/dataset_defaults.rb +63 -2
  106. data/lib/sequel/database/logging.rb +7 -2
  107. data/lib/sequel/database/misc.rb +150 -46
  108. data/lib/sequel/database/query.rb +215 -65
  109. data/lib/sequel/database/schema_generator.rb +64 -20
  110. data/lib/sequel/database/schema_methods.rb +212 -54
  111. data/lib/sequel/dataset/actions.rb +322 -85
  112. data/lib/sequel/dataset/features.rb +96 -8
  113. data/lib/sequel/dataset/graph.rb +38 -11
  114. data/lib/sequel/dataset/misc.rb +50 -23
  115. data/lib/sequel/dataset/mutation.rb +12 -7
  116. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  117. data/lib/sequel/dataset/query.rb +237 -44
  118. data/lib/sequel/dataset/sql.rb +698 -278
  119. data/lib/sequel/dataset.rb +8 -0
  120. data/lib/sequel/exceptions.rb +4 -0
  121. data/lib/sequel/extensions/_pretty_table.rb +79 -0
  122. data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
  123. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  124. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
  125. data/lib/sequel/extensions/migration.rb +97 -11
  126. data/lib/sequel/extensions/named_timezones.rb +5 -0
  127. data/lib/sequel/extensions/null_dataset.rb +90 -0
  128. data/lib/sequel/extensions/pg_array.rb +460 -0
  129. data/lib/sequel/extensions/pg_array_ops.rb +220 -0
  130. data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
  131. data/lib/sequel/extensions/pg_hstore.rb +296 -0
  132. data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
  133. data/lib/sequel/extensions/pg_inet.rb +89 -0
  134. data/lib/sequel/extensions/pg_json.rb +178 -0
  135. data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
  136. data/lib/sequel/extensions/pretty_table.rb +5 -71
  137. data/lib/sequel/extensions/query.rb +1 -1
  138. data/lib/sequel/extensions/query_literals.rb +79 -0
  139. data/lib/sequel/extensions/schema_caching.rb +76 -0
  140. data/lib/sequel/extensions/schema_dumper.rb +251 -37
  141. data/lib/sequel/extensions/select_remove.rb +35 -0
  142. data/lib/sequel/extensions/server_block.rb +139 -0
  143. data/lib/sequel/extensions/sql_expr.rb +4 -110
  144. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  145. data/lib/sequel/extensions/to_dot.rb +95 -83
  146. data/lib/sequel/model/associations.rb +1187 -393
  147. data/lib/sequel/model/base.rb +578 -170
  148. data/lib/sequel/model/errors.rb +1 -1
  149. data/lib/sequel/model/exceptions.rb +5 -1
  150. data/lib/sequel/model/inflections.rb +1 -1
  151. data/lib/sequel/model.rb +30 -11
  152. data/lib/sequel/no_core_ext.rb +2 -0
  153. data/lib/sequel/plugins/active_model.rb +13 -1
  154. data/lib/sequel/plugins/association_pks.rb +22 -4
  155. data/lib/sequel/plugins/caching.rb +25 -18
  156. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  157. data/lib/sequel/plugins/composition.rb +44 -12
  158. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  159. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  160. data/lib/sequel/plugins/dirty.rb +214 -0
  161. data/lib/sequel/plugins/eager_each.rb +59 -0
  162. data/lib/sequel/plugins/force_encoding.rb +6 -6
  163. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  164. data/lib/sequel/plugins/identity_map.rb +123 -8
  165. data/lib/sequel/plugins/instance_filters.rb +10 -0
  166. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  167. data/lib/sequel/plugins/json_serializer.rb +58 -6
  168. data/lib/sequel/plugins/list.rb +12 -2
  169. data/lib/sequel/plugins/many_through_many.rb +79 -28
  170. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  171. data/lib/sequel/plugins/nested_attributes.rb +139 -63
  172. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  173. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  174. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  175. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  176. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  177. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  178. data/lib/sequel/plugins/schema.rb +7 -2
  179. data/lib/sequel/plugins/serialization.rb +98 -49
  180. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  181. data/lib/sequel/plugins/sharding.rb +21 -54
  182. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  183. data/lib/sequel/plugins/static_cache.rb +99 -0
  184. data/lib/sequel/plugins/subclasses.rb +10 -2
  185. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  186. data/lib/sequel/plugins/timestamps.rb +1 -1
  187. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  188. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  189. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  190. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  191. data/lib/sequel/sql.rb +526 -59
  192. data/lib/sequel/timezones.rb +57 -38
  193. data/lib/sequel/version.rb +1 -1
  194. data/spec/adapters/db2_spec.rb +146 -0
  195. data/spec/adapters/firebird_spec.rb +1 -1
  196. data/spec/adapters/mssql_spec.rb +142 -40
  197. data/spec/adapters/mysql_spec.rb +380 -234
  198. data/spec/adapters/oracle_spec.rb +67 -77
  199. data/spec/adapters/postgres_spec.rb +1050 -212
  200. data/spec/adapters/spec_helper.rb +8 -5
  201. data/spec/adapters/sqlite_spec.rb +139 -27
  202. data/spec/core/connection_pool_spec.rb +196 -93
  203. data/spec/core/database_spec.rb +879 -510
  204. data/spec/core/dataset_spec.rb +1415 -1086
  205. data/spec/core/expression_filters_spec.rb +554 -109
  206. data/spec/core/mock_adapter_spec.rb +449 -0
  207. data/spec/core/object_graph_spec.rb +86 -114
  208. data/spec/core/schema_generator_spec.rb +4 -4
  209. data/spec/core/schema_spec.rb +482 -38
  210. data/spec/core/spec_helper.rb +6 -48
  211. data/spec/extensions/active_model_spec.rb +13 -0
  212. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  213. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  214. data/spec/extensions/association_dependencies_spec.rb +15 -25
  215. data/spec/extensions/association_pks_spec.rb +66 -32
  216. data/spec/extensions/association_proxies_spec.rb +4 -4
  217. data/spec/extensions/caching_spec.rb +47 -51
  218. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  219. data/spec/extensions/columns_introspection_spec.rb +91 -0
  220. data/spec/extensions/composition_spec.rb +18 -13
  221. data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
  222. data/spec/extensions/dataset_associations_spec.rb +199 -0
  223. data/spec/extensions/defaults_setter_spec.rb +64 -0
  224. data/spec/extensions/dirty_spec.rb +155 -0
  225. data/spec/extensions/eager_each_spec.rb +34 -0
  226. data/spec/extensions/force_encoding_spec.rb +4 -2
  227. data/spec/extensions/hook_class_methods_spec.rb +69 -92
  228. data/spec/extensions/identity_map_spec.rb +131 -22
  229. data/spec/extensions/inflector_spec.rb +0 -4
  230. data/spec/extensions/instance_filters_spec.rb +11 -21
  231. data/spec/extensions/instance_hooks_spec.rb +72 -0
  232. data/spec/extensions/json_serializer_spec.rb +49 -6
  233. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  234. data/spec/extensions/list_spec.rb +48 -39
  235. data/spec/extensions/many_through_many_spec.rb +283 -250
  236. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  237. data/spec/extensions/migration_spec.rb +140 -35
  238. data/spec/extensions/named_timezones_spec.rb +29 -11
  239. data/spec/extensions/nested_attributes_spec.rb +251 -89
  240. data/spec/extensions/null_dataset_spec.rb +85 -0
  241. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  242. data/spec/extensions/pg_array_ops_spec.rb +105 -0
  243. data/spec/extensions/pg_array_spec.rb +196 -0
  244. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  245. data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
  246. data/spec/extensions/pg_hstore_spec.rb +195 -0
  247. data/spec/extensions/pg_inet_spec.rb +44 -0
  248. data/spec/extensions/pg_json_spec.rb +101 -0
  249. data/spec/extensions/pg_statement_cache_spec.rb +209 -0
  250. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  251. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  252. data/spec/extensions/prepared_statements_spec.rb +87 -0
  253. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  254. data/spec/extensions/pretty_table_spec.rb +7 -6
  255. data/spec/extensions/query_literals_spec.rb +168 -0
  256. data/spec/extensions/query_spec.rb +6 -0
  257. data/spec/extensions/rcte_tree_spec.rb +50 -43
  258. data/spec/extensions/schema_caching_spec.rb +41 -0
  259. data/spec/extensions/schema_dumper_spec.rb +429 -22
  260. data/spec/extensions/schema_spec.rb +25 -21
  261. data/spec/extensions/select_remove_spec.rb +38 -0
  262. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  263. data/spec/extensions/serialization_spec.rb +85 -43
  264. data/spec/extensions/server_block_spec.rb +90 -0
  265. data/spec/extensions/sharding_spec.rb +69 -143
  266. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  267. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  268. data/spec/extensions/spec_helper.rb +22 -61
  269. data/spec/extensions/sql_expr_spec.rb +29 -60
  270. data/spec/extensions/static_cache_spec.rb +145 -0
  271. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  272. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  273. data/spec/extensions/timestamps_spec.rb +6 -6
  274. data/spec/extensions/to_dot_spec.rb +4 -7
  275. data/spec/extensions/touch_spec.rb +13 -14
  276. data/spec/extensions/tree_spec.rb +11 -26
  277. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  278. data/spec/extensions/update_primary_key_spec.rb +30 -24
  279. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  280. data/spec/extensions/validation_helpers_spec.rb +16 -35
  281. data/spec/extensions/xml_serializer_spec.rb +29 -4
  282. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  283. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  284. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  285. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  286. data/spec/integration/associations_test.rb +659 -21
  287. data/spec/integration/database_test.rb +9 -3
  288. data/spec/integration/dataset_test.rb +605 -91
  289. data/spec/integration/eager_loader_test.rb +19 -21
  290. data/spec/integration/migrator_test.rb +2 -3
  291. data/spec/integration/model_test.rb +81 -2
  292. data/spec/integration/plugin_test.rb +454 -143
  293. data/spec/integration/prepared_statement_test.rb +263 -128
  294. data/spec/integration/schema_test.rb +309 -43
  295. data/spec/integration/spec_helper.rb +40 -30
  296. data/spec/integration/timezone_test.rb +38 -12
  297. data/spec/integration/transaction_test.rb +183 -8
  298. data/spec/integration/type_test.rb +18 -4
  299. data/spec/model/association_reflection_spec.rb +201 -7
  300. data/spec/model/associations_spec.rb +1067 -661
  301. data/spec/model/base_spec.rb +329 -95
  302. data/spec/model/dataset_methods_spec.rb +7 -27
  303. data/spec/model/eager_loading_spec.rb +677 -676
  304. data/spec/model/hooks_spec.rb +349 -67
  305. data/spec/model/model_spec.rb +240 -168
  306. data/spec/model/plugins_spec.rb +24 -13
  307. data/spec/model/record_spec.rb +490 -232
  308. data/spec/model/spec_helper.rb +14 -71
  309. data/spec/model/validations_spec.rb +11 -0
  310. data/spec/rcov.opts +2 -0
  311. metadata +178 -80
@@ -0,0 +1,287 @@
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
+ # Derby uses RENAME TABLE syntax to rename tables.
118
+ def rename_table_sql(name, new_name)
119
+ "RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
120
+ end
121
+
122
+ # Primary key indexes appear to be named sqlNNNN on Derby
123
+ def primary_key_index_re
124
+ PRIMARY_KEY_INDEX_RE
125
+ end
126
+
127
+ # If an :identity option is present in the column, add the necessary IDENTITY SQL.
128
+ def type_literal(column)
129
+ if column[:identity]
130
+ sql = "#{super} GENERATED BY DEFAULT AS IDENTITY"
131
+ if sw = column[:start_with]
132
+ sql << " (START WITH #{sw.to_i}"
133
+ sql << " INCREMENT BY #{column[:increment_by].to_i}" if column[:increment_by]
134
+ sql << ")"
135
+ end
136
+ sql
137
+ else
138
+ super
139
+ end
140
+ end
141
+ end
142
+
143
+ # Dataset class for Derby datasets accessed via JDBC.
144
+ class Dataset < JDBC::Dataset
145
+ PAREN_CLOSE = Dataset::PAREN_CLOSE
146
+ PAREN_OPEN = Dataset::PAREN_OPEN
147
+ OFFSET = Dataset::OFFSET
148
+ CAST_STRING_OPEN = "RTRIM(".freeze
149
+ BITCOMP_OPEN = "((0 - ".freeze
150
+ BITCOMP_CLOSE = ") - 1)".freeze
151
+ BLOB_OPEN = "CAST(X'".freeze
152
+ BLOB_CLOSE = "' AS BLOB)".freeze
153
+ HSTAR = "H*".freeze
154
+ TIME_FORMAT = "'%H:%M:%S'".freeze
155
+ DEFAULT_FROM = " FROM sysibm.sysdummy1".freeze
156
+ ROWS = " ROWS".freeze
157
+ FETCH_FIRST = " FETCH FIRST ".freeze
158
+ ROWS_ONLY = " ROWS ONLY".freeze
159
+ BOOL_TRUE = '(1 = 1)'.freeze
160
+ BOOL_FALSE = '(1 = 0)'.freeze
161
+ SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit lock')
162
+
163
+ # Derby doesn't support an expression between CASE and WHEN,
164
+ # so emulate it by using an equality statement for all of the
165
+ # conditions.
166
+ def case_expression_sql_append(sql, ce)
167
+ if ce.expression?
168
+ e = ce.expression
169
+ case_expression_sql_append(sql, ::Sequel::SQL::CaseExpression.new(ce.conditions.map{|c, r| [::Sequel::SQL::BooleanExpression.new(:'=', e, c), r]}, ce.default))
170
+ else
171
+ super
172
+ end
173
+ end
174
+
175
+ # If the type is String, trim the extra spaces since CHAR is used instead
176
+ # of varchar. This can cause problems if you are casting a char/varchar to
177
+ # a string and the ending whitespace is important.
178
+ def cast_sql_append(sql, expr, type)
179
+ if type == String
180
+ sql << CAST_STRING_OPEN
181
+ super
182
+ sql << PAREN_CLOSE
183
+ else
184
+ super
185
+ end
186
+ end
187
+
188
+ # Handle Derby specific LIKE, extract, and some bitwise compliment support.
189
+ def complex_expression_sql_append(sql, op, args)
190
+ case op
191
+ when :ILIKE
192
+ super(sql, :LIKE, [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1))])
193
+ when :"NOT ILIKE"
194
+ super(sql, :"NOT LIKE", [SQL::Function.new(:upper, args.at(0)), SQL::Function.new(:upper, args.at(1))])
195
+ when :%
196
+ sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
197
+ when :&, :|, :^, :<<, :>>
198
+ raise Error, "Derby doesn't support the #{op} operator"
199
+ when :'B~'
200
+ sql << BITCOMP_OPEN
201
+ literal_append(sql, args.at(0))
202
+ sql << BITCOMP_CLOSE
203
+ when :extract
204
+ sql << args.at(0).to_s << PAREN_OPEN
205
+ literal_append(sql, args.at(1))
206
+ sql << PAREN_CLOSE
207
+ else
208
+ super
209
+ end
210
+ end
211
+
212
+ # Derby supports GROUP BY ROLLUP (but not CUBE)
213
+ def supports_group_rollup?
214
+ true
215
+ end
216
+
217
+ # Derby does not support IS TRUE.
218
+ def supports_is_true?
219
+ false
220
+ end
221
+
222
+ # Derby does not support IN/NOT IN with multiple columns
223
+ def supports_multiple_column_in?
224
+ false
225
+ end
226
+
227
+ private
228
+
229
+ # Derby needs a hex string casted to BLOB for blobs.
230
+ def literal_blob_append(sql, v)
231
+ sql << BLOB_OPEN << v.unpack(HSTAR).first << BLOB_CLOSE
232
+ end
233
+
234
+ # Derby needs the standard workaround to insert all default values into
235
+ # a table with more than one column.
236
+ def insert_supports_empty_values?
237
+ false
238
+ end
239
+
240
+ # Derby uses an expression yielding false for false values.
241
+ # Newer versions can use the FALSE literal, but the latest gem version cannot.
242
+ def literal_false
243
+ BOOL_FALSE
244
+ end
245
+
246
+ # Derby handles fractional seconds in timestamps, but not in times
247
+ def literal_sqltime(v)
248
+ v.strftime(TIME_FORMAT)
249
+ end
250
+
251
+ # Derby uses an expression yielding true for true values.
252
+ # Newer versions can use the TRUE literal, but the latest gem version cannot.
253
+ def literal_true
254
+ BOOL_TRUE
255
+ end
256
+
257
+ # Derby doesn't support common table expressions.
258
+ def select_clause_methods
259
+ SELECT_CLAUSE_METHODS
260
+ end
261
+
262
+ # Use a default FROM table if the dataset does not contain a FROM table.
263
+ def select_from_sql(sql)
264
+ if @opts[:from]
265
+ super
266
+ else
267
+ sql << DEFAULT_FROM
268
+ end
269
+ end
270
+
271
+ # Offset comes before limit in Derby
272
+ def select_limit_sql(sql)
273
+ if o = @opts[:offset]
274
+ sql << OFFSET
275
+ literal_append(sql, o)
276
+ sql << ROWS
277
+ end
278
+ if l = @opts[:limit]
279
+ sql << FETCH_FIRST
280
+ literal_append(sql, l)
281
+ sql << ROWS_ONLY
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end
287
+ 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 == '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
@@ -0,0 +1,184 @@
1
+ Sequel.require 'adapters/jdbc/transactions'
2
+
3
+ module Sequel
4
+ module JDBC
5
+ # Database and Dataset support for HSQLDB databases accessed via JDBC.
6
+ module HSQLDB
7
+ # Instance methods for HSQLDB Database objects accessed via JDBC.
8
+ module DatabaseMethods
9
+ PRIMARY_KEY_INDEX_RE = /\Asys_idx_sys_pk_/i.freeze
10
+
11
+ include ::Sequel::JDBC::Transactions
12
+
13
+ # HSQLDB uses the :hsqldb database type.
14
+ def database_type
15
+ :hsqldb
16
+ end
17
+
18
+ # HSQLDB uses an IDENTITY sequence as the default value for primary
19
+ # key columns.
20
+ def serial_primary_key_options
21
+ {:primary_key => true, :type => :integer, :identity=>true, :start_with=>1}
22
+ end
23
+
24
+ # The version of the database, as an integer (e.g 2.2.5 -> 20205)
25
+ def db_version
26
+ @db_version ||= begin
27
+ v = get{DATABASE_VERSION(){}}
28
+ if v =~ /(\d+)\.(\d+)\.(\d+)/
29
+ $1.to_i * 10000 + $2.to_i * 100 + $3.to_i
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # HSQLDB specific SQL for renaming columns, and changing column types and/or nullity.
37
+ def alter_table_sql(table, op)
38
+ case op[:op]
39
+ when :rename_column
40
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} RENAME TO #{quote_identifier(op[:new_name])}"
41
+ when :set_column_type
42
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET DATA TYPE #{type_literal(op)}"
43
+ when :set_column_null
44
+ "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} SET #{op[:null] ? 'NULL' : 'NOT NULL'}"
45
+ else
46
+ super
47
+ end
48
+ end
49
+
50
+ # HSQLDB requires parens around the SELECT, and the WITH DATA syntax.
51
+ def create_table_as_sql(name, sql, options)
52
+ "#{create_table_prefix_sql(name, options)} AS (#{sql}) WITH DATA"
53
+ end
54
+
55
+ # Use IDENTITY() to get the last inserted id.
56
+ def last_insert_id(conn, opts={})
57
+ statement(conn) do |stmt|
58
+ sql = 'CALL IDENTITY()'
59
+ rs = log_yield(sql){stmt.executeQuery(sql)}
60
+ rs.next
61
+ rs.getInt(1)
62
+ end
63
+ end
64
+
65
+ # Primary key indexes appear to start with sys_idx_sys_pk_ on HSQLDB
66
+ def primary_key_index_re
67
+ PRIMARY_KEY_INDEX_RE
68
+ end
69
+
70
+ # If an :identity option is present in the column, add the necessary IDENTITY SQL.
71
+ # It's possible to use an IDENTITY type, but that defaults the sequence to start
72
+ # at 0 instead of 1, and we don't want that.
73
+ def type_literal(column)
74
+ if column[:identity]
75
+ sql = "#{super} GENERATED BY DEFAULT AS IDENTITY"
76
+ if sw = column[:start_with]
77
+ sql << " (START WITH #{sw.to_i}"
78
+ sql << " INCREMENT BY #{column[:increment_by].to_i}" if column[:increment_by]
79
+ sql << ")"
80
+ end
81
+ sql
82
+ else
83
+ super
84
+ end
85
+ end
86
+ end
87
+
88
+ # Dataset class for HSQLDB datasets accessed via JDBC.
89
+ class Dataset < JDBC::Dataset
90
+ BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR}
91
+ BOOL_TRUE = 'TRUE'.freeze
92
+ BOOL_FALSE = 'FALSE'.freeze
93
+ # HSQLDB does support common table expressions, but the support is broken.
94
+ # CTEs operate more like temprorary tables or views, lasting longer than the duration of the expression.
95
+ # CTEs in earlier queries might take precedence over CTEs with the same name in later queries.
96
+ # Also, if any CTE is recursive, all CTEs must be recursive.
97
+ # If you want to use CTEs with HSQLDB, you'll have to manually modify the dataset to allow it.
98
+ SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit lock')
99
+ SQL_WITH_RECURSIVE = "WITH RECURSIVE ".freeze
100
+ APOS = Dataset::APOS
101
+ HSTAR = "H*".freeze
102
+ BLOB_OPEN = "X'".freeze
103
+ BITCOMP_OPEN = "((0 - ".freeze
104
+ BITCOMP_CLOSE = ") - 1)".freeze
105
+ DEFAULT_FROM = " FROM (VALUES (0))".freeze
106
+ TIME_FORMAT = "'%H:%M:%S'".freeze
107
+
108
+ # Handle HSQLDB specific case insensitive LIKE and bitwise operator support.
109
+ def complex_expression_sql_append(sql, op, args)
110
+ case op
111
+ when :ILIKE, :"NOT ILIKE"
112
+ super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), [SQL::Function.new(:ucase, args.at(0)), SQL::Function.new(:ucase, args.at(1)) ])
113
+ when :&, :|, :^
114
+ op = BITWISE_METHOD_MAP[op]
115
+ sql << complex_expression_arg_pairs(args){|a, b| literal(SQL::Function.new(op, a, b))}
116
+ when :<<
117
+ sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * POWER(2, #{literal(b)}))"}
118
+ when :>>
119
+ sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / POWER(2, #{literal(b)}))"}
120
+ when :%
121
+ sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
122
+ when :'B~'
123
+ sql << BITCOMP_OPEN
124
+ literal_append(sql, args.at(0))
125
+ sql << BITCOMP_CLOSE
126
+ else
127
+ super
128
+ end
129
+ end
130
+
131
+ # HSQLDB requires recursive CTEs to have column aliases.
132
+ def recursive_cte_requires_column_aliases?
133
+ true
134
+ end
135
+
136
+ # HSQLDB does not support IS TRUE.
137
+ def supports_is_true?
138
+ false
139
+ end
140
+
141
+ private
142
+
143
+ # Use string in hex format for blob data.
144
+ def literal_blob_append(sql, v)
145
+ sql << BLOB_OPEN << v.unpack(HSTAR).first << APOS
146
+ end
147
+
148
+ # HSQLDB uses FALSE for false values.
149
+ def literal_false
150
+ BOOL_FALSE
151
+ end
152
+
153
+ # HSQLDB handles fractional seconds in timestamps, but not in times
154
+ def literal_sqltime(v)
155
+ v.strftime(TIME_FORMAT)
156
+ end
157
+
158
+ # HSQLDB uses TRUE for true values.
159
+ def literal_true
160
+ BOOL_TRUE
161
+ end
162
+
163
+ # HSQLDB does not support CTEs well enough for Sequel to enable support for them.
164
+ def select_clause_methods
165
+ SELECT_CLAUSE_METHODS
166
+ end
167
+
168
+ # Use a default FROM table if the dataset does not contain a FROM table.
169
+ def select_from_sql(sql)
170
+ if @opts[:from]
171
+ super
172
+ else
173
+ sql << DEFAULT_FROM
174
+ end
175
+ end
176
+
177
+ # Use WITH RECURSIVE instead of WITH if any of the CTEs is recursive
178
+ def select_with_sql_base
179
+ opts[:with].any?{|w| w[:recursive]} ? SQL_WITH_RECURSIVE : super
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,21 @@
1
+ Sequel.require 'adapters/shared/informix'
2
+
3
+ module Sequel
4
+ module JDBC
5
+ # Database and Dataset instance methods for Informix specific
6
+ # support via JDBC.
7
+ module Informix
8
+ # Database instance methods for Informix databases accessed via JDBC.
9
+ module DatabaseMethods
10
+ include Sequel::Informix::DatabaseMethods
11
+
12
+ private
13
+
14
+ # TODO: implement
15
+ def last_insert_id(conn, opts={})
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end