sequel 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/doc/active_record.rdoc +2 -2
- data/doc/cheat_sheet.rdoc +0 -5
- data/doc/opening_databases.rdoc +3 -2
- data/doc/prepared_statements.rdoc +6 -0
- data/doc/release_notes/4.1.0.txt +85 -0
- data/doc/schema_modification.rdoc +9 -2
- data/lib/sequel/adapters/jdbc.rb +5 -0
- data/lib/sequel/adapters/mysql2.rb +24 -3
- data/lib/sequel/adapters/odbc.rb +6 -4
- data/lib/sequel/adapters/postgres.rb +25 -0
- data/lib/sequel/adapters/shared/mysql.rb +4 -29
- data/lib/sequel/adapters/shared/postgres.rb +14 -3
- data/lib/sequel/adapters/shared/sqlite.rb +4 -0
- data/lib/sequel/adapters/utils/replace.rb +36 -0
- data/lib/sequel/database/query.rb +1 -0
- data/lib/sequel/database/schema_generator.rb +12 -5
- data/lib/sequel/database/schema_methods.rb +2 -0
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/extensions/pg_json_ops.rb +0 -6
- data/lib/sequel/model/associations.rb +1 -1
- data/lib/sequel/plugins/instance_filters.rb +11 -1
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -2
- data/lib/sequel/plugins/prepared_statements.rb +38 -9
- data/lib/sequel/plugins/update_primary_key.rb +10 -0
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +1 -22
- data/spec/adapters/postgres_spec.rb +79 -2
- data/spec/core/database_spec.rb +10 -0
- data/spec/core/dataset_spec.rb +8 -3
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/schema_spec.rb +17 -2
- data/spec/extensions/caching_spec.rb +2 -2
- data/spec/extensions/hook_class_methods_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +22 -0
- data/spec/extensions/migration_spec.rb +5 -5
- data/spec/extensions/nested_attributes_spec.rb +4 -4
- data/spec/extensions/prepared_statements_spec.rb +37 -26
- data/spec/extensions/update_primary_key_spec.rb +13 -0
- data/spec/integration/dataset_test.rb +36 -0
- data/spec/model/associations_spec.rb +20 -2
- data/spec/model/hooks_spec.rb +1 -7
- metadata +5 -2
@@ -1,3 +1,5 @@
|
|
1
|
+
Sequel.require 'adapters/utils/replace'
|
2
|
+
|
1
3
|
module Sequel
|
2
4
|
module SQLite
|
3
5
|
# No matter how you connect to SQLite, the following Database options
|
@@ -473,6 +475,8 @@ module Sequel
|
|
473
475
|
|
474
476
|
# Instance methods for datasets that connect to an SQLite database
|
475
477
|
module DatasetMethods
|
478
|
+
include Dataset::Replace
|
479
|
+
|
476
480
|
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'select distinct columns from join where group having compounds order limit')
|
477
481
|
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}
|
478
482
|
EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Sequel
|
2
|
+
class Dataset
|
3
|
+
module Replace
|
4
|
+
INSERT = Dataset::INSERT
|
5
|
+
REPLACE = 'REPLACE'.freeze
|
6
|
+
|
7
|
+
# Execute a REPLACE statement on the database (deletes any duplicate
|
8
|
+
# rows before inserting).
|
9
|
+
def replace(*values)
|
10
|
+
execute_insert(replace_sql(*values))
|
11
|
+
end
|
12
|
+
|
13
|
+
# SQL statement for REPLACE
|
14
|
+
def replace_sql(*values)
|
15
|
+
clone(:replace=>true).insert_sql(*values)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Replace multiple rows in a single query.
|
19
|
+
def multi_replace(*values)
|
20
|
+
clone(:replace=>true).multi_insert(*values)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Databases using this module support REPLACE.
|
24
|
+
def supports_replace?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# If this is an replace instead of an insert, use replace instead
|
31
|
+
def insert_insert_sql(sql)
|
32
|
+
sql << (@opts[:replace] ? REPLACE : INSERT)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -116,12 +116,16 @@ module Sequel
|
|
116
116
|
end
|
117
117
|
|
118
118
|
# Adds a named constraint (or unnamed if name is nil) to the DDL,
|
119
|
-
# with the given block or args.
|
119
|
+
# with the given block or args. To provide options for the constraint, pass
|
120
|
+
# a hash as the first argument.
|
120
121
|
#
|
121
|
-
# constraint(:blah, :num=>1..5)
|
122
|
-
#
|
122
|
+
# constraint(:blah, :num=>1..5)
|
123
|
+
# # CONSTRAINT blah CHECK num >= 1 AND num <= 5
|
124
|
+
# constraint({:name=>:blah, :deferrable=>true}, :num=>1..5)
|
125
|
+
# # CONSTRAINT blah CHECK num >= 1 AND num <= 5 DEFERRABLE INITIALLY DEFERRED
|
123
126
|
def constraint(name, *args, &block)
|
124
|
-
|
127
|
+
opts = name.is_a?(Hash) ? name : {:name=>name}
|
128
|
+
constraints << opts.merge(:type=>:check, :check=>block || args)
|
125
129
|
end
|
126
130
|
|
127
131
|
# Add a foreign key in the table that references another table to the DDL. See column
|
@@ -319,8 +323,11 @@ module Sequel
|
|
319
323
|
#
|
320
324
|
# add_constraint(:valid_name, Sequel.like(:name, 'A%'))
|
321
325
|
# # ADD CONSTRAINT valid_name CHECK (name LIKE 'A%')
|
326
|
+
# add_constraint({:name=>:valid_name, :deferrable=>true}, :num=>1..5)
|
327
|
+
# # CONSTRAINT valid_name CHECK (name LIKE 'A%') DEFERRABLE INITIALLY DEFERRED
|
322
328
|
def add_constraint(name, *args, &block)
|
323
|
-
|
329
|
+
opts = name.is_a?(Hash) ? name : {:name=>name}
|
330
|
+
@operations << opts.merge(:op=>:add_constraint, :type=>:check, :check=>block || args)
|
324
331
|
end
|
325
332
|
|
326
333
|
# Add a unique constraint to the given column(s)
|
@@ -156,6 +156,8 @@ module Sequel
|
|
156
156
|
#
|
157
157
|
# PostgreSQL specific options:
|
158
158
|
# :unlogged :: Create the table as an unlogged table.
|
159
|
+
# :inherits :: Inherit from a different tables. An array can be
|
160
|
+
# specified to inherit from multiple tables.
|
159
161
|
#
|
160
162
|
# See <tt>Schema::Generator</tt> and the {"Schema Modification" guide}[link:files/doc/schema_modification_rdoc.html].
|
161
163
|
def create_table(name, options=OPTS, &block)
|
@@ -117,6 +117,11 @@ module Sequel
|
|
117
117
|
false
|
118
118
|
end
|
119
119
|
|
120
|
+
# Whether the dataset supports REPLACE syntax, false by default.
|
121
|
+
def supports_replace?
|
122
|
+
false
|
123
|
+
end
|
124
|
+
|
120
125
|
# Whether the RETURNING clause is supported for the given type of query.
|
121
126
|
# +type+ can be :insert, :update, or :delete.
|
122
127
|
def supports_returning?(type)
|
@@ -184,12 +184,6 @@ module Sequel
|
|
184
184
|
a.is_a?(Array) || (defined?(PGArray) && a.is_a?(PGArray)) || (defined?(ArrayOp) && a.is_a?(ArrayOp))
|
185
185
|
end
|
186
186
|
|
187
|
-
# Return a placeholder literal with the given str and args, wrapped
|
188
|
-
# in an SQL::StringExpression, used by operators that return text.
|
189
|
-
def text_op(str, args)
|
190
|
-
Sequel::SQL::StringExpression.new(:NOOP, Sequel::SQL::PlaceholderLiteralString.new(str, [self, args]))
|
191
|
-
end
|
192
|
-
|
193
187
|
# Automatically wrap argument in a PGArray if it is a plain Array.
|
194
188
|
# Requires that the pg_array extension has been loaded to work.
|
195
189
|
def wrap_array(arg)
|
@@ -1512,7 +1512,7 @@ module Sequel
|
|
1512
1512
|
if o.is_a?(Hash)
|
1513
1513
|
o = klass.new(o)
|
1514
1514
|
elsif o.is_a?(Integer) || o.is_a?(String) || o.is_a?(Array)
|
1515
|
-
o = klass
|
1515
|
+
o = klass.with_pk!(o)
|
1516
1516
|
elsif !o.is_a?(klass)
|
1517
1517
|
raise(Sequel::Error, "associated object #{o.inspect} not of correct type #{klass}")
|
1518
1518
|
end
|
@@ -22,7 +22,7 @@ module Sequel
|
|
22
22
|
#
|
23
23
|
# # Attempting to delete the object where the filter doesn't
|
24
24
|
# # match any rows raises an error.
|
25
|
-
# i1.delete # raises Sequel::
|
25
|
+
# i1.delete # raises Sequel::NoExistingObject
|
26
26
|
#
|
27
27
|
# # The other object that represents the same row has no
|
28
28
|
# # instance filters, and can be updated normally.
|
@@ -108,6 +108,16 @@ module Sequel
|
|
108
108
|
def _update_dataset
|
109
109
|
apply_instance_filters(super)
|
110
110
|
end
|
111
|
+
|
112
|
+
# Only use prepared statements for update and delete queries
|
113
|
+
# if there are no instance filters.
|
114
|
+
def use_prepared_statements_for?(type)
|
115
|
+
if (type == :update || type == :delete) && !instance_filters.empty?
|
116
|
+
false
|
117
|
+
else
|
118
|
+
super
|
119
|
+
end
|
120
|
+
end
|
111
121
|
end
|
112
122
|
end
|
113
123
|
end
|
@@ -21,8 +21,9 @@ module Sequel
|
|
21
21
|
# Album.add_pg_typecast_on_load_columns :aliases, :config
|
22
22
|
#
|
23
23
|
# This plugin only handles values that the adapter returns as strings. If
|
24
|
-
# the adapter returns a value other than a string
|
25
|
-
#
|
24
|
+
# the adapter returns a value other than a string, this plugin will have no
|
25
|
+
# effect. You may be able to use the regular typecast_on_load plugin to
|
26
|
+
# handle those cases.
|
26
27
|
module PgTypecastOnLoad
|
27
28
|
# Call add_pg_typecast_on_load_columns on the passed column arguments.
|
28
29
|
def self.configure(model, *columns)
|
@@ -1,4 +1,16 @@
|
|
1
1
|
module Sequel
|
2
|
+
class Model
|
3
|
+
module InstanceMethods
|
4
|
+
# Whether prepared statements should be used for the given type of query
|
5
|
+
# (:insert, :insert_select, :refresh, :update, or :delete). True by default,
|
6
|
+
# can be overridden in other plugins to disallow prepared statements for
|
7
|
+
# specific types of queries.
|
8
|
+
def use_prepared_statements_for?(type)
|
9
|
+
true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
2
14
|
module Plugins
|
3
15
|
# The prepared_statements plugin modifies the model to use prepared statements for
|
4
16
|
# instance level deletes and saves, as well as class level lookups by
|
@@ -11,9 +23,6 @@ module Sequel
|
|
11
23
|
# of prepared statements that can be created, unless you tightly control how your
|
12
24
|
# model instances are saved.
|
13
25
|
#
|
14
|
-
# This plugin does not work correctly with the instance filters plugin
|
15
|
-
# or the update_primary_key plugin.
|
16
|
-
#
|
17
26
|
# Usage:
|
18
27
|
#
|
19
28
|
# # Make all model subclasses use prepared statements (called before loading subclasses)
|
@@ -133,30 +142,50 @@ module Sequel
|
|
133
142
|
|
134
143
|
# Use a prepared statement to delete the row.
|
135
144
|
def _delete_without_checking
|
136
|
-
|
145
|
+
if use_prepared_statements_for?(:delete)
|
146
|
+
model.send(:prepared_delete).call(pk_hash)
|
147
|
+
else
|
148
|
+
super
|
149
|
+
end
|
137
150
|
end
|
138
151
|
|
139
152
|
# Use a prepared statement to insert the values into the model's dataset.
|
140
153
|
def _insert_raw(ds)
|
141
|
-
|
154
|
+
if use_prepared_statements_for?(:insert)
|
155
|
+
model.send(:prepared_insert, @values.keys).call(@values)
|
156
|
+
else
|
157
|
+
super
|
158
|
+
end
|
142
159
|
end
|
143
160
|
|
144
161
|
# Use a prepared statement to insert the values into the model's dataset
|
145
162
|
# and return the new column values.
|
146
163
|
def _insert_select_raw(ds)
|
147
|
-
if
|
148
|
-
ps.
|
164
|
+
if use_prepared_statements_for?(:insert_select)
|
165
|
+
if ps = model.send(:prepared_insert_select, @values.keys)
|
166
|
+
ps.call(@values)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
super
|
149
170
|
end
|
150
171
|
end
|
151
172
|
|
152
173
|
# Use a prepared statement to refresh this model's column values.
|
153
174
|
def _refresh_get(ds)
|
154
|
-
|
175
|
+
if use_prepared_statements_for?(:refresh)
|
176
|
+
model.send(:prepared_refresh).call(pk_hash)
|
177
|
+
else
|
178
|
+
super
|
179
|
+
end
|
155
180
|
end
|
156
181
|
|
157
182
|
# Use a prepared statement to update this model's columns in the database.
|
158
183
|
def _update_without_checking(columns)
|
159
|
-
|
184
|
+
if use_prepared_statements_for?(:update)
|
185
|
+
model.send(:prepared_update, columns.keys).call(columns.merge(pk_hash))
|
186
|
+
else
|
187
|
+
super
|
188
|
+
end
|
160
189
|
end
|
161
190
|
end
|
162
191
|
end
|
@@ -54,6 +54,16 @@ module Sequel
|
|
54
54
|
associations.delete(k) if model.association_reflection(k)[:type] != :many_to_one
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
# Do not use prepared statements for update queries, since they don't work
|
59
|
+
# in the case where the primary key has changed.
|
60
|
+
def use_prepared_statements_for?(type)
|
61
|
+
if type == :update
|
62
|
+
false
|
63
|
+
else
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
57
67
|
end
|
58
68
|
end
|
59
69
|
end
|
data/lib/sequel/sql.rb
CHANGED
@@ -1624,7 +1624,7 @@ module Sequel
|
|
1624
1624
|
fun_args = ::Kernel.Array(opts[:*] ? WILDCARD : opts[:args])
|
1625
1625
|
WindowFunction.new(Function.new(m, *fun_args), Window.new(opts))
|
1626
1626
|
else
|
1627
|
-
raise
|
1627
|
+
Kernel.raise(Error, 'unsupported VirtualRow method argument used with block')
|
1628
1628
|
end
|
1629
1629
|
end
|
1630
1630
|
elsif args.empty?
|
data/lib/sequel/version.rb
CHANGED
@@ -3,7 +3,7 @@ module Sequel
|
|
3
3
|
MAJOR = 4
|
4
4
|
# The minor version of Sequel. Bumped for every non-patch level
|
5
5
|
# release, generally around once a month.
|
6
|
-
MINOR =
|
6
|
+
MINOR = 1
|
7
7
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
8
8
|
# releases that fix regressions from previous versions.
|
9
9
|
TINY = 0
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -1070,27 +1070,6 @@ describe "MySQL::Dataset#replace" do
|
|
1070
1070
|
@d.replace({})
|
1071
1071
|
@d.all.should == [{:id=>1, :value=>2}]
|
1072
1072
|
end
|
1073
|
-
|
1074
|
-
specify "should use support arrays, datasets, and multiple values" do
|
1075
|
-
@d.replace([1, 2])
|
1076
|
-
@d.all.should == [{:id=>1, :value=>2}]
|
1077
|
-
@d.replace(1, 2)
|
1078
|
-
@d.all.should == [{:id=>1, :value=>2}]
|
1079
|
-
@d.replace(@d)
|
1080
|
-
@d.all.should == [{:id=>1, :value=>2}]
|
1081
|
-
end
|
1082
|
-
|
1083
|
-
specify "should create a record if the condition is not met" do
|
1084
|
-
@d.replace(:id => 111, :value => 333)
|
1085
|
-
@d.all.should == [{:id => 111, :value => 333}]
|
1086
|
-
end
|
1087
|
-
|
1088
|
-
specify "should update a record if the condition is met" do
|
1089
|
-
@d << {:id => 111}
|
1090
|
-
@d.all.should == [{:id => 111, :value => nil}]
|
1091
|
-
@d.replace(:id => 111, :value => 333)
|
1092
|
-
@d.all.should == [{:id => 111, :value => 333}]
|
1093
|
-
end
|
1094
1073
|
end
|
1095
1074
|
|
1096
1075
|
describe "MySQL::Dataset#complex_expression_sql" do
|
@@ -1303,5 +1282,5 @@ if DB.adapter_scheme == :mysql2
|
|
1303
1282
|
specify "should correctly handle early returning when streaming results" do
|
1304
1283
|
3.times{@ds.each{|r| break r[:a]}.should == 0}
|
1305
1284
|
end
|
1306
|
-
end
|
1285
|
+
end
|
1307
1286
|
end
|
@@ -17,8 +17,7 @@ describe "PostgreSQL", '#create_table' do
|
|
17
17
|
DB.sqls.clear
|
18
18
|
end
|
19
19
|
after do
|
20
|
-
@db.drop_table?(:tmp_dolls)
|
21
|
-
@db.drop_table?(:unlogged_dolls)
|
20
|
+
@db.drop_table?(:tmp_dolls, :unlogged_dolls)
|
22
21
|
end
|
23
22
|
|
24
23
|
specify "should create a temporary table" do
|
@@ -35,6 +34,27 @@ describe "PostgreSQL", '#create_table' do
|
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
37
|
+
specify "should create a table inheriting from another table" do
|
38
|
+
@db.create_table(:unlogged_dolls){text :name}
|
39
|
+
@db.create_table(:tmp_dolls, :inherits=>:unlogged_dolls){}
|
40
|
+
@db[:tmp_dolls].insert('a')
|
41
|
+
@db[:unlogged_dolls].all.should == [{:name=>'a'}]
|
42
|
+
end
|
43
|
+
|
44
|
+
specify "should create a table inheriting from multiple tables" do
|
45
|
+
begin
|
46
|
+
@db.create_table(:unlogged_dolls){text :name}
|
47
|
+
@db.create_table(:tmp_dolls){text :bar}
|
48
|
+
@db.create_table!(:items, :inherits=>[:unlogged_dolls, :tmp_dolls]){text :foo}
|
49
|
+
@db[:items].insert(:name=>'a', :bar=>'b', :foo=>'c')
|
50
|
+
@db[:unlogged_dolls].all.should == [{:name=>'a'}]
|
51
|
+
@db[:tmp_dolls].all.should == [{:bar=>'b'}]
|
52
|
+
@db[:items].all.should == [{:name=>'a', :bar=>'b', :foo=>'c'}]
|
53
|
+
ensure
|
54
|
+
@db.drop_table?(:items)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
38
58
|
specify "should not allow to pass both :temp and :unlogged" do
|
39
59
|
proc do
|
40
60
|
@db.create_table(:temp_unlogged_dolls, :temp => true, :unlogged => true){text :name}
|
@@ -232,6 +252,43 @@ describe "A PostgreSQL dataset" do
|
|
232
252
|
proc{@db[:atest].insert(2)}.should raise_error(Sequel::Postgres::ExclusionConstraintViolation)
|
233
253
|
@db.alter_table(:atest){drop_constraint 'atest_ex'}
|
234
254
|
end if DB.server_version >= 90000
|
255
|
+
|
256
|
+
specify "should support deferrable exclusion constraints" do
|
257
|
+
@db.create_table!(:atest){Integer :t; exclude [[Sequel.desc(:t, :nulls=>:last), '=']], :using=>:btree, :where=>proc{t > 0}, :deferrable => true}
|
258
|
+
proc do
|
259
|
+
@db.transaction do
|
260
|
+
@db[:atest].insert(2)
|
261
|
+
proc{@db[:atest].insert(2)}.should_not raise_error
|
262
|
+
end
|
263
|
+
end.should raise_error(Sequel::Postgres::ExclusionConstraintViolation)
|
264
|
+
end if DB.server_version >= 90000
|
265
|
+
|
266
|
+
specify "should support Database#error_info for getting info hash on the given error" do
|
267
|
+
@db.create_table!(:atest){Integer :t; Integer :t2, :null=>false, :default=>1; constraint :f, :t=>0}
|
268
|
+
begin
|
269
|
+
@db[:atest].insert(1)
|
270
|
+
rescue => e
|
271
|
+
end
|
272
|
+
e.should_not be_nil
|
273
|
+
info = @db.error_info(e)
|
274
|
+
info[:schema].should == 'public'
|
275
|
+
info[:table].should == 'atest'
|
276
|
+
info[:constraint].should == 'f'
|
277
|
+
info[:column].should be_nil
|
278
|
+
info[:type].should be_nil
|
279
|
+
|
280
|
+
begin
|
281
|
+
@db[:atest].insert(0, nil)
|
282
|
+
rescue => e
|
283
|
+
end
|
284
|
+
e.should_not be_nil
|
285
|
+
info = @db.error_info(e.wrapped_exception)
|
286
|
+
info[:schema].should == 'public'
|
287
|
+
info[:table].should == 'atest'
|
288
|
+
info[:constraint].should be_nil
|
289
|
+
info[:column].should == 't2'
|
290
|
+
info[:type].should be_nil
|
291
|
+
end if DB.server_version >= 90300 && DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && Object.const_defined?(:PG) && ::PG.const_defined?(:Constants) && ::PG::Constants.const_defined?(:PG_DIAG_SCHEMA_NAME)
|
235
292
|
|
236
293
|
specify "should support Database#do for executing anonymous code blocks" do
|
237
294
|
@db.drop_table?(:btest)
|
@@ -255,6 +312,19 @@ describe "A PostgreSQL dataset" do
|
|
255
312
|
proc{@db.alter_table(:atest){validate_constraint :atest_fk}}.should_not raise_error
|
256
313
|
end if DB.server_version >= 90200
|
257
314
|
|
315
|
+
specify "should support adding check constarints that are not yet valid, and validating them later" do
|
316
|
+
@db.create_table!(:atest){Integer :a}
|
317
|
+
@db[:atest].insert(5)
|
318
|
+
@db.alter_table(:atest){add_constraint({:name=>:atest_check, :not_valid=>true}){a >= 10}}
|
319
|
+
@db[:atest].insert(10)
|
320
|
+
proc{@db[:atest].insert(6)}.should raise_error(Sequel::DatabaseError)
|
321
|
+
|
322
|
+
proc{@db.alter_table(:atest){validate_constraint :atest_check}}.should raise_error(Sequel::DatabaseError)
|
323
|
+
@db[:atest].where{a < 10}.update(:a=>Sequel.+(:a, 10))
|
324
|
+
@db.alter_table(:atest){validate_constraint :atest_check}
|
325
|
+
proc{@db.alter_table(:atest){validate_constraint :atest_check}}.should_not raise_error
|
326
|
+
end if DB.server_version >= 90200
|
327
|
+
|
258
328
|
specify "should support :using when altering a column's type" do
|
259
329
|
@db.create_table!(:atest){Integer :t}
|
260
330
|
@db[:atest].insert(1262304000)
|
@@ -927,6 +997,13 @@ describe "Postgres::Database schema qualified tables" do
|
|
927
997
|
@db.table_exists?(:schema_test__schema_test).should == true
|
928
998
|
end
|
929
999
|
|
1000
|
+
specify "should be able to add and drop indexes in a schema" do
|
1001
|
+
@db.create_table(:schema_test__schema_test){Integer :i, :index=>true}
|
1002
|
+
@db.indexes(:schema_test__schema_test).keys.should == [:schema_test_schema_test_i_index]
|
1003
|
+
@db.drop_index :schema_test__schema_test, :i
|
1004
|
+
@db.indexes(:schema_test__schema_test).keys.should == []
|
1005
|
+
end
|
1006
|
+
|
930
1007
|
specify "should be able to get primary keys for tables in a given schema" do
|
931
1008
|
@db.create_table(:schema_test__schema_test){primary_key :i}
|
932
1009
|
@db.primary_key(:schema_test__schema_test).should == 'i'
|