sequel 3.21.0 → 3.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
@@ -0,0 +1,172 @@
1
+ = New Features
2
+
3
+ * Sequel now allows dynamic customization for eager loading.
4
+ Previously, the parameters for eager loading were fixed at
5
+ association creation time. Now, they can be modified at query
6
+ time. To dynamically modify an eager load, you use a hash with
7
+ the proc as the value. For example, if you have this code:
8
+
9
+ Artist.eager(:albums)
10
+
11
+ And you only want to eagerly load albums where the id is greater
12
+ than or equal to some number provided by the user, you do:
13
+
14
+ min = params[:min].to_i
15
+ Artist.eager(:albums=>proc{|ds| ds.where{id > min}})
16
+
17
+ This also works when eager loading via eager_graph:
18
+
19
+ Artist.eager_graph(:albums=>proc{|ds| ds.where{id > min}})
20
+
21
+ For eager_graph, the dataset is the dataset to graph into the
22
+ current dataset, and filtering it will result in an SQL query
23
+ that joins to a subquery.
24
+
25
+ You can also use dynamic customization while cascading to also
26
+ eagerly load dependent associations, by making the hash value
27
+ a single entry hash with a proc key and the value being the
28
+ dependent associations to eagerly load. For example, if you want
29
+ to eagerly load tracks for those albums:
30
+
31
+ Artist.eager(:albums=>{proc{|ds| ds.where{id > min}}=>:tracks})
32
+
33
+ * Sequel also now allows dynamic customization for regular
34
+ association loading. Previously, this was possible by using the
35
+ association's dataset:
36
+
37
+ albums = artist.albums_dataset.filter{id > min}
38
+
39
+ However, then there was no handling of caching, callbacks, or
40
+ reciprocals. For example:
41
+
42
+ albums.each{|album| album.artist}
43
+
44
+ Would issue one query per album to get the artist, because the
45
+ reciprocal association was not set. Now you can provide a
46
+ block to the association method:
47
+
48
+ albums = artist.albums{|ds| ds.filter{id > min}}
49
+
50
+ This block is called with the dataset used to retrieve the
51
+ associated objects, and should return a modified version of that
52
+ dataset.
53
+
54
+ Note that ruby 1.8.6 doesn't allow blocks to take block arguments,
55
+ so you have to pass the block as a separate proc argument to the
56
+ association method if you are still using 1.8.6.
57
+
58
+ * Sequel now supports filtering by associations. This wasn't
59
+ previously supported as filtering is a dataset level feature and
60
+ associations are a model level feature, and datasets do not depend
61
+ on models. Now, model datasets have the ability to filter by
62
+ associations. For example, to get all albums for a given artist,
63
+ you could do:
64
+
65
+ artist = Artist[1]
66
+ Album.filter(:artist=>artist)
67
+
68
+ Since the above can also be accomplished with:
69
+
70
+ artist.albums
71
+
72
+ this may not seem like a big improvement, but it allows you to
73
+ filter on multiple associations simultaneously:
74
+
75
+ Album.filter(:artist=>artist, :publisher=>publisher)
76
+
77
+ For simple many_to_one associations, the above is just a simpler
78
+ way to do:
79
+
80
+ Album.filter(:artist_id=>artist.id, :publisher_id=>publisher.id)
81
+
82
+ Sequel supports this for all association types, including
83
+ many_to_many and many_through_many, where a subquery is used, and
84
+ it also works when composite key associations are used:
85
+
86
+ Album.filter(:artist=>artist, :tags=>tag)
87
+
88
+ This will give you the albums for that artist that are also tagged
89
+ with that tag. To provide multiple values for the same
90
+ association, mostly useful for many_to_many associations, you can
91
+ either use separate filter calls or specify the conditions as an
92
+ array:
93
+
94
+ Album.filter(:tags=>tag1).filter(:tags=>tag2)
95
+ Album.filter([[:tags, tag1], [:tags, tag2]])
96
+
97
+ * A columns_introspection extension has been added that makes
98
+ datasets attempt to guess their columns in some cases instead of
99
+ issuing a database query. This can improve performance in cases
100
+ where the columns are needed implicitly, such as graphing. After
101
+ loading the extension, you can enable the support for specific
102
+ datasets by extending them with Sequel::ColumnIntrospection. To
103
+ enable introspection for all datasets, use:
104
+
105
+ Sequel::Dataset.introspect_all_columns
106
+
107
+ * A serialization_modification_detection plugin has been added.
108
+ Previously, Sequel could not detect modifications made to
109
+ serialized objects. It could detect modification if you assigned
110
+ a new value:
111
+
112
+ model.hash_column = model.hash_column.merge(:foo=>:bar)
113
+
114
+ but not if you just modified the object directly:
115
+
116
+ model.hash_columns[:foo] = :bar
117
+
118
+ With this plugin, such modifications can be detected, at a
119
+ potentially significant performance cost.
120
+
121
+ = Other Improvements
122
+
123
+ * When using a migration directory containing both older integer
124
+ migrations and newer timestamp migrations, where some integer
125
+ migrations have not been applied, make sure to apply the remaining
126
+ integer migrations before the timestamp migrations. Previously,
127
+ they could be applied out of order due to a lexicographic sort
128
+ being used instead of a numeric sort.
129
+
130
+ * If a model does not select all columns from its table, the
131
+ insert_select optimization is no longer used. Previously,
132
+ creating a new model object for such a model could result in the
133
+ object containing columns that the model does not select.
134
+
135
+ * You can now use :select=>[] as an option for many_to_many
136
+ associations to select all columns from both the associated
137
+ table and the join table. Previously, this raised an error and
138
+ required you do :select=>'*'.lit as a workaround. The default
139
+ remains to select all columns in the associated table and none
140
+ from the join table.
141
+
142
+ * The xml_serializer plugin now handles namespaced models by
143
+ using __ instead of / as the namespace separator. Previously, /
144
+ was used and caused problems as it is not valid XML.
145
+
146
+ * The :eager_grapher association option can now accept a proc that
147
+ takes a single hash of options instead of a fixed 3 arguments.
148
+ This is the recommended way going forward of writing custom
149
+ :eager_graphers, and all of the internal ones have been converted.
150
+ The previous way of using 3 arguments is still supported.
151
+
152
+ * A bug in the identity_map plugin for many_to_one associations
153
+ without full association reflection information has been fixed.
154
+
155
+ * Sequel is now using GitHub Issues for issue tracking. Old issues
156
+ have been migrated from Google Code.
157
+
158
+ = Backwards Compatibility
159
+
160
+ * The filter by associations support breaks backward compatibilty for
161
+ users who previously added an sql_literal instance method to
162
+ Sequel::Model. Usually, that was done to for reasons similar to
163
+ but inferior than the filter by association support. The following
164
+ code can be used as a temporary workaround until you can modify
165
+ your program to use the new filter by associations support:
166
+
167
+ Sequel::Model::Associations::DatasetMethods.
168
+ send(:remove_method, :complex_expression_sql)
169
+
170
+ * The private Sequel::Model#_load_associated_objects method now takes
171
+ an additional, optional options hash. Plugins that override that
172
+ method need to be modified.
@@ -0,0 +1,420 @@
1
+ = Prepared Statement Plugins
2
+
3
+ * The prepared_statements plugin makes Sequel::Model classes use
4
+ prepared statements for creating, updating, and destroying model
5
+ instances, as well as looking up model objects by primary key.
6
+ With this plugin, all of the following will use prepared
7
+ statements:
8
+
9
+ Artist.plugin :prepared_statements
10
+ Artist.create(:name=>'Foo')
11
+ a = Artist[1]
12
+ a.update(:name=>'Bar')
13
+ a.destroy
14
+
15
+ * The prepared_statements_safe plugin reduces the number of
16
+ prepared statements that can be created by doing two things. First,
17
+ it makes the INSERT statements used when creating instances to use
18
+ as many columns as possible, setting specific values for all
19
+ columns with parseable default values. Second, it changes
20
+ save_changes to just use save, saving all columns instead of just
21
+ the changed ones.
22
+
23
+ The reason for this plugin is that Sequel's default behavior of
24
+ using only the values specifically set when creating instances
25
+ and having update only set changed columns by default can lead
26
+ to a large number of prepared statements being created.
27
+
28
+ For prepared statements to be used, each set of columns in the
29
+ insert and update statements needs to have its own prepared
30
+ statement. If you have a table with 1 primary key column and
31
+ 4 other columns, you can have up to 2^4 = 16 prepared statements
32
+ created, one for each subset of the 4 columns. If you have 1
33
+ primary key column and 20 other columns, there are over a million
34
+ subsets, and you could hit your database limit for prepared
35
+ statements (a denial of service attack).
36
+
37
+ Using the prepared_statements_safe plugin mitigates this
38
+ issue by reducing the number of columns that may or may not be
39
+ present in the query, in many cases making sure that each model
40
+ will only have a single INSERT and a single UPDATE prepared
41
+ statement.
42
+
43
+ * The prepared_statements_associations plugin allows normal
44
+ association method calls to use prepared statements if possible.
45
+ For example:
46
+
47
+ Artist.plugin :prepared_statements_associations
48
+ Artist.many_to_one :albums
49
+ Artist[1].albums
50
+
51
+ Will use a prepared statement to return the albums for that artist.
52
+ This plugin works for all supported association types. There are
53
+ some associations (filtered and custom associations) that Sequel
54
+ cannot currently use a prepared statement reliably, for those
55
+ Sequel will use a regular query.
56
+
57
+ * The prepared_statements_with_pk plugin allows the new
58
+ Dataset#with_pk method (explained below) to use prepared statements.
59
+ For example:
60
+
61
+ Artist.plugin :prepared_statements_with_pk
62
+ Artist.filter(...).with_pk(1)
63
+
64
+ Will use a prepared statement for this query. The most benefit
65
+ from prepared statements come from queries that are expensive to
66
+ parse and plan but quick to execute, so using this plugin with
67
+ a complex filter can in certain cases yield significant performance
68
+ improvements.
69
+
70
+ However, this plugin should be considered unsafe as it is possible
71
+ that it will create an unbounded number of prepared statements. It
72
+ extracts parameters from the dataset using Dataset#unbind
73
+ (explained below), so if your code has conditions that vary per
74
+ query but that Dataset#unbind does not handle, an unbounded number
75
+ of prepared statements can be created. For example:
76
+
77
+ Artist.filter(:a=>params[:b].to_i).with_pk[1]
78
+ Artist.exclude{a > params[:b].to_i}.with_pk[1]
79
+
80
+ are safe, but:
81
+
82
+ Artist.filter(:a=>[1, params[:b].to_i]).with_pk[1]
83
+ Artist.exclude{a > params[:b].to_i + 2}.with_pk[1]
84
+
85
+ are not. For queries that are not safe, Dataset#with_pk should
86
+ not be used with this plugin, you should switch to looking up by
87
+ primary key manually (for a regular query):
88
+
89
+ Artist.filter(:a=>[1, params[:b].to_i])[:id=>1]
90
+
91
+ or using the prepared statement API to create a custom prepared
92
+ statement:
93
+
94
+ # PS = {}
95
+ PS[:name] ||= Artist.filter(:a=>[1, :$b], :id=>:$id).
96
+ prepare(:select, :name)
97
+ PS[:name].call(:b=>params[:b].to_i, :id=>1)
98
+
99
+ = Other New Features
100
+
101
+ * Filtering by associations got a lot more powerful. Sequel 3.23.0
102
+ introduced filtering by associations:
103
+
104
+ Album.filter(:artist=>artist)
105
+
106
+ This capability is much expanded in 3.24.0, allowing you to
107
+ exclude by associations:
108
+
109
+ Album.exclude(:artist=>artist)
110
+
111
+ This will match all albums not by that artist.
112
+
113
+ You can also filter or exclude by multiple associated objects:
114
+
115
+ Album.filter(:artist=>[artist1, artist2])
116
+ Album.exclude(:artist=>[artist1, artist2])
117
+
118
+ The filtered dataset will match all albums by either of those
119
+ two artists, and the excluded dataset will match all albums not
120
+ by either of those two artists.
121
+
122
+ You can also filter or exclude by using a model dataset:
123
+
124
+ Album.filter(:artist=>Artist.filter(:name.like('A%'))).all
125
+ Album.exclude(:artist=>Artist.filter(:name.like('A%'))).all
126
+
127
+ Here the filtered dataset will match all albums where the
128
+ associated artist has a name that begins with A, and the excluded
129
+ dataset will match all albums where the associated artist does not
130
+ have a name that begins with A.
131
+
132
+ All of these types of filtering and excluding work with all of
133
+ association types that ship with Sequel, even the many_through_many
134
+ plugin.
135
+
136
+ * Sequel now supports around hooks, which wrap the related before
137
+ hook, behavior, and after hook. Like other Sequel hooks, these
138
+ are implemented as instance methods. For example, if you wanted
139
+ to log DatabaseErrors raised during save:
140
+
141
+ class Artist < Sequel::Model
142
+ def around_save
143
+ super
144
+ rescue Sequel::DatabaseError => e
145
+ # log the error
146
+ raise
147
+ end
148
+ end
149
+
150
+ All around hooks should call super, not yield. If an around hook
151
+ doesn't call super or yield, it is treated as a hook failure,
152
+ similar to before hooks returning false.
153
+
154
+ For around_validation, the return value of super should be whether
155
+ the object is valid. For other around hooks, the return value of
156
+ super is currently true, but it's possible that will change in the
157
+ future.
158
+
159
+ * Dataset#with_pk has been added to model datasets that allows you
160
+ to find the object with the matching primary key:
161
+
162
+ Artist.filter(:name.like('A%')).with_pk(1)
163
+
164
+ This should make easier the common case where you want to find
165
+ a particular object that is associated to another object:
166
+
167
+ Artist[1].albums_dataset.with_pk(2)
168
+
169
+ Before, there was no way to do that without manually specifying
170
+ the primary key:
171
+
172
+ Artist[1].albums_dataset[:id=>2]
173
+
174
+ To use a composite primary key with with_pk, you have to provide
175
+ an array:
176
+
177
+ Artist[1].albums_dataset.with_pk([1, 2])
178
+
179
+ * Dataset#[] for model datasets will now call with_pk if given a
180
+ single Integer argument. This makes the above case even easier:
181
+
182
+ Artist[1].albums_dataset[2]
183
+
184
+ Note that for backwards compatibility, this only works for
185
+ single integer primary keys. If you have a composite primary key
186
+ or a string/varchar primary key, you have to use with_pk.
187
+
188
+ * Dataset#unbind has been added, which allows you to take a dataset
189
+ that uses static bound values and convert them to placeholders.
190
+ Currently, the only cases handled are SQL::ComplexExpression
191
+ objects that use a =, !=, <, >, <=, or >= operator where the first
192
+ argument is a Symbol, SQL::Indentifier, or
193
+ SQL::QualifiedIdentifier, and the second argument is a Numeric,
194
+ String, Date, or Time. Dataset#unbind returns a two element array,
195
+ where the first element is a modified copy of the receiver, and the
196
+ second element is a bound variable hash:
197
+
198
+ ds, bv = DB[:table].filter(:a=>1).unbind
199
+ ds # DB[:table].filter(:a=>:$a)
200
+ bv # {:a=>1}
201
+
202
+ The purpose of doing this is that you can then use prepare or call
203
+ on the returned dataset with the returned bound variables:
204
+
205
+ ds.call(:select, bv)
206
+ # SELECT * FROM table WHERE (a = ?); [1]
207
+
208
+ ps = ds.prepare(:select, :ps_name)
209
+ # PREPARE ps_name AS SELECT * FROM table WHERE (a = ?)
210
+ ps.call(bv)
211
+ # EXECUTE ps_name(1)
212
+
213
+ Basically, Dataset#unbind takes a specific statement and attempts
214
+ to turn it into a generic statement, along with the placeholder
215
+ values it extracted.
216
+
217
+ Unfortunately, Dataset#unbind cannot handle all cases. For
218
+ example:
219
+
220
+ DB[:table].filter{a + 1 > 10}.unbind
221
+
222
+ will not unbind any values. Also, if you have a query with
223
+ multiple different values for a variable, it will raise an
224
+ UnbindDuplicate exception:
225
+
226
+ DB[:table].filter(:a=>1).or(:a=>2).unbind
227
+
228
+ * A defaults_setter plugin has been added that makes it easy to
229
+ automatically set default values when creating new objects. This
230
+ plugin makes Sequel::Model behave more like ActiveRecord in that
231
+ new model instances (before saving) will have default values
232
+ parsed from the database. Unlike ActiveRecord, only values with
233
+ non-NULL defaults are set. Also, Sequel allows you to easily
234
+ modify the default values used:
235
+
236
+ Album.plugin :default_values
237
+ Album.new.values # {:copies_sold => 0}
238
+ Album.default_values[:copies_sold] = 42
239
+ Album.new.values # {:copies_sold => 42}
240
+
241
+ Before, this was commonly done in an after_initialize hook, but
242
+ that's slower as it is also called for model instances loaded from
243
+ the database.
244
+
245
+ * A Database#views method has been added that returns an array
246
+ of symbols representing view names in the database. This works
247
+ just like Database#tables except it returns views.
248
+
249
+ * A Sequel::ASTTransformer class was added that makes it easy to
250
+ write custom transformers of Sequel's internal abstract syntax
251
+ trees. Dataset#qualify now uses a subclass of ASTTransformer to do
252
+ its transformations, as does the new Dataset#unbind.
253
+
254
+ = Other Improvements
255
+
256
+ * Database#create_table? now uses a single query with IF NOT EXISTS
257
+ if the database supports such syntax. Previously, it issued a
258
+ SELECT query to determine table existence. Sequel currently
259
+ supports this syntax on MySQL, H2, and SQLite 3.3.0+.
260
+
261
+ The Database#supports_create_table_if_not_exists? method was added
262
+ to allow users to determine whether this syntax is supported.
263
+
264
+ * Multiple column IN/NOT IN emulation now works correctly with
265
+ model datasets (or other datasets that use a row_proc).
266
+
267
+ * You can now correctly invert SQL::Constant instances:
268
+
269
+ Sequel::NULL # NULL
270
+ ~Sequel::NULL # NOT NULL
271
+ Sequel::TRUE # TRUE
272
+ ~Sequel::TRUE # FALSE
273
+
274
+ * A bug in the association_pks plugin has been fixed in the case
275
+ where the associated table had a different primary key column name
276
+ than the current table.
277
+
278
+ * The emulated prepared statement support now supports nil and false
279
+ as bound values.
280
+
281
+ * The to_dot extension was refactored for greater readability. The
282
+ only change was a small fix in the display for SQL::Subscript
283
+ instances.
284
+
285
+ * The Dataset#supports_insert_select? method is now available to let
286
+ you know if the dataset supports insert_select. You should use
287
+ this method instead of respond_to? for checking for insert_select
288
+ support.
289
+
290
+ * Prepared statements/bound variable can now use a new :insert_select
291
+ type for preparing a statement that will insert a row and return
292
+ the row inserted, if the dataset supports insert_select.
293
+
294
+ * The Model#initialize_set private method now exists for easier plugin
295
+ writing. It is only called for new model objects, with the hash
296
+ given to initialize. By default, it just calls set.
297
+
298
+ * A small bug when creating anonymous subclasses of Sequel::Model on
299
+ ruby 1.9 has been fixed.
300
+
301
+ * If Thread#kill is used inside a transaction on ruby 1.8 or
302
+ rubinius, the transaction is rolled back. This situation is not
303
+ handled correctly on JRuby or ruby 1.9, and I'm not sure it's
304
+ possible to handle correctly on those implementations.
305
+
306
+ * The postgres adapter now supports the
307
+ Sequel::Postgres::PG_NAMED_TYPES hash for associating conversion
308
+ procs for custom types that don't necessarily have the same type
309
+ oid on different databases. This hash uses symbol keys and
310
+ proc values:
311
+
312
+ Sequel::Postgres::PG_NAMED_TYPES[:interval] = proc{|v| ...}
313
+
314
+ The conversion procs now use a separate hash per Database object
315
+ instead of a hash shared across all Database objects. You
316
+ can now modify the types for a particular Database object, but
317
+ you have to use the type oid:
318
+
319
+ DB.conversion_procs[42] = proc{|v| ...}
320
+
321
+ * On SQLite and MSSQL, literalization of true and false values given
322
+ directly to Dataset#filter has been fixed. So the following now
323
+ works correctly on those databases:
324
+
325
+ DB[:table].filter(true)
326
+ DB[:table].filter(false)
327
+
328
+ Unfortunately, because SQLite and MSSQL don't have a real boolean
329
+ type, these will not work:
330
+
331
+ DB[:table].filter{a & true}
332
+ DB[:table].filter{a & false}
333
+
334
+ You currently have to work around the issue by doing:
335
+
336
+ DB[:table].filter{a & Sequel::TRUE}
337
+ DB[:table].filter{a & Sequel::FALSE}
338
+
339
+ It is possible that a future version of Sequel will remove the need
340
+ for this workaround, but that requires having a separate
341
+ literalization method specific to filters.
342
+
343
+ * The MySQL bit type is no longer treated as a boolean. On MySQL, the
344
+ bit type is a bitfield, which is very different than the MSSQL bit
345
+ type, which is the closest thing to a boolean on MSSQL.
346
+
347
+ * The bool database type is now recognized as a boolean. Some SQLite
348
+ databases use bool, such as the ones used in Firefox.
349
+
350
+ * SQL_AUTO_IS_NULL=0 is now set by default when connecting to MySQL
351
+ using the swift or jdbc adapters. Previously, it was only set by
352
+ default when using the mysql or mysql2 adapters.
353
+
354
+ * Dataset#limit now works correctly on Access, using the TOP syntax.
355
+
356
+ * Dataset#limit now works correctly on DB2, using the FETCH FIRST
357
+ syntax.
358
+
359
+ * The jdbc mssql subadapter was split into separate subadapters for
360
+ sqlserver (using Microsoft's driver) and jtds (using the open
361
+ source JTDS driver).
362
+
363
+ * The jdbc jtds subadapter now supports converting Java CLOB
364
+ objects to ruby strings.
365
+
366
+ * Tables from the INFORMATION_SCHEMA are now ignored when parsing
367
+ schema on JDBC.
368
+
369
+ * The informix adapter has been split into shared/specific parts, and
370
+ a jdbc informix subadapter has been added.
371
+
372
+ * Dataset#insert_select now works correctly on MSSQL when the core
373
+ extensions are disabled.
374
+
375
+ * The sqlite adapter now logs when preparing a statement.
376
+
377
+ * You no longer need to be a PostgreSQL superuser to run the postgres
378
+ adapter specs.
379
+
380
+ * The connection pool specs are now about 10 times faster and not
381
+ subject to race conditions due to using Queues instead of
382
+ sleeping.
383
+
384
+ = Backwards Compatibility
385
+
386
+ * Model#save no longer calls Model#valid?. It now calls the
387
+ Model#_valid? private method that Model#valid? also calls. To mark
388
+ a model instance invalid, you should override the Model#validate
389
+ method and add validation errors to the object.
390
+
391
+ * The BeforeHookFailure exception class has been renamed to
392
+ HookFailure since hook failures can now be raised by around hooks
393
+ that don't call super. BeforeHookFailure is now an alias to
394
+ HookFailure, so no code should break, but you should update your
395
+ code to reflect the new name.
396
+
397
+ * Any custom argument mappers used for prepared statements now need
398
+ to implement the prepared_arg? private instance method and have it
399
+ return true.
400
+
401
+ * If your databases uses bit as a boolean type and isn't MSSQL, it's
402
+ possible that those columns will no longer be treated as booleans.
403
+ Please report such an issue on the bugtracker.
404
+
405
+ * It is possible that the filtering and excluding by association
406
+ datasets will break backwards compatibility in some apps. This can
407
+ only occur if you are using a symbol with the same name as an
408
+ association with a model dataset whose model is the same as the
409
+ associated class. As associations almost never have the same names
410
+ as columns, this would require either aliasing or joining to
411
+ another table. If for some reason this does break your app, you
412
+ can work around it by changing the symbol to an SQL::Identifier or
413
+ a literal string.
414
+
415
+ * The Sequel::Postgres.use_iso_date_format= method now only affects
416
+ future Database objects.
417
+
418
+ * On MySQL, Database#tables no longer returns view names, it only
419
+ returns table names. You have to use Database#views to get view
420
+ names now.
@@ -0,0 +1,88 @@
1
+ = New Features
2
+
3
+ * drop_table, drop_view, drop_column, and drop_constraint all now
4
+ support a :cascade option for using CASCADE.
5
+
6
+ DB.drop_table(:tab, :cascade=>true)
7
+ # DROP TABLE tab CASCADE
8
+
9
+ DB.drop_column(:tab, :col, :cascade=>true)
10
+ # ALTER TABLE tab DROP COLUMN col CASCADE
11
+
12
+ A few databases support CASCADE for dropping tables and views,
13
+ but only PostgreSQL appears to support it for columns and
14
+ constraints. Using the :cascade option when the underlying
15
+ database doesn't support it will probably result in a
16
+ DatabaseError being raised.
17
+
18
+ * You can now use datasets as expressions, allowing things such as:
19
+
20
+ DB[:table1].select(:column1) > DB[:table2].select(:column2)
21
+ # (SELECT column1 FROM table1) > (SELECT column2 FROM table2)
22
+
23
+ DB[:table1].select(:column1).cast(Integer)
24
+ # CAST((SELECT column1 FROM table1) AS integer)
25
+
26
+ * Dataset#select_group has been added for grouping and selecting on
27
+ the same columns.
28
+
29
+ DB[:a].select_group(:b, :c)
30
+ # SELECT b, c FROM a GROUP BY b, c
31
+
32
+ * Dataset#exclude_where and #exclude_having methods have been added,
33
+ allowing you to specify which clause to affect. #exclude's
34
+ behavior is still to add to the HAVING clause if one is present,
35
+ and use the WHERE clause otherwise.
36
+
37
+ * Dataset#select_all now accepts optional arguments and will select
38
+ all columns from those arguments if present:
39
+
40
+ DB[:a].select_all(:a)
41
+ # SELECT a.* FROM a
42
+
43
+ DB.from(:a, :b).select_all(:a, :b)
44
+ # SELECT a.*, b.* FROM a, b
45
+
46
+ * Dataset#group and #group_and_count now both accept virtual row
47
+ blocks:
48
+
49
+ DB[:a].select(:b).group{c(d)}
50
+ # SELECT b FROM a GROUP BY c(d)
51
+
52
+ * If you use a LiteralString as a validation error message,
53
+ Errors#full_messages will now not add the related column name to
54
+ the start of the error message.
55
+
56
+ * Model.set_dataset now accepts SQL::Identifier,
57
+ SQL::QualifiedIdentifier, and SQL::AliasedExpression instances,
58
+ treating them like Symbols.
59
+
60
+ = Other Improvements
61
+
62
+ * The association_pks plugin's setter method will now automatically
63
+ convert a given array of strings to an array of integers if the
64
+ primary key field is an integer field, which should make it easier
65
+ to use in web applications.
66
+
67
+ * nil bound variable, prepared statement, and stored procedure
68
+ arguments are now handled correctly in the JDBC adapter.
69
+
70
+ * On 1.9, you can now load plugins even when ::ClassMethods,
71
+ ::InstanceMethods, or ::DatasetMethods is defined.
72
+
73
+ = Backwards Compatibility
74
+
75
+ * The tinytds adapter now only works with tiny_tds 0.4.5 and greater.
76
+ Also, if you were using the tinytds adapter with FreeTDS 0.91rc1,
77
+ you need to upgrade to FreeTDS 0.91rc2 for it to work. Also, if
78
+ you were referencing an entry in the freetds.conf file, you now
79
+ need to specify it directly using the :dataserver option when
80
+ connecting, the adapter no longer copies the :host option to the
81
+ :dataserver option.
82
+
83
+ * On postgresql, Sequel now no longer drops tables with CASCADE by
84
+ default. You now have to use the :cascade option to drop_table if
85
+ you want to use CASCADE.
86
+
87
+ * The Database#drop_table_sql private method now takes an additional
88
+ options hash argument.