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,27 +1,30 @@
1
1
  module Sequel
2
2
  class Database
3
3
  # ---------------------
4
- # :section: Methods that modify the database schema
4
+ # :section: 2 - Methods that modify the database schema
5
5
  # These methods execute code on the database that modifies the database's schema.
6
6
  # ---------------------
7
7
 
8
8
  AUTOINCREMENT = 'AUTOINCREMENT'.freeze
9
- CASCADE = 'CASCADE'.freeze
10
9
  COMMA_SEPARATOR = ', '.freeze
11
- NO_ACTION = 'NO ACTION'.freeze
12
10
  NOT_NULL = ' NOT NULL'.freeze
13
11
  NULL = ' NULL'.freeze
14
12
  PRIMARY_KEY = ' PRIMARY KEY'.freeze
15
- RESTRICT = 'RESTRICT'.freeze
16
- SET_DEFAULT = 'SET DEFAULT'.freeze
17
- SET_NULL = 'SET NULL'.freeze
18
13
  TEMPORARY = 'TEMPORARY '.freeze
19
14
  UNDERSCORE = '_'.freeze
20
15
  UNIQUE = ' UNIQUE'.freeze
21
16
  UNSIGNED = ' UNSIGNED'.freeze
22
17
 
23
18
  # The order of column modifiers to use when defining a column.
24
- COLUMN_DEFINITION_ORDER = [:default, :null, :unique, :primary_key, :auto_increment, :references]
19
+ COLUMN_DEFINITION_ORDER = [:collate, :default, :null, :unique, :primary_key, :auto_increment, :references]
20
+
21
+ # The default options for join table columns.
22
+ DEFAULT_JOIN_TABLE_COLUMN_OPTIONS = {:null=>false}
23
+
24
+ # The alter table operations that are combinable.
25
+ COMBINABLE_ALTER_TABLE_OPS = [:add_column, :drop_column, :rename_column,
26
+ :set_column_type, :set_column_default, :set_column_null,
27
+ :add_constraint, :drop_constraint]
25
28
 
26
29
  # Adds a column to the specified table. This method expects a column name,
27
30
  # a datatype and optionally a hash with additional constraints and options:
@@ -29,7 +32,7 @@ module Sequel
29
32
  # DB.add_column :items, :name, :text, :unique => true, :null => false
30
33
  # DB.add_column :items, :category, :text, :default => 'ruby'
31
34
  #
32
- # See alter_table.
35
+ # See <tt>alter_table</tt>.
33
36
  def add_column(table, *args)
34
37
  alter_table(table) {add_column(*args)}
35
38
  end
@@ -40,9 +43,9 @@ module Sequel
40
43
  # DB.add_index :posts, [:author, :title], :unique => true
41
44
  #
42
45
  # Options:
43
- # * :ignore_errors - Ignore any DatabaseErrors that are raised
46
+ # :ignore_errors :: Ignore any DatabaseErrors that are raised
44
47
  #
45
- # See alter_table.
48
+ # See <tt>alter_table</tt>.
46
49
  def add_index(table, columns, options={})
47
50
  e = options[:ignore_errors]
48
51
  begin
@@ -65,17 +68,71 @@ module Sequel
65
68
  # end
66
69
  #
67
70
  # Note that +add_column+ accepts all the options available for column
68
- # definitions using create_table, and +add_index+ accepts all the options
71
+ # definitions using <tt>create_table</tt>, and +add_index+ accepts all the options
69
72
  # available for index definition.
70
73
  #
71
- # See Schema::AlterTableGenerator and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
74
+ # See <tt>Schema::AlterTableGenerator</tt> and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
72
75
  def alter_table(name, generator=nil, &block)
73
- generator ||= Schema::AlterTableGenerator.new(self, &block)
74
- alter_table_sql_list(name, generator.operations).flatten.each {|sql| execute_ddl(sql)}
76
+ generator ||= alter_table_generator(&block)
75
77
  remove_cached_schema(name)
78
+ apply_alter_table_generator(name, generator)
76
79
  nil
77
80
  end
78
-
81
+
82
+ # Return a new Schema::AlterTableGenerator instance with the receiver as
83
+ # the database and the given block.
84
+ def alter_table_generator(&block)
85
+ alter_table_generator_class.new(self, &block)
86
+ end
87
+
88
+ # Create a join table using a hash of foreign keys to referenced
89
+ # table names. Example:
90
+ #
91
+ # create_join_table(:cat_id=>:cats, :dog_id=>:dogs)
92
+ # # CREATE TABLE cats_dogs (
93
+ # # cat_id integer NOT NULL REFERENCES cats,
94
+ # # dog_id integer NOT NULL REFERENCES dogs,
95
+ # # PRIMARY KEY (cat_id, dog_id)
96
+ # # )
97
+ # # CREATE INDEX cats_dogs_dog_id_cat_id_index ON cats_dogs(dog_id, cat_id)
98
+ #
99
+ # The primary key and index are used so that almost all operations
100
+ # on the table can benefit from one of the two indexes, and the primary
101
+ # key ensures that entries in the table are unique, which is the typical
102
+ # desire for a join table.
103
+ #
104
+ # You can provide column options by making the values in the hash
105
+ # be option hashes, so long as the option hashes have a :table
106
+ # entry giving the table referenced:
107
+ #
108
+ # create_join_table(:cat_id=>{:table=>:cats, :type=>Bignum}, :dog_id=>:dogs)
109
+ #
110
+ # You can provide a second argument which is a table options hash:
111
+ #
112
+ # create_join_table({:cat_id=>:cats, :dog_id=>:dogs}, :temp=>true)
113
+ #
114
+ # Some table options are handled specially:
115
+ #
116
+ # :index_options :: The options to pass to the index
117
+ # :name :: The name of the table to create
118
+ # :no_index :: Set to true not to create the second index.
119
+ # :no_primary_key :: Set to true to not create the primary key.
120
+ def create_join_table(hash, options={})
121
+ keys = hash.keys.sort_by{|k| k.to_s}
122
+ create_table(join_table_name(hash, options), options) do
123
+ keys.each do |key|
124
+ v = hash[key]
125
+ unless v.is_a?(Hash)
126
+ v = {:table=>v}
127
+ end
128
+ v = DEFAULT_JOIN_TABLE_COLUMN_OPTIONS.merge(v)
129
+ foreign_key(key, v)
130
+ end
131
+ primary_key(keys) unless options[:no_primary_key]
132
+ index(keys.reverse, options[:index_options] || {}) unless options[:no_index]
133
+ end
134
+ end
135
+
79
136
  # Creates a table with the columns given in the provided block:
80
137
  #
81
138
  # DB.create_table :posts do
@@ -85,33 +142,61 @@ module Sequel
85
142
  # index :title
86
143
  # end
87
144
  #
88
- # Options:
89
- # :temp :: Create the table as a temporary table.
145
+ # General options:
146
+ # :as :: Create the table using the value, which should be either a
147
+ # dataset or a literal SQL string. If this option is used,
148
+ # a block should not be given to the method.
90
149
  # :ignore_index_errors :: Ignore any errors when creating indexes.
150
+ # :temp :: Create the table as a temporary table.
151
+ #
152
+ # MySQL specific options:
153
+ # :charset :: The character set to use for the table.
154
+ # :collate :: The collation to use for the table.
155
+ # :engine :: The table engine to use for the table.
91
156
  #
92
- # See Schema::Generator and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
157
+ # See <tt>Schema::Generator</tt> and the {"Schema Modification" guide}[link:files/doc/schema_modification_rdoc.html].
93
158
  def create_table(name, options={}, &block)
94
159
  remove_cached_schema(name)
95
- options = {:generator=>options} if options.is_a?(Schema::Generator)
96
- generator = options[:generator] || Schema::Generator.new(self, &block)
97
- create_table_from_generator(name, generator, options)
98
- create_table_indexes_from_generator(name, generator, options)
99
- nil
160
+ options = {:generator=>options} if options.is_a?(Schema::CreateTableGenerator)
161
+ if sql = options[:as]
162
+ raise(Error, "can't provide both :as option and block to create_table") if block
163
+ create_table_as(name, sql, options)
164
+ else
165
+ generator = options[:generator] || create_table_generator(&block)
166
+ create_table_from_generator(name, generator, options)
167
+ create_table_indexes_from_generator(name, generator, options)
168
+ nil
169
+ end
100
170
  end
101
-
102
- # Forcibly creates a table, attempting to drop it unconditionally (and catching any errors), then creating it.
171
+
172
+ # Forcibly create a table, attempting to drop it if it already exists, then creating it.
103
173
  #
104
174
  # DB.create_table!(:a){Integer :a}
105
- # # DROP TABLE a
175
+ # # SELECT NULL FROM a LIMIT 1 -- check existence
176
+ # # DROP TABLE a -- drop table if already exists
106
177
  # # CREATE TABLE a (a integer)
107
178
  def create_table!(name, options={}, &block)
108
- drop_table(name) rescue nil
179
+ drop_table?(name)
109
180
  create_table(name, options, &block)
110
181
  end
111
182
 
112
- # Creates the table unless the table already exists
183
+ # Creates the table unless the table already exists.
184
+ #
185
+ # DB.create_table?(:a){Integer :a}
186
+ # # SELECT NULL FROM a LIMIT 1 -- check existence
187
+ # # CREATE TABLE a (a integer) -- if it doesn't already exist
113
188
  def create_table?(name, options={}, &block)
114
- create_table(name, options, &block) unless table_exists?(name)
189
+ if supports_create_table_if_not_exists?
190
+ create_table(name, options.merge(:if_not_exists=>true), &block)
191
+ elsif !table_exists?(name)
192
+ create_table(name, options, &block)
193
+ end
194
+ end
195
+
196
+ # Return a new Schema::CreateTableGenerator instance with the receiver as
197
+ # the database and the given block.
198
+ def create_table_generator(&block)
199
+ create_table_generator_class.new(self, &block)
115
200
  end
116
201
 
117
202
  # Creates a view, replacing it if it already exists:
@@ -138,7 +223,7 @@ module Sequel
138
223
  #
139
224
  # DB.drop_column :items, :category
140
225
  #
141
- # See alter_table.
226
+ # See <tt>alter_table</tt>.
142
227
  def drop_column(table, *args)
143
228
  alter_table(table) {drop_column(*args)}
144
229
  end
@@ -148,28 +233,63 @@ module Sequel
148
233
  # DB.drop_index :posts, :title
149
234
  # DB.drop_index :posts, [:author, :title]
150
235
  #
151
- # See alter_table.
236
+ # See <tt>alter_table</tt>.
152
237
  def drop_index(table, columns, options={})
153
238
  alter_table(table){drop_index(columns, options)}
154
239
  end
240
+
241
+ # Drop the join table that would have been created with the
242
+ # same arguments to create_join_table:
243
+ #
244
+ # drop_join_table(:cat_id=>:cats, :dog_id=>:dogs)
245
+ # # DROP TABLE cats_dogs
246
+ def drop_join_table(hash, options={})
247
+ drop_table(join_table_name(hash, options), options)
248
+ end
155
249
 
156
250
  # Drops one or more tables corresponding to the given names:
157
251
  #
252
+ # DB.drop_table(:posts) # DROP TABLE posts
158
253
  # DB.drop_table(:posts, :comments)
254
+ # DB.drop_table(:posts, :comments, :cascade=>true)
159
255
  def drop_table(*names)
256
+ options = names.last.is_a?(Hash) ? names.pop : {}
160
257
  names.each do |n|
161
- execute_ddl(drop_table_sql(n))
258
+ execute_ddl(drop_table_sql(n, options))
162
259
  remove_cached_schema(n)
163
260
  end
164
261
  nil
165
262
  end
166
263
 
264
+ # Drops the table if it already exists. If it doesn't exist,
265
+ # does nothing.
266
+ #
267
+ # DB.drop_table?(:a)
268
+ # # SELECT NULL FROM a LIMIT 1 -- check existence
269
+ # # DROP TABLE a -- if it already exists
270
+ def drop_table?(*names)
271
+ options = names.last.is_a?(Hash) ? names.pop : {}
272
+ if supports_drop_table_if_exists?
273
+ options = options.merge(:if_exists=>true)
274
+ names.each do |name|
275
+ drop_table(name, options)
276
+ end
277
+ else
278
+ names.each do |name|
279
+ drop_table(name, options) if table_exists?(name)
280
+ end
281
+ end
282
+ end
283
+
167
284
  # Drops one or more views corresponding to the given names:
168
285
  #
169
286
  # DB.drop_view(:cheap_items)
287
+ # DB.drop_view(:cheap_items, :pricey_items)
288
+ # DB.drop_view(:cheap_items, :pricey_items, :cascade=>true)
170
289
  def drop_view(*names)
290
+ options = names.last.is_a?(Hash) ? names.pop : {}
171
291
  names.each do |n|
172
- execute_ddl("DROP VIEW #{quote_schema_table(n)}")
292
+ execute_ddl(drop_view_sql(n, options))
173
293
  remove_cached_schema(n)
174
294
  end
175
295
  nil
@@ -191,7 +311,7 @@ module Sequel
191
311
  #
192
312
  # DB.rename_column :items, :cntr, :counter
193
313
  #
194
- # See alter_table.
314
+ # See <tt>alter_table</tt>.
195
315
  def rename_column(table, *args)
196
316
  alter_table(table) {rename_column(*args)}
197
317
  end
@@ -200,7 +320,7 @@ module Sequel
200
320
  #
201
321
  # DB.set_column_default :items, :category, 'perl!'
202
322
  #
203
- # See alter_table.
323
+ # See <tt>alter_table</tt>.
204
324
  def set_column_default(table, *args)
205
325
  alter_table(table) {set_column_default(*args)}
206
326
  end
@@ -209,22 +329,36 @@ module Sequel
209
329
  #
210
330
  # DB.set_column_type :items, :price, :float
211
331
  #
212
- # See alter_table.
332
+ # See <tt>alter_table</tt>.
213
333
  def set_column_type(table, *args)
214
334
  alter_table(table) {set_column_type(*args)}
215
335
  end
216
336
 
217
337
  private
218
338
 
219
- # The SQL to execute to modify the DDL for the given table name. op
220
- # should be one of the operations returned by the AlterTableGenerator.
221
- def alter_table_sql(table, op)
339
+ # Apply the changes in the given alter table ops to the table given by name.
340
+ def apply_alter_table(name, ops)
341
+ alter_table_sql_list(name, ops).each{|sql| execute_ddl(sql)}
342
+ end
343
+
344
+ # Apply the operations in the given generator to the table given by name.
345
+ def apply_alter_table_generator(name, generator)
346
+ apply_alter_table(name, generator.operations)
347
+ end
348
+
349
+ # The class used for alter_table generators.
350
+ def alter_table_generator_class
351
+ Schema::AlterTableGenerator
352
+ end
353
+
354
+ # SQL fragment for given alter table operation.
355
+ def alter_table_op_sql(table, op)
222
356
  quoted_name = quote_identifier(op[:name]) if op[:name]
223
357
  alter_table_op = case op[:op]
224
358
  when :add_column
225
359
  "ADD COLUMN #{column_definition_sql(op)}"
226
360
  when :drop_column
227
- "DROP COLUMN #{quoted_name}"
361
+ "DROP COLUMN #{quoted_name}#{' CASCADE' if op[:cascade]}"
228
362
  when :rename_column
229
363
  "RENAME COLUMN #{quoted_name} TO #{quote_identifier(op[:new_name])}"
230
364
  when :set_column_type
@@ -233,24 +367,56 @@ module Sequel
233
367
  "ALTER COLUMN #{quoted_name} SET DEFAULT #{literal(op[:default])}"
234
368
  when :set_column_null
235
369
  "ALTER COLUMN #{quoted_name} #{op[:null] ? 'DROP' : 'SET'} NOT NULL"
236
- when :add_index
237
- return index_definition_sql(table, op)
238
- when :drop_index
239
- return drop_index_sql(table, op)
240
370
  when :add_constraint
241
371
  "ADD #{constraint_definition_sql(op)}"
242
372
  when :drop_constraint
243
- "DROP CONSTRAINT #{quoted_name}"
373
+ "DROP CONSTRAINT #{quoted_name}#{' CASCADE' if op[:cascade]}"
374
+ else
375
+ raise Error, "Unsupported ALTER TABLE operation: #{op[:op]}"
376
+ end
377
+ end
378
+
379
+ # The SQL to execute to modify the DDL for the given table name. op
380
+ # should be one of the operations returned by the AlterTableGenerator.
381
+ def alter_table_sql(table, op)
382
+ case op[:op]
383
+ when :add_index
384
+ index_definition_sql(table, op)
385
+ when :drop_index
386
+ drop_index_sql(table, op)
244
387
  else
245
- raise Error, "Unsupported ALTER TABLE operation"
388
+ "ALTER TABLE #{quote_schema_table(table)} #{alter_table_op_sql(table, op)}"
246
389
  end
247
- "ALTER TABLE #{quote_schema_table(table)} #{alter_table_op}"
248
390
  end
249
391
 
250
392
  # Array of SQL DDL modification statements for the given table,
251
393
  # corresponding to the DDL changes specified by the operations.
252
394
  def alter_table_sql_list(table, operations)
253
- operations.map{|op| alter_table_sql(table, op)}
395
+ if supports_combining_alter_table_ops?
396
+ grouped_ops = []
397
+ last_combinable = false
398
+ operations.each do |op|
399
+ if combinable_alter_table_op?(op)
400
+ if sql = alter_table_op_sql(table, op)
401
+ grouped_ops << [] unless last_combinable
402
+ grouped_ops.last << sql
403
+ last_combinable = true
404
+ end
405
+ elsif sql = alter_table_sql(table, op)
406
+ grouped_ops << sql
407
+ last_combinable = false
408
+ end
409
+ end
410
+ grouped_ops.map do |gop|
411
+ if gop.is_a?(Array)
412
+ "ALTER TABLE #{quote_schema_table(table)} #{gop.join(', ')}"
413
+ else
414
+ gop
415
+ end
416
+ end
417
+ else
418
+ operations.map{|op| alter_table_sql(table, op)}.flatten.compact
419
+ end
254
420
  end
255
421
 
256
422
  # The SQL string specify the autoincrement property, generally used by
@@ -275,7 +441,12 @@ module Sequel
275
441
  def column_definition_auto_increment_sql(sql, column)
276
442
  sql << " #{auto_increment_sql}" if column[:auto_increment]
277
443
  end
278
-
444
+
445
+ # Add collate SQL fragment to column creation SQL.
446
+ def column_definition_collate_sql(sql, column)
447
+ sql << " COLLATE #{column[:collate]}" if column[:collate]
448
+ end
449
+
279
450
  # Add default SQL fragment to column creation SQL.
280
451
  def column_definition_default_sql(sql, column)
281
452
  sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
@@ -318,7 +489,7 @@ module Sequel
318
489
  sql = " REFERENCES #{quote_schema_table(column[:table])}"
319
490
  sql << "(#{Array(column[:key]).map{|x| quote_identifier(x)}.join(COMMA_SEPARATOR)})" if column[:key]
320
491
  sql << " ON DELETE #{on_delete_clause(column[:on_delete])}" if column[:on_delete]
321
- sql << " ON UPDATE #{on_delete_clause(column[:on_update])}" if column[:on_update]
492
+ sql << " ON UPDATE #{on_update_clause(column[:on_update])}" if column[:on_update]
322
493
  sql << " DEFERRABLE INITIALLY DEFERRED" if column[:deferrable]
323
494
  sql
324
495
  end
@@ -328,6 +499,12 @@ module Sequel
328
499
  "FOREIGN KEY #{literal(constraint[:columns])}#{column_references_sql(constraint)}"
329
500
  end
330
501
 
502
+ # Whether the given alter table operation is combinable.
503
+ def combinable_alter_table_op?(op)
504
+ # Use a dynamic lookup for easier overriding in adapters
505
+ COMBINABLE_ALTER_TABLE_OPS.include?(op[:op])
506
+ end
507
+
331
508
  # SQL DDL fragment specifying a constraint on a table.
332
509
  def constraint_definition_sql(constraint)
333
510
  sql = constraint[:name] ? "CONSTRAINT #{quote_identifier(constraint[:name])} " : ""
@@ -352,9 +529,14 @@ module Sequel
352
529
  execute_ddl(create_table_sql(name, generator, options))
353
530
  end
354
531
 
532
+ # The class used for create_table generators.
533
+ def create_table_generator_class
534
+ Schema::CreateTableGenerator
535
+ end
536
+
355
537
  # Execute the create index statements using the generator.
356
538
  def create_table_indexes_from_generator(name, generator, options)
357
- e = options[:ignore_index_errors]
539
+ e = options[:ignore_index_errors] || options[:if_not_exists]
358
540
  generator.indexes.each do |index|
359
541
  begin
360
542
  index_sql_list(name, [index]).each{|sql| execute_ddl(sql)}
@@ -366,7 +548,25 @@ module Sequel
366
548
 
367
549
  # DDL statement for creating a table with the given name, columns, and options
368
550
  def create_table_sql(name, generator, options)
369
- "CREATE #{temporary_table_sql if options[:temp]}TABLE #{quote_schema_table(name)} (#{column_list_sql(generator)})"
551
+ "#{create_table_prefix_sql(name, options)} (#{column_list_sql(generator)})"
552
+ end
553
+
554
+ # Run a command to create the table with the given name from the given
555
+ # SELECT sql statement.
556
+ def create_table_as(name, sql, options)
557
+ sql = sql.sql if sql.is_a?(Sequel::Dataset)
558
+ run(create_table_as_sql(name, sql, options))
559
+ end
560
+
561
+ # DDL statement for creating a table from the result of a SELECT statement.
562
+ # +sql+ should be a string representing a SELECT query.
563
+ def create_table_as_sql(name, sql, options)
564
+ "#{create_table_prefix_sql(name, options)} AS #{sql}"
565
+ end
566
+
567
+ # DDL statement for creating a table with the given name, columns, and options
568
+ def create_table_prefix_sql(name, options)
569
+ "CREATE #{temporary_table_sql if options[:temp]}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
370
570
  end
371
571
 
372
572
  # Default index name for the table and columns, may be too long
@@ -382,10 +582,15 @@ module Sequel
382
582
  end
383
583
 
384
584
  # SQL DDL statement to drop the table with the given name.
385
- def drop_table_sql(name)
386
- "DROP TABLE #{quote_schema_table(name)}"
585
+ def drop_table_sql(name, options)
586
+ "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_schema_table(name)}#{' CASCADE' if options[:cascade]}"
387
587
  end
388
588
 
589
+ # SQL DDL statement to drop a view with the given name.
590
+ def drop_view_sql(name, options)
591
+ "DROP VIEW #{quote_schema_table(name)}#{' CASCADE' if options[:cascade]}"
592
+ end
593
+
389
594
  # Proxy the filter_expr call to the dataset, used for creating constraints.
390
595
  def filter_expr(*args, &block)
391
596
  schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
@@ -410,6 +615,32 @@ module Sequel
410
615
  indexes.map{|i| index_definition_sql(table_name, i)}
411
616
  end
412
617
 
618
+ # Extract the join table name from the arguments given to create_join_table.
619
+ # Also does argument validation for the create_join_table method.
620
+ def join_table_name(hash, options)
621
+ entries = hash.values
622
+ raise Error, "must have 2 entries in hash given to (create|drop)_join_table" unless entries.length == 2
623
+ if options[:name]
624
+ options[:name]
625
+ else
626
+ table_names = entries.map{|e| join_table_name_extract(e)}
627
+ table_names.map{|t| t.to_s}.sort.join('_')
628
+ end
629
+ end
630
+
631
+ # Extract an individual join table name, which should either be a string
632
+ # or symbol, or a hash containing one of those as the value for :table.
633
+ def join_table_name_extract(entry)
634
+ case entry
635
+ when Symbol, String
636
+ entry
637
+ when Hash
638
+ join_table_name_extract(entry[:table])
639
+ else
640
+ raise Error, "can't extract table name from #{entry.inspect}"
641
+ end
642
+ end
643
+
413
644
  # SQL DDL ON DELETE fragment to use, based on the given action.
414
645
  # The following actions are recognized:
415
646
  #
@@ -420,19 +651,15 @@ module Sequel
420
651
  # but do not allow deferring the integrity check.
421
652
  # * :set_default - Set columns referencing this row to their default value.
422
653
  # * :set_null - Set columns referencing this row to NULL.
654
+ #
655
+ # Any other object given is just converted to a string, with "_" converted to " " and upcased.
423
656
  def on_delete_clause(action)
424
- case action
425
- when :restrict
426
- RESTRICT
427
- when :cascade
428
- CASCADE
429
- when :set_null
430
- SET_NULL
431
- when :set_default
432
- SET_DEFAULT
433
- else
434
- NO_ACTION
435
- end
657
+ action.to_s.gsub("_", " ").upcase
658
+ end
659
+
660
+ # Alias of #on_delete_clause, since the two usually behave the same.
661
+ def on_update_clause(action)
662
+ on_delete_clause(action)
436
663
  end
437
664
 
438
665
  # Proxy the quote_schema_table method to the dataset
@@ -463,7 +690,7 @@ module Sequel
463
690
 
464
691
  # Return true if the given column schema represents an autoincrementing primary key.
465
692
  def schema_autoincrementing_primary_key?(schema)
466
- !!schema[:primary_key]
693
+ !!(schema[:primary_key] && schema[:db_type] =~ /int/io)
467
694
  end
468
695
 
469
696
  # The dataset to use for proxying certain schema methods.
@@ -471,6 +698,12 @@ module Sequel
471
698
  @schema_utility_dataset ||= dataset
472
699
  end
473
700
 
701
+ # Whether the database supports combining multiple alter table
702
+ # operations into a single query, false by default.
703
+ def supports_combining_alter_table_ops?
704
+ false
705
+ end
706
+
474
707
  # SQL DDL fragment for temporary table
475
708
  def temporary_table_sql
476
709
  self.class.const_get(:TEMPORARY)