sequel 4.3.0 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +34 -0
- data/README.rdoc +7 -7
- data/Rakefile +2 -2
- data/doc/active_record.rdoc +2 -2
- data/doc/association_basics.rdoc +21 -7
- data/doc/bin_sequel.rdoc +2 -2
- data/doc/cheat_sheet.rdoc +2 -1
- data/doc/dataset_basics.rdoc +1 -1
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/migration.rdoc +2 -2
- data/doc/object_model.rdoc +2 -2
- data/doc/opening_databases.rdoc +13 -1
- data/doc/querying.rdoc +9 -4
- data/doc/release_notes/4.4.0.txt +92 -0
- data/doc/schema_modification.rdoc +1 -1
- data/doc/security.rdoc +2 -2
- data/doc/sql.rdoc +3 -3
- data/doc/thread_safety.rdoc +1 -1
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/jdbc.rb +85 -19
- data/lib/sequel/adapters/jdbc/db2.rb +1 -1
- data/lib/sequel/adapters/jdbc/derby.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +2 -2
- data/lib/sequel/adapters/jdbc/hsqldb.rb +7 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +34 -3
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +57 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +2 -2
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/shared/db2.rb +5 -0
- data/lib/sequel/adapters/shared/oracle.rb +41 -4
- data/lib/sequel/adapters/shared/sqlanywhere.rb +458 -0
- data/lib/sequel/adapters/sqlanywhere.rb +177 -0
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +11 -3
- data/lib/sequel/core.rb +4 -4
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +2 -2
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/dataset/actions.rb +2 -0
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +37 -16
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/date_arithmetic.rb +2 -2
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +5 -4
- data/lib/sequel/extensions/pg_array.rb +2 -2
- data/lib/sequel/extensions/pg_array_ops.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +2 -2
- data/lib/sequel/extensions/pg_hstore_ops.rb +2 -2
- data/lib/sequel/extensions/pg_json.rb +2 -2
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +2 -2
- data/lib/sequel/extensions/pg_range_ops.rb +2 -2
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/pg_row_ops.rb +3 -3
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +106 -17
- data/lib/sequel/model/base.rb +23 -19
- data/lib/sequel/plugins/json_serializer.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +14 -6
- data/lib/sequel/plugins/pg_array_associations.rb +28 -0
- data/lib/sequel/plugins/rcte_tree.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +11 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/table_select.rb +41 -0
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/sql.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/oracle_spec.rb +22 -1
- data/spec/adapters/postgres_spec.rb +31 -48
- data/spec/adapters/sqlanywhere_spec.rb +170 -0
- data/spec/core/dataset_spec.rb +109 -0
- data/spec/core/object_graph_spec.rb +7 -0
- data/spec/extensions/constraint_validations_spec.rb +7 -0
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +65 -0
- data/spec/extensions/pg_array_associations_spec.rb +44 -0
- data/spec/extensions/rcte_tree_spec.rb +3 -3
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/extensions/table_select_spec.rb +71 -0
- data/spec/integration/associations_test.rb +279 -7
- data/spec/integration/dataset_test.rb +13 -4
- data/spec/integration/schema_test.rb +12 -14
- data/spec/model/associations_spec.rb +472 -3
- data/spec/model/class_dataset_methods_spec.rb +1 -0
- data/spec/model/model_spec.rb +10 -0
- metadata +10 -2
@@ -293,7 +293,7 @@ module Sequel
|
|
293
293
|
|
294
294
|
module DatasetMethods
|
295
295
|
# Return a JSON string representing an array of all objects in
|
296
|
-
# this dataset. Takes the same options as the
|
296
|
+
# this dataset. Takes the same options as the instance
|
297
297
|
# method, and passes them to every instance. Additionally,
|
298
298
|
# respects the following options:
|
299
299
|
#
|
@@ -138,6 +138,13 @@ module Sequel
|
|
138
138
|
h.each{|k, v| cached_set(k, v)}
|
139
139
|
h
|
140
140
|
end
|
141
|
+
|
142
|
+
def filter_by_associations_add_conditions_dataset_filter(ds)
|
143
|
+
reverse_edges.each{|t| ds = ds.join(t[:table], Array(t[:left]).zip(Array(t[:right])), :table_alias=>t[:alias], :qualify=>:deep)}
|
144
|
+
ft = final_reverse_edge
|
145
|
+
ds.join(ft[:table], Array(ft[:left]).zip(Array(ft[:right])), :table_alias=>ft[:alias], :qualify=>:deep).
|
146
|
+
select(*qualify(ft[:alias], Array(self[:left_key])))
|
147
|
+
end
|
141
148
|
end
|
142
149
|
|
143
150
|
module ClassMethods
|
@@ -275,13 +282,14 @@ module Sequel
|
|
275
282
|
ref.right_primary_key_methods
|
276
283
|
end
|
277
284
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
association_filter_handle_inversion(op, SQL::BooleanExpression.from_value_pairs(lpks=>ds), Array(lpks))
|
285
|
+
expr = association_filter_key_expression(ref.qualify(last_alias, Array(ref.final_edge[:left])), meths, obj)
|
286
|
+
unless expr == SQL::Constants::FALSE
|
287
|
+
ds = ds.where(expr).exclude(SQL::BooleanExpression.from_value_pairs(ds.opts[:select].zip([]), :OR))
|
288
|
+
expr = SQL::BooleanExpression.from_value_pairs(lpks=>ds)
|
289
|
+
expr = add_association_filter_conditions(ref, obj, expr)
|
284
290
|
end
|
291
|
+
|
292
|
+
association_filter_handle_inversion(op, expr, Array(lpks))
|
285
293
|
end
|
286
294
|
end
|
287
295
|
end
|
@@ -67,6 +67,9 @@ module Sequel
|
|
67
67
|
# This plugin should work on all supported PostgreSQL versions, except
|
68
68
|
# the remove_all modification method for many_to_pg_array associations, which
|
69
69
|
# requires the array_remove method added in PostgreSQL 9.3.
|
70
|
+
#
|
71
|
+
# This plugin requires that the underlying database have the pg_array
|
72
|
+
# extension loaded.
|
70
73
|
module PgArrayAssociations
|
71
74
|
# The AssociationReflection subclass for many_to_pg_array associations.
|
72
75
|
class ManyToPgArrayAssociationReflection < Sequel::Model::Associations::AssociationReflection
|
@@ -109,6 +112,15 @@ module Sequel
|
|
109
112
|
|
110
113
|
private
|
111
114
|
|
115
|
+
def filter_by_associations_add_conditions_dataset_filter(ds)
|
116
|
+
key = qualify(associated_class.table_name, self[:key])
|
117
|
+
ds.select{unnest(key)}.exclude(key=>nil)
|
118
|
+
end
|
119
|
+
|
120
|
+
def filter_by_associations_conditions_key
|
121
|
+
qualify(self[:model].table_name, primary_key)
|
122
|
+
end
|
123
|
+
|
112
124
|
# Only consider an association as a reciprocal if it has matching keys
|
113
125
|
# and primary keys.
|
114
126
|
def reciprocal_association?(assoc_reflect)
|
@@ -162,8 +174,22 @@ module Sequel
|
|
162
174
|
cached_fetch(:primary_key_method){primary_key}
|
163
175
|
end
|
164
176
|
|
177
|
+
def filter_by_associations_conditions_expression(obj)
|
178
|
+
ds = filter_by_associations_conditions_dataset.where(filter_by_associations_conditions_subquery_conditions(obj))
|
179
|
+
Sequel.function(:coalesce, Sequel.pg_array(filter_by_associations_conditions_key).overlaps(ds), Sequel::SQL::Constants::FALSE)
|
180
|
+
end
|
181
|
+
|
165
182
|
private
|
166
183
|
|
184
|
+
def filter_by_associations_add_conditions_dataset_filter(ds)
|
185
|
+
pk = qualify(associated_class.table_name, primary_key)
|
186
|
+
ds.select{array_agg(pk)}.exclude(pk=>nil)
|
187
|
+
end
|
188
|
+
|
189
|
+
def filter_by_associations_conditions_key
|
190
|
+
qualify(self[:model].table_name, self[:key])
|
191
|
+
end
|
192
|
+
|
167
193
|
# Only consider an association as a reciprocal if it has matching keys
|
168
194
|
# and primary keys.
|
169
195
|
def reciprocal_association?(assoc_reflect)
|
@@ -426,6 +452,7 @@ module Sequel
|
|
426
452
|
Sequel.expr(pk=>obj.select{Sequel.pg_array_op(ref.qualify(obj.model.table_name, ref[:key_column])).unnest})
|
427
453
|
end
|
428
454
|
expr = Sequel::SQL::Constants::FALSE unless expr
|
455
|
+
expr = add_association_filter_conditions(ref, obj, expr)
|
429
456
|
association_filter_handle_inversion(op, expr, [pk])
|
430
457
|
end
|
431
458
|
|
@@ -445,6 +472,7 @@ module Sequel
|
|
445
472
|
Sequel.function(:coalesce, Sequel.pg_array_op(key).overlaps(obj.select{array_agg(ref.qualify(obj.model.table_name, ref.primary_key))}), Sequel::SQL::Constants::FALSE)
|
446
473
|
end
|
447
474
|
expr = Sequel::SQL::Constants::FALSE unless expr
|
475
|
+
expr = add_association_filter_conditions(ref, obj, expr)
|
448
476
|
association_filter_handle_inversion(op, expr, [key])
|
449
477
|
end
|
450
478
|
end
|
@@ -304,7 +304,7 @@ module Sequel
|
|
304
304
|
level = associations
|
305
305
|
no_cache_level = level - 1
|
306
306
|
associations = {}
|
307
|
-
base_case = base_case.select_more(SQL::AliasedExpression.new(0, la))
|
307
|
+
base_case = base_case.select_more(SQL::AliasedExpression.new(Sequel.cast(0, Integer), la))
|
308
308
|
recursive_case = recursive_case.select_more(SQL::AliasedExpression.new(SQL::QualifiedIdentifier.new(t, la) + 1, la)).filter(SQL::QualifiedIdentifier.new(t, la) < level - 1)
|
309
309
|
end
|
310
310
|
table_alias = model.dataset.schema_and_table(model.table_name)[1].to_sym
|
@@ -56,6 +56,17 @@ module Sequel
|
|
56
56
|
# user = User.create
|
57
57
|
# user.permissions = { :global => 'read-only' }
|
58
58
|
# user.save
|
59
|
+
#
|
60
|
+
# Note that if you mutate serialized column values without reassigning them,
|
61
|
+
# those changes won't be picked up by <tt>Model#save_changes</tt> or
|
62
|
+
# <tt>Model#update</tt>. Example:
|
63
|
+
#
|
64
|
+
# user = User[1]
|
65
|
+
# user.permissions[:global] = 'foo'
|
66
|
+
# user.save_changes # Will not pick up changes to permissions
|
67
|
+
#
|
68
|
+
# You can use the +serialization_modification_detection+ plugin to pick
|
69
|
+
# up such changes.
|
59
70
|
module Serialization
|
60
71
|
# The default serializers supported by the serialization module.
|
61
72
|
# Use register_format to add serializers to this hash.
|
@@ -126,7 +126,7 @@ module Sequel
|
|
126
126
|
attr_reader :sti_key_array
|
127
127
|
|
128
128
|
# A hash/proc with class keys and column value values, mapping
|
129
|
-
# the
|
129
|
+
# the class to a particular value given to the sti_key column.
|
130
130
|
# Used to set the column value when creating objects, and for the
|
131
131
|
# filter when retrieving objects in subclasses.
|
132
132
|
attr_reader :sti_key_map
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
|
+
# The table_select plugin changes the default selection for a
|
4
|
+
# model dataset from <tt>*</tt> to <tt>table.*</tt>.
|
5
|
+
# This makes it so that if you join the model's dataset to
|
6
|
+
# other tables, columns in the other tables do not appear
|
7
|
+
# in the result sets (and possibly overwrite columns in the
|
8
|
+
# current model with the same name).
|
9
|
+
#
|
10
|
+
# Usage:
|
11
|
+
#
|
12
|
+
# # Make all model subclasses select table.*
|
13
|
+
# Sequel::Model.plugin :table_select
|
14
|
+
#
|
15
|
+
# # Make the Album class select albums.*
|
16
|
+
# Album.plugin :table_select
|
17
|
+
module TableSelect
|
18
|
+
# Modify the current model's dataset selection, if the model
|
19
|
+
# has a dataset.
|
20
|
+
def self.configure(model)
|
21
|
+
model.instance_eval do
|
22
|
+
self.dataset = dataset if @dataset
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
private
|
28
|
+
|
29
|
+
# If the underlying dataset selects from a single table and
|
30
|
+
# has no explicit selection, select table.* from that table.
|
31
|
+
def convert_input_dataset(ds)
|
32
|
+
ds = super
|
33
|
+
if !ds.opts[:select] && (from = ds.opts[:from]) && from.length == 1 && !ds.opts[:join]
|
34
|
+
ds = ds.select_all(ds.first_source)
|
35
|
+
end
|
36
|
+
ds
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/sequel/plugins/tree.rb
CHANGED
data/lib/sequel/sql.rb
CHANGED
@@ -1477,7 +1477,7 @@ module Sequel
|
|
1477
1477
|
end
|
1478
1478
|
|
1479
1479
|
# Create a new +Subscript+ appending the given subscript(s)
|
1480
|
-
#
|
1480
|
+
# to the current array of subscripts.
|
1481
1481
|
#
|
1482
1482
|
# :a.sql_subscript(2) # a[2]
|
1483
1483
|
# :a.sql_subscript(2) | 1 # a[2, 1]
|
@@ -1582,7 +1582,7 @@ module Sequel
|
|
1582
1582
|
# # Literal Strings
|
1583
1583
|
# ds.filter{{a=>`some SQL`}} # SELECT * FROM t WHERE (a = some SQL)
|
1584
1584
|
#
|
1585
|
-
# For a more detailed explanation, see the {Virtual Rows guide}[
|
1585
|
+
# For a more detailed explanation, see the {Virtual Rows guide}[rdoc-ref:doc/virtual_rows.rdoc].
|
1586
1586
|
class VirtualRow < BasicObject
|
1587
1587
|
WILDCARD = LiteralString.new('*').freeze
|
1588
1588
|
QUESTION_MARK = LiteralString.new('?').freeze
|
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 = 4
|
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
|
@@ -21,13 +21,34 @@ describe "An Oracle database" do
|
|
21
21
|
Integer :id
|
22
22
|
String :cat_name, :size => 50
|
23
23
|
end
|
24
|
+
|
25
|
+
DB.create_table!(:notes) do
|
26
|
+
Integer :id
|
27
|
+
String :title, :size => 50
|
28
|
+
String :content, :text => true
|
29
|
+
end
|
24
30
|
@d = DB[:items]
|
25
31
|
end
|
26
32
|
after do
|
27
33
|
@d.delete
|
28
34
|
end
|
29
35
|
after(:all) do
|
30
|
-
DB.drop_table?(:items, :books, :categories)
|
36
|
+
DB.drop_table?(:items, :books, :categories, :notes)
|
37
|
+
end
|
38
|
+
|
39
|
+
specify "should allow limit and offset with clob columns" do
|
40
|
+
notes = []
|
41
|
+
notes << {:id => 1, :title => 'abc', :content => 'zyx'}
|
42
|
+
notes << {:id => 2, :title => 'def', :content => 'wvu'}
|
43
|
+
notes << {:id => 3, :title => 'ghi', :content => 'tsr'}
|
44
|
+
notes << {:id => 4, :title => 'jkl', :content => 'qpo'}
|
45
|
+
notes << {:id => 5, :title => 'mno', :content => 'nml'}
|
46
|
+
DB[:notes].multi_insert(notes)
|
47
|
+
|
48
|
+
DB[:notes].sort_by{|x| x[:id]}.should == notes
|
49
|
+
rows = DB[:notes].limit(3, 0).all
|
50
|
+
rows.length.should == 3
|
51
|
+
rows.all?{|v| notes.should include(v)}
|
31
52
|
end
|
32
53
|
|
33
54
|
specify "should provide disconnect functionality" do
|
@@ -1763,8 +1763,7 @@ describe 'PostgreSQL array handling' do
|
|
1763
1763
|
@db = DB
|
1764
1764
|
@db.extension :pg_array
|
1765
1765
|
@ds = @db[:items]
|
1766
|
-
@native = DB.adapter_scheme == :postgres
|
1767
|
-
@jdbc = DB.adapter_scheme == :jdbc
|
1766
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
1768
1767
|
@tp = lambda{@db.schema(:items).map{|a| a.last[:type]}}
|
1769
1768
|
end
|
1770
1769
|
after do
|
@@ -1783,10 +1782,8 @@ describe 'PostgreSQL array handling' do
|
|
1783
1782
|
@ds.insert(Sequel.pg_array([1], :int2), Sequel.pg_array([nil, 2], :int4), Sequel.pg_array([3, nil], :int8), Sequel.pg_array([4, nil, 4.5], :real), Sequel.pg_array([5, nil, 5.5], "double precision"))
|
1784
1783
|
@ds.count.should == 1
|
1785
1784
|
rs = @ds.all
|
1786
|
-
if @jdbc || @native
|
1787
|
-
rs.should == [{:i2=>[1], :i4=>[nil, 2], :i8=>[3, nil], :r=>[4.0, nil, 4.5], :dp=>[5.0, nil, 5.5]}]
|
1788
|
-
end
|
1789
1785
|
if @native
|
1786
|
+
rs.should == [{:i2=>[1], :i4=>[nil, 2], :i8=>[3, nil], :r=>[4.0, nil, 4.5], :dp=>[5.0, nil, 5.5]}]
|
1790
1787
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1791
1788
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1792
1789
|
@ds.delete
|
@@ -1798,10 +1795,8 @@ describe 'PostgreSQL array handling' do
|
|
1798
1795
|
@ds.insert(Sequel.pg_array([[1], [2]], :int2), Sequel.pg_array([[nil, 2], [3, 4]], :int4), Sequel.pg_array([[3, nil], [nil, nil]], :int8), Sequel.pg_array([[4, nil], [nil, 4.5]], :real), Sequel.pg_array([[5, nil], [nil, 5.5]], "double precision"))
|
1799
1796
|
|
1800
1797
|
rs = @ds.all
|
1801
|
-
if @jdbc || @native
|
1802
|
-
rs.should == [{:i2=>[[1], [2]], :i4=>[[nil, 2], [3, 4]], :i8=>[[3, nil], [nil, nil]], :r=>[[4, nil], [nil, 4.5]], :dp=>[[5, nil], [nil, 5.5]]}]
|
1803
|
-
end
|
1804
1798
|
if @native
|
1799
|
+
rs.should == [{:i2=>[[1], [2]], :i4=>[[nil, 2], [3, 4]], :i8=>[[3, nil], [nil, nil]], :r=>[[4, nil], [nil, 4.5]], :dp=>[[5, nil], [nil, 5.5]]}]
|
1805
1800
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1806
1801
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1807
1802
|
@ds.delete
|
@@ -1818,10 +1813,8 @@ describe 'PostgreSQL array handling' do
|
|
1818
1813
|
@ds.insert(Sequel.pg_array([BigDecimal.new('1.000000000000000000001'), nil, BigDecimal.new('1')], :numeric))
|
1819
1814
|
@ds.count.should == 1
|
1820
1815
|
rs = @ds.all
|
1821
|
-
if @jdbc || @native
|
1822
|
-
rs.should == [{:n=>[BigDecimal.new('1.000000000000000000001'), nil, BigDecimal.new('1')]}]
|
1823
|
-
end
|
1824
1816
|
if @native
|
1817
|
+
rs.should == [{:n=>[BigDecimal.new('1.000000000000000000001'), nil, BigDecimal.new('1')]}]
|
1825
1818
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1826
1819
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1827
1820
|
@ds.delete
|
@@ -1832,10 +1825,8 @@ describe 'PostgreSQL array handling' do
|
|
1832
1825
|
@ds.delete
|
1833
1826
|
@ds.insert(Sequel.pg_array([[BigDecimal.new('1.0000000000000000000000000000001'), nil], [nil, BigDecimal.new('1')]], :numeric))
|
1834
1827
|
rs = @ds.all
|
1835
|
-
if @jdbc || @native
|
1836
|
-
rs.should == [{:n=>[[BigDecimal.new('1.0000000000000000000000000000001'), nil], [nil, BigDecimal.new('1')]]}]
|
1837
|
-
end
|
1838
1828
|
if @native
|
1829
|
+
rs.should == [{:n=>[[BigDecimal.new('1.0000000000000000000000000000001'), nil], [nil, BigDecimal.new('1')]]}]
|
1839
1830
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1840
1831
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1841
1832
|
@ds.delete
|
@@ -1854,10 +1845,8 @@ describe 'PostgreSQL array handling' do
|
|
1854
1845
|
@ds.insert(Sequel.pg_array(['a', nil, 'NULL', 'b"\'c'], 'char(4)'), Sequel.pg_array(['a', nil, 'NULL', 'b"\'c'], :varchar), Sequel.pg_array(['a', nil, 'NULL', 'b"\'c'], :text))
|
1855
1846
|
@ds.count.should == 1
|
1856
1847
|
rs = @ds.all
|
1857
|
-
if @jdbc || @native
|
1858
|
-
rs.should == [{:c=>['a ', nil, 'NULL', 'b"\'c'], :vc=>['a', nil, 'NULL', 'b"\'c'], :t=>['a', nil, 'NULL', 'b"\'c']}]
|
1859
|
-
end
|
1860
1848
|
if @native
|
1849
|
+
rs.should == [{:c=>['a ', nil, 'NULL', 'b"\'c'], :vc=>['a', nil, 'NULL', 'b"\'c'], :t=>['a', nil, 'NULL', 'b"\'c']}]
|
1861
1850
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1862
1851
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1863
1852
|
@ds.delete
|
@@ -1868,10 +1857,8 @@ describe 'PostgreSQL array handling' do
|
|
1868
1857
|
@ds.delete
|
1869
1858
|
@ds.insert(Sequel.pg_array([[['a'], [nil]], [['NULL'], ['b"\'c']]], 'char(4)'), Sequel.pg_array([[['a'], ['']], [['NULL'], ['b"\'c']]], :varchar), Sequel.pg_array([[['a'], [nil]], [['NULL'], ['b"\'c']]], :text))
|
1870
1859
|
rs = @ds.all
|
1871
|
-
if @jdbc || @native
|
1872
|
-
rs.should == [{:c=>[[['a '], [nil]], [['NULL'], ['b"\'c']]], :vc=>[[['a'], ['']], [['NULL'], ['b"\'c']]], :t=>[[['a'], [nil]], [['NULL'], ['b"\'c']]]}]
|
1873
|
-
end
|
1874
1860
|
if @native
|
1861
|
+
rs.should == [{:c=>[[['a '], [nil]], [['NULL'], ['b"\'c']]], :vc=>[[['a'], ['']], [['NULL'], ['b"\'c']]], :t=>[[['a'], [nil]], [['NULL'], ['b"\'c']]]}]
|
1875
1862
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1876
1863
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1877
1864
|
@ds.delete
|
@@ -1897,10 +1884,8 @@ describe 'PostgreSQL array handling' do
|
|
1897
1884
|
@ds.insert(Sequel.pg_array([true, false], :bool), Sequel.pg_array([d, nil], :date), Sequel.pg_array([t, nil], :time), Sequel.pg_array([ts, nil], :timestamp), Sequel.pg_array([ts, nil], :timestamptz))
|
1898
1885
|
@ds.count.should == 1
|
1899
1886
|
rs = @ds.all
|
1900
|
-
if @jdbc || @native
|
1901
|
-
rs.should == [{:b=>[true, false], :d=>[d, nil], :t=>[t, nil], :ts=>[ts, nil], :tstz=>[ts, nil]}]
|
1902
|
-
end
|
1903
1887
|
if @native
|
1888
|
+
rs.should == [{:b=>[true, false], :d=>[d, nil], :t=>[t, nil], :ts=>[ts, nil], :tstz=>[ts, nil]}]
|
1904
1889
|
rs.first.values.each{|v| v.should_not be_a_kind_of(Array)}
|
1905
1890
|
rs.first.values.each{|v| v.to_a.should be_a_kind_of(Array)}
|
1906
1891
|
@ds.delete
|
@@ -1978,7 +1963,7 @@ describe 'PostgreSQL array handling' do
|
|
1978
1963
|
@ds.insert(rs.first)
|
1979
1964
|
@ds.all.should == rs
|
1980
1965
|
end
|
1981
|
-
end
|
1966
|
+
end
|
1982
1967
|
|
1983
1968
|
specify 'use arrays in bound variables' do
|
1984
1969
|
@db.create_table!(:items) do
|
@@ -2137,7 +2122,7 @@ describe 'PostgreSQL hstore handling' do
|
|
2137
2122
|
@db.extension :pg_array, :pg_hstore
|
2138
2123
|
@ds = @db[:items]
|
2139
2124
|
@h = {'a'=>'b', 'c'=>nil, 'd'=>'NULL', 'e'=>'\\\\" \\\' ,=>'}
|
2140
|
-
@native = DB.adapter_scheme == :postgres
|
2125
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2141
2126
|
end
|
2142
2127
|
after do
|
2143
2128
|
@db.drop_table?(:items)
|
@@ -2152,6 +2137,7 @@ describe 'PostgreSQL hstore handling' do
|
|
2152
2137
|
if @native
|
2153
2138
|
rs = @ds.all
|
2154
2139
|
v = rs.first[:h]
|
2140
|
+
v.should == @h
|
2155
2141
|
v.should_not be_a_kind_of(Hash)
|
2156
2142
|
v.to_hash.should be_a_kind_of(Hash)
|
2157
2143
|
v.to_hash.should == @h
|
@@ -2387,7 +2373,7 @@ describe 'PostgreSQL json type' do
|
|
2387
2373
|
@ds = @db[:items]
|
2388
2374
|
@a = [1, 2, {'a'=>'b'}, 3.0]
|
2389
2375
|
@h = {'a'=>'b', '1'=>[3, 4, 5]}
|
2390
|
-
@native = DB.adapter_scheme == :postgres
|
2376
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2391
2377
|
end
|
2392
2378
|
after do
|
2393
2379
|
@db.drop_table?(:items)
|
@@ -2519,7 +2505,7 @@ describe 'PostgreSQL json type' do
|
|
2519
2505
|
j = Sequel.pg_json([{'a'=>1, 'b'=>'c'}, {'a'=>2, 'b'=>'d'}]).op
|
2520
2506
|
@db.from(j.populate_set(Sequel.cast(nil, :items))).select_order_map(:a).should == [1, 2]
|
2521
2507
|
@db.from(j.populate_set(Sequel.cast(nil, :items))).select_order_map(:b).should == %w'c d'
|
2522
|
-
end if DB.server_version >= 90300 && DB.adapter_scheme == :postgres
|
2508
|
+
end if DB.server_version >= 90300 && (DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc)
|
2523
2509
|
end if DB.server_version >= 90200
|
2524
2510
|
|
2525
2511
|
describe 'PostgreSQL inet/cidr types' do
|
@@ -2539,7 +2525,7 @@ describe 'PostgreSQL inet/cidr types' do
|
|
2539
2525
|
@ipv6 = IPAddr.new(@v6)
|
2540
2526
|
@ipv6nm = IPAddr.new(@v6nm)
|
2541
2527
|
end
|
2542
|
-
@native = DB.adapter_scheme == :postgres
|
2528
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2543
2529
|
end
|
2544
2530
|
after do
|
2545
2531
|
@db.drop_table?(:items)
|
@@ -2650,7 +2636,7 @@ describe 'PostgreSQL range types' do
|
|
2650
2636
|
@r.each{|k, v| @ra[k] = Sequel.pg_array([v], @map[k])}
|
2651
2637
|
@r.each{|k, v| @pgr[k] = Sequel.pg_range(v)}
|
2652
2638
|
@r.each{|k, v| @pgra[k] = Sequel.pg_array([Sequel.pg_range(v)], @map[k])}
|
2653
|
-
@native = DB.adapter_scheme == :postgres
|
2639
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2654
2640
|
end
|
2655
2641
|
after do
|
2656
2642
|
@db.drop_table?(:items)
|
@@ -2732,14 +2718,12 @@ describe 'PostgreSQL range types' do
|
|
2732
2718
|
v.delete(:id)
|
2733
2719
|
v.should == @r
|
2734
2720
|
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
v.each{|k,v1| v1.should == @ra[k].to_a}
|
2742
|
-
end
|
2721
|
+
@db.create_table!(:items){primary_key :id; column :i4, 'int4range[]'; column :i8, 'int8range[]'; column :n, 'numrange[]'; column :d, 'daterange[]'; column :t, 'tsrange[]'; column :tz, 'tstzrange[]'}
|
2722
|
+
c = Class.new(Sequel::Model(@db[:items]))
|
2723
|
+
c.plugin :pg_typecast_on_load, :i4, :i8, :n, :d, :t, :tz unless @native
|
2724
|
+
v = c.create(@ra).values
|
2725
|
+
v.delete(:id)
|
2726
|
+
v.each{|k,v1| v1.should == @ra[k].to_a}
|
2743
2727
|
end
|
2744
2728
|
|
2745
2729
|
specify 'operations/functions with pg_range_ops' do
|
@@ -2817,7 +2801,7 @@ describe 'PostgreSQL interval types' do
|
|
2817
2801
|
@db = DB
|
2818
2802
|
@db.extension :pg_array, :pg_interval
|
2819
2803
|
@ds = @db[:items]
|
2820
|
-
@native = DB.adapter_scheme == :postgres
|
2804
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2821
2805
|
end
|
2822
2806
|
after(:all) do
|
2823
2807
|
Sequel::Postgres::PG_TYPES.delete(1186)
|
@@ -2829,7 +2813,8 @@ describe 'PostgreSQL interval types' do
|
|
2829
2813
|
specify 'insert and retrieve interval values' do
|
2830
2814
|
@db.create_table!(:items){interval :i}
|
2831
2815
|
[
|
2832
|
-
['0', '00:00:00', 0, [
|
2816
|
+
['0', '00:00:00', 0, []],
|
2817
|
+
['1', '00:00:01', 1, [[:seconds, 1]]],
|
2833
2818
|
['1 microsecond', '00:00:00.000001', 0.000001, [[:seconds, 0.000001]]],
|
2834
2819
|
['1 millisecond', '00:00:00.001', 0.001, [[:seconds, 0.001]]],
|
2835
2820
|
['1 second', '00:00:01', 1, [[:seconds, 1]]],
|
@@ -2853,7 +2838,7 @@ describe 'PostgreSQL interval types' do
|
|
2853
2838
|
rs = @ds.all
|
2854
2839
|
rs.first[:i].is_a?(ActiveSupport::Duration).should be_true
|
2855
2840
|
rs.first[:i].should == ActiveSupport::Duration.new(value, parts)
|
2856
|
-
rs.first[:i].parts.sort_by{|k,v| k.to_s}.should == parts.sort_by{|k,v| k.to_s}
|
2841
|
+
rs.first[:i].parts.sort_by{|k,v| k.to_s}.reject{|k,v| v == 0}.should == parts.sort_by{|k,v| k.to_s}
|
2857
2842
|
@ds.delete
|
2858
2843
|
@ds.insert(rs.first)
|
2859
2844
|
@ds.all.should == rs
|
@@ -2935,7 +2920,7 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
2935
2920
|
@db.register_row_type(Sequel.qualify(:public, :person))
|
2936
2921
|
@db.register_row_type(:public__company)
|
2937
2922
|
|
2938
|
-
@native = DB.adapter_scheme == :postgres
|
2923
|
+
@native = DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2939
2924
|
end
|
2940
2925
|
after(:all) do
|
2941
2926
|
@db.drop_table?(:company, :person, :address)
|
@@ -2980,7 +2965,7 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
2980
2965
|
@db.drop_table(:domain_check)
|
2981
2966
|
@db << "DROP DOMAIN positive_integer"
|
2982
2967
|
end
|
2983
|
-
end if DB.adapter_scheme == :postgres
|
2968
|
+
end if DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
|
2984
2969
|
|
2985
2970
|
specify 'insert and retrieve arrays of row types' do
|
2986
2971
|
@ds = @db[:company]
|
@@ -3170,12 +3155,10 @@ describe 'PostgreSQL row-valued/composite types' do
|
|
3170
3155
|
|
3171
3156
|
Company.plugin :pg_typecast_on_load, :employees unless @native
|
3172
3157
|
e = Person.new(:id=>1, :address=>a)
|
3173
|
-
|
3174
|
-
|
3175
|
-
|
3176
|
-
|
3177
|
-
o.employees.should == [e]
|
3178
|
-
end
|
3158
|
+
o = Company.create(:id=>1, :employees=>[{:id=>1, :address=>{:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12345'}}])
|
3159
|
+
o.employees.should == [e]
|
3160
|
+
o = Company.create(:id=>1, :employees=>[e])
|
3161
|
+
o.employees.should == [e]
|
3179
3162
|
end
|
3180
3163
|
end
|
3181
3164
|
end
|