sequel 4.3.0 → 4.4.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 +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
|