内容简介:本文是来自于我在使用 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 模块之初始化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pro Django
Marty Alchin / Apress / 2008-11-24 / USD 49.99
Django is the leading Python web application development framework. Learn how to leverage the Django web framework to its full potential in this advanced tutorial and reference. Endorsed by Django, Pr......一起来看看 《Pro Django》 这本书的介绍吧!