sequel 5.4.0 → 5.5.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 +26 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/doc/release_notes/5.5.0.txt +61 -0
- data/lib/sequel/adapters/postgres.rb +8 -2
- data/lib/sequel/database/query.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +11 -0
- data/lib/sequel/extensions/pg_hstore.rb +10 -0
- data/lib/sequel/extensions/pg_inet.rb +10 -0
- data/lib/sequel/extensions/pg_interval.rb +10 -0
- data/lib/sequel/extensions/pg_json.rb +24 -0
- data/lib/sequel/extensions/pg_range.rb +14 -0
- data/lib/sequel/model/base.rb +29 -18
- data/lib/sequel/plugins/defaults_setter.rb +45 -8
- data/lib/sequel/plugins/dirty.rb +2 -2
- data/lib/sequel/plugins/modification_detection.rb +12 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +2 -1
- data/lib/sequel/plugins/serialization.rb +3 -2
- data/lib/sequel/plugins/typecast_on_load.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +2 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +79 -8
- data/spec/core/schema_spec.rb +10 -0
- data/spec/extensions/defaults_setter_spec.rb +18 -0
- data/spec/extensions/modification_detection_spec.rb +13 -0
- data/spec/extensions/pg_array_spec.rb +11 -0
- data/spec/extensions/pg_hstore_spec.rb +11 -0
- data/spec/extensions/pg_inet_spec.rb +6 -0
- data/spec/extensions/pg_interval_spec.rb +6 -0
- data/spec/extensions/pg_json_spec.rb +29 -0
- data/spec/extensions/pg_range_spec.rb +6 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34e1f1ee3e3e1b863d4efbc3710cae912ae394a655b6e9fed41325f02d54f23e
|
4
|
+
data.tar.gz: af6f231e63231de19bb7956ea16cff29ec2faebe379a0ba86e12df933af0b91b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2f482f59fe3bb9eb19d2fa88a6fccfdf5e259cb23a52e2d21c3bb692f4f3a04339c2011922a03ceb4593b4a2708fbafdd45dbde2a882f7f77d20a3e2048e000
|
7
|
+
data.tar.gz: 19e9f635bcdb299673ab5d042159f7e76dbdee1807fd02b8e897c434e6ad11214113ac252064106507620ae3e9a19d3facb49d181ab28cc08e47c5a5b2ebfa65
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
=== 5.5.0 (2018-01-31)
|
2
|
+
|
3
|
+
* Make Database#copy_table in the postgres adapter handle errors that occur while processing rows (jeremyevans) (#1470)
|
4
|
+
|
5
|
+
* Cache results of changed_columns method in local variables in many places for better performance (jeremyevans)
|
6
|
+
|
7
|
+
* Make modification_detection plugin not break column change detection for new objects (jeremyevans) (#1468)
|
8
|
+
|
9
|
+
* Make pg_range extension set :ruby_default schema value for recognized range defaults (jeremyevans)
|
10
|
+
|
11
|
+
* Make pg_interval extension set :ruby_default schema value for recognized interval defaults (jeremyevans)
|
12
|
+
|
13
|
+
* Make pg_json extension set :callable_default schema value for empty json/jsonb array/hash defaults (jeremyevans)
|
14
|
+
|
15
|
+
* Make pg_inet extension set :ruby_default schema value for recognized inet/cidr defaults (jeremyevans)
|
16
|
+
|
17
|
+
* Make pg_hstore extension set :callable_default schema value for empty hstore defaults (jeremyevans)
|
18
|
+
|
19
|
+
* Make pg_array extension set :callable_default schema value for recognized empty array defaults (jeremyevans) (#1466)
|
20
|
+
|
21
|
+
* Make defaults_setter plugin prefer :callable_default db_schema values over :ruby_default db_schema values (jeremyevans)
|
22
|
+
|
23
|
+
* Add defaults_setter plugin :cache option for caching default values returned (jeremyevans)
|
24
|
+
|
25
|
+
* Freeze string values in hashes returned by Database#schema (jeremyevans)
|
26
|
+
|
1
27
|
=== 5.4.0 (2018-01-04)
|
2
28
|
|
3
29
|
* Enable fractional seconds in timestamps on DB2 (jeremyevans) (#1463)
|
data/MIT-LICENSE
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Copyright (c) 2007-2008 Sharon Rosner
|
2
|
-
Copyright (c) 2008-
|
2
|
+
Copyright (c) 2008-2018 Jeremy Evans
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to
|
data/README.rdoc
CHANGED
@@ -124,7 +124,7 @@ You can also specify optional parameters, such as the connection pool size, or l
|
|
124
124
|
It is also possible to use a hash instead of a connection URL, but make sure to include the :adapter option in this case:
|
125
125
|
|
126
126
|
DB = Sequel.connect(adapter: :postgres, user: 'user', password: 'password', host: 'host', port: port,
|
127
|
-
database: 'database_name
|
127
|
+
database: 'database_name', max_connections: 10, logger: Logger.new('log/db.log'))
|
128
128
|
|
129
129
|
You can specify a block to connect, which will disconnect from the database after it completes:
|
130
130
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* The defaults_setter plugin now supports a :cache option, which
|
4
|
+
will cache default values in the model object's values hash:
|
5
|
+
|
6
|
+
Model.plugin :defaults_setter
|
7
|
+
o = Model.new
|
8
|
+
o.column # => 1 # default value
|
9
|
+
o.values # => {}
|
10
|
+
|
11
|
+
Model.plugin :defaults_setter, cache: true
|
12
|
+
o = Model.new
|
13
|
+
o.column # => 1 # default value
|
14
|
+
o.values # => {:column => 1}
|
15
|
+
|
16
|
+
* The pg_array extension now sets a :callable_default schema entry
|
17
|
+
for recognized empty array defaults.
|
18
|
+
|
19
|
+
* The pg_hstore extension now sets a :callable_default schema entry
|
20
|
+
for recognized empty hstore defaults.
|
21
|
+
|
22
|
+
* The pg_json extension now sets a :callable_default schema entry for
|
23
|
+
recognized empty json/jsonb array/hash defaults.
|
24
|
+
|
25
|
+
* The pg_inet extension now sets a :ruby_default schema entry for
|
26
|
+
recognized inet/cidr defaults.
|
27
|
+
|
28
|
+
* The pg_range extension now sets a :ruby_default schema entry for
|
29
|
+
recognized range defaults.
|
30
|
+
|
31
|
+
* The defaults_setter plugin will now give preference to a
|
32
|
+
:callable_default schema entry over a :ruby_default schema entry.
|
33
|
+
Combined with the other changes listed above, this makes default
|
34
|
+
values recognized by the pg_array, pg_hstore, and pg_json extensions
|
35
|
+
work well if the defaults_setter :cache option is also used.
|
36
|
+
|
37
|
+
= Other Improvements
|
38
|
+
|
39
|
+
* The modification_detection plugin no longer breaks column change
|
40
|
+
detection for new objects.
|
41
|
+
|
42
|
+
* Database#copy_table in the postgres adapter now handles errors that
|
43
|
+
occur when processing rows. Previously, an exception could be
|
44
|
+
raised on the next query in that case.
|
45
|
+
|
46
|
+
* The results of the changed_columns method are now cached in many
|
47
|
+
places internally where they are called in a loop. This results
|
48
|
+
in better performance, especially if the modification_detection or
|
49
|
+
serialization_modification_detection plugins are used.
|
50
|
+
|
51
|
+
= Backwards Compatibility
|
52
|
+
|
53
|
+
* The pg_interval extension now sets a :ruby_default schema entry for
|
54
|
+
recognized interval defaults to the same value Sequel would return
|
55
|
+
if the default value was returned. Previously, Sequel would use a
|
56
|
+
string in the :ruby_schema schema value.
|
57
|
+
|
58
|
+
* String values in hashes returned by Database#schema are now frozen
|
59
|
+
to prevent possible thread-safety issues and issues with
|
60
|
+
unintentional modification of a shared string. The hashes
|
61
|
+
themselves are not frozen and can still be modified.
|
@@ -309,12 +309,18 @@ module Sequel
|
|
309
309
|
while buf = conn.get_copy_data
|
310
310
|
yield buf
|
311
311
|
end
|
312
|
-
nil
|
312
|
+
b = nil
|
313
313
|
else
|
314
314
|
b = String.new
|
315
315
|
b << buf while buf = conn.get_copy_data
|
316
|
-
b
|
317
316
|
end
|
317
|
+
|
318
|
+
res = conn.get_last_result
|
319
|
+
if !res || res.result_status != 1
|
320
|
+
raise PG::NotAllCopyDataRetrieved, "Not all COPY data retrieved"
|
321
|
+
end
|
322
|
+
|
323
|
+
b
|
318
324
|
rescue => e
|
319
325
|
raise_error(e, :disconnect=>true)
|
320
326
|
ensure
|
@@ -175,6 +175,10 @@ module Sequel
|
|
175
175
|
if !c[:max_length] && c[:type] == :string && (max_length = column_schema_max_length(c[:db_type]))
|
176
176
|
c[:max_length] = max_length
|
177
177
|
end
|
178
|
+
|
179
|
+
c.each_value do |v|
|
180
|
+
v.freeze if v.is_a?(String)
|
181
|
+
end
|
178
182
|
end
|
179
183
|
Sequel.synchronize{@schemas[quoted_name] = cols} if cache_schema
|
180
184
|
cols
|
@@ -253,6 +253,17 @@ module Sequel
|
|
253
253
|
end
|
254
254
|
end
|
255
255
|
|
256
|
+
# Set the :callable_default value if the default value is recognized as an empty array.
|
257
|
+
def schema_parse_table(*)
|
258
|
+
super.each do |a|
|
259
|
+
h = a[1]
|
260
|
+
if h[:default] =~ /\A(?:'\{\}'|ARRAY\[\])::([\w ]+)\[\]\z/
|
261
|
+
type = $1.freeze
|
262
|
+
h[:callable_default] = lambda{Sequel.pg_array([], type)}
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
256
267
|
# Convert ruby arrays to PostgreSQL arrays when used as default values.
|
257
268
|
def column_definition_default_sql(sql, column)
|
258
269
|
if (d = column[:default]) && d.is_a?(Array) && !Sequel.condition_specifier?(d)
|
@@ -154,6 +154,16 @@ module Sequel
|
|
154
154
|
db_type == 'hstore' ? :hstore : super
|
155
155
|
end
|
156
156
|
|
157
|
+
# Set the :callable_default value if the default value is recognized as an empty hstore.
|
158
|
+
def schema_parse_table(*)
|
159
|
+
super.each do |a|
|
160
|
+
h = a[1]
|
161
|
+
if h[:type] == :hstore && h[:default] =~ /\A''::hstore\z/
|
162
|
+
h[:callable_default] = lambda{HStore.new({})}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
157
167
|
# Typecast value correctly to HStore. If already an
|
158
168
|
# HStore instance, return as is. If a hash, return
|
159
169
|
# an HStore version of it. If a string, assume it is
|
@@ -85,6 +85,16 @@ module Sequel
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
# Set the :ruby_default value if the default value is recognized as an ip address.
|
89
|
+
def schema_parse_table(*)
|
90
|
+
super.each do |a|
|
91
|
+
h = a[1]
|
92
|
+
if h[:type] == :ipaddr && h[:default] =~ /\A'([:a-fA-F0-9\.\/]+)'::(?:inet|cidr)\z/
|
93
|
+
h[:ruby_default] = IPAddr.new($1)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
88
98
|
# Typecast the given value to an IPAddr object.
|
89
99
|
def typecast_value_ipaddr(value)
|
90
100
|
case value
|
@@ -146,6 +146,16 @@ module Sequel
|
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
149
|
+
# Set the :ruby_default value if the default value is recognized as an interval.
|
150
|
+
def schema_parse_table(*)
|
151
|
+
super.each do |a|
|
152
|
+
h = a[1]
|
153
|
+
if h[:type] == :interval && h[:default] =~ /\A'([\w ]+)'::interval\z/
|
154
|
+
h[:ruby_default] = PARSER.call($1)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
149
159
|
# Typecast value correctly to an ActiveSupport::Duration instance.
|
150
160
|
# If already an ActiveSupport::Duration, return it.
|
151
161
|
# If a numeric argument is given, assume it represents a number
|
@@ -214,6 +214,30 @@ module Sequel
|
|
214
214
|
end
|
215
215
|
end
|
216
216
|
|
217
|
+
# Set the :callable_default value if the default value is recognized as an empty json/jsonb array/hash.
|
218
|
+
def schema_parse_table(*)
|
219
|
+
super.each do |a|
|
220
|
+
h = a[1]
|
221
|
+
if (h[:type] == :json || h[:type] == :jsonb) && h[:default] =~ /\A'(\{\}|\[\])'::jsonb?\z/
|
222
|
+
is_array = $1 == '[]'
|
223
|
+
|
224
|
+
klass = if h[:type] == :json
|
225
|
+
if is_array
|
226
|
+
JSONArray
|
227
|
+
else
|
228
|
+
JSONHash
|
229
|
+
end
|
230
|
+
elsif is_array
|
231
|
+
JSONBArray
|
232
|
+
else
|
233
|
+
JSONBHash
|
234
|
+
end
|
235
|
+
|
236
|
+
h[:callable_default] = lambda{klass.new(is_array ? [] : {})}
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
217
241
|
# Convert the value given to a JSONArray or JSONHash
|
218
242
|
def typecast_value_json(value)
|
219
243
|
case value
|
@@ -262,6 +262,20 @@ module Sequel
|
|
262
262
|
end
|
263
263
|
end
|
264
264
|
|
265
|
+
# Set the :ruby_default value if the default value is recognized as a range.
|
266
|
+
def schema_parse_table(*)
|
267
|
+
super.each do |a|
|
268
|
+
h = a[1]
|
269
|
+
db_type = h[:db_type]
|
270
|
+
if @pg_range_schema_types[db_type] && h[:default] =~ /\A'([^']+)'::#{db_type}\z/
|
271
|
+
default = $1
|
272
|
+
if convertor = conversion_procs[h[:oid]]
|
273
|
+
h[:ruby_default] = convertor.call($1)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
265
279
|
# Typecast value correctly to a PGRange. If already an
|
266
280
|
# PGRange instance with the same db_type, return as is.
|
267
281
|
# If a PGRange with a different subtype, return a new
|
data/lib/sequel/model/base.rb
CHANGED
@@ -1060,7 +1060,7 @@ module Sequel
|
|
1060
1060
|
@new = true
|
1061
1061
|
@modified = true
|
1062
1062
|
initialize_set(values)
|
1063
|
-
|
1063
|
+
_changed_columns.clear
|
1064
1064
|
yield self if block_given?
|
1065
1065
|
end
|
1066
1066
|
|
@@ -1137,9 +1137,9 @@ module Sequel
|
|
1137
1137
|
# a.name = 'Bob'
|
1138
1138
|
# a.changed_columns # => [:name]
|
1139
1139
|
def changed_columns
|
1140
|
-
|
1140
|
+
_changed_columns
|
1141
1141
|
end
|
1142
|
-
|
1142
|
+
|
1143
1143
|
# Deletes and returns +self+. Does not run destroy hooks.
|
1144
1144
|
# Look into using +destroy+ instead.
|
1145
1145
|
#
|
@@ -1212,7 +1212,7 @@ module Sequel
|
|
1212
1212
|
# errors, or dataset.
|
1213
1213
|
def freeze
|
1214
1214
|
values.freeze
|
1215
|
-
|
1215
|
+
_changed_columns.freeze
|
1216
1216
|
unless errors.frozen?
|
1217
1217
|
validate
|
1218
1218
|
errors.freeze
|
@@ -1316,9 +1316,7 @@ module Sequel
|
|
1316
1316
|
# a.modified!(:name)
|
1317
1317
|
# a.name.gsub!(/[aeou]/, 'i')
|
1318
1318
|
def modified!(column=nil)
|
1319
|
-
|
1320
|
-
changed_columns << column
|
1321
|
-
end
|
1319
|
+
_add_changed_column(column) if column
|
1322
1320
|
@modified = true
|
1323
1321
|
end
|
1324
1322
|
|
@@ -1583,6 +1581,17 @@ module Sequel
|
|
1583
1581
|
|
1584
1582
|
private
|
1585
1583
|
|
1584
|
+
# Add a column as a changed column.
|
1585
|
+
def _add_changed_column(column)
|
1586
|
+
cc = _changed_columns
|
1587
|
+
cc << column unless cc.include?(column)
|
1588
|
+
end
|
1589
|
+
|
1590
|
+
# Internal changed_columns method that just returns stored array.
|
1591
|
+
def _changed_columns
|
1592
|
+
@changed_columns ||= []
|
1593
|
+
end
|
1594
|
+
|
1586
1595
|
# Do the deletion of the object's dataset, and check that the row
|
1587
1596
|
# was actually deleted.
|
1588
1597
|
def _delete
|
@@ -1672,7 +1681,7 @@ module Sequel
|
|
1672
1681
|
# is used for reading newly inserted values from the database
|
1673
1682
|
def _refresh(dataset)
|
1674
1683
|
_refresh_set_values(_refresh_get(dataset) || raise(NoExistingObject, "Record not found"))
|
1675
|
-
|
1684
|
+
_changed_columns.clear
|
1676
1685
|
end
|
1677
1686
|
|
1678
1687
|
# Get the row of column data from the database.
|
@@ -1710,7 +1719,7 @@ module Sequel
|
|
1710
1719
|
@this = nil
|
1711
1720
|
@new = false
|
1712
1721
|
@modified = false
|
1713
|
-
pk ? _save_refresh :
|
1722
|
+
pk ? _save_refresh : _changed_columns.clear
|
1714
1723
|
after_create
|
1715
1724
|
true
|
1716
1725
|
end
|
@@ -1721,16 +1730,18 @@ module Sequel
|
|
1721
1730
|
before_update
|
1722
1731
|
columns = opts[:columns]
|
1723
1732
|
if columns.nil?
|
1724
|
-
|
1725
|
-
|
1733
|
+
if opts[:changed]
|
1734
|
+
cc = changed_columns
|
1735
|
+
columns_updated = @values.reject{|k,v| !cc.include?(k)}
|
1736
|
+
cc.clear
|
1726
1737
|
else
|
1727
|
-
_save_update_all_columns_hash
|
1738
|
+
columns_updated = _save_update_all_columns_hash
|
1739
|
+
_changed_columns.clear
|
1728
1740
|
end
|
1729
|
-
changed_columns.clear
|
1730
1741
|
else # update only the specified columns
|
1731
1742
|
columns = Array(columns)
|
1732
1743
|
columns_updated = @values.reject{|k, v| !columns.include?(k)}
|
1733
|
-
|
1744
|
+
_changed_columns.reject!{|c| columns.include?(c)}
|
1734
1745
|
end
|
1735
1746
|
_update_columns(columns_updated)
|
1736
1747
|
@this = nil
|
@@ -1752,7 +1763,7 @@ module Sequel
|
|
1752
1763
|
# can be overridden to avoid the refresh.
|
1753
1764
|
def _save_refresh
|
1754
1765
|
_save_set_values(_refresh_get(this.server?(:default)) || raise(NoExistingObject, "Record not found"))
|
1755
|
-
|
1766
|
+
_changed_columns.clear
|
1756
1767
|
end
|
1757
1768
|
|
1758
1769
|
# Set values to the provided hash. Called after a create,
|
@@ -1769,7 +1780,8 @@ module Sequel
|
|
1769
1780
|
# to their existing values.
|
1770
1781
|
def _save_update_all_columns_hash
|
1771
1782
|
v = Hash[@values]
|
1772
|
-
|
1783
|
+
cc = changed_columns
|
1784
|
+
Array(primary_key).each{|x| v.delete(x) unless cc.include?(x)}
|
1773
1785
|
v
|
1774
1786
|
end
|
1775
1787
|
|
@@ -1847,8 +1859,7 @@ module Sequel
|
|
1847
1859
|
|
1848
1860
|
# Change the value of the column to given value, recording the change.
|
1849
1861
|
def change_column_value(column, value)
|
1850
|
-
|
1851
|
-
cc << column unless cc.include?(column)
|
1862
|
+
_add_changed_column(column)
|
1852
1863
|
@values[column] = value
|
1853
1864
|
end
|
1854
1865
|
|
@@ -23,6 +23,24 @@ module Sequel
|
|
23
23
|
#
|
24
24
|
# Album.default_values[:a] = lambda{Date.today}
|
25
25
|
# Album.new.a # => Date.today
|
26
|
+
#
|
27
|
+
# By default, default values returned are not cached:
|
28
|
+
#
|
29
|
+
# Album.new.a.equal?(Album.new.a) # => false
|
30
|
+
#
|
31
|
+
# However, you can turn on caching of default values:
|
32
|
+
#
|
33
|
+
# Album.plugin :defaults_setter, cache: true
|
34
|
+
# Album.new.a.equal?(Album.new.a) # => false
|
35
|
+
#
|
36
|
+
# Note that if the cache is turned on, the cached values are stored in
|
37
|
+
# the values hash:
|
38
|
+
#
|
39
|
+
# Album.plugin :defaults_setter, cache: true
|
40
|
+
# album = Album.new
|
41
|
+
# album.values # => {}
|
42
|
+
# album.a
|
43
|
+
# album.values # => {:a => Date.today}
|
26
44
|
#
|
27
45
|
# Usage:
|
28
46
|
#
|
@@ -32,22 +50,31 @@ module Sequel
|
|
32
50
|
# # Make the Album class set defaults
|
33
51
|
# Album.plugin :defaults_setter
|
34
52
|
module DefaultsSetter
|
35
|
-
# Set the default values based on the model schema
|
36
|
-
|
37
|
-
|
53
|
+
# Set the default values based on the model schema. Options:
|
54
|
+
# :cache :: Cache default values returned in the model's values hash.
|
55
|
+
def self.configure(model, opts=OPTS)
|
56
|
+
model.instance_exec do
|
57
|
+
set_default_values
|
58
|
+
@cache_default_values = opts[:cache] if opts.has_key?(:cache)
|
59
|
+
end
|
38
60
|
end
|
39
61
|
|
40
62
|
module ClassMethods
|
41
|
-
# The default values to
|
63
|
+
# The default values to use for this model. A hash with column symbol
|
42
64
|
# keys and default values. If the default values respond to +call+, it will be called
|
43
65
|
# to get the value, otherwise the value will be used directly. You can manually modify
|
44
66
|
# this hash to set specific default values, by default the ones will be parsed from the database.
|
45
67
|
attr_reader :default_values
|
46
|
-
|
68
|
+
|
47
69
|
Plugins.after_set_dataset(self, :set_default_values)
|
48
70
|
|
49
|
-
Plugins.inherited_instance_variables(self, :@default_values=>:dup)
|
71
|
+
Plugins.inherited_instance_variables(self, :@default_values=>:dup, :@cache_default_values=>nil)
|
50
72
|
|
73
|
+
# Whether default values should be cached in the values hash after being retrieved.
|
74
|
+
def cache_default_values?
|
75
|
+
@cache_default_values
|
76
|
+
end
|
77
|
+
|
51
78
|
# Freeze default values when freezing model class
|
52
79
|
def freeze
|
53
80
|
@default_values.freeze
|
@@ -59,7 +86,15 @@ module Sequel
|
|
59
86
|
# Parse the cached database schema for this model and set the default values appropriately.
|
60
87
|
def set_default_values
|
61
88
|
h = {}
|
62
|
-
|
89
|
+
if @db_schema
|
90
|
+
@db_schema.each do |k, v|
|
91
|
+
if v[:callable_default]
|
92
|
+
h[k] = v[:callable_default]
|
93
|
+
elsif !v[:ruby_default].nil?
|
94
|
+
h[k] = convert_default_value(v[:ruby_default])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
63
98
|
@default_values = h.merge!(@default_values || {})
|
64
99
|
end
|
65
100
|
|
@@ -82,7 +117,9 @@ module Sequel
|
|
82
117
|
def [](k)
|
83
118
|
if new? && !values.has_key?(k)
|
84
119
|
v = model.default_values[k]
|
85
|
-
v
|
120
|
+
v = v.call if v.respond_to?(:call)
|
121
|
+
values[k] = v if model.cache_default_values?
|
122
|
+
v
|
86
123
|
else
|
87
124
|
super
|
88
125
|
end
|
data/lib/sequel/plugins/dirty.rb
CHANGED
@@ -137,7 +137,7 @@ module Sequel
|
|
137
137
|
# name.gsub(/i/i, 'o')
|
138
138
|
# column_change(:name) # => ['Initial', 'onotoal']
|
139
139
|
def will_change_column(column)
|
140
|
-
|
140
|
+
_add_changed_column(column)
|
141
141
|
check_missing_initial_value(column)
|
142
142
|
|
143
143
|
value = if initial_values.has_key?(column)
|
@@ -186,7 +186,7 @@ module Sequel
|
|
186
186
|
initial = iv[column]
|
187
187
|
super
|
188
188
|
if value == initial
|
189
|
-
|
189
|
+
_changed_columns.delete(column) unless missing_initial_values.include?(column)
|
190
190
|
iv.delete(column)
|
191
191
|
end
|
192
192
|
else
|
@@ -58,13 +58,20 @@ module Sequel
|
|
58
58
|
# Detect which columns have been modified by comparing the cached hash
|
59
59
|
# value to the hash of the current value.
|
60
60
|
def changed_columns
|
61
|
-
|
62
|
-
changed = []
|
63
|
-
v = @values
|
61
|
+
changed = super
|
64
62
|
if vh = @values_hashes
|
65
|
-
|
63
|
+
values = @values
|
64
|
+
changed = changed.dup if frozen?
|
65
|
+
vh.each do |c, v|
|
66
|
+
match = values.has_key?(c) && v == values[c].hash
|
67
|
+
if changed.include?(c)
|
68
|
+
changed.delete(c) if match
|
69
|
+
else
|
70
|
+
changed << c unless match
|
71
|
+
end
|
72
|
+
end
|
66
73
|
end
|
67
|
-
|
74
|
+
changed
|
68
75
|
end
|
69
76
|
|
70
77
|
private
|
@@ -75,7 +75,8 @@ module Sequel
|
|
75
75
|
# it to be assigned.
|
76
76
|
def _save_update_all_columns_hash
|
77
77
|
v = @values.dup
|
78
|
-
|
78
|
+
cc = changed_columns
|
79
|
+
Array(primary_key).each{|x| v.delete(x) unless cc.include?(x)}
|
79
80
|
v.delete(model.lock_column)
|
80
81
|
v
|
81
82
|
end
|
@@ -155,8 +155,9 @@ module Sequel
|
|
155
155
|
end
|
156
156
|
end
|
157
157
|
define_method("#{column}=") do |v|
|
158
|
-
|
159
|
-
|
158
|
+
cc = changed_columns
|
159
|
+
if !cc.include?(column) && (new? || get_column_value(column) != v)
|
160
|
+
cc << column
|
160
161
|
|
161
162
|
will_change_column(column) if respond_to?(:will_change_column)
|
162
163
|
end
|
@@ -252,7 +252,8 @@ module Sequel
|
|
252
252
|
atts.each do |a|
|
253
253
|
arr = Array(a)
|
254
254
|
next if arr.any?{|x| errors.on(x)}
|
255
|
-
|
255
|
+
cc = changed_columns
|
256
|
+
next if opts.fetch(:only_if_modified, true) && !new? && !arr.any?{|x| cc.include?(x)}
|
256
257
|
ds = opts[:dataset] || model.dataset
|
257
258
|
ds = if where
|
258
259
|
where.call(ds, self, arr)
|
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 = 5
|
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
|
@@ -523,11 +523,6 @@ describe "A PostgreSQL dataset" do
|
|
523
523
|
@db[:atest].get(Sequel.extract(:year, :t)).must_equal 2010
|
524
524
|
end
|
525
525
|
|
526
|
-
it "should be able to parse the default value for an interval type" do
|
527
|
-
@db.create_table!(:atest){interval :t, :default=>'1 week'}
|
528
|
-
@db.schema(:atest).first.last[:ruby_default].must_equal '7 days'
|
529
|
-
end
|
530
|
-
|
531
526
|
it "should have #transaction support various types of synchronous options" do
|
532
527
|
@db.transaction(:synchronous=>:on){}
|
533
528
|
@db.transaction(:synchronous=>true){}
|
@@ -1877,6 +1872,11 @@ if uses_pg_or_jdbc && DB.server_version >= 90000
|
|
1877
1872
|
e.wrapped_exception.must_be_kind_of ArgumentError
|
1878
1873
|
e.message.must_include "foo"
|
1879
1874
|
end
|
1875
|
+
|
1876
|
+
it "should handle errors raised during row processing" do
|
1877
|
+
proc{@db.copy_table(@db[:test_copy].select(Sequel[1]/(Sequel[:x] - 3)))}.must_raise Sequel::DatabaseError
|
1878
|
+
@db.get(1).must_equal 1
|
1879
|
+
end
|
1880
1880
|
end
|
1881
1881
|
end
|
1882
1882
|
|
@@ -2362,6 +2362,19 @@ describe 'PostgreSQL array handling' do
|
|
2362
2362
|
c.where(:i=>o2.i, :f=>o2.f, :d=>o2.d, :t=>o2.t).all.must_equal [o]
|
2363
2363
|
end
|
2364
2364
|
|
2365
|
+
it 'with empty array default values and defaults_setter plugin' do
|
2366
|
+
@db.create_table!(:items) do
|
2367
|
+
column :n, 'integer[]', :default=>[]
|
2368
|
+
end
|
2369
|
+
c = Class.new(Sequel::Model(@db[:items]))
|
2370
|
+
c.plugin :defaults_setter, :cache=>true
|
2371
|
+
o = c.new
|
2372
|
+
o.n.class.must_equal(Sequel::Postgres::PGArray)
|
2373
|
+
o.n.to_a.must_be_same_as(o.n.to_a)
|
2374
|
+
o.n << 1
|
2375
|
+
o.save.n.must_equal [1]
|
2376
|
+
end
|
2377
|
+
|
2365
2378
|
it 'operations/functions with pg_array_ops' do
|
2366
2379
|
Sequel.extension :pg_array_ops
|
2367
2380
|
@db.create_table!(:items){column :i, 'integer[]'; column :i2, 'integer[]'; column :i3, 'integer[]'; column :i4, 'integer[]'; column :i5, 'integer[]'}
|
@@ -2599,6 +2612,19 @@ describe 'PostgreSQL hstore handling' do
|
|
2599
2612
|
c.filter(:mtm_items=>c.filter(:id=>o.id)).all.must_equal [o]
|
2600
2613
|
end
|
2601
2614
|
|
2615
|
+
it 'with empty hstore default values and defaults_setter plugin' do
|
2616
|
+
@db.create_table!(:items) do
|
2617
|
+
hstore :h, :default=>Sequel.hstore({})
|
2618
|
+
end
|
2619
|
+
c = Class.new(Sequel::Model(@db[:items]))
|
2620
|
+
c.plugin :defaults_setter, :cache=>true
|
2621
|
+
o = c.new
|
2622
|
+
o.h.class.must_equal(Sequel::Postgres::HStore)
|
2623
|
+
o.h.to_hash.must_be_same_as(o.h.to_hash)
|
2624
|
+
o.h['a'] = 'b'
|
2625
|
+
o.save.h.must_equal('a'=>'b')
|
2626
|
+
end
|
2627
|
+
|
2602
2628
|
it 'operations/functions with pg_hstore_ops' do
|
2603
2629
|
Sequel.extension :pg_hstore_ops, :pg_array_ops
|
2604
2630
|
@db.create_table!(:items){hstore :h1; hstore :h2; hstore :h3; String :t}
|
@@ -2695,11 +2721,10 @@ describe 'PostgreSQL json type' do
|
|
2695
2721
|
json_types.each do |json_type|
|
2696
2722
|
json_array_type = "#{json_type}[]"
|
2697
2723
|
pg_json = lambda{|v| Sequel.send(:"pg_#{json_type}", v)}
|
2724
|
+
hash_class = json_type == :jsonb ? Sequel::Postgres::JSONBHash : Sequel::Postgres::JSONHash
|
2725
|
+
array_class = json_type == :jsonb ? Sequel::Postgres::JSONBArray : Sequel::Postgres::JSONArray
|
2698
2726
|
|
2699
2727
|
it 'insert and retrieve json values' do
|
2700
|
-
hash_class = json_type == :jsonb ? Sequel::Postgres::JSONBHash : Sequel::Postgres::JSONHash
|
2701
|
-
array_class = json_type == :jsonb ? Sequel::Postgres::JSONBArray : Sequel::Postgres::JSONArray
|
2702
|
-
|
2703
2728
|
@db.create_table!(:items){column :j, json_type}
|
2704
2729
|
@ds.insert(pg_json.call(@h))
|
2705
2730
|
@ds.count.must_equal 1
|
@@ -2753,6 +2778,25 @@ describe 'PostgreSQL json type' do
|
|
2753
2778
|
c.create(:h=>pg_json.call(@a)).h.must_equal @a
|
2754
2779
|
end
|
2755
2780
|
|
2781
|
+
it 'with empty json default values and defaults_setter plugin' do
|
2782
|
+
@db.create_table!(:items) do
|
2783
|
+
column :h, json_type, :default=>hash_class.new({})
|
2784
|
+
column :a, json_type, :default=>array_class.new([])
|
2785
|
+
end
|
2786
|
+
c = Class.new(Sequel::Model(@db[:items]))
|
2787
|
+
c.plugin :defaults_setter, :cache=>true
|
2788
|
+
o = c.new
|
2789
|
+
o.h.class.must_equal(hash_class)
|
2790
|
+
o.a.class.must_equal(array_class)
|
2791
|
+
o.h.to_hash.must_be_same_as(o.h.to_hash)
|
2792
|
+
o.a.to_a.must_be_same_as(o.a.to_a)
|
2793
|
+
o.h['a'] = 'b'
|
2794
|
+
o.a << 1
|
2795
|
+
o.save
|
2796
|
+
o.h.must_equal('a'=>'b')
|
2797
|
+
o.a.must_equal([1])
|
2798
|
+
end
|
2799
|
+
|
2756
2800
|
it 'use json in bound variables' do
|
2757
2801
|
@db.create_table!(:items){column :i, json_type}
|
2758
2802
|
@ds.call(:insert, {:i=>pg_json.call(@h)}, {:i=>:$i})
|
@@ -2956,6 +3000,15 @@ describe 'PostgreSQL inet/cidr types' do
|
|
2956
3000
|
@ds.filter(:i=>:$i, :c=>:$c, :m=>:$m).call(:delete, :i=>[@ipv4], :c=>[@ipv4nm], :m=>['12:34:56:78:90:ab']).must_equal 1
|
2957
3001
|
end if uses_pg_or_jdbc
|
2958
3002
|
|
3003
|
+
it 'parse default values for schema' do
|
3004
|
+
@db.create_table!(:items) do
|
3005
|
+
inet :i, :default=>IPAddr.new('127.0.0.1')
|
3006
|
+
cidr :c, :default=>IPAddr.new('127.0.0.1')
|
3007
|
+
end
|
3008
|
+
@db.schema(:items)[0][1][:ruby_default].must_equal IPAddr.new('127.0.0.1')
|
3009
|
+
@db.schema(:items)[1][1][:ruby_default].must_equal IPAddr.new('127.0.0.1')
|
3010
|
+
end
|
3011
|
+
|
2959
3012
|
it 'with models' do
|
2960
3013
|
@db.create_table!(:items) do
|
2961
3014
|
primary_key :id
|
@@ -3113,6 +3166,15 @@ describe 'PostgreSQL range types' do
|
|
3113
3166
|
@ds.filter(h).call(:delete, @ra).must_equal 1
|
3114
3167
|
end if uses_pg_or_jdbc
|
3115
3168
|
|
3169
|
+
it 'parse default values for schema' do
|
3170
|
+
@db.create_table!(:items) do
|
3171
|
+
Integer :j
|
3172
|
+
int4range :i, :default=>1..4
|
3173
|
+
end
|
3174
|
+
@db.schema(:items)[0][1][:ruby_default].must_be_nil
|
3175
|
+
@db.schema(:items)[1][1][:ruby_default].must_equal Sequel::Postgres::PGRange.new(1, 5, :exclude_end=>true, :db_type=>'int4range')
|
3176
|
+
end
|
3177
|
+
|
3116
3178
|
it 'with models' do
|
3117
3179
|
@db.create_table!(:items){primary_key :id; int4range :i4; int8range :i8; numrange :n; daterange :d; tsrange :t; tstzrange :tz}
|
3118
3180
|
c = Class.new(Sequel::Model(@db[:items]))
|
@@ -3282,6 +3344,15 @@ describe 'PostgreSQL interval types' do
|
|
3282
3344
|
@ds.filter(:i=>:$i).call(:delete, :i=>[d]).must_equal 1
|
3283
3345
|
end if uses_pg_or_jdbc
|
3284
3346
|
|
3347
|
+
it 'parse default values for schema' do
|
3348
|
+
@db.create_table!(:items) do
|
3349
|
+
Integer :j
|
3350
|
+
interval :i, :default=>ActiveSupport::Duration.new(3*86400, :days=>3)
|
3351
|
+
end
|
3352
|
+
@db.schema(:items)[0][1][:ruby_default].must_be_nil
|
3353
|
+
@db.schema(:items)[1][1][:ruby_default].must_equal ActiveSupport::Duration.new(3*86400, :days=>3)
|
3354
|
+
end
|
3355
|
+
|
3285
3356
|
it 'with models' do
|
3286
3357
|
@db.create_table!(:items) do
|
3287
3358
|
primary_key :id
|
data/spec/core/schema_spec.rb
CHANGED
@@ -1619,6 +1619,16 @@ describe "Schema Parser" do
|
|
1619
1619
|
@db.schema(:x).wont_be_same_as(@db.schema(:x))
|
1620
1620
|
end
|
1621
1621
|
|
1622
|
+
it "should freeze string values in resulting hash" do
|
1623
|
+
@db.define_singleton_method(:schema_parse_table) do |t, opts|
|
1624
|
+
[[:a, {:oid=>1, :db_type=>'integer'.dup, :default=>"'a'".dup, :ruby_default=>'a'.dup}]]
|
1625
|
+
end
|
1626
|
+
c = @db.schema(:x)[0][1]
|
1627
|
+
c[:db_type].frozen?.must_equal true
|
1628
|
+
c[:default].frozen?.must_equal true
|
1629
|
+
c[:ruby_default].frozen?.must_equal true
|
1630
|
+
end
|
1631
|
+
|
1622
1632
|
it "should provide options if given a table name" do
|
1623
1633
|
c = nil
|
1624
1634
|
@db.define_singleton_method(:schema_parse_table) do |t, opts|
|
@@ -41,6 +41,15 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
41
41
|
(t - Time.now).must_be :<, 1
|
42
42
|
end
|
43
43
|
|
44
|
+
it "should handle :callable_default values in schema in preference to :ruby_default" do
|
45
|
+
@db.define_singleton_method(:schema) do |*|
|
46
|
+
[[:id, {:primary_key=>true}],
|
47
|
+
[:a, {:ruby_default => Time.now, :callable_default=>lambda{Date.today}, :primary_key=>false}]]
|
48
|
+
end
|
49
|
+
@c.dataset = @c.dataset
|
50
|
+
@c.new.a.must_equal Date.today
|
51
|
+
end
|
52
|
+
|
44
53
|
it "should handle Sequel::CURRENT_TIMESTAMP default by using the current DateTime if Sequel.datetime_class is DateTime" do
|
45
54
|
Sequel.datetime_class = DateTime
|
46
55
|
t = @pr.call(Sequel::CURRENT_TIMESTAMP).new.a
|
@@ -60,6 +69,15 @@ describe "Sequel::Plugins::DefaultsSetter" do
|
|
60
69
|
@db.sqls.must_equal ["INSERT INTO foo (a) VALUES (CURRENT_TIMESTAMP)", "SELECT * FROM foo WHERE id = 1"]
|
61
70
|
end
|
62
71
|
|
72
|
+
it "should cache default values if :cache plugin option is used" do
|
73
|
+
@c.plugin :defaults_setter, :cache => true
|
74
|
+
@c.default_values[:a] = 'a'
|
75
|
+
o = @c.new
|
76
|
+
o.a.must_equal 'a'
|
77
|
+
o.values[:a].must_equal 'a'
|
78
|
+
o.a.must_be_same_as(o.a)
|
79
|
+
end
|
80
|
+
|
63
81
|
it "should not override a given value" do
|
64
82
|
@pr.call(2)
|
65
83
|
@c.new('a'=>3).a.must_equal 3
|
@@ -11,6 +11,13 @@ describe "serialization_modification_detection plugin" do
|
|
11
11
|
@ds.db.sqls
|
12
12
|
end
|
13
13
|
|
14
|
+
it "should detect setting new column values on new objects" do
|
15
|
+
@o = @c.new
|
16
|
+
@o.changed_columns.must_equal []
|
17
|
+
@o.a = 'c'
|
18
|
+
@o.changed_columns.must_equal [:a]
|
19
|
+
end
|
20
|
+
|
14
21
|
it "should only detect columns that have been changed" do
|
15
22
|
@o.changed_columns.must_equal []
|
16
23
|
@o.a << 'b'
|
@@ -32,6 +39,12 @@ describe "serialization_modification_detection plugin" do
|
|
32
39
|
@o.changed_columns.must_equal []
|
33
40
|
end
|
34
41
|
|
42
|
+
it "should detect columns that have been changed on frozen objects" do
|
43
|
+
@o.freeze
|
44
|
+
@o.a << 'b'
|
45
|
+
@o.changed_columns.must_equal [:a]
|
46
|
+
end
|
47
|
+
|
35
48
|
it "should not list a column twice" do
|
36
49
|
@o.a = 'b'.dup
|
37
50
|
@o.a << 'a'
|
@@ -209,6 +209,17 @@ describe "pg_array extension" do
|
|
209
209
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :integer_array, :real_array, :decimal_array, :string_array]
|
210
210
|
end
|
211
211
|
|
212
|
+
it "should set :callable_default schema entries if default value is recognized" do
|
213
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer', :default=>'1'}, {:name=>'t', :db_type=>'text[]', :default=>"'{}'::text[]"}]
|
214
|
+
s = @db.schema(:items)
|
215
|
+
s[0][1][:callable_default].must_be_nil
|
216
|
+
v = s[1][1][:callable_default].call
|
217
|
+
Sequel::Postgres::PGArray.===(v).must_equal true
|
218
|
+
@db.literal(v).must_equal "'{}'::text[]"
|
219
|
+
v << 'a'
|
220
|
+
@db.literal(v).must_equal "ARRAY['a']::text[]"
|
221
|
+
end
|
222
|
+
|
212
223
|
it "should support typecasting of the various array types" do
|
213
224
|
{
|
214
225
|
:integer=>{:class=>Integer, :convert=>['1', 1, '1']},
|
@@ -186,6 +186,17 @@ describe "pg_hstore extension" do
|
|
186
186
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :hstore]
|
187
187
|
end
|
188
188
|
|
189
|
+
it "should set :callable_default schema entries if default value is recognized" do
|
190
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer', :default=>'1'}, {:name=>'t', :db_type=>'hstore', :default=>"''::hstore"}]
|
191
|
+
s = @db.schema(:items)
|
192
|
+
s[0][1][:callable_default].must_be_nil
|
193
|
+
v = s[1][1][:callable_default].call
|
194
|
+
Sequel::Postgres::HStore.===(v).must_equal true
|
195
|
+
@db.literal(v).must_equal "''::hstore"
|
196
|
+
v['a'] = 'b'
|
197
|
+
@db.literal(v).must_equal "'\"a\"=>\"b\"'::hstore"
|
198
|
+
end
|
199
|
+
|
189
200
|
it "should support typecasting for the hstore type" do
|
190
201
|
h = Sequel.hstore(1=>2)
|
191
202
|
@db.typecast_value(:hstore, h).object_id.must_equal(h.object_id)
|
@@ -51,6 +51,12 @@ describe "pg_inet extension" do
|
|
51
51
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :ipaddr, :ipaddr]
|
52
52
|
end
|
53
53
|
|
54
|
+
it "should set :ruby_default schema entries if default value is recognized" do
|
55
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer', :default=>'1'}, {:name=>'t', :db_type=>'inet', :default=>"'127.0.0.1'::inet"}]
|
56
|
+
s = @db.schema(:items)
|
57
|
+
s[1][1][:ruby_default].must_equal IPAddr.new('127.0.0.1')
|
58
|
+
end
|
59
|
+
|
54
60
|
it "should support typecasting for the ipaddr type" do
|
55
61
|
ip = IPAddr.new('127.0.0.1')
|
56
62
|
@db.typecast_value(:ipaddr, ip).must_be_same_as(ip)
|
@@ -66,6 +66,12 @@ describe "pg_interval extension" do
|
|
66
66
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :interval]
|
67
67
|
end
|
68
68
|
|
69
|
+
it "should set :ruby_default schema entries if default value is recognized" do
|
70
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer', :default=>'1'}, {:name=>'t', :db_type=>'interval', :default=>"'3 days'::interval"}]
|
71
|
+
s = @db.schema(:items)
|
72
|
+
s[1][1][:ruby_default].must_equal ActiveSupport::Duration.new(3*86400, :days=>3)
|
73
|
+
end
|
74
|
+
|
69
75
|
it "should support typecasting for the interval type" do
|
70
76
|
d = ActiveSupport::Duration.new(31557600 + 2*86400*30 + 3*86400*7 + 4*86400 + 5*3600 + 6*60 + 7, [[:years, 1], [:months, 2], [:days, 25], [:seconds, 18367]])
|
71
77
|
@db.typecast_value(:interval, d).object_id.must_equal d.object_id
|
@@ -183,6 +183,35 @@ describe "pg_json extension" do
|
|
183
183
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :jsonb]
|
184
184
|
end
|
185
185
|
|
186
|
+
it "should set :callable_default schema entries if default value is recognized" do
|
187
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer', :default=>'1'}, {:name=>'jh', :db_type=>'json', :default=>"'{}'::json"}, {:name=>'ja', :db_type=>'json', :default=>"'[]'::json"}, {:name=>'jbh', :db_type=>'jsonb', :default=>"'{}'::jsonb"}, {:name=>'jba', :db_type=>'jsonb', :default=>"'[]'::jsonb"}]
|
188
|
+
s = @db.schema(:items)
|
189
|
+
s[0][1][:callable_default].must_be_nil
|
190
|
+
v = s[1][1][:callable_default].call
|
191
|
+
Sequel::Postgres::JSONHash.===(v).must_equal true
|
192
|
+
@db.literal(v).must_equal "'{}'::json"
|
193
|
+
v['a'] = 'b'
|
194
|
+
@db.literal(v).must_equal "'{\"a\":\"b\"}'::json"
|
195
|
+
|
196
|
+
v = s[2][1][:callable_default].call
|
197
|
+
Sequel::Postgres::JSONArray.===(v).must_equal true
|
198
|
+
@db.literal(v).must_equal "'[]'::json"
|
199
|
+
v << 1
|
200
|
+
@db.literal(v).must_equal "'[1]'::json"
|
201
|
+
|
202
|
+
v = s[3][1][:callable_default].call
|
203
|
+
Sequel::Postgres::JSONBHash.===(v).must_equal true
|
204
|
+
@db.literal(v).must_equal "'{}'::jsonb"
|
205
|
+
v['a'] = 'b'
|
206
|
+
@db.literal(v).must_equal "'{\"a\":\"b\"}'::jsonb"
|
207
|
+
|
208
|
+
v = s[4][1][:callable_default].call
|
209
|
+
Sequel::Postgres::JSONBArray.===(v).must_equal true
|
210
|
+
@db.literal(v).must_equal "'[]'::jsonb"
|
211
|
+
v << 1
|
212
|
+
@db.literal(v).must_equal "'[1]'::jsonb"
|
213
|
+
end
|
214
|
+
|
186
215
|
it "should support typecasting for the json type" do
|
187
216
|
h = Sequel.pg_json(1=>2)
|
188
217
|
a = Sequel.pg_json([1])
|
@@ -93,6 +93,12 @@ describe "pg_range extension" do
|
|
93
93
|
@db.schema(:items).map{|e| e[1][:type]}.must_equal [:integer, :int4range_array, :int8range_array, :numrange_array, :daterange_array, :tsrange_array, :tstzrange_array]
|
94
94
|
end
|
95
95
|
|
96
|
+
it "should set :ruby_default schema entries if default value is recognized" do
|
97
|
+
@db.fetch = [{:name=>'id', :db_type=>'integer', :default=>'1'}, {:oid=>3904, :name=>'t', :db_type=>'int4range', :default=>"'[1,5)'::int4range"}]
|
98
|
+
s = @db.schema(:items)
|
99
|
+
s[1][1][:ruby_default].must_equal Sequel::Postgres::PGRange.new(1, 5, :exclude_end=>true, :db_type=>'int4range')
|
100
|
+
end
|
101
|
+
|
96
102
|
describe "database typecasting" do
|
97
103
|
before do
|
98
104
|
@o = @R.new(1, 2, :db_type=>'int4range')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -255,6 +255,7 @@ extra_rdoc_files:
|
|
255
255
|
- doc/release_notes/5.2.0.txt
|
256
256
|
- doc/release_notes/5.3.0.txt
|
257
257
|
- doc/release_notes/5.4.0.txt
|
258
|
+
- doc/release_notes/5.5.0.txt
|
258
259
|
files:
|
259
260
|
- CHANGELOG
|
260
261
|
- MIT-LICENSE
|
@@ -404,6 +405,7 @@ files:
|
|
404
405
|
- doc/release_notes/5.2.0.txt
|
405
406
|
- doc/release_notes/5.3.0.txt
|
406
407
|
- doc/release_notes/5.4.0.txt
|
408
|
+
- doc/release_notes/5.5.0.txt
|
407
409
|
- doc/schema_modification.rdoc
|
408
410
|
- doc/security.rdoc
|
409
411
|
- doc/sharding.rdoc
|