sequel 2.11.0 → 2.12.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 +168 -0
- data/README.rdoc +77 -95
- data/Rakefile +100 -80
- data/bin/sequel +2 -1
- data/doc/advanced_associations.rdoc +23 -32
- data/doc/cheat_sheet.rdoc +23 -40
- data/doc/dataset_filtering.rdoc +6 -6
- data/doc/prepared_statements.rdoc +22 -22
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/schema.rdoc +3 -1
- data/doc/sharding.rdoc +8 -8
- data/doc/virtual_rows.rdoc +65 -0
- data/lib/sequel.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/ado.rb +3 -3
- data/lib/{sequel_core → sequel}/adapters/db2.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/dbi.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do.rb +9 -5
- data/lib/{sequel_core → sequel}/adapters/do/mysql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do/postgres.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do/sqlite.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/firebird.rb +84 -80
- data/lib/{sequel_core → sequel}/adapters/informix.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc.rb +21 -14
- data/lib/{sequel_core → sequel}/adapters/jdbc/h2.rb +14 -13
- data/lib/{sequel_core → sequel}/adapters/jdbc/mysql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/oracle.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/postgresql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/sqlite.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/mysql.rb +60 -39
- data/lib/{sequel_core → sequel}/adapters/odbc.rb +8 -4
- data/lib/{sequel_core → sequel}/adapters/openbase.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/oracle.rb +38 -7
- data/lib/{sequel_core → sequel}/adapters/postgres.rb +24 -24
- data/lib/{sequel_core → sequel}/adapters/shared/mssql.rb +5 -5
- data/lib/{sequel_core → sequel}/adapters/shared/mysql.rb +126 -71
- data/lib/{sequel_core → sequel}/adapters/shared/oracle.rb +7 -10
- data/lib/{sequel_core → sequel}/adapters/shared/postgres.rb +159 -125
- data/lib/{sequel_core → sequel}/adapters/shared/progress.rb +1 -2
- data/lib/{sequel_core → sequel}/adapters/shared/sqlite.rb +72 -67
- data/lib/{sequel_core → sequel}/adapters/sqlite.rb +11 -7
- data/lib/{sequel_core → sequel}/adapters/utils/date_format.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/utils/stored_procedures.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/utils/unsupported.rb +19 -0
- data/lib/{sequel_core → sequel}/connection_pool.rb +7 -5
- data/lib/sequel/core.rb +221 -0
- data/lib/{sequel_core → sequel}/core_sql.rb +91 -49
- data/lib/{sequel_core → sequel}/database.rb +264 -149
- data/lib/{sequel_core/schema/generator.rb → sequel/database/schema_generator.rb} +6 -2
- data/lib/{sequel_core/database/schema.rb → sequel/database/schema_methods.rb} +12 -12
- data/lib/sequel/database/schema_sql.rb +224 -0
- data/lib/{sequel_core → sequel}/dataset.rb +78 -236
- data/lib/{sequel_core → sequel}/dataset/convenience.rb +99 -61
- data/lib/{sequel_core/object_graph.rb → sequel/dataset/graph.rb} +16 -14
- data/lib/{sequel_core → sequel}/dataset/prepared_statements.rb +1 -1
- data/lib/{sequel_core → sequel}/dataset/sql.rb +150 -99
- data/lib/sequel/deprecated.rb +593 -0
- data/lib/sequel/deprecated_migration.rb +91 -0
- data/lib/sequel/exceptions.rb +48 -0
- data/lib/sequel/extensions/blank.rb +42 -0
- data/lib/{sequel_model → sequel/extensions}/inflector.rb +8 -1
- data/lib/{sequel_core → sequel/extensions}/migration.rb +1 -1
- data/lib/{sequel_core/dataset → sequel/extensions}/pagination.rb +0 -0
- data/lib/{sequel_core → sequel/extensions}/pretty_table.rb +7 -0
- data/lib/{sequel_core/dataset → sequel/extensions}/query.rb +7 -0
- data/lib/sequel/extensions/string_date_time.rb +47 -0
- data/lib/sequel/metaprogramming.rb +43 -0
- data/lib/sequel/model.rb +110 -0
- data/lib/sequel/model/associations.rb +1300 -0
- data/lib/sequel/model/base.rb +937 -0
- data/lib/sequel/model/deprecated.rb +204 -0
- data/lib/sequel/model/deprecated_hooks.rb +103 -0
- data/lib/sequel/model/deprecated_inflector.rb +335 -0
- data/lib/sequel/model/deprecated_validations.rb +388 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/{sequel_model → sequel/model}/exceptions.rb +4 -4
- data/lib/sequel/model/inflections.rb +208 -0
- data/lib/sequel/model/plugins.rb +76 -0
- data/lib/sequel/plugins/caching.rb +122 -0
- data/lib/sequel/plugins/hook_class_methods.rb +122 -0
- data/lib/sequel/plugins/schema.rb +53 -0
- data/lib/sequel/plugins/serialization.rb +117 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
- data/lib/sequel/plugins/validation_class_methods.rb +384 -0
- data/lib/sequel/plugins/validation_helpers.rb +150 -0
- data/lib/{sequel_core → sequel}/sql.rb +125 -190
- data/lib/{sequel_core → sequel}/version.rb +2 -1
- data/lib/sequel_core.rb +1 -172
- data/lib/sequel_model.rb +1 -91
- data/spec/adapters/firebird_spec.rb +5 -5
- data/spec/adapters/informix_spec.rb +1 -1
- data/spec/adapters/mysql_spec.rb +128 -42
- data/spec/adapters/oracle_spec.rb +47 -19
- data/spec/adapters/postgres_spec.rb +64 -52
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +12 -17
- data/spec/{sequel_core → core}/connection_pool_spec.rb +10 -10
- data/spec/{sequel_core → core}/core_ext_spec.rb +19 -19
- data/spec/{sequel_core → core}/core_sql_spec.rb +68 -71
- data/spec/{sequel_core → core}/database_spec.rb +135 -99
- data/spec/{sequel_core → core}/dataset_spec.rb +398 -242
- data/spec/{sequel_core → core}/expression_filters_spec.rb +13 -13
- data/spec/core/migration_spec.rb +263 -0
- data/spec/{sequel_core → core}/object_graph_spec.rb +10 -10
- data/spec/{sequel_core → core}/pretty_table_spec.rb +2 -2
- data/spec/{sequel_core → core}/schema_generator_spec.rb +0 -0
- data/spec/{sequel_core → core}/schema_spec.rb +8 -10
- data/spec/{sequel_core → core}/spec_helper.rb +29 -2
- data/spec/{sequel_core → core}/version_spec.rb +0 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/caching_spec.rb +201 -0
- data/spec/{sequel_model/hooks_spec.rb → extensions/hook_class_methods_spec.rb} +8 -23
- data/spec/{sequel_model → extensions}/inflector_spec.rb +3 -0
- data/spec/{sequel_core → extensions}/migration_spec.rb +4 -4
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/{sequel_model → extensions}/schema_spec.rb +22 -1
- data/spec/extensions/serialization_spec.rb +109 -0
- data/spec/extensions/single_table_inheritance_spec.rb +53 -0
- data/spec/{sequel_model → extensions}/spec_helper.rb +13 -4
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/{sequel_model/validations_spec.rb → extensions/validation_class_methods_spec.rb} +15 -103
- data/spec/extensions/validation_helpers_spec.rb +291 -0
- data/spec/integration/dataset_test.rb +31 -0
- data/spec/integration/eager_loader_test.rb +17 -30
- data/spec/integration/schema_test.rb +8 -5
- data/spec/integration/spec_helper.rb +17 -0
- data/spec/integration/transaction_test.rb +68 -0
- data/spec/{sequel_model → model}/association_reflection_spec.rb +0 -0
- data/spec/{sequel_model → model}/associations_spec.rb +23 -10
- data/spec/{sequel_model → model}/base_spec.rb +29 -20
- data/spec/{sequel_model → model}/caching_spec.rb +16 -14
- data/spec/{sequel_model → model}/dataset_methods_spec.rb +0 -0
- data/spec/{sequel_model → model}/eager_loading_spec.rb +8 -8
- data/spec/model/hooks_spec.rb +472 -0
- data/spec/model/inflector_spec.rb +126 -0
- data/spec/{sequel_model → model}/model_spec.rb +25 -20
- data/spec/model/plugins_spec.rb +142 -0
- data/spec/{sequel_model → model}/record_spec.rb +121 -62
- data/spec/model/schema_spec.rb +92 -0
- data/spec/model/spec_helper.rb +124 -0
- data/spec/model/validations_spec.rb +1080 -0
- metadata +136 -107
- data/lib/sequel_core/core_ext.rb +0 -217
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -44
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/sql.rb +0 -325
- data/lib/sequel_model/association_reflection.rb +0 -267
- data/lib/sequel_model/associations.rb +0 -499
- data/lib/sequel_model/base.rb +0 -539
- data/lib/sequel_model/caching.rb +0 -82
- data/lib/sequel_model/dataset_methods.rb +0 -26
- data/lib/sequel_model/eager_loading.rb +0 -370
- data/lib/sequel_model/hooks.rb +0 -101
- data/lib/sequel_model/plugins.rb +0 -62
- data/lib/sequel_model/record.rb +0 -568
- data/lib/sequel_model/schema.rb +0 -49
- data/lib/sequel_model/validations.rb +0 -429
- data/spec/sequel_model/plugins_spec.rb +0 -80
|
@@ -10,7 +10,7 @@ end
|
|
|
10
10
|
ORACLE_DB.create_table :items do
|
|
11
11
|
varchar2 :name, :size => 50
|
|
12
12
|
number :value, :size => 38
|
|
13
|
-
|
|
13
|
+
date :date_created
|
|
14
14
|
index :value
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -38,10 +38,30 @@ context "An Oracle database" do
|
|
|
38
38
|
ORACLE_DB.disconnect
|
|
39
39
|
ORACLE_DB.pool.size.should == 0
|
|
40
40
|
end
|
|
41
|
+
|
|
42
|
+
specify "should provide schema information" do
|
|
43
|
+
books_schema = [
|
|
44
|
+
[:id, {:char_size=>0, :type=>:number, :allow_null=>true, :type_string=>"NUMBER(38)", :data_size=>22, :precision=>38, :char_used=>false, :scale=>0, :charset_form=>nil, :fsprecision=>38, :lfprecision=>0, :db_type=>"NUMBER(38)"}],
|
|
45
|
+
[:title, {:char_size=>50, :type=>:varchar2, :allow_null=>true, :type_string=>"VARCHAR2(50)", :data_size=>50, :precision=>0, :char_used=>false, :scale=>0, :charset_form=>:implicit, :fsprecision=>0, :lfprecision=>0, :db_type=>"VARCHAR2(50)"}],
|
|
46
|
+
[:category_id, {:char_size=>0, :type=>:number, :allow_null=>true, :type_string=>"NUMBER(38)", :data_size=>22, :precision=>38, :char_used=>false, :scale=>0, :charset_form=>nil, :fsprecision=>38, :lfprecision=>0, :db_type=>"NUMBER(38)"}]]
|
|
47
|
+
categories_schema = [
|
|
48
|
+
[:id, {:char_size=>0, :type=>:number, :allow_null=>true, :type_string=>"NUMBER(38)", :data_size=>22, :precision=>38, :char_used=>false, :scale=>0, :charset_form=>nil, :fsprecision=>38, :lfprecision=>0, :db_type=>"NUMBER(38)"}],
|
|
49
|
+
[:cat_name, {:char_size=>50, :type=>:varchar2, :allow_null=>true, :type_string=>"VARCHAR2(50)", :data_size=>50, :precision=>0, :char_used=>false, :scale=>0, :charset_form=>:implicit, :fsprecision=>0, :lfprecision=>0, :db_type=>"VARCHAR2(50)"}]]
|
|
50
|
+
items_schema = [
|
|
51
|
+
[:name, {:char_size=>50, :type=>:varchar2, :allow_null=>true, :type_string=>"VARCHAR2(50)", :data_size=>50, :precision=>0, :char_used=>false, :scale=>0, :charset_form=>:implicit, :fsprecision=>0, :lfprecision=>0, :db_type=>"VARCHAR2(50)"}],
|
|
52
|
+
[:value, {:char_size=>0, :type=>:number, :allow_null=>true, :type_string=>"NUMBER(38)", :data_size=>22, :precision=>38, :char_used=>false, :scale=>0, :charset_form=>nil, :fsprecision=>38, :lfprecision=>0, :db_type=>"NUMBER(38)"}],
|
|
53
|
+
[:date_created, {:charset_form=>nil, :type=>:date, :type_string=>"DATE", :fsprecision=>0, :data_size=>7, :lfprecision=>0, :precision=>0, :db_type=>"DATE", :char_used=>false, :char_size=>0, :scale=>0, :allow_null=>true}]]
|
|
54
|
+
|
|
55
|
+
{:books => books_schema, :categories => categories_schema, :items => items_schema}.each_pair do |table, expected_schema|
|
|
56
|
+
schema = ORACLE_DB.schema(table)
|
|
57
|
+
schema.should_not be_nil
|
|
58
|
+
expected_schema.should == schema
|
|
59
|
+
end
|
|
60
|
+
end
|
|
41
61
|
end
|
|
42
62
|
|
|
43
63
|
context "An Oracle dataset" do
|
|
44
|
-
|
|
64
|
+
before do
|
|
45
65
|
@d = ORACLE_DB[:items]
|
|
46
66
|
@d.delete # remove all records
|
|
47
67
|
end
|
|
@@ -61,52 +81,52 @@ context "An Oracle dataset" do
|
|
|
61
81
|
@d << {:name => 'def', :value => 789}
|
|
62
82
|
|
|
63
83
|
@d.order(:value).to_a.should == [
|
|
64
|
-
{:name => 'abc', :value => 123},
|
|
65
|
-
{:name => 'abc', :value => 456},
|
|
66
|
-
{:name => 'def', :value => 789}
|
|
84
|
+
{:date_created=>nil, :name => 'abc', :value => 123},
|
|
85
|
+
{:date_created=>nil, :name => 'abc', :value => 456},
|
|
86
|
+
{:date_created=>nil, :name => 'def', :value => 789}
|
|
67
87
|
]
|
|
68
88
|
|
|
69
|
-
@d.select(:name).
|
|
89
|
+
@d.select(:name).distinct.order_by(:name).to_a.should == [
|
|
70
90
|
{:name => 'abc'},
|
|
71
91
|
{:name => 'def'}
|
|
72
92
|
]
|
|
73
93
|
|
|
74
94
|
@d.order(:value.desc).limit(1).to_a.should == [
|
|
75
|
-
{:name => 'def', :value => 789}
|
|
95
|
+
{:date_created=>nil, :name => 'def', :value => 789}
|
|
76
96
|
]
|
|
77
97
|
|
|
78
98
|
@d.filter(:name => 'abc').to_a.should == [
|
|
79
|
-
{:name => 'abc', :value => 123},
|
|
80
|
-
{:name => 'abc', :value => 456}
|
|
99
|
+
{:date_created=>nil, :name => 'abc', :value => 123},
|
|
100
|
+
{:date_created=>nil, :name => 'abc', :value => 456}
|
|
81
101
|
]
|
|
82
102
|
|
|
83
103
|
@d.order(:value.desc).filter(:name => 'abc').to_a.should == [
|
|
84
|
-
{:name => 'abc', :value => 456},
|
|
85
|
-
{:name => 'abc', :value => 123}
|
|
104
|
+
{:date_created=>nil, :name => 'abc', :value => 456},
|
|
105
|
+
{:date_created=>nil, :name => 'abc', :value => 123}
|
|
86
106
|
]
|
|
87
107
|
|
|
88
108
|
@d.filter(:name => 'abc').limit(1).to_a.should == [
|
|
89
|
-
{:name => 'abc', :value => 123}
|
|
109
|
+
{:date_created=>nil, :name => 'abc', :value => 123}
|
|
90
110
|
]
|
|
91
111
|
|
|
92
112
|
@d.filter(:name => 'abc').order(:value.desc).limit(1).to_a.should == [
|
|
93
|
-
{:name => 'abc', :value => 456}
|
|
113
|
+
{:date_created=>nil, :name => 'abc', :value => 456}
|
|
94
114
|
]
|
|
95
115
|
|
|
96
116
|
@d.filter(:name => 'abc').order(:value).limit(1).to_a.should == [
|
|
97
|
-
{:name => 'abc', :value => 123}
|
|
117
|
+
{:date_created=>nil, :name => 'abc', :value => 123}
|
|
98
118
|
]
|
|
99
119
|
|
|
100
120
|
@d.order(:value).limit(1).to_a.should == [
|
|
101
|
-
{:name => 'abc', :value => 123}
|
|
121
|
+
{:date_created=>nil, :name => 'abc', :value => 123}
|
|
102
122
|
]
|
|
103
123
|
|
|
104
124
|
@d.order(:value).limit(1, 1).to_a.should == [
|
|
105
|
-
{:name => 'abc', :value => 456}
|
|
125
|
+
{:date_created=>nil, :name => 'abc', :value => 456}
|
|
106
126
|
]
|
|
107
127
|
|
|
108
128
|
@d.order(:value).limit(1, 2).to_a.should == [
|
|
109
|
-
{:name => 'def', :value => 789}
|
|
129
|
+
{:date_created=>nil, :name => 'def', :value => 789}
|
|
110
130
|
]
|
|
111
131
|
|
|
112
132
|
@d.avg(:value).to_i.should == (789+123+456)/3
|
|
@@ -155,6 +175,14 @@ context "An Oracle dataset" do
|
|
|
155
175
|
@d[:name => 'def'][:value].should == 789
|
|
156
176
|
@d.filter(:value => 530).count.should == 2
|
|
157
177
|
end
|
|
178
|
+
|
|
179
|
+
specify "should translate values correctly" do
|
|
180
|
+
@d << {:name => 'abc', :value => 456}
|
|
181
|
+
@d << {:name => 'def', :value => 789}
|
|
182
|
+
@d.filter(:value > 500).update(:date_created => "to_timestamp('2009-09-09', 'YYYY-MM-DD')".lit)
|
|
183
|
+
|
|
184
|
+
@d[:name => 'def'][:date_created].should == Time.parse('2009-09-09')
|
|
185
|
+
end
|
|
158
186
|
|
|
159
187
|
specify "should delete records correctly" do
|
|
160
188
|
@d << {:name => 'abc', :value => 123}
|
|
@@ -181,7 +209,7 @@ context "An Oracle dataset" do
|
|
|
181
209
|
end
|
|
182
210
|
|
|
183
211
|
context "Joined Oracle dataset" do
|
|
184
|
-
|
|
212
|
+
before do
|
|
185
213
|
@d1 = ORACLE_DB[:books]
|
|
186
214
|
@d1.delete # remove all records
|
|
187
215
|
@d1 << {:id => 1, :title => 'aaa', :category_id => 100}
|
|
@@ -222,7 +250,7 @@ context "Joined Oracle dataset" do
|
|
|
222
250
|
end
|
|
223
251
|
|
|
224
252
|
context "Oracle aliasing" do
|
|
225
|
-
|
|
253
|
+
before do
|
|
226
254
|
@d1 = ORACLE_DB[:books]
|
|
227
255
|
@d1.delete # remove all records
|
|
228
256
|
@d1 << {:id => 1, :title => 'aaa', :category_id => 100}
|
|
@@ -27,7 +27,7 @@ POSTGRES_DB.create_table! :test5 do
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
context "A PostgreSQL database" do
|
|
30
|
-
|
|
30
|
+
before do
|
|
31
31
|
@db = POSTGRES_DB
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -57,14 +57,10 @@ context "A PostgreSQL database" do
|
|
|
57
57
|
[:value, {:type=>:blob, :allow_null=>true, :default=>nil, :db_type=>"bytea", :primary_key=>false}]
|
|
58
58
|
]
|
|
59
59
|
end
|
|
60
|
-
|
|
61
|
-
specify "should get the schema all database tables if no table name is used" do
|
|
62
|
-
@db.schema(:test3, :reload=>true).should == @db.schema(nil, :reload=>true)[:test3]
|
|
63
|
-
end
|
|
64
60
|
end
|
|
65
61
|
|
|
66
62
|
context "A PostgreSQL dataset" do
|
|
67
|
-
|
|
63
|
+
before do
|
|
68
64
|
@d = POSTGRES_DB[:test]
|
|
69
65
|
@d.delete # remove all records
|
|
70
66
|
end
|
|
@@ -160,6 +156,9 @@ context "A PostgreSQL dataset" do
|
|
|
160
156
|
|
|
161
157
|
@d.insert_sql(:x => :y).should =~ \
|
|
162
158
|
/\AINSERT INTO "test" \("x"\) VALUES \("y"\)( RETURNING NULL)?\z/
|
|
159
|
+
|
|
160
|
+
@d.disable_insert_returning.insert_sql(:value => 333).should =~ \
|
|
161
|
+
/\AINSERT INTO "test" \("value"\) VALUES \(333\)\z/
|
|
163
162
|
end
|
|
164
163
|
|
|
165
164
|
specify "should quote fields correctly when reversing the order if quoting identifiers" do
|
|
@@ -199,6 +198,13 @@ context "A PostgreSQL dataset" do
|
|
|
199
198
|
end
|
|
200
199
|
end.should raise_error(Interrupt)
|
|
201
200
|
|
|
201
|
+
proc do
|
|
202
|
+
POSTGRES_DB.transaction do
|
|
203
|
+
@d << {:name => 'abc', :value => 1}
|
|
204
|
+
raise Sequel::Rollback
|
|
205
|
+
end
|
|
206
|
+
end.should_not raise_error
|
|
207
|
+
|
|
202
208
|
@d.count.should == 0
|
|
203
209
|
end
|
|
204
210
|
|
|
@@ -224,29 +230,28 @@ context "A PostgreSQL dataset" do
|
|
|
224
230
|
@d.count.should == 2
|
|
225
231
|
end
|
|
226
232
|
|
|
227
|
-
specify "should support nested transactions through savepoints" do
|
|
233
|
+
specify "should support nested transactions through savepoints using the savepoint option" do
|
|
228
234
|
POSTGRES_DB.transaction do
|
|
229
235
|
@d << {:name => '1'}
|
|
230
|
-
POSTGRES_DB.transaction do
|
|
236
|
+
POSTGRES_DB.transaction(:savepoint=>true) do
|
|
231
237
|
@d << {:name => '2'}
|
|
232
238
|
POSTGRES_DB.transaction do
|
|
233
239
|
@d << {:name => '3'}
|
|
234
|
-
raise Sequel::
|
|
240
|
+
raise Sequel::Rollback
|
|
235
241
|
end
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
raise Sequel::
|
|
242
|
+
end
|
|
243
|
+
@d << {:name => '4'}
|
|
244
|
+
POSTGRES_DB.transaction do
|
|
245
|
+
@d << {:name => '6'}
|
|
246
|
+
POSTGRES_DB.transaction(:savepoint=>true) do
|
|
247
|
+
@d << {:name => '7'}
|
|
248
|
+
raise Sequel::Rollback
|
|
243
249
|
end
|
|
244
|
-
@d << {:name => '5'}
|
|
245
250
|
end
|
|
251
|
+
@d << {:name => '5'}
|
|
246
252
|
end
|
|
247
253
|
|
|
248
|
-
@d.
|
|
249
|
-
@d.order(:name).map(:name).should == %w{1 2 4 5}
|
|
254
|
+
@d.order(:name).map(:name).should == %w{1 4 5 6}
|
|
250
255
|
end
|
|
251
256
|
|
|
252
257
|
specify "should support regexps" do
|
|
@@ -265,16 +270,16 @@ context "A PostgreSQL dataset" do
|
|
|
265
270
|
end
|
|
266
271
|
|
|
267
272
|
specify "should properly escape binary data" do
|
|
268
|
-
POSTGRES_DB['SELECT ? AS a', "\1\2\3".
|
|
273
|
+
POSTGRES_DB['SELECT ? AS a', "\1\2\3".to_sequel_blob].get(:a) == "\1\2\3"
|
|
269
274
|
end
|
|
270
275
|
|
|
271
276
|
specify "should retrieve binary data as Blob object" do
|
|
272
277
|
d = POSTGRES_DB[:test4]
|
|
273
|
-
d << {:name => '123', :value => "\1\2\3".
|
|
278
|
+
d << {:name => '123', :value => "\1\2\3".to_sequel_blob}
|
|
274
279
|
retrieved_binary_value = d[:name => '123'][:value]
|
|
275
280
|
retrieved_binary_value.should be_a_kind_of(::Sequel::SQL::Blob)
|
|
276
281
|
retrieved_binary_value.should == "\1\2\3"
|
|
277
|
-
retrieved_binary_value = d[:value => "\1\2\3".
|
|
282
|
+
retrieved_binary_value = d[:value => "\1\2\3".to_sequel_blob][:value]
|
|
278
283
|
retrieved_binary_value.should be_a_kind_of(::Sequel::SQL::Blob)
|
|
279
284
|
retrieved_binary_value.should == "\1\2\3"
|
|
280
285
|
end
|
|
@@ -285,7 +290,7 @@ context "A PostgreSQL dataset" do
|
|
|
285
290
|
end
|
|
286
291
|
|
|
287
292
|
context "A PostgreSQL dataset with a timestamp field" do
|
|
288
|
-
|
|
293
|
+
before do
|
|
289
294
|
@d = POSTGRES_DB[:test3]
|
|
290
295
|
@d.delete
|
|
291
296
|
end
|
|
@@ -299,7 +304,7 @@ context "A PostgreSQL dataset with a timestamp field" do
|
|
|
299
304
|
end
|
|
300
305
|
|
|
301
306
|
context "A PostgreSQL database" do
|
|
302
|
-
|
|
307
|
+
before do
|
|
303
308
|
@db = POSTGRES_DB
|
|
304
309
|
end
|
|
305
310
|
|
|
@@ -337,7 +342,7 @@ context "A PostgreSQL database" do
|
|
|
337
342
|
end
|
|
338
343
|
|
|
339
344
|
context "A PostgreSQL database" do
|
|
340
|
-
|
|
345
|
+
before do
|
|
341
346
|
end
|
|
342
347
|
|
|
343
348
|
specify "should support fulltext indexes" do
|
|
@@ -346,7 +351,7 @@ context "A PostgreSQL database" do
|
|
|
346
351
|
text :body
|
|
347
352
|
full_text_index [:title, :body]
|
|
348
353
|
end
|
|
349
|
-
POSTGRES_DB.
|
|
354
|
+
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
|
350
355
|
"CREATE TABLE posts (title text, body text)",
|
|
351
356
|
"CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('simple', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))"
|
|
352
357
|
]
|
|
@@ -358,7 +363,7 @@ context "A PostgreSQL database" do
|
|
|
358
363
|
text :body
|
|
359
364
|
full_text_index [:title, :body], :language => 'french'
|
|
360
365
|
end
|
|
361
|
-
POSTGRES_DB.
|
|
366
|
+
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
|
362
367
|
"CREATE TABLE posts (title text, body text)",
|
|
363
368
|
"CREATE INDEX posts_title_body_index ON posts USING gin (to_tsvector('french', (COALESCE(title, '') || ' ' || COALESCE(body, ''))))"
|
|
364
369
|
]
|
|
@@ -380,7 +385,7 @@ context "A PostgreSQL database" do
|
|
|
380
385
|
geometry :geom
|
|
381
386
|
spatial_index [:geom]
|
|
382
387
|
end
|
|
383
|
-
POSTGRES_DB.
|
|
388
|
+
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
|
384
389
|
"CREATE TABLE posts (geom geometry)",
|
|
385
390
|
"CREATE INDEX posts_geom_index ON posts USING gist (geom)"
|
|
386
391
|
]
|
|
@@ -391,7 +396,7 @@ context "A PostgreSQL database" do
|
|
|
391
396
|
varchar :title, :size => 5
|
|
392
397
|
index :title, :type => 'hash'
|
|
393
398
|
end
|
|
394
|
-
POSTGRES_DB.
|
|
399
|
+
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
|
395
400
|
"CREATE TABLE posts (title varchar(5))",
|
|
396
401
|
"CREATE INDEX posts_title_index ON posts USING hash (title)"
|
|
397
402
|
]
|
|
@@ -402,7 +407,7 @@ context "A PostgreSQL database" do
|
|
|
402
407
|
varchar :title, :size => 5
|
|
403
408
|
index :title, :type => 'hash', :unique => true
|
|
404
409
|
end
|
|
405
|
-
POSTGRES_DB.
|
|
410
|
+
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
|
406
411
|
"CREATE TABLE posts (title varchar(5))",
|
|
407
412
|
"CREATE UNIQUE INDEX posts_title_index ON posts USING hash (title)"
|
|
408
413
|
]
|
|
@@ -413,7 +418,7 @@ context "A PostgreSQL database" do
|
|
|
413
418
|
varchar :title, :size => 5
|
|
414
419
|
index :title, :where => {:something => 5}
|
|
415
420
|
end
|
|
416
|
-
POSTGRES_DB.
|
|
421
|
+
POSTGRES_DB.send(:create_table_sql_list, :posts, *g.create_info).should == [
|
|
417
422
|
"CREATE TABLE posts (title varchar(5))",
|
|
418
423
|
"CREATE INDEX posts_title_index ON posts (title) WHERE (something = 5)"
|
|
419
424
|
]
|
|
@@ -424,15 +429,15 @@ context "A PostgreSQL database" do
|
|
|
424
429
|
varchar :title, :size => 5
|
|
425
430
|
index :title, :where => {:something => 5}
|
|
426
431
|
end
|
|
427
|
-
POSTGRES_DB.create_table_sql_list
|
|
432
|
+
POSTGRES_DB.send(:create_table_sql_list, Sequel::SQL::Identifier.new(:posts__test), *g.create_info).should == [
|
|
428
433
|
"CREATE TABLE posts__test (title varchar(5))",
|
|
429
434
|
"CREATE INDEX posts__test_title_index ON posts__test (title) WHERE (something = 5)"
|
|
430
435
|
]
|
|
431
436
|
end
|
|
432
437
|
end
|
|
433
438
|
|
|
434
|
-
context "Postgres::Dataset#multi_insert_sql
|
|
435
|
-
|
|
439
|
+
context "Postgres::Dataset#multi_insert_sql" do
|
|
440
|
+
before do
|
|
436
441
|
@ds = POSTGRES_DB[:test]
|
|
437
442
|
end
|
|
438
443
|
|
|
@@ -461,7 +466,7 @@ context "Postgres::Dataset#multi_insert_sql / #import" do
|
|
|
461
466
|
end
|
|
462
467
|
|
|
463
468
|
context "Postgres::Dataset#insert" do
|
|
464
|
-
|
|
469
|
+
before do
|
|
465
470
|
@ds = POSTGRES_DB[:test5]
|
|
466
471
|
@ds.delete
|
|
467
472
|
end
|
|
@@ -472,9 +477,16 @@ context "Postgres::Dataset#insert" do
|
|
|
472
477
|
@ds.insert(:value=>10)
|
|
473
478
|
end
|
|
474
479
|
|
|
480
|
+
specify "should call insert_sql if disabling insert returning" do
|
|
481
|
+
@ds.disable_insert_returning!
|
|
482
|
+
@ds.should_receive(:execute_insert).once.with('INSERT INTO test5 (value) VALUES (10)', :table=>:test5, :values=>{:value=>10})
|
|
483
|
+
@ds.insert(:value=>10)
|
|
484
|
+
end
|
|
485
|
+
|
|
475
486
|
specify "should use INSERT RETURNING if server_version >= 80200" do
|
|
476
487
|
@ds.meta_def(:server_version){80201}
|
|
477
|
-
@ds.should_receive(:
|
|
488
|
+
@ds.should_receive(:clone).once.with(:server=>:default, :sql=>'INSERT INTO test5 (value) VALUES (10) RETURNING xid').and_return(@ds)
|
|
489
|
+
@ds.should_receive(:single_value).once
|
|
478
490
|
@ds.insert(:value=>10)
|
|
479
491
|
end
|
|
480
492
|
|
|
@@ -512,12 +524,12 @@ context "Postgres::Dataset#insert" do
|
|
|
512
524
|
end
|
|
513
525
|
|
|
514
526
|
context "Postgres::Database schema qualified tables" do
|
|
515
|
-
|
|
527
|
+
before do
|
|
516
528
|
POSTGRES_DB << "CREATE SCHEMA schema_test"
|
|
517
529
|
POSTGRES_DB.instance_variable_set(:@primary_keys, {})
|
|
518
530
|
POSTGRES_DB.instance_variable_set(:@primary_key_sequences, {})
|
|
519
531
|
end
|
|
520
|
-
|
|
532
|
+
after do
|
|
521
533
|
POSTGRES_DB << "DROP SCHEMA schema_test CASCADE"
|
|
522
534
|
POSTGRES_DB.default_schema = :public
|
|
523
535
|
end
|
|
@@ -618,10 +630,10 @@ if POSTGRES_DB.server_version >= 80300
|
|
|
618
630
|
end
|
|
619
631
|
|
|
620
632
|
context "Postgres::Database functions, languages, and triggers" do
|
|
621
|
-
|
|
633
|
+
before do
|
|
622
634
|
@d = POSTGRES_DB
|
|
623
635
|
end
|
|
624
|
-
|
|
636
|
+
after do
|
|
625
637
|
@d.drop_function('tf', :if_exists=>true, :cascade=>true)
|
|
626
638
|
@d.drop_function('tf', :if_exists=>true, :cascade=>true, :args=>%w'integer integer')
|
|
627
639
|
@d.drop_language(:plpgsql, :if_exists=>true, :cascade=>true)
|
|
@@ -631,37 +643,37 @@ context "Postgres::Database functions, languages, and triggers" do
|
|
|
631
643
|
specify "#create_function and #drop_function should create and drop functions" do
|
|
632
644
|
proc{@d['SELECT tf()'].all}.should raise_error(Sequel::DatabaseError)
|
|
633
645
|
args = ['tf', 'SELECT 1', {:returns=>:integer}]
|
|
634
|
-
@d.create_function_sql
|
|
646
|
+
@d.send(:create_function_sql, *args).should =~ /\A\s*CREATE FUNCTION tf\(\)\s+RETURNS integer\s+LANGUAGE SQL\s+AS 'SELECT 1'\s*\z/
|
|
635
647
|
@d.create_function(*args)
|
|
636
648
|
rows = @d['SELECT tf()'].all.should == [{:tf=>1}]
|
|
637
|
-
@d.drop_function_sql
|
|
649
|
+
@d.send(:drop_function_sql, 'tf').should == 'DROP FUNCTION tf()'
|
|
638
650
|
@d.drop_function('tf')
|
|
639
651
|
proc{@d['SELECT tf()'].all}.should raise_error(Sequel::DatabaseError)
|
|
640
652
|
end
|
|
641
653
|
|
|
642
654
|
specify "#create_function and #drop_function should support options" do
|
|
643
655
|
args = ['tf', 'SELECT $1 + $2', {:args=>[[:integer, :a], :integer], :replace=>true, :returns=>:integer, :language=>'SQL', :behavior=>:immutable, :strict=>true, :security_definer=>true, :cost=>2, :set=>{:search_path => 'public'}}]
|
|
644
|
-
@d.create_function_sql
|
|
656
|
+
@d.send(:create_function_sql,*args).should =~ /\A\s*CREATE OR REPLACE FUNCTION tf\(a integer, integer\)\s+RETURNS integer\s+LANGUAGE SQL\s+IMMUTABLE\s+STRICT\s+SECURITY DEFINER\s+COST 2\s+SET search_path = public\s+AS 'SELECT \$1 \+ \$2'\s*\z/
|
|
645
657
|
@d.create_function(*args)
|
|
646
658
|
# Make sure replace works
|
|
647
659
|
@d.create_function(*args)
|
|
648
660
|
rows = @d['SELECT tf(1, 2)'].all.should == [{:tf=>3}]
|
|
649
661
|
args = ['tf', {:if_exists=>true, :cascade=>true, :args=>[[:integer, :a], :integer]}]
|
|
650
|
-
@d.drop_function_sql
|
|
662
|
+
@d.send(:drop_function_sql,*args).should == 'DROP FUNCTION IF EXISTS tf(a integer, integer) CASCADE'
|
|
651
663
|
@d.drop_function(*args)
|
|
652
664
|
# Make sure if exists works
|
|
653
665
|
@d.drop_function(*args)
|
|
654
666
|
end
|
|
655
667
|
|
|
656
668
|
specify "#create_language and #drop_language should create and drop languages" do
|
|
657
|
-
@d.
|
|
669
|
+
@d.send(:create_language_sql, :plpgsql).should == 'CREATE LANGUAGE plpgsql'
|
|
658
670
|
@d.create_language(:plpgsql)
|
|
659
671
|
proc{@d.create_language(:plpgsql)}.should raise_error(Sequel::DatabaseError)
|
|
660
|
-
@d.
|
|
672
|
+
@d.send(:drop_language_sql, :plpgsql).should == 'DROP LANGUAGE plpgsql'
|
|
661
673
|
@d.drop_language(:plpgsql)
|
|
662
674
|
proc{@d.drop_language(:plpgsql)}.should raise_error(Sequel::DatabaseError)
|
|
663
|
-
@d.
|
|
664
|
-
@d.
|
|
675
|
+
@d.send(:create_language_sql, :plpgsql, :trusted=>true, :handler=>:a, :validator=>:b).should == 'CREATE TRUSTED LANGUAGE plpgsql HANDLER a VALIDATOR b'
|
|
676
|
+
@d.send(:drop_language_sql, :plpgsql, :if_exists=>true, :cascade=>true).should == 'DROP LANGUAGE IF EXISTS plpgsql CASCADE'
|
|
665
677
|
# Make sure if exists works
|
|
666
678
|
@d.drop_language(:plpgsql, :if_exists=>true, :cascade=>true)
|
|
667
679
|
end
|
|
@@ -669,7 +681,7 @@ context "Postgres::Database functions, languages, and triggers" do
|
|
|
669
681
|
specify "#create_trigger and #drop_trigger should create and drop triggers" do
|
|
670
682
|
@d.create_language(:plpgsql)
|
|
671
683
|
@d.create_function(:tf, 'BEGIN IF NEW.value IS NULL THEN RAISE EXCEPTION \'Blah\'; END IF; RETURN NEW; END;', :language=>:plpgsql, :returns=>:trigger)
|
|
672
|
-
@d.
|
|
684
|
+
@d.send(:create_trigger_sql, :test, :identity, :tf, :each_row=>true).should == 'CREATE TRIGGER identity BEFORE INSERT OR UPDATE OR DELETE ON public.test FOR EACH ROW EXECUTE PROCEDURE tf()'
|
|
673
685
|
@d.create_trigger(:test, :identity, :tf, :each_row=>true)
|
|
674
686
|
@d[:test].insert(:name=>'a', :value=>1)
|
|
675
687
|
@d[:test].filter(:name=>'a').all.should == [{:name=>'a', :value=>1}]
|
|
@@ -677,10 +689,10 @@ context "Postgres::Database functions, languages, and triggers" do
|
|
|
677
689
|
@d[:test].filter(:name=>'a').all.should == [{:name=>'a', :value=>1}]
|
|
678
690
|
@d[:test].filter(:name=>'a').update(:value=>3)
|
|
679
691
|
@d[:test].filter(:name=>'a').all.should == [{:name=>'a', :value=>3}]
|
|
680
|
-
@d.
|
|
692
|
+
@d.send(:drop_trigger_sql, :test, :identity).should == 'DROP TRIGGER identity ON public.test'
|
|
681
693
|
@d.drop_trigger(:test, :identity)
|
|
682
|
-
@d.
|
|
683
|
-
@d.
|
|
694
|
+
@d.send(:create_trigger_sql, :test, :identity, :tf, :after=>true, :events=>:insert, :args=>[1, 'a']).should == 'CREATE TRIGGER identity AFTER INSERT ON public.test EXECUTE PROCEDURE tf(1, \'a\')'
|
|
695
|
+
@d.send(:drop_trigger_sql, :test, :identity, :if_exists=>true, :cascade=>true).should == 'DROP TRIGGER IF EXISTS identity ON public.test CASCADE'
|
|
684
696
|
# Make sure if exists works
|
|
685
697
|
@d.drop_trigger(:test, :identity, :if_exists=>true, :cascade=>true)
|
|
686
698
|
end
|