Forge

CRUD operations

Insert, Find, FindOne, Count, Update, and Delete.

GitHub

All operations take a context.Context, a table name, and map[string]any values. Every value is bound as a parameter — never interpolated into the SQL string.

Insert

err := db.Insert(ctx, "users", map[string]any{"email": "a@b.com"})

Find one

Returns dbswitch.ErrNotFound when nothing matches.

row, err := db.FindOne(ctx, "users", map[string]any{"email": "a@b.com"})
// row is map[string]any

Find many

Pass nil (or an empty map) as the condition to select all rows.

rows, err := db.Find(ctx, "users", nil)          // all rows
rows, err = db.Find(ctx, "users", map[string]any{"active": true})
// rows is []map[string]any

Need sorting, a limit, or pagination? Use List instead of Find.

Count

Returns how many rows match the same equality-filter shape as Find/List — without fetching the rows themselves.

n, err := db.Count(ctx, "users", nil)                                  // all rows
n, err = db.Count(ctx, "users", map[string]any{"active": true})        // filtered

On PostgreSQL this compiles to SELECT COUNT(*) FROM "users" WHERE …. On DynamoDB, a non-"id" filter still costs a full-table Scan (with Select: COUNT) — see Backends.

Update

Returns the number of rows affected. Refuses an empty condition to avoid updating the whole table by accident.

n, err := db.Update(ctx, "users",
	map[string]any{"email": "c@d.com"},  // set
	map[string]any{"email": "a@b.com"},  // where
)

Delete

Returns rows affected. Also refuses an empty condition.

n, err := db.Delete(ctx, "users", map[string]any{"email": "c@d.com"})

Conditions are equality-only and ANDedWHERE col = val AND …. There are no <, >, OR, IN, LIKE, or joins yet. (Sorting, limits, and pagination are available via List — a cursor comparison is the one non-equality condition you get.) See Limitations.

Result values

Reads return map[string]any; value types are whatever the driver returns. For example, a Postgres UUID comes back as [16]byte and a timestamp as time.Time. Convert at your boundary — there is no struct mapping.

On this page