Drone 源码分析之数据库初始化

栏目: 编程工具 · 发布时间: 6年前

内容简介:本文是来自于我在使用 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

参考资料

  1. default some columns to utf8mb4 #2144

参考资料

茶歇驿站

一个可以让你停下来看一看,在茶歇之余给你帮助的小站,这里的内容主要是后端技术,个人管理,团队管理,以及其他个人杂想。

Drone 源码分析之数据库初始化


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法基础

算法基础

布拉萨德 / 邱仲潘 / 清华大学出版社 / 2005-7 / 49.00元

本书是关于算法导论的经典教材,书中包括大量例题解答与命题证明。本书是按照算法类型而不是按照应用类型对算法进行介绍,以其清晰的概念讲解赢得专家们的广泛赞誉。本书适用对象广泛。对于学习算法设计与分析的本科生和研究生,本书是优透选教材。对于从事算法计算研究和工程应用的科研人员和工程技术人员,本书也是一本优秀的基础性读物。一起来看看 《算法基础》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具