Files
gf/contrib/drivers/pgsql/pgsql_do_insert.go

76 lines
2.2 KiB
Go
Raw Normal View History

2024-01-30 20:03:58 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package pgsql
import (
"context"
"database/sql"
2024-01-30 20:03:58 +08:00
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
2025-12-04 20:33:08 +08:00
"github.com/gogf/gf/v2/text/gstr"
2024-01-30 20:03:58 +08:00
)
// DoInsert inserts or updates data for given table.
2025-12-08 14:37:35 +08:00
// The list parameter must contain at least one record, which was previously validated.
func (d *Driver) DoInsert(
ctx context.Context,
link gdb.Link, table string, list gdb.List, option gdb.DoInsertOption,
) (result sql.Result, err error) {
2024-01-30 20:03:58 +08:00
switch option.InsertOption {
2025-12-08 14:37:35 +08:00
case
2025-12-08 16:28:34 +08:00
gdb.InsertOptionSave,
gdb.InsertOptionReplace:
2025-12-04 20:33:08 +08:00
// PostgreSQL does not support REPLACE INTO syntax, use Save (ON CONFLICT ... DO UPDATE) instead.
// Automatically detect primary keys if OnConflict is not specified.
if len(option.OnConflict) == 0 {
2025-12-08 16:28:34 +08:00
primaryKeys, err := d.Core.GetPrimaryKeys(ctx, table)
2025-12-04 20:33:08 +08:00
if err != nil {
return nil, gerror.WrapCode(
gcode.CodeInternalError,
err,
`failed to get primary keys for Save/Replace operation`,
2025-12-04 20:33:08 +08:00
)
}
2025-12-08 14:37:35 +08:00
foundPrimaryKey := false
for _, conflictKey := range primaryKeys {
if _, ok := list[0][conflictKey]; ok {
foundPrimaryKey = true
break
}
}
if !foundPrimaryKey {
2025-12-08 16:28:34 +08:00
return nil, gerror.NewCodef(
2025-12-04 20:33:08 +08:00
gcode.CodeMissingParameter,
2025-12-08 16:28:34 +08:00
`Replace/Save operation requires conflict detection: `+
`either specify OnConflict() columns or ensure table '%s' has a primary key in the data`,
table,
2025-12-04 20:33:08 +08:00
)
}
option.OnConflict = primaryKeys
}
// Treat Replace as Save operation
option.InsertOption = gdb.InsertOptionSave
2024-01-30 20:03:58 +08:00
case gdb.InsertOptionDefault:
tableFields, err := d.GetCore().GetDB().TableFields(ctx, table)
if err == nil {
for _, field := range tableFields {
if gstr.Equal(field.Key, "pri") {
2024-01-30 20:03:58 +08:00
pkField := *field
ctx = context.WithValue(ctx, internalPrimaryKeyInCtx, pkField)
break
}
}
}
2025-12-04 20:33:08 +08:00
default:
2024-01-30 20:03:58 +08:00
}
return d.Core.DoInsert(ctx, link, table, list, option)
}