wecisecode 15 hours ago
parent
commit
80420fa423
2 changed files with 37 additions and 4 deletions
  1. 17 4
      odbctest/odbcmql/mql_run.go
  2. 20 0
      odbctest/odbcmql/mql_run_file.go

+ 17 - 4
odbctest/odbcmql/mql_run.go

@@ -121,6 +121,7 @@ func Run(t *testing.T) {
 usage: mql path [options] -- mqlstatement
 usage: mql path [options] -- mqlstatement
   path                指定mql文件所在路径,通配符 ** 表示任意字符,* 表示除分隔符以外的任意字符,. 表示递归当前目录下的所有子目录
   path                指定mql文件所在路径,通配符 ** 表示任意字符,* 表示除分隔符以外的任意字符,. 表示递归当前目录下的所有子目录
                       为避免 shell 自动将 * 转换为文件名列表,可以将指定的 path 用引号包含
                       为避免 shell 自动将 * 转换为文件名列表,可以将指定的 path 用引号包含
+  path#N              仅执行指定 mql 文件中的第 N 条语句,N 为自然数
   mqlstatement        指定要执行的 mql 语句,支持多条语句,语句之间用分号 ; 分隔
   mqlstatement        指定要执行的 mql 语句,支持多条语句,语句之间用分号 ; 分隔
 
 
 options:
 options:
@@ -240,6 +241,17 @@ mql语句扩展说明:
 		return
 		return
 	}
 	}
 
 
+	// 解析 path#N 语法:仅执行指定 mql 文件中的第 N 条语句
+	stmtfilter := map[string]int{}
+	for i, p := range spath {
+		if idx := strings.LastIndexByte(p, '#'); idx > 0 && idx < len(p)-1 {
+			if n := cast.ToInt(p[idx+1:]); n > 0 && cast.ToString(n) == p[idx+1:] {
+				stmtfilter[filepath.Clean(p[:idx])] = n
+				spath[i] = p[:idx]
+			}
+		}
+	}
+
 	// 文件名以数字开头
 	// 文件名以数字开头
 	fnmatch := mcfg.CommandArgs.GetString("match", `^\d+.*`)
 	fnmatch := mcfg.CommandArgs.GetString("match", `^\d+.*`)
 	fw, err := filewalker.NewFileWalker(spath, fnmatch) // orderby: dirfirst, filefirst, fullpath
 	fw, err := filewalker.NewFileWalker(spath, fnmatch) // orderby: dirfirst, filefirst, fullpath
@@ -309,7 +321,7 @@ mql语句扩展说明:
 	logger.Info("共找到", len(fns), "个文件")
 	logger.Info("共找到", len(fns), "个文件")
 
 
 	// 顺序读取当前目录下文件名为数字开头的文件,执行其中的mql
 	// 顺序读取当前目录下文件名为数字开头的文件,执行其中的mql
-	(&MQLTest{}).Run(t, fw)
+	(&MQLTest{stmtfilter: stmtfilter}).Run(t, fw)
 	// 等待延迟显示信息输出
 	// 等待延迟显示信息输出
 	// time.Sleep(1 * time.Second)
 	// time.Sleep(1 * time.Second)
 	logger.Info("关闭与服务器的连接")
 	logger.Info("关闭与服务器的连接")
@@ -339,9 +351,10 @@ var commentexprs_2 = regexp.MustCompile(`(?ms)(?:^|\n)\-\-[^\n]*(?:\n|$)`)
 var commentexprs_3 = regexp.MustCompile(`(?ms)(?:^|\n)//[^\n]*(?:\n|$)`)
 var commentexprs_3 = regexp.MustCompile(`(?ms)(?:^|\n)//[^\n]*(?:\n|$)`)
 
 
 type MQLTest struct {
 type MQLTest struct {
-	t         *testing.T
-	fw        *filewalker.FileWalker
-	scopevars *ScopeVars
+	t          *testing.T
+	fw         *filewalker.FileWalker
+	scopevars  *ScopeVars
+	stmtfilter map[string]int // 文件路径(经 filepath.Clean) -> 语句序号(从1开始),仅执行该语句
 }
 }
 
 
 type ScopeVars struct {
 type ScopeVars struct {

+ 20 - 0
odbctest/odbcmql/mql_run_file.go

@@ -33,17 +33,30 @@ func (mt *MQLTest) RunFile(t *testing.T, ctx context.Context,
 	var multilines *MQLRequest
 	var multilines *MQLRequest
 	mqs := spliter.NewMQLSpliter(bufio.NewReader(f))
 	mqs := spliter.NewMQLSpliter(bufio.NewReader(f))
 	rtinfo := time.Now().Add(5 * time.Second)
 	rtinfo := time.Now().Add(5 * time.Second)
+	filterN := mt.stmtfilter[filepath.Clean(ffpath)]
+	if filterN > 0 {
+		logger.Info("仅执行文件 ", ffpath, " 第 ", filterN, " 条语句")
+	}
+	stmtidx := 0
+	skipmultiline := false
 	for {
 	for {
 		mql, fromline, toline, fromchar, tochar, hasnext, _ := mqs.NextMQL()
 		mql, fromline, toline, fromchar, tochar, hasnext, _ := mqs.NextMQL()
 		if !hasnext {
 		if !hasnext {
 			break
 			break
 		}
 		}
+		stmtidx++
 		if time.Now().After(rtinfo) {
 		if time.Now().After(rtinfo) {
 			logger.Info("reading bigfile ", toline, " lines")
 			logger.Info("reading bigfile ", toline, " lines")
 			rtinfo = time.Now().Add(5 * time.Second)
 			rtinfo = time.Now().Add(5 * time.Second)
 		}
 		}
 		// 去掉注释
 		// 去掉注释
 		clean_mql := strings.Join(spliter.MQLSplitClean(mql), ";")
 		clean_mql := strings.Join(spliter.MQLSplitClean(mql), ";")
+		if skipmultiline {
+			if strings.TrimSpace(clean_mql) == "multilines end" {
+				skipmultiline = false
+			}
+			continue
+		}
 		if multilines != nil {
 		if multilines != nil {
 			// 多条语句处理
 			// 多条语句处理
 			if strings.TrimSpace(clean_mql) == "multilines end" {
 			if strings.TrimSpace(clean_mql) == "multilines end" {
@@ -72,6 +85,10 @@ func (mt *MQLTest) RunFile(t *testing.T, ctx context.Context,
 				multilines.Tochar = tochar
 				multilines.Tochar = tochar
 			}
 			}
 		} else if strings.TrimSpace(clean_mql) == "multilines begin" {
 		} else if strings.TrimSpace(clean_mql) == "multilines begin" {
+			if filterN > 0 && stmtidx != filterN {
+				skipmultiline = true
+				continue
+			}
 			multilines = &MQLRequest{FilePath: ffpath}
 			multilines = &MQLRequest{FilePath: ffpath}
 			// 保留语句中的注释
 			// 保留语句中的注释
 			multilines.OriginQueryString = strings.TrimSpace(strings.Replace(mql, "multilines begin", "", 1))
 			multilines.OriginQueryString = strings.TrimSpace(strings.Replace(mql, "multilines begin", "", 1))
@@ -80,6 +97,9 @@ func (mt *MQLTest) RunFile(t *testing.T, ctx context.Context,
 			multilines.Toline = toline
 			multilines.Toline = toline
 			multilines.Tochar = tochar
 			multilines.Tochar = tochar
 		} else {
 		} else {
+			if filterN > 0 && stmtidx != filterN {
+				continue
+			}
 			// 单条语句
 			// 单条语句
 			mqr := &MQLRequest{OriginQueryString: mql, FilePath: ffpath, Fromline: fromline, Toline: toline, Fromchar: fromchar, Tochar: tochar}
 			mqr := &MQLRequest{OriginQueryString: mql, FilePath: ffpath, Fromline: fromline, Toline: toline, Fromchar: fromchar, Tochar: tochar}
 			// 加入请求组,并初始化,提取动作信息
 			// 加入请求组,并初始化,提取动作信息