自己创造的 TML:Test Markup Language

我之前在项目开发中遇到一个痛点,比如我在实现 SQL 解析的若干功能,需要写大量的单元测试,测试中需要指定 SQL 字符串,本着代码与数据分离的思想,这些单测的 SQL 和其它相关的变量数据,应该单独存储在代码外的某个地方。

开发中常见的一些配置文件格式,比如 json、yaml、toml 等等,都是有特定语法规则,而 SQL 字符串中各种可能有的字符都有,容易出现格式问题,比如换行符,单双引号,及其它问题。编写这些配置文件就显得相当繁琐而且易出错。

于是我就产生了一个想法,自己编写一种特殊的配置文件格式,让写 SQL 字符串变得直观、简单。我把我设计的这种简单文件格式称之为:TML,全称为 Test Markup Language。

tml 标记语言

tml 全称 Testing Markup Language,是用于存储单元测试中变量的文本文件。格式简单

结构体定义

目前仅支持以下几种字段数据类型

  • int
  • string
  • []string
  • map[string]string

使用 tml 来标记 struct 中的字段。如

type tmlData struct {
	Sql  string            `tml:"sql"`
	Deps string            `tml:"deps"`
	Meta map[string]string `tml:"meta"`
}

按上面定义,遇到 sql 变量,会按字符串提取。meta 变量按字典规则提取。

解析示例

r, err := os.Open(path)
if err != nil {
    t.Fatalf("open %s failed, err: %s", path, err)
}
defer r.Close()

d := tml.NewDecoder(r)
var data tmlData
if err = d.Decode(&data); err != nil {
    t.Fatalf("parse tml file %s failed, err: %s", path, err)
}

tml 文件语法

变量赋值

行开始,连接两个 @ ,再接着变量名,@@ 前面不能有空白字符

例如

@@ sql
 select from
    table aaa

表示下面行所有字符串,赋值给 sql 变量

字符串变量会去掉前后空白符。

注释

行开始,连续两个 # 表示注释行。# 前不能有空白字符。

数组变量

只支持字符串数组

数组使用逗号隔开,不考虑数组值当中含有逗号的情况

## 数组示例
@@ arr1
field1, field2, 333

字典变量

只支持 map[string]string 类型。

格式为字典 key + 冒号 + value。

示例

## 字典示例
@@ map1
user: name
pass: word

tml 文件示例

对于定义结构体

struct {
		Sql   string            `tml:"sql"`
		Users []string          `tml:"users"`
		Ages  map[string]string `tml:"ages"`
		Count int               `tml:"count"`
	}

相应的 tml 文件内容如下

// 文件开始可以写一些文本,会被忽略

@@ sql
select * 
  from table a 
  union join b 

## 这是一行注释,注释开头必须是 ## ,# 前不能有空格

@@ users
## 中间还可以有注释
kyle, alice, john

@@ ages
kyle: 22
alice: 23
## 中间还可以有注释
john: 29

@@ count
## comment
    7899

另一个我实际使用到的 tml 文件内容:

## 修复匿名字段,这里的 target_table.$1 可以与 meta 中的字段映射上,也就是 $2 会转换成 target_table 的第 2 个字段

@@ sql

INSERT INTO
    TABLE target_table
SELECT
    col1,
    (
        SELECT
            MAX(col2)
        FROM
            another_table
        WHERE
            col1 = source_table.col1
    )
FROM
    source_table;


@@ dialect 

hive

@@ meta

target_table: col1, fixed_col2

@@ bags 

1

@@ not_keep_query

1

@@ deps

source_table.col1 -> target_table.col1
another_table.col2 -> target_table.fixed_col2

tml 解析源码

代码量不多,我直接放在了 Github 上: https://gist.github.com/kylege/e4ddaa1c38818083c7244b229adde9cc

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注