Help us shape the future of Go! Take the 2026 Go Developer Survey

dalgo

package module
v0.55.6 Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2026 License: MIT Imports: 0 Imported by: 0

README ΒΆ

πŸ”Œ DALgo

DALgo is a database abstraction layer for Go applications. It gives your business code one small, consistent API for records, queries, transactions, hooks, and schema-aware key mapping while letting the storage backend remain an implementation choice.

go get github.com/dal-go/dalgo

Build, Test, Vet, Lint Go Report Card Coverage Status Version GoDoc Sourcegraph

🎯 Why Use DALgo

DALgo is useful when an application needs stable data-access code without coupling the domain layer to Firestore, SQL, or a test-only database.

  • Keep application logic independent from a concrete database client.
  • Use the same record, query, and transaction shape across supported adapters.
  • Test business logic with the built-in in-memory adapter.
  • Add logging, validation, metrics, and other behavior through hooks.
  • Model both document/key-value stores and relational tables through one key and schema abstraction.

DALgo does not try to hide every database difference. Adapters can return dal.ErrNotSupported for capabilities their backend cannot provide. This keeps the core API honest while still giving applications a shared path for the common operations.

⚑ Quick Example

This example uses dalgo2memory, the built-in in-memory adapter. The same application code can be written against dal.DB and supplied with another adapter in production.

package main

import (
	"context"
	"fmt"

	"github.com/dal-go/dalgo/dal"
	"github.com/dal-go/dalgo/dalgo2memory"
)

type User struct {
	Name  string
	Email string
}

func main() {
	ctx := context.Background()
	db := dalgo2memory.NewDB()

	key := dal.NewKeyWithID("users", "u1")
	if err := db.Set(ctx, dal.NewRecordWithData(key, &User{
		Name:  "Ada Lovelace",
		Email: "ada@example.com",
	})); err != nil {
		panic(err)
	}

	var user User
	record := dal.NewRecordWithData(key, &user)
	if err := db.Get(ctx, record); err != nil {
		panic(err)
	}
	if record.Exists() {
		fmt.Println(user.Email)
	}
}

πŸ”Œ Core API

The main package is dal. It defines the interfaces application code usually depends on:

  • dal.DB for database-level reads, transactions, schema metadata, and adapter identity.
  • dal.ReadSession and dal.ReadwriteSession for read and write operations.
  • dal.Record and dal.Key for database records and hierarchical keys.
  • dal.Query for structured and text queries.
  • dal.Schema for mapping DALgo keys to relational columns.

Most applications should accept dal.DB, dal.ReadSession, or dal.ReadwriteSession in their own services instead of accepting a concrete adapter type.

func LoadUser(ctx context.Context, db dal.ReadSession, id string) (*User, error) {
	user := new(User)
	record := dal.NewRecordWithData(dal.NewKeyWithID("users", id), user)

	if err := db.Get(ctx, record); err != nil {
		return nil, err
	}
	if !record.Exists() {
		return nil, dal.ErrRecordNotFound
	}
	return user, nil
}

🌳 Hierarchical Collections

DALgo keys can represent nested document paths, which maps naturally to Firestore-style collections such as countries/ireland/cities/dublin.

countryKey := dal.NewKeyWithID("countries", "ireland")
cityKey := dal.NewKeyWithParentAndID(countryKey, "cities", "dublin")

err := db.Set(ctx, dal.NewRecordWithData(cityKey, &City{
	Name:       "Dublin",
	Population: 592713,
}))

The same parent key can scope a query to a nested collection. For Firestore this is the shape of a query under countries/ireland/cities.

ireland := dal.NewKeyWithID("countries", "ireland")
cities := dal.NewCollectionRef("cities", "", ireland)

q := dal.From(cities).NewQuery().
	WhereField("Population", dal.GreaterThen, 100000).
	OrderBy(dal.DescendingField("Population")).
	SelectColumns(
		dal.Column{Expression: dal.Field("Name")},
		dal.Column{Expression: dal.Field("Population")},
	)

πŸ”Ž Queries

DALgo includes a structured query builder for common database-style reads: filters, ordering, joins, column projection, and aggregation. Adapter support is capability-based, so tests can share the same query shape and skip a backend cleanly when it reports dal.ErrNotSupported.

q := dal.From(dal.NewRootCollectionRef("cities", "")).NewQuery().
	WhereField("Country", dal.Equal, "IE").
	OrderBy(dal.DescendingField("Population")).
	Limit(10).
	SelectColumns(
		dal.Column{Expression: dal.Field("Name")},
		dal.Column{Expression: dal.Field("Population")},
	)

records, err := dal.ExecuteQueryAndReadAllToRecords(ctx, q, db)

Recent query capabilities include:

  • Column projection through SelectColumns.
  • GROUP BY, HAVING, and aggregate functions such as COUNT(*) and SUM.
  • Inner and left equi-joins in the structured query model.
  • Source-qualified field references for joins and ORDER BY.
  • Recordset readers with typed columns where the adapter supports columnar output.

πŸ” Transactions

Transactions use callback-style workers. This keeps transaction lifetime scoped and lets adapters implement retries or backend-specific transaction behavior.

err := db.RunReadwriteTransaction(ctx, func(ctx context.Context, tx dal.ReadwriteTransaction) error {
	key := dal.NewKeyWithID("users", "u1")
	return tx.Set(ctx, dal.NewRecordWithData(key, &User{Name: "Ada"}))
}, dal.TxWithMessage("create user u1"))

Transaction options can carry isolation-level requests and a human-readable message. Some adapters can surface the message in logs or backend history.

🧰 Built-In Adapters

This repository includes:

  • dalgo2memory - in-memory DALgo database for tests, examples, local development, and query behavior verification. It supports schema registration, typed records, serialized storage, columnar storage, and mixed-mode map[string]any columnar storage.
  • dalgo2fs - filesystem-backed adapter useful for simple local persistence and examples.

dalgo2memory is intentionally useful beyond trivial tests. It can run many structured query features end to end, which makes it a practical default for unit tests around application data access.

🌐 Supported External Adapters

DALgo supports production use through separate adapter modules:

  • dalgo2firestore for Google Cloud Firestore.
  • dalgo2sql for SQL databases through Go SQL drivers, including SQLite, PostgreSQL, Oracle, and Microsoft SQL Server.
  • dalgo2sqlite for SQLite-specific schema, DDL, and concurrency-aware behavior on top of SQL support.

Deprecated BuntDB and BadgerDB adapters are not listed as supported production targets.

πŸ“¦ Packages

  • dal - core database abstraction, keys, records, sessions, transactions, queries, hooks, and schema mapping.
  • dalgo2memory - built-in in-memory adapter.
  • dalgo2fs - filesystem adapter.
  • orm - object and collection mapping helpers.
  • record - helpers for strongly typed record handling.
  • recordset - row and column-oriented recordset structures.
  • recordops - compare, diff, and render helpers for records.
  • dbschema - schema definitions for collections, fields, indexes, constraints, and defaults.
  • ddl - schema modification operations and applier interfaces.
  • dtql - serialized query format and schema for DALgo queries.
  • update - field update helpers.
  • mocks - generated mocks for tests.

βœ… Quality And Compatibility

The project is maintained with automated checks and adapter-oriented test coverage:

  • CI runs build, tests, go vet, and lint checks.
  • Core packages target full unit-test coverage.
  • Shared end-to-end tests in end2end exercise adapter behavior against the same scenarios.
  • Feature specifications in spec/features document behavior that has been designed, implemented, and verified.

πŸ“š Documentation

Start with these topic pages when you need more than the README:

πŸš€ Projects Using DALgo

🀝 Contributing

Contributions are welcome, especially adapter improvements, end-to-end coverage, and documentation that makes backend capabilities clearer. See CONTRIBUTING.md for project conventions.

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

View Source
const Version = "0.3.4"

Version holds a version of the module Need to be updated by CI when published.

Variables ΒΆ

This section is empty.

Functions ΒΆ

This section is empty.

Types ΒΆ

This section is empty.

Directories ΒΆ

Path Synopsis
Package dbschema provides a portable schema-description vocabulary and read-side (introspection) capability for DALgo.
Package dbschema provides a portable schema-description vocabulary and read-side (introspection) capability for DALgo.
Package ddl provides the schema-modification execution surface for DALgo.
Package ddl provides the schema-modification execution surface for DALgo.
Package dtql provides a 1:1, lossless, human-readable YAML serialization of dalgo's dal.StructuredQuery for the core relational read-only subset.
Package dtql provides a 1:1, lossless, human-readable YAML serialization of dalgo's dal.StructuredQuery for the core relational read-only subset.
mocks
mock_dal
Package mock_dal is a generated GoMock package.
Package mock_dal is a generated GoMock package.
mock_ddl
Package mock_ddl is a generated GoMock package.
Package mock_ddl is a generated GoMock package.
mock_update
Package mock_update is a generated GoMock package.
Package mock_update is a generated GoMock package.
specscore: feat-recordops/diff
specscore: feat-recordops/diff

Jump to

Keyboard shortcuts

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