sequel 3.33.0 → 3.34.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.
- data/CHANGELOG +140 -0
- data/Rakefile +7 -0
- data/bin/sequel +22 -2
- data/doc/dataset_basics.rdoc +1 -1
- data/doc/mass_assignment.rdoc +3 -1
- data/doc/querying.rdoc +28 -4
- data/doc/reflection.rdoc +23 -3
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/schema_modification.rdoc +18 -2
- data/doc/virtual_rows.rdoc +49 -0
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/ibmdb.rb +9 -4
- data/lib/sequel/adapters/jdbc.rb +9 -4
- data/lib/sequel/adapters/jdbc/h2.rb +8 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -5
- data/lib/sequel/adapters/jdbc/postgresql.rb +43 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +19 -0
- data/lib/sequel/adapters/mock.rb +24 -3
- data/lib/sequel/adapters/mysql.rb +29 -50
- data/lib/sequel/adapters/mysql2.rb +13 -28
- data/lib/sequel/adapters/oracle.rb +8 -2
- data/lib/sequel/adapters/postgres.rb +115 -20
- data/lib/sequel/adapters/shared/db2.rb +1 -1
- data/lib/sequel/adapters/shared/mssql.rb +14 -3
- data/lib/sequel/adapters/shared/mysql.rb +59 -11
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +1 -1
- data/lib/sequel/adapters/shared/postgres.rb +127 -30
- data/lib/sequel/adapters/shared/sqlite.rb +55 -38
- data/lib/sequel/adapters/sqlite.rb +9 -3
- data/lib/sequel/adapters/swift.rb +2 -2
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +10 -0
- data/lib/sequel/ast_transformer.rb +4 -0
- data/lib/sequel/connection_pool.rb +8 -0
- data/lib/sequel/connection_pool/sharded_single.rb +5 -0
- data/lib/sequel/connection_pool/sharded_threaded.rb +17 -0
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +14 -0
- data/lib/sequel/core.rb +24 -3
- data/lib/sequel/database/connecting.rb +24 -14
- data/lib/sequel/database/dataset_defaults.rb +1 -0
- data/lib/sequel/database/misc.rb +16 -25
- data/lib/sequel/database/query.rb +20 -2
- data/lib/sequel/database/schema_generator.rb +2 -2
- data/lib/sequel/database/schema_methods.rb +120 -23
- data/lib/sequel/dataset/actions.rb +91 -18
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/prepared_statements.rb +6 -2
- data/lib/sequel/dataset/sql.rb +68 -51
- data/lib/sequel/extensions/_pretty_table.rb +79 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +18 -13
- data/lib/sequel/extensions/migration.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +460 -0
- data/lib/sequel/extensions/pg_array_ops.rb +220 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +174 -0
- data/lib/sequel/extensions/pg_hstore.rb +296 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
- data/lib/sequel/extensions/pretty_table.rb +5 -71
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +227 -31
- data/lib/sequel/extensions/select_remove.rb +35 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -110
- data/lib/sequel/extensions/to_dot.rb +1 -1
- data/lib/sequel/model.rb +11 -2
- data/lib/sequel/model/associations.rb +35 -7
- data/lib/sequel/model/base.rb +159 -36
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/composition.rb +1 -1
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +11 -3
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +4 -3
- data/lib/sequel/plugins/prepared_statements.rb +3 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +5 -1
- data/lib/sequel/plugins/schema.rb +7 -2
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/sql.rb +417 -7
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +12 -15
- data/spec/adapters/mysql_spec.rb +81 -23
- data/spec/adapters/postgres_spec.rb +444 -77
- data/spec/adapters/spec_helper.rb +2 -0
- data/spec/adapters/sqlite_spec.rb +8 -8
- data/spec/core/connection_pool_spec.rb +85 -0
- data/spec/core/database_spec.rb +29 -5
- data/spec/core/dataset_spec.rb +171 -3
- data/spec/core/expression_filters_spec.rb +364 -0
- data/spec/core/mock_adapter_spec.rb +17 -3
- data/spec/core/schema_spec.rb +133 -0
- data/spec/extensions/association_dependencies_spec.rb +13 -13
- data/spec/extensions/caching_spec.rb +26 -3
- data/spec/extensions/class_table_inheritance_spec.rb +2 -2
- data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +23 -94
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +5 -2
- data/spec/extensions/identity_map_spec.rb +17 -0
- data/spec/extensions/instance_filters_spec.rb +1 -1
- data/spec/extensions/lazy_attributes_spec.rb +2 -2
- data/spec/extensions/list_spec.rb +4 -4
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +6 -2
- data/spec/extensions/nested_attributes_spec.rb +20 -0
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +2 -2
- data/spec/extensions/pg_array_ops_spec.rb +105 -0
- data/spec/extensions/pg_array_spec.rb +196 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +64 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
- data/spec/extensions/pg_hstore_spec.rb +195 -0
- data/spec/extensions/pg_statement_cache_spec.rb +209 -0
- data/spec/extensions/prepared_statements_spec.rb +4 -0
- data/spec/extensions/pretty_table_spec.rb +6 -0
- data/spec/extensions/query_literals_spec.rb +168 -0
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +231 -11
- data/spec/extensions/schema_spec.rb +14 -2
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/sharding_spec.rb +6 -6
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +2 -1
- data/spec/extensions/sql_expr_spec.rb +28 -19
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/touch_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +9 -1
- data/spec/integration/associations_test.rb +6 -6
- data/spec/integration/database_test.rb +1 -1
- data/spec/integration/dataset_test.rb +89 -26
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +3 -3
- data/spec/integration/plugin_test.rb +85 -22
- data/spec/integration/prepared_statement_test.rb +28 -8
- data/spec/integration/schema_test.rb +78 -7
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/integration/timezone_test.rb +1 -1
- data/spec/integration/transaction_test.rb +4 -6
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/associations_spec.rb +94 -8
- data/spec/model/base_spec.rb +4 -4
- data/spec/model/hooks_spec.rb +2 -2
- data/spec/model/model_spec.rb +19 -7
- data/spec/model/record_spec.rb +135 -58
- data/spec/model/spec_helper.rb +1 -0
- metadata +35 -7
|
@@ -32,6 +32,10 @@ describe "prepared_statements plugin" do
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
specify "should correctly create instance if dataset supports insert_select" do
|
|
35
|
+
ds = @c.instance_dataset
|
|
36
|
+
def ds.supports_insert_select?
|
|
37
|
+
true
|
|
38
|
+
end
|
|
35
39
|
def @ds.supports_insert_select?
|
|
36
40
|
true
|
|
37
41
|
end
|
|
@@ -63,6 +63,12 @@ describe "PrettyTable" do
|
|
|
63
63
|
/\n(\|x\|y\|)|(\|y\|x\|)\n/
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
specify "should have #string return the string without printing" do
|
|
67
|
+
Sequel::PrettyTable.string(@data1).should =~ /\n(\|x\|y\|)|(\|y\|x\|)\n/
|
|
68
|
+
@output.rewind
|
|
69
|
+
@output.read.should == ''
|
|
70
|
+
end
|
|
71
|
+
|
|
66
72
|
specify "should calculate the maximum width of each column correctly" do
|
|
67
73
|
Sequel::PrettyTable.print(@data2, [:a, :b])
|
|
68
74
|
@output.rewind
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "query_literals extension" do
|
|
4
|
+
before do
|
|
5
|
+
@ds = Sequel::Dataset.new(nil).from(:t)
|
|
6
|
+
@ds.extend(Sequel::QueryLiterals)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should not use special support if given a block" do
|
|
10
|
+
@ds.select('a, b, c'){d}.sql.should == 'SELECT \'a, b, c\', d FROM t'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should have #select use literal string if given a single string" do
|
|
14
|
+
@ds.select('a, b, c').sql.should == 'SELECT a, b, c FROM t'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should have #select use placeholder literal string if given a string and additional arguments" do
|
|
18
|
+
@ds.select('a, b, ?', 1).sql.should == 'SELECT a, b, 1 FROM t'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should have #select work the standard way if initial string is a literal string already" do
|
|
22
|
+
@ds.select('a, b, ?'.lit, 1).sql.should == 'SELECT a, b, ?, 1 FROM t'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should have #select work regularly if not given a string as the first argument" do
|
|
26
|
+
@ds.select(:a, 1).sql.should == 'SELECT a, 1 FROM t'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe 'with existing selection' do
|
|
30
|
+
before do
|
|
31
|
+
@ds = @ds.select(:d)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should have #select_more use literal string if given a single string" do
|
|
35
|
+
@ds.select_more('a, b, c').sql.should == 'SELECT d, a, b, c FROM t'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should have #select_ use placeholder literal string if given a string and additional arguments" do
|
|
39
|
+
@ds.select_more('a, b, ?', 1).sql.should == 'SELECT d, a, b, 1 FROM t'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should have #select_more work the standard way if initial string is a literal string already" do
|
|
43
|
+
@ds.select_more('a, b, ?'.lit, 1).sql.should == 'SELECT d, a, b, ?, 1 FROM t'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should have #select_more work regularly if not given a string as the first argument" do
|
|
47
|
+
@ds.select_more(:a, 1).sql.should == 'SELECT d, a, 1 FROM t'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should have #select_append use literal string if given a single string" do
|
|
52
|
+
@ds.select_append('a, b, c').sql.should == 'SELECT *, a, b, c FROM t'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should have #select_append use placeholder literal string if given a string and additional arguments" do
|
|
56
|
+
@ds.select_append('a, b, ?', 1).sql.should == 'SELECT *, a, b, 1 FROM t'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should have #select_append work the standard way if initial string is a literal string already" do
|
|
60
|
+
@ds.select_append('a, b, ?'.lit, 1).sql.should == 'SELECT *, a, b, ?, 1 FROM t'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should have #select_append work regularly if not given a string as the first argument" do
|
|
64
|
+
@ds.select_append(:a, 1).sql.should == 'SELECT *, a, 1 FROM t'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should have #select_group use literal string if given a single string" do
|
|
68
|
+
@ds.select_group('a, b, c').sql.should == 'SELECT a, b, c FROM t GROUP BY a, b, c'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should have #select_group use placeholder literal string if given a string and additional arguments" do
|
|
72
|
+
@ds.select_group('a, b, ?', 1).sql.should == 'SELECT a, b, 1 FROM t GROUP BY a, b, 1'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should have #select_group work the standard way if initial string is a literal string already" do
|
|
76
|
+
@ds.select_group('a, b, ?'.lit, 1).sql.should == 'SELECT a, b, ?, 1 FROM t GROUP BY a, b, ?, 1'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should have #select_group work regularly if not given a string as the first argument" do
|
|
80
|
+
@ds.select_group(:a, 1).sql.should == 'SELECT a, 1 FROM t GROUP BY a, 1'
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should have #group use literal string if given a single string" do
|
|
84
|
+
@ds.group('a, b, c').sql.should == 'SELECT * FROM t GROUP BY a, b, c'
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should have #group use placeholder literal string if given a string and additional arguments" do
|
|
88
|
+
@ds.group('a, b, ?', 1).sql.should == 'SELECT * FROM t GROUP BY a, b, 1'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should have #select_group work the standard way if initial string is a literal string already" do
|
|
92
|
+
@ds.group('a, b, ?'.lit, 1).sql.should == 'SELECT * FROM t GROUP BY a, b, ?, 1'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should have #select_group work regularly if not given a string as the first argument" do
|
|
96
|
+
@ds.group(:a, 1).sql.should == 'SELECT * FROM t GROUP BY a, 1'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should have #group_and_count use literal string if given a single string" do
|
|
100
|
+
@ds.group_and_count('a, b, c').sql.should == 'SELECT a, b, c, count(*) AS count FROM t GROUP BY a, b, c'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should have #group_and_count use placeholder literal string if given a string and additional arguments" do
|
|
104
|
+
@ds.group_and_count('a, b, ?', 1).sql.should == 'SELECT a, b, 1, count(*) AS count FROM t GROUP BY a, b, 1'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should have #group_and_count work the standard way if initial string is a literal string already" do
|
|
108
|
+
@ds.group_and_count('a, b, ?'.lit, 1).sql.should == 'SELECT a, b, ?, 1, count(*) AS count FROM t GROUP BY a, b, ?, 1'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should have #group_and_count work regularly if not given a string as the first argument" do
|
|
112
|
+
@ds.group_and_count(:a, 1).sql.should == 'SELECT a, 1, count(*) AS count FROM t GROUP BY a, 1'
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "should have #order use literal string if given a single string" do
|
|
116
|
+
@ds.order('a, b, c').sql.should == 'SELECT * FROM t ORDER BY a, b, c'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should have #order use placeholder literal string if given a string and additional arguments" do
|
|
120
|
+
@ds.order('a, b, ?', 1).sql.should == 'SELECT * FROM t ORDER BY a, b, 1'
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should have #order work the standard way if initial string is a literal string already" do
|
|
124
|
+
@ds.order('a, b, ?'.lit, 1).sql.should == 'SELECT * FROM t ORDER BY a, b, ?, 1'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should have #order work regularly if not given a string as the first argument" do
|
|
128
|
+
@ds.order(:a, 1).sql.should == 'SELECT * FROM t ORDER BY a, 1'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe 'with existing order' do
|
|
132
|
+
before do
|
|
133
|
+
@ds = @ds.order(:d)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "should have #order_more use literal string if given a single string" do
|
|
137
|
+
@ds.order_more('a, b, c').sql.should == 'SELECT * FROM t ORDER BY d, a, b, c'
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "should have #order_more use placeholder literal string if given a string and additional arguments" do
|
|
141
|
+
@ds.order_more('a, b, ?', 1).sql.should == 'SELECT * FROM t ORDER BY d, a, b, 1'
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should have #order_more work the standard way if initial string is a literal string already" do
|
|
145
|
+
@ds.order_more('a, b, ?'.lit, 1).sql.should == 'SELECT * FROM t ORDER BY d, a, b, ?, 1'
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "should have #order_more work regularly if not given a string as the first argument" do
|
|
149
|
+
@ds.order_more(:a, 1).sql.should == 'SELECT * FROM t ORDER BY d, a, 1'
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should have #order_prepend use literal string if given a single string" do
|
|
153
|
+
@ds.order_prepend('a, b, c').sql.should == 'SELECT * FROM t ORDER BY a, b, c, d'
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "should have #order_append use placeholder literal string if given a string and additional arguments" do
|
|
157
|
+
@ds.order_prepend('a, b, ?', 1).sql.should == 'SELECT * FROM t ORDER BY a, b, 1, d'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "should have #order_append work the standard way if initial string is a literal string already" do
|
|
161
|
+
@ds.order_prepend('a, b, ?'.lit, 1).sql.should == 'SELECT * FROM t ORDER BY a, b, ?, 1, d'
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "should have #order_append work regularly if not given a string as the first argument" do
|
|
165
|
+
@ds.order_prepend(:a, 1).sql.should == 'SELECT * FROM t ORDER BY a, 1, d'
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
|
+
|
|
3
|
+
describe "schema_caching extension" do
|
|
4
|
+
before do
|
|
5
|
+
@db = Sequel.mock
|
|
6
|
+
@schemas = {'"table"'=>[[:column, {:db_type=>"integer", :default=>"nextval('table_id_seq'::regclass)", :allow_null=>false, :primary_key=>true, :type=>:integer, :ruby_default=>nil}]]}
|
|
7
|
+
@filename = "spec/files/test_schema_#$$.dump"
|
|
8
|
+
@db.instance_variable_set(:@schemas, @schemas)
|
|
9
|
+
end
|
|
10
|
+
after do
|
|
11
|
+
File.delete(@filename) if File.exist?(@filename)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "Database#dump_schema_cache should dump cached schema to the given file" do
|
|
15
|
+
File.exist?(@filename).should be_false
|
|
16
|
+
@db.dump_schema_cache(@filename)
|
|
17
|
+
File.exist?(@filename).should be_true
|
|
18
|
+
File.size(@filename).should > 0
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "Database#load_schema_cache should load cached schema from the given file dumped by #dump_schema_cache" do
|
|
22
|
+
@db.dump_schema_cache(@filename)
|
|
23
|
+
db = Sequel::Database.new
|
|
24
|
+
db.load_schema_cache(@filename)
|
|
25
|
+
@db.instance_variable_get(:@schemas).should == @schemas
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "Database#dump_schema_cache? should dump cached schema to the given file unless the file exists" do
|
|
29
|
+
File.open(@filename, 'wb'){|f|}
|
|
30
|
+
File.size(@filename).should == 0
|
|
31
|
+
@db.dump_schema_cache?(@filename)
|
|
32
|
+
File.size(@filename).should == 0
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "Database#load_schema_cache? should load cached schema from the given file if it exists" do
|
|
36
|
+
db = Sequel::Database.new
|
|
37
|
+
File.exist?(@filename).should be_false
|
|
38
|
+
db.load_schema_cache?(@filename)
|
|
39
|
+
db.instance_variable_get(:@schemas).should == {}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -73,15 +73,8 @@ describe "Sequel::Database dump methods" do
|
|
|
73
73
|
when :t2
|
|
74
74
|
[[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>false}],
|
|
75
75
|
[:c2, {:db_type=>'numeric', :primary_key=>true, :allow_null=>false}]]
|
|
76
|
-
when :t3
|
|
77
|
-
[[:c1, {:db_type=>'date', :default=>"'now()'", :allow_null=>true}],
|
|
78
|
-
[:c2, {:db_type=>'datetime', :allow_null=>false}]]
|
|
79
76
|
when :t5
|
|
80
77
|
[[:c1, {:db_type=>'blahblah', :allow_null=>true}]]
|
|
81
|
-
when :t6
|
|
82
|
-
[[:c1, {:db_type=>'bigint', :primary_key=>true, :allow_null=>true}]]
|
|
83
|
-
when :t7
|
|
84
|
-
[[:c1, {:db_type=>'somedbspecifictype', :primary_key=>true, :allow_null=>false}]]
|
|
85
78
|
end
|
|
86
79
|
end
|
|
87
80
|
end
|
|
@@ -99,10 +92,73 @@ describe "Sequel::Database dump methods" do
|
|
|
99
92
|
end
|
|
100
93
|
|
|
101
94
|
it "should dump non-Integer primary key columns with explicit :type" do
|
|
95
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'bigint', :primary_key=>true, :allow_null=>true}]]}
|
|
102
96
|
@d.dump_table_schema(:t6).should == "create_table(:t6) do\n primary_key :c1, :type=>Bignum\nend"
|
|
103
97
|
end
|
|
104
98
|
|
|
99
|
+
it "should handle foreign keys" do
|
|
100
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
|
|
101
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}]}
|
|
102
|
+
@d.dump_table_schema(:t6).should == "create_table(:t6) do\n foreign_key :c1, :t2, :key=>[:c2]\nend"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should handle primary keys that are also foreign keys" do
|
|
106
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
|
|
107
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2]}]}
|
|
108
|
+
s = @d.dump_table_schema(:t6)
|
|
109
|
+
s.should =~ /create_table\(:t6\) do\n primary_key :c1, /
|
|
110
|
+
s.should =~ /:table=>:t2/
|
|
111
|
+
s.should =~ /:key=>\[:c2\]/
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should handle foreign key options" do
|
|
115
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
|
|
116
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}]}
|
|
117
|
+
s = @d.dump_table_schema(:t6)
|
|
118
|
+
s.should =~ /create_table\(:t6\) do\n foreign_key :c1, :t2, /
|
|
119
|
+
s.should =~ /:key=>\[:c2\]/
|
|
120
|
+
s.should =~ /:on_delete=>:restrict/
|
|
121
|
+
s.should =~ /:on_update=>:set_null/
|
|
122
|
+
s.should =~ /:deferrable=>true/
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should handle foreign key options in the primary key" do
|
|
126
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
|
|
127
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:restrict, :on_update=>:set_null, :deferrable=>true}]}
|
|
128
|
+
s = @d.dump_table_schema(:t6)
|
|
129
|
+
s.should =~ /create_table\(:t6\) do\n primary_key :c1, /
|
|
130
|
+
s.should =~ /:table=>:t2/
|
|
131
|
+
s.should =~ /:key=>\[:c2\]/
|
|
132
|
+
s.should =~ /:on_delete=>:restrict/
|
|
133
|
+
s.should =~ /:on_update=>:set_null/
|
|
134
|
+
s.should =~ /:deferrable=>true/
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should omit foreign key options that are the same as defaults" do
|
|
138
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :allow_null=>true}]]}
|
|
139
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}]}
|
|
140
|
+
s = @d.dump_table_schema(:t6)
|
|
141
|
+
s.should =~ /create_table\(:t6\) do\n foreign_key :c1, :t2, /
|
|
142
|
+
s.should =~ /:key=>\[:c2\]/
|
|
143
|
+
s.should_not =~ /:on_delete/
|
|
144
|
+
s.should_not =~ /:on_update/
|
|
145
|
+
s.should_not =~ /:deferrable/
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "should omit foreign key options that are the same as defaults in the primary key" do
|
|
149
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>true}]]}
|
|
150
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1], :table=>:t2, :key=>[:c2], :on_delete=>:no_action, :on_update=>:no_action, :deferrable=>false}]}
|
|
151
|
+
s = @d.dump_table_schema(:t6)
|
|
152
|
+
s.should =~ /create_table\(:t6\) do\n primary_key :c1, /
|
|
153
|
+
s.should =~ /:table=>:t2/
|
|
154
|
+
s.should =~ /:key=>\[:c2\]/
|
|
155
|
+
s.should_not =~ /:on_delete/
|
|
156
|
+
s.should_not =~ /:on_update/
|
|
157
|
+
s.should_not =~ /:deferrable/
|
|
158
|
+
end
|
|
159
|
+
|
|
105
160
|
it "should dump primary key columns with explicit :type equal to the database type when :same_db option is passed" do
|
|
161
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'somedbspecifictype', :primary_key=>true, :allow_null=>false}]]}
|
|
106
162
|
@d.dump_table_schema(:t7, :same_db => true).should == "create_table(:t7) do\n primary_key :c1, :type=>\"somedbspecifictype\"\nend"
|
|
107
163
|
end
|
|
108
164
|
|
|
@@ -110,6 +166,12 @@ describe "Sequel::Database dump methods" do
|
|
|
110
166
|
@d.dump_table_schema(:t2).should == "create_table(:t2) do\n Integer :c1, :null=>false\n BigDecimal :c2, :null=>false\n \n primary_key [:c1, :c2]\nend"
|
|
111
167
|
end
|
|
112
168
|
|
|
169
|
+
it "should use a composite foreign_key calls if there is a composite foreign key" do
|
|
170
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'integer'}], [:c2, {:db_type=>'integer'}]]}
|
|
171
|
+
@d.meta_def(:foreign_key_list){|*s| [{:columns=>[:c1, :c2], :table=>:t2, :key=>[:c3, :c4]}]}
|
|
172
|
+
@d.dump_table_schema(:t1).should == "create_table(:t1) do\n Integer :c1\n Integer :c2\n \n foreign_key [:c1, :c2], :t2, :key=>[:c3, :c4]\nend"
|
|
173
|
+
end
|
|
174
|
+
|
|
113
175
|
it "should include index information if available" do
|
|
114
176
|
@d.meta_def(:indexes) do |t|
|
|
115
177
|
{:i1=>{:columns=>[:c1], :unique=>false},
|
|
@@ -136,7 +198,7 @@ Sequel.migration do
|
|
|
136
198
|
end
|
|
137
199
|
|
|
138
200
|
down do
|
|
139
|
-
drop_table(:
|
|
201
|
+
drop_table(:t2, :t1)
|
|
140
202
|
end
|
|
141
203
|
end
|
|
142
204
|
END_MIG
|
|
@@ -160,6 +222,92 @@ Sequel.migration do
|
|
|
160
222
|
end
|
|
161
223
|
end
|
|
162
224
|
|
|
225
|
+
down do
|
|
226
|
+
drop_table(:t2, :t1)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
END_MIG
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it "should sort table names topologically when dumping a migration with foreign keys" do
|
|
233
|
+
@d.meta_def(:tables){|o| [:t1, :t2]}
|
|
234
|
+
@d.meta_def(:schema) do |t|
|
|
235
|
+
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true}]]
|
|
236
|
+
end
|
|
237
|
+
@d.meta_def(:foreign_key_list) do |t|
|
|
238
|
+
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
239
|
+
end
|
|
240
|
+
@d.dump_schema_migration.should == <<-END_MIG
|
|
241
|
+
Sequel.migration do
|
|
242
|
+
up do
|
|
243
|
+
create_table(:t2) do
|
|
244
|
+
primary_key :c1
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
create_table(:t1) do
|
|
248
|
+
foreign_key :c2, :t2, :key=>[:c1]
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
down do
|
|
253
|
+
drop_table(:t1, :t2)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
END_MIG
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it "should handle circular dependencies when dumping a migration with foreign keys" do
|
|
260
|
+
@d.meta_def(:tables){|o| [:t1, :t2]}
|
|
261
|
+
@d.meta_def(:schema) do |t|
|
|
262
|
+
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
|
|
263
|
+
end
|
|
264
|
+
@d.meta_def(:foreign_key_list) do |t|
|
|
265
|
+
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : [{:columns=>[:c1], :table=>:t1, :key=>[:c2]}]
|
|
266
|
+
end
|
|
267
|
+
@d.dump_schema_migration.should == <<-END_MIG
|
|
268
|
+
Sequel.migration do
|
|
269
|
+
up do
|
|
270
|
+
create_table(:t1) do
|
|
271
|
+
Integer :c2
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
create_table(:t2) do
|
|
275
|
+
foreign_key :c1, :t1, :key=>[:c2]
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
alter_table(:t1) do
|
|
279
|
+
add_foreign_key [:c2], :t2, :key=>[:c1]
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
down do
|
|
284
|
+
drop_table(:t2, :t1)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
END_MIG
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "should sort topologically even if the database raises an error when trying to parse foreign keys for a non-existent table" do
|
|
291
|
+
@d.meta_def(:tables){|o| [:t1, :t2]}
|
|
292
|
+
@d.meta_def(:schema) do |t|
|
|
293
|
+
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer', :primary_key=>true}]]
|
|
294
|
+
end
|
|
295
|
+
@d.meta_def(:foreign_key_list) do |t|
|
|
296
|
+
raise Sequel::DatabaseError unless [:t1, :t2].include?(t)
|
|
297
|
+
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
298
|
+
end
|
|
299
|
+
@d.dump_schema_migration.should == <<-END_MIG
|
|
300
|
+
Sequel.migration do
|
|
301
|
+
up do
|
|
302
|
+
create_table(:t2) do
|
|
303
|
+
primary_key :c1
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
create_table(:t1) do
|
|
307
|
+
foreign_key :c2, :t2, :key=>[:c1]
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
163
311
|
down do
|
|
164
312
|
drop_table(:t1, :t2)
|
|
165
313
|
end
|
|
@@ -186,7 +334,7 @@ Sequel.migration do
|
|
|
186
334
|
end
|
|
187
335
|
|
|
188
336
|
down do
|
|
189
|
-
drop_table(:
|
|
337
|
+
drop_table(:t2, :t1)
|
|
190
338
|
end
|
|
191
339
|
end
|
|
192
340
|
END_MIG
|
|
@@ -215,12 +363,26 @@ Sequel.migration do
|
|
|
215
363
|
end
|
|
216
364
|
|
|
217
365
|
down do
|
|
218
|
-
drop_table(:
|
|
366
|
+
drop_table(:t2, :t1)
|
|
219
367
|
end
|
|
220
368
|
end
|
|
221
369
|
END_MIG
|
|
222
370
|
end
|
|
223
371
|
|
|
372
|
+
it "should have :indexes => false option disable foreign keys as well when dumping a whole migration" do
|
|
373
|
+
@d.meta_def(:foreign_key_list) do |t|
|
|
374
|
+
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
375
|
+
end
|
|
376
|
+
@d.dump_schema_migration(:indexes=>false).should_not =~ /foreign_key/
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
it "should have :foreign_keys option override :indexes => false disabling of foreign keys" do
|
|
380
|
+
@d.meta_def(:foreign_key_list) do |t|
|
|
381
|
+
t == :t1 ? [{:columns=>[:c2], :table=>:t2, :key=>[:c1]}] : []
|
|
382
|
+
end
|
|
383
|
+
@d.dump_schema_migration(:indexes=>false, :foreign_keys=>true).should =~ /foreign_key/
|
|
384
|
+
end
|
|
385
|
+
|
|
224
386
|
it "should support dumping just indexes as a migration" do
|
|
225
387
|
@d.meta_def(:tables){|o| [:t1]}
|
|
226
388
|
@d.meta_def(:indexes) do |t|
|
|
@@ -242,7 +404,64 @@ end
|
|
|
242
404
|
END_MIG
|
|
243
405
|
end
|
|
244
406
|
|
|
407
|
+
it "should handle missing index parsing support when dumping index migration" do
|
|
408
|
+
@d.meta_def(:tables){|o| [:t1]}
|
|
409
|
+
@d.dump_indexes_migration.should == <<-END_MIG
|
|
410
|
+
Sequel.migration do
|
|
411
|
+
up do
|
|
412
|
+
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
down do
|
|
416
|
+
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
END_MIG
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
it "should handle missing foreign key parsing support when dumping foreign key migration" do
|
|
423
|
+
@d.meta_def(:tables){|o| [:t1]}
|
|
424
|
+
@d.dump_foreign_key_migration.should == <<-END_MIG
|
|
425
|
+
Sequel.migration do
|
|
426
|
+
up do
|
|
427
|
+
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
END_MIG
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
it "should support dumping just foreign_keys as a migration" do
|
|
434
|
+
@d.meta_def(:tables){|o| [:t1, :t2, :t3]}
|
|
435
|
+
@d.meta_def(:schema) do |t|
|
|
436
|
+
t == :t1 ? [[:c2, {:db_type=>'integer'}]] : [[:c1, {:db_type=>'integer'}]]
|
|
437
|
+
end
|
|
438
|
+
@d.meta_def(:foreign_key_list) do |t, *a|
|
|
439
|
+
case t
|
|
440
|
+
when :t1
|
|
441
|
+
[{:columns=>[:c2], :table=>:t2, :key=>[:c1]}]
|
|
442
|
+
when :t2
|
|
443
|
+
[{:columns=>[:c1, :c3], :table=>:t1, :key=>[:c2, :c4]}]
|
|
444
|
+
else
|
|
445
|
+
[]
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
@d.dump_foreign_key_migration.should == <<-END_MIG
|
|
449
|
+
Sequel.migration do
|
|
450
|
+
up do
|
|
451
|
+
alter_table(:t1) do
|
|
452
|
+
add_foreign_key [:c2], :t2, :key=>[:c1]
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
alter_table(:t2) do
|
|
456
|
+
add_foreign_key [:c1, :c3], :t1, :key=>[:c2, :c4]
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
END_MIG
|
|
461
|
+
end
|
|
462
|
+
|
|
245
463
|
it "should handle not null values and defaults" do
|
|
464
|
+
@d.meta_def(:schema){|*s| [[:c1, {:db_type=>'date', :default=>"'now()'", :allow_null=>true}], [:c2, {:db_type=>'datetime', :allow_null=>false}]]}
|
|
246
465
|
@d.dump_table_schema(:t3).should == "create_table(:t3) do\n Date :c1\n DateTime :c2, :null=>false\nend"
|
|
247
466
|
end
|
|
248
467
|
|
|
@@ -289,7 +508,7 @@ END_MIG
|
|
|
289
508
|
["double precision", "timestamp with time zone", "timestamp without time zone",
|
|
290
509
|
"time with time zone", "time without time zone", "character varying(20)"] +
|
|
291
510
|
%w"nvarchar ntext smalldatetime smallmoney binary varbinary nchar" +
|
|
292
|
-
["timestamp(6) without time zone", "timestamp(6) with time zone", "int(12) unsigned", 'bigint unsigned']
|
|
511
|
+
["timestamp(6) without time zone", "timestamp(6) with time zone", "int(12) unsigned", 'bigint unsigned', 'tinyint(3) unsigned']
|
|
293
512
|
@d.meta_def(:schema) do |t, *o|
|
|
294
513
|
i = 0
|
|
295
514
|
types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
|
|
@@ -361,6 +580,7 @@ create_table(:x) do
|
|
|
361
580
|
DateTime :c63, :size=>6
|
|
362
581
|
Integer :c64
|
|
363
582
|
Bignum :c65
|
|
583
|
+
Integer :c66
|
|
364
584
|
end
|
|
365
585
|
END_MIG
|
|
366
586
|
end
|