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
@@ -25,27 +25,27 @@ type for the given database. So while you specified +String+, Sequel will actua
25
25
  +text+ depending on the underlying database. Here's a list of all ruby classes that Sequel will
26
26
  convert to database types:
27
27
 
28
- create_table(:columns_types) do # common database type used
29
- Integer :a0 # integer
30
- String :a1 # varchar(255)
31
- String :a2, :size=>50 # varchar(50)
32
- String :a3, :fixed=>true # char(255)
33
- String :a4, :fixed=>true, :size=>50 # char(50)
34
- String :a5, :text=>true # text
35
- File :b # blob
36
- Fixnum :c # integer
37
- Bignum :d # bigint
38
- Float :e # double precision
39
- BigDecimal :f # numeric
40
- BigDecimal :f2, :size=>10 # numeric(10)
41
- BigDecimal :f3, :size=>[10, 2] # numeric(10, 2)
42
- Date :g # date
43
- DateTime :h # timestamp
44
- Time :i # timestamp
45
- Time :i2, :only_time=>true # time
46
- Numeric :j # numeric
47
- TrueClass :k # boolean
48
- FalseClass :l # boolean
28
+ create_table(:columns_types) do # common database type used
29
+ Integer :a0 # integer
30
+ String :a1 # varchar(255)
31
+ String :a2, size: 50 # varchar(50)
32
+ String :a3, fixed: true # char(255)
33
+ String :a4, fixed: true, size: 50 # char(50)
34
+ String :a5, text: true # text
35
+ File :b # blob
36
+ Fixnum :c # integer
37
+ Bignum :d # bigint
38
+ Float :e # double precision
39
+ BigDecimal :f # numeric
40
+ BigDecimal :f2, size: 10 # numeric(10)
41
+ BigDecimal :f3, size: [10, 2] # numeric(10, 2)
42
+ Date :g # date
43
+ DateTime :h # timestamp
44
+ Time :i # timestamp
45
+ Time :i2, only_time: true # time
46
+ Numeric :j # numeric
47
+ TrueClass :k # boolean
48
+ FalseClass :l # boolean
49
49
  end
50
50
 
51
51
  Note that in addition to the ruby class name, Sequel also pays attention to the column options when
@@ -89,7 +89,7 @@ method, the fourth argument is the options hash. The following options are supp
89
89
  options for the index.
90
90
  :null :: Mark the column as allowing NULL values (if true),
91
91
  or not allowing NULL values (if false). If unspecified, will default
92
- to whatever the database default is.
92
+ to whatever the database default is (usually true).
93
93
  :primary_key :: Mark this column as the primary key. This is used instead of the
94
94
  primary key method if you want a non-autoincrementing primary key.
95
95
  :primary_key_constraint_name :: The name to give the primary key constraint.
@@ -98,7 +98,7 @@ method, the fourth argument is the options hash. The following options are supp
98
98
  as +primary_key+ or +foreign_key+.
99
99
  :unique :: Mark the column as unique, generally has the same effect as
100
100
  creating a unique index on the column.
101
- :unique_constraint_name :: The name to give the unique key constraint.
101
+ :unique_constraint_name :: The name to give the unique constraint.
102
102
 
103
103
  === Other methods
104
104
 
@@ -112,14 +112,14 @@ You've seen this one used already. It's used to create an autoincrementing inte
112
112
 
113
113
  If you want an autoincrementing 64-bit integer:
114
114
 
115
- create_table(:a0){primary_key :id, :type=>:Bignum}
115
+ create_table(:a0){primary_key :id, type: :Bignum}
116
116
 
117
117
  If you want to create a primary key column that doesn't use an autoincrementing integer, you should
118
118
  not use this method. Instead, you should use the :primary_key option to the +column+ method or type
119
119
  method:
120
120
 
121
- create_table(:a1){Integer :id, :primary_key=>true} # Non autoincrementing integer primary key
122
- create_table(:a2){String :name, :primary_key=>true} # varchar(255) primary key
121
+ create_table(:a1){Integer :id, primary_key: true} # Non autoincrementing integer primary key
122
+ create_table(:a2){String :name, primary_key: true} # varchar(255) primary key
123
123
 
124
124
  If you want to create a composite primary key, you should call the +primary_key+ method with an
125
125
  array of column symbols. You can provide a specific name to use for the primary key constraint
@@ -128,7 +128,7 @@ via the :name option:
128
128
  create_table(:items) do
129
129
  Integer :group_id
130
130
  Integer :position
131
- primary_key [:group_id, :position], :name=>:items_pk
131
+ primary_key [:group_id, :position], name: :items_pk
132
132
  end
133
133
 
134
134
  If provided with an array, +primary_key+ does not create a column, it just sets up the primary key constraint.
@@ -147,7 +147,7 @@ as its third argument. A simple example is:
147
147
 
148
148
  +foreign_key+ accepts the same options as +column+. For example, to have a unique foreign key with varchar(16) type:
149
149
 
150
- foreign_key :column_name, :table, :unique=>true, :type=>'varchar(16)'
150
+ foreign_key :column_name, :table, unique: true, type: 'varchar(16)'
151
151
 
152
152
  +foreign_key+ also accepts some specific options:
153
153
 
@@ -186,7 +186,7 @@ When using an array of symbols, you can also provide a :name option to name the
186
186
  String :artist_name
187
187
  String :artist_location
188
188
  String :name
189
- foreign_key [:artist_name, :artist_location], :artists, :name=>'albums_artist_name_location_fkey'
189
+ foreign_key [:artist_name, :artist_location], :artists, name: 'albums_artist_name_location_fkey'
190
190
  end
191
191
 
192
192
  If you want to add a foreign key for a single column with a named constraint, you must use
@@ -196,7 +196,7 @@ the array form with a single symbol:
196
196
  primary_key :id
197
197
  Integer :artist_id
198
198
  String :name
199
- foreign_key [:artist_id], :artists, :name=>'albums_artist_id_fkey'
199
+ foreign_key [:artist_id], :artists, name: 'albums_artist_id_fkey'
200
200
  end
201
201
 
202
202
  ==== +index+
@@ -204,18 +204,18 @@ the array form with a single symbol:
204
204
  +index+ creates indexes on the table. For single columns, calling index is the same as using the
205
205
  <tt>:index</tt> option when creating the column:
206
206
 
207
- create_table(:a){Integer :id, :index=>true}
207
+ create_table(:a){Integer :id, index: true}
208
208
  # Same as:
209
209
  create_table(:a) do
210
210
  Integer :id
211
211
  index :id
212
212
  end
213
213
 
214
- create_table(:a){Integer :id, :index=>{:unique=>true}}
214
+ create_table(:a){Integer :id, index: {unique: true}}
215
215
  # Same as:
216
216
  create_table(:a) do
217
217
  Integer :id
218
- index :id, :unique=>true
218
+ index :id, unique: true
219
219
  end
220
220
 
221
221
  Similar to the +primary_key+ and +foreign_key+ methods, calling +index+ with an array of symbols
@@ -241,11 +241,11 @@ The +unique+ method creates a unique constraint on the table. A unique constrai
241
241
  operates identically to a unique index, so the following three +create_table+ blocks are
242
242
  pretty much identical:
243
243
 
244
- create_table(:a){Integer :a, :unique=>true}
244
+ create_table(:a){Integer :a, unique: true}
245
245
 
246
246
  create_table(:a) do
247
247
  Integer :a
248
- index :a, :unique=>true
248
+ index :a, unique: true
249
249
  end
250
250
 
251
251
  create_table(:a) do
@@ -304,23 +304,23 @@ constraint, as that makes it easier to drop the constraint later if necessary.
304
304
 
305
305
  +create_join_table+ is a shortcut that you can use to create simple many-to-many join tables:
306
306
 
307
- create_join_table(:artist_id=>:artists, :album_id=>:albums)
307
+ create_join_table(artist_id: :artists, album_id: :albums)
308
308
 
309
309
  which expands to:
310
310
 
311
311
  create_table(:albums_artists) do
312
- foreign_key :album_id, :albums, :null=>false
313
- foreign_key :artist_id, :artists, :null=>false
312
+ foreign_key :album_id, :albums
313
+ foreign_key :artist_id, :artists
314
314
  primary_key [:album_id, :artist_id]
315
315
  index [:artist_id, :album_id]
316
316
  end
317
317
 
318
- == <tt>create_table :as=></tt>
318
+ == <tt>create_table :as</tt>
319
319
 
320
320
  To create a table from the result of a SELECT query, instead of passing a block
321
321
  to +create_table+, provide a dataset to the :as option:
322
322
 
323
- create_table(:older_items, :as=>DB[:items].where{updated_at < Date.today << 6})
323
+ create_table(:older_items, as: DB[:items].where{updated_at < Date.today << 6})
324
324
 
325
325
  == +alter_table+
326
326
 
@@ -336,7 +336,7 @@ argument is the column name, the second is the type, and the third is an options
336
336
  hash:
337
337
 
338
338
  alter_table(:albums) do
339
- add_column :copies_sold, Integer, :default=>0
339
+ add_column :copies_sold, Integer, default: 0
340
340
  end
341
341
 
342
342
  === +drop_column+
@@ -374,6 +374,12 @@ Sequel will not add a column, but will add a composite primary key constraint:
374
374
  add_primary_key [:album_id, :artist_id]
375
375
  end
376
376
 
377
+ It is possible to specify a name for the primary key constraint: via the :name option:
378
+
379
+ alter_table(:albums_artists) do
380
+ add_primary_key [:album_id, :artist_id], :name=>:albums_artists_pkey
381
+ end
382
+
377
383
  If you just want to take an existing single column and make it a primary key, call
378
384
  +add_primary_key+ with an array with a single symbol:
379
385
 
@@ -392,18 +398,29 @@ creates a new column:
392
398
  end
393
399
 
394
400
  If you want to add a new foreign key constraint to an existing column, you provide an
395
- array with a single element. It's encouraged to provide a name when adding the constraint,
396
- via the :name option:
401
+ array with a single element:
402
+
403
+ alter_table(:albums) do
404
+ add_foreign_key [:artist_id], :artists
405
+ end
406
+
407
+ It's encouraged to provide a name when adding the constraint, via the :foreign_key_constraint_name
408
+ option if adding the column and the constraint:
409
+
410
+ alter_table(:albums) do
411
+ add_foreign_key :artist_id, :artists, foreign_key_constraint_name: :albums_artist_id_fkey
412
+ end
413
+
414
+ or via the :name option if just adding the constraint:
397
415
 
398
416
  alter_table(:albums) do
399
- add_foreign_key [:artist_id], :artists, :name=>:albums_artist_id_fkey
417
+ add_foreign_key [:artist_id], :artists, name: :albums_artist_id_fkey
400
418
  end
401
419
 
402
- To set up a multiple column foreign key constraint, use an array with multiple column
403
- symbols:
420
+ To set up a multiple column foreign key constraint, use an array with multiple column symbols:
404
421
 
405
422
  alter_table(:albums) do
406
- add_foreign_key [:artist_name, :artist_location], :artists, :name=>:albums_artist_name_location_fkey
423
+ add_foreign_key [:artist_name, :artist_location], :artists, name: :albums_artist_name_location_fkey
407
424
  end
408
425
 
409
426
  === +drop_foreign_key+
@@ -420,13 +437,13 @@ an array. It's encouraged to use the :name option to provide the constraint nam
420
437
  drop, though on some databases Sequel may be able to find the name through introspection:
421
438
 
422
439
  alter_table(:albums) do
423
- drop_foreign_key [:artist_id], :name=>:albums_artist_id_fkey
440
+ drop_foreign_key [:artist_id], name: :albums_artist_id_fkey
424
441
  end
425
442
 
426
443
  An array is also used to drop a composite foreign key constraint:
427
444
 
428
445
  alter_table(:albums) do
429
- drop_foreign_key [:artist_name, :artist_location], :name=>:albums_artist_name_location_fkey
446
+ drop_foreign_key [:artist_name, :artist_location], name: :albums_artist_name_location_fkey
430
447
  end
431
448
 
432
449
  If you do not provide a :name option and Sequel is not able to determine the name
@@ -445,7 +462,7 @@ It accepts the same options as +create_table+'s +index+ method, and you can set
445
462
  a multiple column index using an array:
446
463
 
447
464
  alter_table(:albums_artists) do
448
- add_index [:album_id, :artist_id], :unique=>true
465
+ add_index [:album_id, :artist_id], unique: true
449
466
  end
450
467
 
451
468
  === +drop_index+
@@ -461,7 +478,7 @@ Just like +drop_column+, it is often used in the +down+ block of a migration.
461
478
  To drop an index with a specific name, use the <tt>:name</tt> option:
462
479
 
463
480
  alter_table(:albums) do
464
- drop_index :artist_id, :name=>:artists_id_index
481
+ drop_index :artist_id, name: :artists_id_index
465
482
  end
466
483
 
467
484
  === +add_full_text_index+, +add_spatial_index+
@@ -480,7 +497,7 @@ method:
480
497
 
481
498
  There is no method to add an unnamed constraint, but you can pass +nil+ as the first
482
499
  argument of +add_constraint+ to do so. However, it's not recommended to do that
483
- as it is difficult to drop such a constraint.
500
+ as it is more difficult to drop such a constraint.
484
501
 
485
502
  === +add_unique_constraint+
486
503
 
@@ -491,6 +508,12 @@ method. This usually has the same effect as adding a unique index.
491
508
  add_unique_constraint [:artist_id, :name]
492
509
  end
493
510
 
511
+ You can also specify a name via the :name option when adding the constraint:
512
+
513
+ alter_table(:albums) do
514
+ add_unique_constraint [:artist_id, :name], name: :albums_artist_id_name_ukey
515
+ end
516
+
494
517
  === +drop_constraint+
495
518
 
496
519
  This method drops an existing named constraint:
@@ -506,9 +529,9 @@ For that reason, you should not add unnamed constraints that you ever might need
506
529
  On some databases, you must specify the type of constraint via a <tt>:type</tt> option:
507
530
 
508
531
  alter_table(:albums) do
509
- drop_constraint(:albums_pk, :type=>:primary_key)
510
- drop_constraint(:albums_fk, :type=>:foreign_key)
511
- drop_constraint(:albums_uk, :type=>:unique)
532
+ drop_constraint(:albums_pk, type: :primary_key)
533
+ drop_constraint(:albums_fk, type: :foreign_key)
534
+ drop_constraint(:albums_uk, type: :unique)
512
535
  end
513
536
 
514
537
  === +set_column_default+
@@ -597,9 +620,6 @@ the table if the table already exists. On some databases, it uses
597
620
  <tt>IF NOT EXISTS</tt>, on others it does a separate query to check for
598
621
  existence.
599
622
 
600
- This should not be used inside migrations, as if the table does not
601
- exist, it may mess up the migration.
602
-
603
623
  === +rename_table+
604
624
 
605
625
  You can rename an existing table using +rename_table+. Like +rename_column+,
@@ -623,9 +643,6 @@ is the same as:
623
643
  primary_key :id
624
644
  end
625
645
 
626
- It should not be used inside migrations, as if the table does not exist, it may
627
- mess up the migration.
628
-
629
646
  === <tt>create_table?</tt>
630
647
 
631
648
  <tt>create_table?</tt> only creates the table if it does
@@ -643,8 +660,6 @@ is the same as:
643
660
  end
644
661
  end
645
662
 
646
- Like <tt>create_table!</tt>, it should not be used inside migrations.
647
-
648
663
  === +create_view+ and +create_or_replace_view+
649
664
 
650
665
  These can be used to create views. The difference between them is that
@@ -662,4 +677,3 @@ second argument:
662
677
  arguments:
663
678
 
664
679
  drop_view(:gold_albums, :platinum_albums)
665
-
data/doc/security.rdoc CHANGED
@@ -16,14 +16,11 @@ as it never calls eval on a string that is derived from user input.
16
16
  However, some Sequel methods used for creating methods via metaprogramming
17
17
  could conceivably be abused to do so:
18
18
 
19
- * Sequel::Schema::CreateTableGenerator.add_type_method
20
- * Sequel::Dataset.def_mutation_method
21
19
  * Sequel::Dataset.def_sql_method
22
- * Sequel::Model::Plugins.def_dataset_methods
23
- * Sequel.def_adapter_method (private)
24
- * Sequel::SQL::Expression.to_s_method (private)
25
- * Sequel::Plugins::HookClassMethods::ClassMethods#add_hook_type
20
+ * Sequel::JDBC.load_driver
26
21
  * Sequel::Plugins.def_dataset_methods
22
+ * Sequel::Dataset.prepared_statements_module (private)
23
+ * Sequel::SQL::Expression.to_s_method (private)
27
24
 
28
25
  As long as you don't call those with user input, you should not be
29
26
  vulnerable to code execution.
@@ -48,6 +45,9 @@ There are basically two kinds of possible SQL injections in Sequel:
48
45
  Some Sequel methods are designed to execute raw SQL strings, including:
49
46
 
50
47
  * Sequel::Database#execute
48
+ * Sequel::Database#execute_ddl
49
+ * Sequel::Database#execute_dui
50
+ * Sequel::Database#execute_insert
51
51
  * Sequel::Database#run
52
52
  * Sequel::Database#<<
53
53
  * Sequel::Dataset#fetch_rows
@@ -61,9 +61,12 @@ Some Sequel methods are designed to execute raw SQL strings, including:
61
61
 
62
62
  Here are some examples of use:
63
63
 
64
+ DB.execute 'SQL'
65
+ DB.execute_ddl 'SQL'
66
+ DB.execute_dui 'SQL'
67
+ DB.execute_insert 'SQL'
64
68
  DB.run 'SQL'
65
69
  DB << 'SQL'
66
- DB.execute 'SQL'
67
70
  DB.fetch_rows('SQL'){|row| }
68
71
  DB.dataset.with_sql_all('SQL')
69
72
  DB.dataset.with_sql_delete('SQL')
@@ -102,19 +105,16 @@ With these methods you should use placeholders, in which case Sequel automatical
102
105
 
103
106
  Sequel generally treats ruby strings as SQL strings (escaping them correctly), and
104
107
  not as raw SQL. However, you can convert a ruby string to a literal string, and
105
- Sequel will then treat it as raw SQL. This is typically done through String#lit
106
- if the {core_extensions}[rdoc-ref:doc/core_extensions.rdoc] are in use,
107
- or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] if they are not in use.
108
+ Sequel will then treat it as raw SQL. This is typically done through
109
+ Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit].
108
110
 
109
- 'a'.lit
110
111
  Sequel.lit('a')
111
112
 
112
- Using String#lit or Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] to turn a ruby string into a literal string results
113
+ Using Sequel.lit[rdoc-ref:Sequel::SQL::Builders#lit] to turn a ruby string into a literal string results
113
114
  in SQL injection if the string is derived from user input. With both of these
114
115
  methods, the strings can contain placeholders, which you can use to safely include
115
116
  user input inside a literal string:
116
117
 
117
- 'a = ?'.lit(params[:user_id].to_s)
118
118
  Sequel.lit('a = ?', params[:user_id].to_s)
119
119
 
120
120
  Even though they have similar names, note that Sequel::Database#literal operates very differently from
@@ -132,91 +132,107 @@ a ruby string as raw SQL. For example:
132
132
 
133
133
  ==== SQL Filter Fragments
134
134
 
135
- The most common way to use raw SQL with Sequel is in filters:
135
+ Starting in Sequel 5, Sequel does not automatically convert plain strings to
136
+ literal strings in typical code. Instead, you can use Sequel.lit to
137
+ create literal strings:
136
138
 
137
- DB[:table].where("name > 'M'")
139
+ Sequel.lit("name > 'A'")
138
140
 
139
- If a filter method is passed a string as the first argument, it treats the rest of
140
- the arguments (if any) as placeholders to the string. So you should never do:
141
+ To safely include user input as part of an SQL filter fragment, use Sequel.lit
142
+ with placeholders:
141
143
 
142
- DB[:table].where("name > #{params[:id].to_s}") # SQL Injection!
144
+ DB[:table].where(Sequel.lit("name > ?", params[:id].to_s)) # Safe
143
145
 
144
- Instead, you should use a placeholder:
146
+ Be careful to never call Sequel.lit where the first argument is derived from
147
+ user input.
145
148
 
146
- DB[:table].where("name > ?", params[:id].to_s) # Safe
147
-
148
- Note that for that type of query, Sequel generally encourages the following form:
149
+ There are a few uncommon cases where Sequel will still convert
150
+ plain strings to literal strings.
151
+
152
+ ==== SQL Fragment passed to Dataset#lock_style and Model#lock!
153
+
154
+ The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
155
+ an input string as SQL code. These methods should not be called with user input.
156
+
157
+ DB[:table].lock_style(params[:id]) # SQL injection!
158
+ Album.first.lock!(params[:id]) # SQL injection!
159
+
160
+ ==== SQL Type Names
161
+
162
+ In general, most places where Sequel needs to use an SQL type that should
163
+ be specified by the user, it allows you to use a ruby string, and that
164
+ string is used verbatim as the SQL type. You should not use user input
165
+ for type strings.
166
+
167
+ DB[:table].select(Sequel.cast(:a, params[:id])) # SQL injection!
168
+
169
+ ==== SQL Function Names
170
+
171
+ In most cases, Sequel does not quote SQL function names. You should not use
172
+ user input for function names.
173
+
174
+ DB[:table].select(Sequel.function(params[:id])) # SQL injection!
175
+
176
+ ==== auto_literal_strings extension
149
177
 
150
- DB[:table].where{|o| o.name > params[:id].to_s} # Safe
178
+ If the auto_literal_strings extension is used for backwards compatibility,
179
+ then Sequel will treat plain strings as literal strings if they are used
180
+ as the first argument to a filtering method. This can lead to SQL
181
+ injection:
151
182
 
152
- Sequel's DSL supports a wide variety of SQL concepts, so it's possible to
153
- code most applications without ever using raw SQL.
183
+ DB[:table].where("name > #{params[:id].to_s}")
184
+ # SQL injection when using auto_literal_strings extension
154
185
 
155
- A large number of dataset methods ultimately pass down their arguments to a filter
156
- method, even some you may not expect, so you should be careful. At least the
157
- following methods pass their arguments to a filter method:
186
+ If you are using the auto_literal_strings extension, you need to be very careful,
187
+ as the following methods will treat a plain string given as the first argument
188
+ as a literal string:
158
189
 
159
190
  * Sequel::Dataset#where
160
191
  * Sequel::Dataset#having
161
192
  * Sequel::Dataset#filter
162
193
  * Sequel::Dataset#exclude
163
- * Sequel::Dataset#exclude_where
164
194
  * Sequel::Dataset#exclude_having
165
- * Sequel::Dataset#and
166
195
  * Sequel::Dataset#or
167
196
  * Sequel::Dataset#first
168
197
  * Sequel::Dataset#last
169
198
  * Sequel::Dataset#[]
170
199
 
171
- The Model.find[rdoc-ref:Sequel::Model::ClassMethods#find] and Model.find_or_create[rdoc-ref:Sequel::Model::ClassMethods#find_or_create]
172
- class methods also call down to the filter methods.
200
+ Even stuff that looks like it may be safe isn't:
173
201
 
174
- The no_auto_string_literals extension can be used to remove the default support
175
- for plain strings as literal strings in filter methods.
202
+ DB[:table].first(params[:num_rows])
203
+ # SQL injection when using auto_literal_strings extension
176
204
 
177
- ==== SQL Fragment passed to Dataset#update
205
+ The Model.find[rdoc-ref:Sequel::Model::ClassMethods#find] and
206
+ Model.find_or_create[rdoc-ref:Sequel::Model::ClassMethods#find_or_create]
207
+ class methods will also treat string arguments as literal strings if the
208
+ auto_literal_strings extension is used:
178
209
 
179
- Similar to the filter methods, Sequel::Dataset#update also treats a
180
- string argument as raw SQL:
210
+ Album.find(params[:id])
211
+ # SQL injection when using auto_literal_strings extension
212
+
213
+ Similar to the filter methods, the auto_literal_strings extension
214
+ also makes Sequel::Dataset#update treats a string argument as raw SQL:
181
215
 
182
216
  DB[:table].update("column = 1")
183
217
 
184
218
  So you should not do:
185
219
 
186
- DB[:table].update("column = #{params[:value].to_s}") # SQL Injection!
220
+ DB[:table].update(params[:changes])
221
+ # SQL injection when using auto_literal_strings extension
187
222
 
188
- Instead, you should do:
223
+ or:
189
224
 
190
- DB[:table].update(:column => params[:value].to_s) # Safe
225
+ DB[:table].update("column = #{params[:value].to_s}")
226
+ # SQL injection when using auto_literal_strings extension
191
227
 
192
- The no_auto_string_literals extension can also be used to remove the default support
193
- for plain strings as literal strings in update methods.
194
-
195
- ==== SQL Fragment passed to Dataset#lock_style and Model#lock!
196
-
197
- The Sequel::Dataset#lock_style and Sequel::Model#lock! methods also treat
198
- an input string as SQL code. This method should not be called with user input.
199
-
200
- ==== SQL Fragment passed to Virtual Row #` method
201
-
202
- Virtual row blocks currently support a #` method for using literal SQL:
203
-
204
- DB[:table].where{a > `some SQL`}
205
-
206
- This method should not be called with user input.
207
-
208
- ==== SQL Type Names
209
-
210
- In general, most places where Sequel needs to use an SQL type that should
211
- be specified by the user, it allows you to use a ruby string, and that
212
- string is used verbatim as the SQL type. You should not use user input
213
- for type strings.
214
-
215
- ==== SQL Function Names
228
+ Instead, you should do:
216
229
 
217
- In most cases, Sequel does not quote SQL function names. You should not use
218
- user input for function names.
230
+ DB[:table].update(:column => params[:value].to_s) # Safe
219
231
 
232
+ Because using the auto_literal_strings extension makes SQL injection
233
+ so much eaiser, it is recommended to not use it, and instead
234
+ use Sequel.lit with placeholders.
235
+
220
236
  === SQL Identifier Injections
221
237
 
222
238
  Usually, Sequel treats ruby symbols as SQL identifiers, and ruby
@@ -236,7 +252,7 @@ the Sequel::Dataset#insert and Sequel::Dataset#update methods:
236
252
  DB[:t].insert('b'=>1) # INSERT INTO "t" ("b") VALUES (1)
237
253
 
238
254
  Note how the identifier is still quoted in these cases. Sequel quotes identifiers by default
239
- on most databases. However, it does not quote identifiers by default on DB2 and Informix.
255
+ on most databases. However, it does not quote identifiers by default on DB2.
240
256
  On those databases using an identifier derived from user input can lead to SQL injection.
241
257
  Similarly, if you turn off identifier quoting manually on other databases, you open yourself
242
258
  up to SQL injection if you use identifiers derived from user input.
@@ -262,6 +278,10 @@ uses symbols as identifiers. However, if you are creating symbols from user inp
262
278
  you at least have a denial of service vulnerability in ruby <2.2, and possibly a
263
279
  more serious vulnerability.
264
280
 
281
+ Note that many Database schema modification methods (e.g. create_table, add_column)
282
+ also allow for SQL identifier injections, and possibly also SQL code injections.
283
+ These methods should never be called with user input.
284
+
265
285
  == Denial of Service
266
286
 
267
287
  Sequel converts some strings to symbols. Because symbols in ruby <2.2 are not
@@ -293,7 +313,7 @@ if you allow the user to control the alias name:
293
313
 
294
314
  DB[:table].select(:column.as(params[:alias]))
295
315
 
296
- Then you have a denial of service vulnerability. In general, such a vulnerability
316
+ Then you can have a denial of service vulnerability. In general, such a vulnerability
297
317
  is unlikely, because you are probably indexing into the returned hash(es) by name,
298
318
  and if an alias was used and you didn't expect it, your application wouldn't work.
299
319
 
@@ -353,28 +373,17 @@ These two methods iterate over the second argument (+:name+ and +:copies_sold+ i
353
373
  this example) instead of iterating over the entries in the first argument
354
374
  (<tt>params[:album]</tt> in this example).
355
375
 
356
- In addition to these two methods, you can also use
357
- Model#set_only[rdoc-ref:Sequel::Model::InstanceMethods#set_only] or
358
- Model#update_only[rdoc-ref:Sequel::Model::InstanceMethods#update_only],
359
- which are similar but iterate over the entries in the first argument, checking
360
- the second argument to see if setting the entries is allowed.
361
-
362
- album.set_only(params[:album], [:name, :copies_sold])
363
- album.update_only(params[:album], [:name, :copies_sold])
364
-
365
- If you expect all entries in the second argument to be present in the first
366
- argument, use +set_fields+ or +update_fields+. If you are not sure if all
367
- arguments in the second argument will be present in the first argument, but
368
- do not want to allow setting any column other than the ones listed in the
369
- second argument, use +set_only+ or +update_only+.
370
-
371
- You can override the columns to allow by default during mass assignment via
372
- the Model.set_allowed_columns[rdoc-ref:Sequel::Model::ClassMethods#set_allowed_columns] class method. This is a good
373
- practice, though being explicit on a per-call basis is still recommended:
376
+ If you want to override the columns that Model#set[rdoc-ref:Sequel::Model::InstanceMethods#set]
377
+ allows by default during mass assignment, you can use the whitelist_security plugin, then call
378
+ the set_allowed_columns class method.
374
379
 
380
+ Album.plugin :whitelist_security
375
381
  Album.set_allowed_columns(:name, :copies_sold)
376
382
  Album.create(params[:album]) # Only name and copies_sold set
377
383
 
384
+ Being explicit on a per-call basis using the set_fields and update_fields methods is recommended
385
+ instead of using the whitelist_security plugin and setting a global whitelist.
386
+
378
387
  For more details on the mass assignment methods, see the {Mass Assignment Guide}[rdoc-ref:doc/mass_assignment.rdoc].
379
388
 
380
389
  == General Parameter Handling
@@ -386,7 +395,7 @@ their type. For example:
386
395
  Album.where(:id=>params[:id])
387
396
 
388
397
  is probably a bad idea. Assuming you are using a web framework, <tt>params[:id]</tt> could
389
- be a string, an array, a hash, or nil.
398
+ be a string, an array, a hash, nil, or potentially something else.
390
399
 
391
400
  Assuming that +id+ is an integer field, you probably want to do:
392
401
 
@@ -400,7 +409,7 @@ a string:
400
409
  If you are trying to use an IN clause with a list of id values based on input provided
401
410
  on a web form:
402
411
 
403
- Album.where(:id=>params[:ids].to_a.map{|i| i.to_i})
412
+ Album.where(:id=>params[:ids].to_a.map(&:to_i))
404
413
 
405
414
  Basically, be as explicit as possible. While there aren't any known security issues
406
415
  in Sequel when you do: