package database import ( "context" "database/sql" "fmt" "slices" "strings" ) type insertOptions struct { ignore bool } type InsertOption func(*insertOptions) func WithIgnore() InsertOption { return func(o *insertOptions) { o.ignore = true } } func Insert(ctx context.Context, db *sql.DB, table string, values map[string]any, opts ...InsertOption) (int, error) { var ( id int args []any columns []string ) statement := /*sql*/ ` INSERT %s INTO %s (%s) VALUES (%s) RETURNING id ` options := insertOptions{} for _, opt := range opts { opt(&options) } ignore := "" if options.ignore { ignore = "OR IGNORE" } for key, value := range values { columns = append(columns, key) args = append(args, value) } placeholders := strings.Join(slices.Repeat([]string{"?"}, len(values)), ", ") statement = fmt.Sprintf(statement, ignore, table, strings.Join(columns, ", "), placeholders) return QueryOne(ctx, db, statement, args, func(r *sql.Rows) (int, error) { err := r.Scan(&id) return id, err }) }