|
7 | 7 | "github.com/icinga/icinga-go-library/com" |
8 | 8 | "github.com/icinga/icinga-go-library/strcase" |
9 | 9 | "github.com/icinga/icinga-go-library/types" |
| 10 | + "github.com/jmoiron/sqlx" |
10 | 11 | "github.com/pkg/errors" |
11 | 12 | "strconv" |
12 | 13 | ) |
@@ -44,6 +45,42 @@ func SplitOnDupId[T IDer]() com.BulkChunkSplitPolicy[T] { |
44 | 45 | } |
45 | 46 | } |
46 | 47 |
|
| 48 | +// InsertObtainID executes the given query and fetches the last inserted ID. |
| 49 | +// |
| 50 | +// Using this method for database tables that don't define an auto-incrementing ID, or none at all, |
| 51 | +// will not work. The only supported column that can be retrieved with this method is id. |
| 52 | +// |
| 53 | +// This function expects [TxOrDB] as an executor of the provided query, and is usually a *[sqlx.Tx] or *[DB] instance. |
| 54 | +// |
| 55 | +// Returns the retrieved ID on success and error on any database inserting/retrieving failure. |
| 56 | +func InsertObtainID(ctx context.Context, conn TxOrDB, stmt string, arg any) (int64, error) { |
| 57 | + var resultID int64 |
| 58 | + switch conn.DriverName() { |
| 59 | + case PostgreSQL: |
| 60 | + stmt = stmt + " RETURNING id" |
| 61 | + query, args, err := conn.BindNamed(stmt, arg) |
| 62 | + if err != nil { |
| 63 | + return 0, errors.Wrapf(err, "cannot bind named query %q", stmt) |
| 64 | + } |
| 65 | + |
| 66 | + if err := sqlx.GetContext(ctx, conn, &resultID, query, args...); err != nil { |
| 67 | + return 0, CantPerformQuery(err, query) |
| 68 | + } |
| 69 | + default: |
| 70 | + result, err := sqlx.NamedExecContext(ctx, conn, stmt, arg) |
| 71 | + if err != nil { |
| 72 | + return 0, CantPerformQuery(err, stmt) |
| 73 | + } |
| 74 | + |
| 75 | + resultID, err = result.LastInsertId() |
| 76 | + if err != nil { |
| 77 | + return 0, errors.Wrap(err, "cannot retrieve last inserted ID") |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + return resultID, nil |
| 82 | +} |
| 83 | + |
47 | 84 | // setGaleraOpts sets the "wsrep_sync_wait" variable for each session ensures that causality checks are performed |
48 | 85 | // before execution and that each statement is executed on a fully synchronized node. Doing so prevents foreign key |
49 | 86 | // violation when inserting into dependent tables on different MariaDB/MySQL nodes. When using MySQL single nodes, |
|
0 commit comments