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

MapsDialect

Use db.MapsDialect to read dynamic map rows using driver-specific SQL selected from db.DialectSQL.

MapsDialect

Use db.MapsDialect when you want to read dynamic map[string]any rows from a db.DialectSQL query.

MapsDialect selects the correct SQL or CQL text for the active driver and returns the result as a slice of maps.

rows, err := db.MapsDialect(ctx, conn, queries.EventsReport, 10)
if err != nil {
	return nil, err
}

Function

func MapsDialect(ctx context.Context, c db.DialectQuerier, q db.DialectSQL, args ...any) ([]map[string]any, error)

MapsDialect accepts:

  • a context.Context
  • a dialect-capable connection
  • a db.DialectSQL value
  • optional query arguments

It returns:

[]map[string]any, error

Each returned map represents one database row.

When to Use MapsDialect

Use db.MapsDialect when:

  • the result shape is dynamic
  • the query may differ between drivers
  • queries are loaded from SQL model files
  • you are building reports, exports, admin tools, or generic views
  • you do not want to define a struct for the result
  • the application may run with MySQL, PostgreSQL, or Scylla

For direct query strings, use db.Maps.

For query objects, use db.MapsQuery.

Define Query Model

A query model stores one logical map-based query with driver-specific SQL.

type Queries struct {
	EventsReport db.DialectSQL `json:"EventsReport"`
}

Application code should usually pass the whole db.DialectSQL value to db.MapsDialect.

events, err := db.MapsDialect(ctx, conn, queries.EventsReport, 10)

SQL File Example

For MySQL, model.sql may contain:

--EventsReport
SELECT *
FROM events
ORDER BY created_at DESC
LIMIT ?

For PostgreSQL, model.psql may contain:

--EventsReport
SELECT *
FROM events
ORDER BY created_at DESC
LIMIT $1

For Scylla, model.cql may contain:

--EventsReport
SELECT *
FROM events_by_type
WHERE type = ?
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.MapsDialect.

package main

import (
	"context"

	"github.com/netlifeguru/db"
)

type Queries struct {
	EventsReport db.DialectSQL `json:"EventsReport"`
}

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 ListEventsDialect(ctx context.Context, conn db.Conn, queries Queries, limit int) ([]map[string]any, error) {
	return db.MapsDialect(ctx, conn, queries.EventsReport, limit)
}

Complete Usage Example

This example connects to the database, loads SQL from the active driver model, and prints dynamic map values.

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)
	}

	events, err := ListEventsDialect(ctx, conn, queries, 10)
	if err != nil {
		log.Fatal(err)
	}

	for _, event := range events {
		fmt.Printf(
			"ID: %v | Type: %v | Payload: %v | Created: %v\n",
			event["id"],
			event["type"],
			event["payload"],
			event["created_at"],
		)
	}
}

Returned Row Shape

Each row is represented as a map[string]any.

map[string]any{
	"id":         int64(1),
	"type":       "user.created",
	"payload":    `{"name":"John Doe"}`,
	"created_at": time.Now(),
}

The exact Go value types depend on the active driver and returned column types.

Driver Selection

MapsDialect selects the query field based on the active driver.

Active driverSelected query
MySQLqueries.EventsReport.Mysql
Postgresqueries.EventsReport.Postgres
Scyllaqueries.EventsReport.Scylla

If the selected query is empty, MapsDialect returns an error.

Arguments

Arguments are passed to the selected query.

events, err := db.MapsDialect(ctx, conn, queries.EventsReport, 10)

For MySQL, the selected query may use:

LIMIT ?

For PostgreSQL:

LIMIT $1

For Scylla:

WHERE type = ?
LIMIT ?

The Go call stays the same, but the SQL or CQL text must match the active driver.

SQL Aliases

Map keys are based on returned column names.

Use aliases when selecting computed values or joining tables.

SELECT
	u.id AS user_id,
	u.email AS user_email,
	COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.email

The returned map contains the alias names:

map[string]any{
	"user_id":     int64(1),
	"user_email":  "john@example.com",
	"order_count": int64(3),
}

Typed Access

For typed access, convert a returned map to mapper.Row.

row := mapper.Row(events[0])

eventType, ok := row.String("type")
if !ok {
	return errors.New("invalid event type")
}

Or use standalone mapper converters:

eventType, ok := mapper.AsString(events[0]["type"])
if !ok {
	return errors.New("invalid event type")
}

Use maps directly for generic output.

Use typed access when values are required for business logic.

Empty Results

If the selected query returns no rows, db.MapsDialect returns an empty slice.

events, err := db.MapsDialect(ctx, conn, queries.EventsReport, 10)
if err != nil {
	return nil, err
}

fmt.Println(len(events)) // 0

An empty result is not treated as an error.

Low-Level Equivalent

MapsDialect is a convenience helper.

This:

events, err := db.MapsDialect(ctx, conn, queries.EventsReport, 10)

is equivalent to:

q, err := db.Dialect(conn, queries.EventsReport, 10)
if err != nil {
	return nil, err
}

events, err := db.MapsQuery(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.ListDialect when the dialect query returns multiple typed rows.

users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)

Use db.GetDialect when the dialect query returns zero or one typed 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)

Related Examples

Standalone examples are available in the examples repository:

ValueDialect

Use db.ValueDialect to read a single scalar value using driver-specific SQL selected from db.DialectSQL.

Exec

Execute SQL or CQL statements using Exec, ExecQuery, Insert, Update, and Delete.

On this page

MapsDialectFunctionWhen to Use MapsDialectDefine Query ModelSQL File ExampleLoad QueriesComplete Query ExampleComplete Usage ExampleReturned Row ShapeDriver SelectionArgumentsSQL AliasesTyped AccessEmpty ResultsLow-Level EquivalentRelated HelpersRelated Examples