sequel 4.47.0 → 4.48.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 +134 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.48.0.txt +293 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +24 -7
- data/lib/sequel/adapters/jdbc.rb +36 -22
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
- data/lib/sequel/adapters/mock.rb +24 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +4 -5
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +89 -102
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +75 -24
- data/lib/sequel/adapters/shared/postgres.rb +196 -94
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +5 -5
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +18 -10
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +19 -8
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +6 -6
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +24 -24
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model.rb +25 -57
- data/lib/sequel/model/associations.rb +14 -5
- data/lib/sequel/model/base.rb +96 -32
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +1 -1
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/defaults_setter.rb +10 -0
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +17 -10
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +5 -1
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/serialization.rb +3 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +2 -4
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mysql_spec.rb +78 -28
- data/spec/adapters/oracle_spec.rb +24 -24
- data/spec/adapters/postgres_spec.rb +38 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/core/connection_pool_spec.rb +17 -0
- data/spec/core/database_spec.rb +6 -0
- data/spec/core/dataset_spec.rb +46 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +48 -2
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +8 -8
- data/spec/extensions/defaults_setter_spec.rb +1 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +96 -98
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +9 -3
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/plugin_test.rb +20 -0
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/class_dataset_methods_spec.rb +14 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/model_spec.rb +8 -0
- metadata +6 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -18,6 +18,32 @@ describe "pg_inet extension" do
|
|
|
18
18
|
@db.literal(IPAddr.new('2001:4f8:3:ba:2e0:81ff:fe22:d1f1')).must_equal "'2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128'"
|
|
19
19
|
end unless ipv6_broken
|
|
20
20
|
|
|
21
|
+
deprecated "should set up conversion procs correctly" do
|
|
22
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
23
|
+
cp[869].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
24
|
+
cp[650].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
28
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
29
|
+
cp[1041].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
30
|
+
cp[651].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
31
|
+
cp[1040].call("{127.0.0.1}").must_equal ['127.0.0.1']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should set up conversion procs correctly" do
|
|
35
|
+
cp = @db.conversion_procs
|
|
36
|
+
cp[869].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
37
|
+
cp[650].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should set up conversion procs for arrays correctly" do
|
|
41
|
+
cp = @db.conversion_procs
|
|
42
|
+
cp[1041].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
43
|
+
cp[651].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
|
|
44
|
+
cp[1040].call("{127.0.0.1}").must_equal ['127.0.0.1']
|
|
45
|
+
end
|
|
46
|
+
|
|
21
47
|
it "should not affect literalization of custom objects" do
|
|
22
48
|
o = Object.new
|
|
23
49
|
def o.sql_literal(ds) 'v' end
|
|
@@ -34,6 +34,26 @@ describe "pg_interval extension" do
|
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
deprecated "should set up conversion procs correctly" do
|
|
38
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
39
|
+
cp[1186].call("1 sec").must_equal ActiveSupport::Duration.new(1, [[:seconds, 1]])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
43
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
44
|
+
cp[1187].call("{1 sec}").must_equal [ActiveSupport::Duration.new(1, [[:seconds, 1]])]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should set up conversion procs correctly" do
|
|
48
|
+
cp = @db.conversion_procs
|
|
49
|
+
cp[1186].call("1 sec").must_equal ActiveSupport::Duration.new(1, [[:seconds, 1]])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should set up conversion procs for arrays correctly" do
|
|
53
|
+
cp = @db.conversion_procs
|
|
54
|
+
cp[1187].call("{1 sec}").must_equal [ActiveSupport::Duration.new(1, [[:seconds, 1]])]
|
|
55
|
+
end
|
|
56
|
+
|
|
37
57
|
it "should not affect literalization of custom objects" do
|
|
38
58
|
o = Object.new
|
|
39
59
|
def o.sql_literal(ds) 'v' end
|
|
@@ -17,6 +17,30 @@ describe "pg_json extension" do
|
|
|
17
17
|
@db.extension(:pg_array, :pg_json)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
deprecated "should set up conversion procs correctly" do
|
|
21
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
22
|
+
cp[114].call("{}").must_equal @hc.new({})
|
|
23
|
+
cp[3802].call("{}").must_equal @bhc.new({})
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
27
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
28
|
+
cp[199].call("{[]}").must_equal [@ac.new([])]
|
|
29
|
+
cp[3807].call("{[]}").must_equal [@bac.new([])]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should set up conversion procs correctly" do
|
|
33
|
+
cp = @db.conversion_procs
|
|
34
|
+
cp[114].call("{}").must_equal @hc.new({})
|
|
35
|
+
cp[3802].call("{}").must_equal @bhc.new({})
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should set up conversion procs for arrays correctly" do
|
|
39
|
+
cp = @db.conversion_procs
|
|
40
|
+
cp[199].call("{[]}").must_equal [@ac.new([])]
|
|
41
|
+
cp[3807].call("{[]}").must_equal [@bac.new([])]
|
|
42
|
+
end
|
|
43
|
+
|
|
20
44
|
it "should parse json strings correctly" do
|
|
21
45
|
@m.parse_json('[]').class.must_equal(@ac)
|
|
22
46
|
@m.parse_json('[]').to_a.must_equal []
|
|
@@ -4,10 +4,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
4
4
|
describe "pg_range extension" do
|
|
5
5
|
before(:all) do
|
|
6
6
|
Sequel.extension :pg_array, :pg_range
|
|
7
|
-
@pg_types = Sequel::Postgres::
|
|
7
|
+
@pg_types = Sequel::Postgres::PG__TYPES.dup # SEQUEL5: Remove
|
|
8
8
|
end
|
|
9
9
|
after(:all) do
|
|
10
|
-
Sequel::Postgres::
|
|
10
|
+
Sequel::Postgres::PG__TYPES.replace(@pg_types) # SEQUEL5: Remove
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
before do
|
|
@@ -21,6 +21,46 @@ describe "pg_range extension" do
|
|
|
21
21
|
@db.extension(:pg_array, :pg_range)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
deprecated "should set up conversion procs correctly" do
|
|
25
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
26
|
+
cp[3904].call("[1,2]").must_equal @R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int4range')
|
|
27
|
+
cp[3906].call("[1,2]").must_equal @R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'numrange')
|
|
28
|
+
cp[3908].call("[2011-01-02 10:20:30,2011-02-03 10:20:30)").must_equal @R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tsrange')
|
|
29
|
+
cp[3910].call("[2011-01-02 10:20:30,2011-02-03 10:20:30)").must_equal @R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tstzrange')
|
|
30
|
+
cp[3912].call("[2011-01-02,2011-02-03)").must_equal @R.new(Date.new(2011, 1, 2),Date.new(2011, 2, 3), :exclude_begin=>false, :exclude_end=>true, :db_type=>'daterange')
|
|
31
|
+
cp[3926].call("[1,2]").must_equal @R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int8range')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
deprecated "should set up conversion procs for arrays correctly" do
|
|
35
|
+
cp = Sequel::Postgres::PG__TYPES
|
|
36
|
+
cp[3905].call("{\"[1,2]\"}").must_equal [@R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int4range')]
|
|
37
|
+
cp[3907].call("{\"[1,2]\"}").must_equal [@R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'numrange')]
|
|
38
|
+
cp[3909].call("{\"[2011-01-02 10:20:30,2011-02-03 10:20:30)\"}").must_equal [@R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tsrange')]
|
|
39
|
+
cp[3911].call("{\"[2011-01-02 10:20:30,2011-02-03 10:20:30)\"}").must_equal [@R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tstzrange')]
|
|
40
|
+
cp[3913].call("{\"[2011-01-02,2011-02-03)\"}").must_equal [@R.new(Date.new(2011, 1, 2),Date.new(2011, 2, 3), :exclude_begin=>false, :exclude_end=>true, :db_type=>'daterange')]
|
|
41
|
+
cp[3927].call("{\"[1,2]\"}").must_equal [@R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int8range')]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should set up conversion procs correctly" do
|
|
45
|
+
cp = @db.conversion_procs
|
|
46
|
+
cp[3904].call("[1,2]").must_equal @R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int4range')
|
|
47
|
+
cp[3906].call("[1,2]").must_equal @R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'numrange')
|
|
48
|
+
cp[3908].call("[2011-01-02 10:20:30,2011-02-03 10:20:30)").must_equal @R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tsrange')
|
|
49
|
+
cp[3910].call("[2011-01-02 10:20:30,2011-02-03 10:20:30)").must_equal @R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tstzrange')
|
|
50
|
+
cp[3912].call("[2011-01-02,2011-02-03)").must_equal @R.new(Date.new(2011, 1, 2),Date.new(2011, 2, 3), :exclude_begin=>false, :exclude_end=>true, :db_type=>'daterange')
|
|
51
|
+
cp[3926].call("[1,2]").must_equal @R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int8range')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should set up conversion procs for arrays correctly" do
|
|
55
|
+
cp = @db.conversion_procs
|
|
56
|
+
cp[3905].call("{\"[1,2]\"}").must_equal [@R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int4range')]
|
|
57
|
+
cp[3907].call("{\"[1,2]\"}").must_equal [@R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'numrange')]
|
|
58
|
+
cp[3909].call("{\"[2011-01-02 10:20:30,2011-02-03 10:20:30)\"}").must_equal [@R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tsrange')]
|
|
59
|
+
cp[3911].call("{\"[2011-01-02 10:20:30,2011-02-03 10:20:30)\"}").must_equal [@R.new(Time.local(2011, 1, 2, 10, 20, 30),Time.local(2011, 2, 3, 10, 20, 30), :exclude_begin=>false, :exclude_end=>true, :db_type=>'tstzrange')]
|
|
60
|
+
cp[3913].call("{\"[2011-01-02,2011-02-03)\"}").must_equal [@R.new(Date.new(2011, 1, 2),Date.new(2011, 2, 3), :exclude_begin=>false, :exclude_end=>true, :db_type=>'daterange')]
|
|
61
|
+
cp[3927].call("{\"[1,2]\"}").must_equal [@R.new(1,2, :exclude_begin=>false, :exclude_end=>false, :db_type=>'int8range')]
|
|
62
|
+
end
|
|
63
|
+
|
|
24
64
|
it "should literalize Range instances to strings correctly" do
|
|
25
65
|
@db.literal(Date.new(2011, 1, 2)...Date.new(2011, 3, 2)).must_equal "'[2011-01-02,2011-03-02)'"
|
|
26
66
|
@db.literal(Time.local(2011, 1, 2, 10, 20, 30)...Time.local(2011, 2, 3, 10, 20, 30)).must_equal "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
|
|
@@ -131,43 +171,87 @@ describe "pg_range extension" do
|
|
|
131
171
|
end
|
|
132
172
|
end
|
|
133
173
|
|
|
134
|
-
|
|
174
|
+
deprecated "should support registering custom range types" do
|
|
135
175
|
@R.register('foorange')
|
|
136
176
|
@db.typecast_value(:foorange, 1..2).must_be_kind_of(@R)
|
|
137
177
|
@db.fetch = [{:name=>'id', :db_type=>'foorange'}]
|
|
138
178
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:foorange]
|
|
139
179
|
end
|
|
140
180
|
|
|
141
|
-
|
|
181
|
+
deprecated "should support using a block as a custom conversion proc given as block" do
|
|
142
182
|
@R.register('foo2range'){|s| (s*2).to_i}
|
|
143
183
|
@db.typecast_value(:foo2range, '[1,2]').must_be :==, (11..22)
|
|
144
184
|
end
|
|
145
185
|
|
|
146
|
-
|
|
186
|
+
deprecated "should support using a block as a custom conversion proc given as :converter option" do
|
|
147
187
|
@R.register('foo3range', :converter=>proc{|s| (s*2).to_i})
|
|
148
188
|
@db.typecast_value(:foo3range, '[1,2]').must_be :==, (11..22)
|
|
149
189
|
end
|
|
150
190
|
|
|
151
|
-
|
|
191
|
+
deprecated "should support using an existing scaler conversion proc via the :subtype_oid option" do
|
|
152
192
|
@R.register('foo4range', :subtype_oid=>16)
|
|
153
193
|
@db.typecast_value(:foo4range, '[t,f]').must_equal @R.new(true, false, :db_type=>'foo4range')
|
|
154
194
|
end
|
|
155
195
|
|
|
156
|
-
|
|
196
|
+
deprecated "should raise an error if using :subtype_oid option with unexisting scalar conversion proc" do
|
|
157
197
|
proc{@R.register('fooirange', :subtype_oid=>0)}.must_raise(Sequel::Error)
|
|
158
198
|
end
|
|
159
199
|
|
|
160
|
-
|
|
200
|
+
deprecated "should raise an error if using :converter option and a block argument" do
|
|
161
201
|
proc{@R.register('fooirange', :converter=>proc{}){}}.must_raise(Sequel::Error)
|
|
162
202
|
end
|
|
163
203
|
|
|
164
|
-
|
|
204
|
+
deprecated "should raise an error if using :subtype_oid option and a block argument" do
|
|
165
205
|
proc{@R.register('fooirange', :subtype_oid=>16){}}.must_raise(Sequel::Error)
|
|
166
206
|
end
|
|
167
207
|
|
|
168
|
-
|
|
208
|
+
deprecated "should support registering custom types with :oid option" do
|
|
169
209
|
@R.register('foo5range', :oid=>331)
|
|
170
|
-
Sequel::Postgres::
|
|
210
|
+
Sequel::Postgres::PG__TYPES[331].call('[1,3)').must_be_kind_of(@R)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
deprecated "should not support registering custom range types on a per-Database basis for frozen databases" do
|
|
214
|
+
@db.freeze
|
|
215
|
+
proc{@db.register_range_type('banana', :oid=>7865){|s| s}}.must_raise RuntimeError, TypeError
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "should support registering custom range types" do
|
|
219
|
+
@db.register_range_type('foorange')
|
|
220
|
+
@db.typecast_value(:foorange, 1..2).must_be_kind_of(@R)
|
|
221
|
+
@db.fetch = [{:name=>'id', :db_type=>'foorange'}]
|
|
222
|
+
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:foorange]
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it "should support using a block as a custom conversion proc given as block" do
|
|
226
|
+
@db.register_range_type('foo2range'){|s| (s*2).to_i}
|
|
227
|
+
@db.typecast_value(:foo2range, '[1,2]').must_be :==, (11..22)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "should support using a block as a custom conversion proc given as :converter option" do
|
|
231
|
+
@db.register_range_type('foo3range', :converter=>proc{|s| (s*2).to_i})
|
|
232
|
+
@db.typecast_value(:foo3range, '[1,2]').must_be :==, (11..22)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it "should support using an existing scaler conversion proc via the :subtype_oid option" do
|
|
236
|
+
@db.register_range_type('foo4range', :subtype_oid=>16)
|
|
237
|
+
@db.typecast_value(:foo4range, '[t,f]').must_equal @R.new(true, false, :db_type=>'foo4range')
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "should raise an error if using :subtype_oid option with unexisting scalar conversion proc" do
|
|
241
|
+
proc{@db.register_range_type('fooirange', :subtype_oid=>0)}.must_raise(Sequel::Error)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it "should raise an error if using :converter option and a block argument" do
|
|
245
|
+
proc{@db.register_range_type('fooirange', :converter=>proc{}){}}.must_raise(Sequel::Error)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should raise an error if using :subtype_oid option and a block argument" do
|
|
249
|
+
proc{@db.register_range_type('fooirange', :subtype_oid=>16){}}.must_raise(Sequel::Error)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should support registering custom types with :oid option" do
|
|
253
|
+
@db.register_range_type('foo5range', :oid=>331)
|
|
254
|
+
@db.conversion_procs[331].call('[1,3)').must_be_kind_of(@R)
|
|
171
255
|
end
|
|
172
256
|
|
|
173
257
|
it "should not support registering custom range types on a per-Database basis for frozen databases" do
|
|
@@ -222,7 +306,7 @@ describe "pg_range extension" do
|
|
|
222
306
|
|
|
223
307
|
describe "parser" do
|
|
224
308
|
before do
|
|
225
|
-
@p =
|
|
309
|
+
@p = @R::Parser.new('int4range', proc(&:to_i))
|
|
226
310
|
@sp = @R::Parser.new(nil)
|
|
227
311
|
end
|
|
228
312
|
|
|
@@ -265,14 +349,14 @@ describe "pg_range extension" do
|
|
|
265
349
|
end
|
|
266
350
|
end
|
|
267
351
|
|
|
268
|
-
|
|
352
|
+
deprecated "should set appropriate timestamp range conversion procs when resetting conversion procs" do
|
|
269
353
|
@db.reset_conversion_procs
|
|
270
354
|
procs = @db.conversion_procs
|
|
271
355
|
procs[3908].call('[2011-10-20 11:12:13,2011-10-20 11:12:14]').must_be :==, (Time.local(2011, 10, 20, 11, 12, 13)..(Time.local(2011, 10, 20, 11, 12, 14)))
|
|
272
356
|
procs[3910].call('[2011-10-20 11:12:13,2011-10-20 11:12:14]').must_be :==, (Time.local(2011, 10, 20, 11, 12, 13)..(Time.local(2011, 10, 20, 11, 12, 14)))
|
|
273
357
|
end
|
|
274
358
|
|
|
275
|
-
|
|
359
|
+
deprecated "should set appropriate timestamp range array conversion procs when resetting conversion procs" do
|
|
276
360
|
@db.reset_conversion_procs
|
|
277
361
|
procs = @db.conversion_procs
|
|
278
362
|
procs[3909].call('{"[2011-10-20 11:12:13,2011-10-20 11:12:14]"}').must_be :==, [Time.local(2011, 10, 20, 11, 12, 13)..Time.local(2011, 10, 20, 11, 12, 14)]
|
|
@@ -9,8 +9,18 @@ describe "pg_row extension" do
|
|
|
9
9
|
@db.sqls
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
deprecated "should parse record objects as arrays" do
|
|
13
|
+
a = Sequel::Postgres::PG__TYPES[2249].call("(a,b,c)")
|
|
14
|
+
a.class.must_equal(@m::ArrayRow)
|
|
15
|
+
a.to_a.must_be_kind_of(Array)
|
|
16
|
+
a[0].must_equal 'a'
|
|
17
|
+
a.must_equal %w'a b c'
|
|
18
|
+
a.db_type.must_be_nil
|
|
19
|
+
@db.literal(a).must_equal "ROW('a', 'b', 'c')"
|
|
20
|
+
end
|
|
21
|
+
|
|
12
22
|
it "should parse record objects as arrays" do
|
|
13
|
-
a =
|
|
23
|
+
a = @db.conversion_procs[2249].call("(a,b,c)")
|
|
14
24
|
a.class.must_equal(@m::ArrayRow)
|
|
15
25
|
a.to_a.must_be_kind_of(Array)
|
|
16
26
|
a[0].must_equal 'a'
|
|
@@ -20,7 +30,7 @@ describe "pg_row extension" do
|
|
|
20
30
|
end
|
|
21
31
|
|
|
22
32
|
it "should parse arrays of record objects as arrays of arrays" do
|
|
23
|
-
as =
|
|
33
|
+
as = @db.conversion_procs[2287].call('{"(a,b,c)","(d,e,f)"}')
|
|
24
34
|
as.must_equal [%w'a b c', %w'd e f']
|
|
25
35
|
as.each do |a|
|
|
26
36
|
a.class.must_equal(@m::ArrayRow)
|
|
@@ -135,7 +145,7 @@ describe "pg_row extension" do
|
|
|
135
145
|
p.column_converters.must_equal [Array]
|
|
136
146
|
end
|
|
137
147
|
|
|
138
|
-
|
|
148
|
+
deprecated "should reload registered row types when reseting conversion procs" do
|
|
139
149
|
db = Sequel.mock(:host=>'postgres')
|
|
140
150
|
db.extend_datasets{def quote_identifiers?; false end}
|
|
141
151
|
db.extension(:pg_row)
|
|
@@ -292,7 +302,7 @@ describe "pg_row extension" do
|
|
|
292
302
|
@db.typecast_value(:pg_row_foo, 'bar'=>'1', 'baz'=>'b').must_equal(:bar=>1, :baz=>'bb')
|
|
293
303
|
end
|
|
294
304
|
|
|
295
|
-
|
|
305
|
+
deprecated "should handle conversion procs that aren't added until later" do
|
|
296
306
|
@db.conversion_procs[5] = proc{|s| s * 2}
|
|
297
307
|
@db.fetch = [[{:oid=>1, :typrelid=>2, :typarray=>3}], [{:attname=>'bar', :atttypid=>4}, {:attname=>'baz', :atttypid=>5}]]
|
|
298
308
|
c = proc{|h| [h]}
|
|
@@ -53,7 +53,7 @@ describe "prepared_statements_safe plugin" do
|
|
|
53
53
|
c = Class.new(Sequel::Model)
|
|
54
54
|
c.plugin :prepared_statements_safe
|
|
55
55
|
c1 = Class.new(c)
|
|
56
|
-
c1.
|
|
56
|
+
def c1.get_db_schema; @db_schema = {:i=>{:default=>'f(x)'}, :name=>{:ruby_default=>'foo'}, :id=>{:primary_key=>true}} end
|
|
57
57
|
c1.set_dataset(:people)
|
|
58
58
|
c1.prepared_statements_column_defaults.must_equal(:name=>'foo')
|
|
59
59
|
Class.new(c1).prepared_statements_column_defaults.must_equal(:name=>'foo')
|
|
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
|
2
2
|
|
|
3
3
|
describe "query_literals extension" do
|
|
4
4
|
before do
|
|
5
|
-
|
|
5
|
+
deprecated do
|
|
6
|
+
@ds = Sequel.mock.dataset.from(:t).extension(:query_literals)
|
|
7
|
+
end
|
|
6
8
|
end
|
|
7
9
|
|
|
8
10
|
it "should not use special support if given a block" do
|
|
@@ -75,8 +75,8 @@ end
|
|
|
75
75
|
describe "Sequel::Database dump methods" do
|
|
76
76
|
before do
|
|
77
77
|
@d = Sequel::Database.new.extension(:schema_dumper)
|
|
78
|
-
@d.
|
|
79
|
-
@d.
|
|
78
|
+
def @d.tables(o) o[:schema] ? [o[:schema]] : [:t1, :t2] end
|
|
79
|
+
def @d.schema(t, *o)
|
|
80
80
|
v = case t
|
|
81
81
|
when :t1, 't__t1', Sequel.identifier(:t__t1)
|
|
82
82
|
[[:c1, {:db_type=>'integer', :primary_key=>true, :auto_increment=>true, :allow_null=>false}],
|
|
@@ -116,12 +116,12 @@ describe "Sequel::Database dump methods" do
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
it "should dump non-Integer primary key columns with explicit :type" do
|
|
119
|
-
@d.
|
|
119
|
+
def @d.schema(*s) [[:c1, {:db_type=>'bigint', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
|
|
120
120
|
@d.dump_table_schema(:t6).must_equal "create_table(:t6) do\n primary_key :c1, :type=>:Bignum\nend"
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
it "should dump non-Integer primary key columns with explicit :type when using :same_db=>true" do
|
|
124
|
-
@d.
|
|
124
|
+
def @d.schema(*s) [[:c1, {:db_type=>'bigint', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
|
|
125
125
|
@d.dump_table_schema(:t6, :same_db=>true).must_equal "create_table(:t6) do\n primary_key :c1, :type=>:Bignum\nend"
|
|
126
126
|
end
|
|
127
127
|
|
|
@@ -130,16 +130,16 @@ describe "Sequel::Database dump methods" do
|
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
it "should handle foreign keys" do
|
|
133
|
-
@d.
|
|
134
|
-
@d.
|
|
135
|
-
@d.
|
|
133
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :allow_null=>true}]] end
|
|
134
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
135
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}] end
|
|
136
136
|
@d.dump_table_schema(:t6).must_equal "create_table(:t6) do\n foreign_key :c1, :t2, :key=>[:c2]\nend"
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
it "should handle primary keys that are also foreign keys" do
|
|
140
|
-
@d.
|
|
141
|
-
@d.
|
|
142
|
-
@d.
|
|
140
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
|
|
141
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
142
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}] end
|
|
143
143
|
s = @d.dump_table_schema(:t6)
|
|
144
144
|
s.must_match(/create_table\(:t6\) do\n primary_key :c1, /)
|
|
145
145
|
s.must_match(/:table=>:t2/)
|
|
@@ -147,9 +147,9 @@ describe "Sequel::Database dump methods" do
|
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
it "should handle foreign key options" do
|
|
150
|
-
@d.
|
|
151
|
-
@d.
|
|
152
|
-
@d.
|
|
150
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :allow_null=>true}]] end
|
|
151
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
152
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}] end
|
|
153
153
|
s = @d.dump_table_schema(:t6)
|
|
154
154
|
s.must_match(/create_table\(:t6\) do\n foreign_key :c1, :t2, /)
|
|
155
155
|
s.must_match(/:key=>\[:c2\]/)
|
|
@@ -159,9 +159,9 @@ describe "Sequel::Database dump methods" do
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
it "should handle foreign key options in the primary key" do
|
|
162
|
-
@d.
|
|
163
|
-
@d.
|
|
164
|
-
@d.
|
|
162
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
|
|
163
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
164
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}] end
|
|
165
165
|
s = @d.dump_table_schema(:t6)
|
|
166
166
|
s.must_match(/create_table\(:t6\) do\n primary_key :c1, /)
|
|
167
167
|
s.must_match(/:table=>:t2/)
|
|
@@ -172,9 +172,9 @@ describe "Sequel::Database dump methods" do
|
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
it "should omit foreign key options that are the same as defaults" do
|
|
175
|
-
@d.
|
|
176
|
-
@d.
|
|
177
|
-
@d.
|
|
175
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :allow_null=>true}]] end
|
|
176
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
177
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}] end
|
|
178
178
|
s = @d.dump_table_schema(:t6)
|
|
179
179
|
s.must_match(/create_table\(:t6\) do\n foreign_key :c1, :t2, /)
|
|
180
180
|
s.must_match(/:key=>\[:c2\]/)
|
|
@@ -184,9 +184,9 @@ describe "Sequel::Database dump methods" do
|
|
|
184
184
|
end
|
|
185
185
|
|
|
186
186
|
it "should omit foreign key options that are the same as defaults in the primary key" do
|
|
187
|
-
@d.
|
|
188
|
-
@d.
|
|
189
|
-
@d.
|
|
187
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]] end
|
|
188
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
189
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}] end
|
|
190
190
|
s = @d.dump_table_schema(:t6)
|
|
191
191
|
s.must_match(/create_table\(:t6\) do\n primary_key :c1, /)
|
|
192
192
|
s.must_match(/:table=>:t2/)
|
|
@@ -197,7 +197,7 @@ describe "Sequel::Database dump methods" do
|
|
|
197
197
|
end
|
|
198
198
|
|
|
199
199
|
it "should dump primary key columns with explicit type equal to the database type when :same_db option is passed" do
|
|
200
|
-
@d.
|
|
200
|
+
def @d.schema(*s) [[:c1, {:db_type=>'somedbspecifictype', :primary_key=>true, :allow_null=>false}]] end
|
|
201
201
|
@d.dump_table_schema(:t7, :same_db => true).must_equal "create_table(:t7) do\n column :c1, \"somedbspecifictype\", :null=>false\n \n primary_key [:c1]\nend"
|
|
202
202
|
end
|
|
203
203
|
|
|
@@ -206,15 +206,15 @@ describe "Sequel::Database dump methods" do
|
|
|
206
206
|
end
|
|
207
207
|
|
|
208
208
|
it "should use a composite foreign_key calls if there is a composite foreign key" do
|
|
209
|
-
@d.
|
|
210
|
-
@d.
|
|
211
|
-
@d.
|
|
209
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer'}], [:c2, {:db_type=>'integer'}]] end
|
|
210
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
211
|
+
def @d.foreign_key_list(*s) [{:columns=>[:c1, :c2], :table=>:t2, :key=>[:c3, :c4]}] end
|
|
212
212
|
@d.dump_table_schema(:t1).must_equal "create_table(:t1) do\n Integer :c1\n Integer :c2\n \n foreign_key [:c1, :c2], :t2, :key=>[:c3, :c4]\nend"
|
|
213
213
|
end
|
|
214
214
|
|
|
215
215
|
it "should include index information if available" do
|
|
216
|
-
@d.
|
|
217
|
-
@d.
|
|
216
|
+
def @d.supports_index_parsing?; true end
|
|
217
|
+
def @d.indexes(t)
|
|
218
218
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
219
219
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
|
|
220
220
|
end
|
|
@@ -255,7 +255,7 @@ END_MIG
|
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
it "should sort table names when dumping a migration" do
|
|
258
|
-
@d.
|
|
258
|
+
def @d.tables(o) [:t2, :t1] end
|
|
259
259
|
@d.dump_schema_migration.must_equal <<-END_MIG
|
|
260
260
|
Sequel.migration do
|
|
261
261
|
change do
|
|
@@ -276,12 +276,12 @@ END_MIG
|
|
|
276
276
|
end
|
|
277
277
|
|
|
278
278
|
it "should sort table names topologically when dumping a migration with foreign keys" do
|
|
279
|
-
@d.
|
|
280
|
-
@d.
|
|
279
|
+
def @d.tables(o) [:t1, :t2] end
|
|
280
|
+
def @d.schema(t, *o)
|
|
281
281
|
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true, :auto_increment=>true}]]
|
|
282
282
|
end
|
|
283
|
-
@d.
|
|
284
|
-
@d.
|
|
283
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
284
|
+
def @d.foreign_key_list(t)
|
|
285
285
|
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
286
286
|
end
|
|
287
287
|
@d.dump_schema_migration.must_equal <<-END_MIG
|
|
@@ -300,12 +300,12 @@ END_MIG
|
|
|
300
300
|
end
|
|
301
301
|
|
|
302
302
|
it "should handle circular dependencies when dumping a migration with foreign keys" do
|
|
303
|
-
@d.
|
|
304
|
-
@d.
|
|
303
|
+
def @d.tables(o) [:t1, :t2] end
|
|
304
|
+
def @d.schema(t, *o)
|
|
305
305
|
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
|
|
306
306
|
end
|
|
307
|
-
@d.
|
|
308
|
-
@d.
|
|
307
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
308
|
+
def @d.foreign_key_list(t)
|
|
309
309
|
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : [{:columns=>[:c1], :table=>:t1, :key=>[:c2]}]
|
|
310
310
|
end
|
|
311
311
|
@d.dump_schema_migration.must_equal <<-END_MIG
|
|
@@ -328,12 +328,12 @@ END_MIG
|
|
|
328
328
|
end
|
|
329
329
|
|
|
330
330
|
it "should sort topologically even if the database raises an error when trying to parse foreign keys for a non-existent table" do
|
|
331
|
-
@d.
|
|
332
|
-
@d.
|
|
331
|
+
def @d.tables(o) [:t1, :t2] end
|
|
332
|
+
def @d.schema(t, *o)
|
|
333
333
|
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true, :auto_increment=>true}]]
|
|
334
334
|
end
|
|
335
|
-
@d.
|
|
336
|
-
@d.
|
|
335
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
336
|
+
def @d.foreign_key_list(t)
|
|
337
337
|
raise Sequel::DatabaseError unless [:t1, :t2].include?(t)
|
|
338
338
|
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
339
339
|
end
|
|
@@ -374,8 +374,8 @@ END_MIG
|
|
|
374
374
|
end
|
|
375
375
|
|
|
376
376
|
it "should honor the :index_names => false option to not include names of indexes" do
|
|
377
|
-
@d.
|
|
378
|
-
@d.
|
|
377
|
+
def @d.supports_index_parsing?; true end
|
|
378
|
+
def @d.indexes(t)
|
|
379
379
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
380
380
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
|
|
381
381
|
end
|
|
@@ -406,8 +406,8 @@ END_MIG
|
|
|
406
406
|
end
|
|
407
407
|
|
|
408
408
|
it "should make :index_names => :namespace option a noop if there is a global index namespace" do
|
|
409
|
-
@d.
|
|
410
|
-
@d.
|
|
409
|
+
def @d.supports_index_parsing?; true end
|
|
410
|
+
def @d.indexes(t)
|
|
411
411
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
412
412
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
|
|
413
413
|
end
|
|
@@ -438,9 +438,9 @@ END_MIG
|
|
|
438
438
|
end
|
|
439
439
|
|
|
440
440
|
it "should honor the :index_names => :namespace option to include names of indexes with prepended table name if there is no global index namespace" do
|
|
441
|
-
@d.
|
|
442
|
-
@d.
|
|
443
|
-
@d.
|
|
441
|
+
def @d.global_index_namespace?; false end
|
|
442
|
+
def @d.supports_index_parsing?; true end
|
|
443
|
+
def @d.indexes(t)
|
|
444
444
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
445
445
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
|
|
446
446
|
end
|
|
@@ -471,8 +471,8 @@ END_MIG
|
|
|
471
471
|
end
|
|
472
472
|
|
|
473
473
|
it "should honor the :indexes => false option to not include indexes" do
|
|
474
|
-
@d.
|
|
475
|
-
@d.
|
|
474
|
+
def @d.supports_index_parsing?; true end
|
|
475
|
+
def @d.indexes(t)
|
|
476
476
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
477
477
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
|
|
478
478
|
end
|
|
@@ -497,24 +497,24 @@ END_MIG
|
|
|
497
497
|
end
|
|
498
498
|
|
|
499
499
|
it "should have :indexes => false option disable foreign keys as well when dumping a whole migration" do
|
|
500
|
-
@d.
|
|
500
|
+
def @d.foreign_key_list(t)
|
|
501
501
|
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
502
502
|
end
|
|
503
503
|
@d.dump_schema_migration(:indexes=>false).wont_match(/foreign_key/)
|
|
504
504
|
end
|
|
505
505
|
|
|
506
506
|
it "should have :foreign_keys option override :indexes => false disabling of foreign keys" do
|
|
507
|
-
@d.
|
|
508
|
-
@d.
|
|
507
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
508
|
+
def @d.foreign_key_list(t)
|
|
509
509
|
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
510
510
|
end
|
|
511
511
|
@d.dump_schema_migration(:indexes=>false, :foreign_keys=>true).must_match(/foreign_key/)
|
|
512
512
|
end
|
|
513
513
|
|
|
514
514
|
it "should support dumping just indexes as a migration" do
|
|
515
|
-
@d.
|
|
516
|
-
@d.
|
|
517
|
-
@d.
|
|
515
|
+
def @d.tables(o) [:t1] end
|
|
516
|
+
def @d.supports_index_parsing?; true end
|
|
517
|
+
def @d.indexes(t)
|
|
518
518
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
519
519
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
|
|
520
520
|
end
|
|
@@ -529,9 +529,9 @@ END_MIG
|
|
|
529
529
|
end
|
|
530
530
|
|
|
531
531
|
it "should honor the :index_names => false option to not include names of indexes when dumping just indexes as a migration" do
|
|
532
|
-
@d.
|
|
533
|
-
@d.
|
|
534
|
-
@d.
|
|
532
|
+
def @d.tables(o) [:t1] end
|
|
533
|
+
def @d.supports_index_parsing?; true end
|
|
534
|
+
def @d.indexes(t)
|
|
535
535
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
536
536
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
|
|
537
537
|
end
|
|
@@ -546,9 +546,9 @@ END_MIG
|
|
|
546
546
|
end
|
|
547
547
|
|
|
548
548
|
it "should honor the :index_names => :namespace option be a noop if there is a global index namespace" do
|
|
549
|
-
@d.
|
|
550
|
-
@d.
|
|
551
|
-
@d.
|
|
549
|
+
def @d.tables(o) [:t1, :t2] end
|
|
550
|
+
def @d.supports_index_parsing?; true end
|
|
551
|
+
def @d.indexes(t)
|
|
552
552
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
553
553
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
|
|
554
554
|
end
|
|
@@ -566,10 +566,10 @@ END_MIG
|
|
|
566
566
|
end
|
|
567
567
|
|
|
568
568
|
it "should honor the :index_names => :namespace option to include names of indexes with prepended table name when dumping just indexes as a migration if there is no global index namespace" do
|
|
569
|
-
@d.
|
|
570
|
-
@d.
|
|
571
|
-
@d.
|
|
572
|
-
@d.
|
|
569
|
+
def @d.global_index_namespace?; false end
|
|
570
|
+
def @d.tables(o) [:t1, :t2] end
|
|
571
|
+
def @d.supports_index_parsing?; true end
|
|
572
|
+
def @d.indexes(t)
|
|
573
573
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
574
574
|
:t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>false}}
|
|
575
575
|
end
|
|
@@ -587,7 +587,7 @@ END_MIG
|
|
|
587
587
|
end
|
|
588
588
|
|
|
589
589
|
it "should handle missing index parsing support when dumping index migration" do
|
|
590
|
-
@d.
|
|
590
|
+
def @d.tables(o) [:t1] end
|
|
591
591
|
@d.dump_indexes_migration.must_equal <<-END_MIG
|
|
592
592
|
Sequel.migration do
|
|
593
593
|
change do
|
|
@@ -598,7 +598,7 @@ END_MIG
|
|
|
598
598
|
end
|
|
599
599
|
|
|
600
600
|
it "should handle missing foreign key parsing support when dumping foreign key migration" do
|
|
601
|
-
@d.
|
|
601
|
+
def @d.tables(o) [:t1] end
|
|
602
602
|
@d.dump_foreign_key_migration.must_equal <<-END_MIG
|
|
603
603
|
Sequel.migration do
|
|
604
604
|
change do
|
|
@@ -609,12 +609,12 @@ END_MIG
|
|
|
609
609
|
end
|
|
610
610
|
|
|
611
611
|
it "should support dumping just foreign_keys as a migration" do
|
|
612
|
-
@d.
|
|
613
|
-
@d.
|
|
612
|
+
def @d.tables(o) [:t1, :t2, :t3] end
|
|
613
|
+
def @d.schema(t, *o)
|
|
614
614
|
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
|
|
615
615
|
end
|
|
616
|
-
@d.
|
|
617
|
-
@d.
|
|
616
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
617
|
+
def @d.foreign_key_list(t, *a)
|
|
618
618
|
case t
|
|
619
619
|
when :t1
|
|
620
620
|
[{:columns=>[:c2], :table=>:t2, :key=>[:c1]}]
|
|
@@ -640,12 +640,12 @@ END_MIG
|
|
|
640
640
|
end
|
|
641
641
|
|
|
642
642
|
it "should handle not null values and defaults" do
|
|
643
|
-
@d.
|
|
643
|
+
def @d.schema(*s) [[:c1, {:db_type=>'date', :default=>"'now()'", :allow_null=>true}], [:c2, {:db_type=>'datetime', :allow_null=>false}]] end
|
|
644
644
|
@d.dump_table_schema(:t3).must_equal "create_table(:t3) do\n Date :c1\n DateTime :c2, :null=>false\nend"
|
|
645
645
|
end
|
|
646
646
|
|
|
647
647
|
it "should handle converting common defaults" do
|
|
648
|
-
@d.
|
|
648
|
+
def @d.schema(t, *os)
|
|
649
649
|
s = [[:c1, {:db_type=>'boolean', :default=>"false", :type=>:boolean, :allow_null=>true}],
|
|
650
650
|
[:c2, {:db_type=>'varchar', :default=>"'blah'", :type=>:string, :allow_null=>true}],
|
|
651
651
|
[:c3, {:db_type=>'integer', :default=>"-1", :type=>:integer, :allow_null=>true}],
|
|
@@ -667,10 +667,10 @@ END_MIG
|
|
|
667
667
|
end
|
|
668
668
|
|
|
669
669
|
it "should not use a literal string as a fallback if using MySQL with the :same_db option" do
|
|
670
|
-
@d.
|
|
671
|
-
@d.
|
|
672
|
-
@d.
|
|
673
|
-
@d.
|
|
670
|
+
def @d.database_type; :mysql end
|
|
671
|
+
def @d.supports_index_parsing?; false end
|
|
672
|
+
def @d.supports_foreign_key_parsing?; false end
|
|
673
|
+
def @d.schema(t, *os)
|
|
674
674
|
s = [[:c10, {:db_type=>'foo', :default=>"'6 weeks'", :type=>nil, :allow_null=>true}]]
|
|
675
675
|
s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
|
|
676
676
|
s
|
|
@@ -683,7 +683,8 @@ END_MIG
|
|
|
683
683
|
end
|
|
684
684
|
|
|
685
685
|
it "should convert many database types to ruby types" do
|
|
686
|
-
|
|
686
|
+
def @d.schema(t, *o)
|
|
687
|
+
types = %w"mediumint smallint int integer mediumint(6) smallint(7) int(8) integer(9)
|
|
687
688
|
tinyint tinyint(2) bigint bigint(20) real float double boolean tinytext mediumtext
|
|
688
689
|
longtext text clob date datetime timestamp time char character
|
|
689
690
|
varchar varchar(255) varchar(30) bpchar string money
|
|
@@ -695,7 +696,6 @@ END_MIG
|
|
|
695
696
|
["timestamp(6) without time zone", "timestamp(6) with time zone", 'mediumint(10) unsigned', 'int(9) unsigned',
|
|
696
697
|
'int(10) unsigned', "int(12) unsigned", 'bigint unsigned', 'tinyint(3) unsigned', 'identity', 'int identity'] +
|
|
697
698
|
%w"integer(10) bit bool"
|
|
698
|
-
@d.meta_def(:schema) do |t, *o|
|
|
699
699
|
i = 0
|
|
700
700
|
types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
|
|
701
701
|
end
|
|
@@ -787,10 +787,9 @@ END_MIG
|
|
|
787
787
|
end
|
|
788
788
|
|
|
789
789
|
it "should convert mysql types to ruby types" do
|
|
790
|
-
|
|
791
|
-
@d.meta_def(:schema) do |t, *o|
|
|
790
|
+
def @d.schema(t, *o)
|
|
792
791
|
i = 0
|
|
793
|
-
|
|
792
|
+
['double(15,2)', 'double(7,1) unsigned'].map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
|
|
794
793
|
end
|
|
795
794
|
@d.dump_table_schema(:x).must_equal((<<END_MIG).chomp)
|
|
796
795
|
create_table(:x) do
|
|
@@ -803,11 +802,10 @@ END_MIG
|
|
|
803
802
|
end
|
|
804
803
|
|
|
805
804
|
it "should convert oracle special types to ruby types" do
|
|
806
|
-
@d.
|
|
807
|
-
|
|
808
|
-
@d.meta_def(:schema) do |t, *o|
|
|
805
|
+
def @d.database_type; :oracle end
|
|
806
|
+
def @d.schema(t, *o)
|
|
809
807
|
i = 0
|
|
810
|
-
|
|
808
|
+
['number not null', 'date not null', 'varchar2(4 byte) not null'].map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>false}]}
|
|
811
809
|
end
|
|
812
810
|
@d.dump_table_schema(:x).must_equal((<<END_MIG).chomp)
|
|
813
811
|
create_table(:x) do
|
|
@@ -819,24 +817,24 @@ END_MIG
|
|
|
819
817
|
end
|
|
820
818
|
|
|
821
819
|
it "should force specify :null option for MySQL timestamp columns when using :same_db" do
|
|
822
|
-
@d.
|
|
823
|
-
@d.
|
|
820
|
+
def @d.database_type; :mysql end
|
|
821
|
+
def @d.schema(*s) [[:c1, {:db_type=>'timestamp', :primary_key=>true, :allow_null=>true}]] end
|
|
824
822
|
@d.dump_table_schema(:t3, :same_db=>true).must_equal "create_table(:t3) do\n column :c1, \"timestamp\", :null=>true\n \n primary_key [:c1]\nend"
|
|
825
823
|
|
|
826
|
-
@d.
|
|
824
|
+
def @d.schema(*s) [[:c1, {:db_type=>'timestamp', :primary_key=>true, :allow_null=>false}]] end
|
|
827
825
|
@d.dump_table_schema(:t3, :same_db=>true).must_equal "create_table(:t3) do\n column :c1, \"timestamp\", :null=>false\n \n primary_key [:c1]\nend"
|
|
828
826
|
end
|
|
829
827
|
|
|
830
828
|
it "should use separate primary_key call with non autoincrementable types" do
|
|
831
|
-
@d.
|
|
829
|
+
def @d.schema(*s) [[:c1, {:db_type=>'varchar(8)', :primary_key=>true, :auto_increment=>false}]] end
|
|
832
830
|
@d.dump_table_schema(:t3).must_equal "create_table(:t3) do\n String :c1, :size=>8\n \n primary_key [:c1]\nend"
|
|
833
831
|
@d.dump_table_schema(:t3, :same_db=>true).must_equal "create_table(:t3) do\n column :c1, \"varchar(8)\"\n \n primary_key [:c1]\nend"
|
|
834
832
|
end
|
|
835
833
|
|
|
836
834
|
it "should use explicit type for non integer foreign_key types" do
|
|
837
|
-
@d.
|
|
838
|
-
@d.
|
|
839
|
-
@d.
|
|
835
|
+
def @d.schema(*s) [[:c1, {:db_type=>'date', :primary_key=>true, :auto_increment=>false}]] end
|
|
836
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
837
|
+
def @d.foreign_key_list(t, *a) [{:columns=>[:c1], :table=>:t3, :key=>[:c1]}] if t == :t4 end
|
|
840
838
|
["create_table(:t4) do\n foreign_key :c1, :t3, :type=>Date, :key=>[:c1]\n \n primary_key [:c1]\nend",
|
|
841
839
|
"create_table(:t4) do\n foreign_key :c1, :t3, :key=>[:c1], :type=>Date\n \n primary_key [:c1]\nend"].must_include(@d.dump_table_schema(:t4))
|
|
842
840
|
["create_table(:t4) do\n foreign_key :c1, :t3, :type=>\"date\", :key=>[:c1]\n \n primary_key [:c1]\nend",
|
|
@@ -844,16 +842,16 @@ END_MIG
|
|
|
844
842
|
end
|
|
845
843
|
|
|
846
844
|
it "should correctly handing autoincrementing primary keys that are also foreign keys" do
|
|
847
|
-
@d.
|
|
848
|
-
@d.
|
|
849
|
-
@d.
|
|
845
|
+
def @d.schema(*s) [[:c1, {:db_type=>'integer', :primary_key=>true, :auto_increment=>true}]] end
|
|
846
|
+
def @d.supports_foreign_key_parsing?; true end
|
|
847
|
+
def @d.foreign_key_list(t, *a) [{:columns=>[:c1], :table=>:t3, :key=>[:c1]}] if t == :t4 end
|
|
850
848
|
["create_table(:t4) do\n primary_key :c1, :table=>:t3, :key=>[:c1]\nend",
|
|
851
849
|
"create_table(:t4) do\n primary_key :c1, :key=>[:c1], :table=>:t3\nend"].must_include(@d.dump_table_schema(:t4))
|
|
852
850
|
end
|
|
853
851
|
|
|
854
852
|
it "should handle dumping on PostgreSQL using qualified tables" do
|
|
855
853
|
@d = Sequel.connect('mock://postgres').extension(:schema_dumper)
|
|
856
|
-
@d.
|
|
854
|
+
def @d.schema(*s) [[:c1, {:db_type=>'timestamp', :primary_key=>true, :allow_null=>true}]] end
|
|
857
855
|
@d.dump_table_schema(Sequel.qualify(:foo, :bar), :same_db=>true).must_equal "create_table(Sequel::SQL::QualifiedIdentifier.new(:foo, :bar)) do\n column :c1, \"timestamp\"\n \n primary_key [:c1]\nend"
|
|
858
856
|
end
|
|
859
857
|
end
|