sequel 4.47.0 → 4.48.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|