viking-sequel 3.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3134 -0
- data/COPYING +19 -0
- data/README.rdoc +723 -0
- data/Rakefile +193 -0
- data/bin/sequel +196 -0
- data/doc/advanced_associations.rdoc +644 -0
- data/doc/cheat_sheet.rdoc +218 -0
- data/doc/dataset_basics.rdoc +106 -0
- data/doc/dataset_filtering.rdoc +158 -0
- data/doc/opening_databases.rdoc +296 -0
- data/doc/prepared_statements.rdoc +104 -0
- data/doc/reflection.rdoc +84 -0
- data/doc/release_notes/1.0.txt +38 -0
- data/doc/release_notes/1.1.txt +143 -0
- data/doc/release_notes/1.3.txt +101 -0
- data/doc/release_notes/1.4.0.txt +53 -0
- data/doc/release_notes/1.5.0.txt +155 -0
- data/doc/release_notes/2.0.0.txt +298 -0
- data/doc/release_notes/2.1.0.txt +271 -0
- data/doc/release_notes/2.10.0.txt +328 -0
- data/doc/release_notes/2.11.0.txt +215 -0
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/release_notes/2.2.0.txt +253 -0
- data/doc/release_notes/2.3.0.txt +88 -0
- data/doc/release_notes/2.4.0.txt +106 -0
- data/doc/release_notes/2.5.0.txt +137 -0
- data/doc/release_notes/2.6.0.txt +157 -0
- data/doc/release_notes/2.7.0.txt +166 -0
- data/doc/release_notes/2.8.0.txt +171 -0
- data/doc/release_notes/2.9.0.txt +97 -0
- data/doc/release_notes/3.0.0.txt +221 -0
- data/doc/release_notes/3.1.0.txt +406 -0
- data/doc/release_notes/3.10.0.txt +286 -0
- data/doc/release_notes/3.2.0.txt +268 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/doc/release_notes/3.4.0.txt +325 -0
- data/doc/release_notes/3.5.0.txt +510 -0
- data/doc/release_notes/3.6.0.txt +366 -0
- data/doc/release_notes/3.7.0.txt +179 -0
- data/doc/release_notes/3.8.0.txt +151 -0
- data/doc/release_notes/3.9.0.txt +233 -0
- data/doc/schema.rdoc +36 -0
- data/doc/sharding.rdoc +113 -0
- data/doc/virtual_rows.rdoc +205 -0
- data/lib/sequel.rb +1 -0
- data/lib/sequel/adapters/ado.rb +90 -0
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/amalgalite.rb +176 -0
- data/lib/sequel/adapters/db2.rb +139 -0
- data/lib/sequel/adapters/dbi.rb +113 -0
- data/lib/sequel/adapters/do.rb +188 -0
- data/lib/sequel/adapters/do/mysql.rb +49 -0
- data/lib/sequel/adapters/do/postgres.rb +91 -0
- data/lib/sequel/adapters/do/sqlite.rb +40 -0
- data/lib/sequel/adapters/firebird.rb +283 -0
- data/lib/sequel/adapters/informix.rb +77 -0
- data/lib/sequel/adapters/jdbc.rb +587 -0
- data/lib/sequel/adapters/jdbc/as400.rb +58 -0
- data/lib/sequel/adapters/jdbc/h2.rb +133 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
- data/lib/sequel/adapters/mysql.rb +421 -0
- data/lib/sequel/adapters/odbc.rb +143 -0
- data/lib/sequel/adapters/odbc/mssql.rb +42 -0
- data/lib/sequel/adapters/openbase.rb +64 -0
- data/lib/sequel/adapters/oracle.rb +131 -0
- data/lib/sequel/adapters/postgres.rb +504 -0
- data/lib/sequel/adapters/shared/mssql.rb +490 -0
- data/lib/sequel/adapters/shared/mysql.rb +498 -0
- data/lib/sequel/adapters/shared/oracle.rb +195 -0
- data/lib/sequel/adapters/shared/postgres.rb +830 -0
- data/lib/sequel/adapters/shared/progress.rb +44 -0
- data/lib/sequel/adapters/shared/sqlite.rb +389 -0
- data/lib/sequel/adapters/sqlite.rb +224 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
- data/lib/sequel/connection_pool.rb +99 -0
- data/lib/sequel/connection_pool/sharded_single.rb +84 -0
- data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
- data/lib/sequel/connection_pool/single.rb +29 -0
- data/lib/sequel/connection_pool/threaded.rb +150 -0
- data/lib/sequel/core.rb +293 -0
- data/lib/sequel/core_sql.rb +241 -0
- data/lib/sequel/database.rb +1079 -0
- data/lib/sequel/database/schema_generator.rb +327 -0
- data/lib/sequel/database/schema_methods.rb +203 -0
- data/lib/sequel/database/schema_sql.rb +320 -0
- data/lib/sequel/dataset.rb +32 -0
- data/lib/sequel/dataset/actions.rb +441 -0
- data/lib/sequel/dataset/features.rb +86 -0
- data/lib/sequel/dataset/graph.rb +254 -0
- data/lib/sequel/dataset/misc.rb +119 -0
- data/lib/sequel/dataset/mutation.rb +64 -0
- data/lib/sequel/dataset/prepared_statements.rb +227 -0
- data/lib/sequel/dataset/query.rb +709 -0
- data/lib/sequel/dataset/sql.rb +996 -0
- data/lib/sequel/exceptions.rb +51 -0
- data/lib/sequel/extensions/blank.rb +43 -0
- data/lib/sequel/extensions/inflector.rb +242 -0
- data/lib/sequel/extensions/looser_typecasting.rb +21 -0
- data/lib/sequel/extensions/migration.rb +239 -0
- data/lib/sequel/extensions/named_timezones.rb +61 -0
- data/lib/sequel/extensions/pagination.rb +100 -0
- data/lib/sequel/extensions/pretty_table.rb +82 -0
- data/lib/sequel/extensions/query.rb +52 -0
- data/lib/sequel/extensions/schema_dumper.rb +271 -0
- data/lib/sequel/extensions/sql_expr.rb +122 -0
- data/lib/sequel/extensions/string_date_time.rb +46 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
- data/lib/sequel/metaprogramming.rb +9 -0
- data/lib/sequel/model.rb +120 -0
- data/lib/sequel/model/associations.rb +1514 -0
- data/lib/sequel/model/base.rb +1069 -0
- data/lib/sequel/model/default_inflections.rb +45 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/sequel/model/exceptions.rb +21 -0
- data/lib/sequel/model/inflections.rb +162 -0
- data/lib/sequel/model/plugins.rb +70 -0
- data/lib/sequel/plugins/active_model.rb +59 -0
- data/lib/sequel/plugins/association_dependencies.rb +103 -0
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/boolean_readers.rb +53 -0
- data/lib/sequel/plugins/caching.rb +141 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
- data/lib/sequel/plugins/composition.rb +138 -0
- data/lib/sequel/plugins/force_encoding.rb +72 -0
- data/lib/sequel/plugins/hook_class_methods.rb +126 -0
- data/lib/sequel/plugins/identity_map.rb +116 -0
- data/lib/sequel/plugins/instance_filters.rb +98 -0
- data/lib/sequel/plugins/instance_hooks.rb +57 -0
- data/lib/sequel/plugins/lazy_attributes.rb +77 -0
- data/lib/sequel/plugins/many_through_many.rb +208 -0
- data/lib/sequel/plugins/nested_attributes.rb +206 -0
- data/lib/sequel/plugins/optimistic_locking.rb +81 -0
- data/lib/sequel/plugins/rcte_tree.rb +281 -0
- data/lib/sequel/plugins/schema.rb +66 -0
- data/lib/sequel/plugins/serialization.rb +166 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
- data/lib/sequel/plugins/subclasses.rb +45 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
- data/lib/sequel/plugins/timestamps.rb +87 -0
- data/lib/sequel/plugins/touch.rb +118 -0
- data/lib/sequel/plugins/typecast_on_load.rb +72 -0
- data/lib/sequel/plugins/validation_class_methods.rb +405 -0
- data/lib/sequel/plugins/validation_helpers.rb +223 -0
- data/lib/sequel/sql.rb +1020 -0
- data/lib/sequel/timezones.rb +161 -0
- data/lib/sequel/version.rb +12 -0
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/firebird_spec.rb +407 -0
- data/spec/adapters/informix_spec.rb +97 -0
- data/spec/adapters/mssql_spec.rb +403 -0
- data/spec/adapters/mysql_spec.rb +1019 -0
- data/spec/adapters/oracle_spec.rb +286 -0
- data/spec/adapters/postgres_spec.rb +969 -0
- data/spec/adapters/spec_helper.rb +51 -0
- data/spec/adapters/sqlite_spec.rb +432 -0
- data/spec/core/connection_pool_spec.rb +808 -0
- data/spec/core/core_sql_spec.rb +417 -0
- data/spec/core/database_spec.rb +1662 -0
- data/spec/core/dataset_spec.rb +3827 -0
- data/spec/core/expression_filters_spec.rb +595 -0
- data/spec/core/object_graph_spec.rb +296 -0
- data/spec/core/schema_generator_spec.rb +159 -0
- data/spec/core/schema_spec.rb +830 -0
- data/spec/core/spec_helper.rb +56 -0
- data/spec/core/version_spec.rb +7 -0
- data/spec/extensions/active_model_spec.rb +76 -0
- data/spec/extensions/association_dependencies_spec.rb +127 -0
- data/spec/extensions/association_proxies_spec.rb +50 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/boolean_readers_spec.rb +92 -0
- data/spec/extensions/caching_spec.rb +250 -0
- data/spec/extensions/class_table_inheritance_spec.rb +252 -0
- data/spec/extensions/composition_spec.rb +194 -0
- data/spec/extensions/force_encoding_spec.rb +117 -0
- data/spec/extensions/hook_class_methods_spec.rb +470 -0
- data/spec/extensions/identity_map_spec.rb +202 -0
- data/spec/extensions/inflector_spec.rb +181 -0
- data/spec/extensions/instance_filters_spec.rb +55 -0
- data/spec/extensions/instance_hooks_spec.rb +133 -0
- data/spec/extensions/lazy_attributes_spec.rb +153 -0
- data/spec/extensions/looser_typecasting_spec.rb +39 -0
- data/spec/extensions/many_through_many_spec.rb +884 -0
- data/spec/extensions/migration_spec.rb +332 -0
- data/spec/extensions/named_timezones_spec.rb +72 -0
- data/spec/extensions/nested_attributes_spec.rb +396 -0
- data/spec/extensions/optimistic_locking_spec.rb +100 -0
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/extensions/rcte_tree_spec.rb +205 -0
- data/spec/extensions/schema_dumper_spec.rb +357 -0
- data/spec/extensions/schema_spec.rb +127 -0
- data/spec/extensions/serialization_spec.rb +209 -0
- data/spec/extensions/single_table_inheritance_spec.rb +96 -0
- data/spec/extensions/spec_helper.rb +91 -0
- data/spec/extensions/sql_expr_spec.rb +89 -0
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/extensions/subclasses_spec.rb +52 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
- data/spec/extensions/thread_local_timezones_spec.rb +45 -0
- data/spec/extensions/timestamps_spec.rb +150 -0
- data/spec/extensions/touch_spec.rb +155 -0
- data/spec/extensions/typecast_on_load_spec.rb +69 -0
- data/spec/extensions/validation_class_methods_spec.rb +984 -0
- data/spec/extensions/validation_helpers_spec.rb +438 -0
- data/spec/integration/associations_test.rb +281 -0
- data/spec/integration/database_test.rb +26 -0
- data/spec/integration/dataset_test.rb +963 -0
- data/spec/integration/eager_loader_test.rb +734 -0
- data/spec/integration/model_test.rb +130 -0
- data/spec/integration/plugin_test.rb +814 -0
- data/spec/integration/prepared_statement_test.rb +213 -0
- data/spec/integration/schema_test.rb +361 -0
- data/spec/integration/spec_helper.rb +73 -0
- data/spec/integration/timezone_test.rb +55 -0
- data/spec/integration/transaction_test.rb +122 -0
- data/spec/integration/type_test.rb +96 -0
- data/spec/model/association_reflection_spec.rb +175 -0
- data/spec/model/associations_spec.rb +2633 -0
- data/spec/model/base_spec.rb +418 -0
- data/spec/model/dataset_methods_spec.rb +78 -0
- data/spec/model/eager_loading_spec.rb +1391 -0
- data/spec/model/hooks_spec.rb +240 -0
- data/spec/model/inflector_spec.rb +26 -0
- data/spec/model/model_spec.rb +593 -0
- data/spec/model/plugins_spec.rb +236 -0
- data/spec/model/record_spec.rb +1500 -0
- data/spec/model/spec_helper.rb +97 -0
- data/spec/model/validations_spec.rb +153 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec_config.rb.example +10 -0
- 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
|