sequel 4.22.0 → 4.23.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 +22 -0
- data/README.rdoc +6 -0
- data/Rakefile +59 -81
- data/doc/migration.rdoc +2 -0
- data/doc/release_notes/4.23.0.txt +65 -0
- data/doc/sharding.rdoc +16 -14
- data/doc/testing.rdoc +61 -77
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/mock.rb +0 -1
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/postgresql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +9 -1
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/transactions.rb +2 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/extensions/constraint_validations.rb +12 -12
- data/lib/sequel/extensions/date_arithmetic.rb +0 -4
- data/lib/sequel/extensions/pagination.rb +14 -2
- data/lib/sequel/extensions/pg_enum.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/delay_add_association.rb +50 -0
- data/lib/sequel/plugins/list.rb +2 -2
- data/lib/sequel/plugins/nested_attributes.rb +8 -28
- data/lib/sequel/plugins/update_refresh.rb +50 -0
- data/lib/sequel/plugins/validate_associated.rb +55 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +29 -29
- data/spec/adapters/firebird_spec.rb +97 -103
- data/spec/adapters/informix_spec.rb +25 -25
- data/spec/adapters/mssql_spec.rb +156 -172
- data/spec/adapters/mysql_spec.rb +334 -359
- data/spec/adapters/oracle_spec.rb +67 -69
- data/spec/adapters/postgres_spec.rb +1298 -1249
- data/spec/adapters/spec_helper.rb +2 -35
- data/spec/adapters/sqlanywhere_spec.rb +39 -39
- data/spec/adapters/sqlite_spec.rb +203 -200
- data/spec/bin_spec.rb +57 -59
- data/spec/core/connection_pool_spec.rb +402 -401
- data/spec/core/database_spec.rb +953 -944
- data/spec/core/dataset_spec.rb +2178 -2168
- data/spec/core/deprecated_spec.rb +19 -19
- data/spec/core/expression_filters_spec.rb +415 -415
- data/spec/core/mock_adapter_spec.rb +212 -212
- data/spec/core/object_graph_spec.rb +73 -73
- data/spec/core/placeholder_literalizer_spec.rb +71 -71
- data/spec/core/schema_generator_spec.rb +44 -44
- data/spec/core/schema_spec.rb +470 -472
- data/spec/core/spec_helper.rb +5 -20
- data/spec/core/version_spec.rb +2 -2
- data/spec/core_extensions_spec.rb +320 -320
- data/spec/extensions/accessed_columns_spec.rb +12 -12
- data/spec/extensions/active_model_spec.rb +3 -3
- data/spec/extensions/after_initialize_spec.rb +2 -2
- data/spec/extensions/arbitrary_servers_spec.rb +23 -23
- data/spec/extensions/association_dependencies_spec.rb +34 -34
- data/spec/extensions/association_pks_spec.rb +98 -98
- data/spec/extensions/association_proxies_spec.rb +33 -33
- data/spec/extensions/auto_validations_spec.rb +46 -46
- data/spec/extensions/blacklist_security_spec.rb +19 -18
- data/spec/extensions/blank_spec.rb +36 -36
- data/spec/extensions/boolean_readers_spec.rb +36 -36
- data/spec/extensions/caching_spec.rb +82 -82
- data/spec/extensions/class_table_inheritance_spec.rb +72 -72
- data/spec/extensions/column_conflicts_spec.rb +19 -14
- data/spec/extensions/column_select_spec.rb +19 -19
- data/spec/extensions/columns_introspection_spec.rb +43 -43
- data/spec/extensions/composition_spec.rb +64 -64
- data/spec/extensions/connection_validator_spec.rb +92 -90
- data/spec/extensions/constraint_validations_plugin_spec.rb +92 -92
- data/spec/extensions/constraint_validations_spec.rb +80 -80
- data/spec/extensions/core_refinements_spec.rb +220 -220
- data/spec/extensions/csv_serializer_spec.rb +44 -44
- data/spec/extensions/current_datetime_timestamp_spec.rb +8 -8
- data/spec/extensions/dataset_associations_spec.rb +65 -65
- data/spec/extensions/dataset_source_alias_spec.rb +16 -16
- data/spec/extensions/date_arithmetic_spec.rb +51 -58
- data/spec/extensions/defaults_setter_spec.rb +19 -19
- data/spec/extensions/delay_add_association_spec.rb +52 -0
- data/spec/extensions/dirty_spec.rb +51 -51
- data/spec/extensions/eager_each_spec.rb +8 -8
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +10 -10
- data/spec/extensions/error_splitter_spec.rb +2 -2
- data/spec/extensions/error_sql_spec.rb +4 -4
- data/spec/extensions/eval_inspect_spec.rb +3 -3
- data/spec/extensions/filter_having_spec.rb +8 -8
- data/spec/extensions/force_encoding_spec.rb +30 -30
- data/spec/extensions/from_block_spec.rb +7 -7
- data/spec/extensions/graph_each_spec.rb +19 -19
- data/spec/extensions/hash_aliases_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +100 -100
- data/spec/extensions/inflector_spec.rb +54 -54
- data/spec/extensions/input_transformer_spec.rb +10 -10
- data/spec/extensions/insert_returning_select_spec.rb +8 -8
- data/spec/extensions/instance_filters_spec.rb +26 -26
- data/spec/extensions/instance_hooks_spec.rb +85 -85
- data/spec/extensions/json_serializer_spec.rb +68 -68
- data/spec/extensions/lazy_attributes_spec.rb +49 -49
- data/spec/extensions/list_spec.rb +77 -75
- data/spec/extensions/looser_typecasting_spec.rb +16 -16
- data/spec/extensions/many_through_many_spec.rb +627 -627
- data/spec/extensions/meta_def_spec.rb +7 -7
- data/spec/extensions/migration_spec.rb +217 -217
- data/spec/extensions/modification_detection_spec.rb +20 -20
- data/spec/extensions/mssql_optimistic_locking_spec.rb +21 -21
- data/spec/extensions/named_timezones_spec.rb +18 -18
- data/spec/extensions/nested_attributes_spec.rb +107 -107
- data/spec/extensions/null_dataset_spec.rb +24 -24
- data/spec/extensions/optimistic_locking_spec.rb +21 -21
- data/spec/extensions/pagination_spec.rb +52 -52
- data/spec/extensions/pg_array_associations_spec.rb +273 -273
- data/spec/extensions/pg_array_ops_spec.rb +52 -52
- data/spec/extensions/pg_array_spec.rb +152 -152
- data/spec/extensions/pg_enum_spec.rb +13 -13
- data/spec/extensions/pg_hstore_ops_spec.rb +63 -63
- data/spec/extensions/pg_hstore_spec.rb +84 -84
- data/spec/extensions/pg_inet_spec.rb +15 -15
- data/spec/extensions/pg_interval_spec.rb +29 -29
- data/spec/extensions/pg_json_ops_spec.rb +86 -84
- data/spec/extensions/pg_json_spec.rb +104 -104
- data/spec/extensions/pg_loose_count_spec.rb +6 -6
- data/spec/extensions/pg_range_ops_spec.rb +24 -24
- data/spec/extensions/pg_range_spec.rb +143 -143
- data/spec/extensions/pg_row_ops_spec.rb +14 -14
- data/spec/extensions/pg_row_plugin_spec.rb +12 -12
- data/spec/extensions/pg_row_spec.rb +118 -118
- data/spec/extensions/pg_static_cache_updater_spec.rb +28 -28
- data/spec/extensions/pg_typecast_on_load_spec.rb +21 -21
- data/spec/extensions/prepared_statements_associations_spec.rb +42 -42
- data/spec/extensions/prepared_statements_safe_spec.rb +18 -18
- data/spec/extensions/prepared_statements_spec.rb +28 -28
- data/spec/extensions/prepared_statements_with_pk_spec.rb +11 -11
- data/spec/extensions/pretty_table_spec.rb +16 -16
- data/spec/extensions/query_literals_spec.rb +37 -37
- data/spec/extensions/query_spec.rb +32 -32
- data/spec/extensions/rcte_tree_spec.rb +141 -141
- data/spec/extensions/round_timestamps_spec.rb +21 -21
- data/spec/extensions/schema_caching_spec.rb +8 -8
- data/spec/extensions/schema_dumper_spec.rb +78 -78
- data/spec/extensions/schema_spec.rb +31 -27
- data/spec/extensions/scissors_spec.rb +3 -3
- data/spec/extensions/select_remove_spec.rb +14 -14
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +28 -28
- data/spec/extensions/serialization_modification_detection_spec.rb +33 -33
- data/spec/extensions/serialization_spec.rb +79 -78
- data/spec/extensions/server_block_spec.rb +17 -17
- data/spec/extensions/set_overrides_spec.rb +30 -30
- data/spec/extensions/sharding_spec.rb +65 -65
- data/spec/extensions/shared_caching_spec.rb +29 -29
- data/spec/extensions/single_table_inheritance_spec.rb +79 -79
- data/spec/extensions/skip_create_refresh_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +4 -29
- data/spec/extensions/split_array_nil_spec.rb +9 -9
- data/spec/extensions/split_values_spec.rb +7 -7
- data/spec/extensions/sql_expr_spec.rb +32 -32
- data/spec/extensions/static_cache_spec.rb +123 -123
- data/spec/extensions/string_date_time_spec.rb +34 -34
- data/spec/extensions/string_stripper_spec.rb +15 -15
- data/spec/extensions/subclasses_spec.rb +31 -31
- data/spec/extensions/table_select_spec.rb +15 -15
- data/spec/extensions/tactical_eager_loading_spec.rb +23 -23
- data/spec/extensions/thread_local_timezones_spec.rb +13 -13
- data/spec/extensions/timestamps_spec.rb +40 -40
- data/spec/extensions/to_dot_spec.rb +34 -34
- data/spec/extensions/touch_spec.rb +52 -52
- data/spec/extensions/tree_spec.rb +72 -72
- data/spec/extensions/typecast_on_load_spec.rb +25 -25
- data/spec/extensions/unlimited_update_spec.rb +2 -2
- data/spec/extensions/update_or_create_spec.rb +36 -36
- data/spec/extensions/update_primary_key_spec.rb +35 -35
- data/spec/extensions/update_refresh_spec.rb +41 -0
- data/spec/extensions/validate_associated_spec.rb +52 -0
- data/spec/extensions/validation_class_methods_spec.rb +314 -317
- data/spec/extensions/validation_helpers_spec.rb +195 -195
- data/spec/extensions/xml_serializer_spec.rb +48 -48
- data/spec/guards_helper.rb +55 -0
- data/spec/integration/associations_test.rb +1089 -1088
- data/spec/integration/database_test.rb +29 -29
- data/spec/integration/dataset_test.rb +661 -661
- data/spec/integration/eager_loader_test.rb +147 -147
- data/spec/integration/migrator_test.rb +122 -122
- data/spec/integration/model_test.rb +70 -70
- data/spec/integration/plugin_test.rb +682 -640
- data/spec/integration/prepared_statement_test.rb +172 -172
- data/spec/integration/schema_test.rb +245 -245
- data/spec/integration/spec_helper.rb +1 -64
- data/spec/integration/timezone_test.rb +17 -17
- data/spec/integration/transaction_test.rb +87 -87
- data/spec/integration/type_test.rb +33 -33
- data/spec/model/association_reflection_spec.rb +130 -121
- data/spec/model/associations_spec.rb +1112 -1113
- data/spec/model/base_spec.rb +197 -196
- data/spec/model/class_dataset_methods_spec.rb +118 -118
- data/spec/model/dataset_methods_spec.rb +49 -49
- data/spec/model/eager_loading_spec.rb +705 -702
- data/spec/model/hooks_spec.rb +169 -168
- data/spec/model/inflector_spec.rb +5 -5
- data/spec/model/model_spec.rb +287 -297
- data/spec/model/plugins_spec.rb +47 -47
- data/spec/model/record_spec.rb +534 -535
- data/spec/model/spec_helper.rb +3 -21
- data/spec/model/validations_spec.rb +72 -70
- data/spec/spec_config.rb +8 -0
- metadata +41 -9
- data/lib/sequel/adapters/fdbsql.rb +0 -286
- data/lib/sequel/adapters/jdbc/fdbsql.rb +0 -66
- data/lib/sequel/adapters/openbase.rb +0 -54
- data/lib/sequel/adapters/shared/fdbsql.rb +0 -550
- data/spec/adapters/fdbsql_spec.rb +0 -429
- data/spec/rspec_helper.rb +0 -22
|
@@ -16,78 +16,78 @@ describe Sequel::Model, "BooleanReaders plugin" do
|
|
|
16
16
|
@c.instance_eval(&@p)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
it "should create attribute? readers for all boolean attributes" do
|
|
20
20
|
@c.plugin(:boolean_readers)
|
|
21
21
|
o = @c.new
|
|
22
|
-
o.b?.
|
|
22
|
+
o.b?.must_equal nil
|
|
23
23
|
o.b = '1'
|
|
24
|
-
o.b?.
|
|
24
|
+
o.b?.must_equal true
|
|
25
25
|
o.b = '0'
|
|
26
|
-
o.b?.
|
|
26
|
+
o.b?.must_equal false
|
|
27
27
|
o.b = ''
|
|
28
|
-
o.b?.
|
|
28
|
+
o.b?.must_equal nil
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
it "should not create attribute? readers for non-boolean attributes" do
|
|
32
32
|
@c.plugin(:boolean_readers)
|
|
33
|
-
proc{@c.new.z?}.
|
|
34
|
-
proc{@c.new.id?}.
|
|
33
|
+
proc{@c.new.z?}.must_raise(NoMethodError)
|
|
34
|
+
proc{@c.new.id?}.must_raise(NoMethodError)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
it "should accept a block to determine if an attribute is boolean" do
|
|
38
38
|
@c.plugin(:boolean_readers){|c| db_schema[c][:db_type] == 'tinyint(1)'}
|
|
39
|
-
proc{@c.new.b?}.
|
|
39
|
+
proc{@c.new.b?}.must_raise(NoMethodError)
|
|
40
40
|
o = @c.new
|
|
41
|
-
o.z.
|
|
42
|
-
o.z?.
|
|
41
|
+
o.z.must_equal nil
|
|
42
|
+
o.z?.must_equal nil
|
|
43
43
|
o.z = '1'
|
|
44
|
-
o.z.
|
|
45
|
-
o.z?.
|
|
44
|
+
o.z.must_equal 1
|
|
45
|
+
o.z?.must_equal true
|
|
46
46
|
o.z = '0'
|
|
47
|
-
o.z.
|
|
48
|
-
o.z?.
|
|
47
|
+
o.z.must_equal 0
|
|
48
|
+
o.z?.must_equal false
|
|
49
49
|
o.z = ''
|
|
50
|
-
o.z.
|
|
51
|
-
o.z?.
|
|
50
|
+
o.z.must_equal nil
|
|
51
|
+
o.z?.must_equal nil
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
it "should create boolean readers when set_dataset is defined" do
|
|
55
55
|
c = Class.new(Sequel::Model(@db))
|
|
56
56
|
c.instance_eval(&@p)
|
|
57
57
|
c.plugin(:boolean_readers)
|
|
58
58
|
c.set_dataset(@db[:a])
|
|
59
59
|
o = c.new
|
|
60
|
-
o.b?.
|
|
60
|
+
o.b?.must_equal nil
|
|
61
61
|
o.b = '1'
|
|
62
|
-
o.b?.
|
|
62
|
+
o.b?.must_equal true
|
|
63
63
|
o.b = '0'
|
|
64
|
-
o.b?.
|
|
64
|
+
o.b?.must_equal false
|
|
65
65
|
o.b = ''
|
|
66
|
-
o.b?.
|
|
67
|
-
proc{o.i?}.
|
|
66
|
+
o.b?.must_equal nil
|
|
67
|
+
proc{o.i?}.must_raise(NoMethodError)
|
|
68
68
|
|
|
69
69
|
c = Class.new(Sequel::Model(@db))
|
|
70
70
|
c.instance_eval(&@p)
|
|
71
71
|
c.plugin(:boolean_readers){|x| db_schema[x][:db_type] == 'tinyint(1)'}
|
|
72
72
|
c.set_dataset(@db[:a])
|
|
73
73
|
o = c.new
|
|
74
|
-
o.z.
|
|
75
|
-
o.z?.
|
|
74
|
+
o.z.must_equal nil
|
|
75
|
+
o.z?.must_equal nil
|
|
76
76
|
o.z = '1'
|
|
77
|
-
o.z.
|
|
78
|
-
o.z?.
|
|
77
|
+
o.z.must_equal 1
|
|
78
|
+
o.z?.must_equal true
|
|
79
79
|
o.z = '0'
|
|
80
|
-
o.z.
|
|
81
|
-
o.z?.
|
|
80
|
+
o.z.must_equal 0
|
|
81
|
+
o.z?.must_equal false
|
|
82
82
|
o.z = ''
|
|
83
|
-
o.z.
|
|
84
|
-
o.z?.
|
|
85
|
-
proc{o.b?}.
|
|
83
|
+
o.z.must_equal nil
|
|
84
|
+
o.z?.must_equal nil
|
|
85
|
+
proc{o.b?}.must_raise(NoMethodError)
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
it "should handle cases where getting the columns raises an error" do
|
|
89
89
|
@c.meta_def(:columns){raise Sequel::Error}
|
|
90
|
-
|
|
91
|
-
proc{@c.new.b?}.
|
|
90
|
+
@c.plugin(:boolean_readers)
|
|
91
|
+
proc{@c.new.b?}.must_raise(NoMethodError)
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -54,52 +54,52 @@ describe Sequel::Model, "caching" do
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
it "should set the model's cache store" do
|
|
57
|
-
@c.cache_store.
|
|
58
|
-
@c2.cache_store.
|
|
57
|
+
@c.cache_store.wont_be_nil
|
|
58
|
+
@c2.cache_store.wont_be_nil
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
it "should have a default ttl of 3600" do
|
|
62
|
-
@c.cache_ttl.
|
|
63
|
-
@c2.cache_ttl.
|
|
62
|
+
@c.cache_ttl.must_equal 3600
|
|
63
|
+
@c2.cache_ttl.must_equal 3600
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should take a ttl option" do
|
|
67
67
|
c = Class.new(Sequel::Model(:items))
|
|
68
68
|
c.plugin :caching, @cache, :ttl => 1234
|
|
69
|
-
c.cache_ttl.
|
|
70
|
-
Class.new(c).cache_ttl.
|
|
69
|
+
c.cache_ttl.must_equal 1234
|
|
70
|
+
Class.new(c).cache_ttl.must_equal 1234
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
it "should allow overriding the ttl option via a plugin :caching call" do
|
|
74
74
|
@c.plugin :caching, @cache, :ttl => 1234
|
|
75
|
-
@c.cache_ttl.
|
|
76
|
-
Class.new(@c).cache_ttl.
|
|
75
|
+
@c.cache_ttl.must_equal 1234
|
|
76
|
+
Class.new(@c).cache_ttl.must_equal 1234
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
it "should offer a set_cache_ttl method for setting the ttl" do
|
|
80
|
-
@c.cache_ttl.
|
|
80
|
+
@c.cache_ttl.must_equal 3600
|
|
81
81
|
@c.set_cache_ttl 1234
|
|
82
|
-
@c.cache_ttl.
|
|
83
|
-
Class.new(@c).cache_ttl.
|
|
82
|
+
@c.cache_ttl.must_equal 1234
|
|
83
|
+
Class.new(@c).cache_ttl.must_equal 1234
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
it "should generate a cache key appropriate to the class via the Model#cache_key" do
|
|
87
87
|
m = @c.new
|
|
88
88
|
m.values[:id] = 1
|
|
89
|
-
m.cache_key.
|
|
89
|
+
m.cache_key.must_equal "#{m.class}:1"
|
|
90
90
|
m = @c2.new
|
|
91
91
|
m.values[:id] = 1
|
|
92
|
-
m.cache_key.
|
|
92
|
+
m.cache_key.must_equal "#{m.class}:1"
|
|
93
93
|
|
|
94
94
|
# custom primary key
|
|
95
95
|
@c.set_primary_key :ttt
|
|
96
96
|
m = @c.new
|
|
97
97
|
m.values[:ttt] = 333
|
|
98
|
-
m.cache_key.
|
|
98
|
+
m.cache_key.must_equal "#{m.class}:333"
|
|
99
99
|
c = Class.new(@c)
|
|
100
100
|
m = c.new
|
|
101
101
|
m.values[:ttt] = 333
|
|
102
|
-
m.cache_key.
|
|
102
|
+
m.cache_key.must_equal "#{m.class}:333"
|
|
103
103
|
|
|
104
104
|
# composite primary key
|
|
105
105
|
@c.set_primary_key [:a, :b, :c]
|
|
@@ -107,164 +107,164 @@ describe Sequel::Model, "caching" do
|
|
|
107
107
|
m.values[:a] = 123
|
|
108
108
|
m.values[:c] = 456
|
|
109
109
|
m.values[:b] = 789
|
|
110
|
-
m.cache_key.
|
|
110
|
+
m.cache_key.must_equal "#{m.class}:123,789,456"
|
|
111
111
|
c = Class.new(@c)
|
|
112
112
|
m = c.new
|
|
113
113
|
m.values[:a] = 123
|
|
114
114
|
m.values[:c] = 456
|
|
115
115
|
m.values[:b] = 789
|
|
116
|
-
m.cache_key.
|
|
116
|
+
m.cache_key.must_equal "#{m.class}:123,789,456"
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
it "should generate a cache key via the Model.cache_key method" do
|
|
120
|
-
@c.cache_key(1).
|
|
121
|
-
@c.cache_key([1, 2]).
|
|
120
|
+
@c.cache_key(1).must_equal "#{@c}:1"
|
|
121
|
+
@c.cache_key([1, 2]).must_equal "#{@c}:1,2"
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
it "should raise error if attempting to generate cache_key and primary key value is null" do
|
|
125
125
|
m = @c.new
|
|
126
|
-
proc {m.cache_key}.
|
|
126
|
+
proc {m.cache_key}.must_raise(Sequel::Error)
|
|
127
127
|
m.values[:id] = 1
|
|
128
|
-
|
|
128
|
+
m.cache_key
|
|
129
129
|
|
|
130
130
|
m = @c2.new
|
|
131
|
-
proc {m.cache_key}.
|
|
131
|
+
proc {m.cache_key}.must_raise(Sequel::Error)
|
|
132
132
|
m.values[:id] = 1
|
|
133
|
-
|
|
133
|
+
m.cache_key
|
|
134
134
|
end
|
|
135
135
|
|
|
136
136
|
it "should not raise error if trying to save a new record" do
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
@c.new(:name=>'blah').save
|
|
138
|
+
@c.create(:name=>'blah')
|
|
139
|
+
@c2.new(:name=>'blah').save
|
|
140
|
+
@c2.create(:name=>'blah')
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "should set the cache when reading from the database" do
|
|
144
|
-
@c.db.sqls.
|
|
145
|
-
@cache.
|
|
144
|
+
@c.db.sqls.must_equal []
|
|
145
|
+
@cache.must_be :empty?
|
|
146
146
|
|
|
147
147
|
m = @c[1]
|
|
148
|
-
@c.db.sqls.
|
|
149
|
-
m.values.
|
|
150
|
-
@cache[m.cache_key].
|
|
148
|
+
@c.db.sqls.must_equal ['SELECT * FROM items WHERE id = 1']
|
|
149
|
+
m.values.must_equal(:name=>"sharon", :id=>1)
|
|
150
|
+
@cache[m.cache_key].must_equal m
|
|
151
151
|
m2 = @c[1]
|
|
152
|
-
@c.db.sqls.
|
|
153
|
-
m2.
|
|
154
|
-
m2.values.
|
|
152
|
+
@c.db.sqls.must_equal []
|
|
153
|
+
m2.must_equal m
|
|
154
|
+
m2.values.must_equal(:name=>"sharon", :id=>1)
|
|
155
155
|
|
|
156
156
|
m = @c2[1]
|
|
157
|
-
@c.db.sqls.
|
|
158
|
-
m.values.
|
|
159
|
-
@cache[m.cache_key].
|
|
157
|
+
@c.db.sqls.must_equal ['SELECT * FROM items WHERE id = 1']
|
|
158
|
+
m.values.must_equal(:name=>"sharon", :id=>1)
|
|
159
|
+
@cache[m.cache_key].must_equal m
|
|
160
160
|
m2 = @c2[1]
|
|
161
|
-
@c.db.sqls.
|
|
162
|
-
m2.
|
|
163
|
-
m2.values.
|
|
161
|
+
@c.db.sqls.must_equal []
|
|
162
|
+
m2.must_equal m
|
|
163
|
+
m2.values.must_equal(:name=>"sharon", :id=>1)
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
it "should handle lookups by nil primary keys" do
|
|
167
|
-
@c[nil].
|
|
168
|
-
@c.db.sqls.
|
|
167
|
+
@c[nil].must_equal nil
|
|
168
|
+
@c.db.sqls.must_equal []
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
it "should delete the cache when writing to the database" do
|
|
172
172
|
m = @c[1]
|
|
173
|
-
@cache[m.cache_key].
|
|
173
|
+
@cache[m.cache_key].must_equal m
|
|
174
174
|
m.name = 'hey'
|
|
175
175
|
m.save
|
|
176
|
-
@cache.has_key?(m.cache_key).
|
|
177
|
-
@c.db.sqls.
|
|
176
|
+
@cache.has_key?(m.cache_key).must_equal false
|
|
177
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE id = 1", "UPDATE items SET name = 'hey' WHERE (id = 1)"]
|
|
178
178
|
|
|
179
179
|
m = @c2[1]
|
|
180
|
-
@cache[m.cache_key].
|
|
180
|
+
@cache[m.cache_key].must_equal m
|
|
181
181
|
m.name = 'hey'
|
|
182
182
|
m.save
|
|
183
|
-
@cache.has_key?(m.cache_key).
|
|
184
|
-
@c.db.sqls.
|
|
183
|
+
@cache.has_key?(m.cache_key).must_equal false
|
|
184
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE id = 1", "UPDATE items SET name = 'hey' WHERE (id = 1)"]
|
|
185
185
|
end
|
|
186
186
|
|
|
187
187
|
it "should delete the cache when deleting the record" do
|
|
188
188
|
m = @c[1]
|
|
189
|
-
@cache[m.cache_key].
|
|
189
|
+
@cache[m.cache_key].must_equal m
|
|
190
190
|
m.delete
|
|
191
|
-
@cache.has_key?(m.cache_key).
|
|
192
|
-
@c.db.sqls.
|
|
191
|
+
@cache.has_key?(m.cache_key).must_equal false
|
|
192
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE id = 1", "DELETE FROM items WHERE id = 1"]
|
|
193
193
|
|
|
194
194
|
m = @c2[1]
|
|
195
|
-
@cache[m.cache_key].
|
|
195
|
+
@cache[m.cache_key].must_equal m
|
|
196
196
|
m.delete
|
|
197
|
-
@cache.has_key?(m.cache_key).
|
|
198
|
-
@c.db.sqls.
|
|
197
|
+
@cache.has_key?(m.cache_key).must_equal false
|
|
198
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE id = 1", "DELETE FROM items WHERE id = 1"]
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
it "should support #[] as a shortcut to #find with hash" do
|
|
202
202
|
m = @c[:id => 3]
|
|
203
|
-
@cache[m.cache_key].
|
|
204
|
-
@c.db.sqls.
|
|
203
|
+
@cache[m.cache_key].must_equal nil
|
|
204
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE (id = 3) LIMIT 1"]
|
|
205
205
|
m = @c[1]
|
|
206
|
-
@cache[m.cache_key].
|
|
207
|
-
@c.db.sqls.
|
|
206
|
+
@cache[m.cache_key].must_equal m
|
|
207
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE id = 1"]
|
|
208
208
|
@c[:id => 4]
|
|
209
|
-
@c.db.sqls.
|
|
209
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE (id = 4) LIMIT 1"]
|
|
210
210
|
|
|
211
211
|
m = @c2[:id => 3]
|
|
212
|
-
@cache[m.cache_key].
|
|
213
|
-
@c.db.sqls.
|
|
212
|
+
@cache[m.cache_key].must_equal nil
|
|
213
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE (id = 3) LIMIT 1"]
|
|
214
214
|
m = @c2[1]
|
|
215
|
-
@cache[m.cache_key].
|
|
216
|
-
@c.db.sqls.
|
|
215
|
+
@cache[m.cache_key].must_equal m
|
|
216
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE id = 1"]
|
|
217
217
|
@c2[:id => 4]
|
|
218
|
-
@c.db.sqls.
|
|
218
|
+
@c.db.sqls.must_equal ["SELECT * FROM items WHERE (id = 4) LIMIT 1"]
|
|
219
219
|
end
|
|
220
220
|
|
|
221
221
|
it "should support ignore_exception option" do
|
|
222
222
|
c = Class.new(Sequel::Model(:items))
|
|
223
223
|
c.plugin :caching, @cache, :ignore_exceptions => true
|
|
224
|
-
Class.new(c).cache_ignore_exceptions.
|
|
224
|
+
Class.new(c).cache_ignore_exceptions.must_equal true
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
it "should raise an exception if cache_store is memcached and ignore_exception is not enabled" do
|
|
228
|
-
proc{@c3[1]}.
|
|
228
|
+
proc{@c3[1]}.must_raise ArgumentError
|
|
229
229
|
m = @c3.new.save
|
|
230
|
-
proc{m.update({:name=>'blah'})}.
|
|
230
|
+
proc{m.update({:name=>'blah'})}.must_raise ArgumentError
|
|
231
231
|
end
|
|
232
232
|
|
|
233
233
|
it "should rescue an exception if cache_store is memcached and ignore_exception is enabled" do
|
|
234
|
-
@c4[1].values.
|
|
234
|
+
@c4[1].values.must_equal(:name => 'sharon', :id => 1)
|
|
235
235
|
m = @c4.new.save
|
|
236
|
-
|
|
237
|
-
m.values.
|
|
236
|
+
m.update({:name=>'blah'})
|
|
237
|
+
m.values.must_equal(:name => 'blah', :id => 1, :x => 1)
|
|
238
238
|
end
|
|
239
239
|
|
|
240
240
|
it "should support Model.cache_get_pk for getting a value from the cache by primary key" do
|
|
241
|
-
@c.cache_get_pk(1).
|
|
241
|
+
@c.cache_get_pk(1).must_equal nil
|
|
242
242
|
m = @c[1]
|
|
243
|
-
@c.cache_get_pk(1).
|
|
243
|
+
@c.cache_get_pk(1).must_equal m
|
|
244
244
|
end
|
|
245
245
|
|
|
246
246
|
it "should support Model.cache_delete_pk for removing a value from the cache by primary key" do
|
|
247
247
|
@c[1]
|
|
248
|
-
@c.cache_get_pk(1).
|
|
249
|
-
@c.cache_delete_pk(1).
|
|
250
|
-
@c.cache_get_pk(1).
|
|
248
|
+
@c.cache_get_pk(1).wont_equal nil
|
|
249
|
+
@c.cache_delete_pk(1).must_equal nil
|
|
250
|
+
@c.cache_get_pk(1).must_equal nil
|
|
251
251
|
end
|
|
252
252
|
|
|
253
253
|
it "should support overriding the cache key prefix" do
|
|
254
254
|
c2 = Class.new(@c)
|
|
255
255
|
def c2.cache_key_prefix; "ceetwo" end
|
|
256
256
|
c3 = Class.new(c2)
|
|
257
|
-
@c.cache_key(:id).
|
|
258
|
-
c2.cache_key(:id).
|
|
257
|
+
@c.cache_key(:id).wont_equal c2.cache_key(:id)
|
|
258
|
+
c2.cache_key(:id).must_equal c3.cache_key(:id)
|
|
259
259
|
|
|
260
260
|
@c[1]
|
|
261
|
-
c2.cache_get_pk(1).
|
|
261
|
+
c2.cache_get_pk(1).must_equal nil
|
|
262
262
|
m = c2[1]
|
|
263
|
-
c2.cache_get_pk(1).values.
|
|
264
|
-
c3.cache_get_pk(1).values.
|
|
263
|
+
c2.cache_get_pk(1).values.must_equal @c[1].values
|
|
264
|
+
c3.cache_get_pk(1).values.must_equal m.values
|
|
265
265
|
|
|
266
266
|
m.name << m.name
|
|
267
267
|
m.save
|
|
268
|
-
c2[1].values.
|
|
268
|
+
c2[1].values.must_equal c3[1].values
|
|
269
269
|
end
|
|
270
270
|
end
|
|
@@ -48,51 +48,51 @@ describe "class_table_inheritance plugin" do
|
|
|
48
48
|
Object.send(:remove_const, :Employee)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
Employee.simple_table.
|
|
53
|
-
Manager.simple_table.
|
|
54
|
-
Executive.simple_table.
|
|
55
|
-
Staff.simple_table.
|
|
51
|
+
it "should have simple_table = nil for all classes" do
|
|
52
|
+
Employee.simple_table.must_equal nil
|
|
53
|
+
Manager.simple_table.must_equal nil
|
|
54
|
+
Executive.simple_table.must_equal nil
|
|
55
|
+
Staff.simple_table.must_equal nil
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
it "should have working row_proc if using set_dataset in subclass to remove columns" do
|
|
59
59
|
Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
|
|
60
60
|
Manager.dataset._fetch = {:id=>1, :kind=>'Executive'}
|
|
61
|
-
Manager[1].
|
|
61
|
+
Manager[1].must_equal Executive.load(:id=>1, :kind=>'Executive')
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
Employee.dataset.sql.
|
|
66
|
-
Manager.dataset.sql.
|
|
67
|
-
Executive.dataset.sql.
|
|
68
|
-
Staff.dataset.sql.
|
|
64
|
+
it "should use a joined dataset in subclasses" do
|
|
65
|
+
Employee.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind FROM employees'
|
|
66
|
+
Manager.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)'
|
|
67
|
+
Executive.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)'
|
|
68
|
+
Staff.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)'
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it "should return rows with the correct class based on the polymorphic_key value" do
|
|
72
72
|
@ds._fetch = [{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Staff'}]
|
|
73
|
-
Employee.all.collect{|x| x.class}.
|
|
73
|
+
Employee.all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Staff]
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
it "should return rows with the correct class based on the polymorphic_key value for subclasses" do
|
|
77
77
|
Manager.dataset._fetch = [{:kind=>'Manager'}, {:kind=>'Executive'}]
|
|
78
|
-
Manager.all.collect{|x| x.class}.
|
|
78
|
+
Manager.all.collect{|x| x.class}.must_equal [Manager, Executive]
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
it "should have refresh return all columns in subclass after loading from superclass" do
|
|
82
82
|
Employee.dataset._fetch = [{:id=>1, :name=>'A', :kind=>'Executive'}]
|
|
83
83
|
Executive.instance_dataset._fetch = [{:id=>1, :name=>'A', :kind=>'Executive', :num_staff=>3, :num_managers=>2}]
|
|
84
84
|
a = Employee.first
|
|
85
|
-
a.class.
|
|
86
|
-
a.values.
|
|
87
|
-
a.refresh.values.
|
|
88
|
-
@db.sqls.
|
|
85
|
+
a.class.must_equal Executive
|
|
86
|
+
a.values.must_equal(:id=>1, :name=>'A', :kind=>'Executive')
|
|
87
|
+
a.refresh.values.must_equal(:id=>1, :name=>'A', :kind=>'Executive', :num_staff=>3, :num_managers=>2)
|
|
88
|
+
@db.sqls.must_equal ["SELECT employees.id, employees.name, employees.kind FROM employees LIMIT 1",
|
|
89
89
|
"SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (executives.id = 1) LIMIT 1"]
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
it "should return rows with the current class if cti_key is nil" do
|
|
93
93
|
Employee.plugin(:class_table_inheritance)
|
|
94
94
|
Employee.dataset._fetch = [{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Staff'}]
|
|
95
|
-
Employee.all.collect{|x| x.class}.
|
|
95
|
+
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Employee, Employee]
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
it "should return rows with the current class if cti_key is nil in subclasses" do
|
|
@@ -102,7 +102,7 @@ describe "class_table_inheritance plugin" do
|
|
|
102
102
|
class ::Manager < Employee; end
|
|
103
103
|
class ::Executive < Manager; end
|
|
104
104
|
Manager.dataset._fetch = [{:kind=>'Manager'}, {:kind=>'Executive'}]
|
|
105
|
-
Manager.all.collect{|x| x.class}.
|
|
105
|
+
Manager.all.collect{|x| x.class}.must_equal [Manager, Manager]
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
it "should handle a model map with integer values" do
|
|
@@ -112,41 +112,41 @@ describe "class_table_inheritance plugin" do
|
|
|
112
112
|
class ::Manager < Employee; end
|
|
113
113
|
class ::Executive < Manager; end
|
|
114
114
|
Employee.dataset._fetch = [{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}]
|
|
115
|
-
Employee.all.collect{|x| x.class}.
|
|
115
|
+
Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive]
|
|
116
116
|
Manager.dataset._fetch = [{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}]
|
|
117
|
-
Manager.all.collect{|x| x.class}.
|
|
117
|
+
Manager.all.collect{|x| x.class}.must_equal [Manager, Employee, Manager, Executive]
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
it "should fallback to the main class if the given class does not exist" do
|
|
121
121
|
@ds._fetch = [{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Blah'}, {:kind=>'Staff'}]
|
|
122
|
-
Employee.all.collect{|x| x.class}.
|
|
122
|
+
Employee.all.collect{|x| x.class}.must_equal [Employee, Manager, Employee, Staff]
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
it "should fallback to the main class if the given class does not exist in subclasses" do
|
|
126
126
|
Manager.dataset._fetch = [{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Blah'}]
|
|
127
|
-
Manager.all.collect{|x| x.class}.
|
|
127
|
+
Manager.all.collect{|x| x.class}.must_equal [Manager, Executive, Manager]
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
it "should sets the model class name for the key when creating new parent class records" do
|
|
131
131
|
Employee.create
|
|
132
|
-
@db.sqls.
|
|
132
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
it "should sets the model class name for the key when creating new subclass records" do
|
|
136
136
|
Executive.create
|
|
137
|
-
@db.sqls.
|
|
137
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Executive')",
|
|
138
138
|
"INSERT INTO managers (id) VALUES (1)",
|
|
139
139
|
"INSERT INTO executives (id) VALUES (1)"]
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
it "should ignore existing cti_key value when creating new records" do
|
|
143
143
|
Employee.create(:kind=>'Manager')
|
|
144
|
-
@db.sqls.
|
|
144
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
it "should ignore existing cti_key value in subclasses" do
|
|
148
148
|
Manager.create(:kind=>'Executive')
|
|
149
|
-
@db.sqls.
|
|
149
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Manager')",
|
|
150
150
|
"INSERT INTO managers (id) VALUES (1)"]
|
|
151
151
|
end
|
|
152
152
|
|
|
@@ -155,41 +155,41 @@ describe "class_table_inheritance plugin" do
|
|
|
155
155
|
def o.validate
|
|
156
156
|
errors.add(:kind, 'not present') unless kind
|
|
157
157
|
end
|
|
158
|
-
o.valid?.
|
|
158
|
+
o.valid?.must_equal true
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
it "should set the type column field even when not validating" do
|
|
162
162
|
Employee.new.save(:validate=>false)
|
|
163
|
-
@db.sqls.
|
|
163
|
+
@db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
it "should raise an error if attempting to create an anonymous subclass" do
|
|
167
|
-
proc{Class.new(Manager)}.
|
|
167
|
+
proc{Class.new(Manager)}.must_raise(Sequel::Error)
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
it "should allow specifying a map of names to tables to override implicit mapping" do
|
|
171
|
-
Manager.dataset.sql.
|
|
172
|
-
Staff.dataset.sql.
|
|
171
|
+
Manager.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)'
|
|
172
|
+
Staff.dataset.sql.must_equal 'SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)'
|
|
173
173
|
end
|
|
174
174
|
|
|
175
175
|
it "should lazily load attributes for columns in subclass tables" do
|
|
176
176
|
Manager.instance_dataset._fetch = Manager.dataset._fetch = {:id=>1, :name=>'J', :kind=>'Executive', :num_staff=>2}
|
|
177
177
|
m = Manager[1]
|
|
178
|
-
@db.sqls.
|
|
178
|
+
@db.sqls.must_equal ['SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1']
|
|
179
179
|
Executive.instance_dataset._fetch = Executive.dataset._fetch = {:num_managers=>3}
|
|
180
|
-
m.num_managers.
|
|
181
|
-
@db.sqls.
|
|
182
|
-
m.values.
|
|
180
|
+
m.num_managers.must_equal 3
|
|
181
|
+
@db.sqls.must_equal ['SELECT executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (executives.id = 1) LIMIT 1']
|
|
182
|
+
m.values.must_equal(:id=>1, :name=>'J', :kind=>'Executive', :num_staff=>2, :num_managers=>3)
|
|
183
183
|
end
|
|
184
184
|
|
|
185
185
|
it "should lazily load columns in middle classes correctly when loaded from parent class" do
|
|
186
186
|
Employee.dataset._fetch = {:id=>1, :kind=>'Executive'}
|
|
187
187
|
Manager.dataset._fetch = {:num_staff=>2}
|
|
188
188
|
e = Employee[1]
|
|
189
|
-
e.
|
|
190
|
-
@db.sqls.
|
|
191
|
-
e.num_staff.
|
|
192
|
-
@db.sqls.
|
|
189
|
+
e.must_be_kind_of(Executive)
|
|
190
|
+
@db.sqls.must_equal ["SELECT employees.id, employees.name, employees.kind FROM employees WHERE (id = 1) LIMIT 1"]
|
|
191
|
+
e.num_staff.must_equal 2
|
|
192
|
+
@db.sqls.must_equal ["SELECT managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 1) LIMIT 1"]
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
it "should eagerly load lazily columns in subclasses when loaded from parent class" do
|
|
@@ -197,51 +197,51 @@ describe "class_table_inheritance plugin" do
|
|
|
197
197
|
Manager.dataset._fetch = {:id=>1, :num_staff=>2}
|
|
198
198
|
Executive.dataset._fetch = {:id=>1, :num_managers=>3}
|
|
199
199
|
e = Employee.all.first
|
|
200
|
-
e.
|
|
201
|
-
@db.sqls.
|
|
202
|
-
e.num_staff#.
|
|
203
|
-
@db.sqls.
|
|
204
|
-
e.num_managers#.
|
|
205
|
-
@db.sqls.
|
|
200
|
+
e.must_be_kind_of(Executive)
|
|
201
|
+
@db.sqls.must_equal ["SELECT employees.id, employees.name, employees.kind FROM employees"]
|
|
202
|
+
e.num_staff#.must_equal 2
|
|
203
|
+
@db.sqls.must_equal ["SELECT managers.id, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id IN (1))"]
|
|
204
|
+
e.num_managers#.must_equal 3
|
|
205
|
+
@db.sqls.must_equal ['SELECT executives.id, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (executives.id IN (1))']
|
|
206
206
|
end
|
|
207
207
|
|
|
208
208
|
it "should include schema for columns for tables for ancestor classes" do
|
|
209
|
-
Employee.db_schema.
|
|
210
|
-
Manager.db_schema.
|
|
211
|
-
Executive.db_schema.
|
|
212
|
-
Staff.db_schema.
|
|
209
|
+
Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string})
|
|
210
|
+
Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer})
|
|
211
|
+
Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
|
|
212
|
+
Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :manager_id=>{:type=>:integer})
|
|
213
213
|
end
|
|
214
214
|
|
|
215
215
|
it "should use the correct primary key (which should have the same name in all subclasses)" do
|
|
216
|
-
[Employee, Manager, Executive, Staff].each{|c| c.primary_key.
|
|
216
|
+
[Employee, Manager, Executive, Staff].each{|c| c.primary_key.must_equal :id}
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
it "should have table_name return the table name of the most specific table" do
|
|
220
|
-
Employee.table_name.
|
|
221
|
-
Manager.table_name.
|
|
222
|
-
Executive.table_name.
|
|
223
|
-
Staff.table_name.
|
|
220
|
+
Employee.table_name.must_equal :employees
|
|
221
|
+
Manager.table_name.must_equal :managers
|
|
222
|
+
Executive.table_name.must_equal :executives
|
|
223
|
+
Staff.table_name.must_equal :staff
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
it "should delete the correct rows from all tables when deleting" do
|
|
227
227
|
Executive.load(:id=>1).delete
|
|
228
|
-
@db.sqls.
|
|
228
|
+
@db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
|
|
229
229
|
end
|
|
230
230
|
|
|
231
231
|
it "should not allow deletion of frozen object" do
|
|
232
232
|
o = Executive.load(:id=>1)
|
|
233
233
|
o.freeze
|
|
234
|
-
proc{o.delete}.
|
|
235
|
-
@db.sqls.
|
|
234
|
+
proc{o.delete}.must_raise(Sequel::Error)
|
|
235
|
+
@db.sqls.must_equal []
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
it "should insert the correct rows into all tables when inserting" do
|
|
239
239
|
Executive.create(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
240
240
|
sqls = @db.sqls
|
|
241
|
-
sqls.length.
|
|
242
|
-
sqls[0].
|
|
243
|
-
sqls[1].
|
|
244
|
-
sqls[2].
|
|
241
|
+
sqls.length.must_equal 3
|
|
242
|
+
sqls[0].must_match(/INSERT INTO employees \((name|kind), (name|kind)\) VALUES \('(E|Executive)', '(E|Executive)'\)/)
|
|
243
|
+
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \([12], [12]\)/)
|
|
244
|
+
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([13], [13]\)/)
|
|
245
245
|
end
|
|
246
246
|
|
|
247
247
|
it "should insert the correct rows into all tables with a given primary key" do
|
|
@@ -249,26 +249,26 @@ describe "class_table_inheritance plugin" do
|
|
|
249
249
|
e.id = 2
|
|
250
250
|
e.save
|
|
251
251
|
sqls = @db.sqls
|
|
252
|
-
sqls.length.
|
|
253
|
-
sqls[0].
|
|
254
|
-
sqls[1].
|
|
255
|
-
sqls[2].
|
|
252
|
+
sqls.length.must_equal 3
|
|
253
|
+
sqls[0].must_match(/INSERT INTO employees \((name|kind|id), (name|kind|id), (name|kind|id)\) VALUES \(('E'|'Executive'|2), ('E'|'Executive'|2), ('E'|'Executive'|2)\)/)
|
|
254
|
+
sqls[1].must_match(/INSERT INTO managers \((num_staff|id), (num_staff|id)\) VALUES \(2, 2\)/)
|
|
255
|
+
sqls[2].must_match(/INSERT INTO executives \((num_managers|id), (num_managers|id)\) VALUES \([23], [23]\)/)
|
|
256
256
|
end
|
|
257
257
|
|
|
258
258
|
it "should update the correct rows in all tables when updating" do
|
|
259
259
|
Executive.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
|
|
260
|
-
@db.sqls.
|
|
260
|
+
@db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)", "UPDATE executives SET num_managers = 3 WHERE (id = 2)"]
|
|
261
261
|
end
|
|
262
262
|
|
|
263
263
|
it "should handle many_to_one relationships correctly" do
|
|
264
264
|
Manager.dataset._fetch = {:id=>3, :name=>'E', :kind=>'Executive', :num_managers=>3}
|
|
265
|
-
Staff.load(:manager_id=>3).manager.
|
|
266
|
-
@db.sqls.
|
|
265
|
+
Staff.load(:manager_id=>3).manager.must_equal Executive.load(:id=>3, :name=>'E', :kind=>'Executive', :num_managers=>3)
|
|
266
|
+
@db.sqls.must_equal ['SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id) WHERE (managers.id = 3) LIMIT 1']
|
|
267
267
|
end
|
|
268
268
|
|
|
269
269
|
it "should handle one_to_many relationships correctly" do
|
|
270
270
|
Staff.dataset._fetch = {:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3}
|
|
271
|
-
Executive.load(:id=>3).staff_members.
|
|
272
|
-
@db.sqls.
|
|
271
|
+
Executive.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)]
|
|
272
|
+
@db.sqls.must_equal ['SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id) WHERE (staff.manager_id = 3)']
|
|
273
273
|
end
|
|
274
274
|
end
|