CRUD operations
Insert, Find, FindOne, Count, Update, and Delete.
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]anyFind 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]anyNeed 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}) // filteredOn 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 ANDed — WHERE 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.