Documentation
¶
Index ¶
- Constants
- func Connect(connURL, driver string) (*sqlx.DB, error)
- func CreateModel[T any](m *T) error
- func DeleteModel[T any](m *T) error
- func FindModels[T any](page, limit int, sortField string, sortDir qb.OrderByDir, ...) ([]T, int, error)
- func GetModel[T any](conditions ...Condition) (*T, error)
- func GetModelBy[T any](field string, value any) (*T, error)
- func GetModelByID[T any](value any) (*T, error)
- func GetModelWhereEq[T any](field string, value any) (*T, error)
- func Load()
- func Register(driver IDatabase)
- func UpdateModel[T any](m *T) error
- type Column
- type Condition
- type DB
- type DBModel
- func (db *DBModel) Begin() *DBModel
- func (db *DBModel) Commit() error
- func (db *DBModel) Create(model any) (err error)
- func (db *DBModel) Delete(model any) error
- func (db *DBModel) Fetch(offset, fetch int) *DBModel
- func (db *DBModel) Find(model any) (total int, err error)
- func (db *DBModel) First(model any) (err error)
- func (db *DBModel) Get(model any, getType GetOne) (err error)
- func (db *DBModel) GroupBy(fields ...string) *DBModel
- func (db *DBModel) Having(field any, opt WhereOpt, value any) *DBModel
- func (db *DBModel) Join(join qb.JoinType, table string, condition Condition) *DBModel
- func (db *DBModel) Last(model any) (err error)
- func (db *DBModel) Limit(limit, offset int) *DBModel
- func (db *DBModel) Model(model any) *DBModel
- func (db *DBModel) Omit(columns ...any) *DBModel
- func (db *DBModel) OrderBy(field string, dir qb.OrderByDir) *DBModel
- func (db *DBModel) Raw(sqlStr string, args ...any) *DBModel
- func (db *DBModel) RemoveFetch() qb.Fetch
- func (db *DBModel) RemoveLimit() qb.Limit
- func (db *DBModel) Rollback() error
- func (db *DBModel) Select(columns ...any) *DBModel
- func (db *DBModel) Update(model any) (err error)
- func (db *DBModel) When(condition bool, groupCondition qb.FnWhereBuilder) *DBModel
- func (db *DBModel) Where(field any, opt qb.WhereOpt, value any) *DBModel
- func (db *DBModel) WhereGroup(groupCondition qb.FnWhereBuilder) *DBModel
- func (db *DBModel) WhereOr(field any, opt qb.WhereOpt, value any) *DBModel
- type FieldEmpty
- type FieldNot
- type FieldYear
- type GetOne
- type IDatabase
- type JoinType
- type MetaData
- type OrderByDir
- type Raw
- type Table
- type ValueField
- type WhereAndOr
- type WhereOpt
Constants ¶
const ( MODEL = "model" // Tag `model` used to store metadata for struct fields TABLE = "table" // Table name in the database TYPE = "type" // Column types for database representation REFERENCE = "ref" // Column reference to another table CASCADE = "cascade" // Cascade rules for DELETE and UPDATE RELATION = "rel" // Relation to another table NAME = "name" // Column name in the database )
Constants for model tag attributes and processing
const ( InnerJoin = qb.InnerJoin // Inner join LeftJoin = qb.LeftJoin // Left outer join RightJoin = qb.RightJoin // Right outer join FullOuterJoin = qb.FullOuterJoin // Full outer join CrossJoin = qb.CrossJoin // Cross join )
Join type constants from fluentsql package
const ( Asc = qb.Asc // Ascending order. Desc = qb.Desc // Descending order. )
Constants representing sorting directions from fluentsql package
const ( And = qb.And // Logical AND operator for combining conditions Or = qb.Or // Logical OR operator for combining conditions )
Logical operator constants from fluentsql package
const ( Eq = qb.Eq // Equal to (=) NotEq = qb.NotEq // Not equal to (<>) Diff = qb.Diff // Not equal to (!=) Greater = qb.Greater // Greater than (>) Lesser = qb.Lesser // Less than (<) GrEq = qb.GrEq // Greater than or equal to (>=) LeEq = qb.LeEq // Less than or equal to (<=) Like = qb.Like // Pattern matching (LIKE) NotLike = qb.NotLike // Not pattern matching (NOT LIKE) In = qb.In // Value in a list (IN) NotIn = qb.NotIn // Value not in a list (NOT IN) Between = qb.Between // Value in a range (BETWEEN) NotBetween = qb.NotBetween // Value not in a range (NOT BETWEEN) Null = qb.Null // Null value (IS NULL) NotNull = qb.NotNull // Not null value (IS NOT NULL) Exists = qb.Exists // Subquery results exist (EXISTS) NotExists = qb.NotExists // Subquery results do not exist (NOT EXISTS) EqAny = qb.EqAny // Equal to any value in a subquery (= ANY) NotEqAny = qb.NotEqAny // Not equal to any value in a subquery (<> ANY) DiffAny = qb.DiffAny // Not equal to any value in a subquery (!= ANY) GreaterAny = qb.GreaterAny // Greater than any value in a subquery (> ANY) LesserAny = qb.LesserAny // Less than any value in a subquery (< ANY) GrEqAny = qb.GrEqAny // Greater than or equal to any value in a subquery (>= ANY) LeEqAny = qb.LeEqAny // Less than or equal to any value in a subquery (<= ANY) EqAll = qb.EqAll // Equal to all values in a subquery (= ALL) NotEqAll = qb.NotEqAll // Not equal to all values in a subquery (<> ALL) DiffAll = qb.DiffAll // Not equal to all values in a subquery (!= ALL) GreaterAll = qb.GreaterAll // Greater than all values in a subquery (> ALL) LesserAll = qb.LesserAll // Less than all values in a subquery (< ALL) GrEqAll = qb.GrEqAll // Greater than or equal to all values in a subquery (>= ALL) LeEqAll = qb.LeEqAll // Less than or equal to all values in a subquery (<= ALL) )
SQL condition operator constants from fluentsql package
Variables ¶
This section is empty.
Functions ¶
func Connect ¶
Connect establishes a database connection with comprehensive configuration and connection pooling. This function creates a new database connection using the specified driver and connection URL, then applies optimal connection pool settings based on environment variables or defaults. It also performs connection validation through a ping operation to ensure the database is accessible and responsive before returning the connection instance.
Parameters:
- connURL (string): The database connection URL/DSN (Data Source Name). Format varies by driver:
- MySQL: "user:password@tcp(host:port)/database?param=value"
- PostgreSQL: "postgres://user:password@host:port/database?sslmode=disable"
- SQLite: "file:path/to/database.db" or ":memory:" for in-memory database
- driver (string): The database driver name. Supported values:
- "mysql": MySQL database driver
- "postgres" or "postgresql": PostgreSQL database driver
- "sqlite3": SQLite database driver
- Custom drivers registered with database/sql
Returns:
- *sqlx.DB: A fully configured database connection with optimized pool settings:
- Connection pooling configured based on environment variables
- Connection lifetime and idle time management
- Verified connectivity through ping operation
- error: Returns an error if:
- Driver is not registered or invalid
- Connection URL is malformed or invalid
- Database server is unreachable
- Authentication fails
- Database does not exist
- Network connectivity issues occur
Environment Variables (with defaults):
- DB_MAX_CONNECTION: Maximum open connections (default: 0 = unlimited)
- DB_MAX_IDLE_CONNECTION: Maximum idle connections (default: 10)
- DB_MAX_LIFETIME_CONNECTION: Connection lifetime in minutes (default: 30)
- DB_MAX_IDLE_TIME_CONNECTION: Connection idle time in minutes (default: 3)
Examples:
// MySQL connection
db, err := Connect("user:pass@tcp(localhost:3306)/mydb", "mysql")
if err != nil {
log.Fatal("Failed to connect to MySQL:", err)
}
defer db.Close()
// PostgreSQL connection
connURL := "postgres://user:pass@localhost:5432/mydb?sslmode=disable"
db, err := Connect(connURL, "postgres")
if err != nil {
log.Fatal("Failed to connect to PostgreSQL:", err)
}
// SQLite connection
db, err := Connect("file:./app.db", "sqlite3")
if err != nil {
log.Fatal("Failed to connect to SQLite:", err)
}
// In-memory SQLite for testing
db, err := Connect(":memory:", "sqlite3")
if err != nil {
log.Fatal("Failed to create in-memory database:", err)
}
Note:
- Connection pool settings are automatically applied for optimal performance
- The connection is validated with a ping operation before being returned
- Failed connections are automatically closed to prevent resource leaks
- Environment variables allow runtime configuration without code changes
func CreateModel ¶
CreateModel creates a new record of type T in the database. It begins a transaction, attempts to create the record, and commits the transaction. If an error occurs, the transaction is rolled back and the error is returned.
Generic Type:
- T: The type of the model.
Parameters:
- m (*T): A pointer to the model to be created.
Returns:
- error: An error object if an error occurs during the creation process.
func DeleteModel ¶
DeleteModel deletes a record of type T from the database. It begins a transaction, deletes the record, and commits the transaction. If an error occurs, the transaction is rolled back and the error is returned.
Generic Type:
- T: The type of the model.
Parameters:
- m (*T): A pointer to the model to be deleted.
Returns:
- error: An error object if an error occurs during the deletion process.
func FindModels ¶
func FindModels[T any](page, limit int, sortField string, sortDir qb.OrderByDir, conditions ...qb.Condition) ([]T, int, error)
FindModels retrieves a paginated list of records of type T from the database that match the provided conditions.
Generic Type:
- T: The type of the model.
Parameters:
- page (int): The current page number (1-based). Defaults to 0 if not provided.
- limit (int): The number of records to retrieve per page.
- sortField (string): The field name to sort the results by.
- sortDir (qb.OrderByDir): The sorting direction (qb.Asc for ascending, qb.Desc for descending).
- conditions (...qb.Condition): Variadic list of qb.Condition specifying the field, operator, and value to filter the query.
Returns:
- []T: A slice of records of type T.
- int: The total number of records that match the conditions.
- error: An error object if an error occurs during the retrieval process.
func GetModel ¶
GetModel retrieves the first record of type T from the database that matches the provided conditions.
Generic Type:
- T: The type of the model.
Parameters:
- conditions (...qb.Condition): Variadic list of qb.Condition specifying the field, operator, and value to filter the query.
Returns:
- *T: A pointer to the retrieved model of type T, or nil if no matching record is found.
- error: An error object if an error occurs during the retrieval process. Returns nil if the query succeeds. Logs unexpected errors.
func GetModelBy ¶
GetModelBy allows filtering records of type T from the database by specifying a field and its required value.
This is a helper function that makes use of the GetModelWhereEq function to apply an equality condition.
Generic Type:
- T: The type of the model.
Parameters:
- field (string): The name of the database field to filter on.
- value (any): The value the specified field is required to equal.
Returns:
- *T: A pointer to the first matching record of type T retrieved from the database, or nil if no record is found.
- error: An error object if an error occurs during the retrieval process.
func GetModelByID ¶
GetModelByID retrieves a single database record by its primary key identifier. This is the most commonly used function for fetching individual records when you know the primary key value. It provides a convenient, type-safe way to retrieve records without manually constructing WHERE conditions. The function assumes the primary key field is named "id" and automatically handles type conversion and error handling.
Generic Type:
- T: The model struct type that represents the database table. Must have appropriate database tags for column mapping and should include an "id" field as the primary key.
Parameters:
- value (any): The primary key value to search for. Supported types:
- int, int64, uint, uint64: For integer primary keys
- string: For string-based primary keys (UUIDs, etc.)
- Other types that can be converted to database-compatible values The value will be automatically converted to match the target field type.
Returns:
- *T: A pointer to the retrieved model instance with all fields populated from the database. Returns nil if no record is found with the specified ID.
- error: Returns an error if:
- Database connection fails
- The model type T cannot be processed
- SQL execution fails
- Type conversion fails Returns errors.ItemNotFound if no record exists with the given ID. Returns nil on successful retrieval.
Examples:
// Retrieve user by integer ID
type User struct {
ID int64 `db:"id,primary"`
Name string `db:"name"`
Email string `db:"email"`
}
user, err := GetModelByID[User](123)
if err != nil {
if errors.Is(err, errors.ItemNotFound) {
log.Println("User not found")
} else {
log.Printf("Database error: %v", err)
}
return
}
fmt.Printf("Found user: %s (%s)", user.Name, user.Email)
// Retrieve product by string ID (UUID)
type Product struct {
ID string `db:"id,primary"`
Name string `db:"name"`
Price float64 `db:"price"`
}
productID := "550e8400-e29b-41d4-a716-446655440000"
product, err := GetModelByID[Product](productID)
if err == nil {
fmt.Printf("Product: %s - $%.2f", product.Name, product.Price)
}
// Error handling patterns
order, err := GetModelByID[Order](456)
switch {
case errors.Is(err, errors.ItemNotFound):
// Handle not found case
return nil, fmt.Errorf("order %d does not exist", 456)
case err != nil:
// Handle other database errors
return nil, fmt.Errorf("failed to retrieve order: %w", err)
default:
// Success case
return order, nil
}
// Batch retrieval with error handling
userIDs := []int64{1, 2, 3, 4, 5}
var users []*User
for _, id := range userIDs {
user, err := GetModelByID[User](id)
if err != nil && !errors.Is(err, errors.ItemNotFound) {
return nil, err // Stop on database errors
}
if user != nil {
users = append(users, user)
}
}
Use Cases:
- Retrieving user profiles by user ID
- Fetching specific orders, products, or entities by their primary key
- Loading related records when you have foreign key references
- Implementing REST API endpoints that accept ID parameters
- Cache lookups where you need to fetch missing records by ID
Performance Notes:
- Uses primary key index for optimal query performance
- Single database round trip for each call
- Efficient for individual record retrieval
- Consider batch operations for multiple records
Note:
- Assumes the primary key field is named "id"
- Returns errors.ItemNotFound for missing records (not sql.ErrNoRows)
- The model type T must have proper database tags
- Thread-safe and can be called concurrently
- Automatically handles database connection management
func GetModelWhereEq ¶
GetModelWhereEq retrieves the first record of type T from the database where the specified field equals the given value.
Generic Type:
- T: The type of the model.
Parameters:
- field (string): The name of the database field to filter by.
- value (any): The value to match the field against.
Returns:
- *T: A pointer to the retrieved model of type T, or nil if no matching record is found.
- error: An error object if an error occurs during the retrieval process.
func Load ¶
func Load()
Load initializes the global database connection using the registered driver. This function establishes the primary database connection that will be used throughout the application lifecycle. It delegates the actual connection establishment to the registered database driver and assigns the result to the global dbInstance variable. The function is designed to be called once during application startup.
Behavior:
- Calls the Load() method on the currently registered database driver
- Assigns the resulting connection to the global dbInstance variable
- Panics immediately if the connection cannot be established
- Should be called after registering a proper database driver via Register()
Panics:
- If no database driver has been registered (uses emptyDB which always fails)
- If the registered driver fails to establish a connection
- If database server is unreachable or credentials are invalid
- If the specified database does not exist
Examples:
// Basic application initialization
func main() {
// Register database driver
mysqlDriver := &MySQLDriver{
Host: "localhost",
Port: 3306,
Database: "myapp",
Username: "user",
Password: "password",
}
Register(mysqlDriver)
// Initialize database connection
Load() // Will panic if connection fails
// Application is ready to use database
// dbInstance is now available for ORM operations
}
// With error handling (using recover)
func initDatabase() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("database initialization failed: %v", r)
}
}()
Register(&PostgreSQLDriver{ConnectionString: "postgres://..."})
Load()
return nil
}
// Testing setup
func setupTestDB() {
Register(&MockDriver{}) // Use in-memory database
Load()
}
Note:
- Must be called after Register() to use a proper database driver
- Panics on failure to ensure database connectivity is verified at startup
- Should only be called once during application initialization
- The resulting connection is stored in the global dbInstance variable
- All ORM operations depend on this function being called successfully
func Register ¶
func Register(driver IDatabase)
Register replaces the default database driver with a custom implementation. This function allows applications to specify their database driver (MySQL, PostgreSQL, etc.) by providing an implementation of the IDatabase interface. The registered driver will be used by the Load() function to establish database connections. This design enables driver-specific configuration and connection logic while maintaining a consistent API.
Parameters:
- driver (IDatabase): A custom database driver that implements the IDatabase interface. The driver should handle:
- Database-specific connection string formatting
- Driver-specific configuration options
- Connection establishment and validation
- Error handling for connection failures
Examples:
// MySQL driver registration
type MySQLDriver struct {
Host string
Port int
Database string
Username string
Password string
}
func (d *MySQLDriver) Load() (*sqlx.DB, error) {
connStr := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s",
d.Username, d.Password, d.Host, d.Port, d.Database)
return Connect(connStr, "mysql")
}
// Register the MySQL driver
mysqlDriver := &MySQLDriver{
Host: "localhost",
Port: 3306,
Database: "myapp",
Username: "user",
Password: "password",
}
Register(mysqlDriver)
// PostgreSQL driver registration
type PostgreSQLDriver struct {
ConnectionString string
}
func (d *PostgreSQLDriver) Load() (*sqlx.DB, error) {
return Connect(d.ConnectionString, "postgres")
}
pgDriver := &PostgreSQLDriver{
ConnectionString: "postgres://user:pass@localhost/dbname?sslmode=disable",
}
Register(pgDriver)
// Test/Mock driver registration
type MockDriver struct{}
func (d *MockDriver) Load() (*sqlx.DB, error) {
return Connect(":memory:", "sqlite3")
}
Register(&MockDriver{}) // Useful for testing
Note:
- This function replaces the global dbDriver variable
- Should be called before Load() to ensure the correct driver is used
- The driver will be used for all subsequent database connections
- Typically called during application initialization
- Can be called multiple times to change drivers (useful for testing)
func UpdateModel ¶
UpdateModel updates a record of type T in the database. It begins a transaction, updates the record, and commits the transaction. If an error occurs, the transaction is rolled back and the error is returned.
Generic Type:
- T: The type of the model.
Parameters:
- m (*T): A pointer to the model to be updated.
Returns:
- error: An error object if an error occurs during the update process.
Types ¶
type Column ¶
type Column struct {
Key string // Name of the struct field the column maps to
Name string // Name of the database column
Primary bool // Indicates if the column is a primary key
Types string // Data type of the column
Ref string // Reference to another table column
Relation string // Relation to another table
IsZero bool // Indicates if the column value is the zero value for its type
HasValue bool // Indicates if the column has a valid (non-zero) value
}
Column structure that maps a struct field to a database table column
type Condition ¶
type Condition struct {
// Field represents the name of the column to compare. It can be of type `string` or `FieldNot`.
Field any
// Opt specifies the condition operator such as =, <>, >, <, >=, <=, LIKE, IN, NOT IN, BETWEEN, etc.
Opt WhereOpt
// Value holds the value to be compared against the field. Support ValueField for checking with table's column
Value any
// AndOr specifies the logical combination with the previous condition (AND, OR). Default is AND.
AndOr WhereAndOr
// Group contains sub-conditions enclosed in parentheses `()`.
Group []Condition
}
Condition represents a single condition in a WHERE clause. This is an alias for fluentsql.Condition to maintain backward compatibility.
Usage:
- Defines comparison operations between fields and values
- Supports standard SQL operators (=, >, <, LIKE, etc.)
- Can be combined to form complex conditions
Example:
WHERE user_id = 1 AND status = 'active'
Condition type struct
func (Condition) ToQBCondition ¶
ToQBCondition converts a Condition to qb.Condition. This helper function recursively converts the local Condition struct to the fluentsql qb.Condition struct, including any nested Group conditions.
Returns:
- qb.Condition: The converted condition ready for use with fluentsql
Example:
condition := Condition{
Field: "user_id",
Opt: Eq,
Value: 123,
AndOr: And,
}
qbCondition := condition.ToQBCondition()
type DB ¶
type DB struct {
*sqlx.DB // Embedded sqlx.DB for working with SQL databases, providing full sqlx functionality
}
DB represents a database connection wrapper that embeds sqlx.DB to provide extended functionality. This struct serves as the foundation for database operations throughout the application, providing a consistent interface while leveraging the powerful features of sqlx.DB. The embedded sqlx.DB allows direct access to all sqlx methods while enabling additional custom functionality to be added as needed.
Fields:
- *sqlx.DB: Embedded sqlx.DB instance providing:
- Named parameter support for queries
- Struct scanning capabilities
- Transaction management
- Connection pooling
- Prepared statement caching
Usage:
// The DB struct is typically used internally by the ORM
// and accessed through the global dbInstance variable
db := &DB{DB: sqlxConnection}
// Direct access to sqlx methods is available
rows, err := dbInstance.Query("SELECT * FROM users")
// Custom methods can be added to extend functionality
// while maintaining compatibility with sqlx.DB
type DBModel ¶
type DBModel struct {
// contains filtered or unexported fields
}
DBModel represents the core fluent interface for database operations and query building. This struct serves as the primary entry point for all database interactions, providing a chainable API for constructing complex SQL queries, managing transactions, and executing database operations. It encapsulates various SQL clause builders and maintains state for both ORM-style operations and raw SQL execution.
Fields:
tx (*sqlx.Tx): Optional database transaction for atomic operations. When set, all database operations will be executed within this transaction context. Nil indicates operations should use the global database connection.
model (any): The target model struct that defines the database table structure. Used for ORM operations to determine table name, column mappings, and data types. Should be a struct or pointer to struct with appropriate database tags.
raw (Raw): Container for raw SQL queries and their parameters. When populated, takes precedence over query builder operations. Allows execution of custom SQL that bypasses the ORM query construction.
selectStatement (qb.Select): Builder for SELECT clause construction. Manages column selection, including specific columns, expressions, and aliases. Used in conjunction with query operations to control result set structure.
omitsSelectStatement (qb.Select): Builder for column omission in SELECT operations. Specifies columns to exclude from SELECT statements, useful for excluding sensitive or unnecessary fields from query results.
whereStatement (qb.Where): Builder for WHERE clause conditions. Manages filtering conditions including AND, OR, and grouped conditions. Supports various comparison operators and complex conditional logic.
joinStatement (qb.Join): Builder for JOIN operations between tables. Handles INNER, LEFT, RIGHT, and FULL OUTER joins with custom conditions. Enables relational queries across multiple tables.
groupByStatement (qb.GroupBy): Builder for GROUP BY clause construction. Manages column grouping for aggregate operations and result set organization. Works in conjunction with aggregate functions and HAVING clauses.
havingStatement (qb.Having): Builder for HAVING clause conditions. Provides filtering capabilities for grouped results, similar to WHERE but operates on aggregated data after GROUP BY operations.
orderByStatement (qb.OrderBy): Builder for ORDER BY clause construction. Manages result set sorting with support for multiple columns and directions. Enables ascending and descending sort orders with custom priority.
limitStatement (qb.Limit): Builder for LIMIT and OFFSET operations. Controls result set size and pagination for efficient data retrieval. Supports both limit-only and limit-with-offset configurations.
fetchStatement (qb.Fetch): Builder for FETCH clause operations. Alternative to LIMIT for databases that support FETCH FIRST/NEXT syntax. Provides SQL standard-compliant result set limiting.
Usage Patterns:
// Basic query building
db := Instance().Model(&User{}).Where("age", qb.Gt, 18).OrderBy("name", qb.Asc)
// Transaction-based operations
db := Instance().Begin()
defer db.Rollback() // Rollback if not committed
// Raw SQL execution
db := Instance().Raw("SELECT * FROM users WHERE custom_condition")
// Complex query with multiple clauses
db := Instance().Model(&User{}).
Select("name", "email").
Where("status", qb.Eq, "active").
Join(qb.InnerJoin, "profiles", qb.Condition{Field: "users.id", Opt: qb.Eq, Value: "profiles.user_id"}).
GroupBy("department").
Having("COUNT(*)", qb.Gt, 5).
OrderBy("created_at", qb.Desc).
Limit(10, 0)
Note:
- All builder fields are reset after each operation to prevent state leakage
- Transaction field persists across operations until explicitly committed or rolled back
- Raw SQL takes precedence over query builder operations when both are present
- The struct is designed for method chaining to create fluent, readable database code
func Instance ¶
func Instance() *DBModel
Instance creates and returns a new DBModel instance for database operations. This function serves as the primary entry point for creating database query builders and performing ORM operations. Each instance is independent and maintains its own state for query building, allowing for concurrent usage and isolated operations. The returned instance provides a fluent interface for chaining database operations.
Returns:
- *DBModel: A new database model instance with:
- Clean state with no active transaction
- Empty query builders ready for configuration
- No associated model (must be set via Model() method)
- All SQL clause builders initialized to empty state
Examples:
// Basic instance creation for simple queries
db := Instance()
users := []User{}
err := db.Model(&User{}).Find(&users)
// Chained operations with fluent interface
db := Instance().Model(&User{}).Where("age", qb.Gt, 18).OrderBy("name", qb.Asc)
// Multiple independent instances
userDB := Instance().Model(&User{})
productDB := Instance().Model(&Product{})
// Each instance maintains separate state
// Transaction-based operations
db := Instance().Begin()
defer func() {
if r := recover(); r != nil {
db.Rollback()
}
}()
// Perform operations within transaction
err := db.Model(&User{}).Create(user)
if err != nil {
db.Rollback()
return err
}
return db.Commit()
// Raw SQL operations
db := Instance().Raw("SELECT COUNT(*) FROM users WHERE status = ?", "active")
var count int
err := db.Get(&count)
Usage Patterns:
- Create instance → Set model → Build query → Execute operation
- Instance().Model(&Model{}).QueryMethod().ExecutionMethod()
- Each instance is independent and thread-safe for its own operations
- Instances can be reused but are automatically reset after operations
Note:
- Each call creates a completely new instance with clean state
- No database connection is established until an operation is executed
- The instance must be configured with a model before most operations
- Transaction state persists across operations until committed or rolled back
- All query builder state is reset after each terminal operation
func (*DBModel) Begin ¶
Begin starts a new database transaction.
Returns:
- *DBModel: The DBModel instance with an active transaction.
func (*DBModel) Commit ¶
Commit commits the current database transaction.
Returns:
- error: An error, if any, that occurred during the commit process.
func (*DBModel) Create ¶
Create inserts new data into a database table using various model types. This method provides a flexible interface for inserting data by automatically detecting the input type and routing to the appropriate insertion strategy. It supports raw SQL queries, map-based insertion, batch insertion via slices, and single record insertion via structs.
Parameters:
- model (any): The data to be inserted. Supported types:
- Raw SQL: When db.raw.sqlStr is set, uses raw SQL insertion
- map[string]any: Creates a record using key-value pairs from the map
- []Struct or []*Struct: Batch insertion of multiple records
- Struct or *Struct: Single record insertion using struct fields
Returns:
- error: Returns an error if the insertion fails, model type is unsupported, or if there are database connectivity issues. Returns nil on success.
Examples:
// Single struct insertion
user := User{Name: "John", Email: "john@example.com"}
err := db.Model(&User{}).Create(user)
// Pointer to struct insertion
user := &User{Name: "Jane", Email: "jane@example.com"}
err := db.Model(&User{}).Create(user)
// Batch insertion with slice
users := []User{
{Name: "Alice", Email: "alice@example.com"},
{Name: "Bob", Email: "bob@example.com"},
}
err := db.Model(&User{}).Create(users)
// Map-based insertion
userData := map[string]any{
"name": "Charlie",
"email": "charlie@example.com",
"age": 30,
}
err := db.Model(&User{}).Create(userData)
// Raw SQL insertion
err := db.Model(&User{}).Raw("INSERT INTO users (name, email) VALUES (?, ?)", "David", "david@example.com").Create(nil)
Note:
- Primary key fields are automatically handled and populated after insertion
- The method respects Select() and Omit() clauses for column filtering
- For batch operations, if one record fails, the entire operation may fail
- The model is reset after the operation completes
func (*DBModel) Delete ¶
Delete removes records from the database table based on the provided model and conditions. This method provides a flexible approach to data deletion by supporting both primary key-based deletion and conditional deletion using WHERE clauses. It automatically constructs DELETE SQL statements based on the model's primary keys and any additional conditions specified through the fluent interface. The method ensures safe deletion by requiring at least one WHERE condition to prevent accidental deletion of all table data.
Parameters:
- model (any): The model defining the target table and deletion criteria. Supported types:
- Struct: Direct struct value representing the table model (e.g., User{ID: 1})
- *Struct: Pointer to struct representing the table model (e.g., &User{ID: 1})
- The struct should have appropriate field tags for database mapping
- Primary key fields in the model are used to build WHERE conditions automatically
- Non-nil primary key values are included in the deletion criteria
Returns:
- error: Returns an error if:
- The model cannot be processed or reflected (invalid struct type)
- Table metadata extraction fails
- No WHERE conditions are present (safety requirement)
- Raw SQL execution fails (when using Raw() method)
- DELETE statement construction fails
- Database execution fails
- Database connectivity issues occur Returns nil on successful deletion.
Examples:
// Delete by primary key
user := User{ID: 123}
err := db.Model(&User{}).Delete(user)
// Executes: DELETE FROM users WHERE id = 123
// Delete with pointer to struct
user := &User{ID: 456}
err := db.Model(&User{}).Delete(user)
// Executes: DELETE FROM users WHERE id = 456
// Delete with additional WHERE conditions
user := User{}
err := db.Model(&User{}).Where("status", "inactive").Delete(user)
// Executes: DELETE FROM users WHERE status = 'inactive'
// Delete with multiple conditions
user := User{ID: 789}
err := db.Model(&User{}).Where("created_at < ?", time.Now().AddDate(-1, 0, 0)).Delete(user)
// Executes: DELETE FROM users WHERE id = 789 AND created_at < '2023-01-01'
// Delete with OR conditions
user := User{}
err := db.Model(&User{}).Where("status", "inactive").Or("last_login < ?", oldDate).Delete(user)
// Executes: DELETE FROM users WHERE status = 'inactive' OR last_login < '2023-01-01'
// Delete with grouped conditions
user := User{}
err := db.Model(&User{}).Where("status", "inactive").
Where(func(db *DBModel) *DBModel {
return db.Where("role", "guest").Or("role", "temp")
}).Delete(user)
// Executes: DELETE FROM users WHERE status = 'inactive' AND (role = 'guest' OR role = 'temp')
// Raw SQL deletion
user := User{}
err := db.Model(&User{}).Raw("DELETE FROM users WHERE created_at < NOW() - INTERVAL 1 YEAR").Delete(user)
// Executes the raw SQL directly
// Composite primary key deletion
orderItem := OrderItem{OrderID: 100, ProductID: 200}
err := db.Model(&OrderItem{}).Delete(orderItem)
// Executes: DELETE FROM order_items WHERE order_id = 100 AND product_id = 200
Safety Features:
- Requires at least one WHERE condition to prevent accidental mass deletion
- Automatically includes non-nil primary key values as WHERE conditions
- Validates model structure before executing deletion
- Supports transaction rollback through proper error handling
Note:
- Primary key fields with nil/zero values are ignored in WHERE conditions
- The method respects all WHERE conditions set via the fluent interface
- Raw SQL takes precedence over model-based deletion when both are present
- The fluent model builder is automatically reset after the operation
- For mass deletion, use Raw() method with appropriate WHERE clauses
- Composite primary keys are fully supported with AND logic
- The operation is atomic and will either succeed completely or fail without changes
func (*DBModel) Fetch ¶
Fetch adds a FETCH clause to the query.
Parameters:
- offset (int): The offset for fetching rows.
- fetch (int): The number of rows to fetch.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Find ¶
Find searches for multiple rows in the database based on query criteria.
Parameters:
- model (any): A pointer to the slice where the retrieved rows will be stored.
Returns:
- total (int): The total number of rows matching the query criteria.
- err (error): An error object if any issues occur during the retrieval process; nil otherwise.
func (*DBModel) First ¶
First retrieves the first record ordered by primary key.
Parameters:
- model (any): A pointer to the model where the result will be stored.
Returns:
- err (error): An error object if any issues occur during the retrieval process; nil otherwise.
func (*DBModel) Get ¶
Get retrieves a single record from the database based on the specified strategy.
Parameters:
- model (any): A pointer to the model where the retrieved record will be stored.
- getType (GetOne): The strategy for selecting the record. Possible values are:
- GetFirst: Retrieve the first record ordered by primary key in ascending order.
- GetLast: Retrieve the last record ordered by primary key in descending order.
- TakeOne: Retrieve a random record.
Returns:
- err (error): An error object if any issues occur during the retrieval process; nil otherwise.
func (*DBModel) GroupBy ¶
GroupBy adds GROUP BY fields to the query.
Parameters:
- fields (...string): The fields to group by.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Having ¶
Having adds a HAVING condition to the query.
Parameters:
- field (any): The field or column to filter.
- opt (qb.WhereOpt): The operator to use.
- value (any): The value to compare against.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Join ¶
Join adds a JOIN clause to the query.
Parameters:
- join (qb.JoinType): The type of join (e.g., INNER, LEFT).
- table (string): The name of the table to join.
- condition (qb.Condition): The condition for the join.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Last ¶
Last retrieves the last record ordered by primary key in descending order.
Parameters:
- model (any): A pointer to the model where the result will be stored.
Returns:
- err (error): An error object if any issues occur during the retrieval process; nil otherwise.
func (*DBModel) Limit ¶
Limit adds a LIMIT clause to the query.
Parameters:
- limit (int): The maximum number of rows to return.
- offset (int): The number of rows to skip.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Model ¶
Model associates a struct model with the DBModel instance for ORM operations. This method is fundamental to the ORM functionality as it defines the target table structure, column mappings, and data types for database operations. The model struct should have appropriate database tags to define table and column mappings. This method must be called before most ORM operations to establish the context.
Parameters:
- model (any): The model struct that defines the database table structure. Supported types:
- Struct: Direct struct value (e.g., User{})
- *Struct: Pointer to struct (e.g., &User{}) - recommended for most operations
- The struct should have database tags for proper column mapping:
- `db:"column_name"` for column name mapping
- `db:"column_name,primary"` for primary key designation
- `db:"-"` to exclude fields from database operations
Returns:
- *DBModel: The same DBModel instance for method chaining, now configured with the model.
Examples:
// Basic model association
type User struct {
ID int `db:"id,primary"`
Name string `db:"name"`
Email string `db:"email"`
Age int `db:"age"`
}
db := Instance().Model(&User{})
// Query operations after model association
var users []User
err := db.Find(&users)
// Create operations
user := User{Name: "John", Email: "john@example.com", Age: 30}
err := db.Create(&user) // user.ID will be populated
// Update operations
user.Age = 31
err := db.Where("id", Eq, user.ID).Update(&user)
// Delete operations
err := db.Where("id", Eq, user.ID).Delete(&user)
// Complex model with relationships
type Order struct {
ID int `db:"id,primary"`
UserID int `db:"user_id"`
Total float64 `db:"total"`
Status string `db:"status"`
Created time.Time `db:"created_at"`
Updated time.Time `db:"updated_at"`
Internal string `db:"-"` // Excluded from database operations
}
db := Instance().Model(&Order{})
// Model with custom table name (if different from struct name)
type UserProfile struct {
ID int `db:"id,primary"`
UserID int `db:"user_id"`
Bio string `db:"biography"`
} // Maps to "user_profiles" table by convention
// Multiple models for different operations
userDB := Instance().Model(&User{})
orderDB := Instance().Model(&Order{})
// Each instance maintains separate model context
// Model reuse with different instances
db1 := Instance().Model(&User{}).Where("status", Eq, "active")
db2 := Instance().Model(&User{}).Where("age", qb.Gt, 18)
// Independent query contexts with same model
Model Requirements:
- Struct fields should be exported (capitalized)
- Use appropriate database tags for column mapping
- Primary key fields should be tagged with "primary"
- Time fields should use time.Time type for proper handling
- Nullable fields can use sql.NullString, sql.NullInt64, etc.
Common Patterns:
- Always use pointer to struct: Model(&User{}) instead of Model(User{})
- Set model before any ORM operations
- One model per DBModel instance for clarity
- Use consistent naming conventions between struct and database
Note:
- The model defines the target table name (derived from struct name)
- Column mappings are established through struct tags
- Primary key detection is automatic based on "primary" tag
- The model persists until the DBModel instance is reset
- Required for Create, Update, Delete, Find, and other ORM operations
- Raw SQL operations can work without a model but lose ORM benefits
func (*DBModel) Omit ¶
Omit excludes specific columns from retrieval.
Parameters:
- columns (...any): Variadic list of columns to omit.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) OrderBy ¶
func (db *DBModel) OrderBy(field string, dir qb.OrderByDir) *DBModel
OrderBy adds an ORDER BY clause to the query.
Parameters:
- field (string): The field to sort by.
- dir (qb.OrderByDir): The sorting direction (e.g., ASC or DESC).
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Raw ¶
Raw configures the DBModel to execute a custom SQL query with parameters. This method allows bypassing the ORM's query builder to execute hand-crafted SQL for complex operations, database-specific features, or performance optimization. When Raw is used, it takes precedence over all other query building methods, and the provided SQL will be executed directly against the database.
Parameters:
- sqlStr (string): The raw SQL query string with parameter placeholders. Supports database-specific placeholder syntax:
- MySQL/SQLite: Use ? for parameters (e.g., "SELECT * FROM users WHERE id = ?")
- PostgreSQL: Use $1, $2, etc. for parameters (e.g., "SELECT * FROM users WHERE id = $1")
- args (...any): Variadic arguments that correspond to the parameter placeholders. Arguments are applied in order and should match the placeholder count and expected types. Supports all Go types that can be converted to SQL types.
Returns:
- *DBModel: The same DBModel instance for method chaining, configured for raw SQL execution.
Examples:
// Simple SELECT with parameters
var users []User
err := Instance().Raw("SELECT * FROM users WHERE age > ? AND status = ?", 18, "active").Find(&users)
// Complex query with joins and subqueries
var results []UserStats
query := `
SELECT u.name, COUNT(o.id) as order_count, AVG(o.total) as avg_order
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at > ?
GROUP BY u.id, u.name
HAVING COUNT(o.id) > ?
ORDER BY avg_order DESC
`
err := Instance().Raw(query, time.Now().AddDate(-1, 0, 0), 5).Find(&results)
// Database-specific functions
var count int
err := Instance().Raw("SELECT COUNT(*) FROM users WHERE MATCH(name) AGAINST(?)", "john").Get(&count)
// INSERT with RETURNING (PostgreSQL)
var newID int
err := Instance().Raw("INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id", "John", "john@example.com").Get(&newID)
// UPDATE with complex conditions
err := Instance().Raw("UPDATE products SET price = price * 0.9 WHERE category_id IN (SELECT id FROM categories WHERE name = ?)", "electronics").Exec()
// DELETE with joins
err := Instance().Raw("DELETE u FROM users u JOIN user_sessions s ON u.id = s.user_id WHERE s.last_activity < ?", oldDate).Exec()
// Stored procedure call
err := Instance().Raw("CALL update_user_statistics(?)", userID).Exec()
// Common Table Expression (CTE)
query := `
WITH RECURSIVE category_tree AS (
SELECT id, name, parent_id, 0 as level FROM categories WHERE parent_id IS NULL
UNION ALL
SELECT c.id, c.name, c.parent_id, ct.level + 1
FROM categories c
JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree WHERE level <= ?
`
var categories []Category
err := Instance().Raw(query, 3).Find(&categories)
Use Cases:
- Complex analytical queries with window functions
- Database-specific optimizations and hints
- Stored procedure and function calls
- Bulk operations with custom logic
- Migration and schema manipulation queries
- Performance-critical queries requiring manual optimization
Note:
- Raw SQL takes precedence over all query builder methods
- Parameter placeholders prevent SQL injection when used properly
- The query is executed in the current transaction context if one exists
- Database-specific syntax should match the configured database driver
- Use appropriate execution methods: Get() for single row, Find() for multiple rows, Exec() for non-query operations
- SQL debugging can be enabled via DB_DEBUG environment variable
func (*DBModel) RemoveFetch ¶
RemoveFetch removes the FETCH clause from the query.
Returns:
- qb.Fetch: The removed fetch settings.
func (*DBModel) RemoveLimit ¶
RemoveLimit removes the LIMIT clause from the query.
Returns:
- qb.Limit: The removed limit settings.
func (*DBModel) Rollback ¶
Rollback rolls back the current database transaction.
Returns:
- error: An error, if any, that occurred during the rollback process.
func (*DBModel) Select ¶
Select specifies the list of columns to retrieve.
Parameters:
- columns (...any): Variadic list of columns to include in the SELECT clause.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Update ¶
Update modifies data for a table using a model of type Struct or *Struct.
Parameters:
- model (any): The data model used for updating the table. It can be of type Struct, *Struct, or a map.
Returns:
- error: Returns an error if the update process fails.
func (*DBModel) When ¶
func (db *DBModel) When(condition bool, groupCondition qb.FnWhereBuilder) *DBModel
When conditionally applies a WHERE condition if the provided condition is TRUE.
Parameters:
- condition (bool): Determines whether the condition should be applied.
- groupCondition (qb.FnWhereBuilder): The function to build the condition.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) Where ¶
Where adds a WHERE condition to the query.
Parameters:
- field (any): The field or column to filter.
- opt (qb.WhereOpt): The operator to use (e.g., equals, greater than).
- value (any): The value to compare against.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
func (*DBModel) WhereGroup ¶
func (db *DBModel) WhereGroup(groupCondition qb.FnWhereBuilder) *DBModel
WhereGroup combines multiple WHERE conditions into a group.
Parameters:
- groupCondition (qb.FnWhereBuilder): The function to build grouped conditions.
Returns:
- *DBModel: A reference to the DBModel instance for chaining.
type FieldEmpty ¶
type FieldEmpty qb.FieldEmpty
FieldEmpty represents an empty SQL field, often used in conditions like EXISTS or NOT EXISTS. This is an alias for fluentsql.FieldEmpty to maintain backward compatibility.
Usage:
- Used in subquery conditions where no specific field is referenced
- Commonly used with EXISTS and NOT EXISTS operations
Example:
WHERE NOT EXISTS (SELECT employee_id FROM dependents)
type FieldNot ¶
FieldNot represents a SQL field prefixed with a NOT operator for negating conditions. This is an alias for fluentsql.FieldNot to maintain backward compatibility.
Usage:
- Used to create negated field conditions in SQL queries
- Applies NOT operator to field expressions
Methods:
- String(): Returns the SQL string representation of the negated field.
type FieldYear ¶
FieldYear represents a SQL year extraction operation for a given field. This is an alias for fluentsql.FieldYear to maintain backward compatibility.
Usage:
- Extracts the year portion from date/datetime fields
- Generates database-specific SQL syntax for year extraction
Database-specific implementations:
- MySQL: YEAR(hire_date) Between 1990 AND 1993
- PostgreSQL: DATE_PART('year', hire_date) Between 1990 AND 1993
- SQLite: strftime('%Y', hire_date)
type GetOne ¶
type GetOne int
GetOne represents a strategy for retrieving a single record from the database. Possible values are GetFirst, GetLast, and TakeOne.
type IDatabase ¶
type IDatabase interface {
// Load establishes a connection to the database and returns a configured sqlx.DB instance.
// This method should handle all driver-specific connection logic, including:
// - Connection string parsing and validation
// - Driver-specific configuration options
// - Connection pool settings
// - Initial connection verification
//
// Returns:
// - *sqlx.DB: A fully configured and tested database connection ready for use
// - error: An error if connection establishment fails, including network issues,
// authentication failures, or configuration problems
Load() (*sqlx.DB, error)
}
IDatabase interface defines a contract for database loading operations. This interface provides a standardized way to implement different database drivers and connection strategies while maintaining a consistent API for database initialization. Implementations should handle driver-specific connection logic and configuration.
Methods:
- Load() (*sqlx.DB, error): Establishes and returns a configured database connection
Examples of implementations:
- MySQL driver: Handles MySQL-specific connection strings and configurations
- PostgreSQL driver: Handles PostgreSQL-specific connection strings and configurations
- Mock/Test driver: Provides test database connections for unit testing
Usage:
type MySQLDriver struct {
connectionString string
}
func (d *MySQLDriver) Load() (*sqlx.DB, error) {
return Connect(d.connectionString, "mysql")
}
// Register the driver
Register(&MySQLDriver{connectionString: "user:pass@tcp(localhost:3306)/dbname"})
type JoinType ¶
JoinType represents the type of SQL join operation. This is an alias for fluentsql.JoinType to maintain backward compatibility.
type OrderByDir ¶
type OrderByDir = qb.OrderByDir
OrderByDir represents the sorting direction. This is an alias for fluentsql.OrderByDir to maintain backward compatibility.
Values: - Asc: Ascending order. - Desc: Descending order.
type Raw ¶
type Raw struct {
// contains filtered or unexported fields
}
Raw represents a raw SQL query with its associated parameters for direct database execution. This struct encapsulates both the SQL query string and its corresponding arguments, providing a way to execute custom SQL queries that bypass the ORM's query builder. It's particularly useful for complex queries, database-specific operations, or performance-critical scenarios where hand-crafted SQL is preferred.
Fields:
- sqlStr (string): The raw SQL query string with parameter placeholders. Supports standard SQL parameter placeholders (? for most databases, $1, $2, etc. for PostgreSQL)
- args ([]any): Slice of arguments that correspond to the parameter placeholders in sqlStr. Arguments are applied in order and should match the placeholder count and types
Usage:
// The Raw struct is typically used internally by the Raw() method
raw := Raw{
sqlStr: "SELECT * FROM users WHERE age > ? AND status = ?",
args: []any{18, "active"},
}
// More commonly used through the fluent interface:
db.Raw("SELECT * FROM users WHERE age > ? AND status = ?", 18, "active")
Examples of supported SQL operations:
- Complex SELECT queries with subqueries and CTEs
- Database-specific functions and operators
- Stored procedure calls
- Data manipulation with custom logic
- Performance-optimized queries
- Database administration commands
type Table ¶
type Table struct {
Name string // Database table name derived from struct name (snake_case)
Columns []Column // Complete column definitions with metadata and constraints
Primaries []Column // Primary key columns for unique identification and operations
Values map[string]any // Current column values indexed by column name for operations
Relation []*Table // Related table structures for foreign key and JOIN operations
HasData bool // Flag indicating presence of valid, non-zero data in the struct
}
Table represents the complete metadata and structure of a database table derived from a Go struct. This struct serves as the bridge between Go struct definitions and database table operations, containing all necessary information for ORM functionality including column definitions, primary keys, relationships, and current data values. It's created through reflection analysis of struct types and their database tags.
Fields:
- Name (string): The database table name, typically derived from the struct name converted to snake_case format. Can be overridden with struct tags.
- Columns ([]Column): Complete list of all table columns derived from struct fields. Each column contains metadata about the corresponding database column including name, type, constraints, and current values.
- Primaries ([]Column): Subset of columns that are designated as primary keys. Used for WHERE clause construction in UPDATE and DELETE operations. Supports both single and composite primary keys.
- Values (map[string]any): Current field values indexed by column name. Contains the actual data values from the struct instance, used for INSERT, UPDATE operations and WHERE clause value binding.
- Relation ([]*Table): Related table structures for handling foreign key relationships. Used for JOIN operations and relational data mapping in complex queries. Currently supports basic relationship mapping.
- HasData (bool): Indicates whether the table contains valid, non-zero data. Used to determine if the struct instance has meaningful values for database operations.
Usage:
// Table is typically created through ModelData function
type User struct {
ID int64 `db:"id,primary"`
Name string `db:"name"`
Email string `db:"email"`
}
user := User{ID: 1, Name: "John", Email: "john@example.com"}
table, err := ModelData(user)
if err != nil {
log.Fatal(err)
}
// Access table metadata
fmt.Println("Table name:", table.Name) // "users"
fmt.Println("Column count:", len(table.Columns)) // 3
fmt.Println("Primary keys:", len(table.Primaries)) // 1
fmt.Println("Has data:", table.HasData) // true
// Access column values
fmt.Println("User ID:", table.Values["id"]) // 1
fmt.Println("User name:", table.Values["name"]) // "John"
Examples of generated table structures:
// Simple struct
type Product struct {
ID uint32 `db:"id,primary"`
Name string `db:"name"`
Price float64 `db:"price"`
}
// Results in table.Name = "products", 3 columns, 1 primary key
// Composite primary key
type OrderItem struct {
OrderID int64 `db:"order_id,primary"`
ProductID int64 `db:"product_id,primary"`
Quantity int `db:"quantity"`
}
// Results in table.Primaries containing 2 columns
// With relationships (basic support)
type Order struct {
ID int64 `db:"id,primary"`
UserID int64 `db:"user_id,ref=users.id"`
Total float64 `db:"total"`
}
// Results in relationship metadata in table.Relation
Note:
- Table names are automatically converted to snake_case from struct names
- Column metadata is extracted from struct field tags
- Primary key detection is based on "primary" tag attribute
- Values map contains current struct field values for database operations
- The structure supports both simple and complex database schemas
- Used internally by all ORM operations for metadata and value extraction
type ValueField ¶
type ValueField qb.ValueField
ValueField represents a column/field in a SQL query as a string value. This is an alias for fluentsql.ValueField to maintain backward compatibility.
Usage:
- Used to reference database columns in SQL queries
- Provides type safety for field references
Methods:
- String(): Converts the ValueField to its string representation.
Example:
qb.ValueField("user_details.user_id")
type WhereAndOr ¶
type WhereAndOr = qb.WhereAndOr
WhereAndOr represents logical operators for combining conditions. This is an alias for fluentsql.WhereAndOr to maintain backward compatibility.