ListDialect
Use db.ListDialect to read multiple rows using driver-specific SQL selected from db.DialectSQL.
Use db.ListDialect when you want to read multiple rows from a db.DialectSQL query.
ListDialect selects the correct SQL or CQL text for the active driver and scans the returned rows into a typed Go slice.
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)
if err != nil {
return nil, err
}Function
func ListDialect[T any](ctx context.Context, c db.DialectQuerier, q db.DialectSQL, args ...any) ([]T, error)ListDialect accepts:
- a
context.Context - a dialect-capable connection
- a
db.DialectSQLvalue - optional query arguments
It returns:
[]T, errorWhen to Use ListDialect
Use db.ListDialect when:
- the query can return zero or more rows
- the result should be scanned into
[]T - the application may run with different database drivers
- SQL syntax differs between drivers
- placeholder styles differ between drivers
- queries are loaded from SQL model files
For direct query strings, use db.List.
For query objects, use db.ListQuery.
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"`
}Define Query Model
A query model stores one logical query with driver-specific SQL.
type Queries struct {
ListUsers db.DialectSQL `json:"ListUsers"`
}ListUsers can contain different SQL for each driver.
queries.ListUsers.Mysql
queries.ListUsers.Postgres
queries.ListUsers.ScyllaApplication code usually should not select these fields manually.
Pass the whole db.DialectSQL value to db.ListDialect.
SQL File Example
For MySQL, model.sql may contain:
--ListUsers
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT ?For PostgreSQL, model.psql may contain:
--ListUsers
SELECT *
FROM users
ORDER BY created_at DESC
LIMIT $1For Scylla, model.cql may contain:
--ListUsers
SELECT *
FROM users_by_status
WHERE status = ?
LIMIT ?Load Queries
Load the query model with db.LoadModel.
func LoadQueries(conn db.Conn) (Queries, error) {
var queries Queries
if err := db.LoadModel(conn, ".", &queries); err != nil {
return Queries{}, err
}
return queries, nil
}The active driver decides which model file is loaded:
model.sql -> MySQL
model.psql -> PostgreSQL
model.cql -> ScyllaComplete Query Example
This example loads the query model and uses db.ListDialect.
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"`
}
type Queries struct {
ListUsers db.DialectSQL `json:"ListUsers"`
}
func LoadQueries(conn db.Conn) (Queries, error) {
var queries Queries
if err := db.LoadModel(conn, ".", &queries); err != nil {
return Queries{}, err
}
return queries, nil
}
func ListUsersDialect(ctx context.Context, conn db.Conn, queries Queries, limit int) ([]User, error) {
return db.ListDialect[User](ctx, conn, queries.ListUsers, limit)
}Complete Usage Example
This example connects to the database, loads SQL from the active driver model, and prints users.
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()
queries, err := LoadQueries(conn)
if err != nil {
log.Fatal(err)
}
users, err := ListUsersDialect(ctx, conn, queries, 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"),
)
}
}Driver Selection
ListDialect selects the SQL field based on the active driver.
| Active driver | Selected query |
|---|---|
| MySQL | queries.ListUsers.Mysql |
| Postgres | queries.ListUsers.Postgres |
| Scylla | queries.ListUsers.Scylla |
If the selected query is empty, ListDialect returns an error.
Arguments
Arguments are passed to the selected query.
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)For MySQL, the selected query may use:
LIMIT ?For PostgreSQL:
LIMIT $1For Scylla:
WHERE status = ?
LIMIT ?The Go call stays the same, but the SQL/CQL text must match the active driver.
Empty Results
If the query returns no rows, db.ListDialect returns an empty slice.
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)
if err != nil {
return nil, err
}
fmt.Println(len(users)) // 0An empty result is not treated as an error.
Low-Level Equivalent
ListDialect is a convenience helper.
This:
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)is equivalent to:
q, err := db.Dialect(conn, queries.ListUsers, 10)
if err != nil {
return nil, err
}
users, err := db.ListQuery[User](ctx, conn, q)
if err != nil {
return nil, err
}Use the low-level form when you need access to the selected db.Query.
Related Helpers
Use db.GetDialect when the dialect query should return zero or one row.
user, found, err := db.GetDialect[User](ctx, conn, queries.GetUser, id)Use db.ValueDialect when the dialect query returns one scalar value.
total, found, err := db.ValueDialect[int64](ctx, conn, queries.CountUsers)Use db.MapsDialect when the dialect query returns dynamic map rows.
rows, err := db.MapsDialect(ctx, conn, queries.EventsReport, 10)Related Examples
Standalone examples are available in the examples repository: