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
|
@@ -29,47 +29,47 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
29
29
|
errors.add(model.create_timestamp_field, 'not present') unless send(model.create_timestamp_field)
|
|
30
30
|
errors.add(model.update_timestamp_field, 'not present') unless send(model.update_timestamp_field)
|
|
31
31
|
end
|
|
32
|
-
o.valid?.
|
|
32
|
+
o.valid?.must_equal true
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "should set timestamp fields when skipping validations" do
|
|
36
36
|
@c.plugin :timestamps
|
|
37
37
|
@c.new.save(:validate=>false)
|
|
38
|
-
@c.db.sqls.
|
|
38
|
+
@c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
it "should set the create timestamp field on creation" do
|
|
42
42
|
o = @c.create
|
|
43
|
-
@c.db.sqls.
|
|
44
|
-
o.created_at.
|
|
43
|
+
@c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
|
|
44
|
+
o.created_at.must_equal '2009-08-01'
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "should set the update timestamp field on update" do
|
|
48
48
|
o = @c.load(:id=>1).save
|
|
49
|
-
@c.db.sqls.
|
|
50
|
-
o.updated_at.
|
|
49
|
+
@c.db.sqls.must_equal ["UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
|
|
50
|
+
o.updated_at.must_equal '2009-08-01'
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it "should work with current_datetime_timestamp extension" do
|
|
54
54
|
Sequel.datetime_class = Time
|
|
55
55
|
@c.dataset = @c.dataset.extension(:current_datetime_timestamp)
|
|
56
56
|
o = @c.create
|
|
57
|
-
@c.db.sqls.
|
|
57
|
+
@c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES (CURRENT_TIMESTAMP)"]
|
|
58
58
|
o = @c.load(:id=>1).save
|
|
59
|
-
@c.db.sqls.
|
|
59
|
+
@c.db.sqls.must_equal ["UPDATE t SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
it "should not update the update timestamp on creation" do
|
|
63
|
-
@c.create.updated_at.
|
|
63
|
+
@c.create.updated_at.must_equal nil
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should use the same value for the creation and update timestamps when creating if the :update_on_create option is given" do
|
|
67
67
|
@c.plugin :timestamps, :update_on_create=>true
|
|
68
68
|
o = @c.create
|
|
69
69
|
sqls = @c.db.sqls
|
|
70
|
-
sqls.shift.
|
|
71
|
-
sqls.
|
|
72
|
-
o.created_at.
|
|
70
|
+
sqls.shift.must_match(/INSERT INTO t \((creat|updat)ed_at, (creat|updat)ed_at\) VALUES \('2009-08-01', '2009-08-01'\)/)
|
|
71
|
+
sqls.must_equal []
|
|
72
|
+
o.created_at.must_be :===, o.updated_at
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
it "should allow specifying the create timestamp field via the :create option" do
|
|
@@ -80,8 +80,8 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
80
80
|
def _save_refresh(*) end
|
|
81
81
|
end
|
|
82
82
|
o = c.create
|
|
83
|
-
c.db.sqls.
|
|
84
|
-
o.c.
|
|
83
|
+
c.db.sqls.must_equal ["INSERT INTO t (c) VALUES ('2009-08-01')"]
|
|
84
|
+
o.c.must_equal '2009-08-01'
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it "should allow specifying the update timestamp field via the :update option" do
|
|
@@ -92,8 +92,8 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
92
92
|
db.reset
|
|
93
93
|
end
|
|
94
94
|
o = c.load(:id=>1).save
|
|
95
|
-
c.db.sqls.
|
|
96
|
-
o.u.
|
|
95
|
+
c.db.sqls.must_equal ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
|
|
96
|
+
o.u.must_equal '2009-08-01'
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
it "should not raise an error if the model doesn't have the timestamp columns" do
|
|
@@ -106,55 +106,55 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
106
106
|
end
|
|
107
107
|
c.create(:x=>2)
|
|
108
108
|
c.load(:id=>1, :x=>2).save
|
|
109
|
-
c.db.sqls.
|
|
109
|
+
c.db.sqls.must_equal ["INSERT INTO t (x) VALUES (2)", "UPDATE t SET x = 2 WHERE (id = 1)"]
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
it "should not overwrite an existing create timestamp" do
|
|
113
113
|
o = @c.create(:created_at=>'2009-08-03')
|
|
114
|
-
@c.db.sqls.
|
|
115
|
-
o.created_at.
|
|
114
|
+
@c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES ('2009-08-03')"]
|
|
115
|
+
o.created_at.must_equal '2009-08-03'
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
it "should overwrite an existing create timestamp if the :force option is used" do
|
|
119
119
|
@c.plugin :timestamps, :force=>true
|
|
120
120
|
o = @c.create(:created_at=>'2009-08-03')
|
|
121
|
-
@c.db.sqls.
|
|
122
|
-
o.created_at.
|
|
121
|
+
@c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES ('2009-08-01')"]
|
|
122
|
+
o.created_at.must_equal '2009-08-01'
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
it "should have create_timestamp_field give the create timestamp field" do
|
|
126
|
-
@c.create_timestamp_field.
|
|
126
|
+
@c.create_timestamp_field.must_equal :created_at
|
|
127
127
|
@c.plugin :timestamps, :create=>:c
|
|
128
|
-
@c.create_timestamp_field.
|
|
128
|
+
@c.create_timestamp_field.must_equal :c
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
it "should have update_timestamp_field give the update timestamp field" do
|
|
132
|
-
@c.update_timestamp_field.
|
|
132
|
+
@c.update_timestamp_field.must_equal :updated_at
|
|
133
133
|
@c.plugin :timestamps, :update=>:u
|
|
134
|
-
@c.update_timestamp_field.
|
|
134
|
+
@c.update_timestamp_field.must_equal :u
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
it "should have create_timestamp_overwrite? give the whether to overwrite an existing create timestamp" do
|
|
138
|
-
@c.create_timestamp_overwrite?.
|
|
138
|
+
@c.create_timestamp_overwrite?.must_equal false
|
|
139
139
|
@c.plugin :timestamps, :force=>true
|
|
140
|
-
@c.create_timestamp_overwrite?.
|
|
140
|
+
@c.create_timestamp_overwrite?.must_equal true
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "should have set_update_timestamp_on_create? give whether to set the update timestamp on create" do
|
|
144
|
-
@c.set_update_timestamp_on_create?.
|
|
144
|
+
@c.set_update_timestamp_on_create?.must_equal false
|
|
145
145
|
@c.plugin :timestamps, :update_on_create=>true
|
|
146
|
-
@c.set_update_timestamp_on_create?.
|
|
146
|
+
@c.set_update_timestamp_on_create?.must_equal true
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
it "should work with subclasses" do
|
|
150
150
|
c = Class.new(@c)
|
|
151
151
|
o = c.create
|
|
152
|
-
o.created_at.
|
|
153
|
-
o.updated_at.
|
|
152
|
+
o.created_at.must_equal '2009-08-01'
|
|
153
|
+
o.updated_at.must_equal nil
|
|
154
154
|
o = c.load(:id=>1).save
|
|
155
|
-
o.updated_at.
|
|
156
|
-
c.db.sqls.
|
|
157
|
-
c.create(:created_at=>'2009-08-03').created_at.
|
|
155
|
+
o.updated_at.must_equal '2009-08-01'
|
|
156
|
+
c.db.sqls.must_equal ["INSERT INTO t (created_at) VALUES ('2009-08-01')", "UPDATE t SET updated_at = '2009-08-01' WHERE (id = 1)"]
|
|
157
|
+
c.create(:created_at=>'2009-08-03').created_at.must_equal '2009-08-03'
|
|
158
158
|
|
|
159
159
|
c.class_eval do
|
|
160
160
|
columns :id, :c, :u
|
|
@@ -163,13 +163,13 @@ describe "Sequel::Plugins::Timestamps" do
|
|
|
163
163
|
c2 = Class.new(c)
|
|
164
164
|
c2.db.reset
|
|
165
165
|
o = c2.create
|
|
166
|
-
o.c.
|
|
167
|
-
o.u.
|
|
168
|
-
c2.db.sqls.first.
|
|
166
|
+
o.c.must_equal '2009-08-01'
|
|
167
|
+
o.u.must_be :===, o.c
|
|
168
|
+
c2.db.sqls.first.must_match(/INSERT INTO t \([cu], [cu]\) VALUES \('2009-08-01', '2009-08-01'\)/)
|
|
169
169
|
c2.db.reset
|
|
170
170
|
o = c2.load(:id=>1).save
|
|
171
|
-
o.u.
|
|
172
|
-
c2.db.sqls.
|
|
173
|
-
c2.create(:c=>'2009-08-03').c.
|
|
171
|
+
o.u.must_equal '2009-08-01'
|
|
172
|
+
c2.db.sqls.must_equal ["UPDATE t SET u = '2009-08-01' WHERE (id = 1)"]
|
|
173
|
+
c2.create(:c=>'2009-08-03').c.must_equal '2009-08-01'
|
|
174
174
|
end
|
|
175
175
|
end
|
|
@@ -7,11 +7,11 @@ describe Sequel::Model, "to_dot extension" do
|
|
|
7
7
|
|
|
8
8
|
before do
|
|
9
9
|
@db = DB
|
|
10
|
-
@ds = @db.dataset
|
|
10
|
+
@ds = @db.dataset.extension(:to_dot)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
it "should output a string suitable for input to the graphviz dot program" do
|
|
14
|
-
@ds.
|
|
14
|
+
@ds.to_dot.must_equal((<<END).strip)
|
|
15
15
|
digraph G {
|
|
16
16
|
0 [label="self"];
|
|
17
17
|
0 -> 1 [label=""];
|
|
@@ -21,127 +21,127 @@ END
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "should handle an empty dataset" do
|
|
24
|
-
dot(@ds).
|
|
24
|
+
dot(@ds).must_equal []
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "should handle WITH" do
|
|
28
28
|
def @ds.supports_cte?(*) true end
|
|
29
29
|
a = dot(@ds.with(:a, @ds))
|
|
30
|
-
a[0..3].
|
|
30
|
+
a[0..3].must_equal ["1 -> 2 [label=\"with\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Hash\"];"]
|
|
31
31
|
[["3 -> 4 [label=\"dataset\"];", "4 [label=\"Dataset\"];", "3 -> 5 [label=\"name\"];", "5 [label=\":a\"];"],
|
|
32
|
-
["3 -> 4 [label=\"name\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"dataset\"];", "5 [label=\"Dataset\"];"]].
|
|
32
|
+
["3 -> 4 [label=\"name\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"dataset\"];", "5 [label=\"Dataset\"];"]].must_include(a[4..-1])
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "should handle DISTINCT" do
|
|
36
|
-
dot(@ds.distinct).
|
|
36
|
+
dot(@ds.distinct).must_equal ["1 -> 2 [label=\"distinct\"];", "2 [label=\"Array\"];"]
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "should handle FROM" do
|
|
40
|
-
dot(@ds.from(:a)).
|
|
40
|
+
dot(@ds.from(:a)).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];"]
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it "should handle JOIN" do
|
|
44
|
-
dot(@ds.join(:a)).
|
|
44
|
+
dot(@ds.join(:a)).must_equal ["1 -> 2 [label=\"join\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"INNER JOIN\"];", "3 -> 4 [label=\"table\"];", "4 [label=\":a\"];"]
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "should handle WHERE" do
|
|
48
|
-
dot(@ds.filter(true)).
|
|
48
|
+
dot(@ds.filter(true)).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"ComplexExpression: NOOP\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"true\"];"]
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
it "should handle GROUP" do
|
|
52
|
-
dot(@ds.group(:a)).
|
|
52
|
+
dot(@ds.group(:a)).must_equal ["1 -> 2 [label=\"group\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];"]
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
it "should handle HAVING" do
|
|
56
|
-
dot(@ds.having(:a)).
|
|
56
|
+
dot(@ds.having(:a)).must_equal ["1 -> 2 [label=\"having\"];", "2 [label=\":a\"];"]
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it "should handle UNION" do
|
|
60
|
-
dot(@ds.union(@ds)).
|
|
60
|
+
dot(@ds.union(@ds)).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\"Dataset\"];", "4 -> 5 [label=\"compounds\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":union\"];", "6 -> 8 [label=\"1\"];", "8 [label=\"Dataset\"];", "6 -> 9 [label=\"2\"];", "9 [label=\"nil\"];", "3 -> 10 [label=\"alias\"];", "10 [label=\":t1\"];"]
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it "should handle INTERSECT" do
|
|
64
|
-
dot(@ds.intersect(@ds)).
|
|
64
|
+
dot(@ds.intersect(@ds)).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\"Dataset\"];", "4 -> 5 [label=\"compounds\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":intersect\"];", "6 -> 8 [label=\"1\"];", "8 [label=\"Dataset\"];", "6 -> 9 [label=\"2\"];", "9 [label=\"nil\"];", "3 -> 10 [label=\"alias\"];", "10 [label=\":t1\"];"]
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "should handle EXCEPT" do
|
|
68
|
-
dot(@ds.except(@ds)).
|
|
68
|
+
dot(@ds.except(@ds)).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\"Dataset\"];", "4 -> 5 [label=\"compounds\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":except\"];", "6 -> 8 [label=\"1\"];", "8 [label=\"Dataset\"];", "6 -> 9 [label=\"2\"];", "9 [label=\"nil\"];", "3 -> 10 [label=\"alias\"];", "10 [label=\":t1\"];"]
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it "should handle ORDER" do
|
|
72
|
-
dot(@ds.order(:a)).
|
|
72
|
+
dot(@ds.order(:a)).must_equal ["1 -> 2 [label=\"order\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];"]
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
it "should handle LIMIT and OFFSET" do
|
|
76
|
-
dot(@ds.limit(1, 2)).
|
|
76
|
+
dot(@ds.limit(1, 2)).must_equal ["1 -> 2 [label=\"limit\"];", "2 [label=\"1\"];", "1 -> 3 [label=\"offset\"];", "3 [label=\"2\"];"]
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
it "should handle FOR UPDATE" do
|
|
80
|
-
dot(@ds.for_update).
|
|
80
|
+
dot(@ds.for_update).must_equal ["1 -> 2 [label=\"lock\"];", "2 [label=\":update\"];"]
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
it "should handle LiteralStrings" do
|
|
84
|
-
dot(@ds.filter('a')).
|
|
84
|
+
dot(@ds.filter('a')).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"\\\"(a)\\\".lit\"];"]
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it "should handle true, false, nil" do
|
|
88
|
-
dot(@ds.select(true, false, nil)).
|
|
88
|
+
dot(@ds.select(true, false, nil)).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"true\"];", "2 -> 4 [label=\"1\"];", "4 [label=\"false\"];", "2 -> 5 [label=\"2\"];", "5 [label=\"nil\"];"]
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
it "should handle SQL::ComplexExpressions" do
|
|
92
|
-
dot(@ds.filter(:a=>:b)).
|
|
92
|
+
dot(@ds.filter(:a=>:b)).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"ComplexExpression: =\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "2 -> 4 [label=\"1\"];", "4 [label=\":b\"];"]
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
it "should handle SQL::Identifiers" do
|
|
96
|
-
dot(@ds.select{a}).
|
|
96
|
+
dot(@ds.select{a}).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Identifier\"];", "3 -> 4 [label=\"value\"];", "4 [label=\":a\"];"]
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
it "should handle SQL::QualifiedIdentifiers" do
|
|
100
|
-
dot(@ds.select{a__b}).
|
|
100
|
+
dot(@ds.select{a__b}).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"QualifiedIdentifier\"];", "3 -> 4 [label=\"table\"];", "4 [label=\"\\\"a\\\"\"];", "3 -> 5 [label=\"column\"];", "5 [label=\"\\\"b\\\"\"];"]
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
it "should handle SQL::OrderedExpressions" do
|
|
104
|
-
dot(@ds.order(Sequel.desc(:a, :nulls=>:last))).
|
|
104
|
+
dot(@ds.order(Sequel.desc(:a, :nulls=>:last))).must_equal ["1 -> 2 [label=\"order\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"OrderedExpression: DESC NULLS LAST\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];"]
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
it "should handle SQL::AliasedExpressions" do
|
|
108
|
-
dot(@ds.from(Sequel.as(:a, :b))).
|
|
108
|
+
dot(@ds.from(Sequel.as(:a, :b))).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];"]
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
it "should handle SQL::AliasedExpressions with column aliases" do
|
|
112
|
-
dot(@ds.from(Sequel.as(:a, :b, [:c, :d]))).
|
|
112
|
+
dot(@ds.from(Sequel.as(:a, :b, [:c, :d]))).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"AliasedExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"alias\"];", "5 [label=\":b\"];", "3 -> 6 [label=\"columns\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":c\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":d\"];"]
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
it "should handle SQL::CaseExpressions" do
|
|
116
|
-
dot(@ds.select(Sequel.case({:a=>:b}, :c, :d))).
|
|
116
|
+
dot(@ds.select(Sequel.case({:a=>:b}, :c, :d))).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"CaseExpression\"];", "3 -> 4 [label=\"expression\"];", "4 [label=\":d\"];", "3 -> 5 [label=\"conditions\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\":a\"];", "6 -> 8 [label=\"1\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"default\"];", "9 [label=\":c\"];"]
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
it "should handle SQL::Cast" do
|
|
120
|
-
dot(@ds.select(Sequel.cast(:a, Integer))).
|
|
120
|
+
dot(@ds.select(Sequel.cast(:a, Integer))).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Cast\"];", "3 -> 4 [label=\"expr\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"type\"];", "5 [label=\"Integer\"];"]
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
it "should handle SQL::Function" do
|
|
124
|
-
dot(@ds.select{a(b)}).
|
|
124
|
+
dot(@ds.select{a(b)}).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: a\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"Identifier\"];", "4 -> 5 [label=\"value\"];", "5 [label=\":b\"];", "3 -> 6 [label=\"args\"];", "6 [label=\"Array\"];", "6 -> 7 [label=\"0\"];", "7 [label=\"Identifier\"];", "7 -> 8 [label=\"value\"];", "8 [label=\":b\"];", "3 -> 9 [label=\"opts\"];", "9 [label=\"Hash\"];"]
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
it "should handle SQL::Subscript" do
|
|
128
|
-
dot(@ds.select(Sequel.subscript(:a, 1))).
|
|
128
|
+
dot(@ds.select(Sequel.subscript(:a, 1))).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Subscript\"];", "3 -> 4 [label=\"f\"];", "4 [label=\":a\"];", "3 -> 5 [label=\"sub\"];", "5 [label=\"Array\"];", "5 -> 6 [label=\"0\"];", "6 [label=\"1\"];"]
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
it "should handle SQL::Function with a window" do
|
|
132
|
-
dot(@ds.select{sum{}.over(:partition=>:a)}).
|
|
132
|
+
dot(@ds.select{sum{}.over(:partition=>:a)}).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Function: sum\"];", "3 -> 4 [label=\"args\"];", "4 [label=\"Array\"];", "3 -> 5 [label=\"opts\"];", "5 [label=\"Hash\"];", "5 -> 6 [label=\"over\"];", "6 [label=\"Window\"];", "6 -> 7 [label=\"opts\"];", "7 [label=\"Hash\"];", "7 -> 8 [label=\"partition\"];", "8 [label=\":a\"];"]
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
it "should handle SQL::PlaceholderLiteralString" do
|
|
136
|
-
dot(@ds.where("?", true)).
|
|
136
|
+
dot(@ds.where("?", true)).must_equal ["1 -> 2 [label=\"where\"];", "2 [label=\"PlaceholderLiteralString: \\\"(?)\\\"\"];", "2 -> 3 [label=\"args\"];", "3 [label=\"Array\"];", "3 -> 4 [label=\"0\"];", "4 [label=\"true\"];"]
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
it "should handle JOIN ON" do
|
|
140
|
-
dot(@ds.from(:a).join(:d, :b=>:c)).
|
|
140
|
+
dot(@ds.from(:a).join(:d, :b=>:c)).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN ON\"];", "5 -> 6 [label=\"table\"];", "6 [label=\":d\"];", "5 -> 7 [label=\"on\"];", "7 [label=\"ComplexExpression: =\"];", "7 -> 8 [label=\"0\"];", "8 [label=\"QualifiedIdentifier\"];", "8 -> 9 [label=\"table\"];", "9 [label=\"\\\"d\\\"\"];", "8 -> 10 [label=\"column\"];", "10 [label=\"\\\"b\\\"\"];", "7 -> 11 [label=\"1\"];", "11 [label=\"QualifiedIdentifier\"];", "11 -> 12 [label=\"table\"];", "12 [label=\"\\\"a\\\"\"];", "11 -> 13 [label=\"column\"];", "13 [label=\"\\\"c\\\"\"];"]
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "should handle JOIN USING" do
|
|
144
|
-
dot(@ds.from(:a).join(:d, [:c], :table_alias=>:c)).
|
|
144
|
+
dot(@ds.from(:a).join(:d, [:c], :table_alias=>:c)).must_equal ["1 -> 2 [label=\"from\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\":a\"];", "1 -> 4 [label=\"join\"];", "4 [label=\"Array\"];", "4 -> 5 [label=\"0\"];", "5 [label=\"INNER JOIN USING\"];", "5 -> 6 [label=\"table\"];", "6 [label=\"AliasedExpression\"];", "6 -> 7 [label=\"expression\"];", "7 [label=\":d\"];", "6 -> 8 [label=\"alias\"];", "8 [label=\":c\"];", "5 -> 9 [label=\"using\"];", "9 [label=\"Array\"];", "9 -> 10 [label=\"0\"];", "10 [label=\":c\"];"]
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
it "should handle other types" do
|
|
@@ -149,6 +149,6 @@ END
|
|
|
149
149
|
def o.inspect
|
|
150
150
|
"blah"
|
|
151
151
|
end
|
|
152
|
-
dot(@ds.select(o)).
|
|
152
|
+
dot(@ds.select(o)).must_equal ["1 -> 2 [label=\"select\"];", "2 [label=\"Array\"];", "2 -> 3 [label=\"0\"];", "3 [label=\"Unhandled: blah\"];"]
|
|
153
153
|
end
|
|
154
154
|
end
|
|
@@ -18,186 +18,186 @@ describe "Touch plugin" do
|
|
|
18
18
|
DB.reset
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
it "should default to using Time.now when setting the column values for model instances" do
|
|
22
22
|
c = Class.new(Sequel::Model).set_dataset(:a)
|
|
23
23
|
c.plugin :touch
|
|
24
24
|
c.columns :id, :updated_at
|
|
25
25
|
c.load(:id=>1).touch
|
|
26
|
-
DB.sqls.first.
|
|
26
|
+
DB.sqls.first.must_match(/UPDATE a SET updated_at = '[-0-9 :.]+' WHERE \(id = 1\)/)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
it "should work with current_datetime_timestamp extension" do
|
|
30
30
|
c = Class.new(Sequel::Model).set_dataset(:a)
|
|
31
31
|
c.dataset = c.dataset.extension(:current_datetime_timestamp)
|
|
32
32
|
c.plugin :touch
|
|
33
33
|
c.columns :id, :updated_at
|
|
34
34
|
c.load(:id=>1).touch
|
|
35
|
-
DB.sqls.
|
|
35
|
+
DB.sqls.must_equal ["UPDATE a SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
it "should allow #touch instance method for updating the updated_at column" do
|
|
39
39
|
@Artist.plugin :touch
|
|
40
40
|
@a.touch
|
|
41
|
-
DB.sqls.
|
|
41
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
it "should have #touch take an argument for the column to touch" do
|
|
45
45
|
@Artist.plugin :touch
|
|
46
46
|
@a.touch(:modified_on)
|
|
47
|
-
DB.sqls.
|
|
47
|
+
DB.sqls.must_equal ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
it "should be able to specify the default column to touch in the plugin call using the :column option" do
|
|
51
51
|
@Artist.plugin :touch, :column=>:modified_on
|
|
52
52
|
@a.touch
|
|
53
|
-
DB.sqls.
|
|
53
|
+
DB.sqls.must_equal ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
it "should be able to specify the default column to touch using the touch_column model accessor" do
|
|
57
57
|
@Artist.plugin :touch
|
|
58
58
|
@Artist.touch_column = :modified_on
|
|
59
59
|
@a.touch
|
|
60
|
-
DB.sqls.
|
|
60
|
+
DB.sqls.must_equal ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
it "should be able to specify the associations to touch in the plugin call using the :associations option" do
|
|
64
64
|
@Artist.plugin :touch, :associations=>:albums
|
|
65
65
|
@a.touch
|
|
66
|
-
DB.sqls.
|
|
66
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
67
67
|
"UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
it "should be able to give an array to the :associations option specifying multiple associations" do
|
|
71
71
|
@Album.plugin :touch, :associations=>[:artist, :followup_albums]
|
|
72
72
|
@Album.load(:id=>4, :artist_id=>1).touch
|
|
73
73
|
sqls = DB.sqls
|
|
74
|
-
sqls.shift.
|
|
75
|
-
sqls.sort.
|
|
74
|
+
sqls.shift.must_equal "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
|
|
75
|
+
sqls.sort.must_equal ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
76
76
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
it "should be able to give a hash to the :associations option specifying the column to use for each association" do
|
|
80
80
|
@Artist.plugin :touch, :associations=>{:albums=>:modified_on}
|
|
81
81
|
@a.touch
|
|
82
|
-
DB.sqls.
|
|
82
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
83
83
|
"UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
it "should default to using the touch_column as the default touch column for associations" do
|
|
87
87
|
@Artist.plugin :touch, :column=>:modified_on, :associations=>:albums
|
|
88
88
|
@a.touch
|
|
89
|
-
DB.sqls.
|
|
89
|
+
DB.sqls.must_equal ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
90
90
|
"UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
it "should allow the mixed use of symbols and hashes inside an array for the :associations option" do
|
|
94
94
|
@Album.plugin :touch, :associations=>[:artist, {:followup_albums=>:modified_on}]
|
|
95
95
|
@Album.load(:id=>4, :artist_id=>1).touch
|
|
96
96
|
sqls = DB.sqls
|
|
97
|
-
sqls.shift.
|
|
98
|
-
sqls.sort.
|
|
97
|
+
sqls.shift.must_equal "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
|
|
98
|
+
sqls.sort.must_equal ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
99
99
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
it "should be able to specify the associations to touch via a touch_associations_method" do
|
|
103
103
|
@Album.plugin :touch
|
|
104
104
|
@Album.touch_associations(:artist, {:followup_albums=>:modified_on})
|
|
105
105
|
@Album.load(:id=>4, :artist_id=>1).touch
|
|
106
106
|
sqls = DB.sqls
|
|
107
|
-
sqls.shift.
|
|
108
|
-
sqls.sort.
|
|
107
|
+
sqls.shift.must_equal "UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"
|
|
108
|
+
sqls.sort.must_equal ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
109
109
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
it "should touch associated objects when destroying an object" do
|
|
113
113
|
@Album.plugin :touch
|
|
114
114
|
@Album.touch_associations(:artist, {:followup_albums=>:modified_on})
|
|
115
115
|
@Album.load(:id=>4, :artist_id=>1).destroy
|
|
116
116
|
sqls = DB.sqls
|
|
117
|
-
sqls.shift.
|
|
118
|
-
sqls.sort.
|
|
117
|
+
sqls.shift.must_equal "DELETE FROM albums WHERE id = 4"
|
|
118
|
+
sqls.sort.must_equal ["UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.original_album_id = 4)",
|
|
119
119
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 1)"]
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
it "should be able to touch many_to_one associations" do
|
|
123
123
|
@Album.plugin :touch, :associations=>:artist
|
|
124
124
|
@Album.load(:id=>3, :artist_id=>4).touch
|
|
125
|
-
DB.sqls.
|
|
125
|
+
DB.sqls.must_equal ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 3)",
|
|
126
126
|
"UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (artists.id = 4)"]
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
it "should be able to touch many_to_one associations" do
|
|
130
130
|
@Artist.one_to_one :album, :class=>@Album, :key=>:artist_id
|
|
131
131
|
@Artist.plugin :touch, :associations=>:album
|
|
132
132
|
@a.touch
|
|
133
|
-
DB.sqls.
|
|
133
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
134
134
|
"UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
it "should be able to touch many_to_many associations" do
|
|
138
138
|
@Artist.many_to_many :albums, :class=>@Album, :left_key=>:artist_id, :join_table=>:aa
|
|
139
139
|
@Artist.plugin :touch, :associations=>:albums
|
|
140
140
|
@a.touch
|
|
141
|
-
DB.sqls.
|
|
141
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
142
142
|
"SELECT albums.* FROM albums INNER JOIN aa ON (aa.album_id = albums.id) WHERE (aa.artist_id = 1)",
|
|
143
143
|
"UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
it "should be able to touch many_through_many associations" do
|
|
147
147
|
@Artist.plugin :many_through_many
|
|
148
148
|
@Artist.many_through_many :albums, [[:aa, :artist_id, :album_id]], :class=>@Album
|
|
149
149
|
@Artist.plugin :touch, :associations=>:albums
|
|
150
150
|
@a.touch
|
|
151
|
-
DB.sqls.
|
|
151
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
152
152
|
"SELECT albums.* FROM albums INNER JOIN aa ON (aa.album_id = albums.id) WHERE (aa.artist_id = 1)",
|
|
153
153
|
"UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
154
154
|
end
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
it "should handle touching many_to_one associations with no associated object" do
|
|
157
157
|
@Album.plugin :touch, :associations=>:artist
|
|
158
158
|
@Album.load(:id=>3, :artist_id=>nil).touch
|
|
159
|
-
DB.sqls.
|
|
159
|
+
DB.sqls.must_equal ["UPDATE albums SET updated_at = CURRENT_TIMESTAMP WHERE (id = 3)"]
|
|
160
160
|
end
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
it "should not update a column that doesn't exist" do
|
|
163
163
|
@Album.plugin :touch, :column=>:x
|
|
164
164
|
a = @Album.load(:id=>1)
|
|
165
165
|
a.touch
|
|
166
|
-
DB.sqls.
|
|
166
|
+
DB.sqls.must_equal []
|
|
167
167
|
a.artist_id = 1
|
|
168
168
|
a.touch
|
|
169
|
-
DB.sqls.
|
|
169
|
+
DB.sqls.must_equal ['UPDATE albums SET artist_id = 1 WHERE (id = 1)']
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
it "should raise an error if given a column argument in touch that doesn't exist" do
|
|
173
173
|
@Artist.plugin :touch
|
|
174
|
-
proc{@a.touch(:x)}.
|
|
174
|
+
proc{@a.touch(:x)}.must_raise(Sequel::MassAssignmentRestriction)
|
|
175
175
|
end
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
it "should raise an Error when a nonexistent association is given" do
|
|
178
178
|
@Artist.plugin :touch
|
|
179
|
-
proc{@Artist.plugin :touch, :associations=>:blah}.
|
|
179
|
+
proc{@Artist.plugin :touch, :associations=>:blah}.must_raise(Sequel::Error)
|
|
180
180
|
end
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
it "should work correctly in subclasses" do
|
|
183
183
|
@Artist.plugin :touch
|
|
184
184
|
c1 = Class.new(@Artist)
|
|
185
185
|
c1.load(:id=>4).touch
|
|
186
|
-
DB.sqls.
|
|
186
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 4)"]
|
|
187
187
|
|
|
188
188
|
c1.touch_column = :modified_on
|
|
189
189
|
c1.touch_associations :albums
|
|
190
190
|
c1.load(:id=>1).touch
|
|
191
|
-
DB.sqls.
|
|
191
|
+
DB.sqls.must_equal ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 1)",
|
|
192
192
|
"UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 1)"]
|
|
193
193
|
|
|
194
194
|
@a.touch
|
|
195
|
-
DB.sqls.
|
|
195
|
+
DB.sqls.must_equal ["UPDATE artists SET updated_at = CURRENT_TIMESTAMP WHERE (id = 1)"]
|
|
196
196
|
|
|
197
197
|
@Artist.plugin :touch, :column=>:modified_on, :associations=>:albums
|
|
198
198
|
c2 = Class.new(@Artist)
|
|
199
199
|
c2.load(:id=>4).touch
|
|
200
|
-
DB.sqls.
|
|
200
|
+
DB.sqls.must_equal ["UPDATE artists SET modified_on = CURRENT_TIMESTAMP WHERE (id = 4)",
|
|
201
201
|
"UPDATE albums SET modified_on = CURRENT_TIMESTAMP WHERE (albums.artist_id = 4)"]
|
|
202
202
|
end
|
|
203
203
|
end
|