qsql

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Apr 12, 2025 License: MIT Imports: 16 Imported by: 4

README

qsql is a supplement to the go sql package

Refere to:

database/sql
https://github.com/jmoiron/sqlx

Example:

More example see the example directory.

Directing use

package main

import (
	"github.com/gwaylib/conf"
	"github.com/gwaylib/errors"
	"github.com/gwaylib/qsql"
	_ "github.com/go-sql-driver/mysql"
)

func main() {
    mdb, err := qsql.Open(qsql.DRV_NAME_MYSQL, dsn)
    if err != nil{
        panic(err)
    }
    arr := make([]string, 3)
    if err := mdb.QueryElems(&arr, "SELECT id, created_at, updated_at WHERE id=?", 1); err != nil{
        panic(err)
    }
}

Using ini cache

the configuration file path like : './etc/db.cfg'

The etc file content

[main]
driver: mysql
dsn: username:passwd@tcp(127.0.0.1:3306)/main?timeout=30s&strict=true&loc=Local&parseTime=true&allowOldPasswords=1
max_life_time:7200 # seconds
max_idle_time:0 # seconds
max_idle_conns:0 # num
max_open_conns:0 # num

[log]
driver: mysql
dsn: username:passwd@tcp(127.0.0.1:3306)/log?timeout=30s&strict=true&loc=Local&parseTime=true&allowOldPasswords=1
max_life_time:7200

Make a package for cache.go with ini

package db

import (
	"github.com/gwaylib/conf"
	"github.com/gwaylib/qsql"
	_ "github.com/go-sql-driver/mysql"
)

func init() {
    qsql.RegCacheWithIni(conf.RootDir() + "/etc/db.cfg")

    // Register cache without ini
    // db, err := qsql.Open(qsql.DRV_NAME_MYSQL, dsn)
    // if err != nil{
    //     panic(err)
    // }
    // qsql.RegCache("main", db)
}

func GetCache(section string) *qsql.DB {
	return qsql.GetCache(section)
}

func HasCache(section string) (*qsql.DB, error) {
	return qsql.HasCache(section)
}

func CloseCache() {
	qsql.CloseCache()
}

Using the cache package

package main

import (
	"github.com/gwaylib/conf"
	"github.com/gwaylib/errors"
	_ "github.com/go-sql-driver/mysql"

    "model/db"
)

func main() {
    mdb := db.GetCache("main")
    arr := make([]string, 3)
    if err := mdb.QueryElems(&arr, "SELECT id, created_at, updated_at WHERE id=?", 1); err != nil{
        panic(err)
    }
}

Standard sql

*qsql.DB has implements *sql.DB, so you can call qsql.DB like *sql.DB

mdb := db.GetCache("main") 

row := mdb.QueryRow("SELECT * ...") // 
// ...

rows, err := mdb.Query("SELECT * ...")
// ...

result, err := mdb.Exec("UPDATE ...")
// ...

Insert struct(s) into table

the struct tag format like db:"field", reference to: http://github.com/jmoiron/sqlx

type User struct{
    Id     int64  `db:"id,auto_increment"` // flag "autoincrement", "auto_increment" are supported .
    Name   string `db:"name"`
    Ignore string `db:"-"` // ignore flag: "-"
}

func main() {
    mdb := db.GetCache("main") 

    var u = &User{
        Name:"testing",
    }

    // Insert data with driver.
    if _, err := mdb.InsertStruct(u, "testing"); err != nil{
        // ... 
    }
    // ...
}

Quick sql way

package main

import (
    gErrors "github.com/gwaylib/errors"
)

// Way 1: query result to a struct.
type User struct{
    Id   int64 `db:"id"`
    Name string `db:"name"`
}

func main() {
    mdb := db.GetCache("main") 
    var u = *User{}
    if err := mdb.QueryStruct(u, "SELECT id, name FROM a WHERE id = ?", id); err != nil {
        // sql.ErrNoRows has been replace by gErrors.ErrNoData
        if gErrors.ErrNoData.Equal(err) {
           // no data
        }
        // ...
    }
    // ..

    count := 0
    if err := mdb.QueryElem(&count, "SELECT count(*) FROM a WHERE id = ?", id); err != nil{
        // sql.ErrNoRows has been replace by errors.ErrNoData
        if errors.ErrNoData.Equal(err) {
           // no data
        }
        // ...
    }
}

Make a lazy tx commit

// commit the tx
func main() {
    mdb := qsql.GetCache("main") 
    tx, err := mdb.Begin()
    if err != nil{
        // ...
    }
    fn := func() error {
      if err := tx.Exec("UPDATE testing SET name = ? WHERE id = ?", id); err != nil{
        return err
      }
      return nil
    }
    if err := mdb.Commit(tx, fn); err != nil {
        // ...
    }
}

SqlBuilder

func main() {
    mdb := qsql.GetCache("main") 

    id := 0
    inIds := []interface{}{1,2}

    bd := qsql.NewSqlBuilder(mdb.DriverName())
    bd.Select("id", "created_at")
    bd.Add("FROM")
    bd.AddTab("tmp")
    bd.Add("WHERE")
    bd.AddTab("created_at BETWEEN ? AND ?", time.Now().AddDate(-1,0,0), time.Now())
    bd.AddTabIf(len(inIds)>0, "AND id IN ("+bd.AddIn(inIds)+")", id)
    titles, data, err := mdb.QueryPageArr(bd.String(), bd.Args()...) 
    if err != nil {
        panic(err)
    }

    updateBD := qsql.NewSqlBuilder(mdb.DriverName())
    updateBD.Add("UPDATE tmp SET")
    updateBD.AddTab("(updated_at=?,name=?)", time.Now())
    updateDB.Add("WHERE")
    updateDB.AddTab("id=?", id)
    if _, err := mdb.Exec(updateDB.String(), updateDB.Args()...); err != nil{
        panic(err)
    }
}

Documentation

Overview

Provides database connections in factory mode to optimize database connections

Example:

mdb := db.GetCache("main")

// count sql cbd := NewSqlBuilder(mdb.DriverName()) cbd.Select("COUNT(*)") cbd.Add("FROM tmp") cbd.Add("WHERE") cbd.AddTab("create_at BETWEEN ? AND ?", time.Now().AddDate(-1,0,0), time.Now())

// copy condition qbd := cbd.Copy() qbd.Select("id", "created_at", "name") qbd.Add("OFFSET ?", 0) qbd.Add("LIMIT ?", 20)

pSql := NewPageSql(cbd, qbd) count, err := pSql.QueryCount(db) ... Or titles, result, err := pSql.QueryPageArray(db) ... Or titles, result, err := pSql.QueryPageMap(db) ...

Index

Constants

View Source
const (
	DRV_NAME_MYSQL     = "mysql"
	DRV_NAME_ORACLE    = "oracle" // or "oci8"
	DRV_NAME_POSTGRES  = "postgres"
	DRV_NAME_SQLITE3   = "sqlite3"
	DRV_NAME_SQLSERVER = "sqlserver" // or "mssql"

)

Variables

This section is empty.

Functions

func Close

func Close(closer io.Closer)

A lazy function to closed the io.Closer

func CloseCache

func CloseCache()

Close all instance in the cache.

func Commit

func Commit(tx *sql.Tx, fn func() error) error

A lazy function to commit the *sql.Tx

func InsertStruct

func InsertStruct(drvName string, exec Execer, obj interface{}, tbName string) (sql.Result, error)

func InsertStructContext

func InsertStructContext(drvName string, exec Execer, ctx context.Context, obj interface{}, tbName string) (sql.Result, error)

func MakeDBData added in v0.0.3

func MakeDBData(l int) []interface{}

func QueryElem

func QueryElem(queryer Queryer, result interface{}, querySql string, args ...interface{}) error

func QueryElemContext

func QueryElemContext(queryer Queryer, ctx context.Context, result interface{}, querySql string, args ...interface{}) error

func QueryElems

func QueryElems(queryer Queryer, result interface{}, querySql string, args ...interface{}) error

func QueryElemsContext

func QueryElemsContext(queryer Queryer, ctx context.Context, result interface{}, querySql string, args ...interface{}) error

func QueryPageArr

func QueryPageArr(queryer Queryer, querySql string, args ...interface{}) (titles []string, result [][]interface{}, err error)

func QueryPageArrContext

func QueryPageArrContext(queryer Queryer, ctx context.Context, querySql string, args ...interface{}) (titles []string, result [][]interface{}, err error)

func QueryPageMap

func QueryPageMap(queryer Queryer, querySql string, args ...interface{}) (titles []string, result []map[string]interface{}, err error)

func QueryPageMapContext

func QueryPageMapContext(queryer Queryer, ctx context.Context, querySql string, args ...interface{}) (titles []string, result []map[string]interface{}, err error)

func QueryStruct

func QueryStruct(queryer Queryer, obj interface{}, querySql string, args ...interface{}) error

func QueryStructContext

func QueryStructContext(queryer Queryer, ctx context.Context, obj interface{}, querySql string, args ...interface{}) error

func QueryStructs

func QueryStructs(queryer Queryer, obj interface{}, querySql string, args ...interface{}) error

func QueryStructsContext

func QueryStructsContext(queryer Queryer, ctx context.Context, obj interface{}, querySql string, args ...interface{}) error

func RegCache

func RegCache(key string, db *DB)

Register a db to the connection pool by manully.

func RegCacheWithIni

func RegCacheWithIni(iniPath string)

func Rollback

func Rollback(tx *sql.Tx)

A lazy function to rollback the *sql.Tx

func ScanStructs

func ScanStructs(rows *sql.Rows, obj interface{}) error

func StmtIn added in v0.0.3

func StmtIn(paramStartIdx, paramsLen int, drvName ...string) string

Types

type DB

type DB struct {
	*sql.DB
	// contains filtered or unexported fields
}

qsql.DB Extendd sql.DB and implement qsql.QuickQuery interface

func GetCache

func GetCache(key string) *DB

Get the db instance from the cache.

func HasCache

func HasCache(key string) (*DB, error)

Checking the cache does it have a db instance.

func NewDB

func NewDB(drvName string, db *sql.DB) *DB

func Open

func Open(drvName, dsn string) (*DB, error)

Implement the sql.Open

func (*DB) Close

func (db *DB) Close() error

func (*DB) Commit

func (db *DB) Commit(tx *sql.Tx, fn func() error) error

A lazy function to commit the *sql.Tx if will auto commit when the function is nil error, or do a rollback and return the function error.

func (*DB) DriverName

func (db *DB) DriverName() string

func (*DB) InsertStruct

func (db *DB) InsertStruct(structPtr interface{}, tbName string) (sql.Result, error)

Reflect one db data to the struct. the struct tag format like `db:"field_title"`, reference to: http://github.com/jmoiron/sqlx

func (*DB) InsertStructContext

func (db *DB) InsertStructContext(ctx context.Context, structPtr interface{}, tbName string) (sql.Result, error)

func (*DB) IsClose

func (db *DB) IsClose() bool

func (*DB) QueryElem

func (db *DB) QueryElem(result interface{}, querySql string, args ...interface{}) error

Query one field to a sql.Scanner.

func (*DB) QueryElemContext

func (db *DB) QueryElemContext(ctx context.Context, result interface{}, querySql string, args ...interface{}) error

func (*DB) QueryElems

func (db *DB) QueryElems(result interface{}, querySql string, args ...interface{}) error

Query one field to a sql.Scanner array.

func (*DB) QueryElemsContext

func (db *DB) QueryElemsContext(ctx context.Context, result interface{}, querySql string, args ...interface{}) error

func (*DB) QueryPageArr

func (db *DB) QueryPageArr(querySql string, args ...interface{}) (titles []string, result [][]interface{}, err error)

Reflect the query result to a string array.

func (*DB) QueryPageArrContext

func (db *DB) QueryPageArrContext(ctx context.Context, querySql string, args ...interface{}) (titles []string, result [][]interface{}, err error)

func (*DB) QueryPageMap

func (db *DB) QueryPageMap(querySql string, args ...interface{}) (titles []string, result []map[string]interface{}, err error)

Reflect the query result to a string map.

func (*DB) QueryPageMapContext

func (db *DB) QueryPageMapContext(ctx context.Context, querySql string, args ...interface{}) (titles []string, result []map[string]interface{}, err error)

func (*DB) QueryStruct

func (db *DB) QueryStruct(structPtr interface{}, querySql string, args ...interface{}) error

Reflect the sql.Query result to a struct.

func (*DB) QueryStructContext

func (db *DB) QueryStructContext(ctx context.Context, structPtr interface{}, querySql string, args ...interface{}) error

func (*DB) QueryStructs

func (db *DB) QueryStructs(structPtr interface{}, querySql string, args ...interface{}) error

Reflect the sql.Query result to a struct array. Return empty array if data not found.

func (*DB) QueryStructsContext

func (db *DB) QueryStructsContext(ctx context.Context, structPtr interface{}, querySql string, args ...interface{}) error

func (*DB) ScanStructs

func (db *DB) ScanStructs(rows *sql.Rows, structsPtr interface{}) error

Reflect the sql.Rows to []struct array. Return empty array if data not found. Refere to: github.com/jmoiron/sqlx DO NOT forget close the rows

func (*DB) StmtIn added in v0.0.3

func (db *DB) StmtIn(paramStartIdx, paramsLen int) string

Return "?,?,?,?..." for default, or "@p1,@p2,@p3..." for mssql, or ":1,:2,:3..." for pgsql. paramStartIdx default is 0, but you need count it when the driver is mssq, pgsql etc. .

type DBData

type DBData string

通用的字符串查询

func (*DBData) Scan

func (d *DBData) Scan(i interface{}) error

func (*DBData) String

func (d *DBData) String() string

type Execer

type Execer interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
}

type PageSql

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

func NewPageSql

func NewPageSql(countBD, queryBD *SqlBuilder) *PageSql

func (*PageSql) QueryCount

func (p *PageSql) QueryCount(db *DB) (int64, error)

func (*PageSql) QueryPageArr

func (p *PageSql) QueryPageArr(db *DB) ([]string, [][]interface{}, error)

func (*PageSql) QueryPageMap

func (p *PageSql) QueryPageMap(db *DB) ([]string, []map[string]interface{}, error)

type Queryer

type Queryer interface {
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row

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

type QuickSql added in v0.0.3

type QuickSql interface {
	DriverName() string

	// Insert a struct data into tbName
	//
	// Reflect one db data to the struct.
	// the struct tag format like `db:"field_title"`, reference to: http://github.com/jmoiron/sqlx
	//
	InsertStruct(structPtr interface{}, tbName string) (sql.Result, error)
	InsertStructContext(ctx context.Context, structPtr interface{}, tbName string) (sql.Result, error)

	// Scan the rows result to []struct
	// Reflect the sql.Rows to a struct array.
	// Return empty array if data not found.
	// Refere to: github.com/jmoiron/sqlx
	// DOT NOT forget close the rows after called.
	ScanStructs(rows *sql.Rows, structsPtr interface{}) error

	// Query db data to a struct
	QueryStruct(structPrt interface{}, querySql string, args ...interface{}) error
	QueryStructContext(ctx context.Context, structPrt interface{}, querySql string, args ...interface{}) error
	// Query db data to []struct
	QueryStructs(structsPrt interface{}, querySql string, args ...interface{}) error
	QueryStructsContext(ctx context.Context, structsPrt interface{}, querySql string, args ...interface{}) error

	// Query a element data like int, string.
	// Same as row.Scan(&e)
	QueryElem(ePtr interface{}, querySql string, args ...interface{}) error
	QueryElemContext(ctx context.Context, ePtr interface{}, querySql string, args ...interface{}) error
	// Query elements data like []int, []string in result.
	QueryElems(ePtr interface{}, querySql string, args ...interface{}) error
	QueryElemsContext(ctx context.Context, ePtr interface{}, querySql string, args ...interface{}) error

	// Query a page data to array.
	// the result data is [][]*string but no nil *string pointer instance.
	QueryPageArr(querySql string, args ...interface{}) (titles []string, result [][]interface{}, err error)
	QueryPageArrContext(ctx context.Context, querySql string, args ...interface{}) (titles []string, result [][]interface{}, err error)

	// Query a page data to map, NOT RECOMMENED to use when there is a large page data.
	// the result data is []map[string]*string but no nil *string pointer instance.
	QueryPageMap(querySql string, args ...interface{}) (titles []string, result []map[string]interface{}, err error)
	QueryPageMapContext(ctx context.Context, querySql string, args ...interface{}) (titles []string, result []map[string]interface{}, err error)

	// Extend stmt for the where in
	// paramStartIdx default is 0, but you need count it when the driver is mssq, pgsql etc. .
	//
	// Example for the first input:
	// fmt.Sprintf("select * from table_name where in (%s)", qsql.StmtWhereIn(0,len(args))
	// Or
	// fmt.Sprintf("select * from table_name where in (%s)", qsql.StmtWhereIn(0,len(args), qsql.DRV_NAME_MYSQL)
	//
	// Example for the second input:
	// fmt.Sprintf("select * from table_name where id=? in (%s)", qsql.StmtWhereIn(1,len(args))
	//
	// Return "?,?,?,?..." for default, or "@p1,@p2,@p3..." for mssql, or ":1,:2,:3..." for pgsql when paramStartIdx is 0.
	StmtIn(paramStartIdx, paramLen int) string

	// auto commit when the func is return nil, or auto rollback when the func is error
	Commit(tx *sql.Tx, fn func() error) error
}

type SqlBuilder added in v0.0.3

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

func NewSqlBuilder added in v0.0.3

func NewSqlBuilder(drvName ...string) *SqlBuilder

func (*SqlBuilder) Add added in v0.0.3

func (b *SqlBuilder) Add(key string, args ...interface{}) *SqlBuilder

func (*SqlBuilder) AddIf added in v0.0.3

func (b *SqlBuilder) AddIf(ok bool, key string, args ...interface{}) *SqlBuilder

func (*SqlBuilder) AddIn added in v0.0.3

func (b *SqlBuilder) AddIn(in []interface{}) string

func (*SqlBuilder) AddTab added in v0.0.3

func (b *SqlBuilder) AddTab(key string, args ...interface{}) *SqlBuilder

recursive Add, only format the code when coding

func (*SqlBuilder) Args added in v0.0.3

func (b *SqlBuilder) Args() []interface{}

func (*SqlBuilder) Copy added in v0.0.3

func (b *SqlBuilder) Copy() *SqlBuilder

func (*SqlBuilder) Select added in v0.0.3

func (b *SqlBuilder) Select(column ...string) *SqlBuilder

func (*SqlBuilder) SelectStruct added in v0.0.3

func (b *SqlBuilder) SelectStruct(obj interface{}) *SqlBuilder

func (*SqlBuilder) SetIndent added in v0.0.3

func (b *SqlBuilder) SetIndent(indent string) *SqlBuilder

func (*SqlBuilder) Sql added in v0.0.3

func (b *SqlBuilder) Sql() []interface{}

func (*SqlBuilder) String added in v0.0.3

func (b *SqlBuilder) String() string

Directories

Path Synopsis
example module

Jump to

Keyboard shortcuts

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