GetDialect
Use db.GetDialect to read zero or one row using driver-specific SQL selected from db.DialectSQL.
GetDialect
Use db.GetDialect when you want to read zero or one row from a db.DialectSQL query.
GetDialect selects the correct SQL or CQL text for the active driver and scans the returned row into a typed Go value.
user, found, err := db.GetDialect[User](ctx, conn, queries.GetUser, id)
if err != nil {
return User{}, false, err
}
if !found {
return User{}, false, nil
}Function
func GetDialect[T any](ctx context.Context, c db.DialectQuerier, q db.DialectSQL, args ...any) (T, bool, error)GetDialect accepts:
- a
context.Context - a dialect-capable connection
- a
db.DialectSQLvalue - optional query arguments
It returns:
T, found, errorfound is false when the query returns no rows.
When to Use GetDialect
Use db.GetDialect when:
- the query should return one row or no rows
- 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
- a missing row is a normal application case
For direct query strings, use db.Get.
For query objects, use db.GetQuery.
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 {
GetUser db.DialectSQL `json:"GetUser"`
}Application code should usually pass the whole db.DialectSQL value to db.GetDialect.
user, found, err := db.GetDialect[User](ctx, conn, queries.GetUser, id)SQL File Example
For MySQL, model.sql may contain:
--GetUser
SELECT *
FROM users
WHERE id = ?
LIMIT 1For PostgreSQL, model.psql may contain:
--GetUser
SELECT *
FROM users
WHERE id = $1
LIMIT 1For Scylla, model.cql may contain:
--GetUser
SELECT *
FROM users_by_id
WHERE id = ?
LIMIT 1Load 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.GetDialect.
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 {
GetUser db.DialectSQL `json:"GetUser"`
}
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 GetUserDialect(ctx context.Context, conn db.Conn, queries Queries, id int64) (User, bool, error) {
return db.GetDialect[User](ctx, conn, queries.GetUser, id)
}Complete Usage Example
This example connects to the database, loads SQL from the active driver model, and reads one user.
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)
}
user, found, err := GetUserDialect(ctx, conn, queries, 1)
if err != nil {
log.Fatal(err)
}
if !found {
log.Println("user not found")
return
}
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"),
)
}Not Found
db.GetDialect does not return an error when no row is found.
Instead, it returns found = false.
user, found, err := db.GetDialect[User](ctx, conn, queries.GetUser, id)
if err != nil {
return User{}, false, err
}
if !found {
return User{}, false, nil
}This is useful for optional lookups.
Too Many Rows
db.GetDialect expects zero or one row.
If the selected query returns more than one row, it returns an error.
Use a unique condition or LIMIT 1 when only one row should be returned.
SELECT *
FROM users
WHERE id = ?
LIMIT 1Avoid LIMIT 1 when duplicate rows should be detected by the application.
Driver Selection
GetDialect selects the query field based on the active driver.
| Active driver | Selected query |
|---|---|
| MySQL | queries.GetUser.Mysql |
| Postgres | queries.GetUser.Postgres |
| Scylla | queries.GetUser.Scylla |
If the selected query is empty, GetDialect returns an error.
Arguments
Arguments are passed to the selected query.
user, found, err := db.GetDialect[User](ctx, conn, queries.GetUser, id)For MySQL, the selected query may use:
WHERE id = ?For PostgreSQL:
WHERE id = $1For Scylla:
WHERE id = ?The Go call stays the same, but the SQL or CQL text must match the active driver.
Low-Level Equivalent
GetDialect is a convenience helper.
This:
user, found, err := db.GetDialect[User](ctx, conn, queries.GetUser, id)is equivalent to:
q, err := db.Dialect(conn, queries.GetUser, id)
if err != nil {
return User{}, false, err
}
user, found, err := db.GetQuery[User](ctx, conn, q)
if err != nil {
return User{}, false, err
}Use the low-level form when you need access to the selected db.Query.
Related Helpers
Use db.ListDialect when the dialect query can return multiple rows.
users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)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: