zorm

package module
v0.0.0-...-17af3f9 Latest Latest
Warning

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

Go to latest
Published: Dec 23, 2025 License: MIT Imports: 18 Imported by: 0

README

zorm

license Go Report Card Build Status codecov

🏎️ Zima ORM library that is simple, ultra-fast and self-mockable for Go

English | 中文

🚀 Key Features

⚡ High Performance

  • 8.6x Performance Improvement: Smart caching with zero allocation design
  • Reuse Enabled by Default: Automatic SQL and metadata reuse for repeated operations
  • Connection Pool Management: Configurable pool with optimal defaults for high concurrency
  • Read-Write Separation: Automatic routing of read/write operations for better performance

🗺️ Smart Data Types & Schema Management

  • Map Support: Use map[string]interface{} without struct definitions
  • Auto Naming: CamelCase to snake_case conversion for database fields
  • Flexible Tags: Support zorm:"field_name,auto_incr" format
  • Atomic DDL: Create, alter, and drop tables with atomic operations

🛠️ Complete CRUD Operations & Monitoring

  • One-Line Operations: Simple Insert, Update, Select, Delete APIs
  • Transaction Support: Built-in transaction management with context support
  • Join Queries: Advanced JOIN operations with flexible ON conditions
  • SQL Audit: Complete audit logging for all database operations

Goals

  • Easy to use: SQL-Like (One-Line-CRUD)
  • KISS: Keep it small and beautiful (not big and comprehensive)
  • Universal: Support struct, map, pb and basic types
  • Testable: Support self-mock (because parameters as return values, most mock frameworks don't support)
    • A library that is not test-oriented is not a good library
  • As-Is: Try not to make hidden settings to prevent misuse
  • Solve core pain points:
    • Manual SQL is error-prone, data assembly takes too much time
    • time.Time cannot be read/written directly
    • SQL function results cannot be scanned directly
    • Database operations cannot be easily mocked
    • QueryRow's sql.ErrNoRows problem
    • Directly replace the built-in Scanner, completely take over data reading type conversion
  • Core principles:
    • Don't map a table to a model like other ORMs
    • (In zorm, you can use Fields filter to achieve this)
    • Try to keep it simple, map one operation to one model!
  • Other advantages:
    • More natural where conditions (only add parentheses when needed, compared to gorm)
    • In operation accepts various types of slices
    • Switching from other ORM libraries requires no historical code modification, non-invasive modification

Feature Matrix

Below is a comparison with mainstream ORM libraries (please don't hesitate to open issues for corrections)
Library zorm (me) gorm xorm Notes
Usability No type specification needed :white_check_mark: :x: :x: zorm doesn't need low-frequency DDL in tags
No model specification needed :white_check_mark: :x: :x: gorm/xorm modification operations need to provide "template"
No primary key specification needed :white_check_mark: :x: :x: gorm/xorm prone to misoperation, such as deleting/updating entire table
Low learning cost :white_check_mark: :x: :x: If you know SQL, you can use zorm
Reuse native connections :white_check_mark: :x: :x: zorm has minimal refactoring cost
Full type conversion :white_check_mark: maybe :x: Eliminate type conversion errors
Reuse query commands :white_check_mark: :x: :x: zorm uses the same function for batch and single operations
Map type support Operate database with map :white_check_mark: :x: :x: Without defining struct, flexible handling of dynamic fields
Testability Self-mock :white_check_mark: :x: :x: zorm is very convenient for unit testing
Performance Compared to native time <=1x 2~3x 2~3x xorm using prepare mode will be 2~3x slower
Reflection reflect2 reflect reflect zorm zero use of ValueOf
Cache Optimization :rocket: :white_check_mark: :white_check_mark: 8.6x performance improvement, zero allocation design, smart call-site caching

Quick Start

  1. Import package

    import z "github.com/IceWhaleTech/zorm"
    
  2. Define Table object

    t := z.Table(d.DB, "t_usr")
    
    t1 := z.TableContext(ctx, d.DB, "t_usr")
    
  • d.DB is a database connection object that supports Exec/Query/QueryRow
  • t_usr can be a table name or nested query statement
  • ctx is the Context object to pass, defaults to context.Background() if not provided
  • Reuse functionality is enabled by default, providing 2-14x performance improvement, no additional configuration needed
  1. (Optional) Define model object

    type Info struct {
       ID   int64  `zorm:"id,auto_incr"` // Auto-increment primary key
       Name string // Auto-converted to "name"
       Tag  string // Auto-converted to "tag"
    }
    
  2. Execute operations

  • CRUD interfaces return (affected rows, error)

  • Type V is an abbreviation for map[string]interface{}, similar to gin.H

  • Insert

    // o can be object/slice/ptr slice
    n, err = t.Insert(&o)
    n, err = t.InsertIgnore(&o)
    n, err = t.ReplaceInto(&o)
    
    // Insert only partial fields (others use defaults)
    n, err = t.Insert(&o, z.Fields("name", "tag"))
    
    // Resolve primary key conflicts
    n, err = t.Insert(&o, z.Fields("name", "tag"),
       z.OnConflictDoUpdateSet([]string{"id"}, z.V{
          "name": "new_name",
          "age":  z.U("age+1"), // Use z.U to handle non-variable updates
       }))
    
    // Use map insert (no need to define struct)
    userMap := map[string]interface{}{
       "name":  "John Doe",
       "email": "john@example.com",
       "age":   30,
    }
    n, err = t.Insert(userMap)
    
    // Support embedded struct
    type User struct {
       Name  string `zorm:"name"`
       Email string `zorm:"email"`
       Address struct {
          Street string `zorm:"street"`
          City   string `zorm:"city"`
       } `zorm:"-"` // embedded struct
    }
    n, err = t.Insert(&user)
    
    // Support field ignore
    type User struct {
       Name     string `zorm:"name"`
       Password string `zorm:"-"` // ignore this field
       Email    string `zorm:"email"`
    }
    n, err = t.Insert(&user)
    
    // Auto-increment primary key
    type User struct {
       ID   int64  `zorm:"id,auto_incr"` // Auto-increment primary key
       Name string `zorm:"name"`
       Age  int    `zorm:"age"`
    }
    user := User{Name: "Alice", Age: 25}
    n, err = t.Insert(&user)
    // user.ID will be automatically set to the generated ID
    
    // Support both pointer and non-pointer types
    user := User{Name: "Bob", Age: 30}        // Non-pointer
    users := []User{{Name: "Charlie", Age: 35}} // Non-pointer slice
    n, err = t.Insert(user)   // Non-pointer struct
    n, err = t.Insert(&users) // Non-pointer slice
    
  • Select

    // o can be object/slice/ptr slice
    n, err := t.Select(&o,
       z.Where("name = ?", name),
       z.GroupBy("id"),
       z.Having(z.Gt("id", 0)),
       z.OrderBy("id", "name"),
       z.Limit(1))
    
    // Use basic type + Fields to get count (n value is 1, because result has only 1 row)
    var cnt int64
    n, err = t.Select(&cnt, z.Fields("count(1)"), z.Where("name = ?", name))
    
    // Also support arrays
    var ids []int64
    n, err = t.Select(&ids, z.Fields("id"), z.Where("name = ?", name))
    
    // Can force index
    n, err = t.Select(&ids, z.Fields("id"), z.IndexedBy("idx_xxx"), z.Where("name = ?", name))
    
    // Advanced Join Queries
    // Simple join with string ON condition
    var results []UserOrder
    n, err := t.Select(&results,
       z.Fields("users.id", "users.name", "orders.amount"),
       z.InnerJoin("orders", "users.id = orders.user_id"),
       z.Where("orders.status = ?", "completed"),
    )
    
    // Complex join with condition objects
    n, err = t.Select(&results,
       z.Fields("users.id", "users.name", "orders.amount"),
       z.LeftJoin("orders", z.Eq("users.id", z.U("orders.user_id"))),
    )
    
  • Select to Map (no struct needed)

    // single row to map
    var m map[string]interface{}
    n, err := t.Select(&m, z.Fields("id", "name", "age"), z.Where(z.Eq("id", 1)))
    
    // multiple rows to []map
    var ms []map[string]interface{}
    n, err = t.Select(&ms, z.Fields("id", "name", "age"), z.Where(z.Gt("age", 18)))
    
  • Update

    // o can be object/slice/ptr slice
    n, err = t.Update(&o, z.Where(z.Eq("id", id)))
    
    // Use map update
    n, err = t.Update(z.V{
          "name": "new_name",
          "tag":  "tag1,tag2,tag3",
          "age":  z.U("age+1"), // Use z.U to handle non-variable updates
       }, z.Where(z.Eq("id", id)))
    
    // Use map update partial fields
    n, err = t.Update(z.V{
          "name": "new_name",
          "tag":  "tag1,tag2,tag3",
       }, z.Fields("name"), z.Where(z.Eq("id", id)))
    
    n, err = t.Update(&o, z.Fields("name"), z.Where(z.Eq("id", id)))
    
  • CRUD with Reuse (enabled by default)

    // Reuse is on by default; repeated calls at the same call-site reuse SQL/metadata
    // Update example
    type User struct { ID int64 `zorm:"id"`; Name string `zorm:"name"`; Age int `zorm:"age"` }
    for _, u := range users {
        _, _ = t.Update(&u, z.Fields("name", "age"), z.Where(z.Eq("id", u.ID)))
    }
    
    // Insert example
    for _, u := range users {
        _, _ = t.Insert(&u)
    }
    
  • Delete

    // Delete by condition
    n, err = t.Delete(z.Where("name = ?", name))
    n, err = t.Delete(z.Where(z.Eq("id", id)))
    
  • Exec (Raw SQL)

    // Execute raw SQL with parameters
    n, err = t.Exec("UPDATE users SET status = ? WHERE id = ?", "active", 123)
    n, err = t.Exec("DELETE FROM logs WHERE created_at < ?", time.Now().AddDate(0, 0, -30))
    n, err = t.Exec("CREATE INDEX idx_name ON users (name)")
    
  • Variable conditions

    conds := []interface{}{z.Cond("1=1")} // prevent empty where condition
    if name != "" {
       conds = append(conds, z.Eq("name", name))
    }
    if id > 0 {
       conds = append(conds, z.Eq("id", id))
    }
    // Execute query operation
    n, err := t.Select(&o, z.Where(conds...))
    
  • Join queries

    type Info struct {
       ID   int64  `zorm:"users.id"` // field definition with table name
       Name string `zorm:"users.name"`
       Tag  string `zorm:"tags.tag"`
    }
    
    t := z.Table(d.DB, "users")
    n, err := t.Select(&o, 
       z.InnerJoin("tags", "users.id = tags.user_id"),
       z.Where(z.Eq("users.id", id)))
    
  • Get inserted auto-increment id

    // Modern approach: Use auto_incr tag
    type Info struct {
       ID   int64  `zorm:"id,auto_incr"` // Auto-increment primary key
       Name string `zorm:"name"`
       Age  int    `zorm:"age"`
    }
    
    o := Info{
       Name: "OrcaZ",
       Age:  30,
    }
    n, err = t.Insert(&o)
    
    id := o.ID // get the inserted id automatically set
    

    Note: The old ZormLastId field is still supported for backward compatibility, but the modern auto_incr tag approach is recommended.

  • New features example: Map types and Embedded Struct

    // 1. Use map type (no need to define struct)
    userMap := map[string]interface{}{
       "name":     "John Doe",
       "email":    "john@example.com",
       "age":      30,
       "created_at": time.Now(),
    }
    n, err := t.Insert(userMap)
    
    // 2. Support embedded struct
    type Address struct {
       Street string `zorm:"street"`
       City   string `zorm:"city"`
       Zip    string `zorm:"zip"`
    }
    
    type User struct {
       ID      int64  `zorm:"id"`
       Name    string `zorm:"name"`
       Email   string `zorm:"email"`
       Address Address `zorm:"-"` // embedded struct
       Password string `zorm:"-"` // ignore field
    }
    
    user := User{
       Name:  "Jane Doe",
       Email: "jane@example.com",
       Address: Address{
          Street: "123 Main St",
          City:   "New York",
          Zip:    "10001",
       },
       Password: "secret", // this field will be ignored
    }
    n, err := t.Insert(&user)
    
    // 3. Complex nested structure
    type Profile struct {
       Bio     string `zorm:"bio"`
       Website string `zorm:"website"`
    }
    
    type UserWithProfile struct {
       ID      int64  `zorm:"id"`
       Name    string `zorm:"name"`
       Profile Profile `zorm:"-"` // nested embedding
    }
    
  • Currently using other ORM frameworks (new interfaces can be switched first)

    // [gorm] db is a *gorm.DB
    t := z.Table(db.DB(), "tbl")
    
    // [xorm] db is a *xorm.EngineGroup
    t := z.Table(db.Master().DB().DB, "tbl")
    // or
    t := z.Table(db.Slave().DB().DB, "tbl")
    

Other Details

Table Options
Option Description
Debug Print SQL statements
Reuse Reuse SQL and storage based on call location (enabled by default, 2-14x improvement). Shape-aware multi-shape cache is built-in
NoReuse Disable Reuse functionality (not recommended, will reduce performance)
ToTimestamp Use timestamp for Insert, not formatted string
Audit Enable SQL audit logging and performance monitoring

Option usage example:

n, err = t.Debug().Insert(&o)

n, err = t.ToTimestamp().Insert(&o)

// Reuse functionality is enabled by default, no manual call needed
// If you need to disable it (not recommended), you can call:
n, err = t.NoReuse().Insert(&o)

// Enable audit with chain-style method
userTable := zorm.Table(db, "users").Audit(nil, nil) // Uses default loggers

// Or with custom loggers
auditLogger := zorm.NewJSONAuditLogger()
telemetryCollector := zorm.NewDefaultTelemetryCollector()
userTable := zorm.Table(db, "users").Audit(auditLogger, telemetryCollector)

// Chain multiple options
advancedTable := zorm.Table(db, "users").
   Debug().           // Enable debug mode
   Audit(nil, nil)    // Enable audit logging
Where
Example Description
Where("id=? and name=?", id, name) Regular formatted version
Where(Eq("id", id), Eq("name", name)...) Default to and connection
Where(And(Eq("x", x), Eq("y", y), Or(Eq("x", x), Eq("y", y)...)...)...) And & Or
Predefined Where Conditions
Name Example Description
Logical AND And(...) Any number of parameters, only accepts relational operators below
Logical OR Or(...) Any number of parameters, only accepts relational operators below
Normal condition Cond("id=?", id) Parameter 1 is formatted string, followed by placeholder parameters
Equal Eq("id", id) Two parameters, id=?
Not equal Neq("id", id) Two parameters, id<>?
Greater than Gt("id", id) Two parameters, id>?
Greater than or equal Gte("id", id) Two parameters, id>=?
Less than Lt("id", id) Two parameters, id<?
Less than or equal Lte("id", id) Two parameters, id<=?
Between Between("id", start, end) Three parameters, between start and end
Like Like("name", "x%") Two parameters, name like "x%"
GLOB GLOB("name", "?x*") Two parameters, name glob "?x*"
Multiple value selection In("id", ids) Two parameters, ids is basic type slice
GroupBy
Example Description
GroupBy("id", "name"...) -
Having
Example Description
Having("id=? and name=?", id, name) Regular formatted version
Having(Eq("id", id), Eq("name", name)...) Default to and connection
Having(And(Eq("x", x), Eq("y", y), Or(Eq("x", x), Eq("y", y)...)...)...) And & Or
OrderBy
Example Description
OrderBy("id desc", "name asc"...) -
Limit
Example Description
Limit(1) Page size 1
Limit(3, 2) Page size 3, offset position 2 (Note the difference from MySQL)
OnConflictDoUpdateSet
Example Description
OnConflictDoUpdateSet([]string{"id"}, V{"name": "new"}) Update to resolve primary key conflicts
Map Type Support
Example Description
Insert(map[string]interface{}{"name": "John", "age": 30}) Use map to insert data
Support all CRUD operations Select, Insert, Update, Delete all support map
Embedded Struct Support
Example Description
struct embeds other struct Automatically handle composite object fields
zorm:"-" tag Mark embedded struct
Field Ignore Functionality
Example Description
Password string zorm:"-" Ignore this field, not participate in database operations
Suitable for sensitive fields Such as passwords, temporary fields, etc.
IndexedBy
Example Description
IndexedBy("idx_biz_id") Solve index selectivity issues

How to Mock

Mock steps:
  • Call ZormMock to specify operations to mock
  • Use ZormMockFinish to check if mock was hit
Description:
  • First five parameters are tbl, fun, caller, file, pkg

    • Set to empty for default matching

    • Support wildcards '?' and '*', representing match one character and multiple characters respectively

    • Case insensitive

      Parameter Name Description
      tbl Table name Database table name
      fun Method name Select/Insert/Update/Delete
      caller Caller method name Need to include package name
      file File name File path where used
      pkg Package name Package name where used
  • Last three parameters are return data, return affected rows and error

  • Can only be used in test files

Usage example:

Function to test:

   package x

   func test(db *sql.DB) (X, int, error) {
      var o X
      tbl := z.Table(db, "tbl")
      n, err := tbl.Select(&o, z.Where("`id` >= ?", 1), z.Limit(100))
      return o, n, err
   }

In the x.test method querying tbl data, we need to mock database operations

   // Must set mock in _test.go file
   // Note caller method name needs to include package name
   z.ZormMock("tbl", "Select", "*.test", "", "", &o, 1, nil)

   // Call the function under test
   o1, n1, err := test(db)

   So(err, ShouldBeNil)
   So(n1, ShouldEqual, 1)
   So(o1, ShouldResemble, o)

   // Check if all hits
   err = z.ZormMockFinish()
   So(err, ShouldBeNil)
Performance Monitoring

All operations are automatically monitored with telemetry data:

  • Duration tracking: Measure operation execution time
  • Cache hit rates: Monitor reuse effectiveness
  • Memory usage: Track allocation patterns
  • Error rates: Monitor operation success/failure rates

Supported struct tags:

  • zorm:"field_name" - Field name mapping
  • zorm:"field_name,auto_incr" - Auto-increment primary key
  • zorm:"auto_incr" - Use converted field name with auto-increment
  • zorm:"-" - Ignore field
  • No tag - Auto-convert camelCase to snake_case

📚 Documentation

Performance Test Results

  • 8.6x Performance Improvement: Smart caching with zero allocation design
  • Memory Optimization: 92% memory usage reduction, 75% allocation count reduction
  • Concurrent Safe: Optimized for high concurrency scenarios with sync.Map

Reuse Function Performance Optimization

  • Benchmark Results:

    • Single thread: 8.6x performance improvement
    • Concurrent scenarios: Up to 14.2x performance improvement
    • Memory optimization: 92% memory usage reduction
    • Allocation optimization: 75% allocation count reduction
  • Technical Implementation:

    • Call site caching: Use runtime.Caller to cache file line numbers
    • String pooling: sync.Pool reuses strings.Builder
    • Zero allocation design: Avoid redundant string building and memory allocation
    • Concurrent safe: sync.Map supports high concurrency access
  • Performance Data:

    BenchmarkReuseOptimized-8    	 1000000	      1200 ns/op	     128 B/op	       2 allocs/op
    BenchmarkReuseOriginal-8     	  100000	     10320 ns/op	    1600 B/op	      15 allocs/op
    

Contributors

The existence of this project is thanks to all contributors.

Please give us a 💖star💖 to support us, thank you.

And thank you to all our supporters! 🙏

Documentation

Overview

Package zorm provides SQL audit and telemetry functionality for database operations.

Package zorm provides atomic DDL operations and database schema management.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func And

func And(conds ...interface{}) *ormCondEx

And .

func AtomicCreateTables

func AtomicCreateTables(db ZormDBIFace, logger DDLLogger, models ...interface{}) error

AtomicCreateTables performs atomic table creation with audit logging

func AtomicCreateTablesWithContext

func AtomicCreateTablesWithContext(ctx context.Context, db ZormDBIFace, logger DDLLogger, models ...interface{}) error

AtomicCreateTablesWithContext performs atomic table creation with context and audit logging

func Between

func Between(field string, i interface{}, j interface{}) *ormCond

Between .

func Cond

func Cond(c string, args ...interface{}) *ormCond

Cond .

func CreateTable

func CreateTable(db ZormDBIFace, tableName string, model interface{}, config *DDLConfig) error

CreateTable creates a table from struct definition

func CreateTables

func CreateTables(db ZormDBIFace, models ...interface{}) error

CreateTables automatically creates table schemas

func DropTable

func DropTable(db ZormDBIFace, tableName string) error

DropTable drops a table if it exists

func Eq

func Eq(field string, i interface{}) *ormCond

Eq .

func Fields

func Fields(fields ...string) *fieldsItem

Fields .

func FullJoin

func FullJoin(table string, on ...interface{}) *joinItem

FullJoin 全连接

func GLOB

func GLOB(field string, pattern string) *ormCond

GLOB .

func GroupBy

func GroupBy(fields ...string) *groupByItem

GroupBy .

func Gt

func Gt(field string, i interface{}) *ormCond

Gt .

func Gte

func Gte(field string, i interface{}) *ormCond

Gte .

func Having

func Having(conds ...interface{}) *havingItem

Having .

func In

func In(field string, args ...interface{}) *ormCond

In .

func IndexedBy

func IndexedBy(idx string) *indexedByItem

IndexedBy .

func InnerJoin

func InnerJoin(table string, on ...interface{}) *joinItem

InnerJoin 内连接

func Join

func Join(stmt string) *joinItem

Join .

func LeftJoin

func LeftJoin(table string, on ...interface{}) *joinItem

LeftJoin 左连接

func Like

func Like(field string, pattern string) *ormCond

Like .

func Limit

func Limit(i ...interface{}) *limitItem

Limit .

func Lt

func Lt(field string, i interface{}) *ormCond

Lt .

func Lte

func Lte(field string, i interface{}) *ormCond

Lte .

func Neq

func Neq(field string, i interface{}) *ormCond

Neq .

func OnConflictDoUpdateSet

func OnConflictDoUpdateSet(fields []string, keyVals V) *onConflictDoUpdateSetItem

OnConflictDoUpdateSet .

func Or

func Or(conds ...interface{}) *ormCondEx

Or .

func OrderBy

func OrderBy(orders ...string) *orderByItem

OrderBy .

func RightJoin

func RightJoin(table string, on ...interface{}) *joinItem

RightJoin 右连接

func SetConnectionPool

func SetConnectionPool(db *sql.DB, pool *ConnectionPool)

SetConnectionPool 设置连接池

func TableExists

func TableExists(db ZormDBIFace, tableName string) (bool, error)

TableExists checks if a table exists Priority: SQLite implementation first, MySQL as fallback

func Where

func Where(conds ...interface{}) *whereItem

Where .

func ZormMock

func ZormMock(tbl, fun, caller, file, pkg string, data interface{}, ret int, err error)

ZormMock .

func ZormMockFinish

func ZormMockFinish() error

ZormMockFinish .

Types

type AlterTableCommand

type AlterTableCommand struct {
	TableName string
	Operation string // ADD, DROP, MODIFY, RENAME
	Column    *ColumnDef
	OldName   string // for RENAME operations
	NewName   string // for RENAME operations
}

AlterTableCommand represents an ALTER TABLE command

func (*AlterTableCommand) Description

func (c *AlterTableCommand) Description() string

func (*AlterTableCommand) Execute

func (c *AlterTableCommand) Execute(ctx context.Context, db ZormDBIFace) error

func (*AlterTableCommand) SQL

func (c *AlterTableCommand) SQL() string

type AuditLogger

type AuditLogger interface {
	LogAuditEvent(ctx context.Context, event *SQLAuditEvent)
	LogTelemetryData(ctx context.Context, data *TelemetryData)
}

AuditLogger interface for logging SQL audit events

type AuditableDB

type AuditableDB struct {
	// contains filtered or unexported fields
}

AuditableDB wraps a ZormDBIFace with audit logging

func NewAuditableDB

func NewAuditableDB(db ZormDBIFace, auditLogger AuditLogger, telemetryCollector TelemetryCollector) *AuditableDB

NewAuditableDB creates a new auditable database wrapper

func (*AuditableDB) Disable

func (adb *AuditableDB) Disable()

Disable disables audit logging

func (*AuditableDB) Enable

func (adb *AuditableDB) Enable()

Enable enables audit logging

func (*AuditableDB) ExecContext

func (adb *AuditableDB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)

ExecContext implements ZormDBIFace with audit logging

func (*AuditableDB) GetTelemetryMetrics

func (adb *AuditableDB) GetTelemetryMetrics() map[string]interface{}

GetTelemetryMetrics returns current telemetry metrics

func (*AuditableDB) QueryContext

func (adb *AuditableDB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

QueryContext implements ZormDBIFace with audit logging

func (*AuditableDB) QueryRowContext

func (adb *AuditableDB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRowContext implements ZormDBIFace with audit logging

type CallSite

type CallSite struct {
	File string
	Line int
	Key  string
}

type ColumnDef

type ColumnDef struct {
	Name          string
	Type          string
	Nullable      bool
	DefaultValue  string
	AutoIncrement bool
	Comment       string
}

ColumnDef represents a column definition

type Config

type Config struct {
	Debug               bool
	Reuse               bool // 默认开启,提供2-14倍性能提升
	UseNameWhenTagEmpty bool
	ToTimestamp         bool
}

Config .

type ConnectionPool

type ConnectionPool struct {
	MaxOpenConns    int           // 最大打开连接数
	MaxIdleConns    int           // 最大空闲连接数
	ConnMaxLifetime time.Duration // 连接最大生存时间
	ConnMaxIdleTime time.Duration // 连接最大空闲时间
}

ConnectionPool 连接池配置

func DefaultConnectionPool

func DefaultConnectionPool() *ConnectionPool

DefaultConnectionPool 默认连接池配置

type ConnectionPoolStats

type ConnectionPoolStats struct {
	OpenConnections   int           `json:"open_connections"`
	InUseConnections  int           `json:"in_use_connections"`
	IdleConnections   int           `json:"idle_connections"`
	WaitCount         int64         `json:"wait_count"`
	WaitDuration      time.Duration `json:"wait_duration_ms"`
	MaxIdleClosed     int64         `json:"max_idle_closed"`
	MaxIdleTimeClosed int64         `json:"max_idle_time_closed"`
	MaxLifetimeClosed int64         `json:"max_lifetime_closed"`
}

ConnectionPoolStats represents connection pool statistics

type CreateIndexCommand

type CreateIndexCommand struct {
	IndexName string
	TableName string
	Columns   []string
	Unique    bool
}

CreateIndexCommand represents a CREATE INDEX command

func (*CreateIndexCommand) Description

func (c *CreateIndexCommand) Description() string

func (*CreateIndexCommand) Execute

func (c *CreateIndexCommand) Execute(ctx context.Context, db ZormDBIFace) error

func (*CreateIndexCommand) SQL

func (c *CreateIndexCommand) SQL() string

type CreateTableCommand

type CreateTableCommand struct {
	TableName  string
	Columns    []*ColumnDef
	PrimaryKey []string
}

CreateTableCommand represents a CREATE TABLE command

func (*CreateTableCommand) Description

func (c *CreateTableCommand) Description() string

func (*CreateTableCommand) Execute

func (c *CreateTableCommand) Execute(ctx context.Context, db ZormDBIFace) error

func (*CreateTableCommand) SQL

func (c *CreateTableCommand) SQL() string

type DDLCommand

type DDLCommand interface {
	Execute(ctx context.Context, db ZormDBIFace) error
	SQL() string
	Description() string
}

DDLCommand represents a single atomic DDL operation

type DDLConfig

type DDLConfig struct {
	SchemaManagement bool // Whether to enable schema management
}

DDLConfig DDL configuration

func DefaultDDLConfig

func DefaultDDLConfig() *DDLConfig

DefaultDDLConfig returns default DDL configuration for SQLite

type DDLLogger

type DDLLogger interface {
	LogCommand(ctx context.Context, cmd DDLCommand, err error)
	LogSchemaChange(ctx context.Context, plan *SchemaPlan, err error)
}

DDLLogger interface for logging DDL operations

type DDLManager

type DDLManager struct {
	// contains filtered or unexported fields
}

DDLManager manages DDL operations with audit logging

func NewDDLManager

func NewDDLManager(db ZormDBIFace, logger DDLLogger) *DDLManager

NewDDLManager creates a new DDL manager

func (*DDLManager) CreateTables

func (dm *DDLManager) CreateTables(ctx context.Context, models ...interface{}) error

CreateTables performs atomic table creation using the new DDL system

func (*DDLManager) ExecuteSchemaPlan

func (dm *DDLManager) ExecuteSchemaPlan(ctx context.Context, plan *SchemaPlan) error

ExecuteSchemaPlan executes a schema plan

func (*DDLManager) GenerateSchemaPlan

func (dm *DDLManager) GenerateSchemaPlan(ctx context.Context, targetModels []interface{}) (*SchemaPlan, error)

GenerateSchemaPlan generates a schema plan to transform current schema to target schema

func (*DDLManager) GetCurrentSchema

func (dm *DDLManager) GetCurrentSchema(ctx context.Context) (*SchemaInfo, error)

GetCurrentSchema retrieves current database schema

type DataBindingItem

type DataBindingItem struct {
	SQL    string
	Cols   []interface{}
	Type   reflect2.Type
	Elem   interface{}
	Fields []string // 用于Map类型的字段名
}

type DefaultAuditLogger

type DefaultAuditLogger struct {
	// contains filtered or unexported fields
}

DefaultAuditLogger is a simple console audit logger

func (*DefaultAuditLogger) LogAuditEvent

func (l *DefaultAuditLogger) LogAuditEvent(ctx context.Context, event *SQLAuditEvent)

func (*DefaultAuditLogger) LogTelemetryData

func (l *DefaultAuditLogger) LogTelemetryData(ctx context.Context, data *TelemetryData)

type DefaultDDLLogger

type DefaultDDLLogger struct{}

DefaultDDLLogger is a simple console logger

func (*DefaultDDLLogger) LogCommand

func (l *DefaultDDLLogger) LogCommand(ctx context.Context, cmd DDLCommand, err error)

func (*DefaultDDLLogger) LogSchemaChange

func (l *DefaultDDLLogger) LogSchemaChange(ctx context.Context, plan *SchemaPlan, err error)

type DefaultTelemetryCollector

type DefaultTelemetryCollector struct {
	// contains filtered or unexported fields
}

DefaultTelemetryCollector collects and stores telemetry data

func NewDefaultTelemetryCollector

func NewDefaultTelemetryCollector() *DefaultTelemetryCollector

func (*DefaultTelemetryCollector) CollectTelemetry

func (c *DefaultTelemetryCollector) CollectTelemetry(ctx context.Context, data *TelemetryData)

func (*DefaultTelemetryCollector) GetMetrics

func (c *DefaultTelemetryCollector) GetMetrics() map[string]interface{}

type DropIndexCommand

type DropIndexCommand struct {
	IndexName string
	TableName string
}

DropIndexCommand represents a DROP INDEX command

func (*DropIndexCommand) Description

func (c *DropIndexCommand) Description() string

func (*DropIndexCommand) Execute

func (c *DropIndexCommand) Execute(ctx context.Context, db ZormDBIFace) error

func (*DropIndexCommand) SQL

func (c *DropIndexCommand) SQL() string

type DropTableCommand

type DropTableCommand struct {
	TableName string
	IfExists  bool
}

DropTableCommand represents a DROP TABLE command

func (*DropTableCommand) Description

func (c *DropTableCommand) Description() string

func (*DropTableCommand) Execute

func (c *DropTableCommand) Execute(ctx context.Context, db ZormDBIFace) error

func (*DropTableCommand) SQL

func (c *DropTableCommand) SQL() string

type FieldInfo

type FieldInfo interface {
	GetName() string
	GetValue(ptr unsafe.Pointer) interface{}
	GetType() reflect2.Type
}

FieldInfo 通用字段信息接口

type FileAuditLogger

type FileAuditLogger struct {
	// contains filtered or unexported fields
}

FileAuditLogger logs audit events to a file

func NewFileAuditLogger

func NewFileAuditLogger(filename string) *FileAuditLogger

func (*FileAuditLogger) LogAuditEvent

func (l *FileAuditLogger) LogAuditEvent(ctx context.Context, event *SQLAuditEvent)

func (*FileAuditLogger) LogTelemetryData

func (l *FileAuditLogger) LogTelemetryData(ctx context.Context, data *TelemetryData)

type IndexInfo

type IndexInfo struct {
	Name    string
	Columns []string
	Unique  bool
	Primary bool
}

IndexInfo represents index information

type JSONAuditLogger

type JSONAuditLogger struct {
	// contains filtered or unexported fields
}

JSONAuditLogger logs audit events as JSON

func NewJSONAuditLogger

func NewJSONAuditLogger() *JSONAuditLogger

func (*JSONAuditLogger) LogAuditEvent

func (l *JSONAuditLogger) LogAuditEvent(ctx context.Context, event *SQLAuditEvent)

func (*JSONAuditLogger) LogCommand

func (l *JSONAuditLogger) LogCommand(ctx context.Context, cmd DDLCommand, err error)

LogCommand implements DDLLogger interface

func (*JSONAuditLogger) LogSchemaChange

func (l *JSONAuditLogger) LogSchemaChange(ctx context.Context, plan *SchemaPlan, err error)

LogSchemaChange implements DDLLogger interface

func (*JSONAuditLogger) LogTelemetryData

func (l *JSONAuditLogger) LogTelemetryData(ctx context.Context, data *TelemetryData)

type MapFieldInfo

type MapFieldInfo struct {
	// contains filtered or unexported fields
}

MapFieldInfo map字段信息实现

func (*MapFieldInfo) GetName

func (f *MapFieldInfo) GetName() string

func (*MapFieldInfo) GetType

func (f *MapFieldInfo) GetType() reflect2.Type

func (*MapFieldInfo) GetValue

func (f *MapFieldInfo) GetValue(ptr unsafe.Pointer) interface{}

type MockMatcher

type MockMatcher struct {
	Tbl    string
	Func   string
	Caller string
	File   string
	Pkg    string
	Data   interface{}
	Ret    int
	Err    error
}

MockMatcher .

type ReadWriteDB

type ReadWriteDB struct {
	Master ZormDBIFace   // 主库(写)
	Slaves []ZormDBIFace // 从库(读)
	// contains filtered or unexported fields
}

ReadWriteDB 读写分离数据库

func NewReadWriteDB

func NewReadWriteDB(master ZormDBIFace, slaves ...ZormDBIFace) *ReadWriteDB

NewReadWriteDB 创建读写分离数据库

func (*ReadWriteDB) ExecContext

func (rw *ReadWriteDB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)

ExecContext 实现 ZormDBIFace 接口(写操作使用主库)

func (*ReadWriteDB) QueryContext

func (rw *ReadWriteDB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

QueryContext 实现 ZormDBIFace 接口(读操作使用从库)

func (*ReadWriteDB) QueryRowContext

func (rw *ReadWriteDB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRowContext 实现 ZormDBIFace 接口(读操作使用从库)

type SQLAuditEvent

type SQLAuditEvent struct {
	ID           string                 `json:"id"`
	Timestamp    time.Time              `json:"timestamp"`
	Operation    string                 `json:"operation"` // SELECT, INSERT, UPDATE, DELETE, DDL
	TableName    string                 `json:"table_name"`
	SQL          string                 `json:"sql"`
	Args         []interface{}          `json:"args"`
	Duration     time.Duration          `json:"duration_ms"`
	RowsAffected int64                  `json:"rows_affected"`
	Error        string                 `json:"error,omitempty"`
	UserID       string                 `json:"user_id,omitempty"`
	SessionID    string                 `json:"session_id,omitempty"`
	Metadata     map[string]interface{} `json:"metadata,omitempty"`
}

SQLAuditEvent represents a SQL execution event for auditing

type SchemaInfo

type SchemaInfo struct {
	Tables map[string]*TableInfo
}

SchemaInfo represents current database schema information

type SchemaPlan

type SchemaPlan struct {
	Commands []DDLCommand
	Summary  string
}

SchemaPlan represents a plan for database schema changes

type StructFieldInfo

type StructFieldInfo struct {
	// contains filtered or unexported fields
}

StructFieldInfo struct字段信息实现

func (*StructFieldInfo) GetName

func (f *StructFieldInfo) GetName() string

func (*StructFieldInfo) GetType

func (f *StructFieldInfo) GetType() reflect2.Type

func (*StructFieldInfo) GetValue

func (f *StructFieldInfo) GetValue(ptr unsafe.Pointer) interface{}

type TableInfo

type TableInfo struct {
	Name    string
	Columns map[string]*ColumnDef
	Indexes map[string]*IndexInfo
}

TableInfo represents table schema information

type TelemetryCollector

type TelemetryCollector interface {
	CollectTelemetry(ctx context.Context, data *TelemetryData)
	GetMetrics() map[string]interface{}
}

TelemetryCollector interface for collecting telemetry data

type TelemetryData

type TelemetryData struct {
	ID              string                 `json:"id"`
	Timestamp       time.Time              `json:"timestamp"`
	Operation       string                 `json:"operation"`
	TableName       string                 `json:"table_name"`
	Duration        time.Duration          `json:"duration_ms"`
	RowsAffected    int64                  `json:"rows_affected"`
	CacheHit        bool                   `json:"cache_hit"`
	ReuseEnabled    bool                   `json:"reuse_enabled"`
	ConnectionPool  *ConnectionPoolStats   `json:"connection_pool,omitempty"`
	QueryComplexity int                    `json:"query_complexity"`
	Error           string                 `json:"error,omitempty"`
	Metadata        map[string]interface{} `json:"metadata,omitempty"`
}

TelemetryData represents performance and usage telemetry data

type U

type U string

U - an alias string type for update to support `x=x+1`

type V

type V map[string]interface{}

V - an alias object value type

type ZormDBIFace

type ZormDBIFace interface {
	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
	QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
}

ZormDBIFace .

type ZormItem

type ZormItem interface {
	Type() int
	BuildSQL(*strings.Builder)
	BuildArgs(*[]interface{})
}

ZormItem .

type ZormTable

type ZormTable struct {
	DB   ZormDBIFace
	Name string
	Cfg  Config
	// contains filtered or unexported fields
}

ZormTable .

func Table

func Table(db ZormDBIFace, name string, ctx ...context.Context) *ZormTable

Table .

func TableContext

func TableContext(ctx context.Context, db ZormDBIFace, name string) *ZormTable

TableContext 创建带Context的Table,参数顺序:context, db, name

func (*ZormTable) Audit

func (t *ZormTable) Audit(auditLogger interface{}, telemetryCollector interface{}) *ZormTable

Audit enables SQL auditing for this table

func (*ZormTable) Debug

func (t *ZormTable) Debug() *ZormTable

Debug .

func (*ZormTable) Delete

func (t *ZormTable) Delete(args ...ZormItem) (int, error)

Delete .

func (*ZormTable) Exec

func (t *ZormTable) Exec(query string, args ...interface{}) (int, error)

Exec executes a raw SQL statement with optional parameters Returns the number of affected rows and any error

func (*ZormTable) Insert

func (t *ZormTable) Insert(objs interface{}, args ...ZormItem) (int, error)

Insert .

func (*ZormTable) InsertIgnore

func (t *ZormTable) InsertIgnore(objs interface{}, args ...ZormItem) (int, error)

InsertIgnore .

func (*ZormTable) NoReuse

func (t *ZormTable) NoReuse() *ZormTable

NoReuse 关闭Reuse功能(如果不需要缓存优化)

func (*ZormTable) NoSafeReuse

func (t *ZormTable) NoSafeReuse() *ZormTable

NoSafeReuse 已合并进 Reuse,保持兼容

func (*ZormTable) ReplaceInto

func (t *ZormTable) ReplaceInto(objs interface{}, args ...ZormItem) (int, error)

ReplaceInto .

func (*ZormTable) Reuse

func (t *ZormTable) Reuse() *ZormTable

Reuse .

func (*ZormTable) SafeReuse

func (t *ZormTable) SafeReuse() *ZormTable

SafeReuse 已合并进 Reuse,保持兼容

func (*ZormTable) Select

func (t *ZormTable) Select(res interface{}, args ...ZormItem) (int, error)

Select .

func (*ZormTable) ToTimestamp

func (t *ZormTable) ToTimestamp() *ZormTable

ToTimestamp .

func (*ZormTable) Update

func (t *ZormTable) Update(obj interface{}, args ...ZormItem) (int, error)

Update .

func (*ZormTable) UseNameWhenTagEmpty

func (t *ZormTable) UseNameWhenTagEmpty() *ZormTable

UseNameWhenTagEmpty .

type ZormTx

type ZormTx struct {
	// contains filtered or unexported fields
}

ZormTx 事务实现

func (*ZormTx) Commit

func (tx *ZormTx) Commit() error

Commit 提交事务

func (*ZormTx) ExecContext

func (tx *ZormTx) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)

ExecContext 实现 ZormDBIFace 接口

func (*ZormTx) QueryContext

func (tx *ZormTx) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)

QueryContext 实现 ZormDBIFace 接口

func (*ZormTx) QueryRowContext

func (tx *ZormTx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row

QueryRowContext 实现 ZormDBIFace 接口

func (*ZormTx) Rollback

func (tx *ZormTx) Rollback() error

Rollback 回滚事务

type ZormTxIFace

type ZormTxIFace interface {
	ZormDBIFace
	Commit() error
	Rollback() error
}

ZormTxIFace 事务接口

func Begin

func Begin(db ZormDBIFace) (ZormTxIFace, error)

Begin 开始事务

func BeginContext

func BeginContext(ctx context.Context, db ZormDBIFace) (ZormTxIFace, error)

BeginContext 带上下文开始事务

Directories

Path Synopsis
examples
audit_chain command
basic_select command
camel_to_snake command
crud_map command
crud_struct command
join_query command
on_conflict command
raw_sql_exec command
reuse command
select_map command
tag_formats command

Jump to

Keyboard shortcuts

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