sequel 5.9.0 → 5.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -83,12 +83,12 @@ module Sequel
83
83
  # If convert_infinite_timestamps is true and the value is infinite, return an appropriate
84
84
  # value based on the convert_infinite_timestamps setting.
85
85
  def to_application_timestamp(value)
86
- if value.is_a?(String) && (m = value.match(/(?:(?:[-+]\d\d:\d\d)(:\d\d)?)?( BC)?\z/)) && (m[1] || m[2])
87
- if m[2]
86
+ if value.is_a?(String) && (m = value.match(/((?:[-+]\d\d:\d\d)(:\d\d)?)?( BC)?\z/)) && (m[2] || m[3])
87
+ if m[3]
88
88
  value = value.sub(' BC', '').sub(' ', ' BC ')
89
89
  conv = defined?(JRUBY_VERSION) && JRUBY_VERSION == '9.2.0.0'
90
90
  end
91
- if m[1] || conv
91
+ if m[2] || conv
92
92
  dt = DateTime.parse(value)
93
93
  if conv
94
94
  # :nocov:
@@ -99,7 +99,14 @@ module Sequel
99
99
  end
100
100
  # :nocov:
101
101
  end
102
- dt = dt.to_time unless Sequel.datetime_class == DateTime
102
+ unless Sequel.datetime_class == DateTime
103
+ dt = dt.to_time
104
+ if conv && (timezone == nil || timezone == :local) && !m[1]
105
+ # :nocov:
106
+ dt = Sequel.send(:convert_input_timestamp, dt.strftime("%F %T.%6N"), :local)
107
+ # :nocov:
108
+ end
109
+ end
103
110
  Sequel.convert_output_timestamp(dt, Sequel.application_timezone)
104
111
  else
105
112
  super(value)
@@ -452,13 +452,15 @@ module Sequel
452
452
  end
453
453
  end
454
454
 
455
+ ENDLESS_RANGE_NOT_SUPPORTED = RUBY_VERSION < '2.6'
456
+
455
457
  # Return a ruby Range object for this instance, if one can be created.
456
458
  def to_range
457
459
  return @range if @range
458
460
  raise(Error, "cannot create ruby range for an empty PostgreSQL range") if empty?
459
461
  raise(Error, "cannot create ruby range when PostgreSQL range excludes beginning element") if exclude_begin?
460
462
  raise(Error, "cannot create ruby range when PostgreSQL range has unbounded beginning") unless self.begin
461
- raise(Error, "cannot create ruby range when PostgreSQL range has unbounded ending") unless self.end
463
+ raise(Error, "cannot create ruby range when PostgreSQL range has unbounded ending") if ENDLESS_RANGE_NOT_SUPPORTED && !self.end
462
464
  @range = Range.new(self.begin, self.end, exclude_end?)
463
465
  end
464
466
 
@@ -466,7 +468,7 @@ module Sequel
466
468
  # it must have a beginning and an ending (no unbounded ranges), and it cannot exclude
467
469
  # the beginning element.
468
470
  def valid_ruby_range?
469
- !(empty? || exclude_begin? || !self.begin || !self.end)
471
+ !(empty? || exclude_begin? || !self.begin || (ENDLESS_RANGE_NOT_SUPPORTED && !self.end))
470
472
  end
471
473
 
472
474
  # Whether the beginning of the range is unbounded.
@@ -2401,6 +2401,14 @@ module Sequel
2401
2401
  # cached associations.
2402
2402
  def change_column_value(column, value)
2403
2403
  if assocs = model.autoreloading_associations[column]
2404
+ if new?
2405
+ # Do deeper checking for new objects, so that associations are
2406
+ # not deleted when values do not change. This code is run at
2407
+ # a higher level for existing objects.
2408
+ vals = @values
2409
+ return super unless !vals.include?(column) || value != (c = vals[column]) || value.class != c.class
2410
+ end
2411
+
2404
2412
  assocs.each{|a| associations.delete(a)}
2405
2413
  end
2406
2414
  super
@@ -2681,8 +2689,8 @@ module Sequel
2681
2689
  # creates a subquery to the join table.
2682
2690
  def complex_expression_sql_append(sql, op, args)
2683
2691
  r = args[1]
2684
- if (((op == :'=' || op == :'!=') and r.is_a?(Sequel::Model)) ||
2685
- (multiple = ((op == :IN || op == :'NOT IN') and ((is_ds = r.is_a?(Sequel::Dataset)) or r.all?{|x| x.is_a?(Sequel::Model)}))))
2692
+ if (((op == :'=' || op == :'!=') && r.is_a?(Sequel::Model)) ||
2693
+ (multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (r.respond_to?(:all?) && r.all?{|x| x.is_a?(Sequel::Model)})))))
2686
2694
  l = args[0]
2687
2695
  if ar = model.association_reflections[l]
2688
2696
  if multiple
@@ -45,19 +45,26 @@ module Sequel
45
45
  # race conditions, and is not safe when concurrent modifications are made
46
46
  # to the same list.
47
47
  #
48
- # Additionally, note that unlike ruby arrays, the list plugin assumes that the
49
- # first entry in the list has position 1, not position 0.
48
+ # Note that by default, unlike ruby arrays, the list plugin assumes the first
49
+ # entry in the list has position 1, not position 0.
50
+ #
51
+ # You can change this by providing an integer <tt>:top</tt> option:
52
+ #
53
+ # Item.plugin :list, top: 0
50
54
  #
51
55
  # Copyright (c) 2007-2010 Sharon Rosner, Wayne E. Seguin, Aman Gupta, Adrian Madrid, Jeremy Evans
52
56
  module List
53
- # Set the +position_field+ and +scope_proc+ attributes for the model,
54
- # using the <tt>:field</tt> and <tt>:scope</tt> options, respectively.
57
+ # Set the +position_field+, +scope_proc+ and +top_of_list+ attributes for the model,
58
+ # using the <tt>:field</tt>, <tt>:scope</tt>, and <tt>:top</tt> options, respectively.
55
59
  # The <tt>:scope</tt> option can be a symbol, array of symbols, or a proc that
56
60
  # accepts a model instance and returns a dataset representing the list.
57
61
  # Also, modify the model dataset's order to order by the position and scope fields.
58
62
  def self.configure(model, opts = OPTS)
59
63
  model.position_field = opts[:field] || :position
60
64
  model.dataset = model.dataset.order_prepend(model.position_field)
65
+ model.instance_exec do
66
+ @top_of_list = opts[:top] || 1
67
+ end
61
68
 
62
69
  model.scope_proc = case scope = opts[:scope]
63
70
  when Symbol
@@ -80,7 +87,10 @@ module Sequel
80
87
  # proc should accept an instance and return a dataset representing the list.
81
88
  attr_accessor :scope_proc
82
89
 
83
- Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil)
90
+ # An Integer to use as the position of the top of the list. Defaults to 1.
91
+ attr_reader :top_of_list
92
+
93
+ Plugins.inherited_instance_variables(self, :@position_field=>nil, :@scope_proc=>nil, :@top_of_list=>nil)
84
94
  end
85
95
 
86
96
  module InstanceMethods
@@ -122,7 +132,7 @@ module Sequel
122
132
  checked_transaction do
123
133
  ds = list_dataset
124
134
  op, ds = if target < current
125
- target = 1 if target < 1
135
+ target = model.top_of_list if target < model.top_of_list
126
136
  [:+, ds.where(position_field=>target...current)]
127
137
  else
128
138
  lp ||= last_position
@@ -142,9 +152,9 @@ module Sequel
142
152
  move_to(lp, lp)
143
153
  end
144
154
 
145
- # Move this instance to the top (first position, position 1) of the list.
155
+ # Move this instance to the top (first position, usually position 1) of the list.
146
156
  def move_to_top
147
- move_to(1)
157
+ move_to(model.top_of_list)
148
158
  end
149
159
 
150
160
  # Move this instance the given number of places up in the list, or 1 place
@@ -160,7 +160,7 @@ module Sequel
160
160
 
161
161
  def filter_by_associations_add_conditions_dataset_filter(ds)
162
162
  key = qualify(associated_class.table_name, self[:key])
163
- ds.select{unnest(key)}.exclude(key=>nil)
163
+ ds.cross_join(Sequel.function(:unnest, key).as(:_smtopgaa_, [:_smtopgaa_key_])).exclude(key=>nil).select(:_smtopgaa_key_)
164
164
  end
165
165
 
166
166
  def filter_by_associations_conditions_key
@@ -527,7 +527,7 @@ module Sequel
527
527
  Sequel[pk=>assoc_pks]
528
528
  end
529
529
  when Sequel::Dataset
530
- Sequel[pk=>obj.select{Sequel.pg_array_op(ref.qualify(obj.model.table_name, ref[:key_column])).unnest}]
530
+ obj.select(ref.qualify(obj.model.table_name, ref[:key_column]).as(:key)).from_self.where{{pk=>any(:key)}}.select(1).exists
531
531
  end
532
532
  expr = Sequel::SQL::Constants::FALSE unless expr
533
533
  expr = add_association_filter_conditions(ref, obj, expr)
@@ -32,12 +32,8 @@ module Sequel
32
32
  def self.apply(model, opts=OPTS)
33
33
  opts = opts.dup
34
34
  opts[:class] = model
35
+ opts[:key] ||= :parent_id
35
36
 
36
- model.instance_exec do
37
- @parent_column = (opts[:key] ||= :parent_id)
38
- @tree_order = opts[:order]
39
- end
40
-
41
37
  par = opts.merge(opts.fetch(:parent, OPTS))
42
38
  parent = par.fetch(:name, :parent)
43
39
 
@@ -47,10 +43,16 @@ module Sequel
47
43
  par[:reciprocal] = children
48
44
  chi[:reciprocal] = parent
49
45
 
50
- model.many_to_one parent, par
51
- model.one_to_many children, chi
46
+ model.instance_exec do
47
+ @parent_column = opts[:key]
48
+ @tree_order = opts[:order]
49
+ @parent_association_name = parent
50
+ @children_association_name = children
52
51
 
53
- model.plugin SingleRoot if opts[:single_root]
52
+ many_to_one parent, par
53
+ one_to_many children, chi
54
+ plugin SingleRoot if opts[:single_root]
55
+ end
54
56
  end
55
57
 
56
58
  module ClassMethods
@@ -61,7 +63,13 @@ module Sequel
61
63
  # parent of the leaf.
62
64
  attr_accessor :parent_column
63
65
 
64
- Plugins.inherited_instance_variables(self, :@parent_column=>nil, :@tree_order=>nil)
66
+ # The association name for the parent association
67
+ attr_reader :parent_association_name
68
+
69
+ # The association name for the children association
70
+ attr_reader :children_association_name
71
+
72
+ Plugins.inherited_instance_variables(self, :@parent_column=>nil, :@tree_order=>nil, :@parent_association_name=>nil, :@children_association_name=>nil)
65
73
 
66
74
  # Should freeze tree order if it is an array when freezing the model class.
67
75
  def freeze
@@ -93,7 +101,10 @@ module Sequel
93
101
  # subchild1.ancestors # => [child1, root]
94
102
  def ancestors
95
103
  node, nodes = self, []
96
- nodes << node = node.parent while node.parent
104
+ meth = model.parent_association_name
105
+ while par = node.send(meth)
106
+ nodes << node = par
107
+ end
97
108
  nodes
98
109
  end
99
110
 
@@ -101,8 +112,8 @@ module Sequel
101
112
  #
102
113
  # node.descendants # => [child1, child2, subchild1_1, subchild1_2, subchild2_1, subchild2_2]
103
114
  def descendants
104
- nodes = children.dup
105
- children.each{|child| nodes.concat(child.descendants)}
115
+ nodes = send(model.children_association_name).dup
116
+ send(model.children_association_name).each{|child| nodes.concat(child.descendants)}
106
117
  nodes
107
118
  end
108
119
 
@@ -121,7 +132,11 @@ module Sequel
121
132
  #
122
133
  # subchild1.self_and_siblings # => [subchild1, subchild2]
123
134
  def self_and_siblings
124
- parent ? parent.children : model.roots
135
+ if parent = send(model.parent_association_name)
136
+ parent.send(model.children_association_name)
137
+ else
138
+ model.roots
139
+ end
125
140
  end
126
141
 
127
142
  # Returns all siblings of the current node.
@@ -26,12 +26,27 @@ module Sequel
26
26
  # Set the date used for SQLTime instances.
27
27
  attr_writer :date
28
28
 
29
- # use the date explicitly set, or the current date if there is not a
29
+ # Use the date explicitly set, or the current date if there is not a
30
30
  # date set.
31
31
  def date
32
32
  @date || now
33
33
  end
34
34
 
35
+ # Set the correct date and timezone when parsing times.
36
+ def parse(*)
37
+ t = super
38
+
39
+ utc = Sequel.application_timezone == :utc
40
+ d = @date
41
+ if d || utc
42
+ meth = utc ? :utc : :local
43
+ d ||= t
44
+ t = public_send(meth, d.year, d.month, d.day, t.hour, t.min, t.sec, t.usec)
45
+ end
46
+
47
+ t
48
+ end
49
+
35
50
  # Create a new SQLTime instance given an hour, minute, second, and usec.
36
51
  def create(hour, minute, second, usec = 0)
37
52
  t = date
@@ -1059,7 +1074,11 @@ module Sequel
1059
1074
  def self.from_value_pair(l, r)
1060
1075
  case r
1061
1076
  when Range
1062
- new(:AND, new(:>=, l, r.begin), new(r.exclude_end? ? :< : :<=, l, r.end))
1077
+ expr = new(:>=, l, r.begin)
1078
+ unless r.end.nil?
1079
+ expr = new(:AND, expr, new(r.exclude_end? ? :< : :<=, l, r.end))
1080
+ end
1081
+ expr
1063
1082
  when ::Array, ::Sequel::Dataset
1064
1083
  new(:IN, l, r)
1065
1084
  when NegativeBooleanConstant
@@ -1846,7 +1865,7 @@ module Sequel
1846
1865
  freeze
1847
1866
  end
1848
1867
 
1849
- include(Module.new do
1868
+ m = Module.new do
1850
1869
  # Return an +Identifier+, +QualifiedIdentifier+, or +Function+, depending
1851
1870
  # on arguments and whether a block is provided. Does not currently call the block.
1852
1871
  # See the class level documentation.
@@ -1862,7 +1881,8 @@ module Sequel
1862
1881
  Function.new(m, *args)
1863
1882
  end
1864
1883
  end
1865
- end)
1884
+ end
1885
+ include m
1866
1886
 
1867
1887
  Sequel::VIRTUAL_ROW = new
1868
1888
  end
@@ -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 = 9
8
+ MINOR = 10
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
@@ -271,6 +271,11 @@ describe "PostgreSQL views" do
271
271
  @db.refresh_view(:items_view, :concurrently=>true)
272
272
  end if DB.server_version >= 90400
273
273
 
274
+ it "should support specifying tablespaces for materialized views" do
275
+ @opts = {:materialized=>true}
276
+ @db.create_view(:items_view, @db[:items].where{number >= 10}, :materialized=>true, :tablespace=>:pg_default)
277
+ end if DB.server_version >= 90300
278
+
274
279
  it "should support :if_exists=>true for not raising an error if the view does not exist" do
275
280
  @db.drop_view(:items_view, :if_exists=>true)
276
281
  end
@@ -720,6 +725,21 @@ describe "A PostgreSQL dataset" do
720
725
  @db.add_index :test, [:name, :value], :if_not_exists=>true, :name=>'tnv3'
721
726
  end if DB.server_version >= 90500
722
727
 
728
+ it "should support including columns in indexes" do
729
+ @db.create_table(:atest){Integer :a; Integer :b; Integer :c}
730
+ @db.add_index :atest, :a, :include=>[:b, :c]
731
+ @db.add_index :atest, :b, :include=>:a
732
+ end if DB.server_version >= 110000
733
+
734
+ it "should support specifying tablespaces for tables" do
735
+ @db.create_table(:atest, :tablespace=>:pg_default){Integer :a}
736
+ end
737
+
738
+ it "should support specifying tablespaces for indexes" do
739
+ @db.create_table(:atest){Integer :a}
740
+ @db.add_index :atest, :a, :tablespace=>:pg_default
741
+ end
742
+
723
743
  it "#lock should lock table if inside a transaction" do
724
744
  @db.transaction{@d.lock('EXCLUSIVE'); @d.insert(:name=>'a')}
725
745
  end
@@ -849,6 +869,9 @@ describe "A PostgreSQL dataset with a timestamp field" do
849
869
  end
850
870
  after do
851
871
  @db.convert_infinite_timestamps = false
872
+ Sequel.datetime_class = Time
873
+ Sequel::SQLTime.date = nil
874
+ Sequel.application_timezone = nil
852
875
  end
853
876
  after(:all) do
854
877
  @db.drop_table?(:test3)
@@ -872,22 +895,62 @@ describe "A PostgreSQL dataset with a timestamp field" do
872
895
  (t2.is_a?(Time) ? t2.usec : t2.strftime('%N').to_i/1000).must_equal t.strftime('%N').to_i/1000
873
896
  end
874
897
 
898
+ it "should respect SQLTime.date setting for time columns" do
899
+ Sequel::SQLTime.date = Time.local(2000, 1, 2)
900
+ d = Sequel::SQLTime.create(10, 11, 12)
901
+ @db.get(Sequel.cast(d, :time)).must_equal d
902
+ @db.get(Sequel.cast(d, :timetz)).must_equal d
903
+ end
904
+
905
+ it "should respect Sequel.application_timezone for time columns" do
906
+ d = Sequel::SQLTime.create(10, 11, 12)
907
+ Sequel.application_timezone = :local
908
+ @db.get(Sequel.cast(d, :time)).utc_offset.must_equal Time.now.utc_offset
909
+ @db.get(Sequel.cast(d, :timetz)).utc_offset.must_equal Time.now.utc_offset
910
+ Sequel.application_timezone = :utc
911
+ @db.get(Sequel.cast(d, :time)).utc_offset.must_equal 0
912
+ @db.get(Sequel.cast(d, :timetz)).utc_offset.must_equal 0
913
+ end
914
+
915
+ it "should handle parsing dates and timestamps in with 1, 2, and 3 digit years" do
916
+ [1, 10, 100, -2, -20, -200].each do |year|
917
+ d = Date.new(year, 2, 3)
918
+ @db.get(Sequel.cast(d, Date)).must_equal d
919
+ d = Time.local(year, 2, 3, 10, 11, 12)
920
+ @db.get(Sequel.cast(d, Time)).must_equal d
921
+ begin
922
+ Sequel.datetime_class = DateTime
923
+ d = DateTime.new(year, 2, 3, 10, 11, 12)
924
+ @db.get(Sequel.cast(d, Time)).must_equal d
925
+ ensure
926
+ Sequel.datetime_class = Time
927
+ end
928
+ end
929
+ end
930
+
931
+ it "should handle parsing dates and timestamps in the distant future" do
932
+ d = Date.new(5874896, 2, 3)
933
+ @db.get(Sequel.cast(d, Date)).must_equal d
934
+ d = Time.local(294275, 2, 3, 10, 11, 12)
935
+ @db.get(Sequel.cast(d, Time)).must_equal d
936
+ Sequel.datetime_class = DateTime
937
+ d = DateTime.new(294275, 2, 3, 10, 11, 12)
938
+ @db.get(Sequel.cast(d, Time)).must_equal d
939
+ end
940
+
875
941
  it "should handle BC times and dates" do
876
942
  d = Date.new(-1234, 2, 3)
877
943
  @db.get(Sequel.cast(d, Date)).must_equal d
878
- begin
879
- Sequel.default_timezone = :utc
880
- t = Time.at(-100000000000).utc + 0.5
881
- @db.get(Sequel.cast(t, Time)).must_equal t
882
- @db.get(Sequel.cast(t, :timestamptz)).must_equal t
883
- Sequel.datetime_class = DateTime
884
- dt = DateTime.new(-1234, 2, 3, 10, 20, Rational(30, 20))
885
- @db.get(Sequel.cast(dt, DateTime)).must_equal dt
886
- @db.get(Sequel.cast(dt, :timestamptz)).must_equal dt
887
- ensure
888
- Sequel.datetime_class = Time
889
- Sequel.default_timezone = nil
890
- end
944
+ Sequel.default_timezone = :utc
945
+ t = Time.at(-100000000000).utc + 0.5
946
+ @db.get(Sequel.cast(t, Time)).must_equal t
947
+ @db.get(Sequel.cast(t, :timestamptz)).must_equal t
948
+ Sequel.datetime_class = DateTime
949
+ dt = DateTime.new(-1234, 2, 3, 10, 20, Rational(30, 20))
950
+ @db.get(Sequel.cast(dt, DateTime)).must_equal dt
951
+ @db.get(Sequel.cast(dt, :timestamptz)).must_equal dt
952
+ Sequel.datetime_class = Time
953
+ Sequel.default_timezone = nil
891
954
  end
892
955
 
893
956
  it "should handle infinite timestamps if convert_infinite_timestamps is set" do
@@ -2343,13 +2406,13 @@ describe 'PostgreSQL array handling' do
2343
2406
  end
2344
2407
 
2345
2408
  it 'insert and retrieve custom array types' do
2346
- int2vector = Class.new do
2409
+ point= Class.new do
2347
2410
  attr_reader :array
2348
2411
  def initialize(array)
2349
2412
  @array = array
2350
2413
  end
2351
2414
  def sql_literal_append(ds, sql)
2352
- sql << "'#{array.join(' ')}'"
2415
+ sql << "'(#{array.join(',')})'"
2353
2416
  end
2354
2417
  def ==(other)
2355
2418
  if other.is_a?(self.class)
@@ -2359,16 +2422,16 @@ describe 'PostgreSQL array handling' do
2359
2422
  end
2360
2423
  end
2361
2424
  end
2362
- @db.register_array_type(:int2vector){|s| int2vector.new(s.split.map{|i| i.to_i})}
2425
+ @db.register_array_type(:point){|s| point.new(s[1...-1].split(',').map{|i| i.to_i})}
2363
2426
  @db.create_table!(:items) do
2364
- column :b, 'int2vector[]'
2427
+ column :b, 'point[]'
2365
2428
  end
2366
- @tp.call.must_equal [:int2vector_array]
2367
- int2v = int2vector.new([1, 2])
2368
- @ds.insert(Sequel.pg_array([int2v], :int2vector))
2429
+ @tp.call.must_equal [:point_array]
2430
+ pv = point.new([1, 2])
2431
+ @ds.insert(Sequel.pg_array([pv], :point))
2369
2432
  @ds.count.must_equal 1
2370
2433
  rs = @ds.all
2371
- rs.must_equal [{:b=>[int2v]}]
2434
+ rs.must_equal [{:b=>[pv]}]
2372
2435
  rs.first.values.each{|v| v.class.must_equal(Sequel::Postgres::PGArray)}
2373
2436
  rs.first.values.each{|v| v.to_a.must_be_kind_of(Array)}
2374
2437
  @ds.delete
@@ -2398,7 +2461,7 @@ describe 'PostgreSQL array handling' do
2398
2461
  @ds.delete
2399
2462
  @ds.insert(rs.first)
2400
2463
  @ds.all.must_equal rs
2401
- end if DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
2464
+ end
2402
2465
 
2403
2466
  it 'use arrays in bound variables' do
2404
2467
  @db.create_table!(:items) do
@@ -3039,7 +3102,7 @@ describe 'PostgreSQL json type' do
3039
3102
  j = Sequel.pg_json([{'a'=>1, 'b'=>'c'}, {'a'=>2, 'b'=>'d'}]).op
3040
3103
  @db.from(j.populate_set(Sequel.cast(nil, :items))).select_order_map(:a).must_equal [1, 2]
3041
3104
  @db.from(j.populate_set(Sequel.cast(nil, :items))).select_order_map(:b).must_equal %w'c d'
3042
- end if DB.server_version >= 90300 && (DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc)
3105
+ end if DB.server_version >= 90300
3043
3106
  end
3044
3107
  end if DB.server_version >= 90200
3045
3108
 
@@ -3189,6 +3252,11 @@ describe 'PostgreSQL inet/cidr types' do
3189
3252
 
3190
3253
  @db.get(Sequel.pg_inet_op('1.2.3.4/24').abbrev).must_equal '1.2.3.4/24'
3191
3254
  @db.get(Sequel.pg_inet_op('1.2.3.4/24').broadcast).must_equal IPAddr.new('1.2.3.255/24')
3255
+ @db.get(Sequel.pg_inet_op('1234:3456:5678:789a:9abc:bced:edf0:f012/96').broadcast).must_equal IPAddr.new('1234:3456:5678:789a:9abc:bced::/96')
3256
+ @db.get(Sequel.pg_inet_op('1234:3456:5678:789a:9abc:bced:edf0:f012/128').broadcast).must_equal IPAddr.new('1234:3456:5678:789a:9abc:bced:edf0:f012/128')
3257
+ @db.get(Sequel.pg_inet_op('1234:3456:5678:789a:9abc:bced:edf0:f012/64').broadcast).must_equal IPAddr.new('1234:3456:5678:789a::/64')
3258
+ @db.get(Sequel.pg_inet_op('1234:3456:5678:789a:9abc:bced:edf0:f012/32').broadcast).must_equal IPAddr.new('1234:3456::/32')
3259
+ @db.get(Sequel.pg_inet_op('1234:3456:5678:789a:9abc:bced:edf0:f012/0').broadcast).must_equal IPAddr.new('::/0')
3192
3260
  @db.get(Sequel.pg_inet_op('1.2.3.4/24').family).must_equal 4
3193
3261
  @db.get(Sequel.pg_inet_op('1.2.3.4/24').host).must_equal '1.2.3.4'
3194
3262
  @db.get(Sequel.pg_inet_op('1.2.3.4/24').hostmask).must_equal IPAddr.new('0.0.0.255/32')
@@ -3218,7 +3286,7 @@ describe 'PostgreSQL custom range types' do
3218
3286
  r = Sequel::SQLTime.create(10, 11, 12)..Sequel::SQLTime.create(11, 12, 13)
3219
3287
  @db.get(Sequel.pg_range(r, :timerange)).to_range.must_equal r
3220
3288
  end
3221
- end if DB.server_version >= 90200 && DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
3289
+ end if DB.server_version >= 90200
3222
3290
 
3223
3291
  describe 'PostgreSQL range types' do
3224
3292
  before(:all) do
@@ -3570,7 +3638,7 @@ describe 'PostgreSQL row-valued/composite types' do
3570
3638
  @db.drop_table(:domain_check)
3571
3639
  @db << "DROP DOMAIN positive_integer"
3572
3640
  end
3573
- end if DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
3641
+ end
3574
3642
 
3575
3643
  it 'insert and retrieve arrays of row types' do
3576
3644
  @ds = @db[:company]
@@ -3822,7 +3890,7 @@ describe 'PostgreSQL enum types' do
3822
3890
 
3823
3891
  it "should add array parsers for enum values" do
3824
3892
  @db.get(Sequel.pg_array(%w'a b', :test_enum)).must_equal %w'a b'
3825
- end if DB.adapter_scheme == :postgres || DB.adapter_scheme == :jdbc
3893
+ end
3826
3894
 
3827
3895
  it "should set up model typecasting correctly" do
3828
3896
  c = Class.new(Sequel::Model(:test_enumt))