pg_conn 0.24.0 → 0.26.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/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
|