lagodev

module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: MIT

README

lagodev

Go Reference Tests

Laravel-grade developer experience for Go. lagodev is a focused toolkit that gives you Laravel's migrations, Eloquent's ergonomics, and Artisan's generator-first workflow — without locking you into a web framework. Drop it into a Gin, Fiber, Echo, Chi, net/http, gRPC, or GraphQL service and use only what you need.

lagodev is not a web framework. It is a database layer, a code-gen CLI, and a testing harness. You bring your own HTTP/RPC layer.


Highlights

  • Schema builder — fluent schema.Create("users", func(t *schema.Blueprint) { … }) DSL that compiles to PostgreSQL / MySQL / SQLite — and is extensible to any other dialect via database.Grammar.
  • Migration engine — transactional up/rollback/refresh/fresh/reset/status/step, batching, advisory locking, checksums, SQL preview, dry-run mode.
  • ORMorm.Model base type, generic orm.Query[T] builder, hooks (BeforeCreate/AfterUpdate/…), soft deletes, casts (JSON / bool / date / int), and a thread-safe reflection cache.
  • Query builder — chainable Where/OrWhere/WhereIn/OrderBy/Latest/Join/GroupBy/Having/LockForUpdate with dialect-correct placeholders.
  • RelationsHasOne / HasMany / BelongsTo / BelongsToMany / polymorphic Morph* with single-query eager-loading.
  • Factories & seeders — generic factory.New[T] with states + faker, topologically-ordered seeders with optional transactionality.
  • Artisan CLImake:model -m -f -s -t, make:migration, make:seeder, make:factory, make:test, migrate, migrate:rollback, migrate:fresh, migrate:status, db:seed, db:wipe. Stub-based with override hooks for project-specific templates.
  • Testing harnesslagotest.SQLite(t, …) spins up an in-memory database, applies all registered migrations, and returns a connection in two lines.
  • Driver-agnostic — PostgreSQL (pgx), MySQL (mysql), SQLite (mattn/go-sqlite3) ship in-box. New drivers register themselves via database.Register.

Quick tour

package main

import (
    "context"
    "fmt"

    "github.com/devituz/lagodev/database"
    _ "github.com/devituz/lagodev/drivers/sqlite"
    "github.com/devituz/lagodev/migrations"
    "github.com/devituz/lagodev/orm"
    "github.com/devituz/lagodev/schema"
)

type User struct {
    orm.Model
    Name  string
    Email string
}

func init() {
    migrations.Register(migrations.Define("0001_users",
        func(ctx *migrations.Context) error {
            return ctx.Schema(schema.Create("users", func(t *schema.Blueprint) {
                t.ID()
                t.String("name")
                t.String("email").Unique()
                t.Timestamps()
                t.SoftDeletes()
            }))
        },
        func(ctx *migrations.Context) error {
            return ctx.Schema(schema.DropIfExists("users"))
        },
    ))
}

func main() {
    ctx := context.Background()
    conn, _ := database.Global.Open("default", database.Config{
        Driver: "sqlite", DSN: "file::memory:?cache=shared",
    })
    migrations.New(conn, nil, migrations.Options{}).Up(ctx)

    user := &User{Name: "Ada", Email: "ada@example.com"}
    _ = orm.Save(ctx, conn, user)

    found, _ := orm.Query[User](conn).Where("email", "=", "ada@example.com").First(ctx)
    fmt.Println(found.Name, "→", found.ID)
}

Installation

go get github.com/devituz/lagodev

Then blank-import the driver you want:

_ "github.com/devituz/lagodev/drivers/postgres"  // pgx
_ "github.com/devituz/lagodev/drivers/mysql"     // go-sql-driver/mysql
_ "github.com/devituz/lagodev/drivers/sqlite"    // mattn/go-sqlite3

The Artisan-style CLI lives at cmd/artisan:

go install github.com/devituz/lagodev/cmd/artisan@latest

artisan make:model Post -m -f -s -t   # model + migration + factory + seeder + test
artisan migrate
artisan migrate:status
artisan db:seed

Configuration

The framework reads from environment variables (or any .env file you load with config.LoadEnv):

Variable Purpose
DB_CONNECTION Driver name: postgres, mysql, sqlite
DB_DSN Full DSN; overrides the structured fields below
DB_HOST / DB_PORT TCP coordinates
DB_USERNAME / DB_PASSWORD Credentials
DB_DATABASE / DB_SCHEMA Target database / schema
DB_LOG_QUERIES true to log every query
DB_SLOW_QUERY Threshold (Go duration) for slow-query logs

Architecture

schema/        Blueprint DSL + dialect-aware compiler
migrations/    Engine, registry, repository, advisory lock
database/      Connection, Manager, Tx, Grammar interface
drivers/       postgres, mysql, sqlite (each registers itself in init)
query/         Driver-aware SQL builder
orm/           Model base, Query[T], hooks, casts, soft-delete
relations/     Has*/BelongsTo*/Morph* with eager-load
factory/       factory.New[T] + faker (gofakeit wrapper)
seeder/        Seeder registry + topological runner
cli/           cli.New(...) — Cobra root + cmd/* subcommands + embedded stubs
config/        Env loader + config.FromEnv() → database.Config
logger/        Leveled, SQL-aware, color-on-tty logger
casts/         JSON / bool / int / date casts (extensible)
testing/       lagotest.SQLite(t) harness for tests
benchmarks/    `go test -bench=.` suite
examples/      basic, gin (net/http), microservice
internal/      reflectutil (model schema cache) + inflect (Snake/Plural)

See docs/ARCHITECTURE.md for a deeper walk-through.

Testing

go test ./...                # full suite (in-memory SQLite)
go test -race ./...
go test -bench=. -benchmem ./benchmarks

A typical integration test:

import lagotest "github.com/devituz/lagodev/testing"

func TestThing(t *testing.T) {
    conn, cleanup := lagotest.SQLite(t)
    defer cleanup()

    // conn is ready: migrations applied, in-memory DB, isolated per-test.
}

Roadmap

Area Planned
Drivers SQL Server, CockroachDB, TiDB grammars
ORM Pluck/Chunk/cursor pagination, JSON path queries
CLI make:request, make:command, project scaffolding (new)
Tooling OpenTelemetry spans on every query, structured query logger backend
Schema Online ALTERs, native PostgreSQL types (cidr, tsvector, hstore)

Contributing

Issues and pull requests welcome. Run make check (or go test ./... + go vet ./...) before opening a PR.

License

MIT — see LICENSE.

Directories

Path Synopsis
adapters
gin module
Package casts provides a small attribute-casting layer the ORM applies on reads and writes.
Package casts provides a small attribute-casting layer the ORM applies on reads and writes.
cli
Package cli implements the Artisan-style command-line interface.
Package cli implements the Artisan-style command-line interface.
cmd
Package cmd contains the implementation of each Artisan subcommand.
Package cmd contains the implementation of each Artisan subcommand.
cmd
artisan command
Command artisan is the default lagodev Artisan-style CLI binary.
Command artisan is the default lagodev Artisan-style CLI binary.
Package config loads framework configuration from environment variables and .env files.
Package config loads framework configuration from environment variables and .env files.
drivers
mysql
Package mysql registers the MySQL/MariaDB driver and grammar.
Package mysql registers the MySQL/MariaDB driver and grammar.
postgres
Package postgres registers the PostgreSQL driver and grammar.
Package postgres registers the PostgreSQL driver and grammar.
sqlite
Package sqlite registers the SQLite driver (via mattn/go-sqlite3) and provides a Grammar implementation.
Package sqlite registers the SQLite driver (via mattn/go-sqlite3) and provides a Grammar implementation.
examples
basic command
Example: end-to-end usage of lagodev with an in-memory SQLite database.
Example: end-to-end usage of lagodev with an in-memory SQLite database.
gin command
Example: integrating lagodev with a net/http API.
Example: integrating lagodev with a net/http API.
microservice command
Example: a microservice-style worker that reads jobs from a queue table.
Example: a microservice-style worker that reads jobs from a queue table.
Package factory provides a generic, type-safe model factory inspired by Laravel's factories.
Package factory provides a generic, type-safe model factory inspired by Laravel's factories.
internal
inflect
Package inflect provides minimal, allocation-conscious string transformations used across the framework (snake_case, plural table names, etc.).
Package inflect provides minimal, allocation-conscious string transformations used across the framework (snake_case, plural table names, etc.).
reflectutil
Package reflectutil provides a thread-safe, allocation-amortized reflection cache.
Package reflectutil provides a thread-safe, allocation-amortized reflection cache.
Package logger provides a small, dependency-free structured logger used across the framework.
Package logger provides a small, dependency-free structured logger used across the framework.
Package migrations implements a Laravel-style migration engine.
Package migrations implements a Laravel-style migration engine.
Package orm provides an ActiveRecord-style Model, a fluent query builder, hooks, casts, soft-deletes, and relationships.
Package orm provides an ActiveRecord-style Model, a fluent query builder, hooks, casts, soft-deletes, and relationships.
Package query provides a fluent, driver-aware SQL builder.
Package query provides a fluent, driver-aware SQL builder.
Package relations implements model relationships with eager-loading.
Package relations implements model relationships with eager-loading.
Package schema provides a fluent table-builder DSL (Blueprint) and a driver-agnostic Builder that compiles blueprints into SQL via a Grammar implementation provided by the database driver.
Package schema provides a fluent table-builder DSL (Blueprint) and a driver-agnostic Builder that compiles blueprints into SQL via a Grammar implementation provided by the database driver.
Package seeder runs database seeders with dependency ordering and transactional execution.
Package seeder runs database seeders with dependency ordering and transactional execution.
Package testing provides helpers for running migrations against an ephemeral SQLite database, useful for unit and integration tests.
Package testing provides helpers for running migrations against an ephemeral SQLite database, useful for unit and integration tests.

Jump to

Keyboard shortcuts

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