Skip to content

Commit

Permalink
feat: use gen_random_uuid() for CockroachDB INSERTs
Browse files Browse the repository at this point in the history
  • Loading branch information
alnr committed Jan 20, 2023
1 parent fbb24cf commit 89b6848
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
43 changes: 39 additions & 4 deletions dialect_cockroach.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/gobuffalo/pop/v6/columns"
"github.com/gobuffalo/pop/v6/internal/defaults"
"github.com/gobuffalo/pop/v6/logging"
"github.com/gofrs/uuid"
_ "github.com/jackc/pgx/v4/stdlib" // Import PostgreSQL driver
"github.com/jmoiron/sqlx"
)
Expand Down Expand Up @@ -77,17 +78,17 @@ func (p *cockroach) Create(c *Connection, model *Model, cols columns.Columns) er
w := cols.Writeable()
var query string
if len(w.Cols) > 0 {
query = fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s) returning %s", p.Quote(model.TableName()), w.QuotedString(p), w.SymbolizedString(), model.IDField())
query = fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s) RETURNING %s", p.Quote(model.TableName()), w.QuotedString(p), w.SymbolizedString(), model.IDField())
} else {
query = fmt.Sprintf("INSERT INTO %s DEFAULT VALUES returning %s", p.Quote(model.TableName()), model.IDField())
query = fmt.Sprintf("INSERT INTO %s DEFAULT VALUES RETURNING %s", p.Quote(model.TableName()), model.IDField())
}
txlog(logging.SQL, c, query, model.Value)
stmt, err := c.Store.PrepareNamed(query)
stmt, err := c.Store.PrepareNamedContext(model.ctx, query)
if err != nil {
return err
}
id := map[string]interface{}{}
err = stmt.QueryRow(model.Value).MapScan(id)
err = stmt.QueryRowContext(model.ctx, model.Value).MapScan(id)
if err != nil {
if closeErr := stmt.Close(); closeErr != nil {
return fmt.Errorf("failed to close prepared statement: %s: %w", closeErr, err)
Expand All @@ -99,6 +100,40 @@ func (p *cockroach) Create(c *Connection, model *Model, cols columns.Columns) er
return fmt.Errorf("failed to close statement: %w", err)
}
return nil

case "UUID":
var query string
if model.ID() == emptyUUID {
cols.Remove(model.IDField())
w := cols.Writeable()
if len(w.Cols) > 0 {
query = fmt.Sprintf("INSERT INTO %s (%s, %s) VALUES (gen_random_uuid(), %s) RETURNING %s", p.Quote(model.TableName()), model.IDField(), w.QuotedString(p), w.SymbolizedString(), model.IDField())
} else {
query = fmt.Sprintf("INSERT INTO %s (%s) VALUES (gen_random_uuid()) RETURNING %s", p.Quote(model.TableName()), model.IDField(), model.IDField())
}
} else {
w := cols.Writeable()
w.Add(model.IDField())
query = fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s) RETURNING %s", p.Quote(model.TableName()), w.QuotedString(p), w.SymbolizedString(), model.IDField())
}
txlog(logging.SQL, c, query, model.Value)
stmt, err := c.Store.PrepareNamedContext(model.ctx, query)
if err != nil {
return err
}
var id uuid.UUID
err = stmt.QueryRowContext(model.ctx, model.Value).Scan(&id)
if err != nil {
if closeErr := stmt.Close(); closeErr != nil {
return fmt.Errorf("failed to close prepared statement: %s: %w", closeErr, err)
}
return err
}
model.setID(id)
if err := stmt.Close(); err != nil {
return fmt.Errorf("failed to close statement: %w", err)
}
return nil
}
return genericCreate(c, model, cols, p)
}
Expand Down
6 changes: 3 additions & 3 deletions query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,9 @@ func Test_ToSQL_RawQuery(t *testing.T) {
}

func Test_RawQuery_Empty(t *testing.T) {
Debug = true
defer func() { Debug = false }()

if PDB == nil {
t.Skip("skipping integration tests")
}
t.Run("EmptyQuery", func(t *testing.T) {
r := require.New(t)
transaction(func(tx *Connection) {
Expand Down

0 comments on commit 89b6848

Please sign in to comment.