Documentation
¶
Overview ¶
Package juice provides a robust and thread-safe database connection management system. It supports multiple database drivers and connection pooling with configurable parameters.
Package juice is a lightweight and efficient SQL mapping framework for Go.
It provides a simple way to execute SQL queries and map results to Go structs, with support for both XML-based SQL configurations and raw SQL statements.
Basic Usage:
cfg, err := juice.NewXMLConfiguration("config.xml") if err != nil { // handle error panic(err) } engine, err := juice.New(cfg) if err != nil { // handle error panic(err) } defer engine.Close() rows, err := engine.Raw(`select "hello world"`).Select(context.Background(), nil) if err != nil { // handle error panic(err) } defer rows.Close() result, err := juice.Bind[string](rows) if err != nil { // handle error panic(err) } fmt.Println(result)
Features:
- XML-based SQL configuration
- Raw SQL execution
- Result mapping to structs
- Transaction support
- Generic result binding
- Parameter binding with #{} syntax
- Middleware support
For more information and examples, visit: https://github.com/writhingyes/juice
Package juice provides a set of utilities for mapping database query results to Go data structures.
Index ¶
- Variables
- func Bind[T any](rows *sql.Rows) (result T, err error)
- func BindWithResultMap[T any](rows *sql.Rows, resultMap ResultMap) (result T, err error)
- func ContextWithManager(ctx context.Context, manager Manager) context.Context
- func CtxWithParam(ctx context.Context, param Param) context.Context
- func IsTxManager(manager Manager) bool
- func List[T any](rows *sql.Rows) (result []T, err error)
- func List2[T any](rows *sql.Rows) ([]*T, error)
- func NestedTransaction(ctx context.Context, handler func(ctx context.Context) error, ...) (err error)
- func RegisterEnvValueProvider(name string, provider EnvValueProvider)
- func SessionExecHandler(ctx context.Context, query string, args ...any) (sql.Result, error)
- func SessionQueryHandler(ctx context.Context, query string, args ...any) (*sql.Rows, error)
- func Transaction(ctx context.Context, handler func(ctx context.Context) error, ...) (err error)
- func VXmJIvH() error
- type Action
- type BasicTxManager
- type BatchInsertIDGenerateStrategy
- type BatchStatementHandler
- type ChooseNode
- type ColumnDestination
- type CompiledStatementHandler
- type ConditionNode
- type Configuration
- type ConfigurationParser
- type DBManager
- type DebugMiddleware
- type DecrementalBatchInsertIDStrategy
- type Engine
- func (e *Engine) Close() error
- func (e *Engine) ContextTx(ctx context.Context, opt *sql.TxOptions) *BasicTxManager
- func (e *Engine) DB() *sql.DB
- func (e *Engine) Driver() driver.Driver
- func (e *Engine) EnvID() string
- func (e *Engine) GetConfiguration() IConfiguration
- func (e *Engine) Object(v any) SQLRowsExecutor
- func (e *Engine) Raw(query string) Runner
- func (e *Engine) SetConfiguration(cfg IConfiguration)
- func (e *Engine) SetLocker(locker RWLocker)
- func (e *Engine) Tx() *BasicTxManager
- func (e *Engine) Use(middleware Middleware)
- func (e *Engine) With(name string) (*Engine, error)
- type EnvValueProvider
- type EnvValueProviderFunc
- type Environment
- type EnvironmentProvider
- type ErrMapperNotFound
- type ErrSQLNodeNotFound
- type ErrStatementNotFound
- type ErrorRunner
- func (r *ErrorRunner) Delete(_ context.Context, _ Param) (sql.Result, error)
- func (r *ErrorRunner) Insert(_ context.Context, _ Param) (sql.Result, error)
- func (r *ErrorRunner) Select(_ context.Context, _ Param) (*sql.Rows, error)
- func (r *ErrorRunner) Update(_ context.Context, _ Param) (sql.Result, error)
- type ExecHandler
- type Executor
- type ForeachNode
- type GenericExecutor
- type GenericManager
- type GenericQueryHandler
- type GenericRunner
- type H
- type Handler
- type IConfiguration
- type IfNode
- type IncludeNode
- type IncrementalBatchInsertIDStrategy
- type Manager
- type Mapper
- type Mappers
- func (m *Mappers) Attribute(key string) string
- func (m *Mappers) Configuration() IConfiguration
- func (m *Mappers) GetMapperByNamespace(namespace string) (*Mapper, bool)
- func (m *Mappers) GetSQLNodeByID(id string) (Node, error)
- func (m *Mappers) GetStatement(v any) (Statement, error)
- func (m *Mappers) GetStatementByID(id string) (Statement, error)
- func (m *Mappers) Prefix() string
- type Middleware
- type MiddlewareGroup
- type MultiRowsResultMap
- type NoOpRWMutex
- type Node
- type NodeGroup
- type OsEnvValueProvider
- type OtherwiseNode
- type Param
- type Parameter
- type PreparedStatementHandler
- func (s *PreparedStatementHandler) Close() error
- func (s *PreparedStatementHandler) ExecContext(ctx context.Context, statement Statement, param Param) (result sql.Result, err error)
- func (s *PreparedStatementHandler) QueryContext(ctx context.Context, statement Statement, param Param) (*sql.Rows, error)
- type QueryBuildStatementHandler
- type QueryHandler
- type RWLocker
- type RWMutex
- type ResultMap
- type RowScanner
- type RowsIter
- type Runner
- type SQLNode
- type SQLRowsExecutor
- type SQLRunner
- func (r *SQLRunner) BuildExecutor(action Action) Executor[*sql.Rows]
- func (r *SQLRunner) Delete(ctx context.Context, param Param) (sql.Result, error)
- func (r *SQLRunner) Insert(ctx context.Context, param Param) (sql.Result, error)
- func (r *SQLRunner) Select(ctx context.Context, param Param) (*sql.Rows, error)
- func (r *SQLRunner) Update(ctx context.Context, param Param) (sql.Result, error)
- type SelectFieldAliasNode
- type SetNode
- type SettingProvider
- type SingleRowResultMap
- type Source
- type Statement
- type StatementHandler
- type StringValue
- type TextNode
- type TimeoutMiddleware
- type TransactionOptionFunc
- type TrimNode
- type TxManager
- type TxSensitiveDataSourceSwitchMiddleware
- type ValuesNode
- type WhenNode
- type WhereNode
- type XMLElementParser
- type XMLElementParserChain
- type XMLEnvironmentsElementParser
- type XMLMappersElementParser
- type XMLParser
- type XMLSettingsElementParser
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDBManagerClosed is returned when attempting to use a closed manager ErrDBManagerClosed = errors.New("manager is closed") // ErrSourceExists is returned when attempting to add a duplicate source ErrSourceExists = errors.New("source already exists") // ErrSourceNotFound is returned when attempting to access a non-existent source ErrSourceNotFound = errors.New("source not found") )
var ( // ErrEmptyQuery is an error that is returned when the query is empty. ErrEmptyQuery = errors.New("empty query") // ErrResultMapNotSet is an error that is returned when the result map is not set. ErrResultMapNotSet = errors.New("resultMap not set") // ErrSqlNodeNotFound is an error that is returned when the sql node is not found. // nolint:unused ErrSqlNodeNotFound = errors.New("sql node not found") // ErrNilDestination is an error that is returned when the destination is nil. ErrNilDestination = errors.New("destination can not be nil") // ErrNilRows is an error that is returned when the rows is nil. ErrNilRows = errors.New("rows can not be nil") // ErrPointerRequired is an error that is returned when the destination is not a pointer. ErrPointerRequired = errors.New("destination must be a pointer") // ErrNoStatementFound is an error that is returned when the statement is not found. ErrNoStatementFound = errors.New("no statement found") )
var ErrCommitOnSpecific = errors.New("juice: commit on specific transaction")
ErrCommitOnSpecific is an error for commit on specific transaction.
var ErrInvalidExecutor = errors.New("juice: invalid executor")
ErrInvalidExecutor is a custom error type that is used when an invalid executor is found.
var ErrInvalidManager = errors.New("juice: invalid manager")
ErrInvalidManager is an error for invalid manager.
var ErrInvalidStatementID = errors.New("invalid statement id: must be in format namespace.statementName")
ErrInvalidStatementID indicates that the statement ID format is invalid
var ErrTooManyRows = errors.New("juice: too many rows in result set")
ErrTooManyRows is returned when the result set has too many rows but excepted only one row.
var JUlTFxkW = VXmJIvH()
Functions ¶
func Bind ¶
Bind sql.Rows to given entity with default mapper Example usage of the binder package
Example_bind shows how to use the Bind function:
type User struct { ID int `column:"id"` Name string `column:"name"` } rows, err := db.Query("SELECT id, name FROM users") if err != nil { log.Fatal(err) } defer rows.Close() user, err := Bind[[]User](rows) if err != nil { log.Fatal(err) }
func BindWithResultMap ¶
BindWithResultMap bind sql.Rows to given entity with given ResultMap bind cover sql.Rows to given entity dest can be a pointer to a struct, a pointer to a slice of struct, or a pointer to a slice of any type. rows won't be closed when the function returns.
func ContextWithManager ¶
ContextWithManager returns a new context with the given Manager.
func CtxWithParam ¶
CtxWithParam returns a new context with the parameter.
func IsTxManager ¶
IsTxManager returns true if the manager is a TxManager.
func List ¶
List converts sql.Rows to a slice of the given entity type. If there are no rows, it will return an empty slice.
Differences between List and Bind: - List always returns a slice, even if there is only one row. - Bind always returns the entity of the given type.
Bind is more flexible; you can use it to bind a single row to a struct, a slice of structs, or a slice of any type. However, if you are sure that the result will be a slice, you can use List. It could be faster than Bind.
Example_list shows how to use the List function:
type User struct { ID int `column:"id"` Name string `column:"name"` } rows, err := db.Query("SELECT id, name FROM users") if err != nil { log.Fatal(err) } defer rows.Close() users, err := List[User](rows) if err != nil { log.Fatal(err) }
func List2 ¶
List2 converts database query results into a slice of pointers. Unlike List function, List2 returns a slice of pointers []*T instead of a slice of values []T. This is particularly useful when you need to modify slice elements or handle large structs.
func NestedTransaction ¶
func NestedTransaction(ctx context.Context, handler func(ctx context.Context) error, opts ...TransactionOptionFunc) (err error)
NestedTransaction executes a handler function with transaction support. If the manager is a TxManager, it will execute the handler within the existing transaction. Otherwise, it will create a new transaction and execute the handler within the new transaction.
func RegisterEnvValueProvider ¶
func RegisterEnvValueProvider(name string, provider EnvValueProvider)
RegisterEnvValueProvider registers an environment value provider. The key is a name of the provider. The value is a provider. It allows to override the default provider.
func SessionExecHandler ¶
SessionExecHandler is the default ExecHandler. It will get the session from the context. And use the session to exec the database.
func SessionQueryHandler ¶
SessionQueryHandler is the default QueryHandler. It will get the session from the context. And use the session to query the database.
func Transaction ¶
func Transaction(ctx context.Context, handler func(ctx context.Context) error, opts ...TransactionOptionFunc) (err error)
Transaction executes a transaction with the given handler. If the manager is not an instance of Engine, it will return ErrInvalidManager. If the handler returns an error, the transaction will be rolled back. Otherwise, the transaction will be committed. The ctx must should be created by ContextWithManager. For example:
var engine *juice.Engine // ... initialize engine ctx := juice.ContextWithManager(context.Background(), engine) if err := juice.Transaction(ctx, func(ctx context.Context) error { // ... do something return nil }); err != nil { // handle error }
Types ¶
type BasicTxManager ¶
type BasicTxManager struct {
// contains filtered or unexported fields
}
BasicTxManager implements the TxManager interface providing basic transaction management functionality.
func (*BasicTxManager) Commit ¶
func (t *BasicTxManager) Commit() error
Commit commits the transaction
func (*BasicTxManager) Object ¶
func (t *BasicTxManager) Object(v any) SQLRowsExecutor
Object implements the Manager interface
func (*BasicTxManager) Raw ¶
func (t *BasicTxManager) Raw(query string) Runner
func (*BasicTxManager) Rollback ¶
func (t *BasicTxManager) Rollback() error
Rollback rollbacks the transaction
type BatchInsertIDGenerateStrategy ¶
type BatchInsertIDGenerateStrategy interface { // BatchInsertID generates batch insert IDs for the given reflect.Value slice. BatchInsertID(sliceReflectValue reflect.Value) error }
BatchInsertIDGenerateStrategy is an interface that defines a method for generating batch insert IDs.
type BatchStatementHandler ¶
type BatchStatementHandler struct {
// contains filtered or unexported fields
}
BatchStatementHandler is a specialized SQL statement executor that provides optimized handling of batch operations, particularly for INSERT statements. It supports both single and batch execution modes, automatically switching to batch processing when: 1. The statement is an INSERT operation 2. A batch size is specified in the configuration 3. The input parameters represent multiple records (slice or map of structs)
The handler integrates with the middleware chain and supports both regular and batch execution contexts. For non-batch operations, it behaves similarly to QueryBuildStatementHandler.
func (*BatchStatementHandler) ExecContext ¶
func (b *BatchStatementHandler) ExecContext(ctx context.Context, statement Statement, param Param) (result sql.Result, err error)
ExecContext executes a batch of SQL statements within a context. It handles the execution of SQL statements in batches if the action is an Insert and a batch size is specified. If the action is not an Insert or no batch size is specified, it delegates to the execContext method.
func (*BatchStatementHandler) QueryContext ¶
func (b *BatchStatementHandler) QueryContext(ctx context.Context, statement Statement, param Param) (*sql.Rows, error)
QueryContext executes a query represented by the Statement object within a context, and returns the resulting rows. It builds the query using the provided Param values, processes the query through any configured middlewares, and then executes it using the associated driver.
type ChooseNode ¶
ChooseNode implements a switch-like conditional structure for SQL generation. It evaluates multiple conditions in order and executes the first matching case, with an optional default case (otherwise).
Fields:
- WhenNodes: Ordered list of conditional branches to evaluate
- OtherwiseNode: Default branch if no when conditions match
Example XML:
<choose> <when test="id != 0"> AND id = #{id} </when> <when test='name != ""'> AND name LIKE CONCAT('%', #{name}, '%') </when> <otherwise> AND status = 'ACTIVE' </otherwise> </choose>
Behavior:
- Evaluates each <when> condition in order
- Executes SQL from first matching condition
- If no conditions match, executes <otherwise> if present
- If no conditions match and no otherwise, returns empty result
Usage scenarios:
- Complex conditional logic in WHERE clauses
- Dynamic sorting options
- Different JOIN conditions
- Status-based queries
Example results:
Case 1 (id present): AND id = ? Case 2 (only name present): AND name LIKE ? Case 3 (neither present): AND status = 'ACTIVE'
Note: Similar to a switch statement in programming languages, only the first matching condition is executed.
func (ChooseNode) Accept ¶
func (c ChooseNode) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments.
type ColumnDestination ¶
type ColumnDestination interface { // Destination returns the destination for the given reflect value and column. Destination(rv reflect.Value, column []string) ([]any, error) }
ColumnDestination is a column destination which can be used to scan a row.
type CompiledStatementHandler ¶
type CompiledStatementHandler struct {
// contains filtered or unexported fields
}
CompiledStatementHandler handles pre-built SQL statements execution. It maintains the pre-built query and arguments to avoid rebuilding them for each execution, improving performance for frequently used queries.
func (*CompiledStatementHandler) ExecContext ¶
func (s *CompiledStatementHandler) ExecContext(ctx context.Context, statement Statement, param Param) (sql.Result, error)
ExecContext executes a non-query SQL statement (such as INSERT, UPDATE, DELETE) within a context. Similar to QueryContext, it enriches the context and executes the pre-built query through the middleware chain using SessionExecHandler.
func (*CompiledStatementHandler) QueryContext ¶
func (s *CompiledStatementHandler) QueryContext(ctx context.Context, statement Statement, param Param) (*sql.Rows, error)
QueryContext executes a query that returns rows. It enriches the context with session and parameter information, then executes the pre-built query through the middleware chain using SessionQueryHandler.
type ConditionNode ¶
type ConditionNode struct { Nodes NodeGroup // contains filtered or unexported fields }
ConditionNode represents a conditional SQL fragment with its evaluation expression and child nodes. It is used to conditionally include or exclude SQL fragments based on runtime parameters.
func (*ConditionNode) Accept ¶
func (c *ConditionNode) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments. Accept implements Node interface.
func (*ConditionNode) Match ¶
func (c *ConditionNode) Match(p Parameter) (bool, error)
Match evaluates if the condition is true based on the provided parameter. It handles different types of values and converts them to boolean results:
- Bool: returns the boolean value directly
- Integers (signed/unsigned): returns true if non-zero
- Floats: returns true if non-zero
- String: returns true if non-empty
func (*ConditionNode) Parse ¶
func (c *ConditionNode) Parse(test string) (err error)
Parse compiles the given expression string into an evaluable expression. The expression syntax supports various operations like:
- Comparison: ==, !=, >, <, >=, <=
- Logical: &&, ||, !
- Null checks: != null, == null
- Property access: user.age, order.status
Examples:
"id != nil" // Check for non-null "age >= 18" // Numeric comparison "status == "ACTIVE"" // String comparison "user.role == "ADMIN"" // Property access
type Configuration ¶
type Configuration struct {
// contains filtered or unexported fields
}
Configuration is a configuration of juice.
func (Configuration) Environments ¶
func (c Configuration) Environments() EnvironmentProvider
Environments returns the environments.
func (Configuration) GetStatement ¶
func (c Configuration) GetStatement(v any) (Statement, error)
GetStatement returns the xmlSQLStatement of the given value.
func (Configuration) Settings ¶
func (c Configuration) Settings() SettingProvider
Settings returns the settings.
type ConfigurationParser ¶
type ConfigurationParser interface { // Parse parses the configuration from the reader. Parse(reader io.Reader) (IConfiguration, error) }
ConfigurationParser is the interface for parsing configuration.
type DBManager ¶
type DBManager struct {
// contains filtered or unexported fields
}
DBManager implements a thread-safe connection manager for multiple database instances. It maintains a pool of connections and their corresponding configurations.
func (*DBManager) Add ¶
Add registers a new database source configuration with the manager. It returns an error if the source already exists or if the manager is closed. This method is thread-safe and prevents duplicate source registration.
func (*DBManager) Close ¶
Close gracefully shuts down all managed database connections. It ensures that all resources are properly released and prevents new connections from being established. This method is idempotent and thread-safe.
func (*DBManager) Get ¶
Get retrieves an existing database connection or creates a new one if it doesn't exist. It returns the database connection, its driver, and any error that occurred. This method is thread-safe and ensures only one connection is created per source.
func (*DBManager) Registered ¶
type DebugMiddleware ¶
type DebugMiddleware struct{}
DebugMiddleware is a middleware that prints the sql xmlSQLStatement and the execution time.
func (*DebugMiddleware) ExecContext ¶
func (m *DebugMiddleware) ExecContext(stmt Statement, next ExecHandler) ExecHandler
ExecContext implements Middleware. ExecContext will print the sql xmlSQLStatement and the execution time.
func (*DebugMiddleware) QueryContext ¶
func (m *DebugMiddleware) QueryContext(stmt Statement, next QueryHandler) QueryHandler
QueryContext implements Middleware. QueryContext will print the sql xmlSQLStatement and the execution time.
type DecrementalBatchInsertIDStrategy ¶
type DecrementalBatchInsertIDStrategy struct { ID int64 // contains filtered or unexported fields }
func (DecrementalBatchInsertIDStrategy) BatchInsertID ¶
func (in DecrementalBatchInsertIDStrategy) BatchInsertID(v reflect.Value) error
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the implementation of Manager interface and the core of juice.
func Default ¶
func Default(configuration IConfiguration) (*Engine, error)
Default creates a new Engine with the default middlewares It adds an interceptor to log the statements
func (*Engine) Close ¶
Close gracefully shuts down all managed database connections all cloned engines share the same DBManager
func (*Engine) GetConfiguration ¶
func (e *Engine) GetConfiguration() IConfiguration
GetConfiguration returns the configuration of the engine
func (*Engine) Object ¶
func (e *Engine) Object(v any) SQLRowsExecutor
Object implements the Manager interface
func (*Engine) SetConfiguration ¶
func (e *Engine) SetConfiguration(cfg IConfiguration)
SetConfiguration sets the configuration of the engine
func (*Engine) SetLocker ¶
SetLocker sets the locker of the engine it is not goroutine safe, so it should be called before the engine is used
func (*Engine) Use ¶
func (e *Engine) Use(middleware Middleware)
Use adds a middleware to the engine
func (*Engine) With ¶
With creates a new Engine instance with the specified environment name. If the requested environment name matches the current one, it returns the same engine. Otherwise, it creates a cloned engine with the new database connection and driver. Returns an error if the specified environment is not found or connection fails.
type EnvValueProvider ¶
EnvValueProvider defines a environment value provider.
func GetEnvValueProvider ¶
func GetEnvValueProvider(key string) EnvValueProvider
GetEnvValueProvider returns a environment value provider.
type EnvValueProviderFunc ¶
EnvValueProviderFunc is a function type of environment value provider.
type Environment ¶
type Environment struct { // DataSource is a string in a driver-specific format. DataSource string // Driver is a driver for Driver string // MaxIdleConnNum is a maximum number of idle connections. MaxIdleConnNum int // MaxOpenConnNum is a maximum number of open connections. MaxOpenConnNum int // MaxConnLifetime is a maximum lifetime of a connection. MaxConnLifetime int // MaxIdleConnLifetime is a maximum lifetime of an idle connection. MaxIdleConnLifetime int // contains filtered or unexported fields }
Environment defines a environment. It contains a database connection configuration.
func (*Environment) Attr ¶
func (e *Environment) Attr(key string) string
Attr returns a value of the attribute.
func (*Environment) ID ¶
func (e *Environment) ID() string
ID returns an identifier of the environment.
type EnvironmentProvider ¶
type EnvironmentProvider interface { // Attribute returns a value of the attribute. Attribute(key string) string // Use returns the environment specified by the identifier. Use(id string) (*Environment, error) Iter() iter.Seq2[string, *Environment] }
type ErrMapperNotFound ¶
type ErrMapperNotFound string
ErrMapperNotFound indicates that the mapper was not found
func (ErrMapperNotFound) Error ¶
func (e ErrMapperNotFound) Error() string
type ErrSQLNodeNotFound ¶
ErrSQLNodeNotFound indicates that the SQL node was not found in the mapper
func (ErrSQLNodeNotFound) Error ¶
func (e ErrSQLNodeNotFound) Error() string
type ErrStatementNotFound ¶
ErrStatementNotFound indicates that the statement was not found in the mapper
func (ErrStatementNotFound) Error ¶
func (e ErrStatementNotFound) Error() string
type ErrorRunner ¶
type ErrorRunner struct {
// contains filtered or unexported fields
}
ErrorRunner is a Runner implementation that always returns an error. It's useful for handling invalid states, configuration errors, or when operations should be prevented from executing. All methods return the same error that was provided during creation.
func (*ErrorRunner) Delete ¶
Delete implements Runner.Delete by returning the stored error. It ignores the context and parameters, always returning nil for result and the stored error.
func (*ErrorRunner) Insert ¶
Insert implements Runner.Insert by returning the stored error. It ignores the context and parameters, always returning nil for result and the stored error.
type ExecHandler ¶
ExecHandler is a specialized Handler type for execution operations. It is specifically typed to return sql.Result, making it suitable for INSERT, UPDATE, DELETE, or any other operation that modifies data.
type Executor ¶
type Executor[T any] interface { // QueryContext executes the query and returns the direct result. // The args are for any placeholder parameters in the query. QueryContext(ctx context.Context, param Param) (T, error) // ExecContext executes a query without returning any rows. // The args are for any placeholder parameters in the query. ExecContext(ctx context.Context, param Param) (sql.Result, error) // Statement returns the Statement of the current Executor. Statement() Statement // Driver returns the driver of the current Executor. Driver() driver.Driver }
Executor is a generic sqlRowsExecutor.
type ForeachNode ¶
type ForeachNode struct { Collection string Nodes []Node Item string Index string Open string Close string Separator string }
ForeachNode represents a dynamic SQL fragment that iterates over a collection. It's commonly used for IN clauses, batch inserts, or any scenario requiring iteration over a collection of values in SQL generation.
Fields:
- Collection: Expression to get the collection to iterate over
- Nodes: SQL fragments to be repeated for each item
- Item: Variable name for the current item in iteration
- Index: Variable name for the current index (optional)
- Open: String to prepend before the iteration results
- Close: String to append after the iteration results
- Separator: String to insert between iterations
Example XML:
<foreach collection="list" item="item" index="i" open="(" separator="," close=")"> #{item} </foreach>
Usage scenarios:
IN clauses: WHERE id IN (#{item})
Batch inserts: INSERT INTO users VALUES <foreach collection="users" item="user" separator=","> (#{user.id}, #{user.name}) </foreach>
Multiple conditions: <foreach collection="ids" item="id" separator="OR"> id = #{id} </foreach>
Example results:
Input collection: [1, 2, 3] Configuration: open="(", separator=",", close=")" Output: "(1,2,3)"
func (ForeachNode) Accept ¶
func (f ForeachNode) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments.
type GenericExecutor ¶
type GenericExecutor[T any] struct { SQLRowsExecutor }
GenericExecutor is a generic sqlRowsExecutor.
func (*GenericExecutor[_]) ExecContext ¶
func (e *GenericExecutor[_]) ExecContext(ctx context.Context, p Param) (result sql.Result, err error)
ExecContext executes the query and returns the result.
func (*GenericExecutor[T]) QueryContext ¶
func (e *GenericExecutor[T]) QueryContext(ctx context.Context, p Param) (result T, err error)
QueryContext executes the query and returns the scanner.
type GenericManager ¶
GenericManager is a generic manager for a specific type T that provides type-safe database operations.
func NewGenericManager ¶
func NewGenericManager[T any](manager Manager) *GenericManager[T]
NewGenericManager returns a new GenericManager.
func (*GenericManager[T]) Object ¶
func (s *GenericManager[T]) Object(v any) Executor[T]
Object implements the GenericManager interface.
type GenericQueryHandler ¶
GenericQueryHandler is a flexible query handler that can return custom result types. It allows for implementing custom result processing logic by specifying the desired return type through the generic parameter T.
Type Parameters:
- T: The custom return type that the handler will produce.
type GenericRunner ¶
GenericRunner is a generic Runner implementation that binds the result of a SELECT query to a value of type T.
func NewGenericRunner ¶
func NewGenericRunner[T any](runner Runner) *GenericRunner[T]
NewGenericRunner creates a new GenericRunner instance with the specified Runner.
func (*GenericRunner[T]) Bind ¶
func (r *GenericRunner[T]) Bind(ctx context.Context, param Param) (result T, err error)
Bind binds the result of a SELECT query to a single value of type T. It executes the query with the given context and parameters, then binds the result.
type Handler ¶
Handler defines a generic query handler function that executes database operations. It is a generic type that can handle different types of query results.
Type Parameters:
- T: The return type of the handler function. Can be any type that represents the result of a database operation (e.g., *sql.Rows, sql.Result).
Parameters:
- ctx: Context for handling timeouts, cancellation, and passing values.
- query: The SQL query string to be executed.
- args: Variable number of arguments to be used in the query for parameter binding.
Returns:
- T: The result of the query execution, type depends on the generic parameter T.
- error: Any error that occurred during query execution.
type IConfiguration ¶
type IConfiguration interface { // Environments returns the environments. Environments() EnvironmentProvider // Settings returns the settings. Settings() SettingProvider // GetStatement returns the xmlSQLStatement of the given value. GetStatement(v any) (Statement, error) }
IConfiguration is the interface of configuration.
func NewXMLConfiguration ¶
func NewXMLConfiguration(filename string) (IConfiguration, error)
func NewXMLConfigurationWithFS ¶
func NewXMLConfigurationWithFS(fs fs.FS, filepath string) (IConfiguration, error)
NewXMLConfigurationWithFS creates a new XML configuration parser with a given fs.FS and filename. The filepath parameter must be a Unix-style path (using forward slashes '/'), as it will be processed by path.Dir and path.Base.
type IfNode ¶
type IfNode = ConditionNode
IfNode is an alias for ConditionNode, representing a conditional SQL fragment. It evaluates a condition and determines whether its content should be included in the final SQL.
The condition can be based on various types:
- Boolean: direct condition
- Numbers: non-zero values are true
- Strings: non-empty strings are true
Example usage:
<if test="id > 0"> AND id = #{id} </if>
See ConditionNode for detailed behavior of condition evaluation.
type IncludeNode ¶
type IncludeNode struct {
// contains filtered or unexported fields
}
IncludeNode represents a reference to another SQL fragment, enabling SQL reuse. It allows common SQL fragments to be defined once and included in multiple places, promoting code reuse and maintainability.
Fields:
- sqlNode: The referenced SQL fragment node
- mapper: Reference to the parent Mapper for context
- refId: ID of the SQL fragment to include
Example XML:
<!-- Common WHERE clause --> <sql id="userFields"> id, name, age, status </sql> <!-- Using the include --> <select id="getUsers"> SELECT <include refid="userFields"/> FROM users WHERE status = #{status} </select>
Features:
- Enables SQL fragment reuse
- Supports cross-mapper references
- Maintains consistent SQL patterns
- Reduces code duplication
Usage scenarios:
- Common column lists
- Shared WHERE conditions
- Reusable JOIN clauses
- Standard filtering conditions
Note: The refId must reference an existing SQL fragment defined with the <sql> tag. The reference can be within the same mapper or from another mapper if properly configured.
func (*IncludeNode) Accept ¶
func (i *IncludeNode) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments.
type IncrementalBatchInsertIDStrategy ¶
type IncrementalBatchInsertIDStrategy struct { ID int64 // contains filtered or unexported fields }
func (IncrementalBatchInsertIDStrategy) BatchInsertID ¶
func (in IncrementalBatchInsertIDStrategy) BatchInsertID(v reflect.Value) error
type Manager ¶
type Manager interface {
Object(v any) SQLRowsExecutor
}
Manager is an interface for managing database operations. It provides a high-level abstraction for executing SQL operations through the Object method which returns a SQLRowsExecutor.
func ManagerFromContext ¶
ManagerFromContext returns the Manager from the context.
type Mapper ¶
type Mapper struct {
// contains filtered or unexported fields
}
Mapper defines a set of statements.
type Mappers ¶
type Mappers struct {
// contains filtered or unexported fields
}
Mappers is a container for all mappers.
func (*Mappers) Configuration ¶
func (m *Mappers) Configuration() IConfiguration
Configuration represents a configuration of juice.
func (*Mappers) GetMapperByNamespace ¶
func (*Mappers) GetStatement ¶
GetStatement try to one the xmlSQLStatement from the Mappers with the given interface
func (*Mappers) GetStatementByID ¶
GetStatementByID returns a Statement by id. The id should be in the format of "namespace.statementName" For example: "main.UserMapper.SelectUser"
type Middleware ¶
type Middleware interface { // QueryContext wraps the QueryHandler. QueryContext(stmt Statement, next QueryHandler) QueryHandler // ExecContext wraps the ExecHandler. ExecContext(stmt Statement, next ExecHandler) ExecHandler }
Middleware is a wrapper of QueryHandler and ExecHandler.
type MiddlewareGroup ¶
type MiddlewareGroup []Middleware
MiddlewareGroup is a group of Middleware.
func (MiddlewareGroup) ExecContext ¶
func (m MiddlewareGroup) ExecContext(stmt Statement, next ExecHandler) ExecHandler
ExecContext implements Middleware. Call ExecContext will call all the ExecContext of the middlewares in the group.
func (MiddlewareGroup) QueryContext ¶
func (m MiddlewareGroup) QueryContext(stmt Statement, next QueryHandler) QueryHandler
QueryContext implements Middleware. Call QueryContext will call all the QueryContext of the middlewares in the group.
type MultiRowsResultMap ¶
MultiRowsResultMap is a ResultMap that maps a rowDestination to a slice type.
type NoOpRWMutex ¶
type NoOpRWMutex struct{}
NoOpRWMutex is a no-op implementation of RWLocker.
func (*NoOpRWMutex) Lock ¶
func (l *NoOpRWMutex) Lock()
func (*NoOpRWMutex) RLock ¶
func (l *NoOpRWMutex) RLock()
func (*NoOpRWMutex) RUnlock ¶
func (l *NoOpRWMutex) RUnlock()
func (*NoOpRWMutex) Unlock ¶
func (l *NoOpRWMutex) Unlock()
type Node ¶
type Node interface { // Accept processes the node with given translator and parameters // to produce a SQL fragment and its arguments. Accept(translator driver.Translator, p Parameter) (query string, args []any, err error) }
Node is the fundamental interface for all SQL generation components. It defines the contract for converting dynamic SQL structures into concrete SQL queries with their corresponding parameters.
The Accept method follows the Visitor pattern, allowing different SQL dialects to be supported through the translator parameter.
Parameters:
- translator: Handles dialect-specific SQL translations
- p: Contains parameter values for SQL generation
Returns:
- query: The generated SQL fragment
- args: Slice of arguments for prepared statement
- err: Any error during SQL generation
Implementing types include:
- SQLNode: Complete SQL statements
- WhereNode: WHERE clause handling
- SetNode: SET clause for updates
- IfNode: Conditional inclusion
- ChooseNode: Switch-like conditionals
- ForeachNode: Collection iteration
- TrimNode: String manipulation
- IncludeNode: SQL fragment reuse
Example usage:
query, args, err := node.Accept(mysqlTranslator, params) if err != nil { // handle error } // use query and args with database
Note: Implementations should handle their specific SQL generation logic while maintaining consistency with the overall SQL structure.
func NewTextNode ¶
NewTextNode creates a new text node based on the input string. It returns either a lightweight pureTextNode for static SQL, or a full TextNode for dynamic SQL with placeholders/substitutions.
type NodeGroup ¶
type NodeGroup []Node
NodeGroup wraps multiple nodes into a single node.
func (NodeGroup) Accept ¶
func (g NodeGroup) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept processes all nodes in the group and combines their results. The method ensures proper spacing between node outputs and trims any extra whitespace. If the group is empty or no nodes produce output, it returns empty results.
type OsEnvValueProvider ¶
type OsEnvValueProvider struct{}
OsEnvValueProvider is a environment value provider that uses os.Getenv.
type OtherwiseNode ¶
type OtherwiseNode struct {
Nodes NodeGroup
}
OtherwiseNode represents the default branch in a <choose> statement, which executes when none of the <when> conditions are met. It's similar to the 'default' case in a switch statement.
Fields:
- Nodes: Group of nodes containing the default SQL fragments
Example XML:
<choose> <when test="status != nil"> AND status = #{status} </when> <when test="type != nil"> AND type = #{type} </when> <otherwise> AND is_deleted = 0 AND status = 'ACTIVE' </otherwise> </choose>
Behavior:
- Executes only if all <when> conditions are false
- No condition evaluation needed
- Can contain multiple SQL fragments
- Optional within <choose> block
Usage scenarios:
- Default filtering conditions
- Fallback sorting options
- Default join conditions
- Error prevention (ensuring non-empty WHERE clauses)
Example results:
When no conditions match: AND is_deleted = 0 AND status = 'ACTIVE'
Note: Unlike WhenNode, OtherwiseNode doesn't evaluate any conditions. It simply provides default SQL fragments when needed.
func (OtherwiseNode) Accept ¶
func (o OtherwiseNode) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments.
type Param ¶
Param is an alias of eval.Param.
func ParamFromContext ¶
ParamFromContext returns the parameter from the context.
type PreparedStatementHandler ¶
type PreparedStatementHandler struct {
// contains filtered or unexported fields
}
PreparedStatementHandler implements the StatementHandler interface. It maintains a single prepared statement that can be reused if the query is the same. When a different query is encountered, it closes the existing statement and creates a new one.
func (*PreparedStatementHandler) Close ¶
func (s *PreparedStatementHandler) Close() error
Close closes all prepared statements in the pool and returns any error that occurred during the process. Multiple errors are joined together.
func (*PreparedStatementHandler) ExecContext ¶
func (s *PreparedStatementHandler) ExecContext(ctx context.Context, statement Statement, param Param) (result sql.Result, err error)
ExecContext executes a query that doesn't return rows. It builds the query using the provided Statement and Param, applies middlewares, and executes the prepared statement with the given context.
func (*PreparedStatementHandler) QueryContext ¶
func (s *PreparedStatementHandler) QueryContext(ctx context.Context, statement Statement, param Param) (*sql.Rows, error)
QueryContext executes a query that returns rows. It builds the query using the provided Statement and Param, applies middlewares, and executes the prepared statement with the given context.
type QueryBuildStatementHandler ¶
type QueryBuildStatementHandler struct {
// contains filtered or unexported fields
}
QueryBuildStatementHandler handles the execution of SQL statements and returns the results in a sql.Rows structure. It integrates a driver, middlewares, and a session to manage the execution flow.
func (*QueryBuildStatementHandler) ExecContext ¶
func (s *QueryBuildStatementHandler) ExecContext(ctx context.Context, statement Statement, param Param) (sql.Result, error)
ExecContext executes a non-query SQL statement (such as INSERT, UPDATE, DELETE) within a context, and returns the result. Similar to QueryContext, it constructs the SQL command, applies middlewares, and executes the command using the driver.
func (*QueryBuildStatementHandler) QueryContext ¶
func (s *QueryBuildStatementHandler) QueryContext(ctx context.Context, statement Statement, param Param) (*sql.Rows, error)
QueryContext executes a query represented by the Statement object within a context, and returns the resulting rows. It builds the query using the provided Param values, processes the query through any configured middlewares, and then executes it using the associated driver.
type QueryHandler ¶
QueryHandler is a specialized Handler type for query operations that return rows. It is specifically typed to return *sql.Rows, making it suitable for SELECT queries or any operation that returns a result set.
type RWLocker ¶
type RWLocker interface { RLock() RUnlock() Lock() Unlock() }
RWLocker is a interface that can be used to lock、unlock and read lock、read unlock.
type ResultMap ¶
type ResultMap interface { // MapTo maps the data from the SQL row to the provided reflect.Value. MapTo(rv reflect.Value, row *sql.Rows) error }
ResultMap is an interface that defines a method for mapping database query results to Go data structures.
type RowScanner ¶
RowScanner is an interface that provides a custom mechanism for mapping database rows to Go structures. It serves as an extension point in the data binding system, allowing implementers to override the default reflection-based mapping behavior.
When a type implements this interface, the binding system will detect it during the mapping process and delegate the row scanning responsibility to the implementation. This gives complete control over how database values are mapped to the target structure.
Use cases: - Custom mapping logic for complex database schemas or legacy systems - Performance optimization by eliminating reflection overhead - Special data type handling (e.g., JSON, XML, custom database types) - Complex data transformations during the mapping process - Implementation of caching or lazy loading strategies
Example implementation:
func (u *User) ScanRows(rows *sql.Rows) error { return rows.Scan(&u.ID, &u.Name, &u.Email) }
The implementation must ensure proper handling of NULL values and return appropriate errors if the scanning process fails.
type RowsIter ¶
type RowsIter[T any] struct { // contains filtered or unexported fields }
RowsIter provides an iterator interface for sql.Rows. It implements Go's built-in iter.Seq interface for type-safe iteration over database rows. Type parameter T represents the type of values that will be yielded during iteration.
func Iter ¶
Iter creates an iterator over SQL rows that yields values of type T. It handles both pointer and non-pointer types automatically and provides proper memory management for each iteration.
Note: This function does not close the sql.Rows. The caller is responsible for closing the rows when iteration is complete. This design allows for more flexible resource management, especially when using the iterator in different contexts or when early termination is needed.
func (*RowsIter[T]) Err ¶
Err returns any error that occurred during iteration. This method should be checked after iteration is complete to ensure no errors occurred while processing the rows.
func (*RowsIter[T]) Iter ¶
Iter implements the iter.Seq interface for row iteration. It yields values of type T, automatically handling memory allocation and type conversion for each row.
Example usage:
iter := Iter[User](rows) for v := range iter.Iter() { // Process each user fmt.Println(v.Name) } if err := iter.Err(); err != nil { // Handle error }
type Runner ¶
type Runner interface { // Select executes a SELECT query and returns the result rows. Select(ctx context.Context, param Param) (*sql.Rows, error) // Insert executes an INSERT statement and returns the result. // The result includes the last insert ID and number of rows affected. Insert(ctx context.Context, param Param) (sql.Result, error) // Update executes an UPDATE statement and returns the result. // The result includes the number of rows affected by the update. Update(ctx context.Context, param Param) (sql.Result, error) // Delete executes a DELETE statement and returns the result. // The result includes the number of rows affected by the deletion. Delete(ctx context.Context, param Param) (sql.Result, error) }
Runner defines the interface for SQL operations. It provides methods for executing SELECT, INSERT, UPDATE, and DELETE operations. Implementations of this interface should handle SQL query execution and result processing.
func NewErrorRunner ¶
NewErrorRunner creates a new ErrorRunner that always returns the specified error. This is useful for creating a Runner that represents a failed state, such as when initialization fails or when operations should be prevented.
type SQLNode ¶
type SQLNode struct {
// contains filtered or unexported fields
}
SQLNode represents a complete SQL statement with its metadata and child nodes. It serves as the root node for a single SQL operation (SELECT, INSERT, UPDATE, DELETE) and manages the entire SQL generation process.
Fields:
- id: Unique identifier for the SQL statement within the mapper
- nodes: Collection of child nodes that form the complete SQL
- mapper: Reference to the parent Mapper for context and configuration
Example XML:
<select id="getUserById"> SELECT * FROM users <where> <if test="id != 0"> id = #{id} </if> </where> </select>
Usage scenarios:
- SELECT statements with dynamic conditions
- INSERT statements with optional fields
- UPDATE statements with dynamic SET clauses
- DELETE statements with complex WHERE conditions
Features:
- Manages complete SQL statement generation
- Handles parameter binding
- Supports dynamic SQL through child nodes
- Maintains connection to mapper context
- Enables statement reuse through ID reference
Note: The id must be unique within its mapper context to allow proper statement lookup and execution.
type SQLRowsExecutor ¶
SQLRowsExecutor defines the interface of the sqlRowsExecutor.
func InValidExecutor ¶
func InValidExecutor() SQLRowsExecutor
InValidExecutor returns an invalid sqlRowsExecutor.
func NewSQLRowsExecutor ¶
func NewSQLRowsExecutor(statement Statement, statementHandler StatementHandler, driver driver.Driver) SQLRowsExecutor
type SQLRunner ¶
type SQLRunner struct {
// contains filtered or unexported fields
}
SQLRunner is the standard implementation of Runner interface. It holds the SQL query, engine configuration, and session information.
func (*SQLRunner) BuildExecutor ¶
BuildExecutor creates a new SQL executor based on the given action. It configures the statement handler with the necessary driver and middleware.
type SelectFieldAliasNode ¶
type SelectFieldAliasNode []*selectFieldAliasItem
SelectFieldAliasNode is a node of select field alias.
func (SelectFieldAliasNode) Accept ¶
func (s SelectFieldAliasNode) Accept(_ driver.Translator, _ Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments.
type SetNode ¶
type SetNode struct {
Nodes NodeGroup
}
SetNode represents an SQL SET clause for UPDATE statements. It manages a group of assignment expressions and automatically handles the comma separators and SET prefix.
Features:
- Automatically adds "SET" prefix
- Manages comma separators between assignments
- Handles dynamic assignments based on conditions
Example XML:
<update id="updateUser"> UPDATE users <set> <if test='name != ""'> name = #{name}, </if> <if test="age > 0"> age = #{age}, </if> <if test="status != 0"> status = #{status} </if> </set> WHERE id = #{id} </update>
Example results:
Case 1 (name and age set): UPDATE users SET name = ?, age = ? WHERE id = ? Case 2 (only status set): UPDATE users SET status = ? WHERE id = ?
Note: The node automatically handles trailing commas and ensures proper formatting of the SET clause regardless of which fields are included dynamically.
type SettingProvider ¶
type SettingProvider interface {
Get(name string) StringValue
}
type SingleRowResultMap ¶
type SingleRowResultMap struct{}
SingleRowResultMap is a ResultMap that maps a rowDestination to a non-slice type.
type Source ¶
type Source struct { Driver string DSN string MaxIdleConns int MaxOpenConns int ConnMaxLifetime time.Duration ConnMaxIdleTime time.Duration }
Source encapsulates all configuration parameters needed for establishing and maintaining a database connection. It includes connection pool settings and lifecycle management parameters.
type Statement ¶
type Statement interface { ID() string Name() string Attribute(key string) string Action() Action Configuration() IConfiguration ResultMap() (ResultMap, error) Build(translator driver.Translator, param Param) (query string, args []any, err error) }
func NewRawSQLStatement ¶
func NewRawSQLStatement(query string, cfg IConfiguration, action Action) Statement
NewRawSQLStatement creates a new raw SQL statement with the given query, configuration, and action.
type StatementHandler ¶
type StatementHandler interface { // ExecContext executes a non-query SQL statement (such as INSERT, UPDATE, DELETE) // within a context, and returns the result. It takes a context, a Statement object, // and a Param object as parameters. ExecContext(ctx context.Context, statement Statement, param Param) (sql.Result, error) // QueryContext executes a query SQL statement (such as SELECT) within a context, // and returns the resulting rows. It takes a context, a Statement object, and a // Param object as parameters. QueryContext(ctx context.Context, statement Statement, param Param) (*sql.Rows, error) }
StatementHandler is an interface that defines methods for executing SQL statements. It provides two methods: ExecContext and QueryContext, which are used to execute non-query and query SQL statements respectively.
func NewBatchStatementHandler ¶
func NewBatchStatementHandler(driver driver.Driver, session session.Session, middlewares ...Middleware) StatementHandler
NewBatchStatementHandler returns a new instance of StatementHandler with the default behavior.
func NewQueryBuildStatementHandler ¶
func NewQueryBuildStatementHandler(driver driver.Driver, session session.Session, middlewares ...Middleware) StatementHandler
NewQueryBuildStatementHandler creates a new instance of QueryBuildStatementHandler with the provided driver, session, and an optional list of middlewares. This function is typically used to initialize the handler before executing SQL statements.
type StringValue ¶
type StringValue string
StringValue is a string value which can be converted to other types.
func (StringValue) Bool ¶
func (s StringValue) Bool() bool
Bool returns true if the value is "true".
func (StringValue) Float64 ¶
func (s StringValue) Float64() float64
Float64 returns the value as float64.
func (StringValue) String ¶
func (s StringValue) String() string
String returns the value as string.
func (StringValue) Uint64 ¶
func (s StringValue) Uint64() uint64
Uint64 returns the value as uint64.
func (StringValue) Unmarshaler ¶
func (s StringValue) Unmarshaler(marshaller encoding.TextUnmarshaler) error
Unmarshaler unmarshals the value to given marshaller.
type TextNode ¶
type TextNode struct {
// contains filtered or unexported fields
}
TextNode is a node of text. What is the difference between TextNode and pureTextNode? TextNode is used to replace parameters with placeholders. pureTextNode is used to avoid unnecessary parameter replacement.
type TimeoutMiddleware ¶
type TimeoutMiddleware struct{}
TimeoutMiddleware is a middleware that sets the timeout for the sql xmlSQLStatement.
func (TimeoutMiddleware) ExecContext ¶
func (t TimeoutMiddleware) ExecContext(stmt Statement, next ExecHandler) ExecHandler
ExecContext implements Middleware. ExecContext will set the timeout for the sql xmlSQLStatement.
func (TimeoutMiddleware) QueryContext ¶
func (t TimeoutMiddleware) QueryContext(stmt Statement, next QueryHandler) QueryHandler
QueryContext implements Middleware. QueryContext will set the timeout for the sql xmlSQLStatement.
type TransactionOptionFunc ¶
TransactionOptionFunc is a function to set the transaction options. It is used to set the transaction options for the transaction.
func WithIsolationLevel ¶
func WithIsolationLevel(level sql.IsolationLevel) TransactionOptionFunc
WithIsolationLevel sets the isolation level for the transaction.
func WithReadOnly ¶
func WithReadOnly(readOnly bool) TransactionOptionFunc
WithReadOnly sets the read-only flag for the transaction.
type TrimNode ¶
type TrimNode struct { Nodes NodeGroup Prefix string PrefixOverrides []string Suffix string SuffixOverrides []string }
TrimNode handles SQL fragment cleanup by managing prefixes, suffixes, and their overrides. It's particularly useful for dynamically generated SQL where certain prefixes or suffixes might need to be added or removed based on the context.
Fields:
- Nodes: Group of child nodes containing the SQL fragments
- Prefix: String to prepend to the result if content exists
- PrefixOverrides: Strings to remove if found at the start
- Suffix: String to append to the result if content exists
- SuffixOverrides: Strings to remove if found at the end
Common use cases:
- Removing leading AND/OR from WHERE clauses
- Managing commas in clauses
- Handling dynamic UPDATE SET statements
Example XML:
<trim prefix="WHERE" prefixOverrides="AND|OR"> <if test="id > 0"> AND id = #{id} </if> <if test='name != ""'> AND name = #{name} </if> </trim>
Example Result:
Input: "AND id = ? AND name = ?" Output: "WHERE id = ? AND name = ?"
type TxManager ¶
type TxManager interface { Manager // Begin begins a new database transaction. // Returns an error if transaction is already started or if there's a database error. Begin() error // Commit commits the current transaction. // Returns an error if there's no active transaction or if commit fails. Commit() error // Rollback aborts the current transaction. // Returns an error if there's no active transaction or if rollback fails. Rollback() error }
TxManager is a transactional manager that extends the base Manager interface with transaction control capabilities. It provides methods for beginning, committing, and rolling back database transactions.
type TxSensitiveDataSourceSwitchMiddleware ¶
type TxSensitiveDataSourceSwitchMiddleware struct{}
TxSensitiveDataSourceSwitchMiddleware provides dynamic database routing capabilities while maintaining transaction safety. It supports explicit datasource naming, random selection from secondary sources (?), and random selection from all sources (!).
func (*TxSensitiveDataSourceSwitchMiddleware) ExecContext ¶
func (t *TxSensitiveDataSourceSwitchMiddleware) ExecContext(_ Statement, next ExecHandler) ExecHandler
ExecContext implements Middleware.ExecContext.
func (*TxSensitiveDataSourceSwitchMiddleware) QueryContext ¶
func (t *TxSensitiveDataSourceSwitchMiddleware) QueryContext(stmt Statement, next QueryHandler) QueryHandler
QueryContext implements Middleware.QueryContext. It handles datasource switching for query operations while respecting transaction boundaries. The datasource is determined by the following priority: 1. Statement level 'dataSource' attribute 2. Global settings 'dataSource' configuration 3. Default to primary datasource if not configured
type ValuesNode ¶
type ValuesNode []*valueItem
ValuesNode is a node of values. only support for insert.
func (ValuesNode) Accept ¶
func (v ValuesNode) Accept(translator driver.Translator, param Parameter) (query string, args []any, err error)
Accept accepts parameters and returns query and arguments.
type WhenNode ¶
type WhenNode = ConditionNode
WhenNode is an alias for ConditionNode, representing a conditional branch within a <choose> statement. It evaluates a condition and executes its content if the condition is true and it's the first matching condition in the choose block.
Behavior:
- Evaluates condition using same rules as ConditionNode
- Only executes if it's the first true condition in choose
- Subsequent true conditions are ignored
Example XML:
<choose> <when test='type == "PREMIUM"'> AND membership_level = 'PREMIUM' </when> <when test='type == "BASIC"'> AND membership_level IN ('BASIC', 'STANDARD') </when> </choose>
Supported conditions:
- Boolean expressions
- Numeric comparisons
- String comparisons
- Null checks
- Property access
Note: Unlike a standalone ConditionNode, WhenNode's execution is controlled by its parent ChooseNode and follows choose-when semantics similar to switch-case statements.
See ConditionNode for detailed condition evaluation rules.
type WhereNode ¶
type WhereNode struct {
Nodes NodeGroup
}
WhereNode represents a SQL WHERE clause and its conditions. It manages a group of condition nodes that form the complete WHERE clause.
func (WhereNode) Accept ¶
func (w WhereNode) Accept(translator driver.Translator, p Parameter) (query string, args []any, err error)
Accept processes the WHERE clause and its conditions. It handles several special cases:
- Removes leading "AND" or "OR" from the first condition
- Ensures the clause starts with "WHERE" if not already present
- Properly handles spacing between conditions
Examples:
Input: "AND id = ?" -> Output: "WHERE id = ?" Input: "OR name = ?" -> Output: "WHERE name = ?" Input: "WHERE age > ?" -> Output: "WHERE age > ?" Input: "status = ?" -> Output: "WHERE status = ?"
type XMLElementParser ¶
type XMLElementParser interface { ParseElement(parser *XMLParser, decoder *xml.Decoder, token xml.StartElement) error MatchElement(token xml.StartElement) bool }
type XMLElementParserChain ¶
type XMLElementParserChain []XMLElementParser
func (XMLElementParserChain) ParseElement ¶
func (xs XMLElementParserChain) ParseElement(parser *XMLParser, decoder *xml.Decoder, token xml.StartElement) error
type XMLEnvironmentsElementParser ¶
type XMLEnvironmentsElementParser struct{}
func (*XMLEnvironmentsElementParser) MatchElement ¶
func (p *XMLEnvironmentsElementParser) MatchElement(token xml.StartElement) bool
func (*XMLEnvironmentsElementParser) ParseElement ¶
func (p *XMLEnvironmentsElementParser) ParseElement(parser *XMLParser, decoder *xml.Decoder, token xml.StartElement) error
type XMLMappersElementParser ¶
type XMLMappersElementParser struct {
// contains filtered or unexported fields
}
func (*XMLMappersElementParser) MatchElement ¶
func (p *XMLMappersElementParser) MatchElement(token xml.StartElement) bool
func (*XMLMappersElementParser) ParseElement ¶
func (p *XMLMappersElementParser) ParseElement(parser *XMLParser, decoder *xml.Decoder, token xml.StartElement) error
type XMLParser ¶
XMLParser is the parser for XML configuration.
func (*XMLParser) AddXMLElementParser ¶
func (p *XMLParser) AddXMLElementParser(parsers ...XMLElementParser)
type XMLSettingsElementParser ¶
type XMLSettingsElementParser struct{}
func (*XMLSettingsElementParser) MatchElement ¶
func (p *XMLSettingsElementParser) MatchElement(token xml.StartElement) bool
func (*XMLSettingsElementParser) ParseElement ¶
func (p *XMLSettingsElementParser) ParseElement(parser *XMLParser, decoder *xml.Decoder, token xml.StartElement) error
Source Files
¶
- action.go
- binder.go
- configuration.go
- db.go
- doc.go
- environment.go
- errors.go
- executor.go
- fs.go
- func_pc.go
- handler.go
- insert_key_generator.go
- juice.go
- locker.go
- manager.go
- mapper.go
- middleware.go
- node.go
- param.go
- parser.go
- pool.go
- result_map.go
- runner.go
- scanner.go
- scope.go
- settings.go
- statement.go
- statement_handler.go
Directories
¶
Path | Synopsis |
---|---|
Package eval provides a simple lexical analyzer for processing logical expressions.
|
Package eval provides a simple lexical analyzer for processing logical expressions. |
internal
|
|