enumdb

enumdb loads enumeration sets from relational database tables into thread-safe enum caches.

Part of nurago, a collection of independent Go packages for backend services.

import "github.com/tecnickcom/nurago/pkg/enumdb"

Package enumdb loads enumeration sets from relational database tables into thread-safe enum caches.

It builds in-memory ID-to-name and name-to-ID lookup maps from database reference tables at service startup.

This package is designed for tables where each row represents a single enum value with values that can be scanned into (id int, name string). In practice, this usually corresponds to a numeric primary key column named “id” and a unique string column named “name”.

Example of a MySQL database table that can be used with this package:

CREATE TABLE IF NOT EXISTS `example` (
  `id` SMALLINT UNSIGNED NOT NULL,
  `name` VARCHAR(50) NOT NULL,
  `disabled` TINYINT NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB
COMMENT = 'Example enumeration table';

When To Use

  • Reference tables hold (id, name) rows that never change during a process’s lifetime.
  • You want lookups to avoid the database entirely after startup.

Example

// A real program would use a *sql.DB from sql.Open. The mock keeps the
// example self-contained and its output deterministic.
db, mock, err := sqlmock.New()
if err != nil {
	fmt.Println(err)

	return
}

defer func() { _ = db.Close() }()

mock.ExpectQuery("SELECT id, name FROM status").WillReturnRows(
	sqlmock.NewRows([]string{"id", "name"}).
		AddRow(1, "pending").
		AddRow(2, "active").
		AddRow(3, "archived"),
)

// One query per enumeration table, each returning (id int, name string).
queries := enumdb.EnumTableQuery{
	"status": "SELECT id, name FROM status WHERE disabled = 0 ORDER BY id",
}

enum, err := enumdb.New(context.TODO(), db, queries)
if err != nil {
	fmt.Println(err)

	return
}

// The result is keyed by table name and each value is a thread-safe
// bidirectional cache, ready for lookups without further database access.
name, err := enum["status"].Name(2)
fmt.Println(name, err)

id, err := enum["status"].ID("archived")
fmt.Println(id, err)

fmt.Println(enum["status"].SortNames())

// Output:
// active <nil>
// 3 <nil>
// [active archived pending]

Full source is in example_enumdb_test.go. More runnable examples are on pkg.go.dev.

Dependencies

This package reaches no external module: it uses only the Go standard library.