sequel 3.21.0 → 3.41.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 (363) hide show
  1. data/CHANGELOG +1131 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +106 -65
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +68 -52
  7. data/doc/advanced_associations.rdoc +201 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/bin_sequel.rdoc +144 -0
  10. data/doc/cheat_sheet.rdoc +21 -21
  11. data/doc/core_extensions.rdoc +374 -0
  12. data/doc/dataset_basics.rdoc +10 -10
  13. data/doc/dataset_filtering.rdoc +54 -42
  14. data/doc/mass_assignment.rdoc +56 -0
  15. data/doc/migration.rdoc +89 -557
  16. data/doc/model_hooks.rdoc +80 -29
  17. data/doc/object_model.rdoc +576 -0
  18. data/doc/opening_databases.rdoc +121 -53
  19. data/doc/prepared_statements.rdoc +41 -15
  20. data/doc/querying.rdoc +137 -56
  21. data/doc/reflection.rdoc +36 -10
  22. data/doc/release_notes/3.22.0.txt +39 -0
  23. data/doc/release_notes/3.23.0.txt +172 -0
  24. data/doc/release_notes/3.24.0.txt +420 -0
  25. data/doc/release_notes/3.25.0.txt +88 -0
  26. data/doc/release_notes/3.26.0.txt +88 -0
  27. data/doc/release_notes/3.27.0.txt +82 -0
  28. data/doc/release_notes/3.28.0.txt +304 -0
  29. data/doc/release_notes/3.29.0.txt +459 -0
  30. data/doc/release_notes/3.30.0.txt +135 -0
  31. data/doc/release_notes/3.31.0.txt +146 -0
  32. data/doc/release_notes/3.32.0.txt +202 -0
  33. data/doc/release_notes/3.33.0.txt +157 -0
  34. data/doc/release_notes/3.34.0.txt +671 -0
  35. data/doc/release_notes/3.35.0.txt +144 -0
  36. data/doc/release_notes/3.36.0.txt +245 -0
  37. data/doc/release_notes/3.37.0.txt +338 -0
  38. data/doc/release_notes/3.38.0.txt +234 -0
  39. data/doc/release_notes/3.39.0.txt +237 -0
  40. data/doc/release_notes/3.40.0.txt +73 -0
  41. data/doc/release_notes/3.41.0.txt +155 -0
  42. data/doc/schema_modification.rdoc +585 -0
  43. data/doc/sharding.rdoc +99 -8
  44. data/doc/sql.rdoc +154 -112
  45. data/doc/testing.rdoc +169 -0
  46. data/doc/thread_safety.rdoc +17 -0
  47. data/doc/transactions.rdoc +137 -0
  48. data/doc/validations.rdoc +1 -1
  49. data/doc/virtual_rows.rdoc +78 -43
  50. data/lib/sequel/adapters/ado/access.rb +334 -0
  51. data/lib/sequel/adapters/ado/mssql.rb +18 -12
  52. data/lib/sequel/adapters/ado.rb +69 -21
  53. data/lib/sequel/adapters/amalgalite.rb +17 -14
  54. data/lib/sequel/adapters/cubrid.rb +143 -0
  55. data/lib/sequel/adapters/db2.rb +178 -85
  56. data/lib/sequel/adapters/dbi.rb +19 -21
  57. data/lib/sequel/adapters/do/mysql.rb +17 -11
  58. data/lib/sequel/adapters/do/postgres.rb +2 -61
  59. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  60. data/lib/sequel/adapters/do.rb +20 -39
  61. data/lib/sequel/adapters/firebird.rb +33 -210
  62. data/lib/sequel/adapters/ibmdb.rb +452 -0
  63. data/lib/sequel/adapters/informix.rb +6 -29
  64. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  65. data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
  66. data/lib/sequel/adapters/jdbc/db2.rb +78 -0
  67. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  68. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  69. data/lib/sequel/adapters/jdbc/h2.rb +68 -31
  70. data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
  71. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  73. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  74. data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
  75. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  76. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  77. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  78. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  79. data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
  80. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  81. data/lib/sequel/adapters/jdbc.rb +308 -114
  82. data/lib/sequel/adapters/mock.rb +372 -0
  83. data/lib/sequel/adapters/mysql.rb +130 -230
  84. data/lib/sequel/adapters/mysql2.rb +64 -63
  85. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  86. data/lib/sequel/adapters/odbc.rb +29 -10
  87. data/lib/sequel/adapters/openbase.rb +7 -11
  88. data/lib/sequel/adapters/oracle.rb +364 -57
  89. data/lib/sequel/adapters/postgres.rb +379 -145
  90. data/lib/sequel/adapters/shared/access.rb +236 -11
  91. data/lib/sequel/adapters/shared/cubrid.rb +216 -0
  92. data/lib/sequel/adapters/shared/db2.rb +353 -0
  93. data/lib/sequel/adapters/shared/firebird.rb +231 -0
  94. data/lib/sequel/adapters/shared/informix.rb +53 -0
  95. data/lib/sequel/adapters/shared/mssql.rb +412 -116
  96. data/lib/sequel/adapters/shared/mysql.rb +396 -89
  97. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
  98. data/lib/sequel/adapters/shared/oracle.rb +262 -45
  99. data/lib/sequel/adapters/shared/postgres.rb +688 -279
  100. data/lib/sequel/adapters/shared/progress.rb +5 -8
  101. data/lib/sequel/adapters/shared/sqlite.rb +317 -96
  102. data/lib/sequel/adapters/sqlite.rb +109 -46
  103. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  104. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  105. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  106. data/lib/sequel/adapters/swift.rb +31 -27
  107. data/lib/sequel/adapters/tinytds.rb +177 -25
  108. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  109. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  110. data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
  111. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  112. data/lib/sequel/ast_transformer.rb +194 -0
  113. data/lib/sequel/connection_pool/sharded_single.rb +23 -13
  114. data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
  115. data/lib/sequel/connection_pool/single.rb +11 -3
  116. data/lib/sequel/connection_pool/threaded.rb +69 -20
  117. data/lib/sequel/connection_pool.rb +20 -18
  118. data/lib/sequel/core.rb +143 -11
  119. data/lib/sequel/database/connecting.rb +66 -29
  120. data/lib/sequel/database/dataset.rb +4 -4
  121. data/lib/sequel/database/dataset_defaults.rb +63 -2
  122. data/lib/sequel/database/logging.rb +7 -2
  123. data/lib/sequel/database/misc.rb +192 -51
  124. data/lib/sequel/database/query.rb +299 -114
  125. data/lib/sequel/database/schema_generator.rb +103 -36
  126. data/lib/sequel/database/schema_methods.rb +310 -69
  127. data/lib/sequel/dataset/actions.rb +344 -90
  128. data/lib/sequel/dataset/features.rb +101 -8
  129. data/lib/sequel/dataset/graph.rb +42 -15
  130. data/lib/sequel/dataset/misc.rb +52 -25
  131. data/lib/sequel/dataset/mutation.rb +12 -7
  132. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  133. data/lib/sequel/dataset/query.rb +322 -68
  134. data/lib/sequel/dataset/sql.rb +716 -293
  135. data/lib/sequel/dataset.rb +8 -0
  136. data/lib/sequel/exceptions.rb +4 -0
  137. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  138. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  139. data/lib/sequel/extensions/blank.rb +4 -0
  140. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  141. data/lib/sequel/extensions/connection_validator.rb +109 -0
  142. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  143. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  144. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  145. data/lib/sequel/extensions/inflector.rb +4 -0
  146. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  147. data/lib/sequel/extensions/migration.rb +100 -11
  148. data/lib/sequel/extensions/named_timezones.rb +9 -0
  149. data/lib/sequel/extensions/null_dataset.rb +94 -0
  150. data/lib/sequel/extensions/pagination.rb +4 -0
  151. data/lib/sequel/extensions/pg_array.rb +539 -0
  152. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  153. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  154. data/lib/sequel/extensions/pg_hstore.rb +334 -0
  155. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  156. data/lib/sequel/extensions/pg_inet.rb +113 -0
  157. data/lib/sequel/extensions/pg_interval.rb +191 -0
  158. data/lib/sequel/extensions/pg_json.rb +212 -0
  159. data/lib/sequel/extensions/pg_range.rb +513 -0
  160. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  161. data/lib/sequel/extensions/pg_row.rb +576 -0
  162. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  163. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  164. data/lib/sequel/extensions/pretty_table.rb +17 -72
  165. data/lib/sequel/extensions/query.rb +8 -4
  166. data/lib/sequel/extensions/query_literals.rb +79 -0
  167. data/lib/sequel/extensions/schema_caching.rb +76 -0
  168. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  169. data/lib/sequel/extensions/select_remove.rb +39 -0
  170. data/lib/sequel/extensions/server_block.rb +140 -0
  171. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  172. data/lib/sequel/extensions/sql_expr.rb +8 -110
  173. data/lib/sequel/extensions/string_date_time.rb +4 -0
  174. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  175. data/lib/sequel/extensions/to_dot.rb +99 -83
  176. data/lib/sequel/model/associations.rb +1263 -409
  177. data/lib/sequel/model/base.rb +624 -171
  178. data/lib/sequel/model/errors.rb +1 -1
  179. data/lib/sequel/model/exceptions.rb +24 -2
  180. data/lib/sequel/model/inflections.rb +1 -1
  181. data/lib/sequel/model.rb +30 -11
  182. data/lib/sequel/no_core_ext.rb +2 -0
  183. data/lib/sequel/plugins/active_model.rb +13 -1
  184. data/lib/sequel/plugins/association_pks.rb +137 -16
  185. data/lib/sequel/plugins/caching.rb +25 -18
  186. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  187. data/lib/sequel/plugins/composition.rb +44 -12
  188. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  189. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  190. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  191. data/lib/sequel/plugins/dirty.rb +214 -0
  192. data/lib/sequel/plugins/eager_each.rb +59 -0
  193. data/lib/sequel/plugins/force_encoding.rb +6 -6
  194. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  195. data/lib/sequel/plugins/identity_map.rb +134 -15
  196. data/lib/sequel/plugins/instance_filters.rb +10 -0
  197. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  198. data/lib/sequel/plugins/json_serializer.rb +77 -6
  199. data/lib/sequel/plugins/list.rb +13 -2
  200. data/lib/sequel/plugins/many_through_many.rb +103 -51
  201. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  202. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  203. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  204. data/lib/sequel/plugins/pg_row.rb +121 -0
  205. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  206. data/lib/sequel/plugins/prepared_statements.rb +168 -0
  207. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  208. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  209. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  210. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  211. data/lib/sequel/plugins/schema.rb +8 -3
  212. data/lib/sequel/plugins/serialization.rb +98 -49
  213. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  214. data/lib/sequel/plugins/sharding.rb +21 -54
  215. data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
  216. data/lib/sequel/plugins/static_cache.rb +99 -0
  217. data/lib/sequel/plugins/subclasses.rb +29 -3
  218. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  219. data/lib/sequel/plugins/timestamps.rb +1 -1
  220. data/lib/sequel/plugins/touch.rb +18 -6
  221. data/lib/sequel/plugins/tree.rb +3 -3
  222. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  223. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  224. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  225. data/lib/sequel/plugins/validation_helpers.rb +57 -4
  226. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  227. data/lib/sequel/sql.rb +721 -141
  228. data/lib/sequel/timezones.rb +67 -40
  229. data/lib/sequel/version.rb +1 -1
  230. data/spec/adapters/db2_spec.rb +146 -0
  231. data/spec/adapters/firebird_spec.rb +53 -39
  232. data/spec/adapters/mssql_spec.rb +261 -66
  233. data/spec/adapters/mysql_spec.rb +597 -352
  234. data/spec/adapters/oracle_spec.rb +92 -117
  235. data/spec/adapters/postgres_spec.rb +2103 -341
  236. data/spec/adapters/spec_helper.rb +16 -6
  237. data/spec/adapters/sqlite_spec.rb +237 -76
  238. data/spec/core/connection_pool_spec.rb +270 -141
  239. data/spec/core/database_spec.rb +980 -524
  240. data/spec/core/dataset_spec.rb +1658 -1243
  241. data/spec/core/expression_filters_spec.rb +741 -334
  242. data/spec/core/mock_adapter_spec.rb +453 -0
  243. data/spec/core/object_graph_spec.rb +88 -129
  244. data/spec/core/schema_generator_spec.rb +4 -4
  245. data/spec/core/schema_spec.rb +556 -53
  246. data/spec/core/spec_helper.rb +7 -48
  247. data/spec/core_extensions_spec.rb +626 -0
  248. data/spec/extensions/active_model_spec.rb +13 -0
  249. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  250. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  251. data/spec/extensions/association_dependencies_spec.rb +15 -25
  252. data/spec/extensions/association_pks_spec.rb +227 -33
  253. data/spec/extensions/association_proxies_spec.rb +4 -4
  254. data/spec/extensions/boolean_readers_spec.rb +25 -25
  255. data/spec/extensions/caching_spec.rb +47 -51
  256. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  257. data/spec/extensions/columns_introspection_spec.rb +91 -0
  258. data/spec/extensions/composition_spec.rb +18 -13
  259. data/spec/extensions/connection_validator_spec.rb +118 -0
  260. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  261. data/spec/extensions/constraint_validations_spec.rb +316 -0
  262. data/spec/extensions/dataset_associations_spec.rb +199 -0
  263. data/spec/extensions/defaults_setter_spec.rb +88 -0
  264. data/spec/extensions/dirty_spec.rb +155 -0
  265. data/spec/extensions/eager_each_spec.rb +34 -0
  266. data/spec/extensions/eval_inspect_spec.rb +67 -0
  267. data/spec/extensions/force_encoding_spec.rb +4 -2
  268. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  269. data/spec/extensions/identity_map_spec.rb +142 -24
  270. data/spec/extensions/inflector_spec.rb +0 -4
  271. data/spec/extensions/instance_filters_spec.rb +11 -21
  272. data/spec/extensions/instance_hooks_spec.rb +72 -0
  273. data/spec/extensions/json_serializer_spec.rb +49 -12
  274. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  275. data/spec/extensions/list_spec.rb +49 -40
  276. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  277. data/spec/extensions/many_through_many_spec.rb +368 -254
  278. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  279. data/spec/extensions/migration_spec.rb +140 -35
  280. data/spec/extensions/named_timezones_spec.rb +29 -11
  281. data/spec/extensions/nested_attributes_spec.rb +268 -89
  282. data/spec/extensions/null_dataset_spec.rb +85 -0
  283. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  284. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  285. data/spec/extensions/pg_array_spec.rb +324 -0
  286. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  287. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  288. data/spec/extensions/pg_hstore_spec.rb +200 -0
  289. data/spec/extensions/pg_inet_spec.rb +47 -0
  290. data/spec/extensions/pg_interval_spec.rb +72 -0
  291. data/spec/extensions/pg_json_spec.rb +99 -0
  292. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  293. data/spec/extensions/pg_range_spec.rb +395 -0
  294. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  295. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  296. data/spec/extensions/pg_row_spec.rb +340 -0
  297. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  298. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  299. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  300. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  301. data/spec/extensions/prepared_statements_spec.rb +87 -0
  302. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  303. data/spec/extensions/pretty_table_spec.rb +7 -6
  304. data/spec/extensions/query_literals_spec.rb +167 -0
  305. data/spec/extensions/query_spec.rb +9 -3
  306. data/spec/extensions/rcte_tree_spec.rb +50 -43
  307. data/spec/extensions/schema_caching_spec.rb +41 -0
  308. data/spec/extensions/schema_dumper_spec.rb +434 -49
  309. data/spec/extensions/schema_spec.rb +30 -49
  310. data/spec/extensions/select_remove_spec.rb +38 -0
  311. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  312. data/spec/extensions/serialization_spec.rb +86 -48
  313. data/spec/extensions/server_block_spec.rb +90 -0
  314. data/spec/extensions/sharding_spec.rb +69 -143
  315. data/spec/extensions/single_table_inheritance_spec.rb +65 -29
  316. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  317. data/spec/extensions/spec_helper.rb +34 -67
  318. data/spec/extensions/split_array_nil_spec.rb +24 -0
  319. data/spec/extensions/sql_expr_spec.rb +29 -60
  320. data/spec/extensions/static_cache_spec.rb +145 -0
  321. data/spec/extensions/subclasses_spec.rb +14 -0
  322. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  323. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  324. data/spec/extensions/timestamps_spec.rb +6 -6
  325. data/spec/extensions/to_dot_spec.rb +8 -11
  326. data/spec/extensions/touch_spec.rb +53 -14
  327. data/spec/extensions/tree_spec.rb +11 -26
  328. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  329. data/spec/extensions/update_primary_key_spec.rb +30 -24
  330. data/spec/extensions/validation_class_methods_spec.rb +77 -68
  331. data/spec/extensions/validation_helpers_spec.rb +48 -37
  332. data/spec/extensions/xml_serializer_spec.rb +29 -4
  333. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  334. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  335. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  336. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  337. data/spec/integration/associations_test.rb +659 -21
  338. data/spec/integration/database_test.rb +25 -5
  339. data/spec/integration/dataset_test.rb +729 -141
  340. data/spec/integration/eager_loader_test.rb +38 -54
  341. data/spec/integration/migrator_test.rb +2 -3
  342. data/spec/integration/model_test.rb +81 -2
  343. data/spec/integration/plugin_test.rb +871 -160
  344. data/spec/integration/prepared_statement_test.rb +272 -128
  345. data/spec/integration/schema_test.rb +377 -57
  346. data/spec/integration/spec_helper.rb +49 -32
  347. data/spec/integration/timezone_test.rb +38 -12
  348. data/spec/integration/transaction_test.rb +183 -8
  349. data/spec/integration/type_test.rb +40 -8
  350. data/spec/model/association_reflection_spec.rb +207 -8
  351. data/spec/model/associations_spec.rb +1206 -693
  352. data/spec/model/base_spec.rb +334 -100
  353. data/spec/model/dataset_methods_spec.rb +45 -27
  354. data/spec/model/eager_loading_spec.rb +828 -692
  355. data/spec/model/hooks_spec.rb +355 -67
  356. data/spec/model/model_spec.rb +251 -179
  357. data/spec/model/plugins_spec.rb +24 -13
  358. data/spec/model/record_spec.rb +506 -232
  359. data/spec/model/spec_helper.rb +16 -77
  360. data/spec/model/validations_spec.rb +38 -2
  361. data/spec/rcov.opts +2 -0
  362. metadata +223 -81
  363. data/spec/core/core_sql_spec.rb +0 -451
@@ -0,0 +1,451 @@
1
+ # The constraint_validations extension is designed to easily create database
2
+ # constraints inside create_table and alter_table blocks. It also adds
3
+ # relevant metadata about the constraints to a separate table, which the
4
+ # constraint_validations model plugin uses to setup automatic validations.
5
+ #
6
+ # To use this extension, you first need to load it into the database:
7
+ #
8
+ # DB.extension(:constraint_validations)
9
+ #
10
+ # Note that you should only need to do this when modifying the constraint
11
+ # validations (i.e. when migrating). You should probably not load this
12
+ # extension in general application code.
13
+ #
14
+ # You also need to make sure to add the metadata table for the automatic
15
+ # validations. By default, this table is called sequel_constraint_validations.
16
+ #
17
+ # DB.create_constraint_validations_table
18
+ #
19
+ # This table should only be created once. For new applications, you
20
+ # generally want to create it first, before creating any other application
21
+ # tables.
22
+ #
23
+ # Because migrations instance_eval the up and down blocks on a database,
24
+ # using this extension in a migration can be done via:
25
+ #
26
+ # Sequel.migration do
27
+ # up do
28
+ # extension(:constraint_validations)
29
+ # # ...
30
+ # end
31
+ # down do
32
+ # extension(:constraint_validations)
33
+ # # ...
34
+ # end
35
+ # end
36
+ #
37
+ # However, note that you cannot use change migrations with this extension,
38
+ # you need to use separate up/down migrations.
39
+ #
40
+ # The API for creating the constraints with automatic validations is
41
+ # similar to the validation_helpers model plugin API. However,
42
+ # instead of having separate validates_* methods, it just adds a validate
43
+ # method that accepts a block to the schema generators. Like the
44
+ # create_table and alter_table blocks, this block is instance_evaled and
45
+ # offers its own DSL. Example:
46
+ #
47
+ # DB.create_table(:table) do
48
+ # Integer :id
49
+ # String :name
50
+ #
51
+ # validate do
52
+ # presence :id
53
+ # min_length 5, :name
54
+ # end
55
+ # end
56
+ #
57
+ # instance_eval is used in this case because create_table and alter_table
58
+ # already use instance_eval, so losing access to the surrounding receiver
59
+ # is not an issue.
60
+ #
61
+ # Here's a breakdown of the constraints created for each constraint validation
62
+ # method:
63
+ #
64
+ # All constraints except unique unless :allow_nil is true :: CHECK column IS NOT NULL
65
+ # presence (String column) :: CHECK trim(column) != ''
66
+ # exact_length 5 :: CHECK char_length(column) = 5
67
+ # min_length 5 :: CHECK char_length(column) >= 5
68
+ # max_length 5 :: CHECK char_length(column) <= 5
69
+ # length_range 3..5 :: CHECK char_length(column) >= 3 AND char_length(column) <= 5
70
+ # length_range 3...5 :: CHECK char_length(column) >= 3 AND char_length(column) < 5
71
+ # format /foo\\d+/ :: CHECK column ~ 'foo\\d+'
72
+ # format /foo\\d+/i :: CHECK column ~* 'foo\\d+'
73
+ # like 'foo%' :: CHECK column LIKE 'foo%'
74
+ # ilike 'foo%' :: CHECK column ILIKE 'foo%'
75
+ # includes ['a', 'b'] :: CHECK column IN ('a', 'b')
76
+ # includes [1, 2] :: CHECK column IN (1, 2)
77
+ # includes 3..5 :: CHECK column >= 3 AND column <= 5
78
+ # includes 3...5 :: CHECK column >= 3 AND column < 5
79
+ # unique :: UNIQUE (column)
80
+ #
81
+ # There are some additional API differences:
82
+ #
83
+ # * Only the :message and :allow_nil options are respected. The :allow_blank
84
+ # and :allow_missing options are not respected.
85
+ # * A new option, :name, is respected, for providing the name of the constraint. It is highly
86
+ # recommended that you provide a name for all constraint validations, as
87
+ # otherwise, it is difficult to drop the constraints later.
88
+ # * The includes validation only supports an array of strings, and array of
89
+ # integers, and a range of integers.
90
+ # * There are like and ilike validations, which are similar to the format
91
+ # validation but use a case sensitive or case insensitive LIKE pattern. LIKE
92
+ # patters are very simple, so many regexp patterns cannot be expressed by
93
+ # them, but only a couple databases (PostgreSQL and MySQL) support regexp
94
+ # patterns.
95
+ # * When using the unique validation, column names cannot have embedded commas.
96
+ # For similar reasons, when using an includes validation with an array of
97
+ # strings, none of the strings in the array can have embedded commas.
98
+ # * The unique validation does not support an arbitrary number of columns.
99
+ # For a single column, just the symbol should be used, and for an array
100
+ # of columns, an array of symbols should be used. There is no support
101
+ # for creating two separate unique validations for separate columns in
102
+ # a single call.
103
+ # * A drop method can be called with a constraint name in a alter_table
104
+ # validate block to drop an existing constraint and the related
105
+ # validation metadata.
106
+ # * While it is allowed to create a presence constraint with :allow_nil
107
+ # set to true, doing so does not create a constraint unless the column
108
+ # has String type.
109
+ #
110
+ # Note that this extension has the following issues on certain databases:
111
+ #
112
+ # * MySQL does not support check constraints (they are parsed but ignored),
113
+ # so using this extension does not actually set up constraints on MySQL,
114
+ # except for the unique constraint. It can still be used on MySQL to
115
+ # add the validation metadata so that the plugin can setup automatic
116
+ # validations.
117
+ # * On SQLite, adding constraints to a table is not supported, so it must
118
+ # be emulated by dropping the table and recreating it with the constraints.
119
+ # If you want to use this plugin on SQLite with an alter_table block,
120
+ # you should drop all constraint validation metadata using
121
+ # <tt>drop_constraint_validations_for(:table=>'table')</tt>, and then
122
+ # readd all constraints you want to use inside the alter table block,
123
+ # making no other changes inside the alter_table block.
124
+
125
+ module Sequel
126
+ module ConstraintValidations
127
+ # The default table name used for the validation metadata.
128
+ DEFAULT_CONSTRAINT_VALIDATIONS_TABLE = :sequel_constraint_validations
129
+
130
+ # Set the default validation metadata table name if it has not already
131
+ # been set.
132
+ def self.extended(db)
133
+ db.constraint_validations_table ||= DEFAULT_CONSTRAINT_VALIDATIONS_TABLE
134
+ end
135
+
136
+ # This is the DSL class used for the validate block inside create_table and
137
+ # alter_table.
138
+ class Generator
139
+ # Store the schema generator that encloses this validates block.
140
+ def initialize(generator)
141
+ @generator = generator
142
+ end
143
+
144
+ # Create constraint validation methods that don't take an argument
145
+ %w'presence unique'.each do |v|
146
+ class_eval(<<-END, __FILE__, __LINE__+1)
147
+ def #{v}(columns, opts={})
148
+ @generator.validation({:type=>:#{v}, :columns=>Array(columns)}.merge(opts))
149
+ end
150
+ END
151
+ end
152
+
153
+ # Create constraint validation methods that take an argument
154
+ %w'exact_length min_length max_length length_range format like ilike includes'.each do |v|
155
+ class_eval(<<-END, __FILE__, __LINE__+1)
156
+ def #{v}(arg, columns, opts={})
157
+ @generator.validation({:type=>:#{v}, :columns=>Array(columns), :arg=>arg}.merge(opts))
158
+ end
159
+ END
160
+ end
161
+
162
+ # Given the name of a constraint, drop that constraint from the database,
163
+ # and remove the related validation metadata.
164
+ def drop(constraint)
165
+ @generator.validation({:type=>:drop, :name=>constraint})
166
+ end
167
+
168
+ # Alias of instance_eval for a nicer API.
169
+ def process(&block)
170
+ instance_eval(&block)
171
+ end
172
+ end
173
+
174
+ # Additional methods for the create_table generator to support constraint validations.
175
+ module CreateTableGeneratorMethods
176
+ # An array of stored validation metadata, used later by the database to create
177
+ # constraints.
178
+ attr_reader :validations
179
+
180
+ # Add a validation metadata hash to the stored array.
181
+ def validation(opts)
182
+ @validations << opts
183
+ end
184
+
185
+ # Call into the validate DSL for creating constraint validations.
186
+ def validate(&block)
187
+ Generator.new(self).process(&block)
188
+ end
189
+ end
190
+
191
+ # Additional methods for the alter_table generator to support constraint validations,
192
+ # used to give it a more similar API to the create_table generator.
193
+ module AlterTableGeneratorMethods
194
+ include CreateTableGeneratorMethods
195
+
196
+ # Alias of add_constraint for similarity to create_table generator.
197
+ def constraint(*args)
198
+ add_constraint(*args)
199
+ end
200
+
201
+ # Alias of add_unique_constraint for similarity to create_table generator.
202
+ def unique(*args)
203
+ add_unique_constraint(*args)
204
+ end
205
+ end
206
+
207
+ # The name of the table storing the validation metadata. If modifying this
208
+ # from the default, this should be changed directly after loading the
209
+ # extension into the database
210
+ attr_accessor :constraint_validations_table
211
+
212
+ # Create the table storing the validation metadata for all of the
213
+ # constraints created by this extension.
214
+ def create_constraint_validations_table
215
+ create_table(constraint_validations_table) do
216
+ String :table, :null=>false
217
+ String :constraint_name
218
+ String :validation_type, :null=>false
219
+ String :column, :null=>false
220
+ String :argument
221
+ String :message
222
+ TrueClass :allow_nil
223
+ end
224
+ end
225
+
226
+ # Drop the constraint validations table.
227
+ def drop_constraint_validations_table
228
+ drop_table(constraint_validations_table)
229
+ end
230
+
231
+ # Delete validation metadata for specific constraints. At least
232
+ # one of the following options should be specified:
233
+ #
234
+ # :table :: The table containing the constraint
235
+ # :column :: The column affected by the constraint
236
+ # :constraint :: The name of the related constraint
237
+ #
238
+ # The main reason for this method is when dropping tables
239
+ # or columns. If you have previously defined a constraint
240
+ # validation on the table or column, you should delete the
241
+ # related metadata when dropping the table or column.
242
+ # For a table, this isn't a big issue, as it will just result
243
+ # in some wasted space, but for columns, if you don't drop
244
+ # the related metadata, it could make it impossible to save
245
+ # rows, since a validation for a nonexistent column will be
246
+ # created.
247
+ def drop_constraint_validations_for(opts={})
248
+ ds = from(constraint_validations_table)
249
+ if table = opts[:table]
250
+ ds = ds.where(:table=>constraint_validations_literal_table(table))
251
+ end
252
+ if column = opts[:column]
253
+ ds = ds.where(:column=>column.to_s)
254
+ end
255
+ if constraint = opts[:constraint]
256
+ ds = ds.where(:constraint_name=>constraint.to_s)
257
+ end
258
+ unless table || column || constraint
259
+ raise Error, "must specify :table, :column, or :constraint when dropping constraint validations"
260
+ end
261
+ ds.delete
262
+ end
263
+
264
+ private
265
+
266
+ # Modify the default create_table generator to include
267
+ # the constraint validation methods.
268
+ def alter_table_generator(&block)
269
+ super do
270
+ extend AlterTableGeneratorMethods
271
+ @validations = []
272
+ instance_eval(&block) if block
273
+ end
274
+ end
275
+
276
+ # After running all of the table alteration statements,
277
+ # if there were any constraint validations, run table alteration
278
+ # statements to create related constraints. This is purposely
279
+ # run after the other statements, as the presence validation
280
+ # in alter table requires introspecting the modified model
281
+ # schema.
282
+ def apply_alter_table_generator(name, generator)
283
+ super
284
+ unless generator.validations.empty?
285
+ gen = alter_table_generator
286
+ process_generator_validations(name, gen, generator.validations)
287
+ apply_alter_table(name, gen.operations)
288
+ end
289
+ end
290
+
291
+ # The value of a blank string. An empty string by default, but nil
292
+ # on Oracle as Oracle treats the empty string as NULL.
293
+ def blank_string_value
294
+ if database_type == :oracle
295
+ nil
296
+ else
297
+ ''
298
+ end
299
+ end
300
+
301
+ # Return an unquoted literal form of the table name.
302
+ # This allows the code to handle schema qualified tables,
303
+ # without quoting all table names.
304
+ def constraint_validations_literal_table(table)
305
+ ds = dataset
306
+ ds.quote_identifiers = false
307
+ ds.literal(table)
308
+ end
309
+
310
+ # Before creating the table, add constraints for all of the
311
+ # generators validations to the generator.
312
+ def create_table_from_generator(name, generator, options)
313
+ unless generator.validations.empty?
314
+ process_generator_validations(name, generator, generator.validations)
315
+ end
316
+ super
317
+ end
318
+
319
+ # Modify the default create_table generator to include
320
+ # the constraint validation methods.
321
+ def create_table_generator(&block)
322
+ super do
323
+ extend CreateTableGeneratorMethods
324
+ @validations = []
325
+ instance_eval(&block) if block
326
+ end
327
+ end
328
+
329
+ # For the given table, generator, and validations, add constraints
330
+ # to the generator for each of the validations, as well as adding
331
+ # validation metadata to the constraint validations table.
332
+ def process_generator_validations(table, generator, validations)
333
+ drop_rows = []
334
+ rows = validations.map do |val|
335
+ columns, arg, constraint, validation_type, message, allow_nil = val.values_at(:columns, :arg, :name, :type, :message, :allow_nil)
336
+
337
+ case validation_type
338
+ when :presence
339
+ string_check = columns.select{|c| generator_string_column?(generator, table, c)}.map{|c| [Sequel.trim(c), blank_string_value]}
340
+ generator_add_constraint_from_validation(generator, val, (Sequel.negate(string_check) unless string_check.empty?))
341
+ when :exact_length
342
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| {Sequel.char_length(c) => arg}}))
343
+ when :min_length
344
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| Sequel.char_length(c) >= arg}))
345
+ when :max_length
346
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| Sequel.char_length(c) <= arg}))
347
+ when :length_range
348
+ op = arg.exclude_end? ? :< : :<=
349
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| (Sequel.char_length(c) >= arg.begin) & Sequel.char_length(c).send(op, arg.end)}))
350
+ arg = "#{arg.begin}..#{'.' if arg.exclude_end?}#{arg.end}"
351
+ when :format
352
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| {c => arg}}))
353
+ if arg.casefold?
354
+ validation_type = :iformat
355
+ end
356
+ arg = arg.source
357
+ when :includes
358
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| {c => arg}}))
359
+ if arg.is_a?(Range)
360
+ if (b = arg.begin).is_a?(Integer) && (e = arg.end).is_a?(Integer)
361
+ validation_type = :includes_int_range
362
+ arg = "#{arg.begin}..#{'.' if arg.exclude_end?}#{arg.end}"
363
+ else
364
+ raise Error, "validates includes with a range only supports integers currently, cannot handle: #{arg.inspect}"
365
+ end
366
+ elsif arg.is_a?(Array)
367
+ if arg.all?{|x| x.is_a?(Integer)}
368
+ validation_type = :includes_int_array
369
+ elsif arg.all?{|x| x.is_a?(String)}
370
+ validation_type = :includes_str_array
371
+ else
372
+ raise Error, "validates includes with an array only supports strings and integers currently, cannot handle: #{arg.inspect}"
373
+ end
374
+ arg = arg.join(',')
375
+ else
376
+ raise Error, "validates includes only supports arrays and ranges currently, cannot handle: #{arg.inspect}"
377
+ end
378
+ when :like, :ilike
379
+ generator_add_constraint_from_validation(generator, val, Sequel.&(*columns.map{|c| Sequel.send(validation_type, c, arg)}))
380
+ when :unique
381
+ generator.unique(columns, :name=>constraint)
382
+ columns = [columns.join(',')]
383
+ when :drop
384
+ if generator.is_a?(Sequel::Schema::AlterTableGenerator)
385
+ unless constraint
386
+ raise Error, 'cannot drop a constraint validation without a constraint name'
387
+ end
388
+ generator.drop_constraint(constraint)
389
+ drop_rows << [constraint_validations_literal_table(table), constraint.to_s]
390
+ columns = []
391
+ else
392
+ raise Error, 'cannot drop a constraint validation in a create_table generator'
393
+ end
394
+ else
395
+ raise Error, "invalid or missing validation type: #{val.inspect}"
396
+ end
397
+
398
+ columns.map do |column|
399
+ {:table=>constraint_validations_literal_table(table), :constraint_name=>(constraint.to_s if constraint), :validation_type=>validation_type.to_s, :column=>column.to_s, :argument=>(arg.to_s if arg), :message=>(message.to_s if message), :allow_nil=>allow_nil}
400
+ end
401
+ end
402
+
403
+ ds = from(:sequel_constraint_validations)
404
+ ds.multi_insert(rows.flatten)
405
+ unless drop_rows.empty?
406
+ ds.where([:table, :constraint_name]=>drop_rows).delete
407
+ end
408
+ end
409
+
410
+ # Add the constraint to the generator, including a NOT NULL constraint
411
+ # for all columns unless the :allow_nil option is given.
412
+ def generator_add_constraint_from_validation(generator, val, cons)
413
+ unless val[:allow_nil]
414
+ nil_cons = Sequel.negate(val[:columns].map{|c| [c, nil]})
415
+ cons = cons ? Sequel.&(nil_cons, cons) : nil_cons
416
+ end
417
+
418
+ if cons
419
+ generator.constraint(val[:name], cons)
420
+ end
421
+ end
422
+
423
+
424
+ # Introspect the generator to determine if column
425
+ # created is a string or not.
426
+ def generator_string_column?(generator, table, c)
427
+ if generator.is_a?(Sequel::Schema::AlterTableGenerator)
428
+ # This is the alter table case, which runs after the
429
+ # table has been altered, so just check the database
430
+ # schema for the column.
431
+ schema(table).each do |col, sch|
432
+ if col == c
433
+ return sch[:type] == :string
434
+ end
435
+ end
436
+ false
437
+ else
438
+ # This is the create table case, check the metadata
439
+ # for the column to be created to see if it is a string.
440
+ generator.columns.each do |col|
441
+ if col[:name] == c
442
+ return [String, :text, :varchar].include?(col[:type])
443
+ end
444
+ end
445
+ false
446
+ end
447
+ end
448
+ end
449
+
450
+ Database.register_extension(:constraint_validations, ConstraintValidations)
451
+ end
@@ -1,3 +1,19 @@
1
+ # These are extensions to core classes that Sequel enables by default.
2
+ # They make using Sequel's DSL easier by adding methods to Array,
3
+ # Hash, String, and Symbol to add methods that return Sequel
4
+ # expression objects.
5
+ #
6
+ # This extension is currently loaded by default, but that will no
7
+ # longer be true in a future version. In a future version, you will
8
+ # need to load it manually via:
9
+ #
10
+ # Sequel.extension :core_extensions
11
+
12
+ # This extension loads the core extensions.
13
+ def Sequel.core_extensions?
14
+ true
15
+ end
16
+
1
17
  # Sequel extends +Array+ to add methods to implement the SQL DSL.
2
18
  # Most of these methods require that the array not be empty and that it
3
19
  # must consist solely of other arrays that have exactly two elements.
@@ -8,20 +24,7 @@ class Array
8
24
  # ~[[:a, true]] # SQL: a IS NOT TRUE
9
25
  # ~[[:a, 1], [:b, [2, 3]]] # SQL: a != 1 OR b NOT IN (2, 3)
10
26
  def ~
11
- sql_expr_if_all_two_pairs(:OR, true)
12
- end
13
-
14
- # +true+ if the array is not empty and all of its elements are
15
- # arrays of size 2, +false+ otherwise. This is used to determine if the array
16
- # could be a specifier of conditions, used similarly to a hash
17
- # but allowing for duplicate keys and a specific order.
18
- #
19
- # [].to_a.all_two_pairs? # => false
20
- # [:a].to_a.all_two_pairs? # => false
21
- # [[:b]].to_a.all_two_pairs? # => false
22
- # [[:a, 1]].to_a.all_two_pairs? # => true
23
- def all_two_pairs?
24
- !empty? && all?{|i| (Array === i) && (i.length == 2)}
27
+ Sequel.~(self)
25
28
  end
26
29
 
27
30
  # Return a <tt>Sequel::SQL::CaseExpression</tt> with this array as the conditions and the given
@@ -59,7 +62,7 @@ class Array
59
62
  # [[:a, true]].sql_expr # SQL: a IS TRUE
60
63
  # [[:a, 1], [:b, [2, 3]]].sql_expr # SQL: a = 1 AND b IN (2, 3)
61
64
  def sql_expr
62
- sql_expr_if_all_two_pairs
65
+ Sequel.expr(self)
63
66
  end
64
67
 
65
68
  # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, matching none
@@ -68,7 +71,7 @@ class Array
68
71
  # [[:a, true]].sql_negate # SQL: a IS NOT TRUE
69
72
  # [[:a, 1], [:b, [2, 3]]].sql_negate # SQL: a != 1 AND b NOT IN (2, 3)
70
73
  def sql_negate
71
- sql_expr_if_all_two_pairs(:AND, true)
74
+ Sequel.negate(self)
72
75
  end
73
76
 
74
77
  # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, matching any of the
@@ -77,10 +80,10 @@ class Array
77
80
  # [[:a, true]].sql_or # SQL: a IS TRUE
78
81
  # [[:a, 1], [:b, [2, 3]]].sql_or # SQL: a = 1 OR b IN (2, 3)
79
82
  def sql_or
80
- sql_expr_if_all_two_pairs(:OR)
83
+ Sequel.or(self)
81
84
  end
82
85
 
83
- # Return a <tt>Sequel::SQL::BooleanExpression</tt> representing an SQL string made up of the
86
+ # Return a <tt>Sequel::SQL::StringExpression</tt> representing an SQL string made up of the
84
87
  # concatenation of this array's elements. If an argument is passed
85
88
  # it is used in between each element of the array in the SQL
86
89
  # concatenation.
@@ -90,22 +93,7 @@ class Array
90
93
  # [:a, 'b'].sql_string_join # SQL: a || 'b'
91
94
  # ['a', :b].sql_string_join(' ') # SQL: 'a' || ' ' || b
92
95
  def sql_string_join(joiner=nil)
93
- if joiner
94
- args = zip([joiner]*length).flatten
95
- args.pop
96
- else
97
- args = self
98
- end
99
- args = args.collect{|a| [Symbol, ::Sequel::SQL::Expression, ::Sequel::LiteralString, TrueClass, FalseClass, NilClass].any?{|c| a.is_a?(c)} ? a : a.to_s}
100
- ::Sequel::SQL::StringExpression.new(:'||', *args)
101
- end
102
-
103
- private
104
-
105
- # Raise an error if this array is not made up all two element arrays, otherwise create a <tt>Sequel::SQL::BooleanExpression</tt> from this array.
106
- def sql_expr_if_all_two_pairs(*args)
107
- raise(Sequel::Error, 'Not all elements of the array are arrays of size 2, so it cannot be converted to an SQL expression') unless all_two_pairs?
108
- ::Sequel::SQL::BooleanExpression.from_value_pairs(self, *args)
96
+ Sequel.join(self, joiner)
109
97
  end
110
98
  end
111
99
 
@@ -211,28 +199,24 @@ end
211
199
 
212
200
  # Sequel extends +Symbol+ to add methods to implement the SQL DSL.
213
201
  class Symbol
214
- include Sequel::SQL::QualifyingMethods
215
- include Sequel::SQL::IdentifierMethods
216
202
  include Sequel::SQL::AliasMethods
217
203
  include Sequel::SQL::CastMethods
218
204
  include Sequel::SQL::OrderMethods
219
205
  include Sequel::SQL::BooleanMethods
220
206
  include Sequel::SQL::NumericMethods
207
+ include Sequel::SQL::QualifyingMethods
221
208
  include Sequel::SQL::StringMethods
222
209
  include Sequel::SQL::SubscriptMethods
223
210
  include Sequel::SQL::ComplexExpressionMethods
224
211
  include Sequel::SQL::InequalityMethods if RUBY_VERSION < '1.9.0'
225
212
 
226
- # If no argument is given, returns a <tt>Sequel::SQL::ColumnAll</tt> object specifying all
227
- # columns for this table.
228
- # If an argument is given, returns a <tt>Sequel::SQL::NumericExpression</tt> using the *
229
- # (multiplication) operator with this and the given argument.
230
- #
231
- # :table.* # SQL: table.*
232
- # :column * 2 # SQL: column * 2
233
- def *(ce=(arg=false;nil))
234
- return super(ce) unless arg == false
235
- Sequel::SQL::ColumnAll.new(self);
213
+ # Returns receiver wrapped in an <tt>Sequel::SQL::Identifier</tt>. Usually used to
214
+ # prevent splitting the symbol.
215
+ #
216
+ # :a__b # SQL: "a"."b"
217
+ # :a__b.identifier # SQL: "a__b"
218
+ def identifier
219
+ Sequel::SQL::Identifier.new(self)
236
220
  end
237
221
 
238
222
  # Returns a <tt>Sequel::SQL::Function</tt> with this as the function name,