NetLife Guru

Open source Go packages for fast, maintainable web systems. Built with a documentation-first approach.

Product
OverviewGolang packagesNews
Documentation
DocumentationGo LoggerGo RouterGo DB Form
Company
OverviewContactNewsGitHub
Community / Support
Supportinfo@netlife.guru
© 2026 NetLife Guru. All rights reserved.
GitHubinfo@netlife.guru
NetLife GuruNetLife GuruNetLife Guru
NetLife GuruNetLife GuruNetLife Guru
OverviewDocumentationNewsSupportContact

Golang packages

AboutMulti-DriverSQL Files
Dialect SQL OverviewListDialectGetDialectValueDialectMapsDialect
DBQueryingDialect SQL

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.DialectSQL value
  • optional query arguments

It returns:

[]T, error

When 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.Scylla

Application 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 $1

For 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  -> Scylla

Complete 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 driverSelected query
MySQLqueries.ListUsers.Mysql
Postgresqueries.ListUsers.Postgres
Scyllaqueries.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 $1

For 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)) // 0

An 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:

  • Dialect List

Dialect SQL Overview

Learn how to use db.DialectSQL with driver-specific SQL and shared query helpers.

GetDialect

Use db.GetDialect to read zero or one row using driver-specific SQL selected from db.DialectSQL.

On this page

FunctionWhen to Use ListDialectDefine a ModelDefine Query ModelSQL File ExampleLoad QueriesComplete Query ExampleComplete Usage ExampleDriver SelectionArgumentsEmpty ResultsLow-Level EquivalentRelated HelpersRelated Examples