内容简介:本文是来自于我在使用 Drone 过程中遇到一个问题的排查,然后延伸出来的一篇 Drone 源码分析,希望能对你有所帮助。我增加 commit 信息为中文后提交推送到 gitlab 上,结果 Drone 任务没有触发执行为什么没有自动触发构建呢?
本文是来自于我在使用 Drone 过程中遇到一个问题的排查,然后延伸出来的一篇 Drone 源码分析,希望能对你有所帮助。
缘由
我增加 commit 信息为中文后提交推送到 gitlab 上,结果 Drone 任务没有触发执行
为什么没有自动触发构建呢?
难道是 Webhook 没有调用?遇到问题,肯定最好的方式是查看日志了。
time="2018-09-05T02:01:52Z" level=error msg="failure to save commit for developer-learning/gcd. meddler.Insert: DB error in Exec: Error 1366: Incorrect string value: '\\xE6\\x8F\\x90\\xE4\\xBA\\xA4...' for column 'build_message' at row 1"
从日志我们可以很明显的看到错误信息 meddler.Insert: DB error in Exec: Error 1366: Incorrect string value
,典型的是数据库字符集问题。
commit message 为中文时,无法插入到 MySQL 数据库,然后我去查看 MySQL 的数据库表:
CREATE TABLE `builds` ( `build_id` int(11) NOT NULL AUTO_INCREMENT, `build_repo_id` int(11) DEFAULT NULL, `build_number` int(11) DEFAULT NULL, `build_event` varchar(500) DEFAULT NULL, `build_status` varchar(500) DEFAULT NULL, `build_enqueued` int(11) DEFAULT NULL, `build_created` int(11) DEFAULT NULL, `build_started` int(11) DEFAULT NULL, `build_finished` int(11) DEFAULT NULL, `build_commit` varchar(500) DEFAULT NULL, `build_branch` varchar(500) DEFAULT NULL, `build_ref` varchar(500) DEFAULT NULL, `build_refspec` varchar(1000) DEFAULT NULL, `build_remote` varchar(500) DEFAULT NULL, `build_title` varchar(1000) DEFAULT NULL, `build_message` varchar(2000) DEFAULT NULL, `build_timestamp` int(11) DEFAULT NULL, `build_author` varchar(500) DEFAULT NULL, `build_avatar` varchar(1000) DEFAULT NULL, `build_email` varchar(500) DEFAULT NULL, `build_link` varchar(1000) DEFAULT NULL, `build_deploy` varchar(500) DEFAULT NULL, `build_signed` tinyint(1) DEFAULT NULL, `build_verified` tinyint(1) DEFAULT NULL, `build_parent` int(11) DEFAULT NULL, `build_error` varchar(500) DEFAULT NULL, `build_reviewer` varchar(250) DEFAULT NULL, `build_reviewed` int(11) DEFAULT NULL, `build_sender` varchar(250) DEFAULT NULL, `build_config_id` int(11) DEFAULT NULL, PRIMARY KEY (`build_id`), UNIQUE KEY `build_number` (`build_number`,`build_repo_id`), KEY `ix_build_repo` (`build_repo_id`), KEY `ix_build_author` (`build_author`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
发现 build_message
表的字符集是 latin1
。
有关 MySQL 字符集
源码分析
server.go
中调用 setupStore
:
// cmd/drone-serverserver.go store_ := setupStore(c)
// setup.go func setupStore(c *cli.Context) store.Store { return datastore.New( c.String("driver"), c.String("datasource"), ) }
// store/datastore/store.go // New creates a database connection for the given driver and datasource // and returns a new Store. func New(driver, config string) store.Store { return &datastore{ DB: open(driver, config), driver: driver, config: config, } } ... // open opens a new database connection with the specified // driver and connection string and returns a store. func open(driver, config string) *sql.DB { db, err := sql.Open(driver, config) if err != nil { logrus.Errorln(err) logrus.Fatalln("database connection failed") } if driver == "mysql" { // per issue https://github.com/go-sql-driver/mysql/issues/257 db.SetMaxIdleConns(0) } setupMeddler(driver) if err := pingDatabase(db); err != nil { logrus.Errorln(err) logrus.Fatalln("database ping attempts failed") } if err := setupDatabase(driver, db); err != nil { logrus.Errorln(err) logrus.Fatalln("migration failed") } return db } ... // helper function to setup the databsae by performing // automated database migration steps. func setupDatabase(driver string, db *sql.DB) error { return ddl.Migrate(driver, db) }
// store/datastore/ddl/migrate.go // Migrate performs the database migration. If the migration fails // and error is returned. func Migrate(driver string, db *sql.DB) error { if err := checkPriorMigration(db); err != nil { return err } switch driver { case DriverMysql: return mysql.Migrate(db) case DriverPostgres: return postgres.Migrate(db) default: return sqlite.Migrate(db) } }
// store/datastore/ddl/mysql/ddl_gen.go // Migrate performs the database migration. If the migration fails // and error is returned. func Migrate(db *sql.DB) error { if err := createTable(db); err != nil { return err } completed, err := selectCompleted(db) if err != nil && err != sql.ErrNoRows { return err } for _, migration := range migrations { if _, ok := completed[migration.name]; ok { continue } if _, err := db.Exec(migration.stmt); err != nil { return err } if err := insertMigration(db, migration.name); err != nil { return err } } return nil }
从 migrations
表中查询到数据并存放到一个 map 中,然后用这个 map 来检查清单语句是否存在,也就是检查表是否已经存在,存在即跳出,继续 for 循环,否则执行 SQL 语句,然后将其插入 migrations
表中。
Drone 支持数据库:
- SQLite3
- MySQL
- PostgreSQL
思考
database/sql
参考资料
参考资料
茶歇驿站
一个可以让你停下来看一看,在茶歇之余给你帮助的小站,这里的内容主要是后端技术,个人管理,团队管理,以及其他个人杂想。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- nodejs源码—初始化
- Kratos 初始化源码分析
- Mybatis源码解读-初始化过程详解
- Vue源码探究-类初始化函数详情
- Spring MVC 源码解析(二)— 容器初始化
- Swoole 源码分析——Server 模块之初始化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JSON 在线解析
在线 JSON 格式化工具
RGB转16进制工具
RGB HEX 互转工具