sqlmy

package module
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2020 License: BSD-2-Clause Imports: 12 Imported by: 2

README

项目名称

sqlmy 是一个 对官方的mysql二次封装的工具库, 它的优势在于:

  • 完全兼容官方库接口,面向接口设计
  • 提供 dao 命令行自动生成dao层的代码,开发者可以在完成表结构定义后一键生成dao 层代码
  • 强类型访问数据库的方式.这个的具体实现依赖didi的类库,轮子已经那么多了,没必要再造了
  • 引入mock工具,轻而易举的实现数据库的stub

面向接口的设计,完全兼容官方库

这块其实是为了能够实现单测是mock对象的注入,并且对官方库进行一些删改.包括:

  • 数据库访问前:提供 SqlBuilder 接口,它完成 Sql 构造
  • 数据库访问时:
    • 废弃所有没有 Context 后缀的官方实现,比如保留 QueryContext,但是废弃 Query
    • 扩充 WithBuilder 后缀,组合SqlBuilder能力,比如有 QueryContextWitBuilder
    • 扩充 WithBuilderStruct 后缀,进一步组合Orm能力, 比如有 QueryContextWitBuilderStruct
  • 数据库访问后:提供了 ScanStruct 接口,完成 Orm 能力
重要对象说明
  • DB:原生库 database.DB 的扩展实现(扩充内容见整体思路)
  • Conn: 原始库 daabase.Conn 的扩展实现
  • Tx:原始库database.Tx 的扩展实现
  • Stmt:原始库database.Stmt 的扩展实现
  • Rows:原始库database.Rows 的扩展实现
  • Row:原始库database.Row 的扩展实现
  • Hooks:日志可扩展钩子,默认实现有LogHook

具体的可以参考 接口设计

dao层代码一键生成工具

dao -db demo_db [-t demo_table] [-u root] [-p password] [-h 127.0.0.1] [-P 3306] [-json false] [-pkg dao]

它会读取数据库定义的表结构信息,完成代码自动生成,生成代码大概如下:

// AUTO GEN BY dao, Modify it as you want
package dao

import (
	"context"
	"database/sql"
	"time"

	"github.com/liuximu/sqlmy"
)

const cardTable = "card"

type Card struct {
	Id         int64  `ddb:"id" json:"id"`
	Name       string `ddb:"name" json:"name"`
	KnowID     int64  `ddb:"kid" json:"kid"`
}

type CardParam struct {
	Id         *int64  `ddb:"id" json:"id"`
	Ids        []int64 `ddb:"id,in" json:"id"`
	Name       *string `ddb:"name" json:"name"`
	KnowID     *int64  `ddb:"kid" json:"kid"`

	OrderBy *string `ddb:"_orderby"`
}

type CardList []*Card
type CardParamList []*CardParam

func (c *Card) Query(ctx context.Context, db sqlmy.QueryExecer, where *CardParam, columns []string) error {
	return db.QueryRowContextWithBuilderStruct(ctx, sqlmy.NewSelectBuilder(cardTable, sqlmy.Struct2Where(where), columns), c)
}

func (cp *CardParam) Create(ctx context.Context, db sqlmy.QueryExecer) (sql.Result, error) {
	return db.ExecContextWithBuilder(ctx, sqlmy.NewInsertBuilder(cardTable, sqlmy.Struct2AssignList(cp)))
}

func (cp *CardParam) Update(ctx context.Context, db sqlmy.QueryExecer, where *CardParam) (sql.Result, error) {
	return db.ExecContextWithBuilder(ctx, sqlmy.NewUpdateBuilder(cardTable, sqlmy.Struct2Where(where), sqlmy.Struct2Assign(cp)))
}

func (cp *CardParam) Delete(ctx context.Context, db sqlmy.QueryExecer) (sql.Result, error) {
	return db.ExecContextWithBuilder(ctx, sqlmy.NewDeleteBuilder(cardTable, sqlmy.Struct2Where(cp)))
}

func (cl *CardList) Query(ctx context.Context, db sqlmy.QueryExecer, where *CardParam, columns []string) error {
	return db.QueryContextWithBuilderStruct(ctx, sqlmy.NewSelectBuilder(cardTable, sqlmy.Struct2Where(where), columns), cl)
}

func (cpl CardParamList) Create(ctx context.Context, db sqlmy.QueryExecer) (sql.Result, error) {
	_cpl := make([]interface{}, len(cpl))
	for i, one := range cpl {
		_cpl[i] = one
	}
	return db.ExecContextWithBuilder(ctx, sqlmy.NewInsertBuilder(cardTable, sqlmy.Struct2AssignList(_cpl...)))
}

可以发现大概是这么几种类型:

  • Entity: 完成单条记录Query的数据接收
  • EntityParam: where 条件的构造, 更新和插入的实体载体
  • EntityList: 完成多记录Query的数据接收
  • EntityParamList: 完成多记录的创建
如何获取 dao
go get github.com/liuximu/sqlmy/tool/dao

单测

引入了 sqlmock 完成单测功能.具体用法请查看sqlmock

例子

flashcard 使用本类库完成数据库访问,如果需要可以参考.

Documentation

Index

Constants

View Source
const (
	CommonInsert  = 0
	IgnoreInsert  = 1
	ReplaceInsert = 2
)

Variables

This section is empty.

Functions

func CommitOrRollback

func CommitOrRollback(tx Tx) error

func LogHook

func LogHook(ctx context.Context, ev *Event)

func Scan

func Scan(rs Rows, target interface{}) error

func SetTagName

func SetTagName(name string)

func Struct2Assign

func Struct2Assign(raw interface{}) map[string]interface{}

func Struct2AssignList

func Struct2AssignList(raws ...interface{}) []map[string]interface{}

func Struct2Where

func Struct2Where(raw interface{}) map[string]interface{}

Types

type Conn

type Conn interface {
	DB() DB

	RawConn() *sql.Conn
	// contains filtered or unexported methods
}

type DB

type DB interface {
	Name() string

	Raw() *sql.DB
	// contains filtered or unexported methods
}

func MockDb

func MockDb() (DB, sqlmock.Sqlmock, error)

type DBConfig

type DBConfig struct {
	MaxIdleConns    int
	MaxOpenConns    int
	ConnMaxLifeTime time.Duration
}

type DeleteBuilder

type DeleteBuilder struct {
	Table  string
	Wheres map[string]interface{}
}

func NewDeleteBuilder

func NewDeleteBuilder(table string, wheres map[string]interface{}) *DeleteBuilder

func (*DeleteBuilder) Compile

func (d *DeleteBuilder) Compile() (sql string, args []interface{}, err error)

func (*DeleteBuilder) From

func (d *DeleteBuilder) From(table string) *DeleteBuilder

func (*DeleteBuilder) Where

func (d *DeleteBuilder) Where(wheres map[string]interface{}) *DeleteBuilder

type Event

type Event struct {
	DB   DB
	Type EventType
	Sql  string
	Args []interface{}
	Err  error
	Log  Logger

	Cost time.Duration
}

func NewEvent

func NewEvent(db DB, typ EventType, cost time.Duration, sql string, args []interface{}, err error, log Logger) *Event

TODO pool

type EventType

type EventType int8
const (
	EventPing EventType = iota
	EventStmt
	EventStmtClose
	EventTxBegin
	EventTxCommit
	EventTxRollback
	EventExec
	EventQueryRow
	EventQuery
)

type Handler

type Handler func(ctx context.Context, ev *Event)

type Hooks

type Hooks struct {
	Handlers [9][]Handler
}

func NewLogHooks

func NewLogHooks() *Hooks

func (*Hooks) AddHandler

func (hs *Hooks) AddHandler(he EventType, h Handler)

func (*Hooks) Append

func (hs *Hooks) Append(hook *Hooks)

func (*Hooks) Empty

func (hs *Hooks) Empty(et EventType) bool

func (*Hooks) SetHandler

func (hs *Hooks) SetHandler(he EventType, h Handler)

func (*Hooks) Trigger

func (hs *Hooks) Trigger(ctx context.Context, event *Event)

type InsertBuilder

type InsertBuilder struct {
	Table   string
	Assigns []map[string]interface{}
	// contains filtered or unexported fields
}

func NewIgnoreInsertBuilder

func NewIgnoreInsertBuilder(table string, assigns []map[string]interface{}) *InsertBuilder

func NewInsertBuilder

func NewInsertBuilder(table string, assigns []map[string]interface{}) *InsertBuilder

func NewReplaceInsertBuilder

func NewReplaceInsertBuilder(table string, assigns []map[string]interface{}) *InsertBuilder

func (*InsertBuilder) Compile

func (i *InsertBuilder) Compile() (sql string, args []interface{}, err error)

func (*InsertBuilder) InsertIgnoreInto

func (i *InsertBuilder) InsertIgnoreInto(table string) *InsertBuilder

func (*InsertBuilder) InsertInto

func (i *InsertBuilder) InsertInto(table string) *InsertBuilder

func (*InsertBuilder) ReplaceInto

func (i *InsertBuilder) ReplaceInto(table string) *InsertBuilder

func (*InsertBuilder) Values

func (i *InsertBuilder) Values(assigns []map[string]interface{}) *InsertBuilder

type Logger

type Logger interface {
	Infof(format string, args ...interface{})
	Warnf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
	Error(...interface{})
	Info(...interface{})
}

type MyDB

type MyDB struct {
	DBName   string
	DSN      string
	Protocol string
	Config   *DBConfig

	StatusLogger Logger
	AccessLog    Logger

	Hooks *Hooks
	// contains filtered or unexported fields
}

func (*MyDB) AddHook

func (db *MyDB) AddHook(et EventType, h Handler)

func (*MyDB) BeginTx

func (db *MyDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (Tx, error)

func (*MyDB) Close

func (db *MyDB) Close() error

func (*MyDB) Conn

func (db *MyDB) Conn(ctx context.Context) (Conn, error)

func (*MyDB) Driver

func (db *MyDB) Driver() driver.Driver

func (*MyDB) EnableLog

func (db *MyDB) EnableLog(enable bool)

func (*MyDB) ExecContext

func (db *MyDB) ExecContext(ctx context.Context, query string, args ...interface{}) (rst sql.Result, err error)

func (*MyDB) ExecContextWithBuilder

func (db *MyDB) ExecContextWithBuilder(ctx context.Context, builder SqlBuilder) (sql.Result, error)

func (*MyDB) Init

func (db *MyDB) Init() (err error)

func (*MyDB) Name

func (db *MyDB) Name() string

func (*MyDB) Ping

func (db *MyDB) Ping(ctx context.Context) error

func (*MyDB) PrepareContext

func (db *MyDB) PrepareContext(ctx context.Context, query string) (Stmt, error)

func (*MyDB) QueryContext

func (db *MyDB) QueryContext(ctx context.Context, query string, args ...interface{}) (Rows, error)

func (*MyDB) QueryContextWithBuilder

func (db *MyDB) QueryContextWithBuilder(ctx context.Context, builder SqlBuilder) (Rows, error)

func (*MyDB) QueryContextWithBuilderStruct

func (db *MyDB) QueryContextWithBuilderStruct(ctx context.Context, builder SqlBuilder, dst interface{}) error

func (*MyDB) QueryRowContext

func (db *MyDB) QueryRowContext(ctx context.Context, query string, args ...interface{}) Row

func (*MyDB) QueryRowContextWithBuilder

func (db *MyDB) QueryRowContextWithBuilder(ctx context.Context, builder SqlBuilder) Row

func (*MyDB) QueryRowContextWithBuilderStruct

func (db *MyDB) QueryRowContextWithBuilderStruct(ctx context.Context, builder SqlBuilder, dst interface{}) error

func (*MyDB) Raw

func (db *MyDB) Raw() *sql.DB

func (*MyDB) SetConnMaxLifetime

func (db *MyDB) SetConnMaxLifetime(d time.Duration)

func (*MyDB) SetHook

func (db *MyDB) SetHook(et EventType, h Handler)

func (*MyDB) SetMaxIdleConns

func (db *MyDB) SetMaxIdleConns(n int)

func (*MyDB) SetMaxOpenConns

func (db *MyDB) SetMaxOpenConns(n int)

func (*MyDB) Start

func (db *MyDB) Start() error

func (*MyDB) Stats

func (db *MyDB) Stats() sql.DBStats

func (*MyDB) Stop

func (db *MyDB) Stop(os.Signal)

type QueryExecer

type QueryExecer interface {
	// contains filtered or unexported methods
}

type Row

type Row interface {
	Raw() *sql.Row
	// contains filtered or unexported methods
}

type Rows

type Rows interface {
	Raw() *sql.Rows
	// contains filtered or unexported methods
}

type SelectBuilder

type SelectBuilder struct {
	Table       string
	Wheres      map[string]interface{}
	SelectField []string
}

func NewSelectBuilder

func NewSelectBuilder(table string, wheres map[string]interface{}, selectField []string) *SelectBuilder

func (*SelectBuilder) Compile

func (s *SelectBuilder) Compile() (sql string, args []interface{}, err error)

func (*SelectBuilder) From

func (s *SelectBuilder) From(table string) *SelectBuilder

func (*SelectBuilder) Select

func (s *SelectBuilder) Select(selectFields []string) *SelectBuilder

func (*SelectBuilder) Where

func (s *SelectBuilder) Where(wheres map[string]interface{}) *SelectBuilder

type SqlBuilder

type SqlBuilder interface {
	Compile() (sql string, args []interface{}, err error)
}

type Stmt

type Stmt interface {
	Close() error

	Raw() *sql.Stmt
	// contains filtered or unexported methods
}

type Tx

type Tx interface {
	Raw() *sql.Tx
	// contains filtered or unexported methods
}

type TxError

type TxError struct {
	CommitErr error
	RollError error
}

func (*TxError) Error

func (txError *TxError) Error() string

type UpdateBuilder

type UpdateBuilder struct {
	Table   string
	Wheres  map[string]interface{}
	Assigns map[string]interface{}
}

func NewUpdateBuilder

func NewUpdateBuilder(table string, wheres map[string]interface{}, assigns map[string]interface{}) *UpdateBuilder

func (*UpdateBuilder) Assign

func (u *UpdateBuilder) Assign(assign map[string]interface{}) *UpdateBuilder

func (*UpdateBuilder) Compile

func (u *UpdateBuilder) Compile() (sql string, args []interface{}, err error)

func (*UpdateBuilder) From

func (u *UpdateBuilder) From(table string) *UpdateBuilder

func (*UpdateBuilder) Where

func (u *UpdateBuilder) Where(wheres map[string]interface{}) *UpdateBuilder

Directories

Path Synopsis
dao

Jump to

Keyboard shortcuts

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