yiigo

package module
v1.12.1 Latest Latest
Warning

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

Go to latest
Published: Apr 1, 2024 License: Apache-2.0 Imports: 29 Imported by: 8

README

yiigo

golang GitHub release pkg.go.dev Apache 2.0 license

Go 开发工具包

go get -u github.com/shenghui0779/yiigo

Features

  • Nsq - 封装便于使用
  • Hash - 封装便于使用
  • Http - 封装便于使用(支持文件上传)
  • Crypto - 封装便于使用(支持 AES & RSA)
  • Validator - 支持汉化 & 自定义规则
  • 基于 sqlx 的轻量 SQLBuilder
  • 基于 Redis 的简单分布式锁
  • Websocket 封装提高易用性
    • Dialer - 读写失败支持重连
    • Upgrader - 支持授权校验
  • Value - 用于处理 k-v 格式化的场景,如:生成签名串 等
  • Location - 距离、方位角、经纬度与平面直角坐标系的相互转化
  • TimeWheel - 简单实用的单时间轮(支持一次性和多次重试任务)
  • 实用的辅助方法:IP、file、time、slice、string、version compare 等
SQL Builder

⚠️ 目前支持的特性有限,复杂的SQL(如:子查询等)还需自己手写

builder := yiigo.NewSQLBuilder(*sqlx.DB, func(ctx context.Context, query string, args ...any) {
    fmt.Println(query, args)
})
  • Query
ctx := context.Background()

type User struct {
    ID     int    `db:"id"`
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

var record User
builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).One(ctx, &record)
// SELECT * FROM user WHERE id = ?
// [1]

var records []User
builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("name = ? AND age > ?", "shenghui0779", 20),
).All(ctx, &records)
// SELECT * FROM user WHERE name = ? AND age > ?
// [shenghui0779 20]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.WhereIn("age IN (?)", []int{20, 30}),
).All(...)
// SELECT * FROM user WHERE age IN (?, ?)
// [20 30]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Select("id", "name", "age"),
    yiigo.Where("id = ?", 1),
).One(...)
// SELECT id, name, age FROM user WHERE id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Distinct("name"),
    yiigo.Where("id = ?", 1),
).One(...)
// SELECT DISTINCT name FROM user WHERE id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.LeftJoin("address", "user.id = address.user_id"),
    yiigo.Where("user.id = ?", 1),
).One(...)
// SELECT * FROM user LEFT JOIN address ON user.id = address.user_id WHERE user.id = ?
// [1]

builder.Wrap(
    yiigo.Table("address"),
    yiigo.Select("user_id", "COUNT(*) AS total"),
    yiigo.GroupBy("user_id"),
    yiigo.Having("user_id = ?", 1),
).All(...)
// SELECT user_id, COUNT(*) AS total FROM address GROUP BY user_id HAVING user_id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("age > ?", 20),
    yiigo.OrderBy("age ASC", "id DESC"),
    yiigo.Offset(5),
    yiigo.Limit(10),
).All(...)
// SELECT * FROM user WHERE age > ? ORDER BY age ASC, id DESC LIMIT ? OFFSET ?
// [20, 10, 5]

wrap1 := builder.Wrap(
    yiigo.Table("user_1"),
    yiigo.Where("id = ?", 2),
)

builder.Wrap(
    yiigo.Table("user_0"),
    yiigo.Where("id = ?", 1),
    yiigo.Union(wrap1),
).All(...)
// (SELECT * FROM user_0 WHERE id = ?) UNION (SELECT * FROM user_1 WHERE id = ?)
// [1, 2]

builder.Wrap(
    yiigo.Table("user_0"),
    yiigo.Where("id = ?", 1),
    yiigo.UnionAll(wrap1),
).All(...)
// (SELECT * FROM user_0 WHERE id = ?) UNION ALL (SELECT * FROM user_1 WHERE id = ?)
// [1, 2]

builder.Wrap(
    yiigo.Table("user_0"),
    yiigo.WhereIn("age IN (?)", []int{10, 20}),
    yiigo.Limit(5),
    yiigo.Union(
        builder.Wrap(
            yiigo.Table("user_1"),
            yiigo.Where("age IN (?)", []int{30, 40}),
            yiigo.Limit(5),
        ),
    ),
).All(...)
// (SELECT * FROM user_0 WHERE age IN (?, ?) LIMIT ?) UNION (SELECT * FROM user_1 WHERE age IN (?, ?) LIMIT ?)
// [10, 20, 5, 30, 40, 5]
  • Insert
ctx := context.Background()

type User struct {
    ID     int64  `db:"-"`
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

builder.Wrap(Table("user")).Insert(ctx, &User{
    Name: "yiigo",
    Age:  29,
})
// INSERT INTO user (name, age) VALUES (?, ?)
// [yiigo 29]

builder.Wrap(yiigo.Table("user")).Insert(ctx, yiigo.X{
    "name": "yiigo",
    "age":  29,
})
// INSERT INTO user (name, age) VALUES (?, ?)
// [yiigo 29]
  • Batch Insert
ctx := context.Background()

type User struct {
    ID     int64  `db:"-"`
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

builder.Wrap(Table("user")).BatchInsert(ctx, []*User{
    {
        Name: "shenghui0779",
        Age:  20,
    },
    {
        Name: "yiigo",
        Age:  29,
    },
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [shenghui0779 20 yiigo 29]

builder.Wrap(yiigo.Table("user")).BatchInsert(ctx, []yiigo.X{
    {
        "name": "shenghui0779",
        "age":  20,
    },
    {
        "name": "yiigo",
        "age":  29,
    },
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [shenghui0779 20 yiigo 29]
  • Update
ctx := context.Background()

type User struct {
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).Update(ctx, &User{
    Name: "yiigo",
    Age:  29,
})
// UPDATE user SET name = ?, age = ? WHERE id = ?
// [yiigo 29 1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).Update(ctx, yiigo.X{
    "name": "yiigo",
    "age":  29,
})
// UPDATE user SET name = ?, age = ? WHERE id = ?
// [yiigo 29 1]

builder.Wrap(
    yiigo.Table("product"),
    yiigo.Where("id = ?", 1),
).Update(ctx, yiigo.X{
    "price": yiigo.SQLExpr("price * ? + ?", 2, 100),
})
// UPDATE product SET price = price * ? + ? WHERE id = ?
// [2 100 1]
  • Delete
ctx := context.Background()

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).Delete(ctx)
// DELETE FROM user WHERE id = ?
// [1]

builder.Wrap(yiigo.Table("user")).Truncate(ctx)
// TRUNCATE user
  • Transaction
builder.Transaction(context.Background(), func(ctx context.Context, tx yiigo.TXBuilder) error {
    _, err := tx.Wrap(
        yiigo.Table("address"),
        yiigo.Where("user_id = ?", 1),
    ).Update(ctx, yiigo.X{"default": 0})
    if err != nil {
        return err
    }

    _, err = tx.Wrap(
        yiigo.Table("address"),
        yiigo.Where("id = ?", 1),
    ).Update(ctx, yiigo.X{"default": 1})

    return err
})

Enjoy 😊

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrSQLDataType 不合法的插入或更新数据类型错误
	ErrSQLDataType = errors.New("invaild data type, expects: struct, *struct, yiigo.X")

	// ErrSQLBatchDataType 不合法的批量插入数据类型错误
	ErrSQLBatchDataType = errors.New("invaild data type, expects: []struct, []*struct, []yiigo.X")
)
View Source
var GMT8 = time.FixedZone("CST", 8*3600)

GMT8 东八区时区

Functions

func AddSlashes

func AddSlashes(s string) string

AddSlashes 在字符串的每个引号前添加反斜杠

func ContentType added in v1.6.5

func ContentType(r *http.Request) string

func CreateFile added in v1.6.4

func CreateFile(filename string) (*os.File, error)

CreateFile 创建或清空指定的文件 文件已存在,则清空;文件或目录不存在,则以0775权限创建

func DebugLogger added in v1.11.2

func DebugLogger(options ...zap.Option) *zap.Logger

func DetachContext added in v1.12.1

func DetachContext(ctx context.Context) context.Context

DetachContext returns a copy of parent that is not canceled when parent is canceled. The returned context returns no Deadline or Err, and its Done channel is nil. Calling [Cause] on the returned context returns nil. Use `context.WithoutCancel` if go version >= 1.21.0

func IP2Long

func IP2Long(ip string) uint32

IP2Long IP地址转整数

func Long2IP

func Long2IP(ip uint32) string

Long2IP 整数转IP地址

func MapForm added in v1.6.5

func MapForm(ptr any, form map[string][]string) error

func MapFormByTag added in v1.6.5

func MapFormByTag(ptr any, form map[string][]string, tag string) error

func MapQuery added in v1.6.5

func MapQuery(ptr any, m map[string][]string) error

func MappingByPtr added in v1.6.5

func MappingByPtr(ptr any, setter setter, tag string) error

func MarshalNoEscapeHTML added in v1.7.5

func MarshalNoEscapeHTML(v any) ([]byte, error)

MarshalNoEscapeHTML 不带HTML转义的JSON序列化

func MyTimeEncoder

func MyTimeEncoder(t time.Time, e zapcore.PrimitiveArrayEncoder)

MyTimeEncoder 自定义时间格式化

func NewDB added in v1.11.2

func NewDB(cfg *DBConfig) (*sql.DB, error)

func NewDBX added in v1.11.2

func NewDBX(cfg *DBConfig) (*sqlx.DB, error)

func NewLogger added in v1.11.2

func NewLogger(cfg *LogConfig) *zap.Logger

func Nonce added in v1.10.4

func Nonce(size uint8) string

Nonce 生成随机串(size应为偶数)

func OpenFile added in v1.6.6

func OpenFile(filename string) (*os.File, error)

OpenFile 打开指定的文件 文件已存在,则追加内容;文件或目录不存在,则以0775权限创建

func QuoteMeta

func QuoteMeta(s string) string

QuoteMeta 在字符串预定义的字符前添加反斜杠

func SliceRand added in v1.8.0

func SliceRand[T any](a []T, n int) []T

SliceRand 返回一个指定随机挑选个数的切片 若 n == -1 or n >= len(a),则返回打乱的切片

func SliceUniq added in v1.8.0

func SliceUniq[T ~[]E, E cmp.Ordered](a T) T

SliceUniq 切片去重

func StrToTime

func StrToTime(datetime, layout string) time.Time

StrToTime 时间字符串解析为时间戳

func StripSlashes

func StripSlashes(s string) string

StripSlashes 删除字符串中的反斜杠

func TimeToStr added in v1.9.0

func TimeToStr(timestamp int64, layout string) string

TimeToStr 时间戳格式化为时间字符串 若 timestamp < 0,则使用 `time.Now()`

func Transaction added in v1.9.0

func Transaction(ctx context.Context, db *sqlx.DB, fn func(ctx context.Context, tx *sqlx.Tx) error) error

Transaction 执行数据库事物

func VersionCompare

func VersionCompare(rangeVer, curVer string) (bool, error)

VersionCompare 语义化的版本比较,支持:>, >=, =, !=, <, <=, | (or), & (and). 参数 `rangeVer` 示例:1.0.0, =1.0.0, >2.0.0, >=1.0.0&<2.0.0, <2.0.0|>3.0.0, !=4.0.4

func WeekAround

func WeekAround(timestamp int64, layout string) (monday, sunday string)

WeekAround 返回给定时间戳所在周的「周一」和「周日」时间字符串

Types

type DBConfig added in v1.6.0

type DBConfig struct {
	// Driver 驱动名称
	Driver string
	// DSN 数据源名称
	// [-- MySQL] username:password@tcp(localhost:3306)/dbname?timeout=10s&charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&loc=Local
	// [Postgres] host=localhost port=5432 user=root password=secret dbname=test connect_timeout=10 sslmode=disable
	// [- SQLite] file::memory:?cache=shared
	DSN string
	// MaxOpenConns 设置最大可打开的连接数
	MaxOpenConns int
	// MaxIdleConns 连接池最大闲置连接数
	MaxIdleConns int
	// ConnMaxLifetime 连接的最大生命时长
	ConnMaxLifetime time.Duration
	// ConnMaxIdleTime 连接最大闲置时间
	ConnMaxIdleTime time.Duration
}

DBConfig 数据库初始化配置

type LogConfig added in v1.11.2

type LogConfig struct {
	// Filename 日志名称
	Filename string
	// Level 日志级别
	Level zapcore.Level
	// MaxSize 当前文件多大时轮替;默认:100MB
	MaxSize int
	// MaxAge 轮替的旧文件最大保留时长;默认:不限
	MaxAge int
	// MaxBackups 轮替的旧文件最大保留数量;默认:不限
	MaxBackups int
	// Compress 轮替的旧文件是否压缩;默认:不压缩
	Compress bool
	// Stderr 是否输出到控制台
	Stderr bool
	// Options Zap日志选项
	Options []zap.Option
}

LogConfig 日志初始化配置

type Mutex added in v1.6.5

type Mutex interface {
	// Lock 尝试获取锁;interval - 每隔指定时间尝试获取一次锁;timeout - 获取锁的超时时间
	Lock(ctx context.Context, interval, timeout time.Duration) error
	// UnLock 释放锁
	UnLock(ctx context.Context) error
}

Mutex 分布式锁

func DistributedMutex added in v1.6.5

func DistributedMutex(cli *redis.Client, key, uniqueID string, expire time.Duration) Mutex

DistributedMutex 返回一个分布式锁实例; uniqueID - 建议使用「RequestID」

type Quantity added in v1.12.0

type Quantity int64

Quantity 字节大小

const (
	// B - Byte size
	B Quantity = 1
	// KiB - KibiByte size
	KiB Quantity = 1024 * B
	// MiB - MebiByte size
	MiB Quantity = 1024 * KiB
	// GiB - GibiByte size
	GiB Quantity = 1024 * MiB
	// TiB - TebiByte size
	TiB Quantity = 1024 * GiB
)

func (Quantity) String added in v1.12.0

func (q Quantity) String() string

String 实现 Stringer 接口

type SQLBuilder added in v1.0.4

type SQLBuilder interface {
	TXBuilder
	// Transaction 启用事务
	Transaction(ctx context.Context, f func(ctx context.Context, tx TXBuilder) error) error
}

SQLBuilder SQL构造器

func NewSQLBuilder added in v1.0.4

func NewSQLBuilder(db *sqlx.DB, logFn func(ctx context.Context, query string, args ...any)) SQLBuilder

NewSQLBuilder 生成SQL构造器

type SQLClause added in v1.0.4

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

SQLClause SQL语句

func SQLExpr added in v1.8.2

func SQLExpr(query string, binds ...any) *SQLClause

SQLExpr 生成一个语句表达式,例如:yiigo.SQLExpr("price * ? + ?", 2, 100)

type SQLOption added in v1.12.0

type SQLOption func(w *sqlWrapper)

SQLOption SQL查询选项

func CrossJoin added in v1.2.4

func CrossJoin(table string) SQLOption

CrossJoin 指定 `CROSS JOIN` 语句

func Distinct added in v1.0.5

func Distinct(columns ...string) SQLOption

Distinct 指定 `DISTINCT` 子句

func FullJoin added in v1.0.5

func FullJoin(table, on string) SQLOption

FullJoin 指定 `FULL JOIN` 子句

func GroupBy added in v1.0.5

func GroupBy(columns ...string) SQLOption

GroupBy 指定 `GROUP BY` 子句

func Having added in v1.0.5

func Having(query string, binds ...any) SQLOption

Having 指定 `HAVING` 子句

func Join added in v1.1.2

func Join(table, on string) SQLOption

Join 指定 `INNER JOIN` 子句

func LeftJoin added in v1.0.5

func LeftJoin(table, on string) SQLOption

LeftJoin 指定 `LEFT JOIN` 子句

func Limit added in v1.0.5

func Limit(n int) SQLOption

Limit 指定 `LIMIT` 子句

func Offset added in v1.0.5

func Offset(n int) SQLOption

Offset 指定 `OFFSET` 子句

func OrderBy added in v1.0.5

func OrderBy(columns ...string) SQLOption

OrderBy 指定 `ORDER BY` 子句

func Returning added in v1.12.1

func Returning(column string) SQLOption

Returning 指定 `RETURNING` 子句; 用于 PostgresSQL 和 SQLite(3.35.0) `INSERT` 语句

func RightJoin added in v1.0.5

func RightJoin(table, on string) SQLOption

RightJoin 指定 `RIGHT JOIN` 子句

func Select added in v1.0.5

func Select(columns ...string) SQLOption

Select 指定查询字段名

func Table added in v1.0.5

func Table(name string) SQLOption

Table 指定查询表名称

func Union added in v1.1.2

func Union(wrappers ...SQLWrapper) SQLOption

Union 指定 `UNION` 子句

func UnionAll added in v1.1.2

func UnionAll(wrappers ...SQLWrapper) SQLOption

UnionAll 指定 `UNION ALL` 子句

func Where added in v1.0.5

func Where(query string, binds ...any) SQLOption

Where 指定 `WHERE` 子句

func WhereIn added in v1.1.2

func WhereIn(query string, binds ...any) SQLOption

WhereIn 指定 `WHERE IN` 子句

type SQLWrapper added in v1.1.2

type SQLWrapper interface {
	// One 查询一条数据
	One(ctx context.Context, data any) error
	// All 查询多条数据
	All(ctx context.Context, data any) error
	// Insert 插入数据 (数据类型:`struct`, `*struct`, `yiigo.X`)
	Insert(ctx context.Context, data any) (sql.Result, error)
	// BatchInsert 批量插入数据 (数据类型:`[]struct`, `[]*struct`, `[]yiigo.X`)
	BatchInsert(ctx context.Context, data any) (sql.Result, error)
	// Update 更新数据 (数据类型:`struct`, `*struct`, `yiigo.X`)
	Update(ctx context.Context, data any) (sql.Result, error)
	// Delete 删除数据
	Delete(ctx context.Context) (sql.Result, error)
	// Truncate 清空表
	Truncate(ctx context.Context) (sql.Result, error)
}

SQLWrapper SQL包装器

type TXBuilder added in v1.12.0

type TXBuilder interface {
	// Wrap 包装查询选项
	Wrap(opts ...SQLOption) SQLWrapper
	// contains filtered or unexported methods
}

TXBuilder 事务构造器

type X

type X map[string]any

X 类型别名

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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