sequel 3.21.0 → 3.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
data/bin/sequel CHANGED
@@ -4,20 +4,22 @@ require 'rubygems'
4
4
  require 'optparse'
5
5
  require 'sequel'
6
6
 
7
- db_opts = {:test=>true}
7
+ code = nil
8
8
  copy_databases = nil
9
9
  dump_migration = nil
10
- echo = nil
10
+ dump_schema = nil
11
11
  env = nil
12
- logfile = nil
13
12
  migrate_dir = nil
14
13
  migrate_ver = nil
15
14
  backtrace = nil
15
+ test = true
16
16
  load_dirs = []
17
+ exclusive_options = []
18
+ loggers = []
17
19
 
18
20
  opts = OptionParser.new do |opts|
19
21
  opts.banner = "Sequel: The Database Toolkit for Ruby"
20
- opts.define_head "Usage: sequel <uri|path> [options]"
22
+ opts.define_head "Usage: sequel [options] <uri|path> [file]"
21
23
  opts.separator ""
22
24
  opts.separator "Examples:"
23
25
  opts.separator " sequel sqlite://blog.db"
@@ -33,16 +35,23 @@ opts = OptionParser.new do |opts|
33
35
  exit
34
36
  end
35
37
 
38
+ opts.on("-c", "--code CODE", "run the given code and exit") do |v|
39
+ code = v
40
+ exclusive_options << :c
41
+ end
42
+
36
43
  opts.on("-C", "--copy-databases", "copy one database to another") do
37
44
  copy_databases = true
38
45
  end
39
46
 
40
47
  opts.on("-d", "--dump-migration", "print database migration to STDOUT") do
41
48
  dump_migration = true
49
+ exclusive_options << :d
42
50
  end
43
51
 
44
52
  opts.on("-D", "--dump-migration-same-db", "print database migration to STDOUT without type translation") do
45
53
  dump_migration = :same_db
54
+ exclusive_options << :D
46
55
  end
47
56
 
48
57
  opts.on("-e", "--env ENV", "use environment config for database") do |v|
@@ -50,7 +59,8 @@ opts = OptionParser.new do |opts|
50
59
  end
51
60
 
52
61
  opts.on("-E", "--echo", "echo SQL statements") do
53
- echo = true
62
+ require 'logger'
63
+ loggers << Logger.new($stdout)
54
64
  end
55
65
 
56
66
  opts.on("-I", "--include dir", "specify $LOAD_PATH directory") do |v|
@@ -58,7 +68,8 @@ opts = OptionParser.new do |opts|
58
68
  end
59
69
 
60
70
  opts.on("-l", "--log logfile", "log SQL statements to log file") do |v|
61
- logfile = v
71
+ require 'logger'
72
+ loggers << Logger.new(v)
62
73
  end
63
74
 
64
75
  opts.on("-L", "--load-dir DIR", "loads all *.rb under specifed directory") do |v|
@@ -67,6 +78,7 @@ opts = OptionParser.new do |opts|
67
78
 
68
79
  opts.on("-m", "--migrate-directory DIR", "run the migrations in directory") do |v|
69
80
  migrate_dir = v
81
+ exclusive_options << :m
70
82
  end
71
83
 
72
84
  opts.on("-M", "--migrate-version VER", "migrate the database to version given") do |v|
@@ -74,13 +86,18 @@ opts = OptionParser.new do |opts|
74
86
  end
75
87
 
76
88
  opts.on("-N", "--no-test-connection", "do not test the connection") do
77
- db_opts[:test] = false
89
+ test = false
78
90
  end
79
91
 
80
- opts.on("-r", "--require lib", "require the library, before executing your script") do |v|
92
+ opts.on("-r", "--require LIB", "require the library, before executing your script") do |v|
81
93
  load_dirs << [v]
82
94
  end
83
95
 
96
+ opts.on("-S", "--dump-schema filename", "dump the schema for all tables to the file") do |v|
97
+ dump_schema = v
98
+ exclusive_options << :S
99
+ end
100
+
84
101
  opts.on("-t", "--trace", "Output the full backtrace if an exception is raised") do
85
102
  backtrace = true
86
103
  end
@@ -100,33 +117,23 @@ error_proc = lambda do |msg|
100
117
  end
101
118
 
102
119
  error_proc["Error: Must specify -m if using -M"] if migrate_ver && !migrate_dir
103
- error_proc["Error: Cannot specify -D or -d with -m"] if dump_migration && migrate_dir
104
- error_proc["Error: Cannot specify -C with -d, -D, or -m"] if copy_databases && (dump_migration || migrate_dir)
105
-
106
- if logfile || echo
107
- require 'logger'
108
- db_opts[:loggers] = []
109
- db_opts[:loggers] << Logger.new(logfile) if logfile
110
- db_opts[:loggers] << Logger.new($stdout) if echo
111
- end
120
+ error_proc["Error: Cannot specify #{exclusive_options.map{|v| "-#{v}"}.join(' and ')} together"] if exclusive_options.length > 1
112
121
 
113
122
  connect_proc = lambda do |database|
114
123
  db = if database.nil? || database.empty?
115
- db = Sequel::Database.new(:quote_identifiers=>false)
116
- def db.connect(*args); Object.new; end
117
- db.identifier_input_method = nil
118
- db.identifier_output_method = nil
119
- db
124
+ Sequel.connect('mock:///')
120
125
  elsif File.exist?(database)
121
126
  require 'yaml'
122
127
  env ||= "development"
123
128
  db_config = YAML.load_file(database)
124
129
  db_config = db_config[env] || db_config[env.to_sym] || db_config
125
130
  db_config.keys.each{|k| db_config[k.to_sym] = db_config.delete(k)}
126
- Sequel.connect(db_config.merge!(db_opts))
131
+ Sequel.connect(db_config)
127
132
  else
128
- Sequel.connect(database, db_opts)
133
+ Sequel.connect(database)
129
134
  end
135
+ db.loggers = loggers
136
+ db.test_connection if test
130
137
  db
131
138
  end
132
139
 
@@ -134,7 +141,7 @@ begin
134
141
  DB = connect_proc[db]
135
142
  load_dirs.each{|d| d.is_a?(Array) ? require(d.first) : Dir["#{d}/**/*.rb"].each{|f| load(f)}}
136
143
  if migrate_dir
137
- Sequel.extension :migration
144
+ Sequel.extension :migration, :core_extensions
138
145
  Sequel::Migrator.apply(DB, migrate_dir, migrate_ver)
139
146
  exit
140
147
  end
@@ -143,6 +150,12 @@ begin
143
150
  puts DB.dump_schema_migration(:same_db=>dump_migration==:same_db)
144
151
  exit
145
152
  end
153
+ if dump_schema
154
+ Sequel.extension :schema_caching
155
+ DB.tables.each{|t| DB.schema(Sequel::SQL::Identifier.new(t))}
156
+ DB.dump_schema_cache(dump_schema)
157
+ exit
158
+ end
146
159
  if copy_databases
147
160
  Sequel.extension :migration, :schema_dumper
148
161
 
@@ -151,10 +164,13 @@ begin
151
164
  start_time = Time.now
152
165
  TO_DB = connect_proc[db2]
153
166
  same_db = DB.database_type==TO_DB.database_type
167
+ index_opts = {:same_db=>same_db}
168
+ index_opts[:index_names] = :namespace if !DB.global_index_namespace? && TO_DB.global_index_namespace?
154
169
 
155
170
  puts "Databases connections successful"
156
171
  schema_migration = eval(DB.dump_schema_migration(:indexes=>false, :same_db=>same_db))
157
- index_migration = eval(DB.dump_indexes_migration(:same_db=>same_db))
172
+ index_migration = eval(DB.dump_indexes_migration(index_opts))
173
+ fk_migration = eval(DB.dump_foreign_key_migration(:same_db=>same_db))
158
174
  puts "Migrations dumped successfully"
159
175
 
160
176
  schema_migration.apply(TO_DB, :up)
@@ -186,6 +202,10 @@ begin
186
202
  index_migration.apply(TO_DB, :up)
187
203
  puts "Finished creating indexes"
188
204
 
205
+ puts "Begin adding foreign key constraints"
206
+ fk_migration.apply(TO_DB, :up)
207
+ puts "Finished adding foreign key constraints"
208
+
189
209
  if TO_DB.database_type == :postgres
190
210
  TO_DB.tables.each{|t| TO_DB.reset_primary_key_sequence(t)}
191
211
  puts "Primary key sequences reset successfully"
@@ -193,6 +213,10 @@ begin
193
213
  puts "Database copy finished in #{Time.now - start_time} seconds"
194
214
  exit
195
215
  end
216
+ if code
217
+ eval(code)
218
+ exit
219
+ end
196
220
  rescue => e
197
221
  raise e if backtrace
198
222
  error_proc["Error: #{e.class}: #{e.message}#{e.backtrace.first}"]
@@ -75,7 +75,7 @@ Sequel's +hook_class_methods+ plugin is modeled directly on ActiveRecord's callb
75
75
  end
76
76
  end
77
77
 
78
- Observers can be implemented completely by hooks, so Sequel doesn't allow you to define them separately.
78
+ Observers can be implemented completely by hooks, so Sequel doesn't offer a separate observer class.
79
79
 
80
80
  == Inheritance
81
81
 
@@ -150,16 +150,12 @@ Sequel supports logging of all database queries by allowing multiple loggers for
150
150
  Sequel supports migrations and has a migrator similar to ActiveRecord:
151
151
 
152
152
  Sequel.migration do
153
- up do
153
+ change do
154
154
  create_table(:albums) do
155
155
  primary_key :id
156
156
  String :name
157
157
  end
158
158
  end
159
-
160
- down do
161
- drop_table(:albums)
162
- end
163
159
  end
164
160
 
165
161
  == Differences
@@ -175,7 +171,7 @@ Unlike ActiveRecord 2, Sequel uses method chains on datasets for retrieving obje
175
171
 
176
172
  Sequel uses:
177
173
 
178
- Album.filter{name > 'RF'}.filter(:artist_id=>1).order(:copies_sold).
174
+ Album.where{name > 'RF'}.where(:artist_id=>1).order(:copies_sold).
179
175
  select(:id, :name).all
180
176
 
181
177
  Note that the records aren't retrieved until +all+ is called.
@@ -184,11 +180,11 @@ ActiveRecord 3 adopts this method chaining approach, so if you are familiar with
184
180
 
185
181
  === No Need for SQL String Fragments
186
182
 
187
- As the example above shows, most ActiveRecord code uses SQL string fragments. With Sequel, you rarely need to. Sequel's DSL allows you to create complex queries without ever specifying SQL string fragments (called literal strings in Sequel).
183
+ Like the example above, most ActiveRecord code uses SQL string fragments. With Sequel, you rarely need to. Sequel's DSL allows you to create complex queries without ever specifying SQL string fragments (called literal strings in Sequel).
188
184
 
189
- If you want to use SQL string fragments, Sequel makes it easy by using the <tt>String#lit</tt> method:
185
+ If you want to use SQL string fragments, Sequel makes it easy by using the <tt>Sequel.lit</tt> method:
190
186
 
191
- Album.select('id, name'.lit)
187
+ Album.select(Sequel.lit('id, name'))
192
188
 
193
189
  This usage is not encouraged, though. The recommended way is to use symbols to represent the columns:
194
190
 
@@ -214,17 +210,17 @@ A third reason to not use SQL string fragments is database independence. For ex
214
210
 
215
211
  This is because LIKE is case sensitive on PostgreSQL, but case insensitive on MySQL. With Sequel, you would do:
216
212
 
217
- Album.filter(:name.ilike('A%'))
213
+ Album.filter(Sequel.ilike(:name, 'A%'))
218
214
 
219
215
  This will do a case insensitive search on both databases. If you want a case sensitive search on both, you can use +like+ instead of +ilike+.
220
216
 
221
217
  String concatenation is a similar area, where MySQL and PostgreSQL handle things differently. With Sequel, the same code can work on both databases:
222
218
 
223
- Album.select(:name.sql_string + ' - Name')
219
+ Album.select(Sequel.join([:name, ' - Name']))
224
220
 
225
221
  == Flexible Overriding
226
222
 
227
- Unlike ActiveRecord, which forces you to alias methods if you want to override them, with Sequel you just override the methods and call super:
223
+ Unlike ActiveRecord 2, which forces you to alias methods if you want to override them, with Sequel you just override the methods and call super:
228
224
 
229
225
  class Sequel::Model
230
226
  def after_update
@@ -254,7 +250,7 @@ You can override almost all model class or instance methods this way, just remem
254
250
 
255
251
  == +method_missing+ Missing
256
252
 
257
- Sequel does not use +method_missing+ unless the object truely needs it. Neither <tt>Sequel::Model</tt> nor <tt>Sequel::Dataset</tt> nor <tt>Sequel::Database</tt> implement +method_missing+ at either a class or model level. So if you call +methods+, you can see which methods are available, and if they aren't listed, then the object won't respond to them. Among other things, this means Sequel does not support dynamic finders. So instead of:
253
+ Sequel does not use +method_missing+ unless it's required that the object respond to potentially any method. Neither <tt>Sequel::Model</tt> nor <tt>Sequel::Dataset</tt> nor <tt>Sequel::Database</tt> implement +method_missing+ at either a class or instance level. So if you call +methods+, you can see which methods are available, and if they aren't listed, then the object won't respond to them. Among other things, this means Sequel does not support dynamic finders. So instead of:
258
254
 
259
255
  Album.find_or_create_by_name("RF")
260
256
 
@@ -309,7 +305,7 @@ Sequel supports the same basic association hooks/callbacks as ActiveRecord. It
309
305
  If you pass a block to an association method, it's used to return a modified dataset used for the association, instead of to create an association extension:
310
306
 
311
307
  Artist.one_to_many :gold_albums, :class=>:Album do |ds|
312
- ds.filter{copies_sold > 500000}
308
+ ds.where{copies_sold > 500000}
313
309
  end
314
310
 
315
311
  If you want to create an association extension, you can use the <tt>:extend</tt> association option with a module, which ActiveRecord also supports. In Sequel, the extensions are applied to the association dataset, not to the array of associated objects. You can access the association dataset using the +association_dataset+ method:
@@ -319,13 +315,13 @@ If you want to create an association extension, you can use the <tt>:extend</tt>
319
315
 
320
316
  Association datasets are just like any other Sequel dataset, in that you can filter them and manipulate them further:
321
317
 
322
- gold_albums = artist.albums_dataset.filter{copies_sold > 500000}.order(:name).all
318
+ gold_albums = artist.albums_dataset.where{copies_sold > 500000}.order(:name).all
323
319
 
324
320
  Sequel caches associated objects similarly to ActiveRecord, and you can skip the cache by passing +true+ to the association method, just like ActiveRecord.
325
321
 
326
322
  === Eager Loading
327
323
 
328
- ActiveRecord tries to guess whether to use preloading or JOINs for eager loading by scanning the SQL string fragments you provide for table names. This is error prone and Sequel avoids it by giving you separate methods. In Sequel, +eager+ is used for preloading and +eager_graph+ is used for JOINs. Both have the same API:
324
+ ActiveRecord 2 tries to guess whether to use preloading or JOINs for eager loading by scanning the SQL string fragments you provide for table names. This is error prone and Sequel avoids it by giving you separate methods. In Sequel, +eager+ is used for preloading and +eager_graph+ is used for JOINs. Both have the same API:
329
325
 
330
326
  Artist.eager(:albums=>[:tags, :tracks])
331
327
  Album.eager_graph(:artist, :tracks)
@@ -361,6 +357,24 @@ Table aliasing when eager loading via +eager_graph+ is different in Sequel than
361
357
  # LEFT OUTER JOIN nodes AS children_0 ON (children_0.parent_id = children.id) -- grandchildren
362
358
  # LEFT OUTER JOIN nodes AS children_1 ON (children_1.parent_id = children_0.id) -- great grandchildren
363
359
 
360
+ You can specify aliases on a per join basis, too:
361
+
362
+ Node.eager_graph(:parent=>Sequel.as(:parent, :grandparent),
363
+ :children=>{Sequel.as(:children, :grandchildren)=>Sequel.as(:children, :great_grandchildren)}).all
364
+
365
+ # SELECT nodes.id, nodes.parent_id,
366
+ # parent.id AS parent_id_0, parent.parent_id AS parent_parent_id,
367
+ # grandparent.id AS grandparent_id, grandparent.parent_id AS grandparent_parent_id,
368
+ # children.id AS children_id, children.parent_id AS children_parent_id,
369
+ # grandchildren.id AS grandchildren_id, grandchildren.parent_id AS grandchildren_parent_id,
370
+ # great_grandchildren.id AS great_grandchildren_id, great_grandchildren.parent_id AS great_grandchildren_parent_id
371
+ # FROM nodes
372
+ # LEFT OUTER JOIN nodes AS parent ON (parent.id = nodes.parent_id)
373
+ # LEFT OUTER JOIN nodes AS grandparent ON (grandparent.id = parent.parent_id)
374
+ # LEFT OUTER JOIN nodes AS children ON (children.parent_id = nodes.id)
375
+ # LEFT OUTER JOIN nodes AS grandchildren ON (grandchildren.parent_id = children.id)
376
+ # LEFT OUTER JOIN nodes AS great_grandchildren ON (great_grandchildren.parent_id = grandchildren.id)
377
+
364
378
  === Options
365
379
 
366
380
  Sequel supports many more association options than ActiveRecord, but here's a mapping of ActiveRecord association options to Sequel association options. Note that when you specify columns in Sequel, you use symbols, not strings. Where ActiveRecord would use an SQL string fragment with embedded commas for multiple columns, Sequel would use an array of column symbols.
@@ -383,7 +397,7 @@ ActiveRecord option :: Sequel option
383
397
  <tt>:polymorphic</tt>, <tt>:as</tt>, <tt>:source_type</tt> :: The +sequel_polymorphic+ external plugin
384
398
  <tt>:include</tt> :: <tt>:eager</tt>, <tt>:eager_graph</tt>
385
399
  <tt>:readonly</tt> :: No equivalent, the Sequel <tt>:read_only</tt> option just means the modification methods are not created (it makes the association read only, not records retrieved through the association)
386
- <tt>:through</tt>, <tt>:source</tt> :: Use a +many_to_many+ association
400
+ <tt>:through</tt>, <tt>:source</tt> :: Use a +many_to_many+ association, or the +many_through_many+ plugin
387
401
  <tt>:touch</tt> :: The +touch+ plugin
388
402
  <tt>:autosave</tt> :: A +before_save+ or +after_save+ hook
389
403
  <tt>:finder_sql</tt> :: <tt>:dataset</tt> to set a custom dataset
@@ -505,15 +519,15 @@ You can call +with_sql+ to set the SQL to use, and the +single_value+ to retriev
505
519
 
506
520
  Calling +delete+ directly on the class will probably delete all rows in the table. You want to filter first, then call +delete+:
507
521
 
508
- Album.filter(:id=>id).delete
509
- Album.filter("artist_id = ?", 5).delete
522
+ Album.where(:id=>id).delete
523
+ Album.where("artist_id = ?", 5).delete
510
524
 
511
525
  ==== +destroy+, +destroy_all+
512
526
 
513
527
  Similar to +delete+, you filter first, then +destroy+:
514
528
 
515
- Album.filter(:id=>id).destroy
516
- Album.filter("artist_id = ?", 5).destroy
529
+ Album.where(:id=>id).destroy
530
+ Album.where("artist_id = ?", 5).destroy
517
531
 
518
532
  ==== +establish_connection+
519
533
 
@@ -531,7 +545,7 @@ If you want a specific dataset in that database, you can use +set_dataset+ or <t
531
545
 
532
546
  You need to filter the dataset first, then call <tt>empty?</tt> and invert the result:
533
547
 
534
- !Album.filter(:id=>1).empty?
548
+ !Album.where(:id=>1).empty?
535
549
 
536
550
  ==== +find+
537
551
 
@@ -543,21 +557,21 @@ Note that Sequel returns nil if no record is found, it doesn't raise an exceptio
543
557
 
544
558
  If you want to find multiple objects using an array of primary keys:
545
559
 
546
- Album.filter(:id=>[1, 2, 3]).all
560
+ Album.where(:id=>[1, 2, 3]).all
547
561
 
548
562
  If you are using <tt>find(:first, ...)</tt>, you use a method chain instead of passing the options, and end it with +first+:
549
563
 
550
- Album.filter(:artist_id=>1).order(:name).first
564
+ Album.where(:artist_id=>1).order(:name).first
551
565
 
552
566
  If you are using <tt>find(:last, ...)</tt>, you need to specify an order in Sequel, but the same method chain approach is used, which you end with +last+:
553
567
 
554
- Album.filter(:artist_id=>1).order(:name).last
568
+ Album.where(:artist_id=>1).order(:name).last
555
569
  # You could also do:
556
- Album.filter(:artist_id=>1).order(:name.desc).first
570
+ Album.where(:artist_id=>1).reverse_order(:name).first
557
571
 
558
572
  If you are using <tt>find(:all, ...)</tt>, you use a method chain instead of passing the options, and end it with +all+:
559
573
 
560
- Album.filter(:artist_id=>1).order(:name).all
574
+ Album.where(:artist_id=>1).order(:name).all
561
575
 
562
576
  Here's a mapping of ActiveRecord +find+ options to <tt>Sequel::Dataset</tt> methods:
563
577
 
@@ -583,13 +597,13 @@ Similar to +count_by_sql+, you use +with_sql+, followed by +all+:
583
597
 
584
598
  Just like with <tt>find(:first, ...)</tt>, you use a method chain instead of passing the options, and end it with +first+:
585
599
 
586
- Album.filter(:artist_id=>1).order(:name).first
600
+ Album.where(:artist_id=>1).order(:name).first
587
601
 
588
602
  ==== +last+
589
603
 
590
604
  Just like with <tt>find(:last, ...)</tt>, you use a method chain instead of passing the options, make sure it includes an order, and end it with +last+:
591
605
 
592
- Album.filter(:artist_id=>1).order(:name).last
606
+ Album.where(:artist_id=>1).order(:name).last
593
607
 
594
608
  ==== +named_scope+
595
609
 
@@ -598,12 +612,17 @@ For a pure filter, you can use +subset+:
598
612
  Album.subset(:debut, :position => 1)
599
613
  Album.subset(:gold){copies_sold > 500000}
600
614
 
601
- For anything more complex, you can use +def_dataset_method+:
615
+ For anything more complex, you can use +dataset_module+:
602
616
 
603
- Album.def_dataset_method(:by_artist) do |artist_id|
604
- filter(:artist_id=>artist_id)
617
+ Album.dataset_module do
618
+ def by_artist(artist_id)
619
+ where(:artist_id=>artist_id)
620
+ end
621
+
622
+ def by_release_date
623
+ order(:release_date)
624
+ end
605
625
  end
606
- Album.def_dataset_method(:by_release_date){order(:release_date)}
607
626
 
608
627
  ==== +reset_column_information+
609
628
 
@@ -613,13 +632,13 @@ If you want to completely reload the schema for the table:
613
632
 
614
633
  ==== +serialize+, +seralized_attributes+
615
634
 
616
- Sequel ships with a +serialization+ plugin that you can use. It's more flexible than ActiveRecord's, since you can serialize to marshal or json in addition to yaml:
635
+ Sequel ships with a +serialization+ plugin that you can use.
617
636
 
618
637
  class Album < Sequel::Model
619
638
  plugin :serialization, :json, :permissions
620
639
  end
621
640
 
622
- For +serialized_attributes+, you can use +serialization_map+, which is also a hash, but keys are column symbols and values are either <tt>:marshal</tt>, <tt>:yaml</tt>, or <tt>:json</tt>, specifying the serialization format.
641
+ For +serialized_attributes+, you can use +serialization_map+, which is also a hash, but keys are column symbols and values are callable objects used to serialize the values.
623
642
 
624
643
  ==== +set_inheritance_column+
625
644
 
@@ -657,13 +676,13 @@ As mentioned earlier, +transaction+ is a database method in Sequel, which you ca
657
676
 
658
677
  Just like +delete+ and +destroy+, you filter first, then +update+:
659
678
 
660
- Album.filter(:id=>id).update(:name=>'RF')
661
- Album.filter("artist_id = ?", 5).update(:copies_sold=>0)
679
+ Album.where(:id=>id).update(:name=>'RF')
680
+ Album.where("artist_id = ?", 5).update(:copies_sold=>0)
662
681
 
663
682
  Note that +update+ in that case will operate on a dataset, so it won't run model validations or hooks. If you want those run:
664
683
 
665
684
  Album[id].update(:name=>'RF')
666
- Album.filter("artist_id = ?", 5).all{|a| a.update(:copies_sold=>0)}
685
+ Album.where("artist_id = ?", 5).all{|a| a.update(:copies_sold=>0)}
667
686
 
668
687
  ==== +with_scope+
669
688
 
@@ -694,6 +713,7 @@ ActiveRecord Method :: Sequel Method
694
713
  +set_primary_key+ :: +set_primary_key+
695
714
  +sum+ :: +sum+
696
715
  +table_name+ :: +table_name+
716
+ +unscoped+ :: +unfiltered+
697
717
 
698
718
  === Class Methods without an Equivalent
699
719
 
@@ -714,12 +734,12 @@ ActiveRecord Method :: Notes, Workarounds
714
734
  <tt>clear_active_connections!</tt> :: Sequel doesn't leak connections like ActiveRecord, so you don't need to worry about this
715
735
  <tt>clear_reloadable_connections!</tt> :: Sequel doesn't leak connections like ActiveRecord, so you don't need to worry about this
716
736
  +content_columns+ :: Not needed internally, you can probably do <tt>Album.columns.map{|x| x.to_s}.delete_if{|x| x == Album.primary_key || x =~ /_(id|count)\z/}</tt>
717
- +decrement_counter+ :: <tt>Album.filter(:id=>:id).update(:counter_name=>:counter_name - 1)</tt>
737
+ +decrement_counter+ :: <tt>Album.where(:id=>:id).update(:counter_name=>:counter_name - 1)</tt>
718
738
  +define_attribute_methods+, +define_read_methods+ :: <tt>def_column_accessor(*columns)</tt>, a private method
719
739
  <tt>descends_from_active_record?</tt> :: Not needed internally, if using single table inheritance, <tt>Album.sti_dataset.model == Album</tt>
720
740
  +find_each+, +find_in_batches+ :: Use the +pagination+ extension
721
741
  <tt>generated_methods?</tt> :: No equivalent
722
- +increment_counter+ :: <tt>Album.filter(:id=>:id).update(:counter_name=>:counter_name + 1)</tt>
742
+ +increment_counter+ :: <tt>Album.where(:id=>:id).update(:counter_name=>:counter_name + 1)</tt>
723
743
  <tt>instance_method_already_implemented?</tt> :: No equivalent, Sequel does not create column accessors that override other methods, it just skips them.
724
744
  <tt>match_attribute_method?</tt> :: No equivalent
725
745
  +readonly_attributes+ :: No equivalent
@@ -728,7 +748,7 @@ ActiveRecord Method :: Notes, Workarounds
728
748
  +silence+ :: No equivalent. Because the logger is handled at the <tt>Sequel::Database</tt> level, there is no thread-safe way to turn it off for specific blocks.
729
749
  +scopes+ :: No equivalent
730
750
  +sti_name+ :: No equivalent.
731
- +update_counters+ :: <tt>Album.filter(:id=>:id).update(:counter_name=>:counter_name + 1, :other_counter=>:other_counter - 1)</tt>
751
+ +update_counters+ :: <tt>Album.where(:id=>:id).update(:counter_name=>:counter_name + 1, :other_counter=>:other_counter - 1)</tt>
732
752
  +uncached+ :: No equivalent
733
753
 
734
754
  === Instance Methods with Significantly Different Behavior
@@ -788,13 +808,6 @@ Assuming you want the full behavior of saving just one column without validating
788
808
  album.values[:column] -= 1 # or += 1 for increment!
789
809
  album.save(:column, :validate=>false)
790
810
 
791
- ==== +freeze+, <tt>frozen?</tt>
792
-
793
- Sequel doesn't support freezing objects directly, but you can do it yourself:
794
-
795
- album.values.freeze
796
- album.values.frozen?
797
-
798
811
  ==== <tt>has_attribute?</tt>
799
812
 
800
813
  You have to check the values hash:
@@ -869,6 +882,8 @@ ActiveRecord Method :: Sequel Method
869
882
  +destroy+ :: +destroy+
870
883
  <tt>eql?</tt> :: <tt>===</tt>
871
884
  +errors+ :: +errors+
885
+ +freeze+ :: +freeze+
886
+ <tt>frozen?</tt> :: <tt>frozen?</tt>
872
887
  +hash+ :: +hash+
873
888
  +id+ :: +pk+
874
889
  +inspect+ :: +inspect+
@@ -883,12 +898,13 @@ ActiveRecord Method :: Sequel Method
883
898
 
884
899
  ActiveRecord Method :: Notes, Workarounds
885
900
  +after_validation_on_create+, +after_validation_on_update+ :: Use +after_validation+ and <tt>if new?</tt> or <tt>unless new?</tt>
886
- +as_json+, +from_json+, +to_json+, +from_xml+, +to_xml+ :: No equivalent
901
+ +as_json+, +from_json+, +to_json+ :: Use the +json_serializer+ plugin
902
+ +from_xml+, +to_xml+ :: Use the +xml_serializer+ plugin
887
903
  +attribute_for_inspect+ :: <tt>album[:column].inspect</tt>
888
904
  <tt>attribute_present?</tt> :: <tt>!album[:column].blank?</tt> if using the +blank+ extension
889
905
  +attributes_before_type_cast+ :: Sequel typecasts at a low level, so model objects never see values before they are type cast
890
906
  +before_validation_on_create+, +before_validation_on_update+ :: Use +before_validation+ and <tt>if new?</tt> or <tt>unless new?</tt>
891
- <tt>id=</tt> :: Sequel doesn't have a special primary key setter method, but you can use: <tt>album.send("#{primary_key}=", value)</tt>
907
+ <tt>id=</tt> :: Sequel doesn't have a special primary key setter method, but you can use: <tt>album.send("#{Album.primary_key}=", value)</tt>
892
908
  +mark_for_destruction+, <tt>marked_for_destruction?</tt> :: Use a +before_save+ or +after_save+ hook or the +instance_hooks+ plugin
893
909
  <tt>readonly!</tt> :: No equivalent
894
910
  <tt>readonly?</tt> :: No equivalent