lib/pg_conn.rb in pg_conn-0.24.0 vs lib/pg_conn.rb in pg_conn-0.25.0
- old
+ new
@@ -628,11 +628,14 @@
#
# Insert record(s) in table and return id(s)
#
# There is no variant that takes a single tuple because it would then be
# impossible to have array or hash field values
- def insert(*args)
+ def insert(*args, upsert: nil, **opts)
+ # Add options to args except the special :upsert option
+ args << opts if !opts.empty?
+
# Add schema (=nil) if absent
args.unshift nil if args.size == 2 || (args.size == 3 && args[1].is_a?(Array))
# Add fields (=nil) if absent
args.insert(-2, nil) if !args[-2].is_a?(Array)
@@ -663,18 +666,34 @@
elsif data.is_a?(Hash)
method = :value
fields ||= data.keys
tuples = [fields.map { |field| data[field] }]
else
- raise ArgumentError
+ raise ArgumentError, "Illegal argument '#{data.inspect}'"
end
+ # On-conflict clause
+ upsert_sql =
+ case upsert
+ when true; "on conflict do nothing"
+ when String; "on conlict #{upsert}"
+ when false, nil; ""
+ else
+ raise ArgumentError, "Illegal value for :upsert option: #{upsert.inspect}"
+ end
+
# Execute SQL statement using either :value or :values depending on data arity
self.send method, %(
insert into #{table} (#{quote_identifiers(fields)})
values #{quote_tuples(tuples)}
+ #{upsert_sql}
returning id
)
+ end
+
+ # Use upsert. Currently on 'on conflict do nothing' is supported
+ def upsert(*args)
+ insert(*args, upsert: true)
end
# Update record(s)
def update(schema = nil, table, expr, hash)
table = [schema, table].compact.join(".")