Documentation
¶
Overview ¶
Aether — GoStack Cassandra Wide-Column Database Integration Subsystem.
Purpose: This file implements the Aether Cassandra initialization helper for the GoStack framework. It establishes a gocql cluster session and verifies connectivity, returning the active *gocql.Session bound to the global gostack.Cassandra facade.
Philosophy: Aether surfaces the native gocql session directly. Cassandra operates on a distributed ring topology using the Cassandra Query Language (CQL), which maps naturally to Go's standard library patterns but differs fundamentally from both SQL and document paradigms. Wrapping it behind a SQL-shaped interface would prevent developers from using keyspace-aware queries, lightweight transactions (LWT), and Cassandra-specific consistency level controls.
Architecture: Aether sits in the database package and is only compiled into the binary when the developer explicitly selects Cassandra during project scaffolding, upholding GoStack's Modular Self-Containment principle.
Purpose: This file implements the Traveller database migration registry and runner.
Philosophy: Migrations are self-registering Go files. Each file calls database.Register() inside its init() function, which auto-executes when the package is imported. No manual wiring needed. The Migrator tracks completed migrations in a gostack_migrations table and runs only pending migrations, each wrapped in a database transaction.
Architecture: Part of the database package. The registry is a package-level slice. Migrator coordinates transaction-wrapped Up/Down execution and version tracking.
Choice: Consolidated migrate/migrator.go into database/migrator.go to keep all database operations in a single, cohesive package.
Implementation: - Migration: struct holding version, Up, and Down functions. - Register: self-registration entry point called from migration file init() functions. - Migrator: coordinates Run() and Rollback() against the DB.
GoMon — GoStack MongoDB Integration Subsystem.
Purpose: This file implements the GoMon MongoDB initialization helper for the GoStack framework. It exposes a *mongo.Client bound to the global gostack.Mongo facade after connecting and pinging the MongoDB server to verify the connection is alive.
Philosophy: GoMon does not wrap the MongoDB client behind a custom interface. Instead, it surfaces the official mongo.Client directly, giving developers full access to the native MongoDB Go driver API (collections, aggregations, transactions, change streams, etc.) without any limitations imposed by an intermediate wrapper layer.
Architecture: GoMon sits in the database package alongside the SQL adapter. It is only imported and compiled into the application binary when the developer explicitly selects MongoDB during project scaffolding. This upholds GoStack's Modular Self-Containment principle.
Nexus — GoStack Neo4j Graph Database Integration Subsystem.
Purpose: This file implements the Nexus Neo4j initialization helper for the GoStack framework. It establishes and verifies a Neo4j driver connection, returning the official neo4j.DriverWithContext bound to the global gostack.Neo4j facade.
Philosophy: Nexus surfaces the native Neo4j Go driver directly, giving developers full access to Cypher query execution, graph traversals, transactions, and bookmark management without any wrapper limitations. Graph databases have fundamentally different query patterns (Cypher vs SQL) and forcing them behind a SQL-shaped interface would severely restrict their capabilities.
Architecture: Nexus sits in the database package and is only compiled into the binary when the developer explicitly selects Neo4j during project scaffolding, upholding GoStack's Modular Self-Containment principle.
Purpose: This file contains the QueryBuilder struct and its associated chainable helper methods for constructing and executing relational SQL queries within the GoStack framework.
Philosophy: We believe query construction should be fluent, clean, and database-agnostic. By decoupling SQL compilation details (such as placeholder syntax) from application code, we empower developers to write standard SQL logic that is highly legible and testable.
Architecture: QueryBuilder tracks local query state (table, filters, bindings, eager relations) and delegates execution to an injected database client conforming to the contract.Database interface. Post-execution, result sets are directed to the hydration engine and relationships are eager-loaded.
Choice: We chose a direct, chainable builder style for its readability and simplicity. Rather than a heavily layered AST, we map clauses directly to query strings and bindings, providing a lightweight interface with minimal abstraction overhead.
Implementation: - QueryBuilder: manages table targets, filter state, placeholder index bindings, and relations. - New: instantiates a new builder with an injected database connector. - Where: appends AND filtering clauses with driver-specific placeholders. - WhereIn: appends WHERE IN clauses to avoid query duplication. - With: records relationships to be eager-loaded during hydration. - ToSQL: compiles internal state into an executable SQL string. - Execute: performs connection safety checks and executes the compiled query. - Get: coordinates query execution, cursor hydration, and eager relationship mapping.
Purpose: This file manages dynamic data translation, structural inspection, and relational row hydration for the GoStack framework ecosystem.
Philosophy: By leveraging Go's runtime reflection engine ('reflect'), this utility parses custom 'db' struct tags to reconcile data positioning. This allows the framework to populate data layouts without forcing developers to write manual, error-prone 'rows.Scan' loops for every entity model.
Architecture: It acts as the hydration helper functions within the database package.
Choice: Consolidated into the database package to avoid circular references and keep all mapping operations in a single package context.
Implementation: - Hydrate: inspects raw relational database rows and dynamically maps their column values. - mapRowToStruct: matches database columns with structural fields to assign values. - findFieldByTagName: matches database columns with struct tags or structural exact field name matches.
Purpose: This file implements the dynamic reflection-based ORM Relationship Management system for the GoStack framework. It currently supports eager loading for HasMany and BelongsTo relations.
Philosophy: We believe relationship loading should be convenient, transparent, and highly performant. Rather than inducing N+1 database querying loops, we batch load related entities using single sub-queries. We favor runtime structural tag analysis (db, rel, fk, table) to remain zero-dependency.
Architecture: Post-hydration, the query builder routes structural destination targets to the eager-loader. The loader inspects struct field definitions, queries children/owners using WhereIn sub-queries, and reflective maps hydrated relation structures back onto parent models using normalized key comparisons.
Choice: We chose runtime reflection over code generation to maximize developer ergonomics and avoid introducing CLI build steps into simple application templates.
Implementation: - eagerLoadRelations: root entry point that routes structs and slices to the slice-loader. - eagerLoadRelationForSlice: extracts field tags, defaults tables/keys, and triggers loading. - loadHasMany: eager loads HasMany relationships by mapping parent PKs to child FKs. - loadBelongsTo: eager loads BelongsTo relationships by mapping parent FKs to owner PKs. - findPrimaryKeyField: traverses fields to identify the struct's primary key name. - findFieldByDBTag: matches database column strings with struct field targets. - normalizeKey: coerces numeric and string kinds into comparable types for map lookup.
Purpose: This file implements the Grapher Schema Builder and Table DDL compiler for the GoStack framework. It provides a fluent, driver-aware API for defining and compiling CREATE TABLE and DROP TABLE statements.
Philosophy: Developers should never write raw DDL SQL. All schema definitions are expressed through type-safe Go method calls, allowing the framework to emit the correct SQL for each driver.
Architecture: Part of the database package. The Builder wraps a contract.Tx and dispatches DDL operations. The Table and Column types implement the fluent DSL for schema definition.
Choice: Consolidated schema/builder.go and schema/table.go into a single database/schema.go file to reduce package fragmentation and simplify imports.
Implementation: - ColumnKind: enumeration of supported column types. - Column: struct representing a single column definition with modifier chaining. - Table: struct holding an ordered list of Column definitions for a single table. - Builder: wraps contract.Tx to execute CREATE/DROP TABLE DDL atomically.
Purpose: This file implements the GoStack database seeding registry.
Philosophy: Seeding should be modular and easy to execute. By registering seeders via self-registering init() calls, we keep database population decoupled from the main CLI execution engine.
Architecture: Part of the database package. Seeders implement a simple Seeder interface and are invoked by the console db:seed command.
Purpose: This file implements standard SQL-based database operations, ensuring that the framework can communicate with relational databases like MySQL, PostgreSQL, or SQLite.
Philosophy: We believe relational database interactions should be clean, driver-agnostic, and secure. By wrapping standard library sql.DB pools, we provide a unified execution surface.
Architecture: Part of the database package, providing the driver implementation conforming to contract.Database.
Choice: Consolidated adapter, query, schema, and migrate into the database package to simplify database operations and remove circular dependencies.
Implementation: - SQLAdapter: struct wrapping sql.DB and tracking the driver string name. - NewSQLAdapter: constructor establishing standard database connection pools. - SQLTx: struct wrapping standard sql.Tx transactions.
Index ¶
- func All[T any](db contract.Database) ([]T, error)
- func Create[T any](db contract.Database, fields map[string]any) (*T, error)
- func DeleteRecord[T any](db contract.Database, id any) error
- func Find[T any](db contract.Database, id any) (*T, error)
- func Hydrate(rows *sql.Rows, dest any) error
- func InitAether(hosts string, keyspace string) (*gocql.Session, error)
- func InitGoMon(uri string) (*mongo.Client, error)
- func InitNexus(uri, username, password string) (neo4j.DriverWithContext, error)
- func Register(version int64, up, down func(s *Builder) error)
- func RegisterSeeder(name string, s Seeder)
- func RunAllSeeders() error
- func RunSeeder(name string) error
- func Update[T any](db contract.Database, id any, fields map[string]any) error
- type AfterCreator
- type AfterDeleter
- type BeforeDeleter
- type BeforeSaver
- type Builder
- type Column
- type ColumnKind
- type Migration
- type Migrator
- type Model
- type PageMeta
- type QueryBuilder
- func (qb *QueryBuilder) Count() (int, error)
- func (qb *QueryBuilder) Delete() error
- func (qb *QueryBuilder) DeleteModel(model any) error
- func (qb *QueryBuilder) Execute() (any, error)
- func (qb *QueryBuilder) First(dest any) error
- func (qb *QueryBuilder) Get(dest any) error
- func (qb *QueryBuilder) Insert(data map[string]any) error
- func (qb *QueryBuilder) InsertModel(model any, data map[string]any) error
- func (qb *QueryBuilder) Limit(n int) *QueryBuilder
- func (qb *QueryBuilder) Offset(n int) *QueryBuilder
- func (qb *QueryBuilder) OrderBy(col, dir string) *QueryBuilder
- func (qb *QueryBuilder) Paginate(dest any, page, perPage int) (*PageMeta, error)
- func (qb *QueryBuilder) ToSQL() string
- func (qb *QueryBuilder) Update(data map[string]any) error
- func (qb *QueryBuilder) UpdateModel(model any, data map[string]any) error
- func (qb *QueryBuilder) Where(col, op string, val any) *QueryBuilder
- func (qb *QueryBuilder) WhereIn(col string, vals []any) *QueryBuilder
- func (qb *QueryBuilder) With(relations ...string) *QueryBuilder
- type SQLAdapter
- type SQLTx
- type Seeder
- type Table
- func (t *Table) Boolean(name string) *Column
- func (t *Table) Compile(tableName string) string
- func (t *Table) ID() *Column
- func (t *Table) Integer(name string) *Column
- func (t *Table) String(name string) *Column
- func (t *Table) Text(name string) *Column
- func (t *Table) Timestamp(name string) *Column
- func (t *Table) Timestamps()
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DeleteRecord ¶
DeleteRecord deletes records matching the primary key id.
func Hydrate ¶
Hydrate inspects raw relational database rows and dynamically maps their column values directly into a provided Go struct or slice pointer target.
func InitAether ¶ added in v1.0.1
InitAether initializes and verifies a Cassandra connection using the provided cluster hosts and keyspace. It returns the connected *gocql.Session ready for use as the global gostack.Cassandra facade.
Parameters:
- hosts: A comma-separated string of Cassandra cluster contact points (e.g. "127.0.0.1:9042").
- keyspace: The Cassandra keyspace to bind the session to (e.g. "myapp").
Returns:
- A live *gocql.Session, or an error if the cluster connection or session creation fails.
func InitGoMon ¶ added in v1.0.1
InitGoMon initializes and verifies a MongoDB connection using the provided URI. It returns the connected *mongo.Client ready for use as the global gostack.Mongo facade.
Parameters:
- uri: The MongoDB connection string (e.g. "mongodb://127.0.0.1:27017").
Returns:
- A live *mongo.Client, or an error if connection or ping fails.
func InitNexus ¶ added in v1.0.1
func InitNexus(uri, username, password string) (neo4j.DriverWithContext, error)
InitNexus initializes and verifies a Neo4j connection using the provided URI and credentials. It returns the connected neo4j.DriverWithContext ready for use as the global gostack.Neo4j facade.
Parameters:
- uri: The Neo4j connection URI (e.g. "neo4j://localhost:7687" or "neo4j+s://..." for AuraDB).
- username: The Neo4j authentication username (typically "neo4j").
- password: The Neo4j authentication password.
Returns:
- A live neo4j.DriverWithContext, or an error if connection or verification fails.
func Register ¶
Register adds a new migration to the global registry. Designed to be called from the init() function of each migration file.
func RegisterSeeder ¶
RegisterSeeder adds a seeder to the global registry. Typically called from init() in generated seeder files.
func RunAllSeeders ¶
func RunAllSeeders() error
RunAllSeeders runs all registered seeders. If "DatabaseSeeder" exists, it runs only DatabaseSeeder. Otherwise, it runs all registered seeders.
Types ¶
type AfterCreator ¶
type AfterCreator interface {
AfterCreate() error
}
AfterCreator is implemented by models that need to run logic after a successful INSERT.
type AfterDeleter ¶
type AfterDeleter interface {
AfterDelete() error
}
AfterDeleter is implemented by models that need to run logic after a successful DELETE.
type BeforeDeleter ¶
type BeforeDeleter interface {
BeforeDelete() error
}
BeforeDeleter is implemented by models that need to run logic before a DELETE.
type BeforeSaver ¶
type BeforeSaver interface {
BeforeSave() error
}
BeforeSaver is implemented by models that need to run logic before any INSERT or UPDATE.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder wraps a contract.Tx to execute DDL operations atomically within a database transaction.
func NewBuilder ¶
NewBuilder constructs a Schema Builder bound to an active transaction and a driver name.
type Column ¶
type Column struct {
// contains filtered or unexported fields
}
Column represents a single database column definition.
type ColumnKind ¶
type ColumnKind int
ColumnKind identifies the semantic data category of a column definition.
const ( KindID ColumnKind = iota // Auto-increment primary key KindString // VARCHAR(255) KindInteger // INT KindBoolean // TINYINT(1) / BOOLEAN KindText // TEXT KindTimestamp // DATETIME / TIMESTAMPTZ )
type Migration ¶
type Migration struct {
// Version is a unique integer identifier (e.g. 20260612001, sortable by creation time).
Version int64
// Up defines the forward schema change using the GoStack Schema Builder.
Up func(s *Builder) error
// Down defines the rollback schema change to reverse the Up operation.
Down func(s *Builder) error
}
Migration represents a single versioned schema change with Up and Down functions.
type Migrator ¶
type Migrator struct {
// contains filtered or unexported fields
}
Migrator coordinates running and rolling back database migrations.
func NewMigrator ¶
NewMigrator constructs a Migrator bound to an active database connection.
type Model ¶
type Model interface {
TableName() string
}
Model defines an optional interface for custom database table name mapping.
type PageMeta ¶
type PageMeta struct {
Total int `json:"total"`
Page int `json:"page"`
PerPage int `json:"per_page"`
LastPage int `json:"last_page"`
HasNext bool `json:"has_next"`
HasPrev bool `json:"has_prev"`
}
PageMeta stores structural pagination attributes for API response formatting.
type QueryBuilder ¶
type QueryBuilder struct {
// contains filtered or unexported fields
}
QueryBuilder serves as the core state manager for SQL construction.
func New ¶
func New(db contract.Database, table string) *QueryBuilder
New constructs a new QueryBuilder instance.
func (*QueryBuilder) Count ¶
func (qb *QueryBuilder) Count() (int, error)
Count returns the total number of records matching current query constraints.
func (*QueryBuilder) Delete ¶
func (qb *QueryBuilder) Delete() error
Delete compiles and executes a DELETE statement against the target table. Fires BeforeDelete and AfterDelete hooks on model if provided via DeleteModel.
Example:
gostack.Table("users").Where("id", "=", 42).Delete()
func (*QueryBuilder) DeleteModel ¶
func (qb *QueryBuilder) DeleteModel(model any) error
DeleteModel is Delete with optional model hook support.
func (*QueryBuilder) Execute ¶
func (qb *QueryBuilder) Execute() (any, error)
Execute triggers the execution of the built SQL query via the injected database connection.
func (*QueryBuilder) First ¶
func (qb *QueryBuilder) First(dest any) error
First executes the query with LIMIT 1 and hydrates the result into dest, which should be a pointer to a struct (not a slice). Returns an error wrapping ErrNoRows if no record is found.
Example:
var user model.User
err := gostack.Table("users").Where("email", "=", email).First(&user)
func (*QueryBuilder) Get ¶
func (qb *QueryBuilder) Get(dest any) error
Get executes the compiled query and automatically hydates the database results directly into the provided destination pointer (struct or slice of structs).
func (*QueryBuilder) Insert ¶
func (qb *QueryBuilder) Insert(data map[string]any) error
Insert compiles and executes an INSERT DDL operation against the target table. It fires BeforeSave() before execution and AfterCreate() after a successful insert.
func (*QueryBuilder) InsertModel ¶
func (qb *QueryBuilder) InsertModel(model any, data map[string]any) error
InsertModel is Insert with optional model hook support. Pass the model pointer to enable BeforeSave and AfterCreate lifecycle hooks.
func (*QueryBuilder) Limit ¶
func (qb *QueryBuilder) Limit(n int) *QueryBuilder
Limit caps the number of rows returned.
Example:
gostack.Table("posts").Limit(10).Get(&posts)
func (*QueryBuilder) Offset ¶
func (qb *QueryBuilder) Offset(n int) *QueryBuilder
Offset skips the first n rows before returning results.
Example:
gostack.Table("posts").Limit(10).Offset(20).Get(&posts)
func (*QueryBuilder) OrderBy ¶
func (qb *QueryBuilder) OrderBy(col, dir string) *QueryBuilder
OrderBy appends an ORDER BY clause to the query. dir should be "ASC" or "DESC".
Example:
gostack.Table("posts").OrderBy("created_at", "DESC").Get(&posts)
func (*QueryBuilder) Paginate ¶
func (qb *QueryBuilder) Paginate(dest any, page, perPage int) (*PageMeta, error)
Paginate counts total records matching current query conditions, retrieves the requested chunk of rows for the target page, and hydrates them into dest.
func (*QueryBuilder) ToSQL ¶
func (qb *QueryBuilder) ToSQL() string
ToSQL serializes the internal state into a valid SQL query string.
func (*QueryBuilder) Update ¶
func (qb *QueryBuilder) Update(data map[string]any) error
Update compiles and executes an UPDATE statement against the target table. Fires BeforeSave hook on model if provided via UpdateModel.
Example:
gostack.Table("users").Where("id", "=", 1).Update(map[string]any{"name": "Alice"})
func (*QueryBuilder) UpdateModel ¶
func (qb *QueryBuilder) UpdateModel(model any, data map[string]any) error
UpdateModel is Update with optional model hook support.
func (*QueryBuilder) Where ¶
func (qb *QueryBuilder) Where(col, op string, val any) *QueryBuilder
Where adds a filtering condition to the internal state.
func (*QueryBuilder) WhereIn ¶
func (qb *QueryBuilder) WhereIn(col string, vals []any) *QueryBuilder
WhereIn adds a "WHERE col IN (?, ?, ...)" clause to the query state.
func (*QueryBuilder) With ¶
func (qb *QueryBuilder) With(relations ...string) *QueryBuilder
With specifies one or more relationships to be eager-loaded with the query results.
type SQLAdapter ¶
type SQLAdapter struct {
// contains filtered or unexported fields
}
SQLAdapter is the concrete implementation of the contract.Database interface.
func NewSQLAdapter ¶
func NewSQLAdapter(driver, dsn string) (*SQLAdapter, error)
NewSQLAdapter acts as a constructor for the SQLAdapter.
func (*SQLAdapter) BeginTx ¶
func (a *SQLAdapter) BeginTx() (contract.Tx, error)
BeginTx opens a new database transaction and returns it wrapped in the contract.Tx interface.
func (*SQLAdapter) Close ¶ added in v1.0.1
func (a *SQLAdapter) Close() error
Close releases the underlying SQL database connection pool.
func (*SQLAdapter) Connect ¶
func (a *SQLAdapter) Connect() error
Connect verifies that the database connection is alive by performing a Ping.
func (*SQLAdapter) Driver ¶
func (a *SQLAdapter) Driver() string
Driver returns the database driver identifier name.
type SQLTx ¶
type SQLTx struct {
// contains filtered or unexported fields
}
SQLTx wraps a standard *sql.Tx to implement the contract.Tx interface.
type Seeder ¶
type Seeder interface {
Run() error
}
Seeder defines the contract for populating database tables with seed data.
type Table ¶
type Table struct {
// contains filtered or unexported fields
}
Table holds the full ordered list of column definitions for a CREATE TABLE statement.
func (*Table) Compile ¶
Compile translates the full column list into a driver-aware CREATE TABLE SQL string.
func (*Table) Timestamps ¶
func (t *Table) Timestamps()
Timestamps appends the standard created_at and updated_at columns.