sequel 4.49.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (484) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +130 -0
  3. data/README.rdoc +195 -136
  4. data/Rakefile +26 -42
  5. data/bin/sequel +6 -9
  6. data/doc/advanced_associations.rdoc +91 -168
  7. data/doc/association_basics.rdoc +197 -274
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +66 -43
  10. data/doc/code_order.rdoc +1 -8
  11. data/doc/core_extensions.rdoc +81 -56
  12. data/doc/dataset_basics.rdoc +8 -17
  13. data/doc/dataset_filtering.rdoc +81 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/mass_assignment.rdoc +73 -30
  16. data/doc/migration.rdoc +19 -36
  17. data/doc/model_dataset_method_design.rdoc +14 -17
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +10 -10
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +52 -70
  22. data/doc/opening_databases.rdoc +39 -32
  23. data/doc/postgresql.rdoc +48 -38
  24. data/doc/prepared_statements.rdoc +27 -22
  25. data/doc/querying.rdoc +173 -150
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.2.0.txt +33 -0
  30. data/doc/release_notes/5.3.0.txt +121 -0
  31. data/doc/schema_modification.rdoc +78 -64
  32. data/doc/security.rdoc +97 -88
  33. data/doc/sharding.rdoc +43 -30
  34. data/doc/sql.rdoc +53 -65
  35. data/doc/testing.rdoc +4 -5
  36. data/doc/thread_safety.rdoc +2 -4
  37. data/doc/transactions.rdoc +18 -17
  38. data/doc/validations.rdoc +48 -45
  39. data/doc/virtual_rows.rdoc +87 -115
  40. data/lib/sequel/adapters/ado/access.rb +7 -13
  41. data/lib/sequel/adapters/ado/mssql.rb +2 -9
  42. data/lib/sequel/adapters/ado.rb +9 -25
  43. data/lib/sequel/adapters/amalgalite.rb +3 -18
  44. data/lib/sequel/adapters/ibmdb.rb +9 -45
  45. data/lib/sequel/adapters/jdbc/db2.rb +8 -37
  46. data/lib/sequel/adapters/jdbc/derby.rb +4 -50
  47. data/lib/sequel/adapters/jdbc/h2.rb +6 -26
  48. data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -27
  49. data/lib/sequel/adapters/jdbc/jtds.rb +2 -9
  50. data/lib/sequel/adapters/jdbc/mssql.rb +1 -11
  51. data/lib/sequel/adapters/jdbc/mysql.rb +11 -15
  52. data/lib/sequel/adapters/jdbc/oracle.rb +4 -26
  53. data/lib/sequel/adapters/jdbc/postgresql.rb +23 -33
  54. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +4 -17
  55. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -7
  56. data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -13
  57. data/lib/sequel/adapters/jdbc/transactions.rb +1 -14
  58. data/lib/sequel/adapters/jdbc.rb +18 -74
  59. data/lib/sequel/adapters/mock.rb +4 -30
  60. data/lib/sequel/adapters/mysql.rb +7 -44
  61. data/lib/sequel/adapters/mysql2.rb +5 -23
  62. data/lib/sequel/adapters/odbc/db2.rb +1 -1
  63. data/lib/sequel/adapters/odbc/mssql.rb +4 -12
  64. data/lib/sequel/adapters/odbc/oracle.rb +1 -1
  65. data/lib/sequel/adapters/odbc.rb +0 -19
  66. data/lib/sequel/adapters/oracle.rb +8 -13
  67. data/lib/sequel/adapters/postgres.rb +28 -150
  68. data/lib/sequel/adapters/postgresql.rb +1 -1
  69. data/lib/sequel/adapters/shared/access.rb +11 -51
  70. data/lib/sequel/adapters/shared/db2.rb +3 -61
  71. data/lib/sequel/adapters/shared/mssql.rb +21 -157
  72. data/lib/sequel/adapters/shared/mysql.rb +61 -227
  73. data/lib/sequel/adapters/shared/oracle.rb +13 -41
  74. data/lib/sequel/adapters/shared/postgres.rb +58 -264
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +4 -96
  76. data/lib/sequel/adapters/shared/sqlite.rb +22 -101
  77. data/lib/sequel/adapters/sqlanywhere.rb +4 -23
  78. data/lib/sequel/adapters/sqlite.rb +2 -19
  79. data/lib/sequel/adapters/tinytds.rb +5 -15
  80. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -4
  82. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +3 -6
  83. data/lib/sequel/adapters/utils/replace.rb +0 -5
  84. data/lib/sequel/adapters/utils/stored_procedures.rb +0 -2
  85. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +2 -0
  86. data/lib/sequel/ast_transformer.rb +3 -94
  87. data/lib/sequel/connection_pool/sharded_single.rb +1 -4
  88. data/lib/sequel/connection_pool/sharded_threaded.rb +97 -95
  89. data/lib/sequel/connection_pool/single.rb +0 -2
  90. data/lib/sequel/connection_pool/threaded.rb +94 -110
  91. data/lib/sequel/connection_pool.rb +38 -28
  92. data/lib/sequel/core.rb +42 -101
  93. data/lib/sequel/database/connecting.rb +23 -60
  94. data/lib/sequel/database/dataset.rb +6 -9
  95. data/lib/sequel/database/dataset_defaults.rb +4 -48
  96. data/lib/sequel/database/features.rb +5 -4
  97. data/lib/sequel/database/logging.rb +2 -9
  98. data/lib/sequel/database/misc.rb +36 -55
  99. data/lib/sequel/database/query.rb +8 -13
  100. data/lib/sequel/database/schema_generator.rb +93 -64
  101. data/lib/sequel/database/schema_methods.rb +61 -79
  102. data/lib/sequel/database/transactions.rb +4 -24
  103. data/lib/sequel/database.rb +12 -2
  104. data/lib/sequel/dataset/actions.rb +57 -107
  105. data/lib/sequel/dataset/dataset_module.rb +4 -16
  106. data/lib/sequel/dataset/features.rb +35 -30
  107. data/lib/sequel/dataset/graph.rb +40 -49
  108. data/lib/sequel/dataset/misc.rb +12 -37
  109. data/lib/sequel/dataset/placeholder_literalizer.rb +4 -4
  110. data/lib/sequel/dataset/prepared_statements.rb +23 -51
  111. data/lib/sequel/dataset/query.rb +91 -161
  112. data/lib/sequel/dataset/sql.rb +33 -225
  113. data/lib/sequel/dataset.rb +18 -10
  114. data/lib/sequel/deprecated.rb +18 -27
  115. data/lib/sequel/exceptions.rb +1 -17
  116. data/lib/sequel/extensions/_model_pg_row.rb +0 -7
  117. data/lib/sequel/extensions/_pretty_table.rb +1 -3
  118. data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
  119. data/lib/sequel/extensions/connection_expiration.rb +1 -1
  120. data/lib/sequel/extensions/connection_validator.rb +1 -1
  121. data/lib/sequel/extensions/constraint_validations.rb +11 -11
  122. data/lib/sequel/extensions/core_extensions.rb +39 -49
  123. data/lib/sequel/extensions/core_refinements.rb +39 -45
  124. data/lib/sequel/extensions/current_datetime_timestamp.rb +0 -4
  125. data/lib/sequel/extensions/date_arithmetic.rb +7 -7
  126. data/lib/sequel/extensions/duplicate_columns_handler.rb +12 -9
  127. data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
  128. data/lib/sequel/extensions/eval_inspect.rb +4 -11
  129. data/lib/sequel/extensions/freeze_datasets.rb +1 -69
  130. data/lib/sequel/extensions/from_block.rb +1 -35
  131. data/lib/sequel/extensions/graph_each.rb +2 -2
  132. data/lib/sequel/extensions/identifier_mangling.rb +9 -19
  133. data/lib/sequel/extensions/implicit_subquery.rb +2 -2
  134. data/lib/sequel/extensions/inflector.rb +4 -4
  135. data/lib/sequel/extensions/migration.rb +27 -43
  136. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -84
  137. data/lib/sequel/extensions/null_dataset.rb +2 -8
  138. data/lib/sequel/extensions/pagination.rb +1 -17
  139. data/lib/sequel/extensions/pg_array.rb +20 -189
  140. data/lib/sequel/extensions/pg_extended_date_support.rb +230 -0
  141. data/lib/sequel/extensions/pg_hstore.rb +11 -50
  142. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
  143. data/lib/sequel/extensions/pg_inet.rb +3 -16
  144. data/lib/sequel/extensions/pg_interval.rb +1 -20
  145. data/lib/sequel/extensions/pg_json.rb +7 -27
  146. data/lib/sequel/extensions/pg_loose_count.rb +1 -1
  147. data/lib/sequel/extensions/pg_range.rb +6 -121
  148. data/lib/sequel/extensions/pg_range_ops.rb +1 -3
  149. data/lib/sequel/extensions/pg_row.rb +5 -77
  150. data/lib/sequel/extensions/pg_row_ops.rb +2 -13
  151. data/lib/sequel/extensions/query.rb +3 -4
  152. data/lib/sequel/extensions/round_timestamps.rb +0 -6
  153. data/lib/sequel/extensions/schema_dumper.rb +13 -13
  154. data/lib/sequel/extensions/select_remove.rb +3 -3
  155. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  156. data/lib/sequel/extensions/sql_comments.rb +2 -2
  157. data/lib/sequel/extensions/string_agg.rb +11 -8
  158. data/lib/sequel/extensions/symbol_aref.rb +6 -20
  159. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  160. data/lib/sequel/model/associations.rb +129 -131
  161. data/lib/sequel/model/base.rb +133 -731
  162. data/lib/sequel/model/default_inflections.rb +1 -1
  163. data/lib/sequel/model/errors.rb +0 -3
  164. data/lib/sequel/model/exceptions.rb +2 -6
  165. data/lib/sequel/model/inflections.rb +1 -26
  166. data/lib/sequel/model/plugins.rb +1 -0
  167. data/lib/sequel/model.rb +27 -62
  168. data/lib/sequel/plugins/active_model.rb +2 -5
  169. data/lib/sequel/plugins/association_dependencies.rb +15 -15
  170. data/lib/sequel/plugins/association_pks.rb +14 -28
  171. data/lib/sequel/plugins/association_proxies.rb +6 -7
  172. data/lib/sequel/plugins/auto_validations.rb +4 -4
  173. data/lib/sequel/plugins/before_after_save.rb +0 -43
  174. data/lib/sequel/plugins/blacklist_security.rb +9 -8
  175. data/lib/sequel/plugins/boolean_readers.rb +3 -3
  176. data/lib/sequel/plugins/boolean_subsets.rb +2 -2
  177. data/lib/sequel/plugins/caching.rb +5 -5
  178. data/lib/sequel/plugins/class_table_inheritance.rb +71 -102
  179. data/lib/sequel/plugins/column_conflicts.rb +2 -2
  180. data/lib/sequel/plugins/column_select.rb +2 -2
  181. data/lib/sequel/plugins/composition.rb +15 -24
  182. data/lib/sequel/plugins/constraint_validations.rb +4 -3
  183. data/lib/sequel/plugins/csv_serializer.rb +13 -20
  184. data/lib/sequel/plugins/dataset_associations.rb +2 -2
  185. data/lib/sequel/plugins/def_dataset_method.rb +5 -5
  186. data/lib/sequel/plugins/defaults_setter.rb +1 -1
  187. data/lib/sequel/plugins/delay_add_association.rb +1 -1
  188. data/lib/sequel/plugins/finder.rb +16 -10
  189. data/lib/sequel/plugins/force_encoding.rb +1 -7
  190. data/lib/sequel/plugins/hook_class_methods.rb +4 -106
  191. data/lib/sequel/plugins/input_transformer.rb +10 -11
  192. data/lib/sequel/plugins/insert_returning_select.rb +1 -9
  193. data/lib/sequel/plugins/instance_filters.rb +5 -5
  194. data/lib/sequel/plugins/instance_hooks.rb +7 -52
  195. data/lib/sequel/plugins/inverted_subsets.rb +3 -1
  196. data/lib/sequel/plugins/json_serializer.rb +19 -19
  197. data/lib/sequel/plugins/lazy_attributes.rb +1 -10
  198. data/lib/sequel/plugins/list.rb +6 -6
  199. data/lib/sequel/plugins/many_through_many.rb +11 -8
  200. data/lib/sequel/plugins/mssql_optimistic_locking.rb +3 -3
  201. data/lib/sequel/plugins/nested_attributes.rb +18 -31
  202. data/lib/sequel/plugins/optimistic_locking.rb +3 -3
  203. data/lib/sequel/plugins/pg_array_associations.rb +8 -2
  204. data/lib/sequel/plugins/pg_row.rb +2 -11
  205. data/lib/sequel/plugins/prepared_statements.rb +13 -66
  206. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -1
  207. data/lib/sequel/plugins/rcte_tree.rb +7 -7
  208. data/lib/sequel/plugins/serialization.rb +15 -33
  209. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  210. data/lib/sequel/plugins/sharding.rb +2 -8
  211. data/lib/sequel/plugins/single_table_inheritance.rb +10 -13
  212. data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
  213. data/lib/sequel/plugins/static_cache.rb +8 -9
  214. data/lib/sequel/plugins/string_stripper.rb +3 -3
  215. data/lib/sequel/plugins/subclasses.rb +1 -1
  216. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  217. data/lib/sequel/plugins/table_select.rb +2 -2
  218. data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
  219. data/lib/sequel/plugins/timestamps.rb +6 -7
  220. data/lib/sequel/plugins/touch.rb +4 -8
  221. data/lib/sequel/plugins/tree.rb +3 -3
  222. data/lib/sequel/plugins/typecast_on_load.rb +2 -2
  223. data/lib/sequel/plugins/unlimited_update.rb +1 -7
  224. data/lib/sequel/plugins/update_or_create.rb +3 -3
  225. data/lib/sequel/plugins/update_refresh.rb +3 -3
  226. data/lib/sequel/plugins/uuid.rb +7 -11
  227. data/lib/sequel/plugins/validation_class_methods.rb +10 -9
  228. data/lib/sequel/plugins/validation_contexts.rb +4 -4
  229. data/lib/sequel/plugins/validation_helpers.rb +26 -25
  230. data/lib/sequel/plugins/whitelist_security.rb +13 -9
  231. data/lib/sequel/plugins/xml_serializer.rb +24 -25
  232. data/lib/sequel/sql.rb +145 -276
  233. data/lib/sequel/timezones.rb +8 -23
  234. data/lib/sequel/version.rb +2 -2
  235. data/lib/sequel.rb +1 -1
  236. data/spec/adapter_spec.rb +1 -1
  237. data/spec/adapters/db2_spec.rb +2 -103
  238. data/spec/adapters/mssql_spec.rb +89 -68
  239. data/spec/adapters/mysql_spec.rb +111 -478
  240. data/spec/adapters/oracle_spec.rb +1 -9
  241. data/spec/adapters/postgres_spec.rb +459 -664
  242. data/spec/adapters/spec_helper.rb +12 -31
  243. data/spec/adapters/sqlanywhere_spec.rb +2 -77
  244. data/spec/adapters/sqlite_spec.rb +8 -146
  245. data/spec/bin_spec.rb +11 -16
  246. data/spec/core/connection_pool_spec.rb +173 -74
  247. data/spec/core/database_spec.rb +96 -244
  248. data/spec/core/dataset_spec.rb +99 -414
  249. data/spec/core/deprecated_spec.rb +3 -3
  250. data/spec/core/expression_filters_spec.rb +37 -144
  251. data/spec/core/mock_adapter_spec.rb +241 -4
  252. data/spec/core/object_graph_spec.rb +11 -60
  253. data/spec/core/placeholder_literalizer_spec.rb +1 -14
  254. data/spec/core/schema_generator_spec.rb +51 -40
  255. data/spec/core/schema_spec.rb +88 -77
  256. data/spec/core/spec_helper.rb +6 -24
  257. data/spec/core/version_spec.rb +1 -1
  258. data/spec/core_extensions_spec.rb +7 -83
  259. data/spec/core_model_spec.rb +2 -2
  260. data/spec/deprecation_helper.rb +2 -14
  261. data/spec/extensions/accessed_columns_spec.rb +1 -1
  262. data/spec/extensions/active_model_spec.rb +3 -3
  263. data/spec/extensions/after_initialize_spec.rb +1 -1
  264. data/spec/extensions/arbitrary_servers_spec.rb +2 -2
  265. data/spec/extensions/association_dependencies_spec.rb +1 -1
  266. data/spec/extensions/association_pks_spec.rb +30 -92
  267. data/spec/extensions/association_proxies_spec.rb +1 -1
  268. data/spec/extensions/auto_literal_strings_spec.rb +1 -12
  269. data/spec/extensions/auto_validations_spec.rb +1 -1
  270. data/spec/extensions/blacklist_security_spec.rb +1 -1
  271. data/spec/extensions/blank_spec.rb +1 -1
  272. data/spec/extensions/boolean_readers_spec.rb +1 -1
  273. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  274. data/spec/extensions/caching_spec.rb +1 -1
  275. data/spec/extensions/class_table_inheritance_spec.rb +53 -1118
  276. data/spec/extensions/column_conflicts_spec.rb +1 -1
  277. data/spec/extensions/column_select_spec.rb +4 -4
  278. data/spec/extensions/columns_introspection_spec.rb +1 -1
  279. data/spec/extensions/columns_updated_spec.rb +1 -1
  280. data/spec/extensions/composition_spec.rb +8 -30
  281. data/spec/extensions/connection_expiration_spec.rb +3 -3
  282. data/spec/extensions/connection_validator_spec.rb +3 -3
  283. data/spec/extensions/constraint_validations_plugin_spec.rb +1 -1
  284. data/spec/extensions/constraint_validations_spec.rb +1 -1
  285. data/spec/extensions/core_refinements_spec.rb +1 -3
  286. data/spec/extensions/csv_serializer_spec.rb +4 -9
  287. data/spec/extensions/current_datetime_timestamp_spec.rb +1 -1
  288. data/spec/extensions/dataset_associations_spec.rb +2 -1
  289. data/spec/extensions/dataset_source_alias_spec.rb +1 -1
  290. data/spec/extensions/date_arithmetic_spec.rb +3 -3
  291. data/spec/extensions/def_dataset_method_spec.rb +1 -1
  292. data/spec/extensions/defaults_setter_spec.rb +2 -2
  293. data/spec/extensions/delay_add_association_spec.rb +8 -9
  294. data/spec/extensions/dirty_spec.rb +1 -1
  295. data/spec/extensions/duplicate_columns_handler_spec.rb +1 -1
  296. data/spec/extensions/eager_each_spec.rb +2 -2
  297. data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
  298. data/spec/extensions/error_splitter_spec.rb +1 -1
  299. data/spec/extensions/error_sql_spec.rb +1 -1
  300. data/spec/extensions/eval_inspect_spec.rb +1 -1
  301. data/spec/extensions/finder_spec.rb +1 -1
  302. data/spec/extensions/force_encoding_spec.rb +2 -5
  303. data/spec/extensions/freeze_datasets_spec.rb +1 -1
  304. data/spec/extensions/graph_each_spec.rb +5 -5
  305. data/spec/extensions/hook_class_methods_spec.rb +1 -194
  306. data/spec/extensions/identifier_mangling_spec.rb +17 -170
  307. data/spec/extensions/implicit_subquery_spec.rb +1 -5
  308. data/spec/extensions/inflector_spec.rb +1 -1
  309. data/spec/extensions/input_transformer_spec.rb +7 -2
  310. data/spec/extensions/insert_returning_select_spec.rb +1 -1
  311. data/spec/extensions/instance_filters_spec.rb +1 -1
  312. data/spec/extensions/instance_hooks_spec.rb +1 -95
  313. data/spec/extensions/inverted_subsets_spec.rb +1 -1
  314. data/spec/extensions/json_serializer_spec.rb +1 -1
  315. data/spec/extensions/lazy_attributes_spec.rb +1 -7
  316. data/spec/extensions/list_spec.rb +5 -6
  317. data/spec/extensions/looser_typecasting_spec.rb +1 -1
  318. data/spec/extensions/many_through_many_spec.rb +25 -33
  319. data/spec/extensions/migration_spec.rb +12 -2
  320. data/spec/extensions/modification_detection_spec.rb +1 -1
  321. data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
  322. data/spec/extensions/named_timezones_spec.rb +3 -3
  323. data/spec/extensions/nested_attributes_spec.rb +1 -29
  324. data/spec/extensions/null_dataset_spec.rb +1 -11
  325. data/spec/extensions/optimistic_locking_spec.rb +2 -2
  326. data/spec/extensions/pagination_spec.rb +1 -1
  327. data/spec/extensions/pg_array_associations_spec.rb +22 -26
  328. data/spec/extensions/pg_array_ops_spec.rb +1 -1
  329. data/spec/extensions/pg_array_spec.rb +3 -48
  330. data/spec/extensions/pg_enum_spec.rb +1 -1
  331. data/spec/extensions/pg_extended_date_support_spec.rb +122 -0
  332. data/spec/extensions/pg_hstore_ops_spec.rb +1 -1
  333. data/spec/extensions/pg_hstore_spec.rb +22 -31
  334. data/spec/extensions/pg_inet_ops_spec.rb +1 -1
  335. data/spec/extensions/pg_inet_spec.rb +1 -14
  336. data/spec/extensions/pg_interval_spec.rb +3 -13
  337. data/spec/extensions/pg_json_ops_spec.rb +1 -1
  338. data/spec/extensions/pg_json_spec.rb +1 -13
  339. data/spec/extensions/pg_loose_count_spec.rb +1 -1
  340. data/spec/extensions/pg_range_ops_spec.rb +1 -1
  341. data/spec/extensions/pg_range_spec.rb +3 -88
  342. data/spec/extensions/pg_row_ops_spec.rb +1 -1
  343. data/spec/extensions/pg_row_plugin_spec.rb +1 -1
  344. data/spec/extensions/pg_row_spec.rb +1 -44
  345. data/spec/extensions/pg_static_cache_updater_spec.rb +1 -1
  346. data/spec/extensions/prepared_statements_safe_spec.rb +7 -7
  347. data/spec/extensions/prepared_statements_spec.rb +13 -48
  348. data/spec/extensions/pretty_table_spec.rb +40 -9
  349. data/spec/extensions/query_spec.rb +1 -12
  350. data/spec/extensions/rcte_tree_spec.rb +23 -34
  351. data/spec/extensions/round_timestamps_spec.rb +1 -5
  352. data/spec/extensions/s_spec.rb +1 -1
  353. data/spec/extensions/schema_caching_spec.rb +1 -1
  354. data/spec/extensions/schema_dumper_spec.rb +43 -32
  355. data/spec/extensions/select_remove_spec.rb +1 -1
  356. data/spec/extensions/sequel_4_dataset_methods_spec.rb +1 -1
  357. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  358. data/spec/extensions/serialization_spec.rb +5 -17
  359. data/spec/extensions/server_block_spec.rb +1 -1
  360. data/spec/extensions/server_logging_spec.rb +2 -2
  361. data/spec/extensions/sharding_spec.rb +1 -1
  362. data/spec/extensions/shared_caching_spec.rb +1 -28
  363. data/spec/extensions/single_table_inheritance_spec.rb +2 -5
  364. data/spec/extensions/singular_table_names_spec.rb +1 -1
  365. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  366. data/spec/extensions/spec_helper.rb +5 -27
  367. data/spec/extensions/split_array_nil_spec.rb +1 -1
  368. data/spec/extensions/split_values_spec.rb +1 -1
  369. data/spec/extensions/sql_comments_spec.rb +1 -1
  370. data/spec/extensions/sql_expr_spec.rb +1 -1
  371. data/spec/extensions/static_cache_spec.rb +1 -1
  372. data/spec/extensions/string_agg_spec.rb +2 -2
  373. data/spec/extensions/string_date_time_spec.rb +1 -1
  374. data/spec/extensions/string_stripper_spec.rb +1 -1
  375. data/spec/extensions/subclasses_spec.rb +1 -1
  376. data/spec/extensions/subset_conditions_spec.rb +1 -1
  377. data/spec/extensions/symbol_aref_refinement_spec.rb +1 -1
  378. data/spec/extensions/symbol_as_refinement_spec.rb +1 -1
  379. data/spec/extensions/synchronize_sql_spec.rb +124 -0
  380. data/spec/extensions/table_select_spec.rb +4 -4
  381. data/spec/extensions/tactical_eager_loading_spec.rb +1 -6
  382. data/spec/extensions/thread_local_timezones_spec.rb +1 -1
  383. data/spec/extensions/timestamps_spec.rb +5 -7
  384. data/spec/extensions/to_dot_spec.rb +1 -1
  385. data/spec/extensions/touch_spec.rb +1 -1
  386. data/spec/extensions/tree_spec.rb +1 -1
  387. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  388. data/spec/extensions/unlimited_update_spec.rb +1 -1
  389. data/spec/extensions/update_or_create_spec.rb +12 -16
  390. data/spec/extensions/update_primary_key_spec.rb +4 -3
  391. data/spec/extensions/update_refresh_spec.rb +1 -1
  392. data/spec/extensions/uuid_spec.rb +10 -13
  393. data/spec/extensions/validate_associated_spec.rb +1 -1
  394. data/spec/extensions/validation_class_methods_spec.rb +3 -3
  395. data/spec/extensions/validation_contexts_spec.rb +1 -1
  396. data/spec/extensions/validation_helpers_spec.rb +10 -44
  397. data/spec/extensions/whitelist_security_spec.rb +5 -5
  398. data/spec/extensions/xml_serializer_spec.rb +8 -13
  399. data/spec/guards_helper.rb +2 -1
  400. data/spec/integration/associations_test.rb +1 -23
  401. data/spec/integration/database_test.rb +7 -7
  402. data/spec/integration/dataset_test.rb +12 -47
  403. data/spec/integration/eager_loader_test.rb +1 -1
  404. data/spec/integration/migrator_test.rb +1 -1
  405. data/spec/integration/model_test.rb +4 -82
  406. data/spec/integration/plugin_test.rb +7 -23
  407. data/spec/integration/prepared_statement_test.rb +8 -88
  408. data/spec/integration/schema_test.rb +10 -10
  409. data/spec/integration/spec_helper.rb +17 -21
  410. data/spec/integration/timezone_test.rb +5 -5
  411. data/spec/integration/transaction_test.rb +3 -55
  412. data/spec/integration/type_test.rb +9 -9
  413. data/spec/model/association_reflection_spec.rb +24 -9
  414. data/spec/model/associations_spec.rb +124 -303
  415. data/spec/model/base_spec.rb +43 -137
  416. data/spec/model/class_dataset_methods_spec.rb +2 -20
  417. data/spec/model/dataset_methods_spec.rb +1 -20
  418. data/spec/model/eager_loading_spec.rb +48 -17
  419. data/spec/model/hooks_spec.rb +5 -300
  420. data/spec/model/inflector_spec.rb +1 -1
  421. data/spec/model/model_spec.rb +29 -339
  422. data/spec/model/plugins_spec.rb +2 -16
  423. data/spec/model/record_spec.rb +33 -129
  424. data/spec/model/spec_helper.rb +5 -15
  425. data/spec/model/validations_spec.rb +1 -1
  426. data/spec/sequel_warning.rb +1 -12
  427. metadata +19 -65
  428. data/doc/active_record.rdoc +0 -927
  429. data/lib/sequel/adapters/cubrid.rb +0 -160
  430. data/lib/sequel/adapters/do/mysql.rb +0 -69
  431. data/lib/sequel/adapters/do/postgres.rb +0 -46
  432. data/lib/sequel/adapters/do/sqlite3.rb +0 -41
  433. data/lib/sequel/adapters/do.rb +0 -166
  434. data/lib/sequel/adapters/jdbc/as400.rb +0 -92
  435. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -65
  436. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -37
  437. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -34
  438. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -34
  439. data/lib/sequel/adapters/odbc/progress.rb +0 -12
  440. data/lib/sequel/adapters/shared/cubrid.rb +0 -245
  441. data/lib/sequel/adapters/shared/firebird.rb +0 -261
  442. data/lib/sequel/adapters/shared/informix.rb +0 -63
  443. data/lib/sequel/adapters/shared/progress.rb +0 -40
  444. data/lib/sequel/adapters/swift/mysql.rb +0 -50
  445. data/lib/sequel/adapters/swift/postgres.rb +0 -49
  446. data/lib/sequel/adapters/swift/sqlite.rb +0 -48
  447. data/lib/sequel/adapters/swift.rb +0 -169
  448. data/lib/sequel/adapters/utils/pg_types.rb +0 -4
  449. data/lib/sequel/dataset/mutation.rb +0 -98
  450. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +0 -117
  451. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -8
  452. data/lib/sequel/extensions/filter_having.rb +0 -65
  453. data/lib/sequel/extensions/hash_aliases.rb +0 -51
  454. data/lib/sequel/extensions/meta_def.rb +0 -37
  455. data/lib/sequel/extensions/query_literals.rb +0 -86
  456. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -26
  457. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -133
  458. data/lib/sequel/extensions/set_overrides.rb +0 -82
  459. data/lib/sequel/no_core_ext.rb +0 -4
  460. data/lib/sequel/plugins/association_autoreloading.rb +0 -11
  461. data/lib/sequel/plugins/identifier_columns.rb +0 -49
  462. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -11
  463. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -90
  464. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -137
  465. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -71
  466. data/lib/sequel/plugins/schema.rb +0 -84
  467. data/lib/sequel/plugins/scissors.rb +0 -37
  468. data/spec/core/dataset_mutation_spec.rb +0 -253
  469. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +0 -314
  470. data/spec/extensions/before_after_save_spec.rb +0 -40
  471. data/spec/extensions/filter_having_spec.rb +0 -42
  472. data/spec/extensions/from_block_spec.rb +0 -21
  473. data/spec/extensions/hash_aliases_spec.rb +0 -26
  474. data/spec/extensions/identifier_columns_spec.rb +0 -19
  475. data/spec/extensions/meta_def_spec.rb +0 -35
  476. data/spec/extensions/no_auto_literal_strings_spec.rb +0 -69
  477. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -70
  478. data/spec/extensions/prepared_statements_associations_spec.rb +0 -212
  479. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -40
  480. data/spec/extensions/query_literals_spec.rb +0 -185
  481. data/spec/extensions/schema_spec.rb +0 -123
  482. data/spec/extensions/scissors_spec.rb +0 -27
  483. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -118
  484. data/spec/extensions/set_overrides_spec.rb +0 -75
data/doc/sharding.rdoc CHANGED
@@ -13,7 +13,7 @@ option. Using the :servers database option makes Sequel use a connection pool
13
13
  class that supports sharding, and the minimum required to enable sharding
14
14
  support is to use the empty hash:
15
15
 
16
- DB=Sequel.connect('postgres://master_server/database', :servers=>{})
16
+ DB=Sequel.connect('postgres://master_server/database', servers: {})
17
17
 
18
18
  In most cases, you are probably not going to want to use an empty hash. Keys in the server hash are
19
19
  not restricted to type, but the general recommendation is to use a symbol
@@ -35,8 +35,8 @@ tables you are accessing, unless you really know what you are doing.
35
35
  To use a single, read-only slave that handles SELECT queries, the following
36
36
  is the simplest configuration:
37
37
 
38
- DB=Sequel.connect('postgres://master_server/database', \
39
- :servers=>{:read_only=>{:host=>'slave_server'}})
38
+ DB=Sequel.connect('postgres://master_server/database',
39
+ servers: {read_only: {host: 'slave_server'}})
40
40
 
41
41
  This will use the slave_server for SELECT queries and master_server for
42
42
  other queries.
@@ -48,8 +48,8 @@ the symbol name defined in the connect options. For example:
48
48
  # Force the SELECT to run on the master
49
49
  DB[:users].server(:default).all
50
50
 
51
- # Force the SELECT to run on the read-only slave
52
- DB[:users].server(:read_only).all
51
+ # Force the DELETE to run on the read-only slave
52
+ DB[:users].server(:read_only).delete
53
53
 
54
54
  === Multiple Read-Only Slaves, Single Master
55
55
 
@@ -59,13 +59,13 @@ slave_server1, slave_server2, and slave_server3.
59
59
  num_read_only = 4
60
60
  read_only_host = rand(num_read_only)
61
61
  read_only_proc = proc do |db|
62
- {:host=>"slave_server#{(read_only_host+=1) % num_read_only}"}
62
+ {host: "slave_server#{(read_only_host+=1) % num_read_only}"}
63
63
  end
64
- DB=Sequel.connect('postgres://master_server/database', \
65
- :servers=>{:read_only=>read_only_proc})
64
+ DB=Sequel.connect('postgres://master_server/database',
65
+ servers: {read_only: read_only_proc})
66
66
 
67
67
  This will use one of the slave servers for SELECT queries and use the
68
- master_server for other queries. It's also possible to pick a random host
68
+ master server for other queries. It's also possible to pick a random host
69
69
  instead of using the round robin approach presented above, but that can result
70
70
  in less optimal resource usage.
71
71
 
@@ -78,15 +78,15 @@ it shows that the master database is named :default. So for 4 masters and
78
78
  num_read_only = 4
79
79
  read_only_host = rand(num_read_only)
80
80
  read_only_proc = proc do |db|
81
- {:host=>"slave_server#{(read_only_host+=1) % num_read_only}"}
81
+ {host: "slave_server#{(read_only_host+=1) % num_read_only}"}
82
82
  end
83
83
  num_default = 4
84
84
  default_host = rand(num_default)
85
85
  default_proc = proc do |db|
86
- {:host=>"master_server#{(default_host+=1) % num_default}"}
86
+ {host: "master_server#{(default_host+=1) % num_default}"}
87
87
  end
88
- DB=Sequel.connect('postgres://master_server/database', \
89
- :servers=>{:default=>default_proc, :read_only=>read_only_proc})
88
+ DB=Sequel.connect('postgres://master_server/database',
89
+ servers: {default: default_proc, read_only: read_only_proc})
90
90
 
91
91
  == Sharding
92
92
 
@@ -100,16 +100,16 @@ of 16 shards). First, you need to configure the database:
100
100
 
101
101
  servers = {}
102
102
  (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
103
- servers[hex.to_sym] = {:host=>"hash_host_#{hex}"}
103
+ servers[hex.to_sym] = {host: "hash_host_#{hex}"}
104
104
  end
105
- DB=Sequel.connect('postgres://hash_host/hashes', :servers=>servers)
105
+ DB=Sequel.connect('postgres://hash_host/hashes', servers: servers)
106
106
 
107
107
  This configures 17 servers, the 16 shard servers (/hash_host_[0-9a-f]/), and 1
108
108
  default server which will be used if no shard is specified ("hash_host"). If
109
109
  you want the default server to be one of the shard servers (e.g. hash_host_a),
110
110
  it's easiest to do:
111
111
 
112
- DB=Sequel.connect('postgres://hash_host_a/hashes', :servers=>servers)
112
+ DB=Sequel.connect('postgres://hash_host_a/hashes', servers: servers)
113
113
 
114
114
  That will still set up a second pool of connections for the default server,
115
115
  since it considers the default server and shard servers independent. Note that
@@ -120,7 +120,7 @@ schemas, so you should always have a default server that works.
120
120
 
121
121
  To set the shard for a given query, you use the Dataset#server method:
122
122
 
123
- DB[:hashes].server(:a).where(:hash=>/31337/)
123
+ DB[:hashes].server(:a).where(hash: /31337/)
124
124
 
125
125
  That will return all matching rows on the hash_host_a shard that have a hash
126
126
  column that contains 31337.
@@ -133,7 +133,7 @@ the shard to use. This is fairly easy using a Sequel::Model:
133
133
  dataset_module do
134
134
  def plaintext_for_hash(hash)
135
135
  raise(ArgumentError, 'Invalid SHA-1 Hash') unless /\A[0-9a-f]{40}\z/.match(hash)
136
- server(hash[0...1].to_sym).where(:hash=>hash).get(:plaintext)
136
+ server(hash[0...1].to_sym).where(hash: hash).get(:plaintext)
137
137
  end
138
138
  end
139
139
  end
@@ -146,24 +146,24 @@ to assume the :default shard. However, you can specify a
146
146
  different shard using the :servers_hash option when connecting
147
147
  to the database:
148
148
 
149
- DB = Sequel.connect('postgres://...', :servers_hash=>Hash.new(:some_shard))
149
+ DB = Sequel.connect('postgres://...', servers_hash: Hash.new(:some_shard))
150
150
 
151
151
  You can also use this feature to raise an exception if an
152
152
  unconfigured shard is used:
153
153
 
154
- DB = Sequel.connect('postgres://...', :servers_hash=>Hash.new{raise 'foo'})
154
+ DB = Sequel.connect('postgres://...', servers_hash: Hash.new{raise 'foo'})
155
155
 
156
156
  If you specify a :servers_hash option to raise an exception for non configured
157
157
  shards you should also explicitly specify a :read_only entry in your :servers option
158
158
  for the case where a shard is not specified. In most cases it is sufficient
159
159
  to make the :read_only entry the same as the :default shard:
160
160
 
161
- servers = {:read_only => {}}
161
+ servers = {read_only: {}}
162
162
  (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
163
- servers[hex.to_sym] = {:host=>"hash_host_#{hex}"}
163
+ servers[hex.to_sym] = {host: "hash_host_#{hex}"}
164
164
  end
165
- DB=Sequel.connect('postgres://hash_host/hashes', :servers=>servers,
166
- :servers_hash=>Hash.new{raise Exception.new("Invalid Server")})
165
+ DB=Sequel.connect('postgres://hash_host/hashes', servers: servers,
166
+ servers_hash: Hash.new{raise "Invalid Server"})
167
167
 
168
168
  === Sharding Plugin
169
169
 
@@ -176,7 +176,7 @@ work well with shards. You just need to remember to set to model to use the plu
176
176
  plugin :sharding
177
177
  end
178
178
 
179
- Rainbow.server(:a).first(:id=>1).update(:plaintext=>'VGM')
179
+ Rainbow.server(:a).first(id: 1).update(plaintext: 'VGM')
180
180
 
181
181
  If all of your models are sharded, you can set all models to use the plugin via:
182
182
 
@@ -186,7 +186,7 @@ If all of your models are sharded, you can set all models to use the plugin via:
186
186
 
187
187
  By default, you must specify the server/shard you want to use for every dataset/action,
188
188
  or Sequel will use the default shard. If you have a group of queries that should use the
189
- same shard, it can get a bit redundent to specify the same shard for all of them.
189
+ same shard, it can get a bit redundant to specify the same shard for all of them.
190
190
 
191
191
  The server_block extension adds a Database#with_server method that scopes all database
192
192
  access inside the block to the given shard by default:
@@ -194,7 +194,7 @@ access inside the block to the given shard by default:
194
194
  DB.extension :server_block
195
195
  DB.with_server(:a) do
196
196
  # this SELECT query uses the "a" shard
197
- if r = Rainbow.first(:hash=>/31337/)
197
+ if r = Rainbow.first(hash: /31337/)
198
198
  r.count += 1
199
199
  # this UPDATE query also uses the "a" shard
200
200
  r.save
@@ -209,6 +209,19 @@ you retrieve the models inside the block and save them outside of the block. If
209
209
  need to do that, call the server method explicitly on the dataset used to retrieve the
210
210
  model objects.
211
211
 
212
+ The with_server method also supports a second argument for the default read_only server
213
+ to use, which can be useful if you are mixing sharding and master/slave servers:
214
+
215
+ DB.extension :server_block
216
+ DB.with_server(:a, :a_read_only) do
217
+ # this SELECT query uses the "a_read_only" shard
218
+ if r = Rainbow.first(hash: /31337/)
219
+ r.count += 1
220
+ # this UPDATE query also uses the "a" shard
221
+ r.save
222
+ end
223
+ end
224
+
212
225
  === arbitrary_servers Extension
213
226
 
214
227
  By default, Sequel's sharding support is designed to work with predefined shards. It ships
@@ -220,13 +233,13 @@ The arbitrary_servers extension allows you to pass a server/shard options hash a
220
233
  server to use, and those options will be merged directly into the database's default options:
221
234
 
222
235
  DB.extension :arbitrary_servers
223
- DB[:rainbows].server(:host=>'hash_host_a').all
236
+ DB[:rainbows].server(host: 'hash_host_a').all
224
237
  # or
225
- DB[:rainbows].server(:host=>'hash_host_b', :database=>'backup').all
238
+ DB[:rainbows].server(host: 'hash_host_b', database: 'backup').all
226
239
 
227
240
  arbitrary_servers is designed to work well in conjunction with the server_block extension:
228
241
 
229
- DB.with_server(:host=>'hash_host_b', :database=>'backup') do
242
+ DB.with_server(host: 'hash_host_b', database: 'backup') do
230
243
  DB.synchronize do
231
244
  # All queries here default to the backup database on hash_host_b
232
245
  end
data/doc/sql.rdoc CHANGED
@@ -22,7 +22,7 @@ For SELECT queries, you should probably use <tt>Database#fetch</tt> with a strin
22
22
 
23
23
  You can also use named placeholders by starting the placeholder with a colon, and using a hash for the argument:
24
24
 
25
- DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :pattern=>'A%') do |row|
25
+ DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", pattern: 'A%') do |row|
26
26
  puts row[:name]
27
27
  end
28
28
 
@@ -121,21 +121,15 @@ As you can see, Sequel quotes identifiers by default. Depending on your databas
121
121
 
122
122
  :column # "COLUMN" on some databases
123
123
 
124
- A plain symbol is usually treated as an unqualified identifier. However, if you are using multiple tables in a query, and you want to reference a column in one of the tables that has the same name as a column in another one of the tables, you need to qualify that reference. There are two main ways in Sequel to do that. The first is implicit qualification inside the symbol, using the double underscore:
125
-
126
- :table__column # "table"."column"
127
-
128
- This works by default, but it is possible to turn off by setting <tt>Sequel.split_symbols = false</tt>.
129
-
130
- Note that you can't use a period to separate them:
124
+ A plain symbol is usually treated as an unqualified identifier. However, if you are using multiple tables in a query, and you want to reference a column in one of the tables that has the same name as a column in another one of the tables, you need to qualify that reference. Note that you can't use a period to separate them:
131
125
 
132
126
  :table.column # calls the column method on the symbol
133
127
 
134
128
  Also note that specifying the period inside the symbol doesn't work if you are quoting identifiers:
135
129
 
136
- :"table.column" # "table.column"
130
+ :"table.column" # "table.column" instead of "table"."column"
137
131
 
138
- The second way is to explicitly create a qualified identifier either by using <tt>Sequel.[]</tt> to create an identifier and call <tt>[]</tt> or +qualify+ on that, or by using the <tt>Sequel.qualify</tt> method with the table and column symbols:
132
+ There are a few different Sequel methods for creating qualified identifier objects. The recommended way is to explicitly create a qualified identifier by using <tt>Sequel.[]</tt> to create an identifier and call <tt>[]</tt> or +qualify+ on that, or by using the <tt>Sequel.qualify</tt> method with the table and column symbols:
139
133
 
140
134
  Sequel[:table][:column] # "table"."column"
141
135
  Sequel[:column].qualify(:table) # "table"."column"
@@ -148,6 +142,7 @@ Another way to generate identifiers is to use Sequel's {virtual row support}[rdo
148
142
 
149
143
  You can also use the symbol_aref extension for creating qualified identifiers:
150
144
 
145
+ Sequel.extension :symbol_aref
151
146
  :table[:column] # "table"."column"
152
147
 
153
148
  === Numbers
@@ -173,24 +168,16 @@ In general, Ruby strings map directly to SQL strings:
173
168
 
174
169
  === Aliasing
175
170
 
176
- Sequel allows for implicit aliasing in column symbols using the triple underscore:
177
-
178
- :column___alias # "column" AS "alias"
179
-
180
- You can combine this with implicit qualification:
181
-
182
- :table__column___alias # "table"."column" AS "alias"
183
-
184
- As with creating qualified identifiers via a double underscore, this works by default, but it is possible to turn off by setting <tt>Sequel.split_symbols = false</tt>.
185
-
186
- You can also use the <tt>Sequel.as</tt> method to create an alias, and the +as+ method on most Sequel-specific expression objects:
171
+ You can use the <tt>Sequel.as</tt> method to create an alias, and the +as+ method on most Sequel-specific expression objects:
187
172
 
188
173
  Sequel.as(:column, :alias) # "column" AS "alias"
189
174
  Sequel[:column].as(:alias) # "column" AS "alias"
190
175
  Sequel[:table][:column].as(:alias) # "table"."column" AS "alias"
176
+ (Sequel[:column] + 1).as(:alias) # ("column" + 1) AS "alias"
191
177
 
192
178
  You can also use the symbol_as extension for creating aliased identifiers:
193
179
 
180
+ Sequel.extension :symbol_as
194
181
  :column.as(:alias) # "column" AS "alias"
195
182
 
196
183
  If you want to use a derived column list, you can provide an array of column aliases:
@@ -215,11 +202,11 @@ Aggregate functions work the same way as normal functions, since they share the
215
202
 
216
203
  Sequel.function(:sum, :column) # sum(column)
217
204
 
218
- To use the DISTINCT modifier to an aggregate function, call the +distinct+ method on the function:
205
+ To use the DISTINCT modifier to an aggregate function, call the +distinct+ method on the function expression, which returns a new function expression:
219
206
 
220
207
  DB[:albums].select{sum(:column).distinct} # SELECT sum(DISTINCT column) FROM albums
221
208
 
222
- If you want to use the wildcard as the sole argument of the aggregate function, use the * method on the Function:
209
+ If you want to use the wildcard as the sole argument of the aggregate function, use the * method on the function expression:
223
210
 
224
211
  Sequel.function(:count).* # count(*)
225
212
  DB[:albums].select{count.function.*} # SELECT count(*) FROM albums
@@ -228,10 +215,10 @@ Note that Sequel provides helper methods for aggregate functions such as +count+
228
215
 
229
216
  === Window Functions
230
217
 
231
- If the database supports window functions, Sequel can handle them by calling the +over+ method on a Function:
218
+ If the database supports window functions, Sequel can handle them by calling the +over+ method on a function expression:
232
219
 
233
- DB[:albums].select{function.function.over}
234
- # SELECT function() OVER () FROM albums
220
+ DB[:albums].select{row_number.function.over}
221
+ # SELECT row_number() OVER () FROM albums
235
222
 
236
223
  DB[:albums].select{count.function.*.over}
237
224
  # SELECT count(*) OVER () FROM albums
@@ -244,12 +231,12 @@ If the database supports window functions, Sequel can handle them by calling the
244
231
 
245
232
  === Schema Qualified Functions
246
233
 
247
- If the database supports schema qualified functions, Sequel can handle them by calling the +function+ method on a QuailfiedIdentifier:
234
+ If the database supports schema qualified functions, Sequel can handle them by calling the +function+ method on a qualified identifier:
248
235
 
249
236
  DB[:albums].select{schema[:function].function}
250
237
  # SELECT schema.function() FROM albums
251
238
 
252
- DB[:albums].select{schema[:function].function(col, 2, "a")}
239
+ DB[:albums].select{schema[:function].function(:col, 2, "a")}
253
240
  # SELECT schema.function(col, 2, 'a') FROM albums
254
241
 
255
242
  === Portable/Emulated Functions
@@ -265,7 +252,7 @@ Some examples are:
265
252
 
266
253
  Sequel uses hashes to specify equality:
267
254
 
268
- {:column=>1} # ("column" = 1)
255
+ {column: 1} # ("column" = 1)
269
256
 
270
257
  You can also specify this as an array of two element arrays:
271
258
 
@@ -279,27 +266,27 @@ For expression objects, you can also use the =~ method:
279
266
 
280
267
  You can specify a not equals condition by inverting the hash or array of two element arrays using <tt>Sequel.negate</tt> or <tt>Sequel.~</tt>:
281
268
 
282
- Sequel.negate(:column => 1) # ("column" != 1)
269
+ Sequel.negate(column: 1) # ("column" != 1)
283
270
  Sequel.negate([[:column, 1]]) # ("column" != 1)
284
- Sequel.~(:column => 1) # ("column" != 1)
271
+ Sequel.~(column: 1) # ("column" != 1)
285
272
  Sequel.~([[:column, 1]]) # ("column" != 1)
286
273
 
287
274
  The difference between the two is that +negate+ only works on hashes and arrays of element arrays, and it negates all entries in the hash or array, while ~ does a general inversion. This is best shown by an example with multiple entries:
288
275
 
289
- Sequel.negate(:column => 1, :foo => 2) # (("column" != 1) AND (foo != 2))
290
- Sequel.~(:column => 1, :foo => 2) # (("column" != 1) OR (foo != 2))
276
+ Sequel.negate(column: 1, foo: 2) # (("column" != 1) AND (foo != 2))
277
+ Sequel.~(column: 1, foo: 2) # (("column" != 1) OR (foo != 2))
291
278
 
292
279
  You can also use the ~ method on an equality expression:
293
280
 
294
281
  where{~(column =~ 1)} # ("column" != 1)
295
282
 
296
- On Ruby 1.9+, you can use the !~ method:
283
+ Or you can use the !~ method:
297
284
 
298
285
  where{column !~ 1} # ("column" != 1)
299
286
 
300
287
  The most common need for not equals is in filters, in which case you can use the +exclude+ method:
301
288
 
302
- DB[:albums].exclude(:column=>1) # SELECT * FROM "albums" WHERE ("column" != 1)
289
+ DB[:albums].exclude(column: 1) # SELECT * FROM "albums" WHERE ("column" != 1)
303
290
 
304
291
  Note that +exclude+ does a generalized inversion, similar to <tt>Sequel.~</tt>.
305
292
 
@@ -307,19 +294,19 @@ Note that +exclude+ does a generalized inversion, similar to <tt>Sequel.~</tt>.
307
294
 
308
295
  Sequel also uses hashes to specify inclusion, and inversions of those hashes to specify exclusion:
309
296
 
310
- {:column=>[1, 2, 3]} # ("column" IN (1, 2, 3))
311
- Sequel.~(:column=>[1, 2, 3]) # ("column" NOT IN (1, 2, 3))
297
+ {column: [1, 2, 3]} # ("column" IN (1, 2, 3))
298
+ Sequel.~(column: [1, 2, 3]) # ("column" NOT IN (1, 2, 3))
312
299
 
313
300
  As you may have guessed, Sequel switches from an = to an IN when the hash value is an array. It also does this for datasets, which easily allows you to test for inclusion and exclusion in a subselect:
314
301
 
315
- {:column=>DB[:albums].select(:id)} # ("column" IN (SELECT "id" FROM "albums"))
316
- Sequel.~(:column=>DB[:albums].select(:id)) # ("column" NOT IN (SELECT "id" FROM "albums"))
302
+ {column: DB[:albums].select(:id)} # ("column" IN (SELECT "id" FROM "albums"))
303
+ Sequel.~(column: DB[:albums].select(:id)) # ("column" NOT IN (SELECT "id" FROM "albums"))
317
304
 
318
305
  Similar to =, you can also use =~ with expressions for inclusion:
319
306
 
320
307
  where{column =~ [1, 2, 3]} # ("column" IN (1, 2, 3))
321
308
 
322
- and on Ruby 1.9, !~ for exclusion:
309
+ and !~ for exclusion:
323
310
 
324
311
  where{column !~ [1, 2, 3]} # ("column" NOT IN (1, 2, 3))
325
312
 
@@ -331,17 +318,17 @@ Sequel also supports the SQL EXISTS operator using <tt>Dataset#exists</tt>:
331
318
 
332
319
  Hashes in Sequel use IS if the value is +true+, +false+, or +nil+:
333
320
 
334
- {:column=>nil} # ("column" IS NULL)
335
- {:column=>true} # ("column" IS TRUE)
336
- {:column=>false} # ("column" IS FALSE)
321
+ {column: nil} # ("column" IS NULL)
322
+ {column: true} # ("column" IS TRUE)
323
+ {column: false} # ("column" IS FALSE)
337
324
 
338
325
  Negation works the same way as it does for equality and inclusion:
339
326
 
340
- Sequel.~(:column=>nil) # ("column" IS NOT NULL)
341
- Sequel.~(:column=>true) # ("column" IS NOT TRUE)
342
- Sequel.~(:column=>false) # ("column" IS NOT FALSE)
327
+ Sequel.~(column: nil) # ("column" IS NOT NULL)
328
+ Sequel.~(column: true) # ("column" IS NOT TRUE)
329
+ Sequel.~(column: false) # ("column" IS NOT FALSE)
343
330
 
344
- Likewise, =~ works for identity (and Ruby 1.9, !~ for negative identity):
331
+ Likewise, =~ works for identity and !~ for negative identity on expressions:
345
332
 
346
333
  where{column =~ nil} # ("column" IS NULL)
347
334
  where{column !~ nil} # ("column" IS NOT NULL)
@@ -354,7 +341,7 @@ Sequel's general inversion operator is ~, which works on symbols and most Sequel
354
341
 
355
342
  Note that ~ will actually apply the inversion operation to the underlying object, which is why
356
343
 
357
- Sequel.~(:column=>1)
344
+ Sequel.~(column: 1)
358
345
 
359
346
  produces <tt>(column != 1)</tt> instead of <tt>NOT (column = 1)</tt>.
360
347
 
@@ -367,7 +354,7 @@ Sequel defines the inequality operators directly on most Sequel-specific express
367
354
  Sequel.function(:func) >= 1 # (func() >= 1)
368
355
  Sequel.function(:func, :column) <= 1 # (func("column") <= 1)
369
356
 
370
- If you want to use them on a symbol, you should call <tt>Sequel.[]</tt> with the symbol:
357
+ If you want to use them on a symbol, you should call <tt>Sequel.[]</tt> with the symbol to get an expression object:
371
358
 
372
359
  Sequel[:column] > 1 # ("column" > 1)
373
360
 
@@ -403,7 +390,7 @@ Note that since Sequel implements support for Ruby's coercion protocol, the foll
403
390
  Sequel defines the & and | methods on most Sequel-specific expression objects to handle AND and OR:
404
391
 
405
392
  Sequel[:column1] & :column2 # ("column1" AND "column2")
406
- Sequel[:column1=>1] | {:column2=>2} # (("column1" = 1) OR ("column2" = 2))
393
+ Sequel[{column1: 1}] | {column2: 2} # (("column1" = 1) OR ("column2" = 2))
407
394
  (Sequel.function(:func) > 1) & :column3 # ((func() > 1) AND "column3")
408
395
 
409
396
  Note the use of parentheses in the last statement. If you omit them, you won't get what you expect.
@@ -418,28 +405,28 @@ is parsed as:
418
405
  You can also use the <tt>Sequel.&</tt> and <tt>Sequel.|</tt> methods:
419
406
 
420
407
  Sequel.&(:column1, :column2) # ("column1" AND "column2")
421
- Sequel.|({:column1=>1}, {:column2=>2}) # (("column1" = 1) OR ("column2" = 2))
408
+ Sequel.|({column1: 1}, {column2: 2}) # (("column1" = 1) OR ("column2" = 2))
422
409
 
423
410
  You can use hashes and arrays of two element arrays to specify AND and OR with equality conditions:
424
411
 
425
- {:column1=>1, :column2=>2} # (("column1" = 1) AND ("column2" = 2))
412
+ {column1: 1, column2: 2} # (("column1" = 1) AND ("column2" = 2))
426
413
  [[:column1, 1], [:column2, 2]] # (("column1" = 1) AND ("column2" = 2))
427
414
 
428
415
  As you can see, these literalize with ANDs by default. You can use the <tt>Sequel.or</tt> method to use OR instead:
429
416
 
430
- Sequel.or(:column1=>1, :column2=>2) # (("column1" = 1) OR ("column2" = 2))
417
+ Sequel.or(column1: 1, column2: 2) # (("column1" = 1) OR ("column2" = 2))
431
418
 
432
419
  You've already seen the <tt>Sequel.negate</tt> method, which will use ANDs if multiple entries are used:
433
420
 
434
- Sequel.negate(:column1=>1, :column2=>2) # (("column1" != 1) AND ("column2" != 2))
421
+ Sequel.negate(column1: 1, column2: 2) # (("column1" != 1) AND ("column2" != 2))
435
422
 
436
423
  To negate while using ORs, the <tt>Sequel.~</tt> operator can be used:
437
424
 
438
- Sequel.~(:column1=>1, :column2=>2) # (("column1" != 1) OR ("column2" != 2))
425
+ Sequel.~(column1: 1, column2: 2) # (("column1" != 1) OR ("column2" != 2))
439
426
 
440
427
  Note again that <tt>Dataset#exclude</tt> uses ~, not +negate+:
441
428
 
442
- DB[:albums].exclude(:column1=>1, :column2=>2) # SELECT * FROM "albums" WHERE (("column" != 1) OR ("column2" != 2))
429
+ DB[:albums].exclude(column1: 1, column2: 2) # SELECT * FROM "albums" WHERE (("column" != 1) OR ("column2" != 2))
443
430
 
444
431
  === Casts
445
432
 
@@ -521,8 +508,8 @@ Sequel also supports SQL regular expressions on MySQL and PostgreSQL. You can u
521
508
 
522
509
  Sequel.like(:name, /^A/) # ("name" ~ '^A')
523
510
  ~Sequel.ilike(:name, /^A/) # ("name" !~* '^A')
524
- {:name=>/^A/i} # ("name" ~* '^A')
525
- Sequel.~(:name=>/^A/) # ("name" !~ '^A')
511
+ {name: /^A/i} # ("name" ~* '^A')
512
+ Sequel.~(name: /^A/) # ("name" !~ '^A')
526
513
 
527
514
  Note that using +ilike+ with a regular expression will always make the regexp case insensitive. If you use +like+ or the hash with regexp value, it will only be case insensitive if the Regexp itself is case insensitive.
528
515
 
@@ -545,21 +532,22 @@ On some databases, you can specify null ordering:
545
532
 
546
533
  === All Columns (.*)
547
534
 
548
- To select all columns in a table, Sequel supports the * method on identifiers without an argument:
535
+ To select all columns in a table, Sequel supports the * method on identifiers and qualified without an argument:
549
536
 
550
- Sequel[:table].* # "table".*
537
+ Sequel[:table].* # "table".*
538
+ Sequel[:schema][:table].* # "schema"."table".*
551
539
 
552
540
  === CASE statements
553
541
 
554
- Sequel allows the easy production of SQL CASE statements using the <tt>Sequel.case</tt> method. The first argument is a hash or array of two element arrays representing the conditions, the second argument is the default value (ELSE). The keys of the hash (or first element in each array) is the WHEN condition, and the values of the hash (or second element in each array) is the THEN result. Here are some examples:
542
+ Sequel supports SQL CASE statements using the <tt>Sequel.case</tt> method. The first argument is a hash or array of two element arrays representing the conditions, the second argument is the default value (ELSE). The keys of the hash (or first element in each array) is the WHEN condition, and the values of the hash (or second element in each array) is the THEN result. Here are some examples:
555
543
 
556
- Sequel.case({:column=>1}, 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
557
- Sequel.case([[column, 1]], 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
558
- Sequel.case({{:column=>nil}=>1}, 0) # (CASE WHEN (column IS NULL) THEN 1 ELSE 0 END)
544
+ Sequel.case({column: 1}, 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
545
+ Sequel.case([[:column, 1]], 0) # (CASE WHEN "column" THEN 1 ELSE 0 END)
546
+ Sequel.case({{column: nil}=>1}, 0) # (CASE WHEN (column IS NULL) THEN 1 ELSE 0 END)
559
547
 
560
548
  If the hash or array has multiple arguments, multiple WHEN clauses are used:
561
549
 
562
- Sequel.case({:c=>1, :d=>2}, 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
550
+ Sequel.case({c: 1, d: 2}, 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
563
551
  Sequel.case([[:c, 1], [:d, 2]], 0) # (CASE WHEN "c" THEN 1 WHEN "d" THEN 2 ELSE 0 END)
564
552
 
565
553
  If you provide a 3rd argument to <tt>Sequel.case</tt>, it goes between CASE and WHEN:
data/doc/testing.rdoc CHANGED
@@ -156,13 +156,12 @@ SEQUEL_COLUMNS_INTROSPECTION :: Use the columns_introspection extension when run
156
156
  SEQUEL_CONNECTION_VALIDATOR :: Use the connection validator extension when running the specs
157
157
  SEQUEL_DUPLICATE_COLUMNS_HANDLER :: Use the duplicate columns handler extension with value given when running the specs
158
158
  SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
159
- SEQUEL_FREEZE_DATASETS :: Use the freeze_datasets extension when running the specs
160
159
  SEQUEL_FREEZE_DATABASE :: Freeze the database before running the integration specs
161
160
  SEQUEL_IDENTIFIER_MANGLING :: Use the identifier_mangling extension when running the specs
162
- SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements and prepared_statements_associations plugins when running the specs
163
- SEQUEL_NO_AUTO_LITERAL_STRINGS :: Use the no_auto_string_literals extension when running the specs
161
+ SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements plugin when running the specs
164
162
  SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
165
163
  SEQUEL_NO_CHECK_SQLS :: Don't check for specific SQL syntax when running the specs
164
+ SEQUEL_CHECK_PENDING :: Try running all specs (note, can cause lockups for some adapters), and raise errors for skipped specs that don't fail
166
165
  SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
167
- SEQUEL_NO_SPLIT_SYMBOLS :: Turn off symbol splitting when running the specs
168
- SKIPPED_TEST_WARN :: Warn when skipping any tests because libraries aren't available
166
+ SEQUEL_SPLIT_SYMBOLS :: Turn on symbol splitting when running the adapter and integration specs
167
+ SEQUEL_SYNCHRONIZE_SQL :: Use the synchronize_sql extension when running the specs
@@ -1,10 +1,10 @@
1
1
  = Thread Safety
2
2
 
3
- Most Sequel usage (and all common Sequel usage) is thread safe by default. Specifically, multiple threads can operate on Database instances, Dataset instances, and Model classes concurrently without problems. In general, Database instance and Model classes are not modified after application startup, and modifying Dataset instances returns modified copies of the dataset instead of mutating it.
3
+ Most Sequel usage (and all common Sequel usage) is thread safe by default. Specifically, multiple threads can operate on Database instances, Dataset instances, and Model classes concurrently without problems. In general, Database instance and Model classes are not modified after application startup, and Dataset instances are always frozen.
4
4
 
5
5
  == Connection Pool
6
6
 
7
- In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool does not have an available connection, a new connection will be created. If the maximum number of connections in the pool has already been reached, the thread will block until a connection is available or the connection pool timeout has elapsed (in which case a PoolTimeout error will be raised).
7
+ In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool does not have an available connection, a new connection will be created. If the maximum number of connections in the pool has already been reached, the thread will block until a connection is available or the connection pool timeout has elapsed (in which case a Sequel::PoolTimeout error will be raised).
8
8
 
9
9
  == Exceptions
10
10
 
@@ -13,5 +13,3 @@ This is a small list of things that are specifically non thread-safe. This is n
13
13
  1) Model instances: Model instances are not thread-safe unless they are frozen first. Multiple threads should not operate on an unfrozen model instance concurrently.
14
14
 
15
15
  2) Model class modifications: Model class modifications, such as adding associations and loading plugins, are not designed to be thread safe. You should not modify a class in one thread if any other thread can concurrently access it. Model subclassing is designed to be thread-safe, so you create a model subclass in a thread and modify it safely.
16
-
17
- 3) Dataset mutation methods: Dataset mutation methods are not thread safe, you should not call them on datasets that could be accessed by other threads. It is safe to clone the dataset first inside a thread and call mutation methods on the cloned dataset.