sequel 5.6.0 → 5.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +30 -5099
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +0 -2
- data/doc/postgresql.rdoc +31 -0
- data/doc/querying.rdoc +2 -2
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/testing.rdoc +1 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +11 -0
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +117 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +7 -6
- data/lib/sequel/connection_pool/threaded.rb +6 -6
- data/lib/sequel/core.rb +20 -0
- data/lib/sequel/database/logging.rb +3 -2
- data/lib/sequel/database/schema_generator.rb +1 -2
- data/lib/sequel/dataset/actions.rb +15 -5
- data/lib/sequel/extensions/connection_expiration.rb +3 -3
- data/lib/sequel/extensions/connection_validator.rb +3 -3
- data/lib/sequel/extensions/integer64.rb +30 -0
- data/lib/sequel/extensions/migration.rb +2 -3
- data/lib/sequel/plugins/pg_array_associations.rb +5 -3
- data/lib/sequel/plugins/validate_associated.rb +18 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +6 -6
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +15 -1
- data/spec/adapters/postgres_spec.rb +78 -1
- data/spec/adapters/spec_helper.rb +3 -1
- data/spec/bin_spec.rb +1 -0
- data/spec/core/dataset_spec.rb +10 -0
- data/spec/extensions/integer64_spec.rb +22 -0
- data/spec/extensions/pg_array_associations_spec.rb +14 -2
- data/spec/extensions/spec_helper.rb +1 -0
- data/spec/integration/associations_test.rb +4 -4
- data/spec/integration/dataset_test.rb +2 -0
- data/spec/integration/spec_helper.rb +5 -11
- data/spec/model/spec_helper.rb +1 -0
- metadata +35 -165
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
@@ -134,25 +134,25 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
134
134
|
return conn
|
135
135
|
end
|
136
136
|
|
137
|
-
|
137
|
+
timeout = @timeout
|
138
|
+
timer = Sequel.start_timer
|
138
139
|
|
139
140
|
sync do
|
140
|
-
@waiter.wait(@mutex,
|
141
|
+
@waiter.wait(@mutex, timeout)
|
141
142
|
if conn = next_available
|
142
143
|
return(@allocated[thread] = conn)
|
143
144
|
end
|
144
145
|
end
|
145
146
|
|
146
147
|
until conn = assign_connection(thread)
|
147
|
-
|
148
|
-
|
149
|
-
raise_pool_timeout(current_time - time) if current_time > deadline
|
148
|
+
elapsed = Sequel.elapsed_seconds_since(timer)
|
149
|
+
raise_pool_timeout(elapsed) if elapsed > timeout
|
150
150
|
|
151
151
|
# :nocov:
|
152
152
|
# It's difficult to get to this point, it can only happen if there is a race condition
|
153
153
|
# where a connection cannot be acquired even after the thread is signalled by the condition
|
154
154
|
sync do
|
155
|
-
@waiter.wait(@mutex,
|
155
|
+
@waiter.wait(@mutex, timeout - elapsed)
|
156
156
|
if conn = next_available
|
157
157
|
return(@allocated[thread] = conn)
|
158
158
|
end
|
data/lib/sequel/core.rb
CHANGED
@@ -303,6 +303,26 @@ module Sequel
|
|
303
303
|
@single_threaded ? yield : @data_mutex.synchronize(&block)
|
304
304
|
end
|
305
305
|
|
306
|
+
if RUBY_VERSION >= '2.1'
|
307
|
+
# A timer object that can be passed to Sequel.elapsed_seconds_since
|
308
|
+
# to return the number of seconds elapsed.
|
309
|
+
def self.start_timer
|
310
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
311
|
+
end
|
312
|
+
else
|
313
|
+
# :nocov:
|
314
|
+
def self.start_timer # :nodoc:
|
315
|
+
Time.now
|
316
|
+
end
|
317
|
+
# :nocov:
|
318
|
+
end
|
319
|
+
|
320
|
+
# The elapsed seconds since the given timer object was created. The
|
321
|
+
# timer object should have been created via Sequel.start_timer.
|
322
|
+
def self.elapsed_seconds_since(timer)
|
323
|
+
start_timer - timer
|
324
|
+
end
|
325
|
+
|
306
326
|
# Uses a transaction on all given databases with the given options. This:
|
307
327
|
#
|
308
328
|
# Sequel.transaction([DB1, DB2, DB3]){}
|
@@ -37,14 +37,15 @@ module Sequel
|
|
37
37
|
def log_connection_yield(sql, conn, args=nil)
|
38
38
|
return yield if @loggers.empty?
|
39
39
|
sql = "#{connection_info(conn) if conn && log_connection_info}#{sql}#{"; #{args.inspect}" if args}"
|
40
|
-
|
40
|
+
timer = Sequel.start_timer
|
41
|
+
|
41
42
|
begin
|
42
43
|
yield
|
43
44
|
rescue => e
|
44
45
|
log_exception(e, sql)
|
45
46
|
raise
|
46
47
|
ensure
|
47
|
-
log_duration(
|
48
|
+
log_duration(Sequel.elapsed_seconds_since(timer), sql) unless e
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -263,8 +263,7 @@ module Sequel
|
|
263
263
|
#
|
264
264
|
# Examples:
|
265
265
|
# primary_key(:id)
|
266
|
-
# primary_key(:id,
|
267
|
-
# primary_key(:id, Bigint, keep_order: true)
|
266
|
+
# primary_key(:id, type: :Bignum, keep_order: true)
|
268
267
|
# primary_key([:street_number, :house_number], name: :some constraint_name)
|
269
268
|
def primary_key(name, *args)
|
270
269
|
return composite_primary_key(name, *args) if name.is_a?(Array)
|
@@ -929,14 +929,11 @@ module Sequel
|
|
929
929
|
alias with_sql_update with_sql_delete
|
930
930
|
|
931
931
|
# Run the given SQL and yield each returned row to the block.
|
932
|
-
#
|
933
|
-
# This method should not be called on a shared dataset if the columns selected
|
934
|
-
# in the given SQL do not match the columns in the receiver.
|
935
932
|
def with_sql_each(sql)
|
936
933
|
if rp = row_proc
|
937
|
-
fetch_rows(sql){|r| yield rp.call(r)}
|
934
|
+
_with_sql_dataset.fetch_rows(sql){|r| yield rp.call(r)}
|
938
935
|
else
|
939
|
-
fetch_rows(sql){|r| yield r}
|
936
|
+
_with_sql_dataset.fetch_rows(sql){|r| yield r}
|
940
937
|
end
|
941
938
|
self
|
942
939
|
end
|
@@ -1219,5 +1216,18 @@ module Sequel
|
|
1219
1216
|
c
|
1220
1217
|
end
|
1221
1218
|
end
|
1219
|
+
|
1220
|
+
# Cached dataset to use for with_sql_#{all,each,first,single_value}.
|
1221
|
+
# This is used so that the columns returned by the given SQL do not
|
1222
|
+
# affect the receiver of the with_sql_* method.
|
1223
|
+
def _with_sql_dataset
|
1224
|
+
if @opts[:_with_sql_ds]
|
1225
|
+
self
|
1226
|
+
else
|
1227
|
+
cached_dataset(:_with_sql_ds) do
|
1228
|
+
clone(:_with_sql_ds=>true)
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
end
|
1222
1232
|
end
|
1223
1233
|
end
|
@@ -59,7 +59,7 @@ module Sequel
|
|
59
59
|
# Record the time the connection was created.
|
60
60
|
def make_new(*)
|
61
61
|
conn = super
|
62
|
-
@connection_expiration_timestamps[conn] =
|
62
|
+
@connection_expiration_timestamps[conn] = Sequel.start_timer
|
63
63
|
conn
|
64
64
|
end
|
65
65
|
|
@@ -69,8 +69,8 @@ module Sequel
|
|
69
69
|
def acquire(*a)
|
70
70
|
begin
|
71
71
|
if (conn = super) &&
|
72
|
-
(
|
73
|
-
|
72
|
+
(timer = sync{@connection_expiration_timestamps[conn]}) &&
|
73
|
+
Sequel.elapsed_seconds_since(timer) > @connection_expiration_timeout
|
74
74
|
|
75
75
|
if pool_type == :sharded_threaded
|
76
76
|
sync{allocated(a.last).delete(Thread.current)}
|
@@ -79,7 +79,7 @@ module Sequel
|
|
79
79
|
# Record the time the connection was checked back into the pool.
|
80
80
|
def checkin_connection(*)
|
81
81
|
conn = super
|
82
|
-
@connection_timestamps[conn] =
|
82
|
+
@connection_timestamps[conn] = Sequel.start_timer
|
83
83
|
conn
|
84
84
|
end
|
85
85
|
|
@@ -96,8 +96,8 @@ module Sequel
|
|
96
96
|
def acquire(*a)
|
97
97
|
begin
|
98
98
|
if (conn = super) &&
|
99
|
-
(
|
100
|
-
|
99
|
+
(timer = sync{@connection_timestamps.delete(conn)}) &&
|
100
|
+
Sequel.elapsed_seconds_since(timer) > @connection_validation_timeout &&
|
101
101
|
!db.valid_connection?(conn)
|
102
102
|
|
103
103
|
if pool_type == :sharded_threaded
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
#
|
3
|
+
# The integer64 extension changes the default type used for Integer
|
4
|
+
# to be the same type as used for :Bignum. In general, this means that
|
5
|
+
# instead of Integer resulting in a 32-bit database integer type, it will
|
6
|
+
# result in a 64-bit database integer type. This affects the default
|
7
|
+
# type used for primary_key and foreign_key when using the schema
|
8
|
+
# modification methods.
|
9
|
+
#
|
10
|
+
# Note that it doesn't make sense to use this extension on SQLite, since
|
11
|
+
# the integer type will automatically handle 64-bit integers, and it treats
|
12
|
+
# the integer type specially when the column is also the primary key.
|
13
|
+
#
|
14
|
+
# To load the extension into the database:
|
15
|
+
#
|
16
|
+
# DB.extension :integer64
|
17
|
+
#
|
18
|
+
# Related module: Sequel::Integer64
|
19
|
+
|
20
|
+
#
|
21
|
+
module Sequel
|
22
|
+
module Integer64
|
23
|
+
# Use timestamptz by default for generic timestamp value.
|
24
|
+
def type_literal_generic_integer(column)
|
25
|
+
type_literal_generic_bignum_symbol(column)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Database.register_extension(:integer64, Integer64)
|
30
|
+
end
|
@@ -548,13 +548,13 @@ module Sequel
|
|
548
548
|
# Apply all migrations on the database
|
549
549
|
def run
|
550
550
|
migrations.zip(version_numbers).each do |m, v|
|
551
|
-
|
551
|
+
timer = Sequel.start_timer
|
552
552
|
db.log_info("Begin applying migration version #{v}, direction: #{direction}")
|
553
553
|
checked_transaction(m) do
|
554
554
|
m.apply(db, direction)
|
555
555
|
set_migration_version(up? ? v : v-1)
|
556
556
|
end
|
557
|
-
db.log_info("Finished applying migration version #{v}, direction: #{direction}, took #{sprintf('%0.6f',
|
557
|
+
db.log_info("Finished applying migration version #{v}, direction: #{direction}, took #{sprintf('%0.6f', Sequel.elapsed_seconds_since(timer))} seconds")
|
558
558
|
end
|
559
559
|
|
560
560
|
target
|
@@ -736,7 +736,6 @@ module Sequel
|
|
736
736
|
def get_migration_tuples
|
737
737
|
up_mts = []
|
738
738
|
down_mts = []
|
739
|
-
ms = Migration.descendants
|
740
739
|
files.each do |path|
|
741
740
|
f = File.basename(path)
|
742
741
|
fi = f.downcase
|
@@ -80,7 +80,7 @@ module Sequel
|
|
80
80
|
def array_type
|
81
81
|
cached_fetch(:array_type) do
|
82
82
|
if (sch = associated_class.db_schema) && (s = sch[self[:key]]) && (t = s[:db_type])
|
83
|
-
t
|
83
|
+
t.sub(/\[\]\z/, '').freeze
|
84
84
|
else
|
85
85
|
:integer
|
86
86
|
end
|
@@ -189,7 +189,7 @@ module Sequel
|
|
189
189
|
def array_type
|
190
190
|
cached_fetch(:array_type) do
|
191
191
|
if (sch = self[:model].db_schema) && (s = sch[self[:key]]) && (t = s[:db_type])
|
192
|
-
t
|
192
|
+
t.sub(/\[\]\z/, '').freeze
|
193
193
|
else
|
194
194
|
:integer
|
195
195
|
end
|
@@ -400,7 +400,9 @@ module Sequel
|
|
400
400
|
end
|
401
401
|
|
402
402
|
opts[:clearer] ||= proc do
|
403
|
-
|
403
|
+
pk_value = get_column_value(pk)
|
404
|
+
db_type = opts.array_type
|
405
|
+
opts.associated_dataset.where(Sequel.pg_array_op(key).contains(Sequel.pg_array([pk_value], db_type))).update(key=>Sequel.function(:array_remove, key, Sequel.cast(pk_value, db_type)))
|
404
406
|
end
|
405
407
|
end
|
406
408
|
|
@@ -16,6 +16,24 @@ module Sequel
|
|
16
16
|
#
|
17
17
|
# # Make the Album class support validating associated objects
|
18
18
|
# Album.plugin :validate_associated
|
19
|
+
#
|
20
|
+
# class Album
|
21
|
+
# many_to_one :artist
|
22
|
+
# many_to_many :tags
|
23
|
+
#
|
24
|
+
# # Always validate associated artist when saving the album
|
25
|
+
# def validate
|
26
|
+
# super
|
27
|
+
# if artist
|
28
|
+
# validate_associated_object(model.association_reflection(:artist), artist)
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # When saving after calling this method, validate the given tag as well.
|
33
|
+
# def check_tag!(tag)
|
34
|
+
# delay_validate_associated_object(model.association_reflection(:tags), tag)
|
35
|
+
# end
|
36
|
+
# end
|
19
37
|
module ValidateAssociated
|
20
38
|
# Depend on the instance_hooks plugin.
|
21
39
|
def self.apply(mod)
|
data/lib/sequel/version.rb
CHANGED
@@ -5,7 +5,7 @@ module Sequel
|
|
5
5
|
MAJOR = 5
|
6
6
|
# The minor version of Sequel. Bumped for every non-patch level
|
7
7
|
# release, generally around once a month.
|
8
|
-
MINOR =
|
8
|
+
MINOR = 7
|
9
9
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
10
10
|
# releases that fix regressions from previous versions.
|
11
11
|
TINY = 0
|
data/spec/adapters/mssql_spec.rb
CHANGED
@@ -636,18 +636,18 @@ describe "Database#foreign_key_list" do
|
|
636
636
|
before(:all) do
|
637
637
|
DB.create_table! :items do
|
638
638
|
primary_key :id
|
639
|
-
|
639
|
+
Integer :sku
|
640
640
|
end
|
641
641
|
DB.create_table! :prices do
|
642
|
-
|
642
|
+
Integer :item_id
|
643
643
|
datetime :valid_from
|
644
644
|
float :price
|
645
645
|
primary_key [:item_id, :valid_from]
|
646
646
|
foreign_key [:item_id], :items, :key => :id, :name => :fk_prices_items
|
647
647
|
end
|
648
648
|
DB.create_table! :sales do
|
649
|
-
|
650
|
-
|
649
|
+
Integer :id
|
650
|
+
Integer :price_item_id
|
651
651
|
datetime :price_valid_from
|
652
652
|
foreign_key [:price_item_id, :price_valid_from], :prices, :key => [:item_id, :valid_from], :name => :fk_sales_prices, :on_delete => :cascade
|
653
653
|
end
|
@@ -682,8 +682,8 @@ describe "Database#foreign_key_list" do
|
|
682
682
|
varchar :name
|
683
683
|
end
|
684
684
|
DB.create_table! Sequel[:vendor][:mapping] do
|
685
|
-
|
686
|
-
|
685
|
+
Integer :vendor_id
|
686
|
+
Integer :item_id
|
687
687
|
foreign_key [:vendor_id], Sequel[:vendor][:vendors], :name => :fk_mapping_vendor
|
688
688
|
foreign_key [:item_id], :items, :name => :fk_mapping_item
|
689
689
|
end
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -113,7 +113,7 @@ describe "An Oracle database" do
|
|
113
113
|
it "should create a temporary table" do
|
114
114
|
DB.create_table! :test_tmp, :temp => true do
|
115
115
|
varchar2 :name, :size => 50
|
116
|
-
primary_key :id, :
|
116
|
+
primary_key :id, :null => false
|
117
117
|
index :name, :unique => true
|
118
118
|
end
|
119
119
|
DB.drop_table?(:test_tmp)
|
@@ -311,3 +311,17 @@ describe "An Oracle database" do
|
|
311
311
|
DB[:books].select(:title).group_by(:title).count.must_equal 2
|
312
312
|
end
|
313
313
|
end
|
314
|
+
|
315
|
+
describe "An Oracle database with xml types" do
|
316
|
+
before(:all) do
|
317
|
+
DB.create_table!(:xml_test){xmltype :xml_col}
|
318
|
+
end
|
319
|
+
after(:all) do
|
320
|
+
DB.drop_table(:xml_test)
|
321
|
+
end
|
322
|
+
|
323
|
+
it "should work correctly with temporary clobs" do
|
324
|
+
DB[:xml_test].insert("<a href='b'>c</a>")
|
325
|
+
DB.from(Sequel.lit('xml_test x')).select(Sequel.lit("x.xml_col.getCLOBVal() v")).all.must_equal [{:v=>"<a href=\"b\">c</a>\n"}]
|
326
|
+
end
|
327
|
+
end
|
@@ -107,6 +107,83 @@ describe "PostgreSQL", '#create_table' do
|
|
107
107
|
end
|
108
108
|
end if DB.server_version >= 90000
|
109
109
|
|
110
|
+
it "should support creating identity columns on non-primary key tables" do
|
111
|
+
@db.create_table(:tmp_dolls){Integer :a, :identity=>true}
|
112
|
+
2.times do
|
113
|
+
@db[:tmp_dolls].insert
|
114
|
+
end
|
115
|
+
@db[:tmp_dolls].select_order_map(:a).must_equal [1, 2]
|
116
|
+
@db[:tmp_dolls].insert(:a=>2)
|
117
|
+
@db[:tmp_dolls].select_order_map(:a).must_equal [1, 2, 2]
|
118
|
+
@db[:tmp_dolls].insert(:a=>4)
|
119
|
+
@db[:tmp_dolls].select_order_map(:a).must_equal [1, 2, 2, 4]
|
120
|
+
@db[:tmp_dolls].overriding_user_value.insert(:a=>5)
|
121
|
+
@db[:tmp_dolls].select_order_map(:a).must_equal [1, 2, 2, 3, 4]
|
122
|
+
end if DB.server_version >= 100002
|
123
|
+
|
124
|
+
it "should support creating identity columns generated always" do
|
125
|
+
@db.create_table(:tmp_dolls){primary_key :id, :identity=>:always}
|
126
|
+
2.times do
|
127
|
+
@db[:tmp_dolls].insert
|
128
|
+
end
|
129
|
+
@db[:tmp_dolls].select_order_map(:id).must_equal [1, 2]
|
130
|
+
proc{@db[:tmp_dolls].insert(:id=>2)}.must_raise Sequel::DatabaseError
|
131
|
+
@db[:tmp_dolls].overriding_system_value.insert(:id=>4)
|
132
|
+
@db[:tmp_dolls].select_order_map(:id).must_equal [1, 2, 4]
|
133
|
+
@db[:tmp_dolls].insert
|
134
|
+
@db[:tmp_dolls].select_order_map(:id).must_equal [1, 2, 3, 4]
|
135
|
+
end if DB.server_version >= 100002
|
136
|
+
|
137
|
+
it "should support converting serial columns to identity columns" do
|
138
|
+
@db.create_table(:tmp_dolls){primary_key :id, :identity=>false, :serial=>true}
|
139
|
+
sch = @db.schema(:tmp_dolls)[0][1]
|
140
|
+
sch[:default].must_match(/nextval/)
|
141
|
+
sch[:auto_increment].must_equal true
|
142
|
+
|
143
|
+
2.times do
|
144
|
+
@db[:tmp_dolls].insert
|
145
|
+
end
|
146
|
+
|
147
|
+
@db.convert_serial_to_identity(:tmp_dolls)
|
148
|
+
sch = @db.schema(:tmp_dolls)[0][1]
|
149
|
+
sch[:default].must_be_nil
|
150
|
+
sch[:auto_increment].must_equal true
|
151
|
+
|
152
|
+
@db[:tmp_dolls].insert
|
153
|
+
@db[:tmp_dolls].insert(5)
|
154
|
+
@db[:tmp_dolls].select_order_map(:id).must_equal [1, 2, 3, 5]
|
155
|
+
|
156
|
+
# Make sure it doesn't break if already converted
|
157
|
+
@db.convert_serial_to_identity(:tmp_dolls)
|
158
|
+
end if DB.server_version >= 100002 && DB.get{current_setting('is_superuser')} == 'on'
|
159
|
+
|
160
|
+
it "should support converting serial columns to identity columns when using the :column option" do
|
161
|
+
@db.create_table(:tmp_dolls){Integer :i, :primary_key=>true; serial :id}
|
162
|
+
sch = @db.schema(:tmp_dolls)[1][1]
|
163
|
+
sch[:default].must_match(/nextval/)
|
164
|
+
|
165
|
+
2.times do |i|
|
166
|
+
@db[:tmp_dolls].insert(:i=>-i)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Automatic conversion should not work
|
170
|
+
proc{@db.convert_serial_to_identity(:tmp_dolls)}.must_raise Sequel::Error
|
171
|
+
|
172
|
+
# Conversion of type without related sequence should not work
|
173
|
+
proc{@db.convert_serial_to_identity(:tmp_dolls, :column=>:i)}.must_raise Sequel::Error
|
174
|
+
|
175
|
+
@db.convert_serial_to_identity(:tmp_dolls, :column=>:id)
|
176
|
+
sch = @db.schema(:tmp_dolls)[1][1]
|
177
|
+
sch[:default].must_be_nil
|
178
|
+
|
179
|
+
@db[:tmp_dolls].insert(:i=>200)
|
180
|
+
@db[:tmp_dolls].insert(:i=>300, :id=>5)
|
181
|
+
@db[:tmp_dolls].select_order_map(:id).must_equal [1, 2, 3, 5]
|
182
|
+
|
183
|
+
# Make sure it doesn't break if already converted
|
184
|
+
@db.convert_serial_to_identity(:tmp_dolls, :column=>:id)
|
185
|
+
end if DB.server_version >= 100002 && DB.get{current_setting('is_superuser')} == 'on'
|
186
|
+
|
110
187
|
it "should support pg_loose_count extension" do
|
111
188
|
@db.extension :pg_loose_count
|
112
189
|
@db.create_table(:tmp_dolls){text :name}
|
@@ -324,7 +401,7 @@ describe "A PostgreSQL database" do
|
|
324
401
|
end
|
325
402
|
|
326
403
|
it "should correctly parse the schema" do
|
327
|
-
@db.schema(Sequel[:public][:testfk], :reload=>true).map{|c,s| [c, s[:oid]]}
|
404
|
+
[[[:id, 23], [:i, 23]], [[:id, 20], [:i, 20]]].must_include @db.schema(Sequel[:public][:testfk], :reload=>true).map{|c,s| [c, s[:oid]]}
|
328
405
|
end
|
329
406
|
|
330
407
|
it "should parse foreign keys for tables in a schema" do
|