sequel 3.48.0 → 4.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG +114 -0
- data/Rakefile +10 -7
- data/doc/association_basics.rdoc +25 -23
- data/doc/code_order.rdoc +7 -0
- data/doc/core_extensions.rdoc +0 -10
- data/doc/object_model.rdoc +4 -1
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/4.0.0.txt +262 -0
- data/doc/security.rdoc +0 -28
- data/doc/testing.rdoc +8 -14
- data/lib/sequel/adapters/ado.rb +7 -11
- data/lib/sequel/adapters/ado/access.rb +8 -8
- data/lib/sequel/adapters/ado/mssql.rb +4 -4
- data/lib/sequel/adapters/amalgalite.rb +6 -6
- data/lib/sequel/adapters/cubrid.rb +7 -7
- data/lib/sequel/adapters/db2.rb +5 -9
- data/lib/sequel/adapters/dbi.rb +2 -6
- data/lib/sequel/adapters/do.rb +4 -4
- data/lib/sequel/adapters/firebird.rb +4 -4
- data/lib/sequel/adapters/ibmdb.rb +8 -8
- data/lib/sequel/adapters/informix.rb +2 -10
- data/lib/sequel/adapters/jdbc.rb +17 -17
- data/lib/sequel/adapters/jdbc/as400.rb +2 -2
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +1 -1
- data/lib/sequel/adapters/jdbc/derby.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +2 -2
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
- data/lib/sequel/adapters/jdbc/informix.rb +1 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
- data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
- data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
- data/lib/sequel/adapters/mock.rb +7 -7
- data/lib/sequel/adapters/mysql.rb +3 -3
- data/lib/sequel/adapters/mysql2.rb +4 -4
- data/lib/sequel/adapters/odbc.rb +2 -6
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/openbase.rb +1 -5
- data/lib/sequel/adapters/oracle.rb +13 -17
- data/lib/sequel/adapters/postgres.rb +20 -25
- data/lib/sequel/adapters/shared/cubrid.rb +3 -3
- data/lib/sequel/adapters/shared/db2.rb +2 -2
- data/lib/sequel/adapters/shared/firebird.rb +7 -7
- data/lib/sequel/adapters/shared/mssql.rb +9 -9
- data/lib/sequel/adapters/shared/mysql.rb +29 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
- data/lib/sequel/adapters/shared/oracle.rb +22 -13
- data/lib/sequel/adapters/shared/postgres.rb +61 -46
- data/lib/sequel/adapters/shared/sqlite.rb +9 -9
- data/lib/sequel/adapters/sqlite.rb +17 -11
- data/lib/sequel/adapters/swift.rb +3 -3
- data/lib/sequel/adapters/swift/mysql.rb +1 -1
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +8 -8
- data/lib/sequel/ast_transformer.rb +3 -1
- data/lib/sequel/connection_pool.rb +4 -2
- data/lib/sequel/connection_pool/sharded_single.rb +2 -2
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
- data/lib/sequel/connection_pool/threaded.rb +7 -7
- data/lib/sequel/core.rb +4 -67
- data/lib/sequel/database.rb +1 -0
- data/lib/sequel/database/connecting.rb +2 -8
- data/lib/sequel/database/dataset.rb +2 -7
- data/lib/sequel/database/dataset_defaults.rb +0 -18
- data/lib/sequel/database/features.rb +4 -4
- data/lib/sequel/database/misc.rb +6 -8
- data/lib/sequel/database/query.rb +5 -61
- data/lib/sequel/database/schema_generator.rb +22 -20
- data/lib/sequel/database/schema_methods.rb +48 -20
- data/lib/sequel/database/transactions.rb +7 -17
- data/lib/sequel/dataset.rb +2 -0
- data/lib/sequel/dataset/actions.rb +23 -91
- data/lib/sequel/dataset/features.rb +1 -4
- data/lib/sequel/dataset/graph.rb +3 -47
- data/lib/sequel/dataset/misc.rb +4 -33
- data/lib/sequel/dataset/prepared_statements.rb +3 -1
- data/lib/sequel/dataset/query.rb +116 -240
- data/lib/sequel/dataset/sql.rb +19 -97
- data/lib/sequel/deprecated.rb +0 -16
- data/lib/sequel/exceptions.rb +0 -3
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/columns_introspection.rb +1 -12
- data/lib/sequel/extensions/constraint_validations.rb +3 -3
- data/lib/sequel/extensions/core_extensions.rb +0 -9
- data/lib/sequel/extensions/date_arithmetic.rb +1 -2
- data/lib/sequel/extensions/graph_each.rb +11 -0
- data/lib/sequel/extensions/migration.rb +5 -5
- data/lib/sequel/extensions/null_dataset.rb +11 -13
- data/lib/sequel/extensions/pagination.rb +3 -6
- data/lib/sequel/extensions/pg_array.rb +6 -4
- data/lib/sequel/extensions/pg_array_ops.rb +35 -1
- data/lib/sequel/extensions/pg_json.rb +12 -2
- data/lib/sequel/extensions/pg_json_ops.rb +266 -0
- data/lib/sequel/extensions/pg_range.rb +2 -2
- data/lib/sequel/extensions/pg_range_ops.rb +0 -8
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/pretty_table.rb +0 -4
- data/lib/sequel/extensions/query.rb +3 -8
- data/lib/sequel/extensions/schema_caching.rb +0 -7
- data/lib/sequel/extensions/schema_dumper.rb +10 -17
- data/lib/sequel/extensions/select_remove.rb +0 -4
- data/lib/sequel/extensions/set_overrides.rb +28 -0
- data/lib/sequel/extensions/to_dot.rb +6 -10
- data/lib/sequel/model.rb +6 -7
- data/lib/sequel/model/associations.rb +127 -182
- data/lib/sequel/model/base.rb +88 -211
- data/lib/sequel/model/errors.rb +0 -13
- data/lib/sequel/model/plugins.rb +2 -2
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/after_initialize.rb +11 -17
- data/lib/sequel/plugins/association_autoreloading.rb +1 -47
- data/lib/sequel/plugins/association_dependencies.rb +2 -2
- data/lib/sequel/plugins/auto_validations.rb +2 -8
- data/lib/sequel/plugins/blacklist_security.rb +32 -2
- data/lib/sequel/plugins/caching.rb +1 -1
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/composition.rb +10 -8
- data/lib/sequel/plugins/constraint_validations.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +4 -0
- data/lib/sequel/plugins/defaults_setter.rb +8 -6
- data/lib/sequel/plugins/dirty.rb +6 -6
- data/lib/sequel/plugins/force_encoding.rb +13 -8
- data/lib/sequel/plugins/hook_class_methods.rb +1 -7
- data/lib/sequel/plugins/json_serializer.rb +13 -74
- data/lib/sequel/plugins/lazy_attributes.rb +2 -4
- data/lib/sequel/plugins/list.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +4 -11
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/optimistic_locking.rb +3 -5
- data/lib/sequel/plugins/pg_array_associations.rb +453 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
- data/lib/sequel/plugins/rcte_tree.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +5 -4
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +7 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -2
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +19 -4
- data/lib/sequel/plugins/validation_class_methods.rb +0 -30
- data/lib/sequel/plugins/validation_helpers.rb +13 -31
- data/lib/sequel/plugins/xml_serializer.rb +18 -57
- data/lib/sequel/sql.rb +20 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/db2_spec.rb +14 -23
- data/spec/adapters/firebird_spec.rb +25 -29
- data/spec/adapters/informix_spec.rb +11 -14
- data/spec/adapters/mssql_spec.rb +71 -77
- data/spec/adapters/mysql_spec.rb +165 -172
- data/spec/adapters/oracle_spec.rb +36 -39
- data/spec/adapters/postgres_spec.rb +175 -100
- data/spec/adapters/spec_helper.rb +13 -11
- data/spec/adapters/sqlite_spec.rb +36 -44
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +55 -55
- data/spec/core/dataset_spec.rb +45 -249
- data/spec/core/deprecated_spec.rb +0 -8
- data/spec/core/expression_filters_spec.rb +23 -5
- data/spec/core/object_graph_spec.rb +4 -66
- data/spec/core/schema_spec.rb +35 -12
- data/spec/core/spec_helper.rb +3 -2
- data/spec/core_extensions_spec.rb +17 -19
- data/spec/extensions/arbitrary_servers_spec.rb +2 -3
- data/spec/extensions/association_dependencies_spec.rb +14 -14
- data/spec/extensions/auto_validations_spec.rb +7 -0
- data/spec/extensions/blacklist_security_spec.rb +5 -5
- data/spec/extensions/blank_spec.rb +2 -0
- data/spec/extensions/class_table_inheritance_spec.rb +2 -2
- data/spec/extensions/columns_introspection_spec.rb +2 -29
- data/spec/extensions/composition_spec.rb +10 -17
- data/spec/extensions/core_refinements_spec.rb +5 -1
- data/spec/extensions/dataset_associations_spec.rb +18 -0
- data/spec/extensions/date_arithmetic_spec.rb +2 -2
- data/spec/extensions/defaults_setter_spec.rb +9 -9
- data/spec/extensions/dirty_spec.rb +0 -5
- data/spec/extensions/eval_inspect_spec.rb +2 -0
- data/spec/extensions/force_encoding_spec.rb +2 -18
- data/spec/extensions/hash_aliases_spec.rb +8 -0
- data/spec/extensions/hook_class_methods_spec.rb +39 -58
- data/spec/extensions/inflector_spec.rb +2 -0
- data/spec/extensions/instance_filters_spec.rb +8 -8
- data/spec/extensions/json_serializer_spec.rb +1 -41
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +106 -109
- data/spec/extensions/migration_spec.rb +2 -0
- data/spec/extensions/named_timezones_spec.rb +1 -0
- data/spec/extensions/pg_array_associations_spec.rb +603 -0
- data/spec/extensions/pg_array_ops_spec.rb +25 -0
- data/spec/extensions/pg_array_spec.rb +9 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
- data/spec/extensions/pg_hstore_spec.rb +1 -0
- data/spec/extensions/pg_json_ops_spec.rb +131 -0
- data/spec/extensions/pg_json_spec.rb +10 -4
- data/spec/extensions/pg_range_ops_spec.rb +2 -5
- data/spec/extensions/pg_range_spec.rb +6 -2
- data/spec/extensions/pg_row_ops_spec.rb +2 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
- data/spec/extensions/rcte_tree_spec.rb +15 -15
- data/spec/extensions/schema_dumper_spec.rb +0 -1
- data/spec/extensions/schema_spec.rb +9 -9
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +18 -29
- data/spec/extensions/set_overrides_spec.rb +4 -0
- data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
- data/spec/extensions/single_table_inheritance_spec.rb +4 -4
- data/spec/extensions/spec_helper.rb +8 -9
- data/spec/extensions/sql_expr_spec.rb +2 -0
- data/spec/extensions/string_date_time_spec.rb +2 -0
- data/spec/extensions/string_stripper_spec.rb +2 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
- data/spec/extensions/thread_local_timezones_spec.rb +2 -0
- data/spec/extensions/timestamps_spec.rb +1 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +24 -24
- data/spec/extensions/tree_spec.rb +7 -7
- data/spec/extensions/typecast_on_load_spec.rb +8 -1
- data/spec/extensions/update_primary_key_spec.rb +10 -10
- data/spec/extensions/validation_class_methods_spec.rb +10 -39
- data/spec/extensions/validation_helpers_spec.rb +29 -47
- data/spec/extensions/xml_serializer_spec.rb +1 -23
- data/spec/integration/associations_test.rb +231 -40
- data/spec/integration/database_test.rb +1 -1
- data/spec/integration/dataset_test.rb +64 -64
- data/spec/integration/eager_loader_test.rb +28 -28
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +21 -21
- data/spec/integration/prepared_statement_test.rb +7 -7
- data/spec/integration/schema_test.rb +115 -110
- data/spec/integration/spec_helper.rb +17 -27
- data/spec/integration/timezone_test.rb +1 -1
- data/spec/integration/transaction_test.rb +10 -10
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/association_reflection_spec.rb +2 -28
- data/spec/model/associations_spec.rb +239 -188
- data/spec/model/base_spec.rb +27 -68
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +160 -172
- data/spec/model/hooks_spec.rb +62 -79
- data/spec/model/model_spec.rb +36 -51
- data/spec/model/plugins_spec.rb +5 -19
- data/spec/model/record_spec.rb +125 -151
- data/spec/model/spec_helper.rb +8 -6
- data/spec/model/validations_spec.rb +4 -17
- data/spec/spec_config.rb +2 -10
- metadata +50 -56
- data/lib/sequel/deprecated_core_extensions.rb +0 -135
- data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
- data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
- data/lib/sequel/plugins/identity_map.rb +0 -260
- data/lib/sequel_core.rb +0 -2
- data/lib/sequel_model.rb +0 -2
- data/spec/extensions/association_autoreloading_spec.rb +0 -102
- data/spec/extensions/identity_map_spec.rb +0 -337
- data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
- data/spec/extensions/pg_statement_cache_spec.rb +0 -208
- data/spec/rcov.opts +0 -8
- data/spec/spec_config.rb.example +0 -10
|
@@ -8,19 +8,15 @@ end
|
|
|
8
8
|
|
|
9
9
|
unless Object.const_defined?('Sequel')
|
|
10
10
|
$:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
|
|
11
|
-
require 'sequel
|
|
11
|
+
require 'sequel'
|
|
12
12
|
end
|
|
13
13
|
begin
|
|
14
|
-
require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb') unless defined?(
|
|
14
|
+
require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb') unless defined?(DB)
|
|
15
15
|
rescue LoadError
|
|
16
16
|
end
|
|
17
17
|
Sequel::Deprecation.backtrace_filter = lambda{|line, lineno| lineno < 4 || line =~ /_(spec|test)\.rb/}
|
|
18
18
|
|
|
19
|
-
if ENV['SEQUEL_COLUMNS_INTROSPECTION']
|
|
20
|
-
Sequel.extension :columns_introspection
|
|
21
|
-
Sequel::Dataset.introspect_all_columns
|
|
22
|
-
end
|
|
23
|
-
|
|
19
|
+
Sequel::Database.extension :columns_introspection if ENV['SEQUEL_COLUMNS_INTROSPECTION']
|
|
24
20
|
Sequel::Model.use_transactions = false
|
|
25
21
|
Sequel.cache_anonymous_models = false
|
|
26
22
|
|
|
@@ -41,22 +37,22 @@ def Sequel.guarded?(*checked)
|
|
|
41
37
|
unless ENV['SEQUEL_NO_PENDING']
|
|
42
38
|
checked.each do |c|
|
|
43
39
|
case c
|
|
44
|
-
when
|
|
40
|
+
when DB.database_type
|
|
45
41
|
return c
|
|
46
42
|
when Array
|
|
47
43
|
case c.length
|
|
48
44
|
when 1
|
|
49
|
-
return c if c.first ==
|
|
45
|
+
return c if c.first == DB.adapter_scheme
|
|
50
46
|
when 2
|
|
51
47
|
if c.first.is_a?(Proc)
|
|
52
|
-
return c if c.last ==
|
|
48
|
+
return c if c.last == DB.database_type && c.first.call(DB)
|
|
53
49
|
elsif c.last.is_a?(Proc)
|
|
54
|
-
return c if c.first ==
|
|
50
|
+
return c if c.first == DB.adapter_scheme && c.last.call(DB)
|
|
55
51
|
else
|
|
56
|
-
return c if c.first ==
|
|
52
|
+
return c if c.first == DB.adapter_scheme && c.last == DB.database_type
|
|
57
53
|
end
|
|
58
54
|
when 3
|
|
59
|
-
return c if c[0] ==
|
|
55
|
+
return c if c[0] == DB.adapter_scheme && c[1] == DB.database_type && c[2].call(DB)
|
|
60
56
|
end
|
|
61
57
|
end
|
|
62
58
|
end
|
|
@@ -67,10 +63,10 @@ end
|
|
|
67
63
|
(defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
|
|
68
64
|
def log
|
|
69
65
|
begin
|
|
70
|
-
|
|
66
|
+
DB.loggers << Logger.new(STDOUT)
|
|
71
67
|
yield
|
|
72
68
|
ensure
|
|
73
|
-
|
|
69
|
+
DB.loggers.pop
|
|
74
70
|
end
|
|
75
71
|
end
|
|
76
72
|
|
|
@@ -83,18 +79,12 @@ end
|
|
|
83
79
|
end
|
|
84
80
|
end
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
url = defined?(INTEGRATION_URL) ? INTEGRATION_URL : ENV['SEQUEL_INTEGRATION_URL']
|
|
89
|
-
INTEGRATION_DB = Sequel.connect(url)
|
|
90
|
-
#INTEGRATION_DB.instance_variable_set(:@server_version, 80100)
|
|
91
|
-
end
|
|
92
|
-
else
|
|
93
|
-
INTEGRATION_DB = Sequel.sqlite
|
|
82
|
+
unless defined?(DB)
|
|
83
|
+
DB = Sequel.connect(ENV['SEQUEL_INTEGRATION_URL'])
|
|
94
84
|
end
|
|
95
85
|
|
|
96
|
-
if
|
|
97
|
-
def
|
|
86
|
+
if DB.adapter_scheme == :ibmdb || (DB.adapter_scheme == :ado && DB.database_type == :access)
|
|
87
|
+
def DB.drop_table(*tables)
|
|
98
88
|
super
|
|
99
89
|
rescue Sequel::DatabaseError
|
|
100
90
|
disconnect
|
|
@@ -104,7 +94,7 @@ end
|
|
|
104
94
|
|
|
105
95
|
if ENV['SEQUEL_CONNECTION_VALIDATOR']
|
|
106
96
|
ENV['SEQUEL_NO_CHECK_SQLS'] = '1'
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
DB.extension(:connection_validator)
|
|
98
|
+
DB.pool.connection_validation_timeout = -1
|
|
109
99
|
end
|
|
110
100
|
|
|
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
|
2
2
|
|
|
3
3
|
describe "Database transactions" do
|
|
4
4
|
before(:all) do
|
|
5
|
-
@db =
|
|
5
|
+
@db = DB
|
|
6
6
|
@db.create_table!(:items, :engine=>'InnoDB'){String :name; Integer :value}
|
|
7
7
|
@d = @db[:items]
|
|
8
8
|
end
|
|
@@ -83,7 +83,7 @@ describe "Database transactions" do
|
|
|
83
83
|
@d.count.should == 0
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
if
|
|
86
|
+
if DB.supports_savepoints?
|
|
87
87
|
cspecify "should support nested transactions through savepoints using the savepoint option", [:jdbc, :sqlite] do
|
|
88
88
|
@db.transaction do
|
|
89
89
|
@d << {:name => '1'}
|
|
@@ -131,7 +131,7 @@ describe "Database transactions" do
|
|
|
131
131
|
@d.count.should == 2
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
-
if
|
|
134
|
+
if DB.supports_prepared_transactions?
|
|
135
135
|
specify "should allow saving and destroying of model objects" do
|
|
136
136
|
c = Class.new(Sequel::Model(@d))
|
|
137
137
|
c.set_primary_key :name
|
|
@@ -154,7 +154,7 @@ describe "Database transactions" do
|
|
|
154
154
|
@d.select_order_map(:name).should == []
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
if
|
|
157
|
+
if DB.supports_savepoints_in_prepared_transactions?
|
|
158
158
|
specify "should support savepoints when using prepared transactions" do
|
|
159
159
|
@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@d << {:name => '1'}}}
|
|
160
160
|
@db.commit_prepared_transaction('XYZ')
|
|
@@ -230,7 +230,7 @@ describe "Database transactions" do
|
|
|
230
230
|
c.should == 1
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
-
if
|
|
233
|
+
if DB.supports_savepoints?
|
|
234
234
|
specify "should support after_commit inside savepoints" do
|
|
235
235
|
c = nil
|
|
236
236
|
@db.transaction{@db.transaction(:savepoint=>true){@db.after_commit{c = 1}}; c.should be_nil}
|
|
@@ -244,13 +244,13 @@ describe "Database transactions" do
|
|
|
244
244
|
end
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
-
if
|
|
247
|
+
if DB.supports_prepared_transactions?
|
|
248
248
|
specify "should raise an error if you attempt to use after_commit or after_rollback inside a prepared transaction" do
|
|
249
249
|
proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{}}}.should raise_error(Sequel::Error)
|
|
250
250
|
proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{}}}.should raise_error(Sequel::Error)
|
|
251
251
|
end
|
|
252
252
|
|
|
253
|
-
if
|
|
253
|
+
if DB.supports_savepoints_in_prepared_transactions?
|
|
254
254
|
specify "should raise an error if you attempt to use after_commit or after rollback inside a savepoint in a prepared transaction" do
|
|
255
255
|
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{}}}}.should raise_error(Sequel::Error)
|
|
256
256
|
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{}}}}.should raise_error(Sequel::Error)
|
|
@@ -262,7 +262,7 @@ end
|
|
|
262
262
|
if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or (RUBY_ENGINE == 'rbx' && !Sequel.guarded?([:do, :sqlite], [:tinytds, :mssql]))) and RUBY_VERSION < '1.9'
|
|
263
263
|
describe "Database transactions and Thread#kill" do
|
|
264
264
|
before do
|
|
265
|
-
@db =
|
|
265
|
+
@db = DB
|
|
266
266
|
@db.create_table!(:items, :engine=>'InnoDB'){String :name; Integer :value}
|
|
267
267
|
@d = @db[:items]
|
|
268
268
|
end
|
|
@@ -286,7 +286,7 @@ if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or (RUBY_ENGINE == 'rbx' &&
|
|
|
286
286
|
@d.count.should == 0
|
|
287
287
|
end
|
|
288
288
|
|
|
289
|
-
if
|
|
289
|
+
if DB.supports_savepoints?
|
|
290
290
|
specify "should handle transactions with savepoints inside threads" do
|
|
291
291
|
q = Queue.new
|
|
292
292
|
q1 = Queue.new
|
|
@@ -312,7 +312,7 @@ end
|
|
|
312
312
|
|
|
313
313
|
describe "Database transaction retrying" do
|
|
314
314
|
before(:all) do
|
|
315
|
-
@db =
|
|
315
|
+
@db = DB
|
|
316
316
|
@db.create_table!(:items, :engine=>'InnoDB'){String :a, :unique=>true, :null=>false}
|
|
317
317
|
@d = @db[:items]
|
|
318
318
|
end
|
|
@@ -2,8 +2,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
|
2
2
|
|
|
3
3
|
describe "Supported types" do
|
|
4
4
|
def create_items_table_with_column(name, type, opts={})
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
DB.create_table!(:items){column name, type, opts}
|
|
6
|
+
DB[:items]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
specify "should support casting correctly" do
|
|
@@ -116,20 +116,6 @@ describe Sequel::Model::Associations::AssociationReflection, "#reciprocal" do
|
|
|
116
116
|
ParParentThree.association_reflection(:par_parents).reciprocal.should == :par_parent_threes
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
qspecify "should handle ambiguous reciprocals" do
|
|
120
|
-
ParParent.many_to_one :par_parent_two, :class=>ParParentTwo, :key=>:par_parent_two_id
|
|
121
|
-
ParParent.many_to_one :par_parent_two2, :clone=>:par_parent_two
|
|
122
|
-
ParParentTwo.one_to_many :par_parents, :class=>ParParent, :key=>:par_parent_two_id
|
|
123
|
-
ParParentTwo.one_to_many :par_parents2, :clone=>:par_parents
|
|
124
|
-
ParParent.many_to_many :par_parent_threes, :class=>ParParentThree, :right_key=>:par_parent_three_id
|
|
125
|
-
ParParent.many_to_many :par_parent_threes2, :clone=>:par_parent_threes
|
|
126
|
-
ParParentThree.many_to_many :par_parents
|
|
127
|
-
|
|
128
|
-
[:par_parent_two, :par_parent_two2].should include(ParParentTwo.association_reflection(:par_parents).reciprocal)
|
|
129
|
-
[:par_parents, :par_parents2].should include(ParParent.association_reflection(:par_parent_two).reciprocal)
|
|
130
|
-
[:par_parent_threes, :par_parent_threes2].should include(ParParentThree.association_reflection(:par_parents).reciprocal)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
119
|
it "should handle ambiguous reciprocals where only one doesn't have conditions/blocks" do
|
|
134
120
|
ParParent.many_to_one :par_parent_two, :class=>ParParentTwo, :key=>:par_parent_two_id
|
|
135
121
|
ParParent.many_to_one :par_parent_two2, :clone=>:par_parent_two, :conditions=>{:id=>:id}
|
|
@@ -172,18 +158,6 @@ describe Sequel::Model::Associations::AssociationReflection, "#reciprocal" do
|
|
|
172
158
|
ParParent.association_reflection(:par_parent_two).reciprocal.should == :par_parents
|
|
173
159
|
ParParent.association_reflection(:par_parent_threes).reciprocal.should == :par_parents
|
|
174
160
|
end
|
|
175
|
-
|
|
176
|
-
qspecify "should handle reciprocals where reciprocal association has conditions/block" do
|
|
177
|
-
ParParent.many_to_one :par_parent_two, :conditions=>{:id=>:id}
|
|
178
|
-
ParParentTwo.one_to_many :par_parents
|
|
179
|
-
ParParent.many_to_many :par_parent_threes do |ds|
|
|
180
|
-
ds
|
|
181
|
-
end
|
|
182
|
-
ParParentThree.many_to_many :par_parents
|
|
183
|
-
|
|
184
|
-
ParParentTwo.association_reflection(:par_parents).reciprocal.should == :par_parent_two
|
|
185
|
-
ParParentThree.association_reflection(:par_parents).reciprocal.should == :par_parent_threes
|
|
186
|
-
end
|
|
187
161
|
end
|
|
188
162
|
|
|
189
163
|
describe Sequel::Model::Associations::AssociationReflection, "#select" do
|
|
@@ -313,7 +287,7 @@ describe Sequel::Model::Associations::AssociationReflection, "#eager_limit_strat
|
|
|
313
287
|
@c = Class.new(Sequel::Model(:a))
|
|
314
288
|
end
|
|
315
289
|
after do
|
|
316
|
-
Sequel::Model.default_eager_limit_strategy =
|
|
290
|
+
Sequel::Model.default_eager_limit_strategy = true
|
|
317
291
|
end
|
|
318
292
|
|
|
319
293
|
it "should be nil by default for *_one associations" do
|
|
@@ -401,7 +375,7 @@ describe Sequel::Model, " association reflection methods" do
|
|
|
401
375
|
def self.name; 'Node'; end
|
|
402
376
|
def self.to_s; 'Node'; end
|
|
403
377
|
end
|
|
404
|
-
|
|
378
|
+
DB.reset
|
|
405
379
|
end
|
|
406
380
|
|
|
407
381
|
it "#all_association_reflections should include all association reflection hashes" do
|
|
@@ -138,15 +138,6 @@ describe Sequel::Model, "associate" do
|
|
|
138
138
|
proc{c.one_to_one :c2, :clone=>:cs}.should_not raise_error(Sequel::Error)
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
it "should clear associations cache when using set_values" do
|
|
142
|
-
c = Class.new(Sequel::Model(:c))
|
|
143
|
-
c.many_to_one :c
|
|
144
|
-
o = c.new
|
|
145
|
-
o.associations[:c] = 1
|
|
146
|
-
o.set_values(:id=>1)
|
|
147
|
-
o.associations.should == {}
|
|
148
|
-
end
|
|
149
|
-
|
|
150
141
|
it "should clear associations cache when refreshing object manually" do
|
|
151
142
|
c = Class.new(Sequel::Model(:c))
|
|
152
143
|
c.many_to_one :c
|
|
@@ -156,16 +147,16 @@ describe Sequel::Model, "associate" do
|
|
|
156
147
|
o.associations.should == {}
|
|
157
148
|
end
|
|
158
149
|
|
|
159
|
-
it "should clear associations cache when refreshing object after save" do
|
|
150
|
+
it "should not clear associations cache when refreshing object after save" do
|
|
160
151
|
c = Class.new(Sequel::Model(:c))
|
|
161
152
|
c.many_to_one :c
|
|
162
153
|
o = c.new
|
|
163
154
|
o.associations[:c] = 1
|
|
164
155
|
o.save
|
|
165
|
-
o.associations.should == {}
|
|
156
|
+
o.associations.should == {:c=>1}
|
|
166
157
|
end
|
|
167
158
|
|
|
168
|
-
it "should clear associations cache when saving with insert_select" do
|
|
159
|
+
it "should not clear associations cache when saving with insert_select" do
|
|
169
160
|
ds = Sequel::Model.db[:c]
|
|
170
161
|
def ds.supports_insert_select?() true end
|
|
171
162
|
def ds.insert_select(*) {:id=>1} end
|
|
@@ -174,7 +165,7 @@ describe Sequel::Model, "associate" do
|
|
|
174
165
|
o = c.new
|
|
175
166
|
o.associations[:c] = 1
|
|
176
167
|
o.save
|
|
177
|
-
o.associations.should == {}
|
|
168
|
+
o.associations.should == {:c=>1}
|
|
178
169
|
end
|
|
179
170
|
|
|
180
171
|
end
|
|
@@ -186,7 +177,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
186
177
|
columns :id, :parent_id, :par_parent_id, :blah
|
|
187
178
|
end
|
|
188
179
|
@dataset = @c2.dataset
|
|
189
|
-
|
|
180
|
+
DB.reset
|
|
190
181
|
end
|
|
191
182
|
|
|
192
183
|
it "should use implicit key if omitted" do
|
|
@@ -197,7 +188,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
197
188
|
p.class.should == @c2
|
|
198
189
|
p.values.should == {:x => 1, :id => 1}
|
|
199
190
|
|
|
200
|
-
|
|
191
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE id = 234"]
|
|
201
192
|
end
|
|
202
193
|
|
|
203
194
|
it "should allow association with the same name as the key if :key_column is given" do
|
|
@@ -208,7 +199,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
208
199
|
d.parent_id.should == @c2.load(:x => 1, :id => 1)
|
|
209
200
|
d.parent_id_id.should == 234
|
|
210
201
|
d[:parent_id].should == 234
|
|
211
|
-
|
|
202
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE id = 234"]
|
|
212
203
|
|
|
213
204
|
d.parent_id_id = 3
|
|
214
205
|
d.parent_id_id.should == 3
|
|
@@ -220,7 +211,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
220
211
|
class ::ParParent < Sequel::Model; end
|
|
221
212
|
@c2.many_to_one :par_parent
|
|
222
213
|
@c2.new(:id => 1, :par_parent_id => 234).par_parent.class.should == ParParent
|
|
223
|
-
|
|
214
|
+
DB.sqls.should == ["SELECT * FROM par_parents WHERE id = 234"]
|
|
224
215
|
ensure
|
|
225
216
|
Object.send(:remove_const, :ParParent)
|
|
226
217
|
end
|
|
@@ -233,7 +224,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
233
224
|
end
|
|
234
225
|
@c2.many_to_one :par_parent, :class=>"Par::Parent"
|
|
235
226
|
@c2.new(:id => 1, :par_parent_id => 234).par_parent.class.should == Par::Parent
|
|
236
|
-
|
|
227
|
+
DB.sqls.should == ["SELECT * FROM parents WHERE id = 234"]
|
|
237
228
|
ensure
|
|
238
229
|
Object.send(:remove_const, :Par)
|
|
239
230
|
end
|
|
@@ -247,31 +238,31 @@ describe Sequel::Model, "many_to_one" do
|
|
|
247
238
|
p.class.should == @c2
|
|
248
239
|
p.values.should == {:x => 1, :id => 1}
|
|
249
240
|
|
|
250
|
-
|
|
241
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE id = 567"]
|
|
251
242
|
end
|
|
252
243
|
|
|
253
244
|
it "should respect :qualify => false option" do
|
|
254
245
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :qualify=>false
|
|
255
246
|
@c2.new(:id => 1, :blah => 567).parent
|
|
256
|
-
|
|
247
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE id = 567"]
|
|
257
248
|
end
|
|
258
249
|
|
|
259
250
|
it "should use :primary_key option if given" do
|
|
260
251
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :primary_key => :pk
|
|
261
252
|
@c2.new(:id => 1, :blah => 567).parent
|
|
262
|
-
|
|
253
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.pk = 567) LIMIT 1"]
|
|
263
254
|
end
|
|
264
255
|
|
|
265
256
|
it "should support composite keys" do
|
|
266
257
|
@c2.many_to_one :parent, :class => @c2, :key=>[:id, :parent_id], :primary_key=>[:parent_id, :id]
|
|
267
258
|
@c2.new(:id => 1, :parent_id => 234).parent
|
|
268
|
-
|
|
259
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.parent_id = 1) AND (nodes.id = 234)) LIMIT 1"]
|
|
269
260
|
end
|
|
270
261
|
|
|
271
262
|
it "should not issue query if not all keys have values" do
|
|
272
263
|
@c2.many_to_one :parent, :class => @c2, :key=>[:id, :parent_id], :primary_key=>[:parent_id, :id]
|
|
273
264
|
@c2.new(:id => 1, :parent_id => nil).parent.should == nil
|
|
274
|
-
|
|
265
|
+
DB.sqls.should == []
|
|
275
266
|
end
|
|
276
267
|
|
|
277
268
|
it "should raise an Error unless same number of composite keys used" do
|
|
@@ -284,17 +275,17 @@ describe Sequel::Model, "many_to_one" do
|
|
|
284
275
|
it "should use :select option if given" do
|
|
285
276
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :select=>[:id, :name]
|
|
286
277
|
@c2.new(:id => 1, :blah => 567).parent
|
|
287
|
-
|
|
278
|
+
DB.sqls.should == ["SELECT id, name FROM nodes WHERE (nodes.id = 567) LIMIT 1"]
|
|
288
279
|
end
|
|
289
280
|
|
|
290
281
|
it "should use :conditions option if given" do
|
|
291
282
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :conditions=>{:a=>32}
|
|
292
283
|
@c2.new(:id => 1, :blah => 567).parent
|
|
293
|
-
|
|
284
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((a = 32) AND (nodes.id = 567)) LIMIT 1"]
|
|
294
285
|
|
|
295
286
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :conditions=>:a
|
|
296
287
|
@c2.new(:id => 1, :blah => 567).parent
|
|
297
|
-
|
|
288
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (a AND (nodes.id = 567)) LIMIT 1"]
|
|
298
289
|
end
|
|
299
290
|
|
|
300
291
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
|
@@ -302,24 +293,24 @@ describe Sequel::Model, "many_to_one" do
|
|
|
302
293
|
ds.filter{x > 1}
|
|
303
294
|
end
|
|
304
295
|
@c2.load(:id => 100).child_20
|
|
305
|
-
|
|
296
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
|
306
297
|
end
|
|
307
298
|
|
|
308
299
|
it "should return nil if key value is nil" do
|
|
309
300
|
@c2.many_to_one :parent, :class => @c2
|
|
310
301
|
@c2.new(:id => 1).parent.should == nil
|
|
311
|
-
|
|
302
|
+
DB.sqls.should == []
|
|
312
303
|
end
|
|
313
304
|
|
|
314
305
|
it "should cache negative lookup" do
|
|
315
306
|
@c2.many_to_one :parent, :class => @c2
|
|
316
307
|
@c2.dataset._fetch = []
|
|
317
308
|
d = @c2.new(:id => 1, :parent_id=>555)
|
|
318
|
-
|
|
309
|
+
DB.sqls.should == []
|
|
319
310
|
d.parent.should == nil
|
|
320
|
-
|
|
311
|
+
DB.sqls.should == ['SELECT * FROM nodes WHERE id = 555']
|
|
321
312
|
d.parent.should == nil
|
|
322
|
-
|
|
313
|
+
DB.sqls.should == []
|
|
323
314
|
end
|
|
324
315
|
|
|
325
316
|
it "should define a setter method" do
|
|
@@ -371,11 +362,11 @@ describe Sequel::Model, "many_to_one" do
|
|
|
371
362
|
@c2.many_to_one :parent, :class => @c2
|
|
372
363
|
|
|
373
364
|
d = @c2.load(:id => 1)
|
|
374
|
-
|
|
365
|
+
DB.reset
|
|
375
366
|
d.parent = @c2.new(:id => 345)
|
|
376
|
-
|
|
367
|
+
DB.sqls.should == []
|
|
377
368
|
d.save_changes
|
|
378
|
-
|
|
369
|
+
DB.sqls.should == ['UPDATE nodes SET parent_id = 345 WHERE (id = 1)']
|
|
379
370
|
end
|
|
380
371
|
|
|
381
372
|
it "should populate cache when accessed" do
|
|
@@ -386,7 +377,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
386
377
|
d.associations[:parent].should == nil
|
|
387
378
|
@c2.dataset._fetch = {:id=>234}
|
|
388
379
|
e = d.parent
|
|
389
|
-
|
|
380
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE id = 234"]
|
|
390
381
|
d.associations[:parent].should == e
|
|
391
382
|
end
|
|
392
383
|
|
|
@@ -394,55 +385,55 @@ describe Sequel::Model, "many_to_one" do
|
|
|
394
385
|
@c2.many_to_one :parent, :class => @c2
|
|
395
386
|
|
|
396
387
|
d = @c2.create(:id => 1)
|
|
397
|
-
|
|
388
|
+
DB.reset
|
|
398
389
|
d.associations[:parent].should == nil
|
|
399
390
|
d.parent = @c2.new(:id => 234)
|
|
400
391
|
e = d.parent
|
|
401
392
|
d.associations[:parent].should == e
|
|
402
|
-
|
|
393
|
+
DB.sqls.should == []
|
|
403
394
|
end
|
|
404
395
|
|
|
405
396
|
it "should use cache if available" do
|
|
406
397
|
@c2.many_to_one :parent, :class => @c2
|
|
407
398
|
|
|
408
399
|
d = @c2.create(:id => 1, :parent_id => 234)
|
|
409
|
-
|
|
400
|
+
DB.reset
|
|
410
401
|
d.associations[:parent] = 42
|
|
411
402
|
d.parent.should == 42
|
|
412
|
-
|
|
403
|
+
DB.sqls.should == []
|
|
413
404
|
end
|
|
414
405
|
|
|
415
406
|
it "should not use cache if asked to reload" do
|
|
416
407
|
@c2.many_to_one :parent, :class => @c2
|
|
417
408
|
|
|
418
409
|
d = @c2.create(:id => 1)
|
|
419
|
-
|
|
410
|
+
DB.reset
|
|
420
411
|
d.parent_id = 234
|
|
421
412
|
d.associations[:parent] = 42
|
|
422
413
|
d.parent(true).should_not == 42
|
|
423
|
-
|
|
414
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE id = 234"]
|
|
424
415
|
end
|
|
425
416
|
|
|
426
417
|
it "should use a callback if given one as the argument" do
|
|
427
418
|
@c2.many_to_one :parent, :class => @c2
|
|
428
419
|
|
|
429
420
|
d = @c2.create(:id => 1)
|
|
430
|
-
|
|
421
|
+
DB.reset
|
|
431
422
|
d.parent_id = 234
|
|
432
423
|
d.associations[:parent] = 42
|
|
433
424
|
d.parent(proc{|ds| ds.filter{name > 'M'}}).should_not == 42
|
|
434
|
-
|
|
425
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
|
|
435
426
|
end
|
|
436
427
|
|
|
437
428
|
it "should use a block given to the association method as a callback" do
|
|
438
429
|
@c2.many_to_one :parent, :class => @c2
|
|
439
430
|
|
|
440
431
|
d = @c2.create(:id => 1)
|
|
441
|
-
|
|
432
|
+
DB.reset
|
|
442
433
|
d.parent_id = 234
|
|
443
434
|
d.associations[:parent] = 42
|
|
444
435
|
d.parent{|ds| ds.filter{name > 'M'}}.should_not == 42
|
|
445
|
-
|
|
436
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
|
|
446
437
|
end
|
|
447
438
|
|
|
448
439
|
it "should have the setter add to the reciprocal one_to_many cached association array if it exists" do
|
|
@@ -452,18 +443,18 @@ describe Sequel::Model, "many_to_one" do
|
|
|
452
443
|
|
|
453
444
|
d = @c2.new(:id => 1)
|
|
454
445
|
e = @c2.new(:id => 2)
|
|
455
|
-
|
|
446
|
+
DB.sqls.should == []
|
|
456
447
|
d.parent = e
|
|
457
448
|
e.children.should_not(include(d))
|
|
458
|
-
|
|
449
|
+
DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
|
459
450
|
|
|
460
451
|
d = @c2.new(:id => 1)
|
|
461
452
|
e = @c2.new(:id => 2)
|
|
462
453
|
e.children.should_not(include(d))
|
|
463
|
-
|
|
454
|
+
DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
|
464
455
|
d.parent = e
|
|
465
456
|
e.children.should(include(d))
|
|
466
|
-
|
|
457
|
+
DB.sqls.should == []
|
|
467
458
|
end
|
|
468
459
|
|
|
469
460
|
it "should have setter deal with a one_to_one reciprocal" do
|
|
@@ -498,7 +489,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
498
489
|
f = @c2.new(:id => 3)
|
|
499
490
|
e.children.should_not(include(d))
|
|
500
491
|
f.children.should_not(include(d))
|
|
501
|
-
|
|
492
|
+
DB.reset
|
|
502
493
|
d.parent = e
|
|
503
494
|
e.children.should(include(d))
|
|
504
495
|
d.parent = f
|
|
@@ -506,7 +497,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
506
497
|
e.children.should_not(include(d))
|
|
507
498
|
d.parent = nil
|
|
508
499
|
f.children.should_not(include(d))
|
|
509
|
-
|
|
500
|
+
DB.sqls.should == []
|
|
510
501
|
end
|
|
511
502
|
|
|
512
503
|
it "should have the setter not modify the reciprocal if set to same value as current" do
|
|
@@ -520,7 +511,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
520
511
|
c2.associations[:parent] = c1
|
|
521
512
|
c2.parent = c1
|
|
522
513
|
c1.children.should == [c2, c3]
|
|
523
|
-
|
|
514
|
+
DB.sqls.should == []
|
|
524
515
|
end
|
|
525
516
|
|
|
526
517
|
it "should get all matching records and only return the first if :key option is set to nil" do
|
|
@@ -529,7 +520,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
529
520
|
@c2.dataset.columns(:id, :parent_id, :par_parent_id, :blah)._fetch = [{:id=>1, :parent_id=>0, :par_parent_id=>3, :blah=>4, :children_id=>2, :children_parent_id=>1, :children_par_parent_id=>5, :children_blah=>6}, {}]
|
|
530
521
|
p = @c2.new(:parent_id=>2)
|
|
531
522
|
fgp = p.first_grand_parent
|
|
532
|
-
|
|
523
|
+
DB.sqls.should == ["SELECT nodes.id, nodes.parent_id, nodes.par_parent_id, nodes.blah, children.id AS children_id, children.parent_id AS children_parent_id, children.par_parent_id AS children_par_parent_id, children.blah AS children_blah FROM nodes LEFT OUTER JOIN nodes AS children ON (children.parent_id = nodes.id) WHERE (children_id = 2)"]
|
|
533
524
|
fgp.values.should == {:id=>1, :parent_id=>0, :par_parent_id=>3, :blah=>4}
|
|
534
525
|
fgp.children.first.values.should == {:id=>2, :parent_id=>1, :par_parent_id=>5, :blah=>6}
|
|
535
526
|
end
|
|
@@ -685,13 +676,13 @@ describe Sequel::Model, "one_to_one" do
|
|
|
685
676
|
@dataset = @c2.dataset
|
|
686
677
|
@dataset._fetch = {}
|
|
687
678
|
@c1.dataset._fetch = {}
|
|
688
|
-
|
|
679
|
+
DB.reset
|
|
689
680
|
end
|
|
690
681
|
|
|
691
682
|
it "should have the getter method return a single object if the :one_to_one option is true" do
|
|
692
683
|
@c2.one_to_one :attribute, :class => @c1
|
|
693
684
|
att = @c2.new(:id => 1234).attribute
|
|
694
|
-
|
|
685
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234) LIMIT 1']
|
|
695
686
|
att.should be_a_kind_of(@c1)
|
|
696
687
|
att.values.should == {}
|
|
697
688
|
end
|
|
@@ -708,7 +699,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
708
699
|
attrib = @c1.new(:id=>3)
|
|
709
700
|
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:id=>3}
|
|
710
701
|
@c2.new(:id => 1234).attribute = attrib
|
|
711
|
-
sqls =
|
|
702
|
+
sqls = DB.sqls
|
|
712
703
|
['INSERT INTO attributes (node_id, id) VALUES (1234, 3)',
|
|
713
704
|
'INSERT INTO attributes (id, node_id) VALUES (3, 1234)'].should(include(sqls.slice! 1))
|
|
714
705
|
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 1234)', "SELECT * FROM attributes WHERE (id = 3) LIMIT 1"]
|
|
@@ -716,7 +707,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
716
707
|
@c2.new(:id => 1234).attribute.should == attrib
|
|
717
708
|
attrib = @c1.load(:id=>3)
|
|
718
709
|
@c2.new(:id => 1234).attribute = attrib
|
|
719
|
-
|
|
710
|
+
DB.sqls.should == ["SELECT * FROM attributes WHERE (attributes.node_id = 1234) LIMIT 1",
|
|
720
711
|
'UPDATE attributes SET node_id = NULL WHERE ((node_id = 1234) AND (id != 3))',
|
|
721
712
|
"UPDATE attributes SET node_id = 1234 WHERE (id = 3)"]
|
|
722
713
|
end
|
|
@@ -726,7 +717,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
726
717
|
@c2.use_transactions = true
|
|
727
718
|
attrib = @c1.load(:id=>3)
|
|
728
719
|
@c2.new(:id => 1234).attribute = attrib
|
|
729
|
-
|
|
720
|
+
DB.sqls.should == ['BEGIN',
|
|
730
721
|
'UPDATE attributes SET node_id = NULL WHERE ((node_id = 1234) AND (id != 3))',
|
|
731
722
|
"UPDATE attributes SET node_id = 1234 WHERE (id = 3)",
|
|
732
723
|
'COMMIT']
|
|
@@ -738,7 +729,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
738
729
|
end
|
|
739
730
|
attrib = @c1.load(:id=>3)
|
|
740
731
|
@c2.new(:id => 1234).attribute = attrib
|
|
741
|
-
|
|
732
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE ((a = 1) AND (node_id = 1234) AND (b = 2) AND (id != 3))',
|
|
742
733
|
"UPDATE attributes SET node_id = 1234 WHERE (id = 3)"]
|
|
743
734
|
end
|
|
744
735
|
|
|
@@ -747,7 +738,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
747
738
|
attrib = @c1.new(:id=>3)
|
|
748
739
|
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:id=>3}
|
|
749
740
|
@c2.new(:id => 1234, :xxx=>5).attribute = attrib
|
|
750
|
-
sqls =
|
|
741
|
+
sqls = DB.sqls
|
|
751
742
|
['INSERT INTO attributes (node_id, id) VALUES (5, 3)',
|
|
752
743
|
'INSERT INTO attributes (id, node_id) VALUES (3, 5)'].should(include(sqls.slice! 1))
|
|
753
744
|
sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 5)', "SELECT * FROM attributes WHERE (id = 3) LIMIT 1"]
|
|
@@ -755,7 +746,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
755
746
|
@c2.new(:id => 321, :xxx=>5).attribute.should == attrib
|
|
756
747
|
attrib = @c1.load(:id=>3)
|
|
757
748
|
@c2.new(:id => 621, :xxx=>5).attribute = attrib
|
|
758
|
-
|
|
749
|
+
DB.sqls.should == ["SELECT * FROM attributes WHERE (attributes.node_id = 5) LIMIT 1",
|
|
759
750
|
'UPDATE attributes SET node_id = NULL WHERE ((node_id = 5) AND (id != 3))',
|
|
760
751
|
'UPDATE attributes SET node_id = 5 WHERE (id = 3)']
|
|
761
752
|
end
|
|
@@ -765,7 +756,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
765
756
|
attrib = @c1.load(:id=>3, :y=>6)
|
|
766
757
|
@c1.dataset._fetch = {:id=>3, :y=>6}
|
|
767
758
|
@c2.load(:id => 1234, :x=>5).attribute = attrib
|
|
768
|
-
sqls =
|
|
759
|
+
sqls = DB.sqls
|
|
769
760
|
sqls.last.should =~ /UPDATE attributes SET (node_id = 1234|y = 5), (node_id = 1234|y = 5) WHERE \(id = 3\)/
|
|
770
761
|
sqls.first.should =~ /UPDATE attributes SET (node_id|y) = NULL, (node_id|y) = NULL WHERE \(\(node_id = 1234\) AND \(y = 5\) AND \(id != 3\)\)/
|
|
771
762
|
sqls.length.should == 2
|
|
@@ -779,7 +770,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
779
770
|
p.class.should == @c2
|
|
780
771
|
p.values.should == {}
|
|
781
772
|
|
|
782
|
-
|
|
773
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.node_id = 234) LIMIT 1"]
|
|
783
774
|
end
|
|
784
775
|
|
|
785
776
|
it "should use implicit class if omitted" do
|
|
@@ -787,7 +778,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
787
778
|
class ::ParParent < Sequel::Model; end
|
|
788
779
|
@c2.one_to_one :par_parent
|
|
789
780
|
@c2.new(:id => 234).par_parent.class.should == ParParent
|
|
790
|
-
|
|
781
|
+
DB.sqls.should == ["SELECT * FROM par_parents WHERE (par_parents.node_id = 234) LIMIT 1"]
|
|
791
782
|
ensure
|
|
792
783
|
Object.send(:remove_const, :ParParent)
|
|
793
784
|
end
|
|
@@ -800,7 +791,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
800
791
|
end
|
|
801
792
|
@c2.one_to_one :par_parent, :class=>"Par::Parent"
|
|
802
793
|
@c2.new(:id => 234).par_parent.class.should == Par::Parent
|
|
803
|
-
|
|
794
|
+
DB.sqls.should == ["SELECT * FROM parents WHERE (parents.node_id = 234) LIMIT 1"]
|
|
804
795
|
ensure
|
|
805
796
|
Object.send(:remove_const, :Par)
|
|
806
797
|
end
|
|
@@ -814,25 +805,25 @@ describe Sequel::Model, "one_to_one" do
|
|
|
814
805
|
p.class.should == @c2
|
|
815
806
|
p.values.should == {}
|
|
816
807
|
|
|
817
|
-
|
|
808
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.blah = 234) LIMIT 1"]
|
|
818
809
|
end
|
|
819
810
|
|
|
820
811
|
it "should use :primary_key option if given" do
|
|
821
812
|
@c2.one_to_one :parent, :class => @c2, :key => :pk, :primary_key => :blah
|
|
822
813
|
@c2.new(:id => 1, :blah => 567).parent
|
|
823
|
-
|
|
814
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.pk = 567) LIMIT 1"]
|
|
824
815
|
end
|
|
825
816
|
|
|
826
817
|
it "should support composite keys" do
|
|
827
818
|
@c2.one_to_one :parent, :class => @c2, :primary_key=>[:id, :parent_id], :key=>[:parent_id, :id]
|
|
828
819
|
@c2.new(:id => 1, :parent_id => 234).parent
|
|
829
|
-
|
|
820
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.parent_id = 1) AND (nodes.id = 234)) LIMIT 1"]
|
|
830
821
|
end
|
|
831
822
|
|
|
832
823
|
it "should not issue query if not all keys have values" do
|
|
833
824
|
@c2.one_to_one :parent, :class => @c2, :key=>[:id, :parent_id], :primary_key=>[:parent_id, :id]
|
|
834
825
|
@c2.new(:id => 1, :parent_id => nil).parent.should == nil
|
|
835
|
-
|
|
826
|
+
DB.sqls.should == []
|
|
836
827
|
end
|
|
837
828
|
|
|
838
829
|
it "should raise an Error unless same number of composite keys used" do
|
|
@@ -845,17 +836,17 @@ describe Sequel::Model, "one_to_one" do
|
|
|
845
836
|
it "should use :select option if given" do
|
|
846
837
|
@c2.one_to_one :parent, :class => @c2, :select=>[:id, :name]
|
|
847
838
|
@c2.new(:id => 567).parent
|
|
848
|
-
|
|
839
|
+
DB.sqls.should == ["SELECT id, name FROM nodes WHERE (nodes.node_id = 567) LIMIT 1"]
|
|
849
840
|
end
|
|
850
841
|
|
|
851
842
|
it "should use :conditions option if given" do
|
|
852
843
|
@c2.one_to_one :parent, :class => @c2, :conditions=>{:a=>32}
|
|
853
844
|
@c2.new(:id => 567).parent
|
|
854
|
-
|
|
845
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((a = 32) AND (nodes.node_id = 567)) LIMIT 1"]
|
|
855
846
|
|
|
856
847
|
@c2.one_to_one :parent, :class => @c2, :conditions=>:a
|
|
857
848
|
@c2.new(:id => 567).parent
|
|
858
|
-
|
|
849
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (a AND (nodes.node_id = 567)) LIMIT 1"]
|
|
859
850
|
end
|
|
860
851
|
|
|
861
852
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
|
@@ -863,25 +854,25 @@ describe Sequel::Model, "one_to_one" do
|
|
|
863
854
|
ds.filter{x > 1}
|
|
864
855
|
end
|
|
865
856
|
@c2.load(:id => 100).child_20
|
|
866
|
-
|
|
857
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
|
867
858
|
end
|
|
868
859
|
|
|
869
860
|
it "should return nil if primary_key value is nil" do
|
|
870
861
|
@c2.one_to_one :parent, :class => @c2, :primary_key=>:node_id
|
|
871
862
|
|
|
872
863
|
@c2.new(:id => 1).parent.should be_nil
|
|
873
|
-
|
|
864
|
+
DB.sqls.should == []
|
|
874
865
|
end
|
|
875
866
|
|
|
876
867
|
it "should cache negative lookup" do
|
|
877
868
|
@c2.one_to_one :parent, :class => @c2
|
|
878
869
|
@c2.dataset._fetch = []
|
|
879
870
|
d = @c2.new(:id => 555)
|
|
880
|
-
|
|
871
|
+
DB.sqls.should == []
|
|
881
872
|
d.parent.should == nil
|
|
882
|
-
|
|
873
|
+
DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.node_id = 555) LIMIT 1']
|
|
883
874
|
d.parent.should == nil
|
|
884
|
-
|
|
875
|
+
DB.sqls.should == []
|
|
885
876
|
end
|
|
886
877
|
|
|
887
878
|
it "should have the setter method respect the :key option" do
|
|
@@ -891,7 +882,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
891
882
|
@c2.dataset._fetch = @c2.instance_dataset._fetch = {:id => 4321, :blah => 3}
|
|
892
883
|
d.parent = e
|
|
893
884
|
e.values.should == {:id => 4321, :blah => 3}
|
|
894
|
-
sqls =
|
|
885
|
+
sqls = DB.sqls
|
|
895
886
|
["INSERT INTO nodes (blah, id) VALUES (3, 4321)",
|
|
896
887
|
"INSERT INTO nodes (id, blah) VALUES (4321, 3)"].should include(sqls.slice! 1)
|
|
897
888
|
sqls.should == ["UPDATE nodes SET blah = NULL WHERE (blah = 3)", "SELECT * FROM nodes WHERE (id = 4321) LIMIT 1"]
|
|
@@ -901,7 +892,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
901
892
|
@c2.one_to_one :parent, :class => @c2
|
|
902
893
|
d = @c2.load(:id => 1)
|
|
903
894
|
d.parent = @c2.load(:id => 3, :node_id=>345)
|
|
904
|
-
|
|
895
|
+
DB.sqls.should == ["UPDATE nodes SET node_id = NULL WHERE ((node_id = 1) AND (id != 3))",
|
|
905
896
|
"UPDATE nodes SET node_id = 1 WHERE (id = 3)"]
|
|
906
897
|
end
|
|
907
898
|
|
|
@@ -912,9 +903,9 @@ describe Sequel::Model, "one_to_one" do
|
|
|
912
903
|
d.associations[:parent].should == nil
|
|
913
904
|
@c2.dataset._fetch = {:id=>234}
|
|
914
905
|
e = d.parent
|
|
915
|
-
|
|
906
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.node_id = 1) LIMIT 1"]
|
|
916
907
|
d.parent
|
|
917
|
-
|
|
908
|
+
DB.sqls.should == []
|
|
918
909
|
d.associations[:parent].should == e
|
|
919
910
|
end
|
|
920
911
|
|
|
@@ -935,7 +926,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
935
926
|
d = @c2.load(:id => 1, :parent_id => 234)
|
|
936
927
|
d.associations[:parent] = 42
|
|
937
928
|
d.parent.should == 42
|
|
938
|
-
|
|
929
|
+
DB.sqls.should == []
|
|
939
930
|
end
|
|
940
931
|
|
|
941
932
|
it "should not use cache if asked to reload" do
|
|
@@ -943,7 +934,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
943
934
|
d = @c2.load(:id => 1)
|
|
944
935
|
d.associations[:parent] = [42]
|
|
945
936
|
d.parent(true).should_not == 42
|
|
946
|
-
|
|
937
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.node_id = 1) LIMIT 1"]
|
|
947
938
|
end
|
|
948
939
|
|
|
949
940
|
it "should have the setter set the reciprocal many_to_one cached association" do
|
|
@@ -954,11 +945,11 @@ describe Sequel::Model, "one_to_one" do
|
|
|
954
945
|
e = @c2.load(:id => 2)
|
|
955
946
|
d.parent = e
|
|
956
947
|
e.child.should == d
|
|
957
|
-
|
|
948
|
+
DB.sqls.should == ["UPDATE nodes SET parent_id = NULL WHERE ((parent_id = 1) AND (id != 2))",
|
|
958
949
|
"UPDATE nodes SET parent_id = 1 WHERE (id = 2)"]
|
|
959
950
|
d.parent = nil
|
|
960
951
|
e.child.should == nil
|
|
961
|
-
|
|
952
|
+
DB.sqls.should == ["UPDATE nodes SET parent_id = NULL WHERE (parent_id = 1)"]
|
|
962
953
|
end
|
|
963
954
|
|
|
964
955
|
it "should have the setter remove the object from the previous associated object's reciprocal many_to_one cached association array if it exists" do
|
|
@@ -990,7 +981,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
990
981
|
c2.associations[:parent] = c1
|
|
991
982
|
c2.parent = c1
|
|
992
983
|
c1.child.should == c2
|
|
993
|
-
|
|
984
|
+
DB.sqls.should == []
|
|
994
985
|
end
|
|
995
986
|
|
|
996
987
|
it "should not add associations methods directly to class" do
|
|
@@ -1092,7 +1083,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
1092
1083
|
it "should work_correctly when used with associate" do
|
|
1093
1084
|
@c2.associate :one_to_one, :parent, :class => @c2
|
|
1094
1085
|
@c2.load(:id => 567).parent.should == @c2.load({})
|
|
1095
|
-
|
|
1086
|
+
DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.node_id = 567) LIMIT 1"]
|
|
1096
1087
|
end
|
|
1097
1088
|
end
|
|
1098
1089
|
|
|
@@ -1115,7 +1106,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1115
1106
|
@dataset = @c2.dataset
|
|
1116
1107
|
@dataset._fetch = {}
|
|
1117
1108
|
@c1.dataset._fetch = proc{|sql| sql =~ /SELECT 1/ ? {:a=>1} : {}}
|
|
1118
|
-
|
|
1109
|
+
DB.reset
|
|
1119
1110
|
end
|
|
1120
1111
|
|
|
1121
1112
|
it "should use implicit key if omitted" do
|
|
@@ -1159,7 +1150,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1159
1150
|
d = @c2.load(:id => 1234)
|
|
1160
1151
|
d.associations[:attributes] = []
|
|
1161
1152
|
d.attributes(proc{|ds| ds.filter{name > 'M'}}).should_not == []
|
|
1162
|
-
|
|
1153
|
+
DB.sqls.should == ["SELECT * FROM attributes WHERE ((attributes.nodeid = 1234) AND (name > 'M'))"]
|
|
1163
1154
|
end
|
|
1164
1155
|
|
|
1165
1156
|
it "should use explicit key if given" do
|
|
@@ -1175,7 +1166,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1175
1166
|
it "should not issue query if not all keys have values" do
|
|
1176
1167
|
@c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :id], :primary_key=>[:id, :x]
|
|
1177
1168
|
@c2.load(:id => 1234, :x=>nil).attributes.should == []
|
|
1178
|
-
|
|
1169
|
+
DB.sqls.should == []
|
|
1179
1170
|
end
|
|
1180
1171
|
|
|
1181
1172
|
it "should raise an Error unless same number of composite keys used" do
|
|
@@ -1193,7 +1184,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1193
1184
|
a = @c1.load(:id => 2345)
|
|
1194
1185
|
a.should == n.add_attribute(a)
|
|
1195
1186
|
a.values.should == {:node_id => 1234, :id => 2345}
|
|
1196
|
-
|
|
1187
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = 1234 WHERE (id = 2345)']
|
|
1197
1188
|
end
|
|
1198
1189
|
|
|
1199
1190
|
it "should define an add_ method that works on new records" do
|
|
@@ -1203,7 +1194,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1203
1194
|
a = @c1.new(:id => 234)
|
|
1204
1195
|
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:node_id => 1234, :id => 234}
|
|
1205
1196
|
a.should == n.add_attribute(a)
|
|
1206
|
-
sqls =
|
|
1197
|
+
sqls = DB.sqls
|
|
1207
1198
|
sqls.shift.should =~ /INSERT INTO attributes \((node_)?id, (node_)?id\) VALUES \(1?234, 1?234\)/
|
|
1208
1199
|
sqls.should == ["SELECT * FROM attributes WHERE (id = 234) LIMIT 1"]
|
|
1209
1200
|
a.values.should == {:node_id => 1234, :id => 234}
|
|
@@ -1216,7 +1207,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1216
1207
|
a = @c1.load(:id => 2345, :node_id => 1234)
|
|
1217
1208
|
a.should == n.remove_attribute(a)
|
|
1218
1209
|
a.values.should == {:node_id => nil, :id => 2345}
|
|
1219
|
-
|
|
1210
|
+
DB.sqls.should == ["SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1", 'UPDATE attributes SET node_id = NULL WHERE (id = 2345)']
|
|
1220
1211
|
end
|
|
1221
1212
|
|
|
1222
1213
|
it "should have the remove_ method raise an error if the passed object is not already associated" do
|
|
@@ -1226,16 +1217,16 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1226
1217
|
a = @c1.load(:id => 2345, :node_id => 1234)
|
|
1227
1218
|
@c1.dataset._fetch = []
|
|
1228
1219
|
proc{n.remove_attribute(a)}.should raise_error(Sequel::Error)
|
|
1229
|
-
|
|
1220
|
+
DB.sqls.should == ["SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1"]
|
|
1230
1221
|
end
|
|
1231
1222
|
|
|
1232
1223
|
it "should accept a hash for the add_ method and create a new record" do
|
|
1233
1224
|
@c2.one_to_many :attributes, :class => @c1
|
|
1234
1225
|
n = @c2.new(:id => 1234)
|
|
1235
|
-
|
|
1226
|
+
DB.reset
|
|
1236
1227
|
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:node_id => 1234, :id => 234}
|
|
1237
1228
|
n.add_attribute(:id => 234).should == @c1.load(:node_id => 1234, :id => 234)
|
|
1238
|
-
sqls =
|
|
1229
|
+
sqls = DB.sqls
|
|
1239
1230
|
sqls.shift.should =~ /INSERT INTO attributes \((node_)?id, (node_)?id\) VALUES \(1?234, 1?234\)/
|
|
1240
1231
|
sqls.should == ["SELECT * FROM attributes WHERE (id = 234) LIMIT 1"]
|
|
1241
1232
|
end
|
|
@@ -1245,7 +1236,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1245
1236
|
n = @c2.new(:id => 1234)
|
|
1246
1237
|
@c1.dataset._fetch = {:id=>234, :node_id=>nil}
|
|
1247
1238
|
n.add_attribute(234).should == @c1.load(:node_id => 1234, :id => 234)
|
|
1248
|
-
|
|
1239
|
+
DB.sqls.should == ["SELECT * FROM attributes WHERE id = 234", "UPDATE attributes SET node_id = 1234 WHERE (id = 234)"]
|
|
1249
1240
|
end
|
|
1250
1241
|
|
|
1251
1242
|
it "should raise an error in the add_ method if the passed associated object is not of the correct type" do
|
|
@@ -1258,7 +1249,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1258
1249
|
n = @c2.new(:id => 1234)
|
|
1259
1250
|
@c1.dataset._fetch = {:id=>234, :node_id=>1234}
|
|
1260
1251
|
n.remove_attribute(234).should == @c1.load(:node_id => nil, :id => 234)
|
|
1261
|
-
|
|
1252
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.id = 234)) LIMIT 1',
|
|
1262
1253
|
'UPDATE attributes SET node_id = NULL WHERE (id = 234)']
|
|
1263
1254
|
end
|
|
1264
1255
|
|
|
@@ -1273,7 +1264,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1273
1264
|
n = @c2.new(:id => 1234, :xxx=>5)
|
|
1274
1265
|
a = @c1.load(:id => 2345)
|
|
1275
1266
|
n.add_attribute(a).should == a
|
|
1276
|
-
|
|
1267
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = 5 WHERE (id = 2345)']
|
|
1277
1268
|
end
|
|
1278
1269
|
|
|
1279
1270
|
it "should have add_ method not add the same object to the cached association array if the object is already in the array" do
|
|
@@ -1286,7 +1277,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1286
1277
|
a.should == n.add_attribute(a)
|
|
1287
1278
|
a.values.should == {:node_id => 1234, :id => 2345}
|
|
1288
1279
|
n.attributes.should == [a]
|
|
1289
|
-
|
|
1280
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = 1234 WHERE (id = 2345)'] * 2
|
|
1290
1281
|
end
|
|
1291
1282
|
|
|
1292
1283
|
it "should have add_ method respect composite keys" do
|
|
@@ -1295,7 +1286,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1295
1286
|
n = @c2.load(:id => 1234, :x=>5)
|
|
1296
1287
|
a = @c1.load(:id => 2345)
|
|
1297
1288
|
n.add_attribute(a).should == a
|
|
1298
|
-
sqls =
|
|
1289
|
+
sqls = DB.sqls
|
|
1299
1290
|
sqls.shift.should =~ /UPDATE attributes SET (node_id = 1234|y = 5), (node_id = 1234|y = 5) WHERE \(id = 2345\)/
|
|
1300
1291
|
sqls.should == []
|
|
1301
1292
|
end
|
|
@@ -1308,7 +1299,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1308
1299
|
n = @c2.load(:id => 1234, :x=>5)
|
|
1309
1300
|
a = @c1.load(:id => 2345, :z => 8, :node_id => 1234, :y=>5)
|
|
1310
1301
|
n.add_attribute([2345, 8]).should == a
|
|
1311
|
-
sqls =
|
|
1302
|
+
sqls = DB.sqls
|
|
1312
1303
|
sqls.shift.should =~ /SELECT \* FROM attributes WHERE \(\((id|z) = (2345|8)\) AND \((id|z) = (2345|8)\)\) LIMIT 1/
|
|
1313
1304
|
sqls.shift.should =~ /UPDATE attributes SET (node_id|y) = (1234|5), (node_id|y) = (1234|5) WHERE \(\((id|z) = (2345|8)\) AND \((id|z) = (2345|8)\)\)/
|
|
1314
1305
|
sqls.should == []
|
|
@@ -1320,7 +1311,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1320
1311
|
n = @c2.load(:id => 1234, :x=>5)
|
|
1321
1312
|
a = @c1.load(:id => 2345, :node_id=>1234, :y=>5)
|
|
1322
1313
|
n.remove_attribute(a).should == a
|
|
1323
|
-
sqls =
|
|
1314
|
+
sqls = DB.sqls
|
|
1324
1315
|
sqls.pop.should =~ /UPDATE attributes SET (node_id|y) = NULL, (node_id|y) = NULL WHERE \(id = 2345\)/
|
|
1325
1316
|
sqls.should == ["SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.y = 5) AND (id = 2345)) LIMIT 1"]
|
|
1326
1317
|
end
|
|
@@ -1331,7 +1322,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1331
1322
|
n = @c2.new(:id => 123)
|
|
1332
1323
|
@c1.dataset._fetch = {:id=>234, :node_id=>123, :y=>5}
|
|
1333
1324
|
n.remove_attribute([234, 5]).should == @c1.load(:node_id => nil, :y => 5, :id => 234)
|
|
1334
|
-
sqls =
|
|
1325
|
+
sqls = DB.sqls
|
|
1335
1326
|
sqls.length.should == 2
|
|
1336
1327
|
sqls.first.should =~ /SELECT \* FROM attributes WHERE \(\(attributes.node_id = 123\) AND \(attributes\.(id|y) = (234|5)\) AND \(attributes\.(id|y) = (234|5)\)\) LIMIT 1/
|
|
1337
1328
|
sqls.last.should =~ /UPDATE attributes SET node_id = NULL WHERE \(\((id|y) = (234|5)\) AND \((id|y) = (234|5)\)\)/
|
|
@@ -1425,7 +1416,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1425
1416
|
end
|
|
1426
1417
|
@c2.new(:id => 1234).all_other_attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((nodeid != 1234) AND (xxx = 5)) ORDER BY a LIMIT 10'
|
|
1427
1418
|
@c2.new(:id => 1234).all_other_attributes.should == [@c1.load({})]
|
|
1428
|
-
|
|
1419
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE ((nodeid != 1234) AND (xxx = 5)) ORDER BY a LIMIT 10']
|
|
1429
1420
|
end
|
|
1430
1421
|
|
|
1431
1422
|
it "should support a :limit option" do
|
|
@@ -1446,7 +1437,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1446
1437
|
n.associations.include?(:attributes).should == false
|
|
1447
1438
|
atts = n.attributes
|
|
1448
1439
|
atts.should == n.associations[:attributes]
|
|
1449
|
-
|
|
1440
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1450
1441
|
end
|
|
1451
1442
|
|
|
1452
1443
|
it "should use cache if available" do
|
|
@@ -1454,7 +1445,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1454
1445
|
n = @c2.new(:id => 1234)
|
|
1455
1446
|
n.associations[:attributes] = 42
|
|
1456
1447
|
n.attributes.should == 42
|
|
1457
|
-
|
|
1448
|
+
DB.sqls.should == []
|
|
1458
1449
|
end
|
|
1459
1450
|
|
|
1460
1451
|
it "should not use cache if asked to reload" do
|
|
@@ -1462,7 +1453,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1462
1453
|
n = @c2.new(:id => 1234)
|
|
1463
1454
|
n.associations[:attributes] = 42
|
|
1464
1455
|
n.attributes(true).should_not == 42
|
|
1465
|
-
|
|
1456
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1466
1457
|
end
|
|
1467
1458
|
|
|
1468
1459
|
it "should add item to cache if it exists when calling add_" do
|
|
@@ -1540,10 +1531,10 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1540
1531
|
|
|
1541
1532
|
n = @c2.new(:id => 1234)
|
|
1542
1533
|
atts = n.attributes
|
|
1543
|
-
|
|
1534
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1544
1535
|
atts.should == [@c1.load({})]
|
|
1545
1536
|
atts.map{|a| a.node}.should == [n]
|
|
1546
|
-
|
|
1537
|
+
DB.sqls.should == []
|
|
1547
1538
|
end
|
|
1548
1539
|
|
|
1549
1540
|
it "should use an explicit :reciprocal option if given" do
|
|
@@ -1551,16 +1542,16 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1551
1542
|
|
|
1552
1543
|
n = @c2.new(:id => 1234)
|
|
1553
1544
|
atts = n.attributes
|
|
1554
|
-
|
|
1545
|
+
DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
|
1555
1546
|
atts.should == [@c1.load({})]
|
|
1556
1547
|
atts.map{|a| a.associations[:wxyz]}.should == [n]
|
|
1557
|
-
|
|
1548
|
+
DB.sqls.should == []
|
|
1558
1549
|
end
|
|
1559
1550
|
|
|
1560
1551
|
it "should have an remove_all_ method that removes all associated objects" do
|
|
1561
1552
|
@c2.one_to_many :attributes, :class => @c1
|
|
1562
1553
|
@c2.new(:id => 1234).remove_all_attributes
|
|
1563
|
-
|
|
1554
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 1234)']
|
|
1564
1555
|
end
|
|
1565
1556
|
|
|
1566
1557
|
it "should have remove_all method respect association filters" do
|
|
@@ -1568,19 +1559,19 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1568
1559
|
ds.filter(:b=>2)
|
|
1569
1560
|
end
|
|
1570
1561
|
@c2.new(:id => 1234).remove_all_attributes
|
|
1571
|
-
|
|
1562
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE ((a = 1) AND (node_id = 1234) AND (b = 2))']
|
|
1572
1563
|
end
|
|
1573
1564
|
|
|
1574
1565
|
it "should have the remove_all_ method respect the :primary_key option" do
|
|
1575
1566
|
@c2.one_to_many :attributes, :class => @c1, :primary_key=>:xxx
|
|
1576
1567
|
@c2.new(:id => 1234, :xxx=>5).remove_all_attributes
|
|
1577
|
-
|
|
1568
|
+
DB.sqls.should == ['UPDATE attributes SET node_id = NULL WHERE (node_id = 5)']
|
|
1578
1569
|
end
|
|
1579
1570
|
|
|
1580
1571
|
it "should have the remove_all_ method respect composite keys" do
|
|
1581
1572
|
@c2.one_to_many :attributes, :class => @c1, :key=>[:node_id, :y], :primary_key=>[:id, :x]
|
|
1582
1573
|
@c2.new(:id => 1234, :x=>5).remove_all_attributes
|
|
1583
|
-
sqls =
|
|
1574
|
+
sqls = DB.sqls
|
|
1584
1575
|
sqls.pop.should =~ /UPDATE attributes SET (node_id|y) = NULL, (node_id|y) = NULL WHERE \(\(node_id = 1234\) AND \(y = 5\)\)/
|
|
1585
1576
|
sqls.should == []
|
|
1586
1577
|
end
|
|
@@ -1800,11 +1791,6 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1800
1791
|
p.remove_attribute(c).should == nil
|
|
1801
1792
|
p.attributes.should == [c]
|
|
1802
1793
|
end
|
|
1803
|
-
|
|
1804
|
-
qspecify "should raise an error if trying to use the :one_to_one option" do
|
|
1805
|
-
proc{@c2.one_to_many :attribute, :class => @c1, :one_to_one=>true}.should raise_error(Sequel::Error)
|
|
1806
|
-
proc{@c2.associate :one_to_many, :attribute, :class => @c1, :one_to_one=>true}.should raise_error(Sequel::Error)
|
|
1807
|
-
end
|
|
1808
1794
|
end
|
|
1809
1795
|
|
|
1810
1796
|
describe Sequel::Model, "many_to_many" do
|
|
@@ -1829,7 +1815,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1829
1815
|
@c1.dataset.autoid = 1
|
|
1830
1816
|
|
|
1831
1817
|
[@c1, @c2].each{|c| c.dataset._fetch = {}}
|
|
1832
|
-
|
|
1818
|
+
DB.reset
|
|
1833
1819
|
end
|
|
1834
1820
|
|
|
1835
1821
|
it "should use implicit key values and join table if omitted" do
|
|
@@ -1901,7 +1887,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1901
1887
|
it "should not issue query if not all keys have values" do
|
|
1902
1888
|
@c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :y]
|
|
1903
1889
|
@c2.load(:id => 1234, :x=>nil).attributes.should == []
|
|
1904
|
-
|
|
1890
|
+
DB.sqls.should == []
|
|
1905
1891
|
end
|
|
1906
1892
|
|
|
1907
1893
|
it "should raise an Error unless same number of composite keys used" do
|
|
@@ -1959,7 +1945,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1959
1945
|
n.xxx = 555
|
|
1960
1946
|
n.attributes_dataset.sql.should == 'SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10'
|
|
1961
1947
|
n.attributes.should == [@c1.load({})]
|
|
1962
|
-
|
|
1948
|
+
DB.sqls.should == ['SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10']
|
|
1963
1949
|
end
|
|
1964
1950
|
|
|
1965
1951
|
it "should support a :dataset option that accepts the reflection as an argument" do
|
|
@@ -1971,7 +1957,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1971
1957
|
n.xxx = 555
|
|
1972
1958
|
n.attributes_dataset.sql.should == 'SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10'
|
|
1973
1959
|
n.attributes.should == [@c1.load({})]
|
|
1974
|
-
|
|
1960
|
+
DB.sqls.should == ['SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10']
|
|
1975
1961
|
end
|
|
1976
1962
|
|
|
1977
1963
|
it "should support a :limit option" do
|
|
@@ -1994,7 +1980,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1994
1980
|
a.should == n.add_attribute(a)
|
|
1995
1981
|
a.should == n.remove_attribute(a)
|
|
1996
1982
|
n.remove_all_attributes
|
|
1997
|
-
sqls =
|
|
1983
|
+
sqls = DB.sqls
|
|
1998
1984
|
['INSERT INTO attribute2node (node_id, attribute_id) VALUES (1234, 2345)',
|
|
1999
1985
|
'INSERT INTO attribute2node (attribute_id, node_id) VALUES (2345, 1234)'].should(include(sqls.shift))
|
|
2000
1986
|
["DELETE FROM attribute2node WHERE ((node_id = 1234) AND (attribute_id = 2345))",
|
|
@@ -2008,7 +1994,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2008
1994
|
n = @c2.load(:id => 1234)
|
|
2009
1995
|
a = @c1.load(:id => 2345)
|
|
2010
1996
|
n.add_attribute(a).should == a
|
|
2011
|
-
sqls =
|
|
1997
|
+
sqls = DB.sqls
|
|
2012
1998
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)',
|
|
2013
1999
|
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'].should(include(sqls.shift))
|
|
2014
2000
|
sqls.should == []
|
|
@@ -2021,7 +2007,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2021
2007
|
a = @c1.load(:id => 2345)
|
|
2022
2008
|
@c1.dataset._fetch = {:id=>2345}
|
|
2023
2009
|
n.add_attribute(2345).should == a
|
|
2024
|
-
sqls =
|
|
2010
|
+
sqls = DB.sqls
|
|
2025
2011
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)',
|
|
2026
2012
|
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (2345, 1234)'].should(include(sqls.pop))
|
|
2027
2013
|
sqls.should == ["SELECT * FROM attributes WHERE id = 2345"]
|
|
@@ -2033,7 +2019,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2033
2019
|
n = @c2.load(:id => 1234)
|
|
2034
2020
|
@c1.dataset._fetch = @c1.instance_dataset._fetch = {:id=>1}
|
|
2035
2021
|
n.add_attribute(:id => 1).should == @c1.load(:id => 1)
|
|
2036
|
-
sqls =
|
|
2022
|
+
sqls = DB.sqls
|
|
2037
2023
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 1)',
|
|
2038
2024
|
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (1, 1234)'
|
|
2039
2025
|
].should(include(sqls.pop))
|
|
@@ -2046,7 +2032,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2046
2032
|
n = @c2.new(:id => 1234)
|
|
2047
2033
|
a = @c1.new(:id => 2345)
|
|
2048
2034
|
n.remove_attribute(a).should == a
|
|
2049
|
-
|
|
2035
|
+
DB.sqls.should == ['DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 2345))']
|
|
2050
2036
|
end
|
|
2051
2037
|
|
|
2052
2038
|
it "should raise an error in the add_ method if the passed associated object is not of the correct type" do
|
|
@@ -2059,7 +2045,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2059
2045
|
n = @c2.new(:id => 1234)
|
|
2060
2046
|
@c1.dataset._fetch = {:id=>234}
|
|
2061
2047
|
n.remove_attribute(234).should == @c1.load(:id => 234)
|
|
2062
|
-
|
|
2048
|
+
DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (attributes.id = 234) LIMIT 1",
|
|
2063
2049
|
"DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))"]
|
|
2064
2050
|
end
|
|
2065
2051
|
|
|
@@ -2074,7 +2060,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2074
2060
|
n = @c2.load(:id => 1234).set(:xxx=>5)
|
|
2075
2061
|
a = @c1.load(:id => 2345).set(:yyy=>8)
|
|
2076
2062
|
n.add_attribute(a).should == a
|
|
2077
|
-
sqls =
|
|
2063
|
+
sqls = DB.sqls
|
|
2078
2064
|
['INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (5, 8)',
|
|
2079
2065
|
'INSERT INTO attributes_nodes (attribute_id, node_id) VALUES (8, 5)'
|
|
2080
2066
|
].should(include(sqls.pop))
|
|
@@ -2097,7 +2083,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2097
2083
|
n = @c2.load(:id => 1234, :x=>5)
|
|
2098
2084
|
a = @c1.load(:id => 2345, :z=>8)
|
|
2099
2085
|
a.should == n.add_attribute(a)
|
|
2100
|
-
sqls =
|
|
2086
|
+
sqls = DB.sqls
|
|
2101
2087
|
m = /INSERT INTO attributes_nodes \((\w+), (\w+), (\w+), (\w+)\) VALUES \((\d+), (\d+), (\d+), (\d+)\)/.match(sqls.pop)
|
|
2102
2088
|
sqls.should == []
|
|
2103
2089
|
m.should_not == nil
|
|
@@ -2121,7 +2107,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2121
2107
|
a = @c1.load(:id => 2345, :z=>8)
|
|
2122
2108
|
@c1.dataset._fetch = {:id => 2345, :z=>8}
|
|
2123
2109
|
n.add_attribute([2345, 8]).should == a
|
|
2124
|
-
sqls =
|
|
2110
|
+
sqls = DB.sqls
|
|
2125
2111
|
sqls.shift.should =~ /SELECT \* FROM attributes WHERE \(\((id|z) = (8|2345)\) AND \((id|z) = (8|2345)\)\) LIMIT 1/
|
|
2126
2112
|
sqls.pop.should =~ /INSERT INTO attributes_nodes \([lr][12], [lr][12], [lr][12], [lr][12]\) VALUES \((1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8), (1234|5|2345|8)\)/
|
|
2127
2113
|
sqls.should == []
|
|
@@ -2133,7 +2119,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2133
2119
|
n = @c2.new(:id => 1234, :xxx=>5)
|
|
2134
2120
|
a = @c1.new(:id => 2345, :yyy=>8)
|
|
2135
2121
|
n.remove_attribute(a).should == a
|
|
2136
|
-
|
|
2122
|
+
DB.sqls.should == ['DELETE FROM attributes_nodes WHERE ((node_id = 5) AND (attribute_id = 8))']
|
|
2137
2123
|
end
|
|
2138
2124
|
|
|
2139
2125
|
it "should have the remove_ method respect composite keys" do
|
|
@@ -2141,7 +2127,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2141
2127
|
n = @c2.load(:id => 1234, :x=>5)
|
|
2142
2128
|
a = @c1.load(:id => 2345, :z=>8)
|
|
2143
2129
|
a.should == n.remove_attribute(a)
|
|
2144
|
-
|
|
2130
|
+
DB.sqls.should == ["DELETE FROM attributes_nodes WHERE ((l1 = 1234) AND (l2 = 5) AND (r1 = 2345) AND (r2 = 8))"]
|
|
2145
2131
|
end
|
|
2146
2132
|
|
|
2147
2133
|
it "should accept a array of composite primary key values for the remove_ method and remove an existing record" do
|
|
@@ -2150,7 +2136,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2150
2136
|
n = @c2.new(:id => 1234)
|
|
2151
2137
|
@c1.dataset._fetch = {:id=>234, :y=>8}
|
|
2152
2138
|
@c1.load(:id => 234, :y=>8).should == n.remove_attribute([234, 8])
|
|
2153
|
-
sqls =
|
|
2139
|
+
sqls = DB.sqls
|
|
2154
2140
|
["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.id = 234) AND (attributes.y = 8)) LIMIT 1",
|
|
2155
2141
|
"SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE ((attributes.y = 8) AND (attributes.id = 234)) LIMIT 1"].should include(sqls.shift)
|
|
2156
2142
|
sqls.should == ["DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))"]
|
|
@@ -2214,7 +2200,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2214
2200
|
@c2.many_to_many :attributes, :class => @c1
|
|
2215
2201
|
|
|
2216
2202
|
@c2.new(:id => 1234).attributes.should == [@c1.load({})]
|
|
2217
|
-
|
|
2203
|
+
DB.sqls.should == ['SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))']
|
|
2218
2204
|
end
|
|
2219
2205
|
|
|
2220
2206
|
it "should populate cache when accessed" do
|
|
@@ -2232,7 +2218,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2232
2218
|
n = @c2.new(:id => 1234)
|
|
2233
2219
|
n.associations[:attributes] = 42
|
|
2234
2220
|
n.attributes.should == 42
|
|
2235
|
-
|
|
2221
|
+
DB.sqls.should == []
|
|
2236
2222
|
end
|
|
2237
2223
|
|
|
2238
2224
|
it "should not use cache if asked to reload" do
|
|
@@ -2241,7 +2227,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2241
2227
|
n = @c2.new(:id => 1234)
|
|
2242
2228
|
n.associations[:attributes] = 42
|
|
2243
2229
|
n.attributes(true).should_not == 42
|
|
2244
|
-
|
|
2230
|
+
DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))"]
|
|
2245
2231
|
end
|
|
2246
2232
|
|
|
2247
2233
|
it "should add item to cache if it exists when calling add_" do
|
|
@@ -2317,19 +2303,19 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2317
2303
|
it "should have an remove_all_ method that removes all associations" do
|
|
2318
2304
|
@c2.many_to_many :attributes, :class => @c1
|
|
2319
2305
|
@c2.new(:id => 1234).remove_all_attributes
|
|
2320
|
-
|
|
2306
|
+
DB.sqls.should == ['DELETE FROM attributes_nodes WHERE (node_id = 1234)']
|
|
2321
2307
|
end
|
|
2322
2308
|
|
|
2323
2309
|
it "should have the remove_all_ method respect the :left_primary_key option" do
|
|
2324
2310
|
@c2.many_to_many :attributes, :class => @c1, :left_primary_key=>:xxx
|
|
2325
2311
|
@c2.new(:id => 1234, :xxx=>5).remove_all_attributes
|
|
2326
|
-
|
|
2312
|
+
DB.sqls.should == ['DELETE FROM attributes_nodes WHERE (node_id = 5)']
|
|
2327
2313
|
end
|
|
2328
2314
|
|
|
2329
2315
|
it "should have the remove_all_ method respect composite keys" do
|
|
2330
2316
|
@c2.many_to_many :attributes, :class => @c1, :left_primary_key=>[:id, :x], :left_key=>[:l1, :l2]
|
|
2331
2317
|
@c2.load(:id => 1234, :x=>5).remove_all_attributes
|
|
2332
|
-
|
|
2318
|
+
DB.sqls.should == ['DELETE FROM attributes_nodes WHERE ((l1 = 1234) AND (l2 = 5))']
|
|
2333
2319
|
end
|
|
2334
2320
|
|
|
2335
2321
|
it "remove_all should set the cached instance variable to []" do
|
|
@@ -2376,7 +2362,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2376
2362
|
o.add_attribute(@c1.load(:id=>44))
|
|
2377
2363
|
o.remove_attribute(@c1.load(:id=>45))
|
|
2378
2364
|
o.remove_all_attributes
|
|
2379
|
-
sqls =
|
|
2365
|
+
sqls = DB.sqls
|
|
2380
2366
|
sqls.shift =~ /INSERT INTO attributes_nodes \((node_id|attribute_id), (node_id|attribute_id)\) VALUES \((1234|44), (1234|44)\)/
|
|
2381
2367
|
sqls.should == ["DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234) AND (attribute_id = 45))",
|
|
2382
2368
|
"DELETE FROM attributes_nodes WHERE ((x = 123) AND (node_id = 1234))"]
|
|
@@ -2392,7 +2378,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2392
2378
|
end
|
|
2393
2379
|
p.add_attribute(c)
|
|
2394
2380
|
p.instance_variable_get(:@x).should == c
|
|
2395
|
-
|
|
2381
|
+
DB.sqls.should == []
|
|
2396
2382
|
end
|
|
2397
2383
|
|
|
2398
2384
|
it "should support an :adder option for defining the _add_ method" do
|
|
@@ -2401,7 +2387,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2401
2387
|
c = @c1.load(:id=>123)
|
|
2402
2388
|
p.add_attribute(c)
|
|
2403
2389
|
p.instance_variable_get(:@x).should == c
|
|
2404
|
-
|
|
2390
|
+
DB.sqls.should == []
|
|
2405
2391
|
end
|
|
2406
2392
|
|
|
2407
2393
|
it "should allow additional arguments given to the add_ method and pass them onwards to the _add_ method" do
|
|
@@ -2427,7 +2413,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2427
2413
|
end
|
|
2428
2414
|
p.remove_attribute(c)
|
|
2429
2415
|
p.instance_variable_get(:@x).should == c
|
|
2430
|
-
|
|
2416
|
+
DB.sqls.should == []
|
|
2431
2417
|
end
|
|
2432
2418
|
|
|
2433
2419
|
it "should support a :remover option for defining the _remove_ method" do
|
|
@@ -2436,7 +2422,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2436
2422
|
c = @c1.load(:id=>123)
|
|
2437
2423
|
p.remove_attribute(c)
|
|
2438
2424
|
p.instance_variable_get(:@x).should == c
|
|
2439
|
-
|
|
2425
|
+
DB.sqls.should == []
|
|
2440
2426
|
end
|
|
2441
2427
|
|
|
2442
2428
|
it "should allow additional arguments given to the remove_ method and pass them onwards to the _remove_ method" do
|
|
@@ -2471,7 +2457,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2471
2457
|
end
|
|
2472
2458
|
p.remove_all_attributes
|
|
2473
2459
|
p.instance_variable_get(:@x).should == :foo
|
|
2474
|
-
|
|
2460
|
+
DB.sqls.should == []
|
|
2475
2461
|
end
|
|
2476
2462
|
|
|
2477
2463
|
it "should support a :clearer option for defining the _remove_all_ method" do
|
|
@@ -2479,7 +2465,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2479
2465
|
p = @c2.load(:id=>10)
|
|
2480
2466
|
p.remove_all_attributes
|
|
2481
2467
|
p.instance_variable_get(:@x).should == :foo
|
|
2482
|
-
|
|
2468
|
+
DB.sqls.should == []
|
|
2483
2469
|
end
|
|
2484
2470
|
|
|
2485
2471
|
it "should support (before|after)_(add|remove) callbacks" do
|
|
@@ -2575,7 +2561,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2575
2561
|
ds.filter(:name=>'John')
|
|
2576
2562
|
end
|
|
2577
2563
|
@c2.load(:id=>1).remove_all_attributes
|
|
2578
|
-
|
|
2564
|
+
DB.sqls.should == ["DELETE FROM attributes_nodes WHERE (node_id = 1)"]
|
|
2579
2565
|
end
|
|
2580
2566
|
|
|
2581
2567
|
it "should use assocation's dataset when grabbing a record to remove from the assocation by primary key" do
|
|
@@ -2584,7 +2570,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
2584
2570
|
end
|
|
2585
2571
|
@c1.dataset._fetch = {:id=>2}
|
|
2586
2572
|
@c2.load(:id=>1).remove_attribute(2)
|
|
2587
|
-
|
|
2573
|
+
DB.sqls.should == ["SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1)) WHERE ((join_table_att = 3) AND (attributes.id = 2)) LIMIT 1",
|
|
2588
2574
|
"DELETE FROM attributes_nodes WHERE ((node_id = 1) AND (attribute_id = 2))"]
|
|
2589
2575
|
end
|
|
2590
2576
|
end
|
|
@@ -3227,47 +3213,13 @@ describe "Sequel::Model Associations with non-column expression keys" do
|
|
|
3227
3213
|
end
|
|
3228
3214
|
end
|
|
3229
3215
|
|
|
3230
|
-
describe "Model#pk_or_nil" do
|
|
3231
|
-
before do
|
|
3232
|
-
@m = Class.new(Sequel::Model)
|
|
3233
|
-
@m.columns :id, :x, :y
|
|
3234
|
-
end
|
|
3235
|
-
|
|
3236
|
-
qspecify "should be default return the value of the :id column" do
|
|
3237
|
-
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
3238
|
-
m.pk_or_nil.should == 111
|
|
3239
|
-
end
|
|
3240
|
-
|
|
3241
|
-
qspecify "should be return the primary key value for custom primary key" do
|
|
3242
|
-
@m.set_primary_key :x
|
|
3243
|
-
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
3244
|
-
m.pk_or_nil.should == 2
|
|
3245
|
-
end
|
|
3246
|
-
|
|
3247
|
-
qspecify "should be return the primary key value for composite primary key" do
|
|
3248
|
-
@m.set_primary_key [:y, :x]
|
|
3249
|
-
m = @m.load(:id => 111, :x => 2, :y => 3)
|
|
3250
|
-
m.pk_or_nil.should == [3, 2]
|
|
3251
|
-
end
|
|
3252
|
-
|
|
3253
|
-
qspecify "should not raise if no primary key" do
|
|
3254
|
-
@m.set_primary_key nil
|
|
3255
|
-
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
3256
|
-
m.pk_or_nil.should be_nil
|
|
3257
|
-
|
|
3258
|
-
@m.no_primary_key
|
|
3259
|
-
m = @m.new(:id => 111, :x => 2, :y => 3)
|
|
3260
|
-
m.pk_or_nil.should be_nil
|
|
3261
|
-
end
|
|
3262
|
-
end
|
|
3263
|
-
|
|
3264
3216
|
describe Sequel::Model, "#refresh" do
|
|
3265
3217
|
before do
|
|
3266
3218
|
@c = Class.new(Sequel::Model(:items)) do
|
|
3267
3219
|
unrestrict_primary_key
|
|
3268
3220
|
columns :id, :x
|
|
3269
3221
|
end
|
|
3270
|
-
|
|
3222
|
+
DB.reset
|
|
3271
3223
|
end
|
|
3272
3224
|
|
|
3273
3225
|
specify "should remove cached associations" do
|
|
@@ -3290,7 +3242,7 @@ describe "Model#freeze" do
|
|
|
3290
3242
|
one_to_one :b, :key=>:album_id, :class=>B
|
|
3291
3243
|
end
|
|
3292
3244
|
@o = Album.load(:id=>1).freeze
|
|
3293
|
-
|
|
3245
|
+
DB.sqls
|
|
3294
3246
|
end
|
|
3295
3247
|
after do
|
|
3296
3248
|
Object.send(:remove_const, :Album)
|
|
@@ -3312,3 +3264,102 @@ describe "Model#freeze" do
|
|
|
3312
3264
|
@o.associations[:b].should be_nil
|
|
3313
3265
|
end
|
|
3314
3266
|
end
|
|
3267
|
+
|
|
3268
|
+
describe "association autoreloading" do
|
|
3269
|
+
before do
|
|
3270
|
+
@c = Class.new(Sequel::Model)
|
|
3271
|
+
@Artist = Class.new(@c).set_dataset(:artists)
|
|
3272
|
+
@Artist.dataset._fetch = {:id=>2, :name=>'Ar'}
|
|
3273
|
+
@Album = Class.new(@c).set_dataset(:albums)
|
|
3274
|
+
@Artist.columns :id, :name
|
|
3275
|
+
@Album.columns :id, :name, :artist_id
|
|
3276
|
+
@Album.db_schema[:artist_id][:type] = :integer
|
|
3277
|
+
@Album.many_to_one :artist, :class=>@Artist
|
|
3278
|
+
DB.reset
|
|
3279
|
+
end
|
|
3280
|
+
|
|
3281
|
+
specify "should reload many_to_one association when foreign key is modified" do
|
|
3282
|
+
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
3283
|
+
album.artist
|
|
3284
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 2']
|
|
3285
|
+
|
|
3286
|
+
album.artist_id = 1
|
|
3287
|
+
album.artist
|
|
3288
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 1']
|
|
3289
|
+
end
|
|
3290
|
+
|
|
3291
|
+
specify "should handle multiple many_to_one association with the same foreign key" do
|
|
3292
|
+
@Album.many_to_one :artist2, :key=>:artist_id, :class=>@Artist
|
|
3293
|
+
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
3294
|
+
album.artist
|
|
3295
|
+
album.artist2
|
|
3296
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 2'] * 2
|
|
3297
|
+
|
|
3298
|
+
album.artist
|
|
3299
|
+
album.artist2
|
|
3300
|
+
DB.sqls.should == []
|
|
3301
|
+
|
|
3302
|
+
album.artist_id = 1
|
|
3303
|
+
album.artist
|
|
3304
|
+
album.artist2
|
|
3305
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 1'] * 2
|
|
3306
|
+
end
|
|
3307
|
+
|
|
3308
|
+
specify "should not reload when value has not changed" do
|
|
3309
|
+
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
3310
|
+
album.artist
|
|
3311
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 2']
|
|
3312
|
+
|
|
3313
|
+
album.artist_id = 2
|
|
3314
|
+
album.artist
|
|
3315
|
+
DB.sqls.should == []
|
|
3316
|
+
|
|
3317
|
+
album.artist_id = "2"
|
|
3318
|
+
album.artist
|
|
3319
|
+
DB.sqls.should == []
|
|
3320
|
+
end
|
|
3321
|
+
|
|
3322
|
+
specify "should reload all associations which use the foreign key" do
|
|
3323
|
+
@Album.many_to_one :other_artist, :key => :artist_id, :foreign_key => :id, :class => @Artist
|
|
3324
|
+
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
3325
|
+
album.artist
|
|
3326
|
+
album.other_artist
|
|
3327
|
+
DB.reset
|
|
3328
|
+
|
|
3329
|
+
album.artist_id = 1
|
|
3330
|
+
album.artist
|
|
3331
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 1']
|
|
3332
|
+
|
|
3333
|
+
album.other_artist
|
|
3334
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 1']
|
|
3335
|
+
end
|
|
3336
|
+
|
|
3337
|
+
specify "should work with composite keys" do
|
|
3338
|
+
@Album.many_to_one :composite_artist, :key => [:artist_id, :name], :primary_key => [:id, :name], :class => @Artist
|
|
3339
|
+
album = @Album.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
3340
|
+
album.composite_artist
|
|
3341
|
+
DB.reset
|
|
3342
|
+
|
|
3343
|
+
album.artist_id = 1
|
|
3344
|
+
album.composite_artist
|
|
3345
|
+
DB.sqls.should == ["SELECT * FROM artists WHERE ((artists.id = 1) AND (artists.name = 'Al')) LIMIT 1"]
|
|
3346
|
+
|
|
3347
|
+
album.name = 'Al2'
|
|
3348
|
+
album.composite_artist
|
|
3349
|
+
DB.sqls.should == ["SELECT * FROM artists WHERE ((artists.id = 1) AND (artists.name = 'Al2')) LIMIT 1"]
|
|
3350
|
+
end
|
|
3351
|
+
|
|
3352
|
+
specify "should work with subclasses" do
|
|
3353
|
+
salbum = Class.new(@Album)
|
|
3354
|
+
oartist = Class.new(@c).set_dataset(:oartist)
|
|
3355
|
+
oartist.columns :id, :name
|
|
3356
|
+
salbum.many_to_one :artist2, :class=>oartist, :key=>:artist_id
|
|
3357
|
+
album = salbum.load(:id => 1, :name=>'Al', :artist_id=>2)
|
|
3358
|
+
album.artist
|
|
3359
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 2']
|
|
3360
|
+
|
|
3361
|
+
album.artist_id = 1
|
|
3362
|
+
album.artist
|
|
3363
|
+
DB.sqls.should == ['SELECT * FROM artists WHERE id = 1']
|
|
3364
|
+
end
|
|
3365
|
+
end
|