From 852c7bb7b22553bcb32b330c2f437da1530d1d13 Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Tue, 26 Mar 2024 16:28:06 +0800 Subject: [PATCH 1/2] support list_files --- r/example.result | 27 +++++++++++++++++++++++++-- r/extensions.result | 2 +- src/main.go | 38 ++++++++++++++++++++++++++++++++++++++ t/example.test | 7 +++++++ 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/r/example.result b/r/example.result index 6e5cb8d..81c8485 100644 --- a/r/example.result +++ b/r/example.result @@ -6,8 +6,9 @@ a b SELECT 1 FROM NON_EXISTING_TABLE; Error 1146 (42S02): Table 'example.NON_EXISTING_TABLE' doesn't exist SELECT 2 FROM NON_EXISTING_TABLE; +Error 1146 (42S02): Table 'example.NON_EXISTING_TABLE' doesn't exist SELECT 3 FROM NON_EXISTING_TABLE; -Got one of the listed errors +Error 1146 (42S02): Table 'example.NON_EXISTING_TABLE' doesn't exist SELECT 4; 4 4 @@ -20,8 +21,9 @@ SELECT 6; 1 SELECT; Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 1 near "1 SELECT;" 2 SELECT; +Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 1 near "2 SELECT;" 3 SELECT; -Got one of the listed errors +Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 1 near "3 SELECT;" explain analyze format='brief' select * from t; id estRows actRows task access object execution info operator info memory disk TableReader 10000.00 5 root NULL time:, loops:, RU:, cop_task: {num:, max:, proc_keys:, rpc_num:, rpc_time:, copr_cache_hit_ratio:, build_task_duration:, max_distsql_concurrency:} data:TableFullScan Bytes N/A @@ -33,6 +35,27 @@ TableReader_5 10000.00 5 root NULL time:, loops:, RU:, cop_task: insert into t values (6, 6); affected rows: 1 info: +--list_files ./src +main.go +perror.go +query.go +query_test.go +type.go +util.go +util_test.go +xml.go +--list_files ./src *.go +main.go +perror.go +query.go +query_test.go +type.go +util.go +util_test.go +xml.go +--list_files ./src *_test.go +query_test.go +util_test.go DROP TABLE IF EXISTS t1; affected rows: 0 info: diff --git a/r/extensions.result b/r/extensions.result index 814e650..983b030 100644 --- a/r/extensions.result +++ b/r/extensions.result @@ -1,2 +1,2 @@ SELECT 1 FROM NON_EXISTING_TABLE; -Got one of the listed errors +Error 1146 (42S02): Table 'extensions.NON_EXISTING_TABLE' doesn't exist diff --git a/src/main.go b/src/main.go index 9ddaf45..9ed611d 100644 --- a/src/main.go +++ b/src/main.go @@ -19,6 +19,7 @@ import ( "database/sql" "flag" "fmt" + "io/fs" "os" "path/filepath" "regexp" @@ -493,6 +494,43 @@ func (t *tester) Run() error { return errors.Annotate(err, fmt.Sprintf("Could not parse regex in --replace_regex: line: %d sql:%v", q.Line, q.Query)) } t.replaceRegex = regex + case Q_LIST_FILES: + q.Query = strings.TrimSpace(q.Query) + parts := strings.Split(q.Query, " ") + if len(parts) > 2 { + return errors.New("list_files contains at most 2 arguments") + } + dirPath := parts[0] + fileInfo, err := os.Stat(dirPath) + if os.IsNotExist(err) { + return errors.Annotate(err, fmt.Sprintf("Directory %s not exists", dirPath)) + } + if err != nil { + return errors.Annotate(err, fmt.Sprintf("Fail to get infomation for directory %s", dirPath)) + } + if !fileInfo.IsDir() { + return errors.Annotate(err, fmt.Sprintf("%s is not a directory", dirPath)) + } + files, err := os.ReadDir(dirPath) + if err != nil { + return errors.Annotate(err, fmt.Sprintf("Fail to list files insides %s", dirPath)) + } + if len(parts) == 2 { + targetFiles := []fs.DirEntry{} + for _, file := range files { + name := file.Name() + match, err := filepath.Match(parts[1], name) + if err != nil || !match { + continue + } + targetFiles = append(targetFiles, file) + } + files = targetFiles + } + for _, file := range files { + t.buf.WriteString(file.Name()) + t.buf.WriteString("\n") + } default: log.WithFields(log.Fields{"command": q.firstWord, "arguments": q.Query, "line": q.Line}).Warn("command not implemented") } diff --git a/t/example.test b/t/example.test index 4b6f18d..24eae18 100644 --- a/t/example.test +++ b/t/example.test @@ -38,6 +38,13 @@ explain analyze select * from t; --enable_info insert into t values (6, 6); +--echo --list_files ./src +--list_files ./src +--echo --list_files ./src *.go +--list_files ./src *.go +--echo --list_files ./src *_test.go +--list_files ./src *_test.go + DROP TABLE IF EXISTS t1; CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT NOT NULL UNIQUE); INSERT t1 VALUES (1, 1); From c27777950dafa3257bdc9bbd8f074a3acb3f0280 Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Tue, 26 Mar 2024 16:54:27 +0800 Subject: [PATCH 2/2] support mkdir and remove_files_wildcard --- r/example.result | 2 ++ src/main.go | 87 +++++++++++++++++++++++++++++++++++------------- t/example.test | 5 +++ 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/r/example.result b/r/example.result index 81c8485..9446b63 100644 --- a/r/example.result +++ b/r/example.result @@ -70,3 +70,5 @@ affected rows: 3 info: Records: 2 Duplicates: 1 Warnings: 0 1 use `test`;; +0 +0 diff --git a/src/main.go b/src/main.go index 9ed611d..b12bde7 100644 --- a/src/main.go +++ b/src/main.go @@ -494,43 +494,53 @@ func (t *tester) Run() error { return errors.Annotate(err, fmt.Sprintf("Could not parse regex in --replace_regex: line: %d sql:%v", q.Line, q.Query)) } t.replaceRegex = regex + case Q_MKDIR: + q.Query = strings.TrimSpace(q.Query) + if err := os.MkdirAll(q.Query, os.ModePerm); err != nil { + t.buf.WriteString("1\n") + return errors.Annotate(err, fmt.Sprintf("failed to create directories: %s", q.Query)) + } + t.buf.WriteString("0\n") case Q_LIST_FILES: q.Query = strings.TrimSpace(q.Query) parts := strings.Split(q.Query, " ") + if len(parts) < 1 { + return errors.New("list_files contains at least 1 argument") + } if len(parts) > 2 { return errors.New("list_files contains at most 2 arguments") } - dirPath := parts[0] - fileInfo, err := os.Stat(dirPath) - if os.IsNotExist(err) { - return errors.Annotate(err, fmt.Sprintf("Directory %s not exists", dirPath)) - } - if err != nil { - return errors.Annotate(err, fmt.Sprintf("Fail to get infomation for directory %s", dirPath)) - } - if !fileInfo.IsDir() { - return errors.Annotate(err, fmt.Sprintf("%s is not a directory", dirPath)) - } - files, err := os.ReadDir(dirPath) + + files, err := getFilesInDir(parts[0]) if err != nil { - return errors.Annotate(err, fmt.Sprintf("Fail to list files insides %s", dirPath)) + return err } + if len(parts) == 2 { - targetFiles := []fs.DirEntry{} - for _, file := range files { - name := file.Name() - match, err := filepath.Match(parts[1], name) - if err != nil || !match { - continue - } - targetFiles = append(targetFiles, file) - } - files = targetFiles + files = filterByPattern(files, parts[1]) } for _, file := range files { t.buf.WriteString(file.Name()) t.buf.WriteString("\n") } + case Q_REMOVE_FILES_WILDCARD: + q.Query = strings.TrimSpace(q.Query) + parts := strings.Split(q.Query, " ") + if len(parts) != 2 { + return errors.New("remove_files_wildcard requires 2 arguments") + } + + files, err := getFilesInDir(parts[0]) + if err != nil { + return err + } + files = filterByPattern(files, parts[1]) + for _, file := range files { + err = os.Remove(filepath.Join(parts[0], file.Name())) + if err != nil { + continue + } + } default: log.WithFields(log.Fields{"command": q.firstWord, "arguments": q.Query, "line": q.Line}).Warn("command not implemented") } @@ -545,6 +555,37 @@ func (t *tester) Run() error { return t.flushResult() } +func getFilesInDir(dirPath string) ([]fs.DirEntry, error) { + fileInfo, err := os.Stat(dirPath) + if os.IsNotExist(err) { + return nil, errors.Annotate(err, fmt.Sprintf("Directory %s not exists", dirPath)) + } + if err != nil { + return nil, errors.Annotate(err, fmt.Sprintf("Fail to get infomation for directory %s", dirPath)) + } + if !fileInfo.IsDir() { + return nil, errors.Annotate(err, fmt.Sprintf("%s is not a directory", dirPath)) + } + files, err := os.ReadDir(dirPath) + if err != nil { + return nil, errors.Annotate(err, fmt.Sprintf("Fail to list files insides %s", dirPath)) + } + return files, nil +} + +func filterByPattern(files []fs.DirEntry, pattern string) []fs.DirEntry { + targetFiles := []fs.DirEntry{} + for _, file := range files { + name := file.Name() + match, err := filepath.Match(pattern, name) + if err != nil || !match { + continue + } + targetFiles = append(targetFiles, file) + } + return targetFiles +} + func (t *tester) concurrentRun(concurrentQueue []query, concurrentSize int) error { if len(concurrentQueue) == 0 { return nil diff --git a/t/example.test b/t/example.test index 24eae18..2663815 100644 --- a/t/example.test +++ b/t/example.test @@ -55,3 +55,8 @@ INSERT t1 VALUES (1, 1), (1, 1) ON DUPLICATE KEY UPDATE f1 = 2, f2 = 2; --echo $a use `test`;; + +--mkdir ./tmp +--mkdir ./tmp1 +--remove_files_wildcard ./tmp * +--remove_files_wildcard ./tmp1 a \ No newline at end of file