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
Select OverviewListGetValueMaps
DBQueryingSelect

List

Use db.List to read multiple database rows into a typed Go slice.

Use db.List when a query is expected to return multiple rows.

It scans all returned rows into a typed Go slice.

users, err := db.List[User](ctx, conn, selectUsersQuery, 10)
if err != nil {
	return nil, err
}

db.List is the most common helper for list endpoints and collection-style reads.

Function

func List[T any](ctx context.Context, c db.Conn, query string, args ...any) ([]T, error)

List accepts:

  • a context.Context
  • a db.Conn
  • a SQL or CQL query string
  • optional query arguments

It returns:

[]T, error

When to Use List

Use db.List when:

  • the query can return zero or more rows
  • the result shape is known
  • you want a typed []T
  • the result set can safely fit in memory
  • you are building list endpoints, reports, or search results

For very large result sets, prefer streaming patterns where appropriate.

Define a Model

Create a struct that represents one returned row.

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"`
}

The struct is mapped using the mapper package.

The db tags match returned column names.

Query

The query can be written directly in Go code.

For MySQL and Scylla, use ? placeholders.

const selectUsersQuery = `
	SELECT *
	FROM users
	ORDER BY created_at DESC
	LIMIT ?
`

For PostgreSQL, use numbered placeholders.

const selectUsersQuery = `
	SELECT *
	FROM users
	ORDER BY created_at DESC
	LIMIT $1
`

Complete Query Example

This example returns users as a typed slice.

package main

import (
	"context"
	"database/sql"
	"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 ListUsers(ctx context.Context, conn db.Conn, limit int) ([]User, error) {
	return db.List[User](ctx, conn, selectUsersQuery, limit)
}

Complete Usage Example

This example connects to the database, loads users, 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 := ListUsers(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.List returns an empty slice.

users, err := db.List[User](ctx, conn, selectUsersQuery, 10)
if err != nil {
	return nil, err
}

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

An empty result is not treated as an error.

This makes db.List a good fit for list endpoints and search results.

Driver Placeholder Differences

The Go call stays the same across drivers.

users, err := db.List[User](ctx, conn, selectUsersQuery, 10)

Only the query placeholder syntax changes.

DriverPlaceholder
MySQL?
Postgres$1
Scylla?

Scylla Example

For Scylla, queries are usually based on query tables.

const selectUsersByStatusQuery = `
	SELECT *
	FROM users_by_status
	WHERE status = ?
	LIMIT ?
`

func ListUsersByStatus(ctx context.Context, conn db.Conn, status string, limit int) ([]User, error) {
	return db.List[User](ctx, conn, selectUsersByStatusQuery, status, limit)
}

Related Helpers

Use db.Get when the query should return zero or one row.

user, found, err := db.Get[User](ctx, conn, selectUserQuery, id)

Use db.Value when the query returns a single scalar value.

total, found, err := db.Value[int64](ctx, conn, countUsersQuery)

Use db.Maps when the result shape is dynamic.

rows, err := db.Maps(ctx, conn, selectRowsQuery)

Related Examples

Standalone examples are available in the examples repository:

  • Select List

Select Overview

Learn the high-level select helpers for reading lists, single rows, scalar values, and map results.

Get

Use db.Get to read zero or one database row into a typed Go value.

On this page

FunctionWhen to Use ListDefine a ModelQueryComplete Query ExampleComplete Usage ExampleEmpty ResultsDriver Placeholder DifferencesScylla ExampleRelated HelpersRelated Examples