Skip to content

yiigo/contrib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

contrib

golang GitHub release pkg.go.dev Apache 2.0 license

Go 开发实用库

获取

go get -u github.com/yiigo/contrib

包含

  • xhash - 封装便于使用
  • xcrypto - 封装便于使用(支持 AES & RSA)
  • validator - 支持汉化和自定义规则
  • 基于 Redis 的分布式锁
  • 基于 sqlx 的轻量SQLBuilder
  • 基于泛型的无限菜单分类层级树
  • linklist - 一个并发安全的双向列表
  • errgroup - 基于官方版本改良,支持并发协程数量控制
  • xvalue - 用于处理 k-v 格式化的场景,如:生成签名串 等
  • xcoord - 距离、方位角、经纬度与平面直角坐标系的相互转化
  • timewheel - 简单实用的单层时间轮(支持一次性和多次重试任务)
  • 实用的辅助方法:IP、file、time、slice、string、version compare 等

⚠️ 注意:如需支持协程并发复用的 errgrouptimewheel,请使用 👉 nightfall

SQL Builder

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

builder := contrib.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
    records []User
)

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

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

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

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

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

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

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

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

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

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

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

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

builder.Wrap(
    contrib.Table("user_0"),
    contrib.WhereIn("age IN (?)", []int{10, 20}),
    contrib.Limit(5),
    contrib.Union(
        builder.Wrap(
            contrib.Table("user_1"),
            contrib.Where("age IN (?)", []int{30, 40}),
            contrib.Limit(5),
        ),
    ),
).All(ctx, &records)
// (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(contrib.Table("user")).Insert(ctx, contrib.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: "yiigo",
        Age:  20,
    },
    {
        Name: "yiigo",
        Age:  29,
    },
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [yiigo 20 yiigo 29]

builder.Wrap(contrib.Table("user")).BatchInsert(ctx, []contrib.X{
    {
        "name": "yiigo",
        "age":  20,
    },
    {
        "name": "yiigo",
        "age":  29,
    },
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [yiigo 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(
    contrib.Table("user"),
    contrib.Where("id = ?", 1),
).Update(ctx, &User{
    Name: "yiigo",
    Age:  29,
})
// UPDATE user SET name = ?, age = ? WHERE (id = ?)
// [yiigo 29 1]

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

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

👉 Delete

ctx := context.Background()

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

builder.Wrap(contrib.Table("user")).Truncate(ctx)
// TRUNCATE user

👉 Transaction

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

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

    return err
})

Enjoy 😊