Quarry Docs
GitHub
Example

Results Scanning

Quarry's scan layer is intentionally smaller than an ORM, but it still covers the practical cases: structs, pointers, nullables, scalar values, and queries that run through a transaction.

Quarry logo

Struct hydration

type UserView struct {
    ID        int            `db:"id"`
    Email     string         `db:"email"`
    CreatedAt time.Time       `db:"created_at"`
    Nickname  *string        `db:"nickname"`
    Status    sql.NullString `db:"status"`
}
users, err := scan.All[UserView](ctx, db,
    qq.Select(
        quarry.C("id"),
        quarry.C("email"),
        quarry.C("created_at"),
        quarry.C("nickname"),
        quarry.C("status"),
    ).
        From("users").
        Where(quarry.Eq("tenant_id", 42)),
)
Tag precedence db tags win first, then json, then snake_case matching. Unknown columns are ignored so you can select a little more than you scan.

One row, maybe one row

One is the strict version. MaybeOne is the zero-or-one version. Both keep the row-count contract explicit.

One

user, err := scan.One[UserView](ctx, db,
    qq.Select("id", "email").
        From("users").
        Where(quarry.Eq("id", 9)),
)

MaybeOne

user, err := scan.MaybeOne[UserView](ctx, db,
    qq.Select("id", "email").
        From("users").
        Where(quarry.Eq("email", "ada@example.com")),
)

Transactions and writes

tx, err := db.BeginTx(ctx, nil)
if err != nil {
    return err
}
defer tx.Rollback()

if _, err := scan.Exec(ctx, tx,
    qq.Update("users").
        Set("last_seen_at", time.Now()).
        Where(quarry.Eq("id", 9)),
); err != nil {
    return err
}

The same helpers work with *sql.DB and *sql.Tx. The package only cares that the handle exposes the right context methods.

Scalar and aggregate scans

count, err := scan.One[int64](ctx, db,
    qq.Select(quarry.Raw("COUNT(*)")).
        From("users").
        Where(quarry.Eq("tenant_id", 42)),
)
emails, err := scan.All[string](ctx, db,
    qq.Select("email").
        From("users").
        Where(quarry.Eq("active", true)),
)

For the lower-level execution helpers, see Scan and Errors.