viking-sequel 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. data/CHANGELOG +3134 -0
  2. data/COPYING +19 -0
  3. data/README.rdoc +723 -0
  4. data/Rakefile +193 -0
  5. data/bin/sequel +196 -0
  6. data/doc/advanced_associations.rdoc +644 -0
  7. data/doc/cheat_sheet.rdoc +218 -0
  8. data/doc/dataset_basics.rdoc +106 -0
  9. data/doc/dataset_filtering.rdoc +158 -0
  10. data/doc/opening_databases.rdoc +296 -0
  11. data/doc/prepared_statements.rdoc +104 -0
  12. data/doc/reflection.rdoc +84 -0
  13. data/doc/release_notes/1.0.txt +38 -0
  14. data/doc/release_notes/1.1.txt +143 -0
  15. data/doc/release_notes/1.3.txt +101 -0
  16. data/doc/release_notes/1.4.0.txt +53 -0
  17. data/doc/release_notes/1.5.0.txt +155 -0
  18. data/doc/release_notes/2.0.0.txt +298 -0
  19. data/doc/release_notes/2.1.0.txt +271 -0
  20. data/doc/release_notes/2.10.0.txt +328 -0
  21. data/doc/release_notes/2.11.0.txt +215 -0
  22. data/doc/release_notes/2.12.0.txt +534 -0
  23. data/doc/release_notes/2.2.0.txt +253 -0
  24. data/doc/release_notes/2.3.0.txt +88 -0
  25. data/doc/release_notes/2.4.0.txt +106 -0
  26. data/doc/release_notes/2.5.0.txt +137 -0
  27. data/doc/release_notes/2.6.0.txt +157 -0
  28. data/doc/release_notes/2.7.0.txt +166 -0
  29. data/doc/release_notes/2.8.0.txt +171 -0
  30. data/doc/release_notes/2.9.0.txt +97 -0
  31. data/doc/release_notes/3.0.0.txt +221 -0
  32. data/doc/release_notes/3.1.0.txt +406 -0
  33. data/doc/release_notes/3.10.0.txt +286 -0
  34. data/doc/release_notes/3.2.0.txt +268 -0
  35. data/doc/release_notes/3.3.0.txt +192 -0
  36. data/doc/release_notes/3.4.0.txt +325 -0
  37. data/doc/release_notes/3.5.0.txt +510 -0
  38. data/doc/release_notes/3.6.0.txt +366 -0
  39. data/doc/release_notes/3.7.0.txt +179 -0
  40. data/doc/release_notes/3.8.0.txt +151 -0
  41. data/doc/release_notes/3.9.0.txt +233 -0
  42. data/doc/schema.rdoc +36 -0
  43. data/doc/sharding.rdoc +113 -0
  44. data/doc/virtual_rows.rdoc +205 -0
  45. data/lib/sequel.rb +1 -0
  46. data/lib/sequel/adapters/ado.rb +90 -0
  47. data/lib/sequel/adapters/ado/mssql.rb +30 -0
  48. data/lib/sequel/adapters/amalgalite.rb +176 -0
  49. data/lib/sequel/adapters/db2.rb +139 -0
  50. data/lib/sequel/adapters/dbi.rb +113 -0
  51. data/lib/sequel/adapters/do.rb +188 -0
  52. data/lib/sequel/adapters/do/mysql.rb +49 -0
  53. data/lib/sequel/adapters/do/postgres.rb +91 -0
  54. data/lib/sequel/adapters/do/sqlite.rb +40 -0
  55. data/lib/sequel/adapters/firebird.rb +283 -0
  56. data/lib/sequel/adapters/informix.rb +77 -0
  57. data/lib/sequel/adapters/jdbc.rb +587 -0
  58. data/lib/sequel/adapters/jdbc/as400.rb +58 -0
  59. data/lib/sequel/adapters/jdbc/h2.rb +133 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
  61. data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
  62. data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
  64. data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
  65. data/lib/sequel/adapters/mysql.rb +421 -0
  66. data/lib/sequel/adapters/odbc.rb +143 -0
  67. data/lib/sequel/adapters/odbc/mssql.rb +42 -0
  68. data/lib/sequel/adapters/openbase.rb +64 -0
  69. data/lib/sequel/adapters/oracle.rb +131 -0
  70. data/lib/sequel/adapters/postgres.rb +504 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +490 -0
  72. data/lib/sequel/adapters/shared/mysql.rb +498 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +195 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +830 -0
  75. data/lib/sequel/adapters/shared/progress.rb +44 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +389 -0
  77. data/lib/sequel/adapters/sqlite.rb +224 -0
  78. data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
  79. data/lib/sequel/connection_pool.rb +99 -0
  80. data/lib/sequel/connection_pool/sharded_single.rb +84 -0
  81. data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
  82. data/lib/sequel/connection_pool/single.rb +29 -0
  83. data/lib/sequel/connection_pool/threaded.rb +150 -0
  84. data/lib/sequel/core.rb +293 -0
  85. data/lib/sequel/core_sql.rb +241 -0
  86. data/lib/sequel/database.rb +1079 -0
  87. data/lib/sequel/database/schema_generator.rb +327 -0
  88. data/lib/sequel/database/schema_methods.rb +203 -0
  89. data/lib/sequel/database/schema_sql.rb +320 -0
  90. data/lib/sequel/dataset.rb +32 -0
  91. data/lib/sequel/dataset/actions.rb +441 -0
  92. data/lib/sequel/dataset/features.rb +86 -0
  93. data/lib/sequel/dataset/graph.rb +254 -0
  94. data/lib/sequel/dataset/misc.rb +119 -0
  95. data/lib/sequel/dataset/mutation.rb +64 -0
  96. data/lib/sequel/dataset/prepared_statements.rb +227 -0
  97. data/lib/sequel/dataset/query.rb +709 -0
  98. data/lib/sequel/dataset/sql.rb +996 -0
  99. data/lib/sequel/exceptions.rb +51 -0
  100. data/lib/sequel/extensions/blank.rb +43 -0
  101. data/lib/sequel/extensions/inflector.rb +242 -0
  102. data/lib/sequel/extensions/looser_typecasting.rb +21 -0
  103. data/lib/sequel/extensions/migration.rb +239 -0
  104. data/lib/sequel/extensions/named_timezones.rb +61 -0
  105. data/lib/sequel/extensions/pagination.rb +100 -0
  106. data/lib/sequel/extensions/pretty_table.rb +82 -0
  107. data/lib/sequel/extensions/query.rb +52 -0
  108. data/lib/sequel/extensions/schema_dumper.rb +271 -0
  109. data/lib/sequel/extensions/sql_expr.rb +122 -0
  110. data/lib/sequel/extensions/string_date_time.rb +46 -0
  111. data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
  112. data/lib/sequel/metaprogramming.rb +9 -0
  113. data/lib/sequel/model.rb +120 -0
  114. data/lib/sequel/model/associations.rb +1514 -0
  115. data/lib/sequel/model/base.rb +1069 -0
  116. data/lib/sequel/model/default_inflections.rb +45 -0
  117. data/lib/sequel/model/errors.rb +39 -0
  118. data/lib/sequel/model/exceptions.rb +21 -0
  119. data/lib/sequel/model/inflections.rb +162 -0
  120. data/lib/sequel/model/plugins.rb +70 -0
  121. data/lib/sequel/plugins/active_model.rb +59 -0
  122. data/lib/sequel/plugins/association_dependencies.rb +103 -0
  123. data/lib/sequel/plugins/association_proxies.rb +41 -0
  124. data/lib/sequel/plugins/boolean_readers.rb +53 -0
  125. data/lib/sequel/plugins/caching.rb +141 -0
  126. data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
  127. data/lib/sequel/plugins/composition.rb +138 -0
  128. data/lib/sequel/plugins/force_encoding.rb +72 -0
  129. data/lib/sequel/plugins/hook_class_methods.rb +126 -0
  130. data/lib/sequel/plugins/identity_map.rb +116 -0
  131. data/lib/sequel/plugins/instance_filters.rb +98 -0
  132. data/lib/sequel/plugins/instance_hooks.rb +57 -0
  133. data/lib/sequel/plugins/lazy_attributes.rb +77 -0
  134. data/lib/sequel/plugins/many_through_many.rb +208 -0
  135. data/lib/sequel/plugins/nested_attributes.rb +206 -0
  136. data/lib/sequel/plugins/optimistic_locking.rb +81 -0
  137. data/lib/sequel/plugins/rcte_tree.rb +281 -0
  138. data/lib/sequel/plugins/schema.rb +66 -0
  139. data/lib/sequel/plugins/serialization.rb +166 -0
  140. data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
  141. data/lib/sequel/plugins/subclasses.rb +45 -0
  142. data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
  143. data/lib/sequel/plugins/timestamps.rb +87 -0
  144. data/lib/sequel/plugins/touch.rb +118 -0
  145. data/lib/sequel/plugins/typecast_on_load.rb +72 -0
  146. data/lib/sequel/plugins/validation_class_methods.rb +405 -0
  147. data/lib/sequel/plugins/validation_helpers.rb +223 -0
  148. data/lib/sequel/sql.rb +1020 -0
  149. data/lib/sequel/timezones.rb +161 -0
  150. data/lib/sequel/version.rb +12 -0
  151. data/lib/sequel_core.rb +1 -0
  152. data/lib/sequel_model.rb +1 -0
  153. data/spec/adapters/firebird_spec.rb +407 -0
  154. data/spec/adapters/informix_spec.rb +97 -0
  155. data/spec/adapters/mssql_spec.rb +403 -0
  156. data/spec/adapters/mysql_spec.rb +1019 -0
  157. data/spec/adapters/oracle_spec.rb +286 -0
  158. data/spec/adapters/postgres_spec.rb +969 -0
  159. data/spec/adapters/spec_helper.rb +51 -0
  160. data/spec/adapters/sqlite_spec.rb +432 -0
  161. data/spec/core/connection_pool_spec.rb +808 -0
  162. data/spec/core/core_sql_spec.rb +417 -0
  163. data/spec/core/database_spec.rb +1662 -0
  164. data/spec/core/dataset_spec.rb +3827 -0
  165. data/spec/core/expression_filters_spec.rb +595 -0
  166. data/spec/core/object_graph_spec.rb +296 -0
  167. data/spec/core/schema_generator_spec.rb +159 -0
  168. data/spec/core/schema_spec.rb +830 -0
  169. data/spec/core/spec_helper.rb +56 -0
  170. data/spec/core/version_spec.rb +7 -0
  171. data/spec/extensions/active_model_spec.rb +76 -0
  172. data/spec/extensions/association_dependencies_spec.rb +127 -0
  173. data/spec/extensions/association_proxies_spec.rb +50 -0
  174. data/spec/extensions/blank_spec.rb +67 -0
  175. data/spec/extensions/boolean_readers_spec.rb +92 -0
  176. data/spec/extensions/caching_spec.rb +250 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +252 -0
  178. data/spec/extensions/composition_spec.rb +194 -0
  179. data/spec/extensions/force_encoding_spec.rb +117 -0
  180. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  181. data/spec/extensions/identity_map_spec.rb +202 -0
  182. data/spec/extensions/inflector_spec.rb +181 -0
  183. data/spec/extensions/instance_filters_spec.rb +55 -0
  184. data/spec/extensions/instance_hooks_spec.rb +133 -0
  185. data/spec/extensions/lazy_attributes_spec.rb +153 -0
  186. data/spec/extensions/looser_typecasting_spec.rb +39 -0
  187. data/spec/extensions/many_through_many_spec.rb +884 -0
  188. data/spec/extensions/migration_spec.rb +332 -0
  189. data/spec/extensions/named_timezones_spec.rb +72 -0
  190. data/spec/extensions/nested_attributes_spec.rb +396 -0
  191. data/spec/extensions/optimistic_locking_spec.rb +100 -0
  192. data/spec/extensions/pagination_spec.rb +99 -0
  193. data/spec/extensions/pretty_table_spec.rb +91 -0
  194. data/spec/extensions/query_spec.rb +85 -0
  195. data/spec/extensions/rcte_tree_spec.rb +205 -0
  196. data/spec/extensions/schema_dumper_spec.rb +357 -0
  197. data/spec/extensions/schema_spec.rb +127 -0
  198. data/spec/extensions/serialization_spec.rb +209 -0
  199. data/spec/extensions/single_table_inheritance_spec.rb +96 -0
  200. data/spec/extensions/spec_helper.rb +91 -0
  201. data/spec/extensions/sql_expr_spec.rb +89 -0
  202. data/spec/extensions/string_date_time_spec.rb +93 -0
  203. data/spec/extensions/subclasses_spec.rb +52 -0
  204. data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
  205. data/spec/extensions/thread_local_timezones_spec.rb +45 -0
  206. data/spec/extensions/timestamps_spec.rb +150 -0
  207. data/spec/extensions/touch_spec.rb +155 -0
  208. data/spec/extensions/typecast_on_load_spec.rb +69 -0
  209. data/spec/extensions/validation_class_methods_spec.rb +984 -0
  210. data/spec/extensions/validation_helpers_spec.rb +438 -0
  211. data/spec/integration/associations_test.rb +281 -0
  212. data/spec/integration/database_test.rb +26 -0
  213. data/spec/integration/dataset_test.rb +963 -0
  214. data/spec/integration/eager_loader_test.rb +734 -0
  215. data/spec/integration/model_test.rb +130 -0
  216. data/spec/integration/plugin_test.rb +814 -0
  217. data/spec/integration/prepared_statement_test.rb +213 -0
  218. data/spec/integration/schema_test.rb +361 -0
  219. data/spec/integration/spec_helper.rb +73 -0
  220. data/spec/integration/timezone_test.rb +55 -0
  221. data/spec/integration/transaction_test.rb +122 -0
  222. data/spec/integration/type_test.rb +96 -0
  223. data/spec/model/association_reflection_spec.rb +175 -0
  224. data/spec/model/associations_spec.rb +2633 -0
  225. data/spec/model/base_spec.rb +418 -0
  226. data/spec/model/dataset_methods_spec.rb +78 -0
  227. data/spec/model/eager_loading_spec.rb +1391 -0
  228. data/spec/model/hooks_spec.rb +240 -0
  229. data/spec/model/inflector_spec.rb +26 -0
  230. data/spec/model/model_spec.rb +593 -0
  231. data/spec/model/plugins_spec.rb +236 -0
  232. data/spec/model/record_spec.rb +1500 -0
  233. data/spec/model/spec_helper.rb +97 -0
  234. data/spec/model/validations_spec.rb +153 -0
  235. data/spec/rcov.opts +6 -0
  236. data/spec/spec_config.rb.example +10 -0
  237. metadata +346 -0
@@ -0,0 +1,93 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "String#to_time" do
4
+ specify "should convert the string into a Time object" do
5
+ "2007-07-11".to_time.should == Time.parse("2007-07-11")
6
+ "06:30".to_time.should == Time.parse("06:30")
7
+ end
8
+
9
+ specify "should raise InvalidValue for an invalid time" do
10
+ proc {'0000-00-00'.to_time}.should raise_error(Sequel::InvalidValue)
11
+ end
12
+ end
13
+
14
+ context "String#to_date" do
15
+ after do
16
+ Sequel.convert_two_digit_years = true
17
+ end
18
+
19
+ specify "should convert the string into a Date object" do
20
+ "2007-07-11".to_date.should == Date.parse("2007-07-11")
21
+ end
22
+
23
+ specify "should convert 2 digit years by default" do
24
+ "July 11, 07".to_date.should == Date.parse("2007-07-11")
25
+ end
26
+
27
+ specify "should not convert 2 digit years if set not to" do
28
+ Sequel.convert_two_digit_years = false
29
+ "July 11, 07".to_date.should == Date.parse("0007-07-11")
30
+ end
31
+
32
+ specify "should raise InvalidValue for an invalid date" do
33
+ proc {'0000-00-00'.to_date}.should raise_error(Sequel::InvalidValue)
34
+ end
35
+ end
36
+
37
+ context "String#to_datetime" do
38
+ after do
39
+ Sequel.convert_two_digit_years = true
40
+ end
41
+
42
+ specify "should convert the string into a DateTime object" do
43
+ "2007-07-11 10:11:12a".to_datetime.should == DateTime.parse("2007-07-11 10:11:12a")
44
+ end
45
+
46
+ specify "should convert 2 digit years by default" do
47
+ "July 11, 07 10:11:12a".to_datetime.should == DateTime.parse("2007-07-11 10:11:12a")
48
+ end
49
+
50
+ specify "should not convert 2 digit years if set not to" do
51
+ Sequel.convert_two_digit_years = false
52
+ "July 11, 07 10:11:12a".to_datetime.should == DateTime.parse("0007-07-11 10:11:12a")
53
+ end
54
+
55
+ specify "should raise InvalidValue for an invalid date" do
56
+ proc {'0000-00-00'.to_datetime}.should raise_error(Sequel::InvalidValue)
57
+ end
58
+ end
59
+
60
+ context "String#to_sequel_time" do
61
+ after do
62
+ Sequel.datetime_class = Time
63
+ Sequel.convert_two_digit_years = true
64
+ end
65
+
66
+ specify "should convert the string into a Time object by default" do
67
+ "2007-07-11 10:11:12a".to_sequel_time.class.should == Time
68
+ "2007-07-11 10:11:12a".to_sequel_time.should == Time.parse("2007-07-11 10:11:12a")
69
+ end
70
+
71
+ specify "should convert the string into a DateTime object if that is set" do
72
+ Sequel.datetime_class = DateTime
73
+ "2007-07-11 10:11:12a".to_sequel_time.class.should == DateTime
74
+ "2007-07-11 10:11:12a".to_sequel_time.should == DateTime.parse("2007-07-11 10:11:12a")
75
+ end
76
+
77
+ specify "should convert 2 digit years by default if using DateTime class" do
78
+ Sequel.datetime_class = DateTime
79
+ "July 11, 07 10:11:12a".to_sequel_time.should == DateTime.parse("2007-07-11 10:11:12a")
80
+ end
81
+
82
+ specify "should not convert 2 digit years if set not to when using DateTime class" do
83
+ Sequel.datetime_class = DateTime
84
+ Sequel.convert_two_digit_years = false
85
+ "July 11, 07 10:11:12a".to_sequel_time.should == DateTime.parse("0007-07-11 10:11:12a")
86
+ end
87
+
88
+ specify "should raise InvalidValue for an invalid time" do
89
+ proc {'0000-00-00'.to_sequel_time}.should raise_error(Sequel::InvalidValue)
90
+ Sequel.datetime_class = DateTime
91
+ proc {'0000-00-00'.to_sequel_time}.should raise_error(Sequel::InvalidValue)
92
+ end
93
+ end
@@ -0,0 +1,52 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Sequel::Model, "Subclasses plugin" do
4
+ before do
5
+ @c = Class.new(Sequel::Model)
6
+ @c.plugin :subclasses
7
+ end
8
+
9
+ specify "#subclasses should record direct subclasses of the given model" do
10
+ @c.subclasses.should == []
11
+
12
+ sc1 = Class.new(@c)
13
+ @c.subclasses.should == [sc1]
14
+ sc1.subclasses.should == []
15
+
16
+ sc2 = Class.new(@c)
17
+ @c.subclasses.should == [sc1, sc2]
18
+ sc1.subclasses.should == []
19
+ sc2.subclasses.should == []
20
+
21
+ ssc1 = Class.new(sc1)
22
+ @c.subclasses.should == [sc1, sc2]
23
+ sc1.subclasses.should == [ssc1]
24
+ sc2.subclasses.should == []
25
+ end
26
+
27
+ specify "#descendents should record all descendent subclasses of the given model" do
28
+ @c.descendents.should == []
29
+
30
+ sc1 = Class.new(@c)
31
+ @c.descendents.should == [sc1]
32
+ sc1.descendents.should == []
33
+
34
+ sc2 = Class.new(@c)
35
+ @c.descendents.should == [sc1, sc2]
36
+ sc1.descendents.should == []
37
+ sc2.descendents.should == []
38
+
39
+ ssc1 = Class.new(sc1)
40
+ @c.descendents.should == [sc1, ssc1, sc2]
41
+ sc1.descendents.should == [ssc1]
42
+ sc2.descendents.should == []
43
+ ssc1.descendents.should == []
44
+
45
+ sssc1 = Class.new(ssc1)
46
+ @c.descendents.should == [sc1, ssc1, sssc1, sc2]
47
+ sc1.descendents.should == [ssc1, sssc1]
48
+ sc2.descendents.should == []
49
+ ssc1.descendents.should == [sssc1]
50
+ sssc1.descendents.should == []
51
+ end
52
+ end
@@ -0,0 +1,65 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::TacticalEagerLoading" do
4
+ before do
5
+ class ::TaticalEagerLoadingModel < Sequel::Model
6
+ plugin :tactical_eager_loading
7
+ columns :id, :parent_id
8
+ many_to_one :parent, :class=>self
9
+ one_to_many :children, :class=>self, :key=>:parent_id
10
+ ds = dataset
11
+ def ds.fetch_rows(sql)
12
+ execute(sql)
13
+ where = @opts[:where]
14
+ if !where
15
+ yield(:id=>1, :parent_id=>101)
16
+ yield(:id=>2, :parent_id=>102)
17
+ yield(:id=>101, :parent_id=>nil)
18
+ yield(:id=>102, :parent_id=>nil)
19
+ elsif where.args.first.column == :id
20
+ Array(where.args.last).each do |x|
21
+ yield(:id=>x, :parent_id=>nil)
22
+ end
23
+ elsif where.args.first.column == :parent_id
24
+ Array(where.args.last).each do |x|
25
+ yield(:id=>x-100, :parent_id=>x) if x > 100
26
+ end
27
+ end
28
+ end
29
+ end
30
+ @c = ::TaticalEagerLoadingModel
31
+ @ds = TaticalEagerLoadingModel.dataset
32
+ MODEL_DB.reset
33
+ end
34
+ after do
35
+ Object.send(:remove_const, :TaticalEagerLoadingModel)
36
+ end
37
+
38
+ it "Dataset#all should set the retrieved_by and reteived_with attributes" do
39
+ ts = @c.all
40
+ ts.map{|x| [x.retrieved_by, x.retrieved_with]}.should == [[@ds,ts], [@ds,ts], [@ds,ts], [@ds,ts]]
41
+ end
42
+
43
+ it "Dataset#all shouldn't raise an error if a Sequel::Model instance is not returned" do
44
+ proc{@c.naked.all}.should_not raise_error
45
+ end
46
+
47
+ it "association getter methods should eagerly load the association if the association isn't cached" do
48
+ MODEL_DB.sqls.length.should == 0
49
+ ts = @c.all
50
+ MODEL_DB.sqls.length.should == 1
51
+ ts.map{|x| x.parent}.should == [ts[2], ts[3], nil, nil]
52
+ MODEL_DB.sqls.length.should == 2
53
+ ts.map{|x| x.children}.should == [[], [], [ts[0]], [ts[1]]]
54
+ MODEL_DB.sqls.length.should == 3
55
+ end
56
+
57
+ it "association getter methods should not eagerly load the association if the association is cached" do
58
+ MODEL_DB.sqls.length.should == 0
59
+ ts = @c.all
60
+ MODEL_DB.sqls.length.should == 1
61
+ ts.map{|x| x.parent}.should == [ts[2], ts[3], nil, nil]
62
+ @ds.should_not_receive(:eager_load)
63
+ ts.map{|x| x.parent}.should == [ts[2], ts[3], nil, nil]
64
+ end
65
+ end
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "Sequel thread_local_timezones extension" do
4
+ after do
5
+ Sequel.default_timezone = nil
6
+ Sequel.thread_application_timezone = nil
7
+ Sequel.thread_database_timezone = nil
8
+ Sequel.thread_typecast_timezone = nil
9
+ end
10
+
11
+ it "should allow specifying thread local timezones via thread_*_timezone=" do
12
+ proc{Sequel.thread_application_timezone = :local}.should_not raise_error
13
+ proc{Sequel.thread_database_timezone = :utc}.should_not raise_error
14
+ proc{Sequel.thread_typecast_timezone = nil}.should_not raise_error
15
+ end
16
+
17
+ it "should use thread local timezone if available" do
18
+ Sequel.thread_application_timezone = :local
19
+ Sequel.application_timezone.should == :local
20
+ Sequel.thread_database_timezone = :utc
21
+ Sequel.database_timezone.should == :utc
22
+ Sequel.thread_typecast_timezone = nil
23
+ Sequel.typecast_timezone.should == nil
24
+ end
25
+
26
+ it "should fallback to default timezone if no thread_local timezone" do
27
+ Sequel.default_timezone = :utc
28
+ Sequel.application_timezone.should == :utc
29
+ Sequel.database_timezone.should == :utc
30
+ Sequel.typecast_timezone.should == :utc
31
+ end
32
+
33
+ it "should use a nil thread_local_timezone if set instead of falling back to the default timezone if thread_local_timezone is set to :nil" do
34
+ Sequel.typecast_timezone = :utc
35
+ Sequel.thread_typecast_timezone = nil
36
+ Sequel.typecast_timezone.should == :utc
37
+ Sequel.thread_typecast_timezone = :nil
38
+ Sequel.typecast_timezone.should == nil
39
+ end
40
+
41
+ it "should be thread safe" do
42
+ [Thread.new{Sequel.thread_application_timezone = :utc; sleep 0.03; Sequel.application_timezone.should == :utc},
43
+ Thread.new{sleep 0.01; Sequel.thread_application_timezone = :local; sleep 0.01; Sequel.application_timezone.should == :local}].each{|x| x.join}
44
+ end
45
+ end
@@ -0,0 +1,150 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::Timestamps" do
4
+ before do
5
+ dc = Object.new
6
+ dc.instance_eval do
7
+ def now
8
+ '2009-08-01'
9
+ end
10
+ end
11
+ Sequel.datetime_class = dc
12
+ @c = Class.new(Sequel::Model(:t))
13
+ @c.class_eval do
14
+ columns :id, :created_at, :updated_at
15
+ plugin :timestamps
16
+ db.reset
17
+ def _refresh(ds); self end
18
+ end
19
+ end
20
+ after do
21
+ Sequel.datetime_class = Time
22
+ end
23
+
24
+ it "should set the create timestamp field on creation" do
25
+ o = @c.create
26
+ @c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
27
+ o.created_at.should == '2009-08-01'
28
+ end
29
+
30
+ it "should set the update timestamp field on update" do
31
+ o = @c.load(:id=>1).save
32
+ @c.db.sqls.should == ["UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
33
+ o.updated_at.should == '2009-08-01'
34
+ end
35
+
36
+ it "should not update the update timestamp on creation" do
37
+ @c.create.updated_at.should == nil
38
+ end
39
+
40
+ it "should use the same value for the creation and update timestamps when creating if the :update_on_create option is given" do
41
+ @c.plugin :timestamps, :update_on_create=>true
42
+ o = @c.create
43
+ @c.db.sqls.length.should == 1
44
+ @c.db.sqls.first.should =~ /INSERT INTO t \((creat|updat)ed_at, (creat|updat)ed_at\) VALUES \('2009-08-01', '2009-08-01'\)/
45
+ o.created_at.should === o.updated_at
46
+ end
47
+
48
+ it "should allow specifying the create timestamp field via the :create option" do
49
+ c = Class.new(Sequel::Model(:t))
50
+ c.class_eval do
51
+ columns :id, :c
52
+ plugin :timestamps, :create=>:c
53
+ db.reset
54
+ def _refresh(ds); self end
55
+ end
56
+ o = c.create
57
+ c.db.sqls.should == ["INSERT INTO t (c) VALUES ('2009-08-01')"]
58
+ o.c.should == '2009-08-01'
59
+ end
60
+
61
+ it "should allow specifying the update timestamp field via the :update option" do
62
+ c = Class.new(Sequel::Model(:t))
63
+ c.class_eval do
64
+ columns :id, :u
65
+ plugin :timestamps, :update=>:u
66
+ db.reset
67
+ def _refresh(ds); self end
68
+ end
69
+ o = c.load(:id=>1).save
70
+ c.db.sqls.should == ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
71
+ o.u.should == '2009-08-01'
72
+ end
73
+
74
+ it "should not raise an error if the model doesn't have the timestamp columns" do
75
+ c = Class.new(Sequel::Model(:t))
76
+ c.class_eval do
77
+ columns :id, :x
78
+ plugin :timestamps
79
+ db.reset
80
+ def _refresh(ds); self end
81
+ end
82
+ c.create(:x=>2)
83
+ c.load(:id=>1, :x=>2).save
84
+ c.db.sqls.should == ["INSERT INTO t (x) VALUES (2)", "UPDATE t SET x = 2 WHERE (id = 1)"]
85
+ end
86
+
87
+ it "should not overwrite an existing create timestamp" do
88
+ o = @c.create(:created_at=>'2009-08-03')
89
+ @c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-03')"]
90
+ o.created_at.should == '2009-08-03'
91
+ end
92
+
93
+ it "should overwrite an existing create timestamp if the :force option is used" do
94
+ @c.plugin :timestamps, :force=>true
95
+ o = @c.create(:created_at=>'2009-08-03')
96
+ @c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
97
+ o.created_at.should == '2009-08-01'
98
+ end
99
+
100
+ it "should have create_timestamp_field give the create timestamp field" do
101
+ @c.create_timestamp_field.should == :created_at
102
+ @c.plugin :timestamps, :create=>:c
103
+ @c.create_timestamp_field.should == :c
104
+ end
105
+
106
+ it "should have update_timestamp_field give the update timestamp field" do
107
+ @c.update_timestamp_field.should == :updated_at
108
+ @c.plugin :timestamps, :update=>:u
109
+ @c.update_timestamp_field.should == :u
110
+ end
111
+
112
+ it "should have create_timestamp_overwrite? give the whether to overwrite an existing create timestamp" do
113
+ @c.create_timestamp_overwrite?.should == false
114
+ @c.plugin :timestamps, :force=>true
115
+ @c.create_timestamp_overwrite?.should == true
116
+ end
117
+
118
+ it "should have set_update_timestamp_on_create? give whether to set the update timestamp on create" do
119
+ @c.set_update_timestamp_on_create?.should == false
120
+ @c.plugin :timestamps, :update_on_create=>true
121
+ @c.set_update_timestamp_on_create?.should == true
122
+ end
123
+
124
+ it "should work with subclasses" do
125
+ c = Class.new(@c)
126
+ o = c.create
127
+ o.created_at.should == '2009-08-01'
128
+ o.updated_at.should == nil
129
+ o = c.load(:id=>1).save
130
+ o.updated_at.should == '2009-08-01'
131
+ c.db.sqls.should == ["INSERT INTO t (created_at) VALUES ('2009-08-01')", "UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
132
+ c.create(:created_at=>'2009-08-03').created_at.should == '2009-08-03'
133
+
134
+ c.class_eval do
135
+ columns :id, :c, :u
136
+ plugin :timestamps, :create=>:c, :update=>:u, :force=>true, :update_on_create=>true
137
+ end
138
+ c2 = Class.new(c)
139
+ c2.db.reset
140
+ o = c2.create
141
+ o.c.should == '2009-08-01'
142
+ o.u.should === o.c
143
+ c2.db.sqls.first.should =~ /INSERT INTO t \([cu], [cu]\) VALUES \('2009-08-01', '2009-08-01'\)/
144
+ c2.db.reset
145
+ o = c2.load(:id=>1).save
146
+ o.u.should == '2009-08-01'
147
+ c2.db.sqls.should == ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
148
+ c2.create(:c=>'2009-08-03').c.should == '2009-08-01'
149
+ end
150
+ end
@@ -0,0 +1,155 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "Touch plugin" do
4
+ before do
5
+ @c = Class.new(Sequel::Model) do
6
+ def _refresh(*); end
7
+ end
8
+ p = proc{def touch_instance_value; touch_association_value; end}
9
+ @Artist = Class.new(@c, &p).set_dataset(:artists)
10
+ @Album = Class.new(@c, &p).set_dataset(:albums)
11
+
12
+ @Artist.columns :id, :updated_at, :modified_on
13
+ @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
14
+
15
+ @Album.columns :id, :updated_at, :modified_on, :artist_id, :original_album_id
16
+ @Album.one_to_many :followup_albums, :class=>@Album, :key=>:original_album_id
17
+ @Album.many_to_one :artist, :class=>@Artist
18
+
19
+ @a = @Artist.load(:id=>1)
20
+ MODEL_DB.reset
21
+ end
22
+
23
+ specify "should default to using Time.now when setting the column values for model instances" do
24
+ c = Class.new(Sequel::Model).set_dataset(:a)
25
+ c.plugin :touch
26
+ c.columns :id, :updated_at
27
+ c.load(:id=>1).touch
28
+ MODEL_DB.sqls.first.should =~ /UPDATE a SET updated_at = '[-0-9 :.]+' WHERE \(id = 1\)/
29
+ end
30
+
31
+ specify "should allow #touch instance method for updating the updated_at column" do
32
+ @Artist.plugin :touch
33
+ @a.touch
34
+ MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
35
+ end
36
+
37
+ specify "should have #touch take an argument for the column to touch" do
38
+ @Artist.plugin :touch
39
+ @a.touch(:modified_on)
40
+ MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)"]
41
+ end
42
+
43
+ specify "should be able to specify the default column to touch in the plugin call using the :column option" do
44
+ @Artist.plugin :touch, :column=>:modified_on
45
+ @a.touch
46
+ MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)"]
47
+ end
48
+
49
+ specify "should be able to specify the default column to touch using the touch_column model accessor" do
50
+ @Artist.plugin :touch
51
+ @Artist.touch_column = :modified_on
52
+ @a.touch
53
+ MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)"]
54
+ end
55
+
56
+ specify "should be able to specify the associations to touch in the plugin call using the :associations option" do
57
+ @Artist.plugin :touch, :associations=>:albums
58
+ @a.touch
59
+ MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
60
+ "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
61
+ end
62
+
63
+ specify "should be able to give an array to the :associations option specifying multiple associations" do
64
+ @Album.plugin :touch, :associations=>[:artist, :followup_albums]
65
+ @Album.load(:id=>4, :artist_id=>1).touch
66
+ MODEL_DB.sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
67
+ MODEL_DB.sqls.sort.should == ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
68
+ "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
69
+ end
70
+
71
+ specify "should be able to give a hash to the :associations option specifying the column to use for each association" do
72
+ @Artist.plugin :touch, :associations=>{:albums=>:modified_on}
73
+ @a.touch
74
+ MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
75
+ "UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
76
+ end
77
+
78
+ specify "should default to using the touch_column as the default touch column for associations" do
79
+ @Artist.plugin :touch, :column=>:modified_on, :associations=>:albums
80
+ @a.touch
81
+ MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)",
82
+ "UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
83
+ end
84
+
85
+ specify "should allow the mixed use of symbols and hashes inside an array for the :associations option" do
86
+ @Album.plugin :touch, :associations=>[:artist, {:followup_albums=>:modified_on}]
87
+ @Album.load(:id=>4, :artist_id=>1).touch
88
+ MODEL_DB.sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
89
+ MODEL_DB.sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
90
+ "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
91
+ end
92
+
93
+ specify "should be able to specify the associations to touch via a touch_associations_method" do
94
+ @Album.plugin :touch
95
+ @Album.touch_associations(:artist, {:followup_albums=>:modified_on})
96
+ @Album.load(:id=>4, :artist_id=>1).touch
97
+ MODEL_DB.sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
98
+ MODEL_DB.sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
99
+ "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
100
+ end
101
+
102
+ specify "should touch associated objects when destroying an object" do
103
+ @Album.plugin :touch
104
+ @Album.touch_associations(:artist, {:followup_albums=>:modified_on})
105
+ @Album.load(:id=>4, :artist_id=>1).destroy
106
+ MODEL_DB.sqls.shift.should == "DELETE FROM albums WHERE (id = 4)"
107
+ MODEL_DB.sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
108
+ "UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
109
+ end
110
+
111
+ specify "should not update a column that doesn't exist" do
112
+ @Album.plugin :touch, :column=>:x
113
+ a = @Album.load(:id=>1)
114
+ a.touch
115
+ MODEL_DB.sqls.should == []
116
+ a.artist_id = 1
117
+ a.touch
118
+ MODEL_DB.sqls.should == ['UPDATE albums SET artist_id = 1 WHERE (id = 1)']
119
+ end
120
+
121
+ specify "should raise an error if given a column argument in touch that doesn't exist" do
122
+ @Artist.plugin :touch
123
+ proc{@a.touch(:x)}.should raise_error(Sequel::Error)
124
+ end
125
+
126
+ specify "should raise an Error when a nonexistent association is given" do
127
+ @Artist.plugin :touch
128
+ proc{@Artist.plugin :touch, :associations=>:blah}.should raise_error(Sequel::Error)
129
+ end
130
+
131
+ specify "should work correctly in subclasses" do
132
+ @Artist.plugin :touch
133
+ c1 = Class.new(@Artist)
134
+ c1.load(:id=>4).touch
135
+ MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"]
136
+ MODEL_DB.reset
137
+
138
+ c1.touch_column = :modified_on
139
+ c1.touch_associations :albums
140
+ c1.load(:id=>1).touch
141
+ MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)",
142
+ "UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
143
+ MODEL_DB.reset
144
+
145
+ @a.touch
146
+ MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
147
+ MODEL_DB.reset
148
+
149
+ @Artist.plugin :touch, :column=>:modified_on, :associations=>:albums
150
+ c2 = Class.new(@Artist)
151
+ c2.load(:id=>4).touch
152
+ MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 4)",
153
+ "UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 4)"]
154
+ end
155
+ end