ListQuery
Use db.ListQuery to read multiple database rows from a prepared db.Query value.
Use db.ListQuery when you already have a db.Query value and expect multiple rows.
It scans all returned rows into a typed Go slice.
users, err := db.ListQuery[User](ctx, conn, q)
if err != nil {
return nil, err
}ListQuery is the query-object version of db.List.
Function
func ListQuery[T any](ctx context.Context, c db.Querier, q db.Query) ([]T, error)ListQuery accepts:
- a
context.Context - a connection or query-capable value
- a
db.Query
It returns:
[]T, errorWhen to Use ListQuery
Use db.ListQuery when:
- you already created a
db.Query - the query can return zero or more rows
- the result shape is known
- you want a typed
[]T - query creation and query execution are separate steps
- the query was created by
db.Rawordb.Dialect
For direct query strings, use db.List.
Define a Model
type User struct {
ID int64 `db:"id"`
Name string `db:"name"`
Email string `db:"email"`
Active bool `db:"active"`
CreatedAt time.Time `db:"created_at"`
}Create a Query Object
Create a db.Query using db.Raw.
For MySQL and Scylla, use ? placeholders.
const selectUsersQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT ?
`q, err := db.Raw(selectUsersQuery, 10)
if err != nil {
return nil, err
}For PostgreSQL, the query uses numbered placeholders.
const selectUsersQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT $1
`The Go code stays the same:
q, err := db.Raw(selectUsersQuery, 10)
if err != nil {
return nil, err
}Execute the Query Object
Pass the query object into db.ListQuery.
users, err := db.ListQuery[User](ctx, conn, q)
if err != nil {
return nil, err
}Complete Query Example
This example creates a db.Query and reads users as a typed slice.
package main
import (
"context"
"time"
"github.com/netlifeguru/db"
)
type User struct {
ID int64 `db:"id"`
Name string `db:"name"`
Email string `db:"email"`
Active bool `db:"active"`
CreatedAt time.Time `db:"created_at"`
}
const selectUsersQuery = `
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT ?
`
func ListUsersQuery(ctx context.Context, conn db.Conn, limit int) ([]User, error) {
q, err := db.Raw(selectUsersQuery, limit)
if err != nil {
return nil, err
}
return db.ListQuery[User](ctx, conn, q)
}Complete Usage Example
This example connects to the database, executes the query-object helper, and prints the result.
package main
import (
"context"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
"github.com/joho/godotenv"
)
func main() {
err := godotenv.Load()
if err != nil {
log.Println(".env file not found, I'm using system env variables")
}
conn, err := connectDB()
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
users, err := ListUsersQuery(ctx, conn, 10)
if err != nil {
log.Fatal(err)
}
for _, user := range users {
fmt.Printf(
"ID: %d | Name: %s | Email: %s | Active: %t | Created: %s\n",
user.ID,
user.Name,
user.Email,
user.Active,
user.CreatedAt.Format("2006-01-02 15:04:05"),
)
}
}Empty Results
If the query returns no rows, db.ListQuery returns an empty slice.
users, err := db.ListQuery[User](ctx, conn, q)
if err != nil {
return nil, err
}
fmt.Println(len(users)) // 0An empty result is not treated as an error.
Raw Query Validation
db.Raw returns an error when the query string is empty.
q, err := db.Raw("", 10)
if err != nil {
return nil, err
}This prevents empty query objects from being executed accidentally.
Query Objects From Dialect SQL
ListQuery is often used together with db.Dialect.
q, err := db.Dialect(conn, queries.ListUsers, 10)
if err != nil {
return nil, err
}
return db.ListQuery[User](ctx, conn, q)For direct dialect usage, you can also use db.ListDialect.
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)Related Helpers
Use db.List when you want to pass the query string directly.
users, err := db.List[User](ctx, conn, selectUsersQuery, 10)Use db.GetQuery when the query object should return zero or one row.
user, found, err := db.GetQuery[User](ctx, conn, q)Use db.ValueQuery when the query object returns one scalar value.
total, found, err := db.ValueQuery[int64](ctx, conn, q)Use db.MapsQuery when the query object returns dynamic map rows.
rows, err := db.MapsQuery(ctx, conn, q)Related Examples
Standalone examples are available in the examples repository: