mapper

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2026 License: MIT Imports: 8 Imported by: 0

README

NLG DB Mapper

Fast SQL row-to-struct mapping for Go applications.

Use mapper to scan database rows into Go structs with minimal boilerplate, reflection caching, and flexible field mapping support.

Go Reference Go Report Card Go Version License


Mapper

Mapper is a small standalone utility package for scanning database rows into Go structs, maps, or custom row handlers.

You usually do not need to learn it deeply unless you want direct control over row scanning. When using NetLife Guru database drivers, mapper is already used internally.

It works with any database driver that can be adapted to the mapper.Rows interface.

Note

Mapper is database-agnostic and can be used with different SQL-compatible systems such as MySQL, PostgreSQL, ScyllaDB, CockroachDB, MariaDB, and similar drivers.

The package does not depend on a specific database engine. It only needs rows that can be adapted to the mapper.Rows interface.

For clarity and consistency, the examples in this documentation use MySQL, but the same mapping concepts apply to other supported database systems.

Features

  • Standalone Package: Can be used independently without the NetLife Guru database layer
  • Database Agnostic: Works with any driver that can expose rows through the mapper.Rows interface
  • Struct Mapping: Scans database rows directly into Go structs
  • Column Name Matching: Maps columns by name instead of relying on scan position
  • Tag Support: Uses db tags first, then json tags, and falls back to field names
  • Snake Case Fallback: Automatically supports snake_case column names for exported struct fields
  • Map Scanning: Scans rows into map[string]any for dynamic use cases
  • Custom Mapping: Supports custom row mapping through the ScanMapper interface
  • Nullable Value Support: Handles nullable-style structs with fields such as String, Time, Bool, Int64, Float64, and Valid
  • Pointer Support: Assigns scanned values into pointer fields when needed
  • JSON Field Support: Can assign JSON strings or byte slices into slices and maps
  • Typed Row Helpers: Provides helper methods for reading int, int64, string, bool, and time.Time from row maps
  • Scan Plan Cache: Caches struct metadata and scan plans for repeated row scanning
  • Workspace Pooling: Reuses internal scan workspaces to reduce allocation overhead
  • Standard Go Friendly: Designed around simple interfaces, structs, generics, and database/sql-style row behavior

Requirements

This package requires Go 1.22 or newer.

It is designed for modern Go projects and may use language and standard library features introduced in recent Go versions.

  • Go: 1.22 or newer
  • Dependencies: Standard library only
  • Implementation: Generics, reflection, and caching

Quick Example

The example assumes db is a *sql.DB-compatible database handle and mapper is imported from github.com/netlifeguru/mapper.

type User struct {
	ID        string    `db:"id"`
	Name      string    `db:"name"`
	Email     string    `db:"email"`
	Active    bool      `db:"active"`
	CreatedAt time.Time `db:"created_at"`
}

rows, err := db.Query(`
	SELECT id, name, email, active, created_at
	FROM users
	ORDER BY created_at DESC
`)

if err != nil {
	return err
}
defer rows.Close()

users, err := mapper.ScanStructSlice[User](rows)
if err != nil {
	return err
}

Main APIs

API Purpose
ScanStructRows Stream rows into structs with a callback
ScanStructSlice Scan all rows into []T
ScanStructOne Scan exactly one row
ScanMapRows Scan rows into map[string]any
FillFromMap Fill a struct from map[string]any
Row converters Typed access to map values

Documentation

Full package documentation, guides, and examples are available at:

https://netlife.guru/docs/go/mapper

API reference is also available on pkg.go.dev:

https://pkg.go.dev/github.com/netlifeguru/mapper


Notes

  • Review package-specific concurrency behavior before using it in highly parallel workloads.
  • Check performance characteristics when using this package in latency-sensitive paths.
  • See the package documentation and examples for limitations and recommended usage patterns.

Versioning

This project follows Semantic Versioning.

See CHANGELOG.md for release history and breaking changes.


Contributing

Community contributions, feedback, and improvements are welcome.

Please read CONTRIBUTING.md before submitting pull requests or opening issues.


Code of Conduct

This project follows a Code of Conduct.

Please read CODE_OF_CONDUCT.md before contributing or participating in discussions.


Author

Created and maintained by NetLife Guru s.r.o.


License

MIT License. See LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoRows      = errors.New("mapper: no rows")
	ErrTooManyRows = errors.New("mapper: too many rows")
)

Functions

func AsBool

func AsBool(v any) (bool, bool)

func AsInt

func AsInt(v any) (int, bool)

func AsInt64

func AsInt64(v any) (int64, bool)

func AsString

func AsString(v any) (string, bool)

func AsTime

func AsTime(v any) (time.Time, bool)

func AssignValue

func AssignValue(dst reflect.Value, src any) error

func ClearNamedStructScanPlanCache

func ClearNamedStructScanPlanCache()

func CurrentSchemaVersion

func CurrentSchemaVersion() string

func FillFromMap

func FillFromMap[T any](dst *T, m map[string]any) error

func ScanMapRows

func ScanMapRows(rows Rows, each func(row map[string]any) error) error

func ScanStructOne

func ScanStructOne[T any](rows Rows) (*T, error)

func ScanStructRows

func ScanStructRows[T any](rows Rows, each func(*T) error) error

func ScanStructRowsWithCacheKey

func ScanStructRowsWithCacheKey[T any](
	rows Rows,
	cacheKey string,
	each func(*T) error,
) error

func ScanStructSlice

func ScanStructSlice[T any](rows Rows) ([]T, error)

func SetSchemaVersion

func SetSchemaVersion(version string)

func ToSnakeCase

func ToSnakeCase(s string) string

Types

type NullStringLike

type NullStringLike struct {
	String string
	Valid  bool
}

type NullTimeLike

type NullTimeLike struct {
	Time  time.Time
	Valid bool
}

type Row

type Row map[string]any

func (Row) Bool

func (r Row) Bool(key string) (bool, bool)

func (Row) Int

func (r Row) Int(key string) (int, bool)

func (Row) Int64

func (r Row) Int64(key string) (int64, bool)

func (Row) String

func (r Row) String(key string) (string, bool)

func (Row) Time

func (r Row) Time(key string) (time.Time, bool)

type Rows

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Err() error
	Close() error
	Columns() ([]string, error)
}

type ScanMapper

type ScanMapper interface {
	ScanMap(map[string]any) error
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL