sequel 4.41.0 → 4.42.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 +98 -0
- data/README.rdoc +23 -10
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +5 -2
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/core_extensions.rdoc +2 -2
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/migration.rdoc +19 -1
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/release_notes/4.42.0.txt +221 -0
- data/doc/testing.rdoc +3 -1
- data/lib/sequel/adapters/ado/access.rb +0 -1
- data/lib/sequel/adapters/ado/mssql.rb +0 -1
- data/lib/sequel/adapters/do/mysql.rb +0 -1
- data/lib/sequel/adapters/do/postgres.rb +0 -1
- data/lib/sequel/adapters/do/sqlite3.rb +0 -1
- data/lib/sequel/adapters/ibmdb.rb +21 -25
- data/lib/sequel/adapters/jdbc.rb +8 -16
- data/lib/sequel/adapters/jdbc/as400.rb +0 -1
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
- data/lib/sequel/adapters/jdbc/db2.rb +0 -1
- data/lib/sequel/adapters/jdbc/derby.rb +0 -1
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
- data/lib/sequel/adapters/jdbc/h2.rb +0 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
- data/lib/sequel/adapters/mock.rb +54 -12
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +11 -17
- data/lib/sequel/adapters/odbc/mssql.rb +0 -1
- data/lib/sequel/adapters/oracle.rb +8 -20
- data/lib/sequel/adapters/postgres.rb +11 -29
- data/lib/sequel/adapters/shared/access.rb +5 -12
- data/lib/sequel/adapters/shared/cubrid.rb +4 -13
- data/lib/sequel/adapters/shared/db2.rb +4 -2
- data/lib/sequel/adapters/shared/firebird.rb +2 -4
- data/lib/sequel/adapters/shared/informix.rb +4 -2
- data/lib/sequel/adapters/shared/mssql.rb +3 -5
- data/lib/sequel/adapters/shared/mysql.rb +4 -14
- data/lib/sequel/adapters/shared/oracle.rb +1 -3
- data/lib/sequel/adapters/shared/postgres.rb +16 -38
- data/lib/sequel/adapters/shared/progress.rb +0 -2
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
- data/lib/sequel/adapters/shared/sqlite.rb +20 -16
- data/lib/sequel/adapters/sqlite.rb +8 -20
- data/lib/sequel/adapters/swift/mysql.rb +0 -1
- data/lib/sequel/adapters/swift/postgres.rb +0 -1
- data/lib/sequel/adapters/swift/sqlite.rb +0 -1
- data/lib/sequel/adapters/tinytds.rb +4 -12
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
- data/lib/sequel/ast_transformer.rb +2 -2
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +0 -66
- data/lib/sequel/database/features.rb +6 -0
- data/lib/sequel/database/misc.rb +31 -17
- data/lib/sequel/database/query.rb +7 -4
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset.rb +8 -8
- data/lib/sequel/dataset/actions.rb +140 -46
- data/lib/sequel/dataset/features.rb +1 -5
- data/lib/sequel/dataset/graph.rb +7 -8
- data/lib/sequel/dataset/misc.rb +127 -56
- data/lib/sequel/dataset/mutation.rb +9 -20
- data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
- data/lib/sequel/dataset/prepared_statements.rb +102 -46
- data/lib/sequel/dataset/query.rb +155 -72
- data/lib/sequel/dataset/sql.rb +26 -9
- data/lib/sequel/extensions/columns_introspection.rb +3 -1
- data/lib/sequel/extensions/core_extensions.rb +5 -5
- data/lib/sequel/extensions/core_refinements.rb +5 -5
- data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
- data/lib/sequel/extensions/freeze_datasets.rb +69 -0
- data/lib/sequel/extensions/identifier_mangling.rb +196 -0
- data/lib/sequel/extensions/looser_typecasting.rb +11 -7
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +5 -2
- data/lib/sequel/extensions/pagination.rb +42 -23
- data/lib/sequel/extensions/pg_enum.rb +3 -3
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
- data/lib/sequel/model/associations.rb +25 -8
- data/lib/sequel/model/base.rb +88 -29
- data/lib/sequel/model/dataset_module.rb +37 -0
- data/lib/sequel/plugins/association_pks.rb +4 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/constraint_validations.rb +1 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +8 -8
- data/lib/sequel/plugins/eager_each.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -4
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +2 -2
- data/lib/sequel/sql.rb +69 -36
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +10 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -5
- data/spec/adapters/mysql_spec.rb +9 -9
- data/spec/adapters/postgres_spec.rb +67 -68
- data/spec/adapters/spec_helper.rb +6 -1
- data/spec/adapters/sqlite_spec.rb +29 -15
- data/spec/core/connection_pool_spec.rb +14 -14
- data/spec/core/database_spec.rb +38 -180
- data/spec/core/dataset_mutation_spec.rb +253 -0
- data/spec/core/dataset_spec.rb +394 -537
- data/spec/core/expression_filters_spec.rb +34 -32
- data/spec/core/mock_adapter_spec.rb +27 -35
- data/spec/core/placeholder_literalizer_spec.rb +2 -4
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +1 -2
- data/spec/core_extensions_spec.rb +22 -29
- data/spec/extensions/active_model_spec.rb +6 -6
- data/spec/extensions/association_dependencies_spec.rb +2 -2
- data/spec/extensions/blacklist_security_spec.rb +3 -3
- data/spec/extensions/boolean_readers_spec.rb +12 -12
- data/spec/extensions/caching_spec.rb +13 -10
- data/spec/extensions/class_table_inheritance_spec.rb +38 -43
- data/spec/extensions/column_conflicts_spec.rb +1 -3
- data/spec/extensions/columns_introspection_spec.rb +2 -3
- data/spec/extensions/composition_spec.rb +5 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
- data/spec/extensions/constraint_validations_spec.rb +14 -8
- data/spec/extensions/core_refinements_spec.rb +22 -29
- data/spec/extensions/csv_serializer_spec.rb +7 -6
- data/spec/extensions/date_arithmetic_spec.rb +15 -15
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +1 -1
- data/spec/extensions/dirty_spec.rb +19 -10
- data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
- data/spec/extensions/eager_each_spec.rb +12 -16
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +4 -3
- data/spec/extensions/force_encoding_spec.rb +12 -12
- data/spec/extensions/freeze_datasets_spec.rb +31 -0
- data/spec/extensions/graph_each_spec.rb +6 -18
- data/spec/extensions/hook_class_methods_spec.rb +7 -7
- data/spec/extensions/identifier_mangling_spec.rb +307 -0
- data/spec/extensions/instance_filters_spec.rb +5 -6
- data/spec/extensions/instance_hooks_spec.rb +12 -12
- data/spec/extensions/json_serializer_spec.rb +12 -15
- data/spec/extensions/lazy_attributes_spec.rb +4 -4
- data/spec/extensions/list_spec.rb +19 -21
- data/spec/extensions/many_through_many_spec.rb +108 -163
- data/spec/extensions/meta_def_spec.rb +7 -2
- data/spec/extensions/migration_spec.rb +10 -12
- data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
- data/spec/extensions/named_timezones_spec.rb +4 -3
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +17 -12
- data/spec/extensions/optimistic_locking_spec.rb +4 -5
- data/spec/extensions/pagination_spec.rb +8 -10
- data/spec/extensions/pg_array_associations_spec.rb +28 -27
- data/spec/extensions/pg_array_ops_spec.rb +2 -1
- data/spec/extensions/pg_array_spec.rb +6 -2
- data/spec/extensions/pg_enum_spec.rb +5 -3
- data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
- data/spec/extensions/pg_hstore_spec.rb +7 -6
- data/spec/extensions/pg_inet_ops_spec.rb +2 -1
- data/spec/extensions/pg_inet_spec.rb +2 -1
- data/spec/extensions/pg_interval_spec.rb +2 -1
- data/spec/extensions/pg_json_ops_spec.rb +2 -1
- data/spec/extensions/pg_json_spec.rb +6 -3
- data/spec/extensions/pg_loose_count_spec.rb +1 -0
- data/spec/extensions/pg_range_ops_spec.rb +3 -1
- data/spec/extensions/pg_range_spec.rb +9 -5
- data/spec/extensions/pg_row_ops_spec.rb +2 -1
- data/spec/extensions/pg_row_plugin_spec.rb +4 -6
- data/spec/extensions/pg_row_spec.rb +5 -3
- data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
- data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +12 -11
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +8 -5
- data/spec/extensions/rcte_tree_spec.rb +39 -39
- data/spec/extensions/round_timestamps_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +1 -2
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
- data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
- data/spec/extensions/serialization_spec.rb +15 -13
- data/spec/extensions/set_overrides_spec.rb +14 -8
- data/spec/extensions/sharding_spec.rb +9 -18
- data/spec/extensions/shared_caching_spec.rb +3 -4
- data/spec/extensions/single_table_inheritance_spec.rb +11 -11
- data/spec/extensions/skip_create_refresh_spec.rb +2 -1
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/extensions/split_values_spec.rb +2 -2
- data/spec/extensions/sql_comments_spec.rb +6 -0
- data/spec/extensions/static_cache_spec.rb +7 -9
- data/spec/extensions/string_agg_spec.rb +30 -29
- data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
- data/spec/extensions/thread_local_timezones_spec.rb +2 -2
- data/spec/extensions/timestamps_spec.rb +28 -3
- data/spec/extensions/to_dot_spec.rb +1 -2
- data/spec/extensions/tree_spec.rb +33 -29
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -0
- data/spec/extensions/update_primary_key_spec.rb +11 -7
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +0 -1
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +10 -10
- data/spec/extensions/validation_helpers_spec.rb +10 -10
- data/spec/extensions/xml_serializer_spec.rb +7 -3
- data/spec/integration/associations_test.rb +31 -31
- data/spec/integration/dataset_test.rb +17 -19
- data/spec/integration/eager_loader_test.rb +24 -24
- data/spec/integration/model_test.rb +6 -6
- data/spec/integration/plugin_test.rb +43 -43
- data/spec/integration/prepared_statement_test.rb +6 -6
- data/spec/integration/schema_test.rb +63 -52
- data/spec/integration/spec_helper.rb +6 -1
- data/spec/integration/transaction_test.rb +13 -13
- data/spec/model/association_reflection_spec.rb +17 -17
- data/spec/model/associations_spec.rb +101 -96
- data/spec/model/base_spec.rb +175 -49
- data/spec/model/class_dataset_methods_spec.rb +5 -9
- data/spec/model/dataset_methods_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +209 -235
- data/spec/model/hooks_spec.rb +15 -15
- data/spec/model/model_spec.rb +28 -21
- data/spec/model/plugins_spec.rb +4 -5
- data/spec/model/record_spec.rb +59 -57
- data/spec/model/spec_helper.rb +1 -1
- data/spec/model/validations_spec.rb +6 -6
- data/spec/spec_config.rb +1 -1
- metadata +10 -2
|
@@ -123,8 +123,10 @@ describe "Composition plugin" do
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
it "should not clear compositions cache when saving with insert_select" do
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
@c.dataset = @c.dataset.with_extend do
|
|
127
|
+
def supports_insert_select?; true end
|
|
128
|
+
def insert_select(*) {:id=>1} end
|
|
129
|
+
end
|
|
128
130
|
@c.composition :date, :composer=>proc{}, :decomposer=>proc{}
|
|
129
131
|
@c.create(:date=>Date.new(3, 4, 5)).compositions.must_equal(:date=>Date.new(3, 4, 5))
|
|
130
132
|
end
|
|
@@ -201,7 +203,7 @@ describe "Composition plugin" do
|
|
|
201
203
|
|
|
202
204
|
it ":mapping option :composer should return nil if all values are nil" do
|
|
203
205
|
@c.composition :date, :mapping=>[:year, :month, :day]
|
|
204
|
-
@c.new.date.
|
|
206
|
+
@c.new.date.must_be_nil
|
|
205
207
|
end
|
|
206
208
|
|
|
207
209
|
it ":mapping option :decomposer should set all related fields to nil if nil" do
|
|
@@ -19,9 +19,9 @@ describe "Sequel::Plugins::ConstraintValidations" do
|
|
|
19
19
|
@db = Sequel.mock
|
|
20
20
|
set_fetch({})
|
|
21
21
|
@ds = @db[:items]
|
|
22
|
-
@ds.
|
|
22
|
+
@ds.send(:columns=, [:name])
|
|
23
23
|
@ds2 = Sequel.mock[:items2]
|
|
24
|
-
@ds2.
|
|
24
|
+
@ds2.send(:columns=, [:name])
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "should load the validation_helpers plugin into the class" do
|
|
@@ -234,7 +234,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
|
|
|
234
234
|
c.plugin :constraint_validations, :validation_options=>{:unique=>{:message=>'is bad'}}
|
|
235
235
|
c.constraint_validations.must_equal [[:validates_unique, [:name], {:message=>'is bad'}]]
|
|
236
236
|
c.constraint_validation_reflections.must_equal(:name=>[[:unique, {:message=>'is bad'}]])
|
|
237
|
-
c.dataset
|
|
237
|
+
c.dataset = c.dataset.with_fetch(:count=>1)
|
|
238
238
|
o = c.new(:name=>'a')
|
|
239
239
|
o.valid?.must_equal false
|
|
240
240
|
o.errors.full_messages.must_equal ['name is bad']
|
|
@@ -245,7 +245,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
|
|
|
245
245
|
c.plugin :constraint_validations, :validation_options=>{:unique=>{:message=>'is bad'}}
|
|
246
246
|
c.constraint_validations.must_equal [[:validates_unique, [:name], {:message=>'is bad', :allow_nil=>true}]]
|
|
247
247
|
c.constraint_validation_reflections.must_equal(:name=>[[:unique, {:message=>'is bad', :allow_nil=>true}]])
|
|
248
|
-
c.dataset
|
|
248
|
+
c.dataset = c.dataset.with_fetch(:count=>1)
|
|
249
249
|
o = c.new(:name=>'a')
|
|
250
250
|
o.valid?.must_equal false
|
|
251
251
|
o.errors.full_messages.must_equal ['name is bad']
|
|
@@ -258,7 +258,7 @@ describe "Sequel::Plugins::ConstraintValidations" do
|
|
|
258
258
|
sc.plugin :constraint_validations, :validation_options=>{:unique=>{:allow_missing=>true, :allow_nil=>false}}
|
|
259
259
|
sc.constraint_validations.must_equal [[:validates_unique, [:name], {:message=>'is bad', :allow_missing=>true, :allow_nil=>false}]]
|
|
260
260
|
sc.constraint_validation_reflections.must_equal(:name=>[[:unique, {:message=>'is bad', :allow_missing=>true, :allow_nil=>false}]])
|
|
261
|
-
sc.dataset
|
|
261
|
+
sc.dataset = sc.dataset.with_fetch(:count=>1)
|
|
262
262
|
o = sc.new(:name=>'a')
|
|
263
263
|
o.valid?.must_equal false
|
|
264
264
|
o.errors.full_messages.must_equal ['name is bad']
|
|
@@ -2,8 +2,8 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "constraint_validations extension" do
|
|
4
4
|
def parse_insert(s)
|
|
5
|
-
m = /\AINSERT INTO sequel_constraint_validations \((.*)
|
|
6
|
-
Hash[*m[1].split(
|
|
5
|
+
m = /\AINSERT INTO "?sequel_constraint_validations"? \("?(.*)"?\) VALUES \((.*)\)\z/.match(s)
|
|
6
|
+
Hash[*m[1].split(/"?, "?/).map{|v| v.to_sym}.zip(m[2].split(/"?, "?/).map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def parse_insert_value(s)
|
|
@@ -130,13 +130,17 @@ describe "constraint_validations extension" do
|
|
|
130
130
|
|
|
131
131
|
it "should handle presence validation on Oracle with IS NOT NULL instead of != ''" do
|
|
132
132
|
@db = Sequel.mock(:host=>'oracle')
|
|
133
|
+
@db.extend_datasets do
|
|
134
|
+
def quote_identifiers?; false end
|
|
135
|
+
def input_identifier(v) v.to_s end
|
|
136
|
+
end
|
|
133
137
|
@db.extension(:constraint_validations)
|
|
134
138
|
@db.create_table(:foo){String :name; validate{presence :name}}
|
|
135
139
|
sqls = @db.sqls
|
|
136
|
-
s = sqls.slice!(1)
|
|
137
|
-
m = /\AINSERT INTO sequel_constraint_validations \((.*)\) SELECT (.*) FROM DUAL\z
|
|
138
|
-
Hash[*m[1].split(', ').map{|v| v.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten].must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
|
|
139
|
-
sqls.must_equal ["BEGIN", "COMMIT",
|
|
140
|
+
s = sqls.slice!(1).upcase
|
|
141
|
+
m = /\AINSERT INTO sequel_constraint_validations \((.*)\) SELECT (.*) FROM DUAL\z/i.match(s)
|
|
142
|
+
Hash[*m[1].split(', ').map{|v| v.downcase.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v.downcase.gsub('null', 'NULL'))}).reject{|k, v| v.nil?}.flatten].must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
|
|
143
|
+
sqls.must_equal ["BEGIN", "COMMIT", 'CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) IS NOT NULL)))']
|
|
140
144
|
end
|
|
141
145
|
|
|
142
146
|
it "should assume column is not a String if it can't determine the type" do
|
|
@@ -194,20 +198,22 @@ describe "constraint_validations extension" do
|
|
|
194
198
|
|
|
195
199
|
it "should support :format constraint validation" do
|
|
196
200
|
@db = Sequel.mock(:host=>'postgres')
|
|
201
|
+
@db.extend_datasets{def quote_identifiers?; false end}
|
|
197
202
|
@db.extension(:constraint_validations)
|
|
198
203
|
@db.create_table(:foo){String :name; validate{format(/^foo.*/, :name)}}
|
|
199
204
|
sqls = @db.sqls
|
|
200
205
|
parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"format", :column=>"name", :table=>"foo", :argument=>'^foo.*')
|
|
201
|
-
sqls.must_equal ["BEGIN", "COMMIT",
|
|
206
|
+
sqls.must_equal ["BEGIN", "COMMIT", %[CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~ '^foo.*')))]]
|
|
202
207
|
end
|
|
203
208
|
|
|
204
209
|
it "should support :format constraint validation with case insensitive format" do
|
|
205
210
|
@db = Sequel.mock(:host=>'postgres')
|
|
211
|
+
@db.extend_datasets{def quote_identifiers?; false end}
|
|
206
212
|
@db.extension(:constraint_validations)
|
|
207
213
|
@db.create_table(:foo){String :name; validate{format(/^foo.*/i, :name)}}
|
|
208
214
|
sqls = @db.sqls
|
|
209
215
|
parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"iformat", :column=>"name", :table=>"foo", :argument=>'^foo.*')
|
|
210
|
-
sqls.must_equal ["BEGIN", "COMMIT",
|
|
216
|
+
sqls.must_equal ["BEGIN", "COMMIT", %[CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~* '^foo.*')))]]
|
|
211
217
|
end
|
|
212
218
|
|
|
213
219
|
it "should support :includes constraint validation with an array of strings" do
|
|
@@ -6,14 +6,15 @@ using Sequel::CoreRefinements
|
|
|
6
6
|
|
|
7
7
|
describe "Core refinements" do
|
|
8
8
|
before do
|
|
9
|
-
db = Sequel
|
|
10
|
-
@d = db[:items]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
db = Sequel.mock
|
|
10
|
+
@d = db[:items].with_extend do
|
|
11
|
+
def supports_regexp?; true end
|
|
12
|
+
def l(*args, &block)
|
|
13
|
+
literal(filter_expr(*args, &block))
|
|
14
|
+
end
|
|
15
|
+
def lit(*args)
|
|
16
|
+
literal(*args)
|
|
17
|
+
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -184,7 +185,7 @@ end
|
|
|
184
185
|
|
|
185
186
|
describe "String#lit" do
|
|
186
187
|
before do
|
|
187
|
-
@ds = Sequel
|
|
188
|
+
@ds = Sequel.mock[:t]
|
|
188
189
|
end
|
|
189
190
|
|
|
190
191
|
it "should return an LiteralString object" do
|
|
@@ -200,16 +201,14 @@ describe "String#lit" do
|
|
|
200
201
|
a = 'DISTINCT ?'.lit(:a)
|
|
201
202
|
a.must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
|
|
202
203
|
@ds.literal(a).must_equal 'DISTINCT a'
|
|
203
|
-
@ds.
|
|
204
|
-
@ds.literal(a).must_equal 'DISTINCT "a"'
|
|
204
|
+
@ds.with_quote_identifiers(true).literal(a).must_equal 'DISTINCT "a"'
|
|
205
205
|
end
|
|
206
206
|
|
|
207
207
|
it "should handle named placeholders if given a single argument hash" do
|
|
208
208
|
a = 'DISTINCT :b'.lit(:b=>:a)
|
|
209
209
|
a.must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
|
|
210
210
|
@ds.literal(a).must_equal 'DISTINCT a'
|
|
211
|
-
@ds.
|
|
212
|
-
@ds.literal(a).must_equal 'DISTINCT "a"'
|
|
211
|
+
@ds.with_quote_identifiers(true).literal(a).must_equal 'DISTINCT "a"'
|
|
213
212
|
end
|
|
214
213
|
|
|
215
214
|
it "should treat placeholder literal strings as generic expressions" do
|
|
@@ -285,11 +284,7 @@ end
|
|
|
285
284
|
|
|
286
285
|
describe "Column references" do
|
|
287
286
|
before do
|
|
288
|
-
@ds = Sequel
|
|
289
|
-
def @ds.quoted_identifier_append(sql, c)
|
|
290
|
-
sql << "`#{c}`"
|
|
291
|
-
end
|
|
292
|
-
@ds.quote_identifiers = true
|
|
287
|
+
@ds = Sequel.mock.dataset.with_quote_identifiers(true).with_extend{def quoted_identifier_append(sql, c) sql << "`#{c}`" end}
|
|
293
288
|
end
|
|
294
289
|
|
|
295
290
|
it "should be quoted properly" do
|
|
@@ -349,30 +344,28 @@ end
|
|
|
349
344
|
|
|
350
345
|
describe "Symbol" do
|
|
351
346
|
before do
|
|
352
|
-
@ds = Sequel.mock.dataset
|
|
353
|
-
@ds.quote_identifiers = true
|
|
354
|
-
@ds.identifier_input_method = :upcase
|
|
347
|
+
@ds = Sequel.mock.dataset.with_quote_identifiers(true)
|
|
355
348
|
end
|
|
356
349
|
|
|
357
350
|
it "#identifier should format an identifier" do
|
|
358
|
-
@ds.literal(:xyz__abc.identifier).must_equal '"
|
|
351
|
+
@ds.literal(:xyz__abc.identifier).must_equal '"xyz__abc"'
|
|
359
352
|
end
|
|
360
353
|
|
|
361
354
|
it "#qualify should format a qualified column" do
|
|
362
|
-
@ds.literal(:xyz.qualify(:abc)).must_equal '"
|
|
355
|
+
@ds.literal(:xyz.qualify(:abc)).must_equal '"abc"."xyz"'
|
|
363
356
|
end
|
|
364
357
|
|
|
365
358
|
it "#qualify should work on QualifiedIdentifiers" do
|
|
366
|
-
@ds.literal(:xyz.qualify(:abc).qualify(:def)).must_equal '"
|
|
359
|
+
@ds.literal(:xyz.qualify(:abc).qualify(:def)).must_equal '"def"."abc"."xyz"'
|
|
367
360
|
end
|
|
368
361
|
|
|
369
362
|
it "should be able to qualify an identifier" do
|
|
370
|
-
@ds.literal(:xyz.identifier.qualify(:xyz__abc)).must_equal '"
|
|
363
|
+
@ds.literal(:xyz.identifier.qualify(:xyz__abc)).must_equal '"xyz"."abc"."xyz"'
|
|
371
364
|
end
|
|
372
365
|
|
|
373
366
|
it "should be able to specify a schema.table.column" do
|
|
374
|
-
@ds.literal(:column.qualify(:table.qualify(:schema))).must_equal '"
|
|
375
|
-
@ds.literal(:column.qualify(:table__name.identifier.qualify(:schema))).must_equal '"
|
|
367
|
+
@ds.literal(:column.qualify(:table.qualify(:schema))).must_equal '"schema"."table"."column"'
|
|
368
|
+
@ds.literal(:column.qualify(:table__name.identifier.qualify(:schema))).must_equal '"schema"."table__name"."column"'
|
|
376
369
|
end
|
|
377
370
|
|
|
378
371
|
it "should be able to specify order" do
|
|
@@ -387,13 +380,13 @@ describe "Symbol" do
|
|
|
387
380
|
it "should work correctly with objects" do
|
|
388
381
|
o = Object.new
|
|
389
382
|
def o.sql_literal(ds) "(foo)" end
|
|
390
|
-
@ds.literal(:column.qualify(o)).must_equal '(foo)."
|
|
383
|
+
@ds.literal(:column.qualify(o)).must_equal '(foo)."column"'
|
|
391
384
|
end
|
|
392
385
|
end
|
|
393
386
|
|
|
394
387
|
describe "Symbol" do
|
|
395
388
|
before do
|
|
396
|
-
@ds = Sequel
|
|
389
|
+
@ds = Sequel.mock.dataset
|
|
397
390
|
end
|
|
398
391
|
|
|
399
392
|
it "should support sql_function method" do
|
|
@@ -95,7 +95,7 @@ describe "Sequel::Plugins::CsvSerializer" do
|
|
|
95
95
|
|
|
96
96
|
@album = @Album.from_csv('2,AS', :headers=>[nil, 'name'])
|
|
97
97
|
@album.name.must_equal 'AS'
|
|
98
|
-
@album.artist_id.
|
|
98
|
+
@album.artist_id.must_be_nil
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
it "#from_csv should support :headers to specify headers" do
|
|
@@ -109,8 +109,10 @@ describe "Sequel::Plugins::CsvSerializer" do
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
it "should support a to_csv class and dataset method" do
|
|
112
|
-
@Album.dataset
|
|
113
|
-
@Artist.dataset
|
|
112
|
+
@Album.dataset = @Album.dataset.with_fetch(:id=>1, :name=>'RF', :artist_id=>2)
|
|
113
|
+
@Artist.dataset = @Artist.dataset.with_fetch(:id=>2, :name=>'YJM')
|
|
114
|
+
@Album.columns(:id, :name, :artist_id)
|
|
115
|
+
@Album.db_schema.replace(:id=>{:type=>:integer}, :artist_id=>{:type=>:integer})
|
|
114
116
|
@Album.array_from_csv(@Album.to_csv).must_equal [@album]
|
|
115
117
|
@Album.array_from_csv(@Album.dataset.to_csv(:only=>:name), :only=>:name).must_equal [@Album.load(:name=>@album.name)]
|
|
116
118
|
end
|
|
@@ -166,9 +168,8 @@ describe "Sequel::Plugins::CsvSerializer" do
|
|
|
166
168
|
it "should use a dataset's selected columns" do
|
|
167
169
|
columns = [:id]
|
|
168
170
|
ds = @Artist.select(*columns).limit(1)
|
|
169
|
-
ds.
|
|
170
|
-
ds.
|
|
171
|
-
ds.to_csv(:write_headers => true).must_equal "id\n10\n"
|
|
171
|
+
ds.send(:columns=, columns)
|
|
172
|
+
ds.with_fetch(:id => 10).to_csv(:write_headers => true).must_equal "id\n10\n"
|
|
172
173
|
end
|
|
173
174
|
|
|
174
175
|
it "should pass all the examples from the documentation" do
|
|
@@ -83,21 +83,21 @@ describe "date_arithmetic extension" do
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
it "should correctly literalize on Postgres" do
|
|
86
|
-
db = dbf.call(:postgres)
|
|
86
|
+
db = dbf.call(:postgres).dataset.with_quote_identifiers(false)
|
|
87
87
|
db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS timestamp)"
|
|
88
88
|
db.literal(Sequel.date_add(:a, @h1)).must_equal "(CAST(a AS timestamp) + CAST('1 days ' AS interval))"
|
|
89
89
|
db.literal(Sequel.date_add(:a, @h2)).must_equal "(CAST(a AS timestamp) + CAST('1 years 1 months 1 days 1 hours 1 minutes 1 seconds ' AS interval))"
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
it "should correctly literalize on SQLite" do
|
|
93
|
-
db = dbf.call(:sqlite)
|
|
93
|
+
db = dbf.call(:sqlite).dataset.with_quote_identifiers(false)
|
|
94
94
|
db.literal(Sequel.date_add(:a, @h0)).must_equal "datetime(a)"
|
|
95
95
|
db.literal(Sequel.date_add(:a, @h1)).must_equal "datetime(a, '1 days')"
|
|
96
96
|
db.literal(Sequel.date_add(:a, @h2)).must_equal "datetime(a, '1 years', '1 months', '1 days', '1 hours', '1 minutes', '1 seconds')"
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
it "should correctly literalize on MySQL" do
|
|
100
|
-
db = dbf.call(:mysql)
|
|
100
|
+
db = dbf.call(:mysql).dataset.with_quote_identifiers(false)
|
|
101
101
|
db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS DATETIME)"
|
|
102
102
|
db.literal(Sequel.date_add(:a, @h1)).must_equal "DATE_ADD(a, INTERVAL 1 DAY)"
|
|
103
103
|
db.literal(Sequel.date_add(:a, @h2)).must_equal "DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(DATE_ADD(a, INTERVAL 1 YEAR), INTERVAL 1 MONTH), INTERVAL 1 DAY), INTERVAL 1 HOUR), INTERVAL 1 MINUTE), INTERVAL 1 SECOND)"
|
|
@@ -113,10 +113,10 @@ describe "date_arithmetic extension" do
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
it "should correctly literalize on MSSQL" do
|
|
116
|
-
db = dbf.call(:mssql)
|
|
117
|
-
db.literal(Sequel.date_add(:
|
|
118
|
-
db.literal(Sequel.date_add(:
|
|
119
|
-
db.literal(Sequel.date_add(:
|
|
116
|
+
db = dbf.call(:mssql).dataset.with_quote_identifiers(false)
|
|
117
|
+
db.literal(Sequel.date_add(:A, @h0)).must_equal "CAST(A AS datetime)"
|
|
118
|
+
db.literal(Sequel.date_add(:A, @h1)).must_equal "DATEADD(day, 1, A)"
|
|
119
|
+
db.literal(Sequel.date_add(:A, @h2)).must_equal "DATEADD(second, 1, DATEADD(minute, 1, DATEADD(hour, 1, DATEADD(day, 1, DATEADD(month, 1, DATEADD(year, 1, A))))))"
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
it "should correctly literalize on H2" do
|
|
@@ -129,7 +129,7 @@ describe "date_arithmetic extension" do
|
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
it "should correctly literalize on access" do
|
|
132
|
-
db = dbf.call(:access)
|
|
132
|
+
db = dbf.call(:access).dataset.with_quote_identifiers(false)
|
|
133
133
|
db.literal(Sequel.date_add(:a, @h0)).must_equal "CDate(a)"
|
|
134
134
|
db.literal(Sequel.date_add(:a, @h1)).must_equal "DATEADD('d', 1, a)"
|
|
135
135
|
db.literal(Sequel.date_add(:a, @h2)).must_equal "DATEADD('s', 1, DATEADD('n', 1, DATEADD('h', 1, DATEADD('d', 1, DATEADD('m', 1, DATEADD('yyyy', 1, a))))))"
|
|
@@ -146,17 +146,17 @@ describe "date_arithmetic extension" do
|
|
|
146
146
|
end
|
|
147
147
|
|
|
148
148
|
it "should correctly literalize on Oracle" do
|
|
149
|
-
db = dbf.call(:oracle)
|
|
150
|
-
db.literal(Sequel.date_add(:
|
|
151
|
-
db.literal(Sequel.date_add(:
|
|
152
|
-
db.literal(Sequel.date_add(:
|
|
149
|
+
db = dbf.call(:oracle).dataset.with_quote_identifiers(false)
|
|
150
|
+
db.literal(Sequel.date_add(:A, @h0)).must_equal "CAST(A AS timestamp)"
|
|
151
|
+
db.literal(Sequel.date_add(:A, @h1)).must_equal "(A + INTERVAL '1' DAY)"
|
|
152
|
+
db.literal(Sequel.date_add(:A, @h2)).must_equal "(A + INTERVAL '1' YEAR + INTERVAL '1' MONTH + INTERVAL '1' DAY + INTERVAL '1' HOUR + INTERVAL '1' MINUTE + INTERVAL '1' SECOND)"
|
|
153
153
|
end
|
|
154
154
|
|
|
155
155
|
it "should correctly literalize on DB2" do
|
|
156
156
|
db = dbf.call(:db2)
|
|
157
|
-
db.literal(Sequel.date_add(:
|
|
158
|
-
db.literal(Sequel.date_add(:
|
|
159
|
-
db.literal(Sequel.date_add(:
|
|
157
|
+
db.literal(Sequel.date_add(:A, @h0)).must_equal "CAST(A AS timestamp)"
|
|
158
|
+
db.literal(Sequel.date_add(:A, @h1)).must_equal "(CAST(A AS timestamp) + 1 days)"
|
|
159
|
+
db.literal(Sequel.date_add(:A, @h2)).must_equal "(CAST(A AS timestamp) + 1 years + 1 months + 1 days + 1 hours + 1 minutes + 1 seconds)"
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
it "should raise error if literalizing on an unsupported database" do
|
|
@@ -63,7 +63,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
|
63
63
|
it "should not override a given value" do
|
|
64
64
|
@pr.call(2)
|
|
65
65
|
@c.new('a'=>3).a.must_equal 3
|
|
66
|
-
@c.new('a'=>nil).a.
|
|
66
|
+
@c.new('a'=>nil).a.must_be_nil
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
it "should work correctly when subclassing" do
|
|
@@ -90,7 +90,7 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
|
90
90
|
it "should have procs that set default values set them to nil" do
|
|
91
91
|
@pr.call(2)
|
|
92
92
|
@c.default_values[:a] = proc{nil}
|
|
93
|
-
@c.new.a.
|
|
93
|
+
@c.new.a.must_be_nil
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
it "should work correctly on a model without a dataset" do
|
|
@@ -45,7 +45,7 @@ describe "Sequel::Plugins::DelayAddAssociation" do
|
|
|
45
45
|
@c.send(:define_method, :validate){|*| errors.add(:name, 'is b') if name == 'b'}
|
|
46
46
|
@o = @c.new(:name=>'a')
|
|
47
47
|
@o.add_c(@c.load(:id=>2, :name=>'b'))
|
|
48
|
-
@o.save.
|
|
48
|
+
@o.save.must_be_nil
|
|
49
49
|
@o.errors[:cs].must_equal ["name is b"]
|
|
50
50
|
@o.cs.first.errors[:name].must_equal ['is b']
|
|
51
51
|
end
|
|
@@ -11,19 +11,19 @@ describe "Sequel::Plugins::Dirty" do
|
|
|
11
11
|
dirty_plugin_specs = shared_description do
|
|
12
12
|
it "initial_value should be the current value if value has not changed" do
|
|
13
13
|
@o.initial_value(:initial).must_equal 'i'
|
|
14
|
-
@o.initial_value(:missing).
|
|
14
|
+
@o.initial_value(:missing).must_be_nil
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
it "initial_value should be the intial value if value has changed" do
|
|
18
18
|
@o.initial_value(:initial_changed).must_equal 'ic'
|
|
19
|
-
@o.initial_value(:missing_changed).
|
|
19
|
+
@o.initial_value(:missing_changed).must_be_nil
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "initial_value should handle case where initial value is reassigned later" do
|
|
23
23
|
@o.initial_changed = 'ic'
|
|
24
24
|
@o.initial_value(:initial_changed).must_equal 'ic'
|
|
25
25
|
@o.missing_changed = nil
|
|
26
|
-
@o.initial_value(:missing_changed).
|
|
26
|
+
@o.initial_value(:missing_changed).must_be_nil
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "changed_columns should handle case where initial value is reassigned later" do
|
|
@@ -40,8 +40,8 @@ describe "Sequel::Plugins::Dirty" do
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "column_change should be nil if no change has been made" do
|
|
43
|
-
@o.column_change(:initial).
|
|
44
|
-
@o.column_change(:missing).
|
|
43
|
+
@o.column_change(:initial).must_be_nil
|
|
44
|
+
@o.column_change(:missing).must_be_nil
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "column_changed? should return whether the column has changed" do
|
|
@@ -76,9 +76,9 @@ describe "Sequel::Plugins::Dirty" do
|
|
|
76
76
|
@o.reset_column(:initial_changed)
|
|
77
77
|
@o.initial_changed.must_equal 'ic'
|
|
78
78
|
@o.reset_column(:missing)
|
|
79
|
-
@o.missing.
|
|
79
|
+
@o.missing.must_be_nil
|
|
80
80
|
@o.reset_column(:missing_changed)
|
|
81
|
-
@o.missing_changed.
|
|
81
|
+
@o.missing_changed.must_be_nil
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
it "reset_column should remove missing values from the values" do
|
|
@@ -124,11 +124,18 @@ describe "Sequel::Plugins::Dirty" do
|
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
it "should have #dup duplicate structures" do
|
|
127
|
+
was_new = @o.new?
|
|
128
|
+
@o.update(:missing=>'m2')
|
|
127
129
|
@o.dup.initial_values.must_equal @o.initial_values
|
|
128
130
|
@o.dup.initial_values.wont_be_same_as(@o.initial_values)
|
|
129
131
|
@o.dup.instance_variable_get(:@missing_initial_values).must_equal @o.instance_variable_get(:@missing_initial_values)
|
|
130
132
|
@o.dup.instance_variable_get(:@missing_initial_values).wont_be_same_as(@o.instance_variable_get(:@missing_initial_values))
|
|
131
|
-
|
|
133
|
+
if was_new
|
|
134
|
+
@o.previous_changes.must_be_nil
|
|
135
|
+
@o.dup.previous_changes.must_be_nil
|
|
136
|
+
else
|
|
137
|
+
@o.dup.previous_changes.must_equal @o.previous_changes
|
|
138
|
+
end
|
|
132
139
|
@o.dup.previous_changes.wont_be_same_as(@o.previous_changes) if @o.previous_changes
|
|
133
140
|
end
|
|
134
141
|
end
|
|
@@ -148,8 +155,10 @@ describe "Sequel::Plugins::Dirty" do
|
|
|
148
155
|
end
|
|
149
156
|
|
|
150
157
|
it "save_changes should clear the cached initial values" do
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
@c.dataset = @c.dataset.with_extend do
|
|
159
|
+
def supports_insert_select?; true end
|
|
160
|
+
def insert_select(*) {:id=>1} end
|
|
161
|
+
end
|
|
153
162
|
@o.save
|
|
154
163
|
@o.column_changes.must_equal({})
|
|
155
164
|
end
|