pg_conn 0.24.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/TODO +5 -0
- data/lib/pg_conn/version.rb +1 -1
- data/lib/pg_conn.rb +75 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4148bbd8c21613249beed07d5248aa71780a8805881afc94899f9f29cd2d452d
|
4
|
+
data.tar.gz: 21bea1c8c108a4a135eb1d6936a56995b457db0e8192a17b745d0b3dd1676846
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cca5aea976d949607b1650e8f00347a22be14907c8296a26379cd804a51f5610bb9786bc21b3b9317496a00ef135564033f276d5e3300dbd4d133b056835a79
|
7
|
+
data.tar.gz: 8bcf303b9712c1e6de69c301115c88a53d908aad90c8bce6b8e73e912d6b710772fb88a6bb191bc34142ca29f016845bfbc035cda4670c91d5e3d407ce82907e
|
data/TODO
CHANGED
data/lib/pg_conn/version.rb
CHANGED
data/lib/pg_conn.rb
CHANGED
@@ -269,8 +269,8 @@ module PgConn
|
|
269
269
|
#
|
270
270
|
# The :elem_type option can be a postgres type name (String or Symbol) or
|
271
271
|
# an array of type names. It is used as the required explicit element
|
272
|
-
# type when the argument is an empty array.
|
273
|
-
#
|
272
|
+
# type when the argument is an empty array. It is not needed if the array
|
273
|
+
# is guaranteed to be non-empty. Nested arrays are not supported
|
274
274
|
#
|
275
275
|
def quote_value(value, elem_type: nil)
|
276
276
|
case value
|
@@ -294,19 +294,62 @@ module PgConn
|
|
294
294
|
|
295
295
|
# Quote values and concatenate them using ',' as separator
|
296
296
|
def quote_values(values, elem_type: nil)
|
297
|
-
|
298
|
-
|
297
|
+
values.map { |value| quote_value(value, elem_type: elem_type) }.join(", ")
|
298
|
+
end
|
299
|
+
|
300
|
+
# Quote an array of values as a tuple. The element types should be in the
|
301
|
+
# same order as the array arguments. #quote_tuples is same as #quote_values
|
302
|
+
# except the values may have different types (this makes no difference
|
303
|
+
# except in the case when the tuple may contain empty array(s))
|
304
|
+
def quote_tuple(tuple, elem_types: nil)
|
305
|
+
elem_types = Array(elem_types)
|
306
|
+
tuple.map { |value|
|
299
307
|
elem_type = value.is_a?(Array) ? elem_types&.shift : nil
|
300
308
|
quote_value(value, elem_type: elem_type)
|
301
309
|
}.join(", ")
|
302
310
|
end
|
303
311
|
|
304
|
-
# Quote an array of values as a tuple. Just an alias for #quote_values
|
305
|
-
def quote_tuple(tuple, elem_type: nil) = quote_values(tuple, elem_type: elem_type)
|
306
|
-
|
307
312
|
# Quote an array of tuples
|
308
|
-
def quote_tuples(tuples,
|
309
|
-
tuples.map { |tuple| "(#{
|
313
|
+
def quote_tuples(tuples, elem_types: nil)
|
314
|
+
tuples.map { |tuple| "(#{quote_tuple(tuple, elem_types: elem_types)})" }.join(", ")
|
315
|
+
end
|
316
|
+
|
317
|
+
# Quote a record and cast it into the given type, the type can also be a
|
318
|
+
# table or view. 'data' is a hash or struct representation of the record
|
319
|
+
#
|
320
|
+
# Note that the fields are retrived from the database so this method is not
|
321
|
+
# as fast as the other quote-methods. It is however very convenient when
|
322
|
+
# you're testing and need a composite type because record-quoting can
|
323
|
+
# easily become unwieldly
|
324
|
+
def quote_record(schema_name = nil, type, data, elem_types: nil)
|
325
|
+
qual_name = [schema_name, type].compact .join('.')
|
326
|
+
|
327
|
+
fields = self.values(%(
|
328
|
+
select attname
|
329
|
+
from pg_attribute
|
330
|
+
where
|
331
|
+
attrelid = '#{qual_name}'::regclass
|
332
|
+
and attnum > 0
|
333
|
+
and not attisdropped
|
334
|
+
order by attnum
|
335
|
+
)).map(&:to_sym)
|
336
|
+
|
337
|
+
values =
|
338
|
+
case data
|
339
|
+
when Hash; fields.map { |f| data[f] }
|
340
|
+
when OpenStruct; fields.map { |f| data.send(f) }
|
341
|
+
when Array; data
|
342
|
+
else
|
343
|
+
raise Error, "Illegal value #{data.inspect}"
|
344
|
+
end
|
345
|
+
|
346
|
+
"(#{quote_tuple(values, elem_types: elem_types)})::#{qual_name}"
|
347
|
+
end
|
348
|
+
|
349
|
+
def quote_records(schema_name = nil, type, datas, elem_types: nil)
|
350
|
+
qual_name = [schema_name, type].compact .join('.') + "[]"
|
351
|
+
records = datas.map { |data| quote_record(schema_name, type, data, elem_types: elem_types) }
|
352
|
+
"array[#{records.join(", ")}]::#{qual_name}"
|
310
353
|
end
|
311
354
|
|
312
355
|
# :call-seq:
|
@@ -630,7 +673,10 @@ module PgConn
|
|
630
673
|
#
|
631
674
|
# There is no variant that takes a single tuple because it would then be
|
632
675
|
# impossible to have array or hash field values
|
633
|
-
def insert(*args)
|
676
|
+
def insert(*args, upsert: nil, **opts)
|
677
|
+
# Add options to args except the special :upsert option
|
678
|
+
args << opts if !opts.empty?
|
679
|
+
|
634
680
|
# Add schema (=nil) if absent
|
635
681
|
args.unshift nil if args.size == 2 || (args.size == 3 && args[1].is_a?(Array))
|
636
682
|
|
@@ -648,7 +694,7 @@ module PgConn
|
|
648
694
|
|
649
695
|
# Find method and normalize data
|
650
696
|
if data.is_a?(Array) # Array of tuples
|
651
|
-
method = :values
|
697
|
+
method = :values # The pg_conn method when multiple records are inserted
|
652
698
|
if data.empty?
|
653
699
|
return []
|
654
700
|
elsif data.first.is_a?(Array) # Tuple (array) element. Requires the 'fields' argument
|
@@ -661,21 +707,37 @@ module PgConn
|
|
661
707
|
raise ArgumentError
|
662
708
|
end
|
663
709
|
elsif data.is_a?(Hash)
|
664
|
-
method = :value
|
710
|
+
method = :value # The pg_conn method when only one record is inserted
|
665
711
|
fields ||= data.keys
|
666
712
|
tuples = [fields.map { |field| data[field] }]
|
667
713
|
else
|
668
|
-
raise ArgumentError
|
714
|
+
raise ArgumentError, "Illegal argument '#{data.inspect}'"
|
669
715
|
end
|
670
716
|
|
717
|
+
# On-conflict clause
|
718
|
+
upsert_sql =
|
719
|
+
case upsert
|
720
|
+
when true; "on conflict do nothing"
|
721
|
+
when String; "on conlict #{upsert}"
|
722
|
+
when false, nil; ""
|
723
|
+
else
|
724
|
+
raise ArgumentError, "Illegal value for :upsert option: #{upsert.inspect}"
|
725
|
+
end
|
726
|
+
|
671
727
|
# Execute SQL statement using either :value or :values depending on data arity
|
672
728
|
self.send method, %(
|
673
729
|
insert into #{table} (#{quote_identifiers(fields)})
|
674
730
|
values #{quote_tuples(tuples)}
|
731
|
+
#{upsert_sql}
|
675
732
|
returning id
|
676
733
|
)
|
677
734
|
end
|
678
735
|
|
736
|
+
# Use upsert. Currently on 'on conflict do nothing' is supported
|
737
|
+
def upsert(*args)
|
738
|
+
insert(*args, upsert: true)
|
739
|
+
end
|
740
|
+
|
679
741
|
# Update record(s)
|
680
742
|
def update(schema = nil, table, expr, hash)
|
681
743
|
table = [schema, table].compact.join(".")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_conn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|