# HG changeset patch
# User Christophe de Vienne <christophe@cdevienne.info>
# Date 1639412682 -3600
#      Mon Dec 13 17:24:42 2021 +0100
# Node ID 49ce5682db45f99f167507180ae7193384d7f189
# Parent  d907e7ba03837e8b0112b27ad59981740c06f034
add SQLUpsertColumns

This version of SQLUpsert allows to choose which columns would be inserted,
and which columns would be updated only.

diff --git a/database/sql.go b/database/sql.go
--- a/database/sql.go
+++ b/database/sql.go
@@ -133,9 +133,15 @@
 
 // SQLUpsert generates a squirrel "upsert" statement
 func SQLUpsert(m Mapped) squirrel.InsertBuilder {
+	return SQLUpsertColumns(m, m.Columns(true), m.Columns(false))
+}
+
+func SQLUpsertColumns(
+	m Mapped, insertColumns []string, updateColumns []string,
+) squirrel.InsertBuilder {
 	updateSQL, updateArgs, err := squirrel.
 		Update(m.Table()).
-		SetMap(ValuesMap(m, m.Columns(false)...)).
+		SetMap(ValuesMap(m, updateColumns...)).
 		ToSql()
 	if err != nil {
 		panic(err)
@@ -147,12 +153,11 @@
 	}
 	suffix := "ON CONFLICT (" + m.PKeyColumn() + ") DO UPDATE SET " + updateParts[1]
 
-	allColumns := m.Columns(true)
 	q := squirrel.
 		Insert(m.Table()).
 		PlaceholderFormat(squirrel.Dollar).
-		Columns(allColumns...).
-		Values(m.Values(allColumns...)...).
+		Columns(insertColumns...).
+		Values(m.Values(insertColumns...)...).
 		Suffix(suffix, updateArgs...)
 	return q
 }
diff --git a/database/sql_helper.go b/database/sql_helper.go
--- a/database/sql_helper.go
+++ b/database/sql_helper.go
@@ -105,6 +105,17 @@
 	return nil
 }
 
+// Upsert upserts a Mapped into the db
+func (h *SQLHelper) UpsertColumns(insertColumns, updateColumns []string, instances ...Mapped) error {
+	for _, instance := range instances {
+		query := SQLUpsertColumns(instance, insertColumns, updateColumns)
+		if _, err := h.Exec(query); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 // Update updates the given Mapped into the db using their
 // pkey as predicate for the where clause
 func (h *SQLHelper) Update(instances ...Mapped) error {