gotool

介绍

golang 工具集

软件架构

软件架构说明

安装教程

  1. xxxx
  2. xxxx
  3. xxxx

使用说明

  1. xxxx
  2. xxxx
  3. xxxx

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request

特技

  1. 使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md
  2. Gitee 官方博客 blog.gitee.com
  3. 你可以 https://gitee.com/explore 这个地址来了解 Gitee 上的优秀开源项目
  4. GVP 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
  5. Gitee 官方提供的使用手册 https://gitee.com/help
  6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 https://gitee.com/gitee-stars/

fork && import

在项目根目录下运行如下命令,版本号可以根据实际情况修改。在项目根目录下运行它就是给主 mod 添加 replace,可以对依赖的 mod 也起作用 go mod edit -replace github.com/mojocn/base64Captcha@v1.3.1=github.com/myzero1/fork2base64Captcha@z1.1.1

给 mod 添加新的依赖使用 go get github.com/mojocn/base64Captcha@v1.3.1

go modules的replace使用, 解决fork的项目import问题
寒枫Alex · 2019-08-23 15:32:57 · 777 次点击 · 预计阅读时间 2 分钟 · 17分钟之前 开始浏览
这是一个创建于 2019-08-23 15:32:57 的文章,其中的信息可能已经有所发展或是发生改变。
探究问题所在
如果直接第三方依赖, golang是可以满足使用的. 但如果我们需要修复第三方依赖的bug, 抑或为第三方依赖添加新feature, 那将是非常反常识的.
在其他语言中, 往往是可以import相对路径的包, 因此改动第三方依赖非常简单, 只需要fork一下, 然后改动相关代码, 然后将自己项目的依赖定位到新的地址即可.
但是在golang中不是这样, golang中, 只允许绝对路径, 所有的import, 都将唯一定位到同一个固定的地方, 下面举例.
如果我们fork了我们的一个依赖的仓库, 它的结构可能如下:

forked-repo
    |--a.go # import了some-dir
    |--b.go # import了some-dir
    |--some-dir # 子module
        |--c.go
        |--d.go
我们可以将自己的项目的依赖地址定位到forked-repo上, 这样我们对a.go和b.go的改动, 是可以生效的, 这也很符合我们的常识.
但如果我们需要改动c.go, 那会发现, 我们的改动并不会生效, 因为a.goimport的some-dir, 地址实际上是github.com/源地址/xxxx, 我们fork后的地址是github.com/fork地址/xxx. 这样, 子module依旧是使用原仓库的, 这就是问题所在.

解决方案
1. 替换依赖地址
直接替换所有的依赖地址, 可以通过sed命令或者其他方法. 如果你打算长期依赖于fork后的仓库, 且需要改动的地方不多的时候, 可以考虑这种方式.
但如果你考虑提交pull request的话, 那这种方式无疑很麻烦.

2. 通过go modules的replace
go modules的replace命令一般而言, 是最佳的解决方案. 如果你在使用go modules, 可以考虑这种方式.

官方对replace命令的描述:

replace指令在顶级go.mod中为实际用于满足go源文件或go.mod文件中的依赖项的内容提供附加控制,而在building时忽略除主模块以外的模块中的replace指令.
简而言之就是:

在项目的go.mod中, 使用replace命令的话, 可以对import路径进行替换. 也就是可以达到, 我们import的是a, 但在构建的时候, 实际使用的是b.
可以replace是成VCS(github或者其他地方), 或者文件系统路径(可以是绝对路径, 也可以是相对于项目根目录的相对路径). 使用文件系统路径这种, 在开发调试的使用, 非常有用.
最顶层go.mod的replace命令, 将影响到自身, 以及自身的所有依赖. 也就是可以间接改变依赖的项目的import. 这样我们在fork的项目的import, 不用在fork项目里面的go.mod进行replace, 直接在使用的项目里replace即可.
使用方式
直接编辑go.mod:

module nt-pdf-generator

go 1.12

require (
    github.com/xxx/abc v0.2.0 # replace的依赖, 必须要require
)

replace github.com/xxx/abc => ../github.com/hanFengSan/abc # 文件路径不需要附带版本信息
然后运行一下:

go mod tidy
大功告成.

z1tryout

试用 设计逻辑

1判断运行程序的机器是不是虚拟机
2获取cupid
3向gitee.com发送请求
4获取请求中的时间戳和返回的数据
5若返回的数据中的过期时间比请求中的时间戳小就通过
6没cupid对应一个文件,文件中就只有一个过期时间     如 cupid  > 2021-01-12 12:13:14

z1log

日志 设计逻辑
https://www.liuvv.com/p/5d303099.html 

1. 基于 https://github.com/uber-go/zap
2. 开箱即用
3. 滚动日志文件
4. 添加bufer
5. 不用于z1err中
6. SetLog(Filename string,istimestrap,MaxSize,MaxBackups,MaxAge,Compress,AddLogBuffer int);istimestrap == 1 使用时间戳否则使用时间字符串;Compress == 0    不压缩,其它都压缩;AddLogBuffer == 1 日志输出到缓存中,之后可以充缓存中读取日志数据;Filename == ""   不输出到文件中
7. DefultLog() 恢复默认配置,默认日志只打印到控制台上

z1cnf

配置 设计逻辑
https://www.liuvv.com/p/e2f28eb4.html

1. 基于 github.com/spf13/viper
2. 开箱即用
3. 测试动态更新,加上 Z1viper.WatchConfig()  使用 z1cnf.Z1viper.GetString(`z1cnf`) 就可也拉到最新的值了
4. z1cnf.Init(z1cnf.JSON, `config/config.yaml`, `{"contentType":"json","name":"张三","年龄":18}`)
5. 格式转换 func Convert(sourceType, sourceContent, targetType string) (targetContent string)

logs

  1. 预发布 z1crypto 和 z1captcha at 2020/11/30 14:33:33
  2. 预发布 z1struct at 2020/12/1 11:55:33
  3. 预发布 z1info at 2021/01/05 13:18:33 封装 build info
  4. 预发布 z1cnf 和 z1log 2022/01/28 10:32:00
  5. 预发布 z1auth 2023/04/20 10:32:00
  6. 预发布 z1mongo 和 z1db 2023/05/36 15:20 v0.9.0

参考资料

  • z1mongodb
// https://blog.csdn.net/jacky128256/article/details/99726666
// http://www.zzvips.com/article/172678.html
// https://blog.csdn.net/liboshi123/article/details/125839950
// https://cloud.tencent.com/developer/article/1702760
// https://cloud.tencent.com/developer/article/2245003
// https://blog.csdn.net/ezreal_pan/article/details/116062190
// https://blog.csdn.net/qq_51657072/article/details/125497153
// https://blog.csdn.net/LightUpHeaven/article/details/82663146
// https://blog.csdn.net/ezreal_pan/article/details/116062190
// https://blog.csdn.net/qq_51657072/article/details/125497153
// https://blog.csdn.net/LightUpHeaven/article/details/82663146

sqlparse
// https://github.com/blastrain/vitess-sqlparser/issues?q=join
// https://github.com/xwb1989/sqlparser/issues/46
// https://github.com/pingcap/tidb/tree/master/parser/mysql
// https://github.com/z1-mirror/sql2mongo

sql2mongo支持的sql类型

INSERT INTO role (name, des, CreatedAt) VALUES ('z1', 'myzero1', 1684654029),('z12', 'myzero12',1684654033)DELETE FROM user WHERE name = 'z1'DROP TABLE userSELECT user.username,user.id FROM user WHERE username LIKE "myzero1%"SELECT user.username,role.des FROM user JOIN role ON user.rid=role.id WHERE user.username LIKE "myzero1%"SELECT user.username,role.des FROM user_role JOIN role ON user_role.rid=role.id JOIN role ON user_role.uid=user.id WHERE user.username LIKE "myzero1%"

z1db使用gorm操作mongodb数据库的方法列表

1.  bash z1db/scripts/z1db-install.sh 安装 z1db
2.  bash z1db/scripts/z1sql2grom.sh 把sql转为struct,包含gorm、json、bson标签和DBType实现
安装说明:使用z1db前需要先运行go\pkg\mod\gitee.com\myzero1\gotool@v0.9.0\z1db.sh脚本替换grom的包,否则mongodb无效
需要使用mongdb,需要让对应的model实现DBType方法,请参考MongoUser   go\pkg\mod\gitee.com\myzero1\gotool@v0.9.0\z1db\model.go

详情参考 go\pkg\mod\gitee.com\myzero1\gotool@v0.9.0\test\z1db_test.go

  • create
实例:
		user := z1db.MongoUser{
			Username: `gorm_username`,
			Email:    `gorm_email@qq.com`,
		}
		tx := db.Model(&z1db.MongoUser{}).Create(&user)
		// tx := db.Create(&user)
		if tx.Error != nil {
			t.Error(tx.Error)
		} else {
			t.Log(`----RowsAffected--create--1---`, tx.RowsAffected)
		}

对应sql:
INSERT INTO `mongo_users` (
	`created_at`,
	`updated_at`,
	`deleted_at`,
	`username`,
	`email`,
	`mobile_phone`,
	`avatar`,
	`password`,
	`api_token`,
	`status`,
	`rid`
)
VALUES
	(
		1684986904,
		1684986904,
		NULL,
		'gorm_username',
		'gorm_email@qq.com',
		'',
		'',
		'',
		'',
		1,
		1
	)

说明:

  • delete
实例:
		tx := db.Model(&z1db.MongoUser{}).Where("username = ?", `gorm_username2`).Delete(&z1db.MongoUser{})
		// tx := db.Where("username = ?", `gorm_username2`).Delete(&z1db.MongoUser{})

		if tx.Error != nil {
			t.Error(tx.Error)
		} else {
			t.Log(`----RowsAffected--Delete-----`, tx.RowsAffected)
		}

对应sql:
UPDATE `mongo_users`
SET `deleted_at` = '2023-05-25 11:55:04.669'
WHERE
	username = 'gorm_username2'
AND `mongo_users`.`deleted_at` IS NULL

说明:

  • update
实例:
		tx := db.Model(&z1db.MongoUser{}).Where(`username=?`, `gorm_username`).Updates(z1db.MongoUser{Username: `gorm_username-updated`})

		if tx.Error != nil {
			t.Error(tx.Error)
		} else {
			t.Log(`----RowsAffected--update-----`, tx.RowsAffected)
		}

对应sql:
UPDATE `mongo_users`
SET `updated_at` = 1684986904,
 `username` = 'gorm_username-updated'
WHERE
	username = 'gorm_username'
AND `mongo_users`.`deleted_at` IS NULL

说明:

  • select one
实例:
		user := z1db.MongoUser{}
		tx := db.Model(&z1db.MongoUser{}).Where("username = ?", `gorm_username-updated`).Find(&user)
		// tx := db.Model(&z1db.MongoUser{}).Select("username").Where("username = ?", `gorm_username-updated`).Find(&user)

		if tx.Error != nil {
			t.Error(tx.Error)
		} else {
			t.Log(`----RowsAffected---Select----one-----`, tx.RowsAffected)
			t.Log(`----Result---Select-----one----`, user)
		}

对应sql:
SELECT
	`username`
FROM
	`mongo_users`
WHERE
	username = 'gorm_username'
AND `mongo_users`.`deleted_at` IS NULL
LIMIT 1

说明:
user 必须声明为实例(user := z1db.MongoUser{}),不能只声明不实例(var user z1db.MongoUser)
  • select many
实例:
		users := []z1db.MongoUser{
			z1db.MongoUser{},
		}

		tx := db.Model(&z1db.MongoUser{}).Where("username like ?", `gorm_username%`).Offset(1).Limit(20).Find(&users)
		// tx := db.Model(&z1db.MongoUser{}).Select("username").Where("username like ?", `gorm_username-updated`).Offset(1).Limit(20).Find(&users)

		if tx.Error != nil {
			t.Error(tx.Error)
		} else {
			t.Log(`----RowsAffected---Select---many-----`, tx.RowsAffected)
			t.Log(`----Result---Select----many----`, users)
		}

对应sql:
SELECT
	`username`
FROM
	`mongo_users`
WHERE
	username = 'gorm_username'
AND `mongo_users`.`deleted_at` IS NULL

说明:
users 必须声明为实例(users := []z1db.MongoUser{z1db.MongoUser{}}),不能只声明不实例(var users []z1db.MongoUser)
  • select count
实例:
		var count int64

		tx := db.Model(&z1db.MongoUser{}).Where("username like ?", `gorm_username%`).Count(&count)
		// tx := db.Model(&z1db.MongoUser{}).Select("username").Where("username like ?", `gorm_username%`).Count(&count)

		if tx.Error != nil {
			t.Error(tx.Error)
		} else {
			t.Log(`----RowsAffected---Select---count-----`, tx.RowsAffected)
			t.Log(`----RowsAffected---Select---count-----`, count)
		}

对应sql:
SELECT
	count(*)
FROM
	`mongo_users`
WHERE
	(
		username LIKE 'gorm_username%'
		OR created_at > 0
	)
AND `mongo_users`.`deleted_at` IS NULL

说明: