sequel 3.21.0 → 3.36.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 (311) hide show
  1. data/CHANGELOG +855 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +23 -7
  4. data/Rakefile +42 -24
  5. data/bin/sequel +26 -8
  6. data/doc/active_record.rdoc +1 -0
  7. data/doc/advanced_associations.rdoc +171 -11
  8. data/doc/association_basics.rdoc +293 -43
  9. data/doc/dataset_basics.rdoc +5 -5
  10. data/doc/dataset_filtering.rdoc +8 -0
  11. data/doc/mass_assignment.rdoc +56 -0
  12. data/doc/migration.rdoc +85 -552
  13. data/doc/model_hooks.rdoc +78 -27
  14. data/doc/object_model.rdoc +541 -0
  15. data/doc/opening_databases.rdoc +97 -50
  16. data/doc/prepared_statements.rdoc +40 -14
  17. data/doc/querying.rdoc +28 -4
  18. data/doc/reflection.rdoc +30 -4
  19. data/doc/release_notes/3.22.0.txt +39 -0
  20. data/doc/release_notes/3.23.0.txt +172 -0
  21. data/doc/release_notes/3.24.0.txt +420 -0
  22. data/doc/release_notes/3.25.0.txt +88 -0
  23. data/doc/release_notes/3.26.0.txt +88 -0
  24. data/doc/release_notes/3.27.0.txt +82 -0
  25. data/doc/release_notes/3.28.0.txt +304 -0
  26. data/doc/release_notes/3.29.0.txt +459 -0
  27. data/doc/release_notes/3.30.0.txt +135 -0
  28. data/doc/release_notes/3.31.0.txt +146 -0
  29. data/doc/release_notes/3.32.0.txt +202 -0
  30. data/doc/release_notes/3.33.0.txt +157 -0
  31. data/doc/release_notes/3.34.0.txt +671 -0
  32. data/doc/release_notes/3.35.0.txt +144 -0
  33. data/doc/release_notes/3.36.0.txt +245 -0
  34. data/doc/schema_modification.rdoc +572 -0
  35. data/doc/sharding.rdoc +95 -3
  36. data/doc/testing.rdoc +129 -0
  37. data/doc/thread_safety.rdoc +17 -0
  38. data/doc/transactions.rdoc +137 -0
  39. data/doc/virtual_rows.rdoc +51 -2
  40. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  41. data/lib/sequel/adapters/ado.rb +40 -18
  42. data/lib/sequel/adapters/amalgalite.rb +17 -9
  43. data/lib/sequel/adapters/db2.rb +175 -86
  44. data/lib/sequel/adapters/dbi.rb +15 -15
  45. data/lib/sequel/adapters/do/mysql.rb +17 -11
  46. data/lib/sequel/adapters/do/postgres.rb +1 -57
  47. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  48. data/lib/sequel/adapters/do.rb +18 -36
  49. data/lib/sequel/adapters/firebird.rb +27 -208
  50. data/lib/sequel/adapters/ibmdb.rb +453 -0
  51. data/lib/sequel/adapters/informix.rb +6 -23
  52. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  53. data/lib/sequel/adapters/jdbc/db2.rb +47 -0
  54. data/lib/sequel/adapters/jdbc/derby.rb +287 -0
  55. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  56. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  57. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  58. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  59. data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  61. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  62. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +58 -48
  64. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  65. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  66. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  67. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  68. data/lib/sequel/adapters/jdbc.rb +265 -94
  69. data/lib/sequel/adapters/mock.rb +361 -0
  70. data/lib/sequel/adapters/mysql.rb +118 -222
  71. data/lib/sequel/adapters/mysql2.rb +58 -57
  72. data/lib/sequel/adapters/odbc/mssql.rb +15 -7
  73. data/lib/sequel/adapters/odbc.rb +28 -9
  74. data/lib/sequel/adapters/openbase.rb +3 -5
  75. data/lib/sequel/adapters/oracle.rb +349 -53
  76. data/lib/sequel/adapters/postgres.rb +356 -107
  77. data/lib/sequel/adapters/shared/access.rb +32 -9
  78. data/lib/sequel/adapters/shared/db2.rb +342 -0
  79. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  80. data/lib/sequel/adapters/shared/informix.rb +53 -0
  81. data/lib/sequel/adapters/shared/mssql.rb +335 -118
  82. data/lib/sequel/adapters/shared/mysql.rb +340 -76
  83. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  84. data/lib/sequel/adapters/shared/oracle.rb +243 -45
  85. data/lib/sequel/adapters/shared/postgres.rb +524 -279
  86. data/lib/sequel/adapters/shared/progress.rb +5 -8
  87. data/lib/sequel/adapters/shared/sqlite.rb +265 -89
  88. data/lib/sequel/adapters/sqlite.rb +101 -39
  89. data/lib/sequel/adapters/swift/mysql.rb +9 -12
  90. data/lib/sequel/adapters/swift/postgres.rb +9 -74
  91. data/lib/sequel/adapters/swift/sqlite.rb +8 -6
  92. data/lib/sequel/adapters/swift.rb +8 -7
  93. data/lib/sequel/adapters/tinytds.rb +161 -21
  94. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
  95. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  96. data/lib/sequel/ast_transformer.rb +194 -0
  97. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  98. data/lib/sequel/connection_pool/sharded_threaded.rb +28 -2
  99. data/lib/sequel/connection_pool/single.rb +5 -0
  100. data/lib/sequel/connection_pool/threaded.rb +38 -14
  101. data/lib/sequel/connection_pool.rb +10 -2
  102. data/lib/sequel/core.rb +118 -11
  103. data/lib/sequel/database/connecting.rb +38 -28
  104. data/lib/sequel/database/dataset.rb +4 -4
  105. data/lib/sequel/database/dataset_defaults.rb +63 -2
  106. data/lib/sequel/database/logging.rb +7 -2
  107. data/lib/sequel/database/misc.rb +150 -46
  108. data/lib/sequel/database/query.rb +215 -65
  109. data/lib/sequel/database/schema_generator.rb +64 -20
  110. data/lib/sequel/database/schema_methods.rb +212 -54
  111. data/lib/sequel/dataset/actions.rb +322 -85
  112. data/lib/sequel/dataset/features.rb +96 -8
  113. data/lib/sequel/dataset/graph.rb +38 -11
  114. data/lib/sequel/dataset/misc.rb +50 -23
  115. data/lib/sequel/dataset/mutation.rb +12 -7
  116. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  117. data/lib/sequel/dataset/query.rb +237 -44
  118. data/lib/sequel/dataset/sql.rb +698 -278
  119. data/lib/sequel/dataset.rb +8 -0
  120. data/lib/sequel/exceptions.rb +4 -0
  121. data/lib/sequel/extensions/_pretty_table.rb +79 -0
  122. data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
  123. data/lib/sequel/extensions/columns_introspection.rb +61 -0
  124. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
  125. data/lib/sequel/extensions/migration.rb +97 -11
  126. data/lib/sequel/extensions/named_timezones.rb +5 -0
  127. data/lib/sequel/extensions/null_dataset.rb +90 -0
  128. data/lib/sequel/extensions/pg_array.rb +460 -0
  129. data/lib/sequel/extensions/pg_array_ops.rb +220 -0
  130. data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
  131. data/lib/sequel/extensions/pg_hstore.rb +296 -0
  132. data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
  133. data/lib/sequel/extensions/pg_inet.rb +89 -0
  134. data/lib/sequel/extensions/pg_json.rb +178 -0
  135. data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
  136. data/lib/sequel/extensions/pretty_table.rb +5 -71
  137. data/lib/sequel/extensions/query.rb +1 -1
  138. data/lib/sequel/extensions/query_literals.rb +79 -0
  139. data/lib/sequel/extensions/schema_caching.rb +76 -0
  140. data/lib/sequel/extensions/schema_dumper.rb +251 -37
  141. data/lib/sequel/extensions/select_remove.rb +35 -0
  142. data/lib/sequel/extensions/server_block.rb +139 -0
  143. data/lib/sequel/extensions/sql_expr.rb +4 -110
  144. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  145. data/lib/sequel/extensions/to_dot.rb +95 -83
  146. data/lib/sequel/model/associations.rb +1187 -393
  147. data/lib/sequel/model/base.rb +578 -170
  148. data/lib/sequel/model/errors.rb +1 -1
  149. data/lib/sequel/model/exceptions.rb +5 -1
  150. data/lib/sequel/model/inflections.rb +1 -1
  151. data/lib/sequel/model.rb +30 -11
  152. data/lib/sequel/no_core_ext.rb +2 -0
  153. data/lib/sequel/plugins/active_model.rb +13 -1
  154. data/lib/sequel/plugins/association_pks.rb +22 -4
  155. data/lib/sequel/plugins/caching.rb +25 -18
  156. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  157. data/lib/sequel/plugins/composition.rb +44 -12
  158. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  159. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  160. data/lib/sequel/plugins/dirty.rb +214 -0
  161. data/lib/sequel/plugins/eager_each.rb +59 -0
  162. data/lib/sequel/plugins/force_encoding.rb +6 -6
  163. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  164. data/lib/sequel/plugins/identity_map.rb +123 -8
  165. data/lib/sequel/plugins/instance_filters.rb +10 -0
  166. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  167. data/lib/sequel/plugins/json_serializer.rb +58 -6
  168. data/lib/sequel/plugins/list.rb +12 -2
  169. data/lib/sequel/plugins/many_through_many.rb +79 -28
  170. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  171. data/lib/sequel/plugins/nested_attributes.rb +139 -63
  172. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  173. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  174. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  175. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  176. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  177. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  178. data/lib/sequel/plugins/schema.rb +7 -2
  179. data/lib/sequel/plugins/serialization.rb +98 -49
  180. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  181. data/lib/sequel/plugins/sharding.rb +21 -54
  182. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  183. data/lib/sequel/plugins/static_cache.rb +99 -0
  184. data/lib/sequel/plugins/subclasses.rb +10 -2
  185. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  186. data/lib/sequel/plugins/timestamps.rb +1 -1
  187. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  188. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  189. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  190. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  191. data/lib/sequel/sql.rb +526 -59
  192. data/lib/sequel/timezones.rb +57 -38
  193. data/lib/sequel/version.rb +1 -1
  194. data/spec/adapters/db2_spec.rb +146 -0
  195. data/spec/adapters/firebird_spec.rb +1 -1
  196. data/spec/adapters/mssql_spec.rb +142 -40
  197. data/spec/adapters/mysql_spec.rb +380 -234
  198. data/spec/adapters/oracle_spec.rb +67 -77
  199. data/spec/adapters/postgres_spec.rb +1050 -212
  200. data/spec/adapters/spec_helper.rb +8 -5
  201. data/spec/adapters/sqlite_spec.rb +139 -27
  202. data/spec/core/connection_pool_spec.rb +196 -93
  203. data/spec/core/database_spec.rb +879 -510
  204. data/spec/core/dataset_spec.rb +1415 -1086
  205. data/spec/core/expression_filters_spec.rb +554 -109
  206. data/spec/core/mock_adapter_spec.rb +449 -0
  207. data/spec/core/object_graph_spec.rb +86 -114
  208. data/spec/core/schema_generator_spec.rb +4 -4
  209. data/spec/core/schema_spec.rb +482 -38
  210. data/spec/core/spec_helper.rb +6 -48
  211. data/spec/extensions/active_model_spec.rb +13 -0
  212. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  213. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  214. data/spec/extensions/association_dependencies_spec.rb +15 -25
  215. data/spec/extensions/association_pks_spec.rb +66 -32
  216. data/spec/extensions/association_proxies_spec.rb +4 -4
  217. data/spec/extensions/caching_spec.rb +47 -51
  218. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  219. data/spec/extensions/columns_introspection_spec.rb +91 -0
  220. data/spec/extensions/composition_spec.rb +18 -13
  221. data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
  222. data/spec/extensions/dataset_associations_spec.rb +199 -0
  223. data/spec/extensions/defaults_setter_spec.rb +64 -0
  224. data/spec/extensions/dirty_spec.rb +155 -0
  225. data/spec/extensions/eager_each_spec.rb +34 -0
  226. data/spec/extensions/force_encoding_spec.rb +4 -2
  227. data/spec/extensions/hook_class_methods_spec.rb +69 -92
  228. data/spec/extensions/identity_map_spec.rb +131 -22
  229. data/spec/extensions/inflector_spec.rb +0 -4
  230. data/spec/extensions/instance_filters_spec.rb +11 -21
  231. data/spec/extensions/instance_hooks_spec.rb +72 -0
  232. data/spec/extensions/json_serializer_spec.rb +49 -6
  233. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  234. data/spec/extensions/list_spec.rb +48 -39
  235. data/spec/extensions/many_through_many_spec.rb +283 -250
  236. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  237. data/spec/extensions/migration_spec.rb +140 -35
  238. data/spec/extensions/named_timezones_spec.rb +29 -11
  239. data/spec/extensions/nested_attributes_spec.rb +251 -89
  240. data/spec/extensions/null_dataset_spec.rb +85 -0
  241. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  242. data/spec/extensions/pg_array_ops_spec.rb +105 -0
  243. data/spec/extensions/pg_array_spec.rb +196 -0
  244. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  245. data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
  246. data/spec/extensions/pg_hstore_spec.rb +195 -0
  247. data/spec/extensions/pg_inet_spec.rb +44 -0
  248. data/spec/extensions/pg_json_spec.rb +101 -0
  249. data/spec/extensions/pg_statement_cache_spec.rb +209 -0
  250. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  251. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  252. data/spec/extensions/prepared_statements_spec.rb +87 -0
  253. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  254. data/spec/extensions/pretty_table_spec.rb +7 -6
  255. data/spec/extensions/query_literals_spec.rb +168 -0
  256. data/spec/extensions/query_spec.rb +6 -0
  257. data/spec/extensions/rcte_tree_spec.rb +50 -43
  258. data/spec/extensions/schema_caching_spec.rb +41 -0
  259. data/spec/extensions/schema_dumper_spec.rb +429 -22
  260. data/spec/extensions/schema_spec.rb +25 -21
  261. data/spec/extensions/select_remove_spec.rb +38 -0
  262. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  263. data/spec/extensions/serialization_spec.rb +85 -43
  264. data/spec/extensions/server_block_spec.rb +90 -0
  265. data/spec/extensions/sharding_spec.rb +69 -143
  266. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  267. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  268. data/spec/extensions/spec_helper.rb +22 -61
  269. data/spec/extensions/sql_expr_spec.rb +29 -60
  270. data/spec/extensions/static_cache_spec.rb +145 -0
  271. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  272. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  273. data/spec/extensions/timestamps_spec.rb +6 -6
  274. data/spec/extensions/to_dot_spec.rb +4 -7
  275. data/spec/extensions/touch_spec.rb +13 -14
  276. data/spec/extensions/tree_spec.rb +11 -26
  277. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  278. data/spec/extensions/update_primary_key_spec.rb +30 -24
  279. data/spec/extensions/validation_class_methods_spec.rb +30 -51
  280. data/spec/extensions/validation_helpers_spec.rb +16 -35
  281. data/spec/extensions/xml_serializer_spec.rb +29 -4
  282. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  283. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  284. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  285. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  286. data/spec/integration/associations_test.rb +659 -21
  287. data/spec/integration/database_test.rb +9 -3
  288. data/spec/integration/dataset_test.rb +605 -91
  289. data/spec/integration/eager_loader_test.rb +19 -21
  290. data/spec/integration/migrator_test.rb +2 -3
  291. data/spec/integration/model_test.rb +81 -2
  292. data/spec/integration/plugin_test.rb +454 -143
  293. data/spec/integration/prepared_statement_test.rb +263 -128
  294. data/spec/integration/schema_test.rb +309 -43
  295. data/spec/integration/spec_helper.rb +40 -30
  296. data/spec/integration/timezone_test.rb +38 -12
  297. data/spec/integration/transaction_test.rb +183 -8
  298. data/spec/integration/type_test.rb +18 -4
  299. data/spec/model/association_reflection_spec.rb +201 -7
  300. data/spec/model/associations_spec.rb +1067 -661
  301. data/spec/model/base_spec.rb +329 -95
  302. data/spec/model/dataset_methods_spec.rb +7 -27
  303. data/spec/model/eager_loading_spec.rb +677 -676
  304. data/spec/model/hooks_spec.rb +349 -67
  305. data/spec/model/model_spec.rb +240 -168
  306. data/spec/model/plugins_spec.rb +24 -13
  307. data/spec/model/record_spec.rb +490 -232
  308. data/spec/model/spec_helper.rb +14 -71
  309. data/spec/model/validations_spec.rb +11 -0
  310. data/spec/rcov.opts +2 -0
  311. metadata +178 -80
@@ -0,0 +1,155 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::Dirty" do
4
+ before do
5
+ @db = Sequel.mock(:fetch=>{:initial=>'i', :initial_changed=>'ic'}, :numrows=>1)
6
+ @c = Class.new(Sequel::Model(@db[:c]))
7
+ @c.plugin :dirty
8
+ @c.columns :initial, :initial_changed, :missing, :missing_changed
9
+ end
10
+
11
+ shared_examples_for "dirty plugin" do
12
+ it "initial_value should be the current value if value has not changed" do
13
+ @o.initial_value(:initial).should == 'i'
14
+ @o.initial_value(:missing).should == nil
15
+ end
16
+
17
+ it "initial_value should be the intial value if value has changed" do
18
+ @o.initial_value(:initial_changed).should == 'ic'
19
+ @o.initial_value(:missing_changed).should == nil
20
+ end
21
+
22
+ it "initial_value should handle case where initial value is reassigned later" do
23
+ @o.initial_changed = 'ic'
24
+ @o.initial_value(:initial_changed).should == 'ic'
25
+ @o.missing_changed = nil
26
+ @o.initial_value(:missing_changed).should == nil
27
+ end
28
+
29
+ it "changed_columns should handle case where initial value is reassigned later" do
30
+ @o.changed_columns.should == [:initial_changed, :missing_changed]
31
+ @o.initial_changed = 'ic'
32
+ @o.changed_columns.should == [:missing_changed]
33
+ @o.missing_changed = nil
34
+ @o.changed_columns.should == [:missing_changed]
35
+ end
36
+
37
+ it "column_change should give initial and current values if there has been a change made" do
38
+ @o.column_change(:initial_changed).should == ['ic', 'ic2']
39
+ @o.column_change(:missing_changed).should == [nil, 'mc2']
40
+ end
41
+
42
+ it "column_change should be nil if no change has been made" do
43
+ @o.column_change(:initial).should == nil
44
+ @o.column_change(:missing).should == nil
45
+ end
46
+
47
+ it "column_changed? should return whether the column has changed" do
48
+ @o.column_changed?(:initial).should == false
49
+ @o.column_changed?(:initial_changed).should == true
50
+ @o.column_changed?(:missing).should == false
51
+ @o.column_changed?(:missing_changed).should == true
52
+ end
53
+
54
+ it "column_changed? should handle case where initial value is reassigned later" do
55
+ @o.initial_changed = 'ic'
56
+ @o.column_changed?(:initial_changed).should == false
57
+ @o.missing_changed = nil
58
+ @o.column_changed?(:missing_changed).should == false
59
+ end
60
+
61
+ it "changed_columns should handle case where initial value is reassigned later" do
62
+ @o.changed_columns.should == [:initial_changed, :missing_changed]
63
+ @o.initial_changed = 'ic'
64
+ @o.changed_columns.should == [:missing_changed]
65
+ @o.missing_changed = nil
66
+ @o.changed_columns.should == [:missing_changed]
67
+ end
68
+
69
+ it "column_changes should give initial and current values" do
70
+ @o.column_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
71
+ end
72
+
73
+ it "reset_column should reset the column to its initial value" do
74
+ @o.reset_column(:initial)
75
+ @o.initial.should == 'i'
76
+ @o.reset_column(:initial_changed)
77
+ @o.initial_changed.should == 'ic'
78
+ @o.reset_column(:missing)
79
+ @o.missing.should == nil
80
+ @o.reset_column(:missing_changed)
81
+ @o.missing_changed.should == nil
82
+ end
83
+
84
+ it "reset_column should remove missing values from the values" do
85
+ @o.reset_column(:missing)
86
+ @o.values.has_key?(:missing).should == false
87
+ @o.reset_column(:missing_changed)
88
+ @o.values.has_key?(:missing_changed).should == false
89
+ end
90
+
91
+ it "refresh should clear the cached initial values" do
92
+ @o.refresh
93
+ @o.column_changes.should == {}
94
+ end
95
+
96
+ it "will_change_column should be used to signal in-place modification to column" do
97
+ @o.will_change_column(:initial)
98
+ @o.initial << 'b'
99
+ @o.column_change(:initial).should == ['i', 'ib']
100
+ @o.will_change_column(:initial_changed)
101
+ @o.initial_changed << 'b'
102
+ @o.column_change(:initial_changed).should == ['ic', 'ic2b']
103
+ @o.will_change_column(:missing)
104
+ @o.values[:missing] = 'b'
105
+ @o.column_change(:missing).should == [nil, 'b']
106
+ @o.will_change_column(:missing_changed)
107
+ @o.missing_changed << 'b'
108
+ @o.column_change(:missing_changed).should == [nil, 'mc2b']
109
+ end
110
+
111
+ it "will_change_column should different types of existing objects" do
112
+ [nil, true, false, Class.new{undef_method :clone}.new, Class.new{def clone; raise TypeError; end}.new].each do |v|
113
+ o = @c.new(:initial=>v)
114
+ o.will_change_column(:initial)
115
+ o.initial = 'a'
116
+ o.column_change(:initial).should == [v, 'a']
117
+ end
118
+ end
119
+
120
+ it "save should clear the cached initial values" do
121
+ @o.save
122
+ @o.column_changes.should == {}
123
+ end
124
+
125
+ it "save_changes should clear the cached initial values" do
126
+ @o.save_changes
127
+ @o.column_changes.should == {}
128
+ end
129
+ end
130
+
131
+ describe "with new instance" do
132
+ before do
133
+ @o = @c.new(:initial=>'i', :initial_changed=>'ic')
134
+ @o.initial_changed = 'ic2'
135
+ @o.missing_changed = 'mc2'
136
+ end
137
+
138
+ it_should_behave_like "dirty plugin"
139
+ end
140
+
141
+ describe "with existing instance" do
142
+ before do
143
+ @o = @c[1]
144
+ @o.initial_changed = 'ic2'
145
+ @o.missing_changed = 'mc2'
146
+ end
147
+
148
+ it_should_behave_like "dirty plugin"
149
+
150
+ it "previous_changes should be the previous changes after saving" do
151
+ @o.save
152
+ @o.previous_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,34 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::EagerEach" do
4
+ before do
5
+ @c = Class.new(Sequel::Model(:items))
6
+ @c.columns :id, :parent_id
7
+ @c.plugin :eager_each
8
+ @c.one_to_many :children, :class=>@c, :key=>:parent_id
9
+ @c.db.sqls
10
+ end
11
+
12
+ it "should make #each on an eager dataset do eager loading" do
13
+ a = []
14
+ ds = @c.eager(:children)
15
+ ds._fetch = [{:id=>1, :parent_id=>nil}, {:id=>2, :parent_id=>nil}]
16
+ @c.dataset._fetch = [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}, {:id=>5, :parent_id=>2}, {:id=>6, :parent_id=>2}]
17
+ ds.each{|c| a << c}
18
+ a.should == [@c.load(:id=>1, :parent_id=>nil), @c.load(:id=>2, :parent_id=>nil)]
19
+ a.map{|c| c.associations[:children]}.should == [[@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)], [@c.load(:id=>5, :parent_id=>2), @c.load(:id=>6, :parent_id=>2)]]
20
+ @c.db.sqls.should == ['SELECT * FROM items', 'SELECT * FROM items WHERE (items.parent_id IN (1, 2))']
21
+ end
22
+
23
+ it "should make #each on an eager_graph dataset do eager loading" do
24
+ a = []
25
+ ds = @c.eager_graph(:children)
26
+ ds._fetch = []
27
+ ds._fetch = [{:id=>1, :parent_id=>nil, :children_id=>3, :children_parent_id=>1}, {:id=>1, :parent_id=>nil, :children_id=>4, :children_parent_id=>1}, {:id=>2, :parent_id=>nil, :children_id=>5, :children_parent_id=>2}, {:id=>2, :parent_id=>nil, :children_id=>6, :children_parent_id=>2}]
28
+ ds.each{|c| a << c}
29
+ a.should == [@c.load(:id=>1, :parent_id=>nil), @c.load(:id=>2, :parent_id=>nil)]
30
+ a.map{|c| c.associations[:children]}.should == [[@c.load(:id=>3, :parent_id=>1), @c.load(:id=>4, :parent_id=>1)], [@c.load(:id=>5, :parent_id=>2), @c.load(:id=>6, :parent_id=>2)]]
31
+ @c.db.sqls.should == ['SELECT items.id, items.parent_id, children.id AS children_id, children.parent_id AS children_parent_id FROM items LEFT OUTER JOIN items AS children ON (children.parent_id = items.id)']
32
+ end
33
+
34
+ end
@@ -74,12 +74,13 @@ describe "force_encoding plugin" do
74
74
 
75
75
  specify "should work when saving new model instances" do
76
76
  o = @c.new
77
- @c.dataset = ds = MODEL_DB[:a]
77
+ ds = MODEL_DB[:a]
78
78
  def ds.first
79
79
  s = 'blah'
80
80
  s.force_encoding('US-ASCII')
81
81
  {:id=>1, :x=>s}
82
82
  end
83
+ @c.dataset = ds
83
84
  o.save
84
85
  o.x.should == 'blah'
85
86
  o.x.encoding.should == @e1
@@ -87,12 +88,13 @@ describe "force_encoding plugin" do
87
88
 
88
89
  specify "should work when refreshing model instances" do
89
90
  o = @c.load(:id=>1, :x=>'as')
90
- @c.dataset = ds = MODEL_DB[:a]
91
+ ds = MODEL_DB[:a]
91
92
  def ds.first
92
93
  s = 'blah'
93
94
  s.force_encoding('US-ASCII')
94
95
  {:id=>1, :x=>s}
95
96
  end
97
+ @c.dataset = ds
96
98
  o.refresh
97
99
  o.x.should == 'blah'
98
100
  o.x.encoding.should == @e1
@@ -6,187 +6,185 @@ describe "Model hooks" do
6
6
  end
7
7
 
8
8
  specify "should be definable using a block" do
9
- $adds = []
9
+ adds = []
10
10
  c = Class.new(Sequel::Model)
11
11
  c.class_eval do
12
- before_save {$adds << 'hi'}
12
+ before_save{adds << 'hi'}
13
13
  end
14
14
 
15
15
  c.new.before_save
16
- $adds.should == ['hi']
16
+ adds.should == ['hi']
17
17
  end
18
18
 
19
19
  specify "should be definable using a method name" do
20
- $adds = []
20
+ adds = []
21
21
  c = Class.new(Sequel::Model)
22
22
  c.class_eval do
23
- def bye; $adds << 'bye'; end
23
+ define_method(:bye){adds << 'bye'}
24
24
  before_save :bye
25
25
  end
26
26
 
27
27
  c.new.before_save
28
- $adds.should == ['bye']
28
+ adds.should == ['bye']
29
29
  end
30
30
 
31
31
  specify "should be additive" do
32
- $adds = []
32
+ adds = []
33
33
  c = Class.new(Sequel::Model)
34
34
  c.class_eval do
35
- after_save {$adds << 'hyiyie'}
36
- after_save {$adds << 'byiyie'}
35
+ after_save{adds << 'hyiyie'}
36
+ after_save{adds << 'byiyie'}
37
37
  end
38
38
 
39
39
  c.new.after_save
40
- $adds.should == ['hyiyie', 'byiyie']
40
+ adds.should == ['hyiyie', 'byiyie']
41
41
  end
42
42
 
43
43
  specify "before hooks should run in reverse order" do
44
- $adds = []
44
+ adds = []
45
45
  c = Class.new(Sequel::Model)
46
46
  c.class_eval do
47
- before_save {$adds << 'hyiyie'}
48
- before_save {$adds << 'byiyie'}
47
+ before_save{adds << 'hyiyie'}
48
+ before_save{adds << 'byiyie'}
49
49
  end
50
50
 
51
51
  c.new.before_save
52
- $adds.should == ['byiyie', 'hyiyie']
52
+ adds.should == ['byiyie', 'hyiyie']
53
53
  end
54
54
 
55
55
  specify "should not be additive if the method or tag already exists" do
56
- $adds = []
56
+ adds = []
57
57
  c = Class.new(Sequel::Model)
58
58
  c.class_eval do
59
- def bye; $adds << 'bye'; end
59
+ define_method(:bye){adds << 'bye'}
60
60
  before_save :bye
61
61
  before_save :bye
62
62
  end
63
63
 
64
64
  c.new.before_save
65
- $adds.should == ['bye']
65
+ adds.should == ['bye']
66
66
 
67
- $adds = []
67
+ adds = []
68
68
  d = Class.new(Sequel::Model)
69
69
  d.class_eval do
70
- before_save(:bye){$adds << 'hyiyie'}
71
- before_save(:bye){$adds << 'byiyie'}
70
+ before_save(:bye){adds << 'hyiyie'}
71
+ before_save(:bye){adds << 'byiyie'}
72
72
  end
73
73
 
74
74
  d.new.before_save
75
- $adds.should == ['byiyie']
75
+ adds.should == ['byiyie']
76
76
 
77
- $adds = []
77
+ adds = []
78
78
  e = Class.new(Sequel::Model)
79
79
  e.class_eval do
80
- def bye; $adds << 'bye'; end
80
+ define_method(:bye){adds << 'bye'}
81
81
  before_save :bye
82
- before_save(:bye){$adds << 'byiyie'}
82
+ before_save(:bye){adds << 'byiyie'}
83
83
  end
84
84
 
85
85
  e.new.before_save
86
- $adds.should == ['byiyie']
86
+ adds.should == ['byiyie']
87
87
 
88
- $adds = []
88
+ adds = []
89
89
  e = Class.new(Sequel::Model)
90
90
  e.class_eval do
91
- def bye; $adds << 'bye'; end
92
- before_save(:bye){$adds << 'byiyie'}
91
+ define_method(:bye){adds << 'bye'}
92
+ before_save(:bye){adds << 'byiyie'}
93
93
  before_save :bye
94
94
  end
95
95
 
96
96
  e.new.before_save
97
- $adds.should == ['bye']
97
+ adds.should == ['bye']
98
98
  end
99
99
 
100
100
  specify "should be inheritable" do
101
- # pending
102
-
103
- $adds = []
101
+ adds = []
104
102
  a = Class.new(Sequel::Model)
105
103
  a.class_eval do
106
- after_save {$adds << '123'}
104
+ after_save{adds << '123'}
107
105
  end
108
106
 
109
107
  b = Class.new(a)
110
108
  b.class_eval do
111
- after_save {$adds << '456'}
112
- after_save {$adds << '789'}
109
+ after_save{adds << '456'}
110
+ after_save{adds << '789'}
113
111
  end
114
112
 
115
113
  b.new.after_save
116
- $adds.should == ['123', '456', '789']
114
+ adds.should == ['123', '456', '789']
117
115
  end
118
116
 
119
117
  specify "should be overridable in descendant classes" do
120
- $adds = []
118
+ adds = []
121
119
  a = Class.new(Sequel::Model)
122
120
  a.class_eval do
123
- before_save {$adds << '123'}
121
+ before_save{adds << '123'}
124
122
  end
125
123
 
126
124
  b = Class.new(a)
127
125
  b.class_eval do
128
- def before_save; $adds << '456'; end
126
+ define_method(:before_save){adds << '456'}
129
127
  end
130
128
 
131
129
  a.new.before_save
132
- $adds.should == ['123']
133
- $adds = []
130
+ adds.should == ['123']
131
+ adds = []
134
132
  b.new.before_save
135
- $adds.should == ['456']
133
+ adds.should == ['456']
136
134
  end
137
135
 
138
136
  specify "should stop processing if a before hook returns false" do
139
- $flag = true
140
- $adds = []
137
+ flag = true
138
+ adds = []
141
139
 
142
140
  a = Class.new(Sequel::Model)
143
141
  a.class_eval do
144
- before_save {$adds << 'cruel'; $flag}
145
- before_save {$adds << 'blah'; $flag}
142
+ before_save{adds << 'cruel'; flag}
143
+ before_save{adds << 'blah'; flag}
146
144
  end
147
145
 
148
146
  a.new.before_save
149
- $adds.should == ['blah', 'cruel']
147
+ adds.should == ['blah', 'cruel']
150
148
 
151
149
  # chain should not break on nil
152
- $adds = []
153
- $flag = nil
150
+ adds = []
151
+ flag = nil
154
152
  a.new.before_save
155
- $adds.should == ['blah', 'cruel']
153
+ adds.should == ['blah', 'cruel']
156
154
 
157
- $adds = []
158
- $flag = false
155
+ adds = []
156
+ flag = false
159
157
  a.new.before_save
160
- $adds.should == ['blah']
158
+ adds.should == ['blah']
161
159
 
162
160
  b = Class.new(a)
163
161
  b.class_eval do
164
- before_save {$adds << 'mau'}
162
+ before_save{adds << 'mau'}
165
163
  end
166
164
 
167
- $adds = []
165
+ adds = []
168
166
  b.new.before_save
169
- $adds.should == ['mau', 'blah']
167
+ adds.should == ['mau', 'blah']
170
168
  end
171
169
  end
172
170
 
173
171
  describe "Model#after_initialize" do
174
172
  specify "should be called after initialization" do
175
- $values1 = nil
176
- $reached_after_initialized = false
173
+ values1 = nil
174
+ reached_after_initialized = false
177
175
 
178
176
  a = Class.new(Sequel::Model)
179
177
  a.class_eval do
180
178
  columns :x, :y
181
179
  after_initialize do
182
- $values1 = @values.clone
183
- $reached_after_initialized = true
180
+ values1 = @values.clone
181
+ reached_after_initialized = true
184
182
  end
185
183
  end
186
184
 
187
185
  a.new(:x => 1, :y => 2)
188
- $values1.should == {:x => 1, :y => 2}
189
- $reached_after_initialized.should == true
186
+ values1.should == {:x => 1, :y => 2}
187
+ reached_after_initialized.should == true
190
188
  end
191
189
  end
192
190
 
@@ -206,11 +204,7 @@ describe "Model#before_create && Model#after_create" do
206
204
  specify "should be called around new record creation" do
207
205
  @c.before_create {MODEL_DB << "BLAH before"}
208
206
  @c.create(:x => 2)
209
- MODEL_DB.sqls.should == [
210
- 'BLAH before',
211
- 'INSERT INTO items (x) VALUES (2)',
212
- 'BLAH after'
213
- ]
207
+ MODEL_DB.sqls.should == ['BLAH before', 'INSERT INTO items (x) VALUES (2)', 'BLAH after']
214
208
  end
215
209
 
216
210
  specify ".create should cancel the save and raise an error if before_create returns false and raise_on_save_failure is true" do
@@ -242,11 +236,7 @@ describe "Model#before_update && Model#after_update" do
242
236
  @c.before_update {MODEL_DB << "BLAH before"}
243
237
  m = @c.load(:id => 2233, :x=>123)
244
238
  m.save
245
- MODEL_DB.sqls.should == [
246
- 'BLAH before',
247
- 'UPDATE items SET x = 123 WHERE (id = 2233)',
248
- 'BLAH after'
249
- ]
239
+ MODEL_DB.sqls.should == ['BLAH before', 'UPDATE items SET x = 123 WHERE (id = 2233)', 'BLAH after']
250
240
  end
251
241
 
252
242
  specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
@@ -279,22 +269,14 @@ describe "Model#before_save && Model#after_save" do
279
269
  @c.before_save {MODEL_DB << "BLAH before"}
280
270
  m = @c.load(:id => 2233, :x=>123)
281
271
  m.save
282
- MODEL_DB.sqls.should == [
283
- 'BLAH before',
284
- 'UPDATE items SET x = 123 WHERE (id = 2233)',
285
- 'BLAH after'
286
- ]
272
+ MODEL_DB.sqls.should == ['BLAH before', 'UPDATE items SET x = 123 WHERE (id = 2233)', 'BLAH after']
287
273
  end
288
274
 
289
275
  specify "should be called around record creation" do
290
276
  @c.before_save {MODEL_DB << "BLAH before"}
291
277
  @c.no_primary_key
292
278
  @c.create(:x => 2)
293
- MODEL_DB.sqls.should == [
294
- 'BLAH before',
295
- 'INSERT INTO items (x) VALUES (2)',
296
- 'BLAH after'
297
- ]
279
+ MODEL_DB.sqls.should == ['BLAH before', 'INSERT INTO items (x) VALUES (2)', 'BLAH after']
298
280
  end
299
281
 
300
282
  specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
@@ -319,10 +301,6 @@ describe "Model#before_destroy && Model#after_destroy" do
319
301
  @c = Class.new(Sequel::Model(:items))
320
302
  @c.class_eval do
321
303
  after_destroy {MODEL_DB << "BLAH after"}
322
-
323
- def delete
324
- MODEL_DB << "DELETE BLAH"
325
- end
326
304
  end
327
305
  end
328
306
 
@@ -330,11 +308,7 @@ describe "Model#before_destroy && Model#after_destroy" do
330
308
  @c.before_destroy {MODEL_DB << "BLAH before"}
331
309
  m = @c.load(:id => 2233)
332
310
  m.destroy
333
- MODEL_DB.sqls.should == [
334
- 'BLAH before',
335
- 'DELETE BLAH',
336
- 'BLAH after'
337
- ]
311
+ MODEL_DB.sqls.should == ['BLAH before', "DELETE FROM items WHERE id = 2233", 'BLAH after']
338
312
  end
339
313
 
340
314
  specify "#destroy should cancel the destroy and raise an error if before_destroy returns false and raise_on_save_failure is true" do
@@ -428,7 +402,7 @@ end
428
402
 
429
403
  describe "Model#add_hook_type" do
430
404
  before do
431
- class Foo < Sequel::Model(:items)
405
+ class ::Foo < Sequel::Model(:items)
432
406
  add_hook_type :before_bar, :after_bar
433
407
 
434
408
  def bar
@@ -439,6 +413,9 @@ describe "Model#add_hook_type" do
439
413
  end
440
414
  @f = Class.new(Foo)
441
415
  end
416
+ after do
417
+ Object.send(:remove_const, :Foo)
418
+ end
442
419
 
443
420
  specify "should have before_bar and after_bar class methods" do
444
421
  @f.should respond_to(:before_bar)