wdb

command
v0.0.0-...-64c43b1 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2024 License: Apache-2.0 Imports: 11 Imported by: 0

README

#+startup: content
#+title: wdb插件文档
* wdb文档
** 约定及使用方式
当前只做了mysql生成.
*** 约定
 - *必须在文件级定义 ~sql.db~ option才会生成db代码.*.
 - *使用包名作为数据库配置名,默认生成的操作代码目录为 pkg/dbop/包名,可以通过 ~WDB_OPCODE_PATH~ 修改*
 - *定义了 ~sql.tbl_name~ option 会自动生成名为 `消息名Ex`的消息体(含数据条目创建时间和最后一次修改时间)*
*** 使用
| level  | options         | value  | desc                                                |
|--------+-----------------+--------+-----------------------------------------------------|
| 文件级 |                 |        |                                                     |
|        | sql.db          | string | 此文件定义的表归属于哪个数据库                      |
| 消息级 |                 |        |                                                     |
|        | sql.tbl_name    | string | string类型的值会作为实际sql的表名                   |
|        | sql.ignore      | bool   | 标识message不是sql表.                               |
|        | sql.pk          | string | 设置primary key,值为以','分隔的字段名称             |
|        | sql.primary_key | string | 同 sql.pk                                           |
|        | sql.index.*     | string | 普通索引,值为以','分隔的字段名称                    |
|        | sql.unique.*    | string | unique索引,值为以','分隔的字段名称                  |
|        | sql.engine      | string | mysql engine                                        |
|        | sql.ex          | bool   | 默认true, false: 不生成ex结构体和接口               |
|        | sql.upsert      | bool   | 默认true, false: 可以生成的情况下禁止生成upsert接口 |
|        | sql.update      | bool   | 默认true, false: 可以生成的情况下禁止生成update接口 |
| 字段级 |                 |        |                                                     |
|        | sql.pk          | bool   | 设置本字段是primary key.                            |
|        | sql.primary_key | bool   | 同 sql.pk                                           |
|        | sql.auto_incr   | bool   | 设置字段自增,仅能在一个int类型的字段上设置          |
|        | sql.type        | string | 设置mysql类型,会忽略 sql.size,sql.null              |
|        | sql.size        | int    | 对string类型设置长度,varchar(size)                  |
|        | sql.null        | bool   | 字段可以为null,默认所有字段NOT NULL                 |
|        | sql.custom      | bool   | 对本字段,自定义序列化和反序列化函数                 |

~sql.pk~ 优先使用消息级配置的字段列表数据.

关于索引,看下面具体章节的介绍.

生成代码中以下接口使用 sql.Stmt. 批量接口和其余接口都是拼接sql.
 - insert
 - update
 - upsert
 - find
 - delete


表自动同步:
#+begin_quote
生成代码默认会在服务启动时候,检测表和索引.
#+end_quote
 - 检测数据库内表是否存在,不存在则创建. 如果表已经存在,会检查字段,如果有新增字段,自动添加缺失的字段.
 - 检测数据库内表所关联的索引是否存在,不存在则创建.


只有设置了Primary Key字段, 才会生成update,upsert,find 相关方法.否则可以使用select配合where使用进行查询,使用insert 进行更新.
 
生成代码对外暴露了 ~*sqlx.DB~ 指针,可以自定义执行的sql.

生成代码还包含了一个简单的sql语句生成(会根据调用顺序生成sql语句,应该像正常写sql那样去调用),例:
#+begin_src go
  db_user.UserInfoNamedSQL(128).Insert().Uid().Email().Name().ToSQL() // insert user_info(`uid`,`email`,`name`) values(:uid,:email,:name)
	db_user.UserInfoNamedSQL(128).Delete().Email().And().Name().ToSQL() // delete from user_info where `email` = :email and `name` = :name
	db_user.UserInfoNamedSQL(128).Update().Name().Email().Where().Uid().ToSQL() // update user_info set `name`=:name,`email`=:email where `uid` = :uid
	db_user.UserInfoNamedSQL(128).Select().Uid().Name().Where().Uid().And().Email().Limit(10, 0).ToSQL() //select `uid`,`name` from user_info where `uid` = :uid and `email` = :email limit 10,0

  // 错误的示例(ERROR EXAMPLE):
  db_user.UserInfoNamedSQL(128).Update().Email().Where().And().Email().ToSQL() => update user_info set `email`=:email where  and `email` = :email
#+end_src

 
*** 环境变量
| 环境变量        | 默认值                       |                          |
|-----------------+------------------------------+--------------------------|
| WDB_SVC_PKG     | github.com/walleframe/svc_db | 不能为空,替换管理包      |
| WDB_OPCODE_PATH | pkg/dbop/                    | 生成的数据库操作代码目录 |
| WDB_CHARSET     | utf8mb4                      | 表和数据库的字符集       |
| WDB_COLLATE     | utf8mb4_general_ci           | 表和数据库               |

** 字段类型
| wproto类型  | sql类型         |
|-------------+-----------------|
| int8        | tinyint         |
| int16,int32 | int             |
| int64       | bigint          |
| uint64      | bigint unsigned |
| string      | varchar(64)     |
| []byte      | blob            |


除了上表的sql类型,还支持 ~timestamp~ 类型. 需要通过 ~sql.type~ 指定.

例:
#+begin_example
sql.type = "timestamp default current_timestamp on update current_timestamp"
sql.type = "timestamp default current_timestamp"
#+end_example

数组,字典,自定义类型 对应的sql类型都是 ~varchar(256)~. 可以通过 ~sql.size~ 修改长度. 默认使用json进行序列化和反序列化.

通过包内提供的字段级函数变量进行调整.

基础类型默认不提供序列化方法的修改.可以通过 ~sql.custom~ 选项,来生成修改方法.

** 示例
*** 用户信息表
表定义 
#+begin_src protobuf
sql.db = "db_user"; // 定义当前文件所有表是在'db_user'数据库

message user_info {
	sql.pk = "uid" // Primary Key 
	sql.unique.name = "name" // name字段做唯一索引
	sql.index.email = "email" // email字段做索引
	int64 uid = 1 {
		sql.auto_incr = true  // 自增
	};
	string name = 2 {
		sql.size = 128
	};
	string email = 3;
}
#+end_src

生成代码调用
#+begin_src go
  var (
	  user *dbop.UserInfo
	  users []*dbop.UserInfo
	  err error
    uid int64 = 1
	  res sql.Result
	)
  // 插入信息
  res, err = db_user.UserInfoOP().Insert(ctx, user)
  uid, err := res.LastInsertId() //
  // 更新
  res, err = db_user.UserInfoOP().Update(ctx, user)
  // merge
  res, err = db_user.UserInfoOP().Upsert(ctx, user)

  // 查找指定用户
	user, err = db_user.UserInfoOP().Find(ctx, uid)
  // 通过索引查找
  users, err = db_user.UserInfoOP().FindByIndexEmail(ctx, "xxx@xx.com", 5, 0) // limit 0,5

  // 自定义数据查询
  users,err = db_user.UserInfoOP().Select(ctx, nil) // 查询全部数据
  users,err = db_user.UserInfoOP().Select(ctx, db_user.UserInfoOP().Where(32).Uid().LessEqual(1000)) // 查询uid小于1000的数据
#+end_src
接口示例(Ex结构体内包含 ModifyStamp,CreateStamp.):
#+begin_src go
type UserInfoKey = int64

type UserInfoOperation interface {
	Insert(ctx context.Context, data *dbop.UserInfo) (res sql.Result, err error)
	InsertMany(ctx context.Context, datas []*dbop.UserInfo) (res sql.Result, err error)

	Update(ctx context.Context, data *dbop.UserInfo) (res sql.Result, err error)
	Upsert(ctx context.Context, data *dbop.UserInfo) (res sql.Result, err error)
	UpsertMany(ctx context.Context, datas []*dbop.UserInfo) (res sql.Result, err error)

	Find(ctx context.Context, uid int64) (data *dbop.UserInfo, err error)
	FindEx(ctx context.Context, uid int64) (data *dbop.UserInfoEx, err error)
	Delete(ctx context.Context, uid int64) (res sql.Result, err error)

	FindByKey(ctx context.Context, id UserInfoKey) (data *dbop.UserInfo, err error)
	FindExByKey(ctx context.Context, id UserInfoKey) (data *dbop.UserInfoEx, err error)
	DeleteByKey(ctx context.Context, id UserInfoKey) (res sql.Result, err error)

	FindByKeyArray(ctx context.Context, ids []UserInfoKey) (datas []*dbop.UserInfo, err error)
	FindExByKeyArray(ctx context.Context, ids []UserInfoKey) (datas []*dbop.UserInfoEx, err error)
	DeleteByKeyArray(ctx context.Context, ids []UserInfoKey) (res sql.Result, err error)

	FindByIndexEmail(ctx context.Context, email string, limit, offset int) (datas []*dbop.UserInfo, err error)
	FindExByIndexEmail(ctx context.Context, email string, limit, offset int) (datas []*dbop.UserInfoEx, err error)
	CountByIndexEmail(ctx context.Context, email string) (count int, err error)
	DeleteByIndexEmail(ctx context.Context, email string) (res sql.Result, err error)

	FindByIndexName(ctx context.Context, name string, limit, offset int) (datas []*dbop.UserInfo, err error)
	FindExByIndexName(ctx context.Context, name string, limit, offset int) (datas []*dbop.UserInfoEx, err error)
	CountByIndexName(ctx context.Context, name string) (count int, err error)
	DeleteByIndexName(ctx context.Context, name string) (res sql.Result, err error)

	Where(bufSize int) *UserInfoWhereStmt
	Select(ctx context.Context, where *UserInfoWhereStmt) (datas []*dbop.UserInfo, err error)
	SelectEx(ctx context.Context, where *UserInfoWhereStmt) (datas []*dbop.UserInfoEx, err error)
	Count(ctx context.Context, where *UserInfoWhereStmt) (count int, err error)

	DeleteMany(ctx context.Context, where *UserInfoWhereStmt) (res sql.Result, err error)

	RangeAll(ctx context.Context, where *UserInfoWhereStmt, f func(ctx context.Context, row *dbop.UserInfo) bool) error
	RangeAllEx(ctx context.Context, where *UserInfoWhereStmt, f func(ctx context.Context, row *dbop.UserInfoEx) bool) error
	AllData(ctx context.Context, where *UserInfoWhereStmt) (datas []*dbop.UserInfo, err error)
	AllDataEx(ctx context.Context, where *UserInfoWhereStmt) (datas []*dbop.UserInfoEx, err error)

	// use for custom named sql
	DB() *sqlx.DB
}

// 数据库操作接口
var UserInfoOP = func() UserInfoOperation

// 自定义sql语句生成. 注意: 仅辅助生成sql语句.
func UserInfoNamedSQL(bufSize int) *UserInfoSQLWriter 

// 同步表字段,索引到数据库.(表不存在创建,已经存在,对比列,如果列不存在则创建,已经存在列,不会检查类型,需要业务方保证)
func SyncUserInfoDBTable(ctx context.Context, db *sqlx.DB) (err error)

// 结构体到Primary Key 转换
func UserInfoToPrimaryKeys(rows []*dbop.UserInfo) (ids []UserInfoKey)
func UserInfoExToPrimaryKeysEx(rows []*dbop.UserInfoEx) (ids []UserInfoKey)

// 手动创建
func NewUserInfoOperation(db *sqlx.DB) (_ *xUserInfoOperation, err error) 
#+end_src
*** 好友列表
#+begin_src protobuf
message user_friend {
	sql.pk = "uid,fid" // Primary Key 是 uid,fid 
	sql.index.uid = "uid" // 使用uid做索引 
	int64 uid = 1 ;
	int64 fid = 2 ;
	int8 state = 3;
}
#+end_src
生成接口 
#+begin_src go
type UserFriendKey struct {
	Uid int64
	Fid int64
}

type UserFriendOperation interface {
	Insert(ctx context.Context, data *dbop.UserFriend) (res sql.Result, err error)
	InsertMany(ctx context.Context, datas []*dbop.UserFriend) (res sql.Result, err error)

	Update(ctx context.Context, data *dbop.UserFriend) (res sql.Result, err error)
	Upsert(ctx context.Context, data *dbop.UserFriend) (res sql.Result, err error)
	UpsertMany(ctx context.Context, datas []*dbop.UserFriend) (res sql.Result, err error)

	Find(ctx context.Context, uid int64, fid int64) (data *dbop.UserFriend, err error)
	FindEx(ctx context.Context, uid int64, fid int64) (data *dbop.UserFriendEx, err error)
	Delete(ctx context.Context, uid int64, fid int64) (res sql.Result, err error)

	FindByKey(ctx context.Context, id UserFriendKey) (data *dbop.UserFriend, err error)
	FindExByKey(ctx context.Context, id UserFriendKey) (data *dbop.UserFriendEx, err error)
	DeleteByKey(ctx context.Context, id UserFriendKey) (res sql.Result, err error)

	FindByKeyArray(ctx context.Context, ids []UserFriendKey) (datas []*dbop.UserFriend, err error)
	FindExByKeyArray(ctx context.Context, ids []UserFriendKey) (datas []*dbop.UserFriendEx, err error)
	DeleteByKeyArray(ctx context.Context, ids []UserFriendKey) (res sql.Result, err error)

	FindByIndexUid(ctx context.Context, uid int64, limit, offset int) (datas []*dbop.UserFriend, err error)
	FindExByIndexUid(ctx context.Context, uid int64, limit, offset int) (datas []*dbop.UserFriendEx, err error)
	CountByIndexUid(ctx context.Context, uid int64) (count int, err error)
	DeleteByIndexUid(ctx context.Context, uid int64) (res sql.Result, err error)

	Where(bufSize int) *UserFriendWhereStmt
	Select(ctx context.Context, where *UserFriendWhereStmt) (datas []*dbop.UserFriend, err error)
	SelectEx(ctx context.Context, where *UserFriendWhereStmt) (datas []*dbop.UserFriendEx, err error)
	Count(ctx context.Context, where *UserFriendWhereStmt) (count int, err error)

	DeleteMany(ctx context.Context, where *UserFriendWhereStmt) (res sql.Result, err error)

	RangeAll(ctx context.Context, where *UserFriendWhereStmt, f func(ctx context.Context, row *dbop.UserFriend) bool) error
	RangeAllEx(ctx context.Context, where *UserFriendWhereStmt, f func(ctx context.Context, row *dbop.UserFriendEx) bool) error
	AllData(ctx context.Context, where *UserFriendWhereStmt) (datas []*dbop.UserFriend, err error)
	AllDataEx(ctx context.Context, where *UserFriendWhereStmt) (datas []*dbop.UserFriendEx, err error)

	// use for custom named sql
	DB() *sqlx.DB
}
#+end_src
 
*** 操作日志
#+begin_src protobuf
message user_xx_log {
	sql.engine = "MyISAM"
	sql.ex = false // 不生成扩展结构体
	sql.update = false // 不生成update方法
	sql.upsert = false // 不生成upsret方法
	int64 id = 1 {
		sql.auto_incr = true
      sql.pk = true
	}
	int64 uid = 2;
	int64 xx = 3;
	string x2 = 4;
	int64 create_stamp = 5{ // 记录写入时间
		sql.type = "timestamp default current_timestamp"
	}
}
#+end_src

#+begin_src go
type UserXxLogKey = int64

type UserXxLogOperation interface {
	Insert(ctx context.Context, data *dbop.UserXxLog) (res sql.Result, err error)
	InsertMany(ctx context.Context, datas []*dbop.UserXxLog) (res sql.Result, err error)

	Find(ctx context.Context, id int64) (data *dbop.UserXxLog, err error)
	Delete(ctx context.Context, id int64) (res sql.Result, err error)

	FindByKey(ctx context.Context, id UserXxLogKey) (data *dbop.UserXxLog, err error)
	DeleteByKey(ctx context.Context, id UserXxLogKey) (res sql.Result, err error)

	FindByKeyArray(ctx context.Context, ids []UserXxLogKey) (datas []*dbop.UserXxLog, err error)
	DeleteByKeyArray(ctx context.Context, ids []UserXxLogKey) (res sql.Result, err error)

	Where(bufSize int) *UserXxLogWhereStmt
	Select(ctx context.Context, where *UserXxLogWhereStmt) (datas []*dbop.UserXxLog, err error)
	Count(ctx context.Context, where *UserXxLogWhereStmt) (count int, err error)

	DeleteMany(ctx context.Context, where *UserXxLogWhereStmt) (res sql.Result, err error)

	RangeAll(ctx context.Context, where *UserXxLogWhereStmt, f func(ctx context.Context, row *dbop.UserXxLog) bool) error
	AllData(ctx context.Context, where *UserXxLogWhereStmt) (datas []*dbop.UserXxLog, err error)

	// use for custom named sql
	DB() *sqlx.DB
}
#+end_src

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

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