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(".")