sequel 4.23.0 → 4.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +26 -0
- data/Rakefile +1 -1
- data/doc/release_notes/4.24.0.txt +99 -0
- data/doc/sql.rdoc +10 -1
- data/lib/sequel/adapters/jdbc.rb +7 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
- 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 +1 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +2 -2
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -1
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +14 -6
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/core.rb +12 -1
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/extensions/pg_inet_ops.rb +200 -0
- data/lib/sequel/plugins/association_pks.rb +63 -18
- data/lib/sequel/plugins/auto_validations.rb +43 -9
- data/lib/sequel/plugins/class_table_inheritance.rb +236 -179
- data/lib/sequel/plugins/update_refresh.rb +26 -1
- data/lib/sequel/plugins/validation_helpers.rb +7 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/oracle_spec.rb +1 -1
- data/spec/adapters/postgres_spec.rb +61 -0
- data/spec/core_extensions_spec.rb +5 -1
- data/spec/extensions/association_pks_spec.rb +73 -1
- data/spec/extensions/auto_validations_spec.rb +34 -0
- data/spec/extensions/class_table_inheritance_spec.rb +58 -54
- data/spec/extensions/pg_inet_ops_spec.rb +101 -0
- data/spec/extensions/spec_helper.rb +5 -5
- data/spec/extensions/update_refresh_spec.rb +12 -0
- data/spec/extensions/validation_helpers_spec.rb +7 -0
- data/spec/integration/plugin_test.rb +48 -13
- metadata +6 -4
- data/lib/sequel/adapters/db2.rb +0 -229
- data/lib/sequel/adapters/dbi.rb +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ce66a463879671227d5446f7e224b1610bccd9f
|
4
|
+
data.tar.gz: e16b849b789b960f5c6d86dd7049a61ebe42c169
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ac3191f57bffb08c000deef706301c4b6628cb707ef9f870df162d7d55d3ed21982f931c3b9bbc3658cf4a693e7aa2b45d8a3dd1c62a0345d9d2d88dd7dc391
|
7
|
+
data.tar.gz: d05096b10746ea930ecd79f8cde66e295b9b5e99002c64df479369473a1bb603b36c9a69ce2462fecd33c1dc3217705bac651d590dca4c58a85edd44b1c515b3
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
=== 4.24.0 (2015-07-01)
|
2
|
+
|
3
|
+
* Allow class_table_inheritance plugin to support subclasses that don't add additional columns (QuinnHarris, jeremyevans) (#1030)
|
4
|
+
|
5
|
+
* Add :columns option to update_refresh plugin, specifying the columns to include in the RETURNING clause (celsworth) (#1029)
|
6
|
+
|
7
|
+
* Use column symbol key for auto validation unique errors if the unique index is on a single column (jeremyevans)
|
8
|
+
|
9
|
+
* Allow :timeout option to Database#listen in the postgres adapter to be a callable object (celsworth) (#1028)
|
10
|
+
|
11
|
+
* Add pg_inet_ops extension, for DSL support for PostgreSQL inet/cidr operators and functions (celsworth, jeremyevans) (#1024)
|
12
|
+
|
13
|
+
* Support :*_opts options in auto_validations plugin, for setting options for the underlying validation methods (celsworth, jeremyevans) (#1026)
|
14
|
+
|
15
|
+
* Support :delay_pks association option in association_pks to delay setting of associated_pks until after saving (jeremyevans)
|
16
|
+
|
17
|
+
* Make jdbc subadapters work if they issue queries while the subadapter is being loaded (jeremyevans) (#1022)
|
18
|
+
|
19
|
+
* Handle 64-bit auto incrementing primary keys in jdbc subadapters (DougEverly) (#1018, #1019)
|
20
|
+
|
21
|
+
* Remove the deprecated db2 and dbi adapters (jeremyevans)
|
22
|
+
|
23
|
+
* Make auto_validation plugin use :from=>:values option to setup validations on the underlying columns (jeremyevans)
|
24
|
+
|
25
|
+
* Add :from=>:values option to validation_helpers methods, for getting values from the values hash instead of a method call (jeremyevans)
|
26
|
+
|
1
27
|
=== 4.23.0 (2015-06-01)
|
2
28
|
|
3
29
|
* Make dataset.call_sproc(:insert) work in the jdbc adapter (flash-gordon) (#1013)
|
data/Rakefile
CHANGED
@@ -86,7 +86,7 @@ run_spec = proc do |patterns|
|
|
86
86
|
lib_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'lib')
|
87
87
|
rubylib = ENV['RUBYLIB']
|
88
88
|
ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)
|
89
|
-
if RUBY_PLATFORM =~ /mingw32/
|
89
|
+
if RUBY_PLATFORM =~ /mingw32/ || RUBY_DESCRIPTION =~ /windows/i
|
90
90
|
patterns = patterns.split.map{|pat| Dir[pat].to_a}.flatten.join(' ')
|
91
91
|
end
|
92
92
|
sh "#{FileUtils::RUBY} -e \"ARGV.each{|f| require f}\" #{patterns}"
|
@@ -0,0 +1,99 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A pg_inet_ops extension has been added, for DSL support for
|
4
|
+
calling PostgreSQL inet functions and operators. Example:
|
5
|
+
|
6
|
+
r = Sequel.pg_inet_op(:inet)
|
7
|
+
|
8
|
+
~r # ~inet
|
9
|
+
r & :other # inet & other
|
10
|
+
r | :other # inet | other
|
11
|
+
r << :other # inet << other
|
12
|
+
r >> :other # inet >> other
|
13
|
+
|
14
|
+
r.contained_by(:other) # inet << other
|
15
|
+
r.contained_by_or_equals(:other) # inet <<= other
|
16
|
+
r.contains(:other) # inet >> other
|
17
|
+
r.contains_or_equals(:other) # inet >>= other
|
18
|
+
r.contains_or_contained_by(:other) # inet && other
|
19
|
+
|
20
|
+
r.abbrev # abbrev(inet)
|
21
|
+
r.broadcast # broadcast(inet)
|
22
|
+
r.family # family(inet)
|
23
|
+
r.host # host(inet)
|
24
|
+
r.hostmask # hostmask(inet)
|
25
|
+
r.masklen # masklen(inet)
|
26
|
+
r.netmask # netmask(inet)
|
27
|
+
r.network # network(inet)
|
28
|
+
r.set_masklen(16) # set_masklen(inet, 16)
|
29
|
+
r.text # text(inet)
|
30
|
+
|
31
|
+
* The association_pks plugin now supports a :delay_pks association
|
32
|
+
option. When set to true, this makes the methods created by the
|
33
|
+
plugin usable on new objects, by delaying the saving of the
|
34
|
+
associated pks until after the new object has been saved. When
|
35
|
+
set to :always, this also changes the behavior of the methods
|
36
|
+
for existing objects, so that nothing is persisted until the
|
37
|
+
object has been saved. Example:
|
38
|
+
|
39
|
+
Album.plugin :association_pks
|
40
|
+
Album.many_to_many :tags, :delay_pks=>true
|
41
|
+
|
42
|
+
album = Album.new(:tag_pks=>[1,2,3]) # No database query
|
43
|
+
album.save # Queries to insert album, and then update albums_tags
|
44
|
+
|
45
|
+
* The class_table_inheritance plugin now supports subclasses that
|
46
|
+
don't require additional columns, and therefore do not need to
|
47
|
+
join to additional tables. It now loads the
|
48
|
+
single_table_inheritance plugin and supports options that were
|
49
|
+
previously only supported by single_table_inheritance, such as the
|
50
|
+
:key_map and :key_chooser options.
|
51
|
+
|
52
|
+
* The validation_helpers plugin now supports a :from=>:values option
|
53
|
+
in the validation methods, which will take the value directly from
|
54
|
+
the values hash instead of calling the related method. This
|
55
|
+
allows validation_helpers to differentiate between validations on
|
56
|
+
underlying database column and validations on the model.
|
57
|
+
|
58
|
+
The auto_validations plugin has been modified to use this feature,
|
59
|
+
since all validations it generates are for validations on the
|
60
|
+
underlying database columns.
|
61
|
+
|
62
|
+
* The auto_validations plugin now supports options to pass to each
|
63
|
+
of the underlying validation methods:
|
64
|
+
|
65
|
+
Sequel::Model.plugin :auto_validations,
|
66
|
+
:unique_opts=>{:only_if_modified=>true}
|
67
|
+
|
68
|
+
In addition to :unique_opts, there is support for :not_null_opts
|
69
|
+
(for NOT NULL columns without a default), :explicit_not_null_opts
|
70
|
+
(for NOT NULL columns with a default), :max_length_opts, and
|
71
|
+
:schema_types_opts.
|
72
|
+
|
73
|
+
* The update_refresh plugin now accepts a :columns option, which
|
74
|
+
specifies the columns to refresh. This option is currently only
|
75
|
+
respected if the related dataset supports RETURNING.
|
76
|
+
|
77
|
+
* The :timeout option to Database#listen in the postgres adapter can
|
78
|
+
now be a callable object, previously it had to be Numeric. This
|
79
|
+
allows you to dynamically change the timeout based on current
|
80
|
+
application state.
|
81
|
+
|
82
|
+
= Other Improvements
|
83
|
+
|
84
|
+
* The uniqueness validations added by the auto_validations plugin now
|
85
|
+
use a symbol key in the related Errors instance if the underlying
|
86
|
+
index was on a single column. Previously, the uniqueness
|
87
|
+
validations for a single column would use an array key in the
|
88
|
+
related Errors instance.
|
89
|
+
|
90
|
+
* The jdbc subadapters now correctly handle 64-bit autoincrementing
|
91
|
+
primary keys.
|
92
|
+
|
93
|
+
* The jdbc subadapters now work correctly if they issue queries while
|
94
|
+
the subadapter is being loaded. This can happen in the
|
95
|
+
jdbc/postgresql adapter if the pg_hstore extension is used.
|
96
|
+
|
97
|
+
= Backwards Compatibility
|
98
|
+
|
99
|
+
* The deprecated db2 and dbi adapters have been removed.
|
data/doc/sql.rdoc
CHANGED
@@ -237,6 +237,15 @@ If the database supports schema qualified functions, Sequel can handle them by c
|
|
237
237
|
DB[:albums].select{schema__function.function(col, 2, "a")}
|
238
238
|
# SELECT schema.function(col, 2, 'a') FROM albums
|
239
239
|
|
240
|
+
=== Portable/Emulated Functions
|
241
|
+
|
242
|
+
Sequel offers some support for portable SQL functions, allowing you to call standard SQL functions, where Sequel will emulate support on databases that lack native support.
|
243
|
+
Some examples are:
|
244
|
+
|
245
|
+
Sequel.char_length(:column) # char_length(column)
|
246
|
+
Sequel.extract(:year, :column) # extract(year FROM column)
|
247
|
+
Sequel.trim(:column) # trim(column)
|
248
|
+
|
240
249
|
=== Equality Operator (=)
|
241
250
|
|
242
251
|
Sequel uses hashes to specify equality:
|
@@ -506,7 +515,7 @@ Note that using +ilike+ with a regular expression will always make the regexp ca
|
|
506
515
|
|
507
516
|
=== Order Specifications (ASC, DESC)
|
508
517
|
|
509
|
-
Sequel supports specifying ascending or descending order using the asc+ and +desc+ method on most Sequel-specific expression objects:
|
518
|
+
Sequel supports specifying ascending or descending order using the +asc+ and +desc+ method on most Sequel-specific expression objects:
|
510
519
|
|
511
520
|
Sequel.expr(:column).asc # "column" ASC
|
512
521
|
Sequel.expr(:column).qualify(:table).desc # "table"."column" DESC
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -354,6 +354,7 @@ module Sequel
|
|
354
354
|
raise(Error, "No connection string specified") unless uri
|
355
355
|
|
356
356
|
resolved_uri = jndi? ? get_uri_from_jndi : uri
|
357
|
+
setup_type_convertor_map_early
|
357
358
|
|
358
359
|
@driver = if (match = /\Ajdbc:([^:]+)/.match(resolved_uri)) && (prok = Sequel::Database.load_adapter(match[1].to_sym, :map=>DATABASE_SETUP, :subdir=>'jdbc'))
|
359
360
|
prok.call(self)
|
@@ -640,7 +641,13 @@ module Sequel
|
|
640
641
|
h[:table_schem] == 'INFORMATION_SCHEMA'
|
641
642
|
end
|
642
643
|
|
644
|
+
# Called after loading subadapter-specific code, overridable by subadapters.
|
643
645
|
def setup_type_convertor_map
|
646
|
+
end
|
647
|
+
|
648
|
+
# Called before loading subadapter-specific code, necessary so that subadapter initialization code
|
649
|
+
# that runs queries works correctly. This cannot be overriding in subadapters,
|
650
|
+
def setup_type_convertor_map_early
|
644
651
|
@type_convertor_map = TypeConvertor::MAP.merge(Java::JavaSQL::Types::TIMESTAMP=>timestamp_convertor)
|
645
652
|
@basic_type_convertor_map = TypeConvertor::BASIC_MAP
|
646
653
|
end
|
@@ -46,7 +46,7 @@ module Sequel
|
|
46
46
|
rs = stmt.getGeneratedKeys
|
47
47
|
begin
|
48
48
|
if rs.next
|
49
|
-
rs.
|
49
|
+
rs.getLong(1)
|
50
50
|
else
|
51
51
|
0
|
52
52
|
end
|
@@ -57,7 +57,7 @@ module Sequel
|
|
57
57
|
statement(conn) do |st|
|
58
58
|
rs = st.executeQuery(LAST_INSERT_ID)
|
59
59
|
rs.next
|
60
|
-
rs.
|
60
|
+
rs.getLong(1)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -439,14 +439,16 @@ module Sequel
|
|
439
439
|
# :after_listen :: An object that responds to +call+ that is called with the underlying connection after the LISTEN
|
440
440
|
# statement is sent, but before the connection starts waiting for notifications.
|
441
441
|
# :loop :: Whether to continually wait for notifications, instead of just waiting for a single
|
442
|
-
# notification. If this option is given, a block must be provided. If this object responds to call
|
442
|
+
# notification. If this option is given, a block must be provided. If this object responds to +call+, it is
|
443
443
|
# called with the underlying connection after each notification is received (after the block is called).
|
444
444
|
# If a :timeout option is used, and a callable object is given, the object will also be called if the
|
445
445
|
# timeout expires. If :loop is used and you want to stop listening, you can either break from inside the
|
446
446
|
# block given to #listen, or you can throw :stop from inside the :loop object's call method or the block.
|
447
447
|
# :server :: The server on which to listen, if the sharding support is being used.
|
448
|
-
# :timeout :: How long to wait for a notification, in seconds (can provide a float value for
|
449
|
-
#
|
448
|
+
# :timeout :: How long to wait for a notification, in seconds (can provide a float value for fractional seconds).
|
449
|
+
# If this object responds to +call+, it will be called and should return the number of seconds to wait.
|
450
|
+
# If the loop option is also specified, the object will be called on each iteration to obtain a new
|
451
|
+
# timeout value. If not given or nil, waits indefinitely.
|
450
452
|
#
|
451
453
|
# This method is only supported if pg is used as the underlying ruby driver. It returns the
|
452
454
|
# channel the notification was sent to (as a string), unless :loop was used, in which case it returns nil.
|
@@ -465,19 +467,25 @@ module Sequel
|
|
465
467
|
conn.execute(sql)
|
466
468
|
end
|
467
469
|
opts[:after_listen].call(conn) if opts[:after_listen]
|
468
|
-
timeout = opts[:timeout]
|
470
|
+
timeout = opts[:timeout]
|
471
|
+
if timeout
|
472
|
+
timeout_block = timeout.respond_to?(:call) ? timeout : proc{timeout}
|
473
|
+
end
|
474
|
+
|
469
475
|
if l = opts[:loop]
|
470
476
|
raise Error, 'calling #listen with :loop requires a block' unless block
|
471
477
|
loop_call = l.respond_to?(:call)
|
472
478
|
catch(:stop) do
|
473
479
|
loop do
|
474
|
-
|
480
|
+
t = timeout_block ? [timeout_block.call] : []
|
481
|
+
conn.wait_for_notify(*t, &block)
|
475
482
|
l.call(conn) if loop_call
|
476
483
|
end
|
477
484
|
end
|
478
485
|
nil
|
479
486
|
else
|
480
|
-
|
487
|
+
t = timeout_block ? [timeout_block.call] : []
|
488
|
+
conn.wait_for_notify(*t, &block)
|
481
489
|
end
|
482
490
|
ensure
|
483
491
|
conn.execute("UNLISTEN *")
|
@@ -37,7 +37,7 @@ module Sequel
|
|
37
37
|
# Execute the given stored procedure with the given name.
|
38
38
|
#
|
39
39
|
# Options:
|
40
|
-
# :args :: Arguments to stored procedure. For named
|
40
|
+
# :args :: Arguments to stored procedure. For named arguments, this should be a
|
41
41
|
# hash keyed by argument named. For unnamed arguments, this should be an
|
42
42
|
# array. Output parameters to the function are specified using :output.
|
43
43
|
# You can also name output parameters and provide a type by using an
|
data/lib/sequel/core.rb
CHANGED
@@ -84,11 +84,22 @@ module Sequel
|
|
84
84
|
# DB = Sequel.connect('postgres://user:password@host:port/database_name')
|
85
85
|
# DB = Sequel.connect('sqlite:///blog.db', :max_connections=>10)
|
86
86
|
#
|
87
|
+
# You can also pass a single options hash:
|
88
|
+
#
|
89
|
+
# DB = Sequel.connect(:adapter=>'sqlite', :database=>'./blog.db')
|
90
|
+
#
|
87
91
|
# If a block is given, it is passed the opened +Database+ object, which is
|
88
92
|
# closed when the block exits. For example:
|
89
93
|
#
|
90
94
|
# Sequel.connect('sqlite://blog.db'){|db| puts db[:users].count}
|
91
|
-
#
|
95
|
+
#
|
96
|
+
# If a block is not given, a reference to this database will be held in
|
97
|
+
# <tt>Sequel::DATABASES</tt> until it is removed manually. This is by
|
98
|
+
# design, and used by <tt>Sequel::Model</tt> to pick the default
|
99
|
+
# database. It is recommended to pass a block if you do not want the
|
100
|
+
# resulting Database object to remain in memory until the process
|
101
|
+
# terminates.
|
102
|
+
#
|
92
103
|
# For details, see the {"Connecting to a Database" guide}[rdoc-ref:doc/opening_databases.rdoc].
|
93
104
|
# To set up a master/slave or sharded database connection, see the {"Master/Slave Databases and Sharding" guide}[rdoc-ref:doc/sharding.rdoc].
|
94
105
|
def self.connect(*args, &block)
|
@@ -6,7 +6,7 @@ module Sequel
|
|
6
6
|
# ---------------------
|
7
7
|
|
8
8
|
# Array of supported database adapters
|
9
|
-
ADAPTERS = %w'ado amalgalite cubrid
|
9
|
+
ADAPTERS = %w'ado amalgalite cubrid do firebird ibmdb informix jdbc mock mysql mysql2 odbc oracle postgres sqlanywhere sqlite swift tinytds'.collect(&:to_sym)
|
10
10
|
|
11
11
|
@single_threaded = false
|
12
12
|
|
@@ -42,7 +42,6 @@ module Sequel
|
|
42
42
|
else
|
43
43
|
uri = URI.parse(conn_string)
|
44
44
|
scheme = uri.scheme
|
45
|
-
scheme = :dbi if scheme =~ /\Adbi-/
|
46
45
|
c = adapter_class(scheme)
|
47
46
|
uri_options = c.send(:uri_to_options, uri)
|
48
47
|
uri.query.split('&').collect{|s| s.split('=')}.each{|k,v| uri_options[k.to_sym] = v if k && !k.empty?} unless uri.query.to_s.strip.empty?
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# The pg_inet_ops extension adds support to Sequel's DSL to make
|
2
|
+
# it easier to call PostgreSQL inet functions and operators.
|
3
|
+
#
|
4
|
+
# To load the extension:
|
5
|
+
#
|
6
|
+
# Sequel.extension :pg_inet_ops
|
7
|
+
#
|
8
|
+
# The most common usage is passing an expression to Sequel.pg_inet_op:
|
9
|
+
#
|
10
|
+
# r = Sequel.pg_inet_op(:inet)
|
11
|
+
#
|
12
|
+
# Also, on most Sequel expression objects, you can call the pg_inet
|
13
|
+
# method:
|
14
|
+
#
|
15
|
+
# r = Sequel.expr(:ip).pg_inet
|
16
|
+
#
|
17
|
+
# If you have loaded the {core_extensions extension}[rdoc-ref:doc/core_extensions.rdoc],
|
18
|
+
# or you have loaded the core_refinements extension
|
19
|
+
# and have activated refinements for the file, you can also use Symbol#pg_inet:
|
20
|
+
#
|
21
|
+
# r = :inet.pg_inet
|
22
|
+
#
|
23
|
+
# This creates a Sequel::Postgres::InetOp object that can be used
|
24
|
+
# for easier querying:
|
25
|
+
#
|
26
|
+
# ~r # ~inet
|
27
|
+
# r & other # inet & other
|
28
|
+
# r | other # inet | other
|
29
|
+
# r << :other # inet << other
|
30
|
+
# r >> :other # inet >> other
|
31
|
+
#
|
32
|
+
# r.contained_by(:other) # inet << other
|
33
|
+
# r.contained_by_or_equals(:other) # inet <<= other
|
34
|
+
# r.contains(:other) # inet >> other
|
35
|
+
# r.contains_or_equals(:other) # inet >>= other
|
36
|
+
# r.contains_or_contained_by(:other) # inet && other
|
37
|
+
#
|
38
|
+
# r.abbrev # abbrev(inet)
|
39
|
+
# r.broadcast # broadcast(inet)
|
40
|
+
# r.family # family(inet)
|
41
|
+
# r.host # host(inet)
|
42
|
+
# r.hostmask # hostmask(inet)
|
43
|
+
# r.masklen # masklen(inet)
|
44
|
+
# r.netmask # netmask(inet)
|
45
|
+
# r.network # network(inet)
|
46
|
+
# r.set_masklen(16) # set_masklen(inet, 16)
|
47
|
+
# r.text # text(inet)
|
48
|
+
#
|
49
|
+
# If a String or IPAddr instance is passed to Sequel.pg_inet_op, it will automatically
|
50
|
+
# be cast to +inet+. To treat the object as a +cidr+, you must cast it before passing
|
51
|
+
# it to Sequel.pg_inet_op:
|
52
|
+
#
|
53
|
+
# r = Sequel.pg_inet_op(Sequel.cast('1.2.3.4', :cidr))
|
54
|
+
#
|
55
|
+
# See the PostgreSQL network function and operator documentation for more
|
56
|
+
# details on what these functions and operators do.
|
57
|
+
|
58
|
+
require 'ipaddr'
|
59
|
+
|
60
|
+
module Sequel
|
61
|
+
module Postgres
|
62
|
+
# The InetOp class is a simple container for a single object that
|
63
|
+
# defines methods that yield Sequel expression objects representing
|
64
|
+
# PostgreSQL inet operators and functions.
|
65
|
+
#
|
66
|
+
# Most methods in this class are defined via metaprogramming, see
|
67
|
+
# the pg_inet_ops extension documentation for details on the API.
|
68
|
+
class InetOp < Sequel::SQL::Wrapper
|
69
|
+
include Sequel::SQL::BitwiseMethods
|
70
|
+
|
71
|
+
# For String and IPAddr instances, wrap them in a cast to inet,
|
72
|
+
# to avoid ambiguity issues when calling operator methods.
|
73
|
+
def initialize(v)
|
74
|
+
case v
|
75
|
+
when ::Sequel::LiteralString
|
76
|
+
# nothing
|
77
|
+
when String, IPAddr
|
78
|
+
v = Sequel.cast(v, :inet)
|
79
|
+
end
|
80
|
+
super
|
81
|
+
end
|
82
|
+
|
83
|
+
OPERATORS = {
|
84
|
+
:contained_by_or_equals => ["(".freeze, " <<= ".freeze, ")".freeze].freeze,
|
85
|
+
:contains_or_equals => ["(".freeze, " >>= ".freeze, ")".freeze].freeze,
|
86
|
+
:contains_or_contained_by => ["(".freeze, " && ".freeze, ")".freeze].freeze,
|
87
|
+
}.freeze
|
88
|
+
|
89
|
+
OPERATORS.keys.each do |f|
|
90
|
+
class_eval("def #{f}(v) Sequel::SQL::BooleanExpression.new(:NOOP, operator(:#{f}, v)) end", __FILE__, __LINE__)
|
91
|
+
end
|
92
|
+
|
93
|
+
%w'<< >>'.each do |f|
|
94
|
+
class_eval("def #{f}(v) Sequel::SQL::BooleanExpression.new(:NOOP, super) end", __FILE__, __LINE__)
|
95
|
+
end
|
96
|
+
|
97
|
+
%w'& | +'.each do |f|
|
98
|
+
class_eval("def #{f}(v) self.class.new(super) end", __FILE__, __LINE__)
|
99
|
+
end
|
100
|
+
|
101
|
+
%w'abbrev host text'.each do |f|
|
102
|
+
class_eval("def #{f}() Sequel::SQL::StringExpression.new(:NOOP, function(:#{f})) end", __FILE__, __LINE__)
|
103
|
+
end
|
104
|
+
|
105
|
+
%w'family masklen'.each do |f|
|
106
|
+
class_eval("def #{f}() Sequel::SQL::NumericExpression.new(:NOOP, function(:#{f})) end", __FILE__, __LINE__)
|
107
|
+
end
|
108
|
+
|
109
|
+
%w'broadcast hostmask netmask network'.each do |f|
|
110
|
+
class_eval("def #{f}() self.class.new(function(:#{f})) end", __FILE__, __LINE__)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Return the receiver.
|
114
|
+
def pg_inet
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
# Return an expression for the bitwise NOT of the receiver
|
119
|
+
def ~
|
120
|
+
self.class.new(super)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Return an expression for the subtraction of the argument from the receiver
|
124
|
+
def -(v)
|
125
|
+
case v
|
126
|
+
when Integer
|
127
|
+
self.class.new(super)
|
128
|
+
else
|
129
|
+
Sequel::SQL::NumericExpression.new(:NOOP, super)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Return an expression for the calling of the set_masklen function with the receiver and the given argument
|
134
|
+
def set_masklen(v)
|
135
|
+
self.class.new(Sequel::SQL::Function.new(:set_masklen, self, v))
|
136
|
+
end
|
137
|
+
|
138
|
+
alias contained_by <<
|
139
|
+
alias contains >>
|
140
|
+
|
141
|
+
undef_method :*, :/
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
# Handle PostgreSQL specific operator types
|
146
|
+
def operator(type, other)
|
147
|
+
Sequel::SQL::PlaceholderLiteralString.new(OPERATORS[type], [value, other])
|
148
|
+
end
|
149
|
+
|
150
|
+
# Return a function called with the receiver.
|
151
|
+
def function(name)
|
152
|
+
Sequel::SQL::Function.new(name, self)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
module InetOpMethods
|
157
|
+
# Wrap the receiver in an InetOp so you can easily use the PostgreSQL
|
158
|
+
# inet functions and operators with it.
|
159
|
+
def pg_inet
|
160
|
+
InetOp.new(self)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
module SQL::Builders
|
166
|
+
# Return the expression wrapped in the Postgres::InetOp.
|
167
|
+
def pg_inet_op(v)
|
168
|
+
case v
|
169
|
+
when Postgres::InetOp
|
170
|
+
v
|
171
|
+
else
|
172
|
+
Postgres::InetOp.new(v)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class SQL::GenericExpression
|
178
|
+
include Sequel::Postgres::InetOpMethods
|
179
|
+
end
|
180
|
+
|
181
|
+
class LiteralString
|
182
|
+
include Sequel::Postgres::InetOpMethods
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# :nocov:
|
187
|
+
if Sequel.core_extensions?
|
188
|
+
class Symbol
|
189
|
+
include Sequel::Postgres::InetOpMethods
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
if defined?(Sequel::CoreRefinements)
|
194
|
+
module Sequel::CoreRefinements
|
195
|
+
refine Symbol do
|
196
|
+
include Sequel::Postgres::InetOpMethods
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
# :nocov:
|