sequel 3.21.0 → 3.31.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.
- data/CHANGELOG +485 -3
- data/README.rdoc +20 -6
- data/Rakefile +37 -19
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +249 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +89 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +129 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +5 -7
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +45 -0
- data/lib/sequel/adapters/jdbc/derby.rb +247 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +56 -29
- data/lib/sequel/adapters/jdbc/hsqldb.rb +170 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -11
- data/lib/sequel/adapters/jdbc/oracle.rb +81 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +9 -13
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -6
- data/lib/sequel/adapters/jdbc/sqlserver.rb +71 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +231 -78
- data/lib/sequel/adapters/mock.rb +335 -0
- data/lib/sequel/adapters/mysql.rb +82 -184
- data/lib/sequel/adapters/mysql2.rb +26 -25
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +1 -6
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +351 -53
- data/lib/sequel/adapters/postgres.rb +194 -33
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +321 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +231 -106
- data/lib/sequel/adapters/shared/mysql.rb +181 -63
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +231 -41
- data/lib/sequel/adapters/shared/postgres.rb +214 -82
- data/lib/sequel/adapters/shared/progress.rb +4 -7
- data/lib/sequel/adapters/shared/sqlite.rb +201 -57
- data/lib/sequel/adapters/sqlite.rb +29 -21
- data/lib/sequel/adapters/swift/mysql.rb +12 -7
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +160 -19
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +104 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +17 -7
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +231 -76
- data/lib/sequel/dataset/features.rb +91 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +48 -27
- data/lib/sequel/dataset/query.rb +236 -43
- data/lib/sequel/dataset/sql.rb +665 -253
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1020 -337
- data/lib/sequel/model/base.rb +414 -132
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +88 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +109 -52
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +111 -29
- data/spec/adapters/mysql_spec.rb +135 -123
- data/spec/adapters/oracle_spec.rb +49 -77
- data/spec/adapters/postgres_spec.rb +267 -78
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +21 -30
- data/spec/core/database_spec.rb +788 -512
- data/spec/core/dataset_spec.rb +1073 -1053
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +419 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_autoreloading_spec.rb +1 -10
- data/spec/extensions/association_dependencies_spec.rb +2 -12
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/caching_spec.rb +23 -50
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/hook_class_methods_spec.rb +65 -91
- data/spec/extensions/identity_map_spec.rb +114 -22
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +53 -0
- data/spec/extensions/json_serializer_spec.rb +4 -5
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +17 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/migration_spec.rb +35 -32
- data/spec/extensions/named_timezones_spec.rb +23 -3
- data/spec/extensions/nested_attributes_spec.rb +97 -88
- data/spec/extensions/optimistic_locking_spec.rb +9 -20
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +53 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +1 -6
- data/spec/extensions/rcte_tree_spec.rb +41 -43
- data/spec/extensions/schema_dumper_spec.rb +5 -8
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +72 -43
- data/spec/extensions/sharding_spec.rb +66 -140
- data/spec/extensions/single_table_inheritance_spec.rb +18 -29
- data/spec/extensions/spec_helper.rb +13 -61
- data/spec/extensions/sql_expr_spec.rb +20 -60
- data/spec/extensions/tactical_eager_loading_spec.rb +9 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +537 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +461 -65
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +212 -122
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +865 -662
- data/spec/model/base_spec.rb +275 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +222 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +381 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +115 -73
|
@@ -4,86 +4,46 @@ describe "Sequel sql_expr extension" do
|
|
|
4
4
|
specify "Object#sql_expr should wrap the object in a GenericComplexExpression" do
|
|
5
5
|
o = Object.new
|
|
6
6
|
s = o.sql_expr
|
|
7
|
-
s.should
|
|
8
|
-
s.
|
|
9
|
-
s.
|
|
10
|
-
(s
|
|
11
|
-
(
|
|
12
|
-
(
|
|
13
|
-
s.
|
|
14
|
-
s.
|
|
15
|
-
s.
|
|
16
|
-
s.
|
|
17
|
-
s.desc.should be_a_kind_of(Sequel::SQL::OrderedExpression)
|
|
18
|
-
s.sql_string.should be_a_kind_of(Sequel::SQL::StringExpression)
|
|
7
|
+
s.should == Sequel::SQL::GenericComplexExpression.new(:NOOP, o)
|
|
8
|
+
(s+1).should == Sequel::SQL::NumericExpression.new(:+, s, 1)
|
|
9
|
+
(s & true).should == Sequel::SQL::BooleanExpression.new(:AND, s, true)
|
|
10
|
+
(s < 1).should == Sequel::SQL::BooleanExpression.new(:<, s, 1)
|
|
11
|
+
s.sql_subscript(1).should == Sequel::SQL::Subscript.new(s, [1])
|
|
12
|
+
s.like('a').should == Sequel::SQL::BooleanExpression.new(:LIKE, s, 'a')
|
|
13
|
+
s.as(:a).should == Sequel::SQL::AliasedExpression.new(s, :a)
|
|
14
|
+
s.cast(Integer).should == Sequel::SQL::Cast.new(s, Integer)
|
|
15
|
+
s.desc.should == Sequel::SQL::OrderedExpression.new(s, true)
|
|
16
|
+
s.sql_string.should == Sequel::SQL::StringExpression.new(:NOOP, s)
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
specify "Numeric#sql_expr should wrap the object in a NumericExpression" do
|
|
22
|
-
[1, 2.0, 2^
|
|
23
|
-
|
|
24
|
-
s.should be_a_kind_of(Sequel::SQL::NumericExpression)
|
|
25
|
-
s.op.should == :NOOP
|
|
26
|
-
s.args.should == [o]
|
|
20
|
+
[1, 2.0, 2^70, BigDecimal.new('1.0')].each do |o|
|
|
21
|
+
o.sql_expr.should == Sequel::SQL::NumericExpression.new(:NOOP, o)
|
|
27
22
|
end
|
|
28
23
|
end
|
|
29
24
|
|
|
30
25
|
specify "String#sql_expr should wrap the object in a StringExpression" do
|
|
31
|
-
|
|
32
|
-
s = o.sql_expr
|
|
33
|
-
s.should be_a_kind_of(Sequel::SQL::StringExpression)
|
|
34
|
-
s.op.should == :NOOP
|
|
35
|
-
s.args.should == [o]
|
|
26
|
+
"".sql_expr.should == Sequel::SQL::StringExpression.new(:NOOP, "")
|
|
36
27
|
end
|
|
37
28
|
|
|
38
29
|
specify "NilClass, TrueClass, and FalseClass#sql_expr should wrap the object in a BooleanExpression" do
|
|
39
30
|
[nil, true, false].each do |o|
|
|
40
|
-
|
|
41
|
-
s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
|
|
42
|
-
s.op.should == :NOOP
|
|
43
|
-
s.args.should == [o]
|
|
31
|
+
o.sql_expr.should == Sequel::SQL::BooleanExpression.new(:NOOP, o)
|
|
44
32
|
end
|
|
45
33
|
end
|
|
46
34
|
|
|
47
35
|
specify "Proc#sql_expr should should treat the object as a virtual row block" do
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
s = proc{a__b}.sql_expr
|
|
53
|
-
s.should be_a_kind_of(Sequel::SQL::QualifiedIdentifier)
|
|
54
|
-
s.table.should == "a"
|
|
55
|
-
s.column.should == "b"
|
|
56
|
-
|
|
57
|
-
s = proc{a(b)}.sql_expr
|
|
58
|
-
s.should be_a_kind_of(Sequel::SQL::Function)
|
|
59
|
-
s.f.should == :a
|
|
60
|
-
s.args.length.should == 1
|
|
61
|
-
s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
|
|
62
|
-
s.args.first.value.should == :b
|
|
36
|
+
proc{a}.sql_expr.should == Sequel::SQL::Identifier.new(:a)
|
|
37
|
+
proc{a__b}.sql_expr.should == Sequel::SQL::QualifiedIdentifier.new('a', 'b')
|
|
38
|
+
proc{a(b)}.sql_expr.should == Sequel::SQL::Function.new(:a, Sequel::SQL::Identifier.new(:b))
|
|
63
39
|
end
|
|
64
40
|
|
|
65
41
|
specify "Proc#sql_expr should should wrap the object in a GenericComplexExpression if the object is not already an expression" do
|
|
66
|
-
|
|
67
|
-
s.should be_a_kind_of(Sequel::SQL::GenericComplexExpression)
|
|
68
|
-
s.op.should == :NOOP
|
|
69
|
-
s.args.should == [1]
|
|
42
|
+
proc{1}.sql_expr.should == Sequel::SQL::GenericComplexExpression.new(:NOOP, 1)
|
|
70
43
|
end
|
|
71
44
|
|
|
72
45
|
specify "Proc#sql_expr should should convert a hash or array of two element arrays to a BooleanExpression" do
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
s.op.should == :"="
|
|
76
|
-
s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
|
|
77
|
-
s.args.first.value.should == :a
|
|
78
|
-
s.args.last.should be_a_kind_of(Sequel::SQL::Identifier)
|
|
79
|
-
s.args.last.value.should == :b
|
|
80
|
-
|
|
81
|
-
s = proc{[[a,b]]}.sql_expr
|
|
82
|
-
s.should be_a_kind_of(Sequel::SQL::BooleanExpression)
|
|
83
|
-
s.op.should == :"="
|
|
84
|
-
s.args.first.should be_a_kind_of(Sequel::SQL::Identifier)
|
|
85
|
-
s.args.first.value.should == :a
|
|
86
|
-
s.args.last.should be_a_kind_of(Sequel::SQL::Identifier)
|
|
87
|
-
s.args.last.value.should == :b
|
|
46
|
+
proc{{a=>b}}.sql_expr.should == Sequel::SQL::BooleanExpression.new(:'=', Sequel::SQL::Identifier.new(:a), Sequel::SQL::Identifier.new(:b))
|
|
47
|
+
proc{[[a,b]]}.sql_expr.should == Sequel::SQL::BooleanExpression.new(:'=', Sequel::SQL::Identifier.new(:a), Sequel::SQL::Identifier.new(:b))
|
|
88
48
|
end
|
|
89
49
|
end
|
|
@@ -7,23 +7,13 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
|
|
|
7
7
|
columns :id, :parent_id
|
|
8
8
|
many_to_one :parent, :class=>self
|
|
9
9
|
one_to_many :children, :class=>self, :key=>:parent_id
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
10
|
+
dataset._fetch = proc do |sql|
|
|
11
|
+
if sql !~ /WHERE/
|
|
12
|
+
[{:id=>1, :parent_id=>101}, {:id=>2, :parent_id=>102}, {:id=>101, :parent_id=>nil}, {:id=>102, :parent_id=>nil}]
|
|
13
|
+
elsif sql =~ /WHERE.*\bid IN \(([\d, ]*)\)/
|
|
14
|
+
$1.split(', ').map{|x| {:id=>x.to_i, :parent_id=>nil}}
|
|
15
|
+
elsif sql =~ /WHERE.*\bparent_id IN \(([\d, ]*)\)/
|
|
16
|
+
$1.split(', ').map{|x| {:id=>x.to_i - 100, :parent_id=>x.to_i} if x.to_i > 100}.compact
|
|
27
17
|
end
|
|
28
18
|
end
|
|
29
19
|
end
|
|
@@ -49,9 +39,9 @@ describe "Sequel::Plugins::TacticalEagerLoading" do
|
|
|
49
39
|
ts = @c.all
|
|
50
40
|
MODEL_DB.sqls.length.should == 1
|
|
51
41
|
ts.map{|x| x.parent}.should == [ts[2], ts[3], nil, nil]
|
|
52
|
-
MODEL_DB.sqls.length.should ==
|
|
42
|
+
MODEL_DB.sqls.length.should == 1
|
|
53
43
|
ts.map{|x| x.children}.should == [[], [], [ts[0]], [ts[1]]]
|
|
54
|
-
MODEL_DB.sqls.length.should ==
|
|
44
|
+
MODEL_DB.sqls.length.should == 1
|
|
55
45
|
end
|
|
56
46
|
|
|
57
47
|
it "association getter methods should not eagerly load the association if the association is cached" do
|
|
@@ -39,7 +39,27 @@ describe "Sequel thread_local_timezones extension" do
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
it "should be thread safe" do
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
|
43
|
+
tz1, tz2 = nil, nil
|
|
44
|
+
t1 = Thread.new do
|
|
45
|
+
Sequel.thread_application_timezone = :utc
|
|
46
|
+
q2.push nil
|
|
47
|
+
q.pop
|
|
48
|
+
tz1 = Sequel.application_timezone
|
|
49
|
+
end
|
|
50
|
+
t2 = Thread.new do
|
|
51
|
+
Sequel.thread_application_timezone = :local
|
|
52
|
+
q2.push nil
|
|
53
|
+
q1.pop
|
|
54
|
+
tz2 = Sequel.application_timezone
|
|
55
|
+
end
|
|
56
|
+
q2.pop
|
|
57
|
+
q2.pop
|
|
58
|
+
q.push nil
|
|
59
|
+
q1.push nil
|
|
60
|
+
t1.join
|
|
61
|
+
t2.join
|
|
62
|
+
tz1.should == :utc
|
|
63
|
+
tz2.should == :local
|
|
44
64
|
end
|
|
45
65
|
end
|
|
@@ -13,9 +13,10 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
13
13
|
@c.class_eval do
|
|
14
14
|
columns :id, :created_at, :updated_at
|
|
15
15
|
plugin :timestamps
|
|
16
|
+
def _save_refresh(*) end
|
|
16
17
|
db.reset
|
|
17
|
-
def _refresh(ds); self end
|
|
18
18
|
end
|
|
19
|
+
@c.dataset.autoid = nil
|
|
19
20
|
end
|
|
20
21
|
after do
|
|
21
22
|
Sequel.datetime_class = Time
|
|
@@ -40,8 +41,9 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
40
41
|
it "should use the same value for the creation and update timestamps when creating if the :update_on_create option is given" do
|
|
41
42
|
@c.plugin :timestamps, :update_on_create=>true
|
|
42
43
|
o = @c.create
|
|
43
|
-
@c.db.sqls
|
|
44
|
-
|
|
44
|
+
sqls = @c.db.sqls
|
|
45
|
+
sqls.shift.should =~ /INSERT INTO t \((creat|updat)ed_at, (creat|updat)ed_at\) VALUES \('2009-08-01', '2009-08-01'\)/
|
|
46
|
+
sqls.should == []
|
|
45
47
|
o.created_at.should === o.updated_at
|
|
46
48
|
end
|
|
47
49
|
|
|
@@ -50,8 +52,7 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
50
52
|
c.class_eval do
|
|
51
53
|
columns :id, :c
|
|
52
54
|
plugin :timestamps, :create=>:c
|
|
53
|
-
|
|
54
|
-
def _refresh(ds); self end
|
|
55
|
+
def _save_refresh(*) end
|
|
55
56
|
end
|
|
56
57
|
o = c.create
|
|
57
58
|
c.db.sqls.should == ["INSERT INTO t (c) VALUES ('2009-08-01')"]
|
|
@@ -64,7 +65,6 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
64
65
|
columns :id, :u
|
|
65
66
|
plugin :timestamps, :update=>:u
|
|
66
67
|
db.reset
|
|
67
|
-
def _refresh(ds); self end
|
|
68
68
|
end
|
|
69
69
|
o = c.load(:id=>1).save
|
|
70
70
|
c.db.sqls.should == ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
|
|
@@ -2,9 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe Sequel::Model, "to_dot extension" do
|
|
4
4
|
def dot(ds)
|
|
5
|
-
|
|
6
|
-
ds.send(:_to_dot, a, "", 0, ds, 0)
|
|
7
|
-
a[2..-1]
|
|
5
|
+
Sequel::ToDot.new(ds).instance_variable_get(:@dot)[4...-1]
|
|
8
6
|
end
|
|
9
7
|
|
|
10
8
|
before do
|
|
@@ -13,14 +11,13 @@ describe Sequel::Model, "to_dot extension" do
|
|
|
13
11
|
end
|
|
14
12
|
|
|
15
13
|
it "should output a string suitable for input to the graphviz dot program" do
|
|
16
|
-
@ds.to_dot.should == (<<END
|
|
14
|
+
@ds.to_dot.should == (<<END).strip
|
|
17
15
|
digraph G {
|
|
18
16
|
0 [label="self"];
|
|
19
17
|
0 -> 1 [label=""];
|
|
20
18
|
1 [label="Dataset"];
|
|
21
19
|
}
|
|
22
20
|
END
|
|
23
|
-
).strip
|
|
24
21
|
end
|
|
25
22
|
|
|
26
23
|
it "should handle an empty dataset" do
|
|
@@ -123,7 +120,7 @@ END
|
|
|
123
120
|
end
|
|
124
121
|
|
|
125
122
|
it "should handle SQL::Subscript" do
|
|
126
|
-
dot(@ds.select(:a.sql_subscript(1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript
|
|
123
|
+
dot(@ds.select(:a.sql_subscript(1))).should == ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
|
|
127
124
|
end
|
|
128
125
|
|
|
129
126
|
it "should handle SQL::WindowFunction" do
|
|
@@ -135,7 +132,7 @@ END
|
|
|
135
132
|
end
|
|
136
133
|
|
|
137
134
|
it "should handle JOIN ON" do
|
|
138
|
-
dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"
|
|
135
|
+
dot(@ds.from(:a).join(:d, :b=>:c)).should == ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"ComplexExpression: =\"];", "7 -> 8 [label=\"0\"];", "8 [label=\"QualifiedIdentifier\"];", "8 -> 9 [label=\"table\"];", "9 [label=\"\\\"d\\\"\"];", "8 -> 10 [label=\"column\"];", "10 [label=\"\\\"b\\\"\"];", "7 -> 11 [label=\"1\"];", "11 [label=\"QualifiedIdentifier\"];", "11 -> 12 [label=\"table\"];", "12 [label=\"\\\"a\\\"\"];", "11 -> 13 [label=\"column\"];", "13 [label=\"\\\"c\\\"\"];"]
|
|
139
136
|
end
|
|
140
137
|
|
|
141
138
|
it "should handle JOIN USING" do
|
|
@@ -2,9 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "Touch plugin" do
|
|
4
4
|
before do
|
|
5
|
-
@c = Class.new(Sequel::Model)
|
|
6
|
-
def _refresh(*); end
|
|
7
|
-
end
|
|
5
|
+
@c = Class.new(Sequel::Model)
|
|
8
6
|
p = proc{def touch_instance_value; touch_association_value; end}
|
|
9
7
|
@Artist = Class.new(@c, &p).set_dataset(:artists)
|
|
10
8
|
@Album = Class.new(@c, &p).set_dataset(:albums)
|
|
@@ -63,8 +61,9 @@ describe "Touch plugin" do
|
|
|
63
61
|
specify "should be able to give an array to the :associations option specifying multiple associations" do
|
|
64
62
|
@Album.plugin :touch, :associations=>[:artist, :followup_albums]
|
|
65
63
|
@Album.load(:id=>4, :artist_id=>1).touch
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
sqls = MODEL_DB.sqls
|
|
65
|
+
sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
|
|
66
|
+
sqls.sort.should == ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
68
67
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
69
68
|
end
|
|
70
69
|
|
|
@@ -85,8 +84,9 @@ describe "Touch plugin" do
|
|
|
85
84
|
specify "should allow the mixed use of symbols and hashes inside an array for the :associations option" do
|
|
86
85
|
@Album.plugin :touch, :associations=>[:artist, {:followup_albums=>:modified_on}]
|
|
87
86
|
@Album.load(:id=>4, :artist_id=>1).touch
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
sqls = MODEL_DB.sqls
|
|
88
|
+
sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
|
|
89
|
+
sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
90
90
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
91
91
|
end
|
|
92
92
|
|
|
@@ -94,8 +94,9 @@ describe "Touch plugin" do
|
|
|
94
94
|
@Album.plugin :touch
|
|
95
95
|
@Album.touch_associations(:artist, {:followup_albums=>:modified_on})
|
|
96
96
|
@Album.load(:id=>4, :artist_id=>1).touch
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
sqls = MODEL_DB.sqls
|
|
98
|
+
sqls.shift.should == "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
|
|
99
|
+
sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
99
100
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
100
101
|
end
|
|
101
102
|
|
|
@@ -103,8 +104,9 @@ describe "Touch plugin" do
|
|
|
103
104
|
@Album.plugin :touch
|
|
104
105
|
@Album.touch_associations(:artist, {:followup_albums=>:modified_on})
|
|
105
106
|
@Album.load(:id=>4, :artist_id=>1).destroy
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
sqls = MODEL_DB.sqls
|
|
108
|
+
sqls.shift.should == "DELETE FROM albums WHERE (id = 4)"
|
|
109
|
+
sqls.sort.should == ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
108
110
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
109
111
|
end
|
|
110
112
|
|
|
@@ -133,18 +135,15 @@ describe "Touch plugin" do
|
|
|
133
135
|
c1 = Class.new(@Artist)
|
|
134
136
|
c1.load(:id=>4).touch
|
|
135
137
|
MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"]
|
|
136
|
-
MODEL_DB.reset
|
|
137
138
|
|
|
138
139
|
c1.touch_column = :modified_on
|
|
139
140
|
c1.touch_associations :albums
|
|
140
141
|
c1.load(:id=>1).touch
|
|
141
142
|
MODEL_DB.sqls.should == ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
142
143
|
"UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
|
|
143
|
-
MODEL_DB.reset
|
|
144
144
|
|
|
145
145
|
@a.touch
|
|
146
146
|
MODEL_DB.sqls.should == ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
147
|
-
MODEL_DB.reset
|
|
148
147
|
|
|
149
148
|
@Artist.plugin :touch, :column=>:modified_on, :associations=>:albums
|
|
150
149
|
c2 = Class.new(@Artist)
|
|
@@ -7,26 +7,11 @@ describe Sequel::Model, "tree plugin" do
|
|
|
7
7
|
c.class_eval do
|
|
8
8
|
def self.name; 'Node'; end
|
|
9
9
|
columns :id, :name, :parent_id, :i, :pi
|
|
10
|
+
plugin :tree, opts
|
|
10
11
|
end
|
|
11
|
-
ds = c.dataset
|
|
12
|
-
class << ds
|
|
13
|
-
attr_accessor :row_sets
|
|
14
|
-
def fetch_rows(sql)
|
|
15
|
-
@db << sql
|
|
16
|
-
if rs = row_sets.shift
|
|
17
|
-
rs.each{|row| yield row}
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
c.plugin :tree, opts
|
|
22
12
|
c
|
|
23
13
|
end
|
|
24
14
|
|
|
25
|
-
def y(c, *hs)
|
|
26
|
-
ds = c.dataset
|
|
27
|
-
ds.row_sets = hs
|
|
28
|
-
end
|
|
29
|
-
|
|
30
15
|
before do
|
|
31
16
|
@c = klass
|
|
32
17
|
@ds = @c.dataset
|
|
@@ -71,7 +56,7 @@ describe Sequel::Model, "tree plugin" do
|
|
|
71
56
|
end
|
|
72
57
|
|
|
73
58
|
it "should have roots return an array of the tree's roots" do
|
|
74
|
-
|
|
59
|
+
@ds._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
|
|
75
60
|
@c.roots.should == [@c.load(:id=>1, :parent_id=>nil, :name=>'r')]
|
|
76
61
|
@db.sqls.should == ["SELECT * FROM nodes WHERE (parent_id IS NULL)"]
|
|
77
62
|
end
|
|
@@ -81,14 +66,14 @@ describe Sequel::Model, "tree plugin" do
|
|
|
81
66
|
end
|
|
82
67
|
|
|
83
68
|
it "should have ancestors return the ancestors of the current node" do
|
|
84
|
-
|
|
69
|
+
@ds._fetch = [[{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}]]
|
|
85
70
|
@o.ancestors.should == [@c.load(:id=>1, :parent_id=>5, :name=>'r'), @c.load(:id=>5, :parent_id=>nil, :name=>'r2')]
|
|
86
71
|
@db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
|
|
87
72
|
"SELECT * FROM nodes WHERE (nodes.id = 5) LIMIT 1"]
|
|
88
73
|
end
|
|
89
74
|
|
|
90
75
|
it "should have descendants return the descendants of the current node" do
|
|
91
|
-
|
|
76
|
+
@ds._fetch = [[{:id=>3, :parent_id=>2, :name=>'r'}, {:id=>4, :parent_id=>2, :name=>'r2'}], [{:id=>5, :parent_id=>4, :name=>'r3'}], []]
|
|
92
77
|
@o.descendants.should == [@c.load(:id=>3, :parent_id=>2, :name=>'r'), @c.load(:id=>4, :parent_id=>2, :name=>'r2'), @c.load(:id=>5, :parent_id=>4, :name=>'r3')]
|
|
93
78
|
@db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.parent_id = 2)",
|
|
94
79
|
"SELECT * FROM nodes WHERE (nodes.parent_id = 3)",
|
|
@@ -97,7 +82,7 @@ describe Sequel::Model, "tree plugin" do
|
|
|
97
82
|
end
|
|
98
83
|
|
|
99
84
|
it "should have root return the root of the current node" do
|
|
100
|
-
|
|
85
|
+
@ds._fetch = [[{:id=>1, :parent_id=>5, :name=>'r'}], [{:id=>5, :parent_id=>nil, :name=>'r2'}]]
|
|
101
86
|
@o.root.should == @c.load(:id=>5, :parent_id=>nil, :name=>'r2')
|
|
102
87
|
@db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
|
|
103
88
|
"SELECT * FROM nodes WHERE (nodes.id = 5) LIMIT 1"]
|
|
@@ -113,14 +98,14 @@ describe Sequel::Model, "tree plugin" do
|
|
|
113
98
|
end
|
|
114
99
|
|
|
115
100
|
it "should have self_and_siblings return the children of the current node's parent" do
|
|
116
|
-
|
|
101
|
+
@ds._fetch = [[{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup]]
|
|
117
102
|
@o.self_and_siblings.should == [@c.load(:id=>7, :parent_id=>1, :name=>'r2'), @o]
|
|
118
103
|
@db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
|
|
119
104
|
"SELECT * FROM nodes WHERE (nodes.parent_id = 1)"]
|
|
120
105
|
end
|
|
121
106
|
|
|
122
107
|
it "should have siblings return the children of the current node's parent, except for the current node" do
|
|
123
|
-
|
|
108
|
+
@ds._fetch = [[{:id=>1, :parent_id=>3, :name=>'r'}], [{:id=>7, :parent_id=>1, :name=>'r2'}, @o.values.dup]]
|
|
124
109
|
@o.siblings.should == [@c.load(:id=>7, :parent_id=>1, :name=>'r2')]
|
|
125
110
|
@db.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 1) LIMIT 1",
|
|
126
111
|
"SELECT * FROM nodes WHERE (nodes.parent_id = 1)"]
|
|
@@ -132,23 +117,23 @@ describe Sequel::Model, "tree plugin" do
|
|
|
132
117
|
end
|
|
133
118
|
|
|
134
119
|
it "should have root class method return the root" do
|
|
135
|
-
|
|
120
|
+
@c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
|
|
136
121
|
@c.root.should == @c.load(:id=>1, :parent_id=>nil, :name=>'r')
|
|
137
122
|
end
|
|
138
123
|
|
|
139
124
|
it "prevents creating a second root" do
|
|
140
|
-
|
|
125
|
+
@c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
|
|
141
126
|
lambda { @c.create }.should raise_error(Sequel::Plugins::Tree::TreeMultipleRootError)
|
|
142
127
|
end
|
|
143
128
|
|
|
144
129
|
it "errors when promoting an existing record to a second root" do
|
|
145
|
-
|
|
130
|
+
@c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
|
|
146
131
|
n = @c.load(:id => 2, :parent_id => 1)
|
|
147
132
|
lambda { n.update(:parent_id => nil) }.should raise_error(Sequel::Plugins::Tree::TreeMultipleRootError)
|
|
148
133
|
end
|
|
149
134
|
|
|
150
135
|
it "allows updating existing root" do
|
|
151
|
-
|
|
136
|
+
@c.dataset._fetch = [{:id=>1, :parent_id=>nil, :name=>'r'}]
|
|
152
137
|
lambda { @c.root.update(:name => 'fdsa') }.should_not raise_error
|
|
153
138
|
end
|
|
154
139
|
end
|
|
@@ -2,22 +2,17 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe Sequel::Model, "TypecastOnLoad plugin" do
|
|
4
4
|
before do
|
|
5
|
-
@db = Sequel
|
|
5
|
+
@db = Sequel.mock(:fetch=>{:id=>1, :b=>"1", :y=>"0"}, :columns=>[:id, :b, :y])
|
|
6
6
|
def @db.schema(*args)
|
|
7
7
|
[[:id, {}], [:y, {:type=>:boolean, :db_type=>'tinyint(1)'}], [:b, {:type=>:integer, :db_type=>'integer'}]]
|
|
8
8
|
end
|
|
9
9
|
@c = Class.new(Sequel::Model(@db[:items])) do
|
|
10
|
-
include(Module.new{def _refresh(ds); values[:b] = b.to_s; self; end})
|
|
11
10
|
attr_accessor :bset
|
|
12
11
|
def b=(x)
|
|
13
12
|
self.bset = true
|
|
14
13
|
super
|
|
15
14
|
end
|
|
16
15
|
end
|
|
17
|
-
@c.instance_eval do
|
|
18
|
-
@columns = [:id, :b, :y]
|
|
19
|
-
def columns; @columns; end
|
|
20
|
-
end
|
|
21
16
|
end
|
|
22
17
|
|
|
23
18
|
specify "should call setter method with value when loading the object, for all given columns" do
|
|
@@ -9,57 +9,63 @@ describe "Sequel::Plugins::UpdatePrimaryKey" do
|
|
|
9
9
|
@c.unrestrict_primary_key
|
|
10
10
|
@o = @c.new
|
|
11
11
|
@ds = @c.dataset
|
|
12
|
-
@ds.extend(Module.new do
|
|
13
|
-
attr_accessor :a
|
|
14
|
-
def fetch_rows(sql)
|
|
15
|
-
yield(a.dup)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def update(h)
|
|
19
|
-
if literal(opts[:where]) =~ /a = (\d)/ and $1.to_i == a[:a]
|
|
20
|
-
a.update(h)
|
|
21
|
-
end
|
|
22
|
-
super
|
|
23
|
-
end
|
|
24
|
-
end)
|
|
25
|
-
@ds.a = {:a=>1, :b=>3}
|
|
26
|
-
@ds2 = @ds.naked
|
|
27
12
|
MODEL_DB.reset
|
|
28
13
|
end
|
|
29
14
|
|
|
30
15
|
specify "should handle regular updates" do
|
|
16
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>1, :b=>4}], [{:a=>1, :b=>4}], [{:a=>1, :b=>5}], [{:a=>1, :b=>5}], [{:a=>1, :b=>6}], [{:a=>1, :b=>6}]]
|
|
31
17
|
@c.first.update(:b=>4)
|
|
32
|
-
@
|
|
18
|
+
@c.all.should == [@c.load(:a=>1, :b=>4)]
|
|
19
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET b = 4 WHERE (a = 1)", "SELECT * FROM a"]
|
|
33
20
|
@c.first.set(:b=>5).save
|
|
34
|
-
@
|
|
21
|
+
@c.all.should == [@c.load(:a=>1, :b=>5)]
|
|
22
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET b = 5 WHERE (a = 1)", "SELECT * FROM a"]
|
|
35
23
|
@c.first.set(:b=>6).save(:b)
|
|
36
|
-
@
|
|
24
|
+
@c.all.should == [@c.load(:a=>1, :b=>6)]
|
|
25
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET b = 6 WHERE (a = 1)", "SELECT * FROM a"]
|
|
37
26
|
end
|
|
38
27
|
|
|
39
28
|
specify "should handle updating the primary key field with another field" do
|
|
29
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>4}]]
|
|
40
30
|
@c.first.update(:a=>2, :b=>4)
|
|
41
|
-
@
|
|
31
|
+
@c.all.should == [@c.load(:a=>2, :b=>4)]
|
|
32
|
+
sqls = MODEL_DB.sqls
|
|
33
|
+
["UPDATE a SET a = 2, b = 4 WHERE (a = 1)", "UPDATE a SET b = 4, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
|
|
34
|
+
sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
|
|
42
35
|
end
|
|
43
36
|
|
|
44
37
|
specify "should handle updating just the primary key field when saving changes" do
|
|
38
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>3}], [{:a=>2, :b=>3}], [{:a=>3, :b=>3}]]
|
|
45
39
|
@c.first.update(:a=>2)
|
|
46
|
-
@
|
|
40
|
+
@c.all.should == [@c.load(:a=>2, :b=>3)]
|
|
41
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 2 WHERE (a = 1)", "SELECT * FROM a"]
|
|
47
42
|
@c.first.set(:a=>3).save(:a)
|
|
48
|
-
@
|
|
43
|
+
@c.all.should == [@c.load(:a=>3, :b=>3)]
|
|
44
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 3 WHERE (a = 2)", "SELECT * FROM a"]
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
specify "should handle saving after modifying the primary key field with another field" do
|
|
48
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>4}]]
|
|
52
49
|
@c.first.set(:a=>2, :b=>4).save
|
|
53
|
-
@
|
|
50
|
+
@c.all.should == [@c.load(:a=>2, :b=>4)]
|
|
51
|
+
sqls = MODEL_DB.sqls
|
|
52
|
+
["UPDATE a SET a = 2, b = 4 WHERE (a = 1)", "UPDATE a SET b = 4, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
|
|
53
|
+
sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
specify "should handle saving after modifying just the primary key field" do
|
|
57
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>3}]]
|
|
57
58
|
@c.first.set(:a=>2).save
|
|
58
|
-
@
|
|
59
|
+
@c.all.should == [@c.load(:a=>2, :b=>3)]
|
|
60
|
+
sqls = MODEL_DB.sqls
|
|
61
|
+
["UPDATE a SET a = 2, b = 3 WHERE (a = 1)", "UPDATE a SET b = 3, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
|
|
62
|
+
sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
specify "should handle saving after updating the primary key" do
|
|
66
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>5}]]
|
|
62
67
|
@c.first.update(:a=>2).update(:b=>4).set(:b=>5).save
|
|
63
|
-
@
|
|
68
|
+
@c.all.should == [@c.load(:a=>2, :b=>5)]
|
|
69
|
+
MODEL_DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 2 WHERE (a = 1)", "UPDATE a SET b = 4 WHERE (a = 2)", "UPDATE a SET b = 5 WHERE (a = 2)", "SELECT * FROM a"]
|
|
64
70
|
end
|
|
65
71
|
end
|