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
@@ -4,171 +4,183 @@ Sequel is very flexibile when it comes to filtering records. You can specify you
4
4
 
5
5
  == Filtering using a custom filter string
6
6
 
7
- If you wish to write your SQL by hand, you can just supply it to the dataset's #filter method:
7
+ If you wish to write your SQL by hand, you can just supply it to the dataset's #where method:
8
8
 
9
- items.filter('x < 10').sql
9
+ items.where('x < 10').sql
10
10
  #=> "SELECT * FROM items WHERE x < 10"
11
11
 
12
12
  In order to prevent SQL injection, you can replace literal values with question marks and supply the values as additional arguments:
13
13
 
14
- items.filter('category = ?', 'ruby').sql
14
+ items.where('category = ?', 'ruby').sql
15
15
  #=> "SELECT * FROM items WHERE category = 'ruby'"
16
16
 
17
17
  You can also use placeholders with :placeholder and a hash of placeholder values:
18
18
 
19
- items.filter('category = :category', :category=>'ruby').sql
19
+ items.where('category = :category', :category=>'ruby').sql
20
20
  #=> "SELECT * FROM items WHERE category = 'ruby'"
21
21
 
22
22
  === Specifying SQL functions
23
23
 
24
- Sequel also allows you to specify functions by using the Symbol#sql_function method:
24
+ Sequel also allows you to specify functions by using the Sequel.function method:
25
25
 
26
- items.literal(:avg.sql_function(:price)) #=> "avg(price)"
26
+ items.literal(Sequel.function(:avg, :price)) #=> "avg(price)"
27
27
 
28
28
  If you are specifying a filter/selection/order, you can use a virtual row block:
29
29
 
30
30
  items.select{avg(price)}
31
31
 
32
+ You can also use the {core_extensions extension}[link:files/doc/core_extensions_rdoc.html] and the +sql_function+ method:
33
+
34
+ :avg.sql_function(:price)
35
+
32
36
  == Filtering using a hash
33
37
 
34
38
  If you just need to compare records against values, you can supply a hash:
35
39
 
36
- items.filter(:category => 'ruby').sql
40
+ items.where(:category => 'ruby').sql
37
41
  #=> "SELECT * FROM items WHERE (category = 'ruby')"
38
42
 
39
43
  Sequel can check for null values:
40
44
 
41
- items.filter(:category => nil).sql
45
+ items.where(:category => nil).sql
42
46
  #=> "SELECT * FROM items WHERE (category IS NULL)"
43
47
 
44
48
  Or compare two columns:
45
49
 
46
- items.filter(:x => :some_table__y).sql
50
+ items.where(:x => :some_table__y).sql
47
51
  #=> "SELECT * FROM items WHERE (x = some_table.y)"
48
52
 
49
53
  And also compare against multiple values:
50
54
 
51
- items.filter(:category => ['ruby', 'perl']).sql
55
+ items.where(:category => ['ruby', 'perl']).sql
52
56
  #=> "SELECT * FROM items WHERE (category IN ('ruby', 'perl'))"
53
57
 
54
58
  Ranges (both inclusive and exclusive) can also be used:
55
59
 
56
- items.filter(:price => 100..200).sql
60
+ items.where(:price => 100..200).sql
57
61
  #=> "SELECT * FROM items WHERE (price >= 100 AND price <= 200)"
58
62
 
59
- items.filter(:price => 100...200).sql
63
+ items.where(:price => 100...200).sql
60
64
  #=> "SELECT * FROM items WHERE (price >= 100 AND price < 200)"
61
65
 
66
+ == Filtering using an array
67
+
68
+ If you need to select multiple items from a dataset, you can supply an array:
69
+
70
+ item_array = [1, 38, 47, 99]
71
+ items.where(:id => item_array).sql
72
+ #=> "SELECT * FROM items WHERE (id IN (1, 38, 47, 99))"
73
+
62
74
  == Filtering using expressions
63
75
 
64
- Sequel allows you to use ruby expressions directly in the call to filter:
76
+ You can pass a block to where, which is evaluated in a special context:
65
77
 
66
- items.filter(:price * 2 < 50).sql
78
+ items.where{price * 2 < 50}.sql
67
79
  #=> "SELECT * FROM items WHERE ((price * 2) < 50)
68
80
 
69
- This works for the standard inequality and arithmetic operators (though you can't use the inequality operators directly on a symbol):
81
+ This works for the standard inequality and arithmetic operators:
70
82
 
71
- items.filter(:price + 100 < 200).sql
83
+ items.where{price + 100 < 200}.sql
72
84
  #=> "SELECT * FROM items WHERE ((price + 100) < 200)
73
85
 
74
- items.filter(:price - 100 > 200).sql
86
+ items.where{price - 100 > 200}.sql
75
87
  #=> "SELECT * FROM items WHERE ((price - 100) > 200)
76
88
 
77
- items.filter(:price * 100 <= 200).sql
89
+ items.where{price * 100 <= 200}.sql
78
90
  #=> "SELECT * FROM items WHERE ((price * 100) <= 200)
79
91
 
80
- items.filter(:price / 100 >= 200).sql
92
+ items.where{price / 100 >= 200}.sql
81
93
  #=> "SELECT * FROM items WHERE ((price / 100) >= 200)
82
94
 
83
95
  You use the overloaded bitwise and (&) and or (|) operators to combine expressions:
84
96
 
85
- items.filter((:price + 100 < 200) & (:price * 100 <= 200)).sql
97
+ items.where{(price + 100 < 200) & (price * 100 <= 200)}.sql
86
98
  #=> "SELECT * FROM items WHERE (((price + 100) < 200) AND ((price * 100) <= 200))
87
99
 
88
- items.filter((:price - 100 > 200) | (:price / 100 >= 200)).sql
100
+ items.where{(price - 100 > 200) | (price / 100 >= 200)}.sql
89
101
  #=> "SELECT * FROM items WHERE (((price - 100) > 200) OR ((price / 100) >= 200))
90
102
 
91
- To filter by equality, you use the standard hash, which can be combined with other operators:
103
+ To filter by equality, you use the standard hash, which can be combined with other expressions using Sequel.& and Sequel.|:
92
104
 
93
- items.filter({:category => 'ruby'} & (:price + 100 < 200)).sql
105
+ items.where{Sequel.&({:category => 'ruby'}, (price + 100 < 200))}.sql
94
106
  #=> "SELECT * FROM items WHERE ((category = 'ruby') AND ((price + 100) < 200))"
95
107
 
96
108
  This works with other hash values, such as arrays and ranges:
97
109
 
98
- items.filter({:category => ['ruby', 'other']} | (:price - 100 > 200)).sql
110
+ items.where{Sequel.|({:category => ['ruby', 'other']}, (:price - 100 > 200))}.sql
99
111
  #=> "SELECT * FROM items WHERE ((category IN ('ruby', 'other')) OR ((price - 100) <= 200))"
100
112
 
101
- items.filter({:price => (100..200)} & :active).sql
113
+ items.where{Sequel.&({:price => (100..200)}, :active)).sql
102
114
  #=> "SELECT * FROM items WHERE ((price >= 100 AND price <= 200) AND active)"
103
115
 
104
116
  === Negating conditions
105
117
 
106
- You can use the inversion operator (~) in most cases:
118
+ You can use the exclude method to exclude conditions:
107
119
 
108
- items.filter(~{:category => 'ruby'}).sql
120
+ items.exclude(:category => 'ruby').sql
109
121
  #=> "SELECT * FROM items WHERE (category != 'ruby')"
110
122
 
111
- items.filter{~:active}.sql
123
+ items.exclude(:active).sql
112
124
  #=> "SELECT * FROM items WHERE NOT active"
113
125
 
114
- items.filter(~(:price / 100 >= 200)).sql
126
+ items.exclude{price / 100 >= 200}.sql
115
127
  #=> "SELECT * FROM items WHERE ((price / 100) < 200)
116
128
 
117
129
  === Comparing against column references
118
130
 
119
131
  You can also compare against other columns:
120
132
 
121
- items.filter{credit > debit}.sql
133
+ items.where{credit > debit}.sql
122
134
  #=> "SELECT * FROM items WHERE (credit > debit)
123
135
 
124
136
  Or against SQL functions:
125
137
 
126
- items.filter{price - 100 < max(price)}.sql
138
+ items.where{price - 100 < max(price)}.sql
127
139
  #=> "SELECT * FROM items WHERE ((price - 100) < max(price))"
128
140
 
129
141
  == String search functions
130
142
 
131
- You can search SQL strings using the #like method:
143
+ You can search SQL strings using the Sequel.like method:
132
144
 
133
- items.filter(:name.like('Acme%')).sql
145
+ items.where(Sequel.like(:name, 'Acme%')).sql
134
146
  #=> "SELECT * FROM items WHERE (name LIKE 'Acme%')"
135
147
 
136
148
  You can specify a Regexp as a like argument, but this will probably only work
137
149
  on PostgreSQL and MySQL:
138
150
 
139
- items.filter(:name.like(/Acme.*/)).sql
151
+ items.where(Sequel.like(:name, /Acme.*/)).sql
140
152
  #=> "SELECT * FROM items WHERE (name ~ 'Acme.*')"
141
153
 
142
154
  Like can also take more than one argument:
143
155
 
144
- items.filter(:name.like('Acme%', /Beta.*/)).sql
156
+ items.where(Sequel.like(:name, 'Acme%', /Beta.*/)).sql
145
157
  #=> "SELECT * FROM items WHERE ((name LIKE 'Acme%') OR (name ~ 'Beta.*'))"
146
158
 
147
159
  == String concatenation
148
160
 
149
- You can concatenate SQL strings using Array#sql_string_join:
161
+ You can concatenate SQL strings using Sequel.join:
150
162
 
151
- items.filter([:name, :comment].sql_string_join.like('%acme%')).sql
163
+ items.where(Sequel.join([:name, :comment]).like('%acme%')).sql
152
164
  #=> "SELECT * FROM items WHERE ((name || comment) LIKE 'Acme%')"
153
165
 
154
166
  Array#sql_string_join also takes a join argument:
155
167
 
156
- items.filter([:name, :comment].sql_string_join(' ').like('%acme%')).sql
168
+ items.filter(Sequel.join([:name, :comment], ' ').like('%acme%')).sql
157
169
  #=> "SELECT * FROM items WHERE ((name || ' ' || comment) LIKE 'Acme%')"
158
170
 
159
171
  == Filtering using sub-queries
160
172
 
161
173
  One of the best features of Sequel is the ability to use datasets as sub-queries. Sub-queries can be very useful for filtering records, and many times provide a simpler alternative to table joins. Sub-queries can be used in all forms of filters:
162
174
 
163
- refs = consumer_refs.filter(:logged_in).select(:consumer_id)
164
- consumers.filter(:id => refs).sql
175
+ refs = consumer_refs.where(:logged_in).select(:consumer_id)
176
+ consumers.where(:id => refs).sql
165
177
  #=> "SELECT * FROM consumers WHERE (id IN (SELECT consumer_id FROM consumer_refs WHERE logged_in))"
166
178
 
167
179
  Note that if you are checking for the inclusion of a single column in a subselect, the subselect should only select a single column.
168
180
 
169
181
  == Using OR instead of AND
170
182
 
171
- By default, if you chain calls to +filter+, the conditions get ANDed together. If you want to use an OR for a condition, you can use the +or+ method:
183
+ By default, if you chain calls to +where+, the conditions get ANDed together. If you want to use an OR for a condition, you can use the +or+ method:
172
184
 
173
- items.filter(:name=>'Food').or(:vendor=>1).sql
185
+ items.where(:name=>'Food').or(:vendor=>1).sql
174
186
  #=> "SELECT * FROM items WHERE ((name = 'Food') OR (vendor = 1))"
@@ -0,0 +1,56 @@
1
+ = Sequel::Model Mass Assignment
2
+
3
+ Most Model methods that take a hash of attribute keys and values, including <tt>Model.new</tt>, <tt>Model.create</tt>, <tt>Model#set</tt> and <tt>Model#update</tt> are subject to Sequel's mass assignment rules.
4
+ When you pass a hash to these methods, each key has an <tt>=</tt> appended to it (the setter method), and if the setter method exists and access to it is not restricted, Sequel will call the setter method with the hash value.
5
+ By default, there are two types of setter methods that are restricted.
6
+ The first is methods like <tt>typecast_on_assignment=</tt> and <tt>==</tt>, which don't affect columns.
7
+ These methods cannot be enabled for mass assignment.
8
+ The second is primary key setters.
9
+ To enable use of primary key setters, you need to call +unrestrict_primary_key+ for that model:
10
+
11
+ Post.unrestrict_primary_key
12
+
13
+ Since mass assignment by default allows modification of all column values except for primary key columns, it can be a security risk in some cases.
14
+ Sequel has multiple ways of securing mass assignment.
15
+ The first way is using +set_allowed_columns+:
16
+
17
+ Post.set_allowed_columns :title, :body, :category
18
+
19
+ This explicitly sets which methods are allowed (<tt>title=</tt>, <tt>body=</tt>, and <tt>category=</tt>), all other methods will not be allowed.
20
+ This method is useful in simple applications where the same columns are allowed in all cases, but not appropriate when different columns are allowed in different scenarios (e.g. admin access vs. user access).
21
+ To handle cases where different columns are allowed in different cases, you can use +set_only+ or +update_only+:
22
+
23
+ # user case
24
+ post.set_only(params[:post], :title, :body)
25
+ # admin case
26
+ post.set_only(params[:post], :title, :body, :deleted)
27
+
28
+ In this case, only the <tt>title=</tt> and <tt>body=</tt> methods will be allowed in the mass assignment in the user case, and only <tt>title=</tt>, <tt>body=</tt>, and <tt>deleted=</tt> will be allowed for mass assignment in the admin case.
29
+
30
+ By default, if an invalid setter method call is attempted, Sequel raises a <tt>Sequel::Error</tt> exception. You can have Sequel silently ignore invalid calls by doing:
31
+
32
+ # Global default
33
+ Sequel::Model.strict_param_setting = false
34
+ # Class level
35
+ Post.strict_param_setting = false
36
+ # Instance level
37
+ post.strict_param_setting = false
38
+
39
+ These mass assignment methods have been around a long time, but starting in Sequel 3.12.0, the +set_fields+ and +update_fields+ methods were added, and these may be a better mass assignment choice for most users.
40
+ These methods take two arguments, the attributes hash as the first argument, and a single array of valid field names as the second argument:
41
+
42
+ post.set_fields(params[:post], [:title, :body])
43
+
44
+ +set_fields+ and +update_fields+ differ in implementation from +set_only+ and +update_only+.
45
+ With +set_only+ and +update_only+, the hash is iterated over and it checks each method call attempt to see if it is valid.
46
+ With +set_fields+ and +update_fields+, the array is iterated over, and it just looks up the value in the hash and calls the appropriate setter method.
47
+
48
+ +set_fields+ and +update_fields+ are designed for the case where you are expecting specific fields in the input, and want to ignore the other fields.
49
+ They work great for things like HTML forms where the form fields are static.
50
+ +set_only+ and +update_only+ are designed for cases where you are not sure what fields are going to be present in the input, but still want to make sure only certain setter methods can be called.
51
+ They work great for flexible APIs.
52
+
53
+ Starting in Sequel 3.34.0, +set_fields+ and +update_fields+ take an optional argument hash, and currently handles the :missing option. With <tt>:missing=>:skip</tt>, +set_fields+ and +update_fields+ will just skip missing entries in the hash, allowing them to be used in flexible APIs. With <tt>:missing=>:raise</tt>, +set_fields+ and +update_fields+ will raise an error if one of the entries in the hash is missing, instead of just assigning the value to nil or whatever the hash's default value is. That allows stricter checks, similar to the :strict_param_checking setting for the default mass assignment methods.
54
+
55
+ In all of the mass assignment cases, methods starting with +set+ will set the attributes without saving the object, while methods starting with +update+ will set the attributes and then save the changes to the object.
56
+