mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
100 lines
1.9 KiB
Go
100 lines
1.9 KiB
Go
|
|
package sqlparser
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bufio"
|
||
|
|
"github.com/kanzihuang/vitess/go/vt/sqlparser"
|
||
|
|
"io"
|
||
|
|
"regexp"
|
||
|
|
)
|
||
|
|
|
||
|
|
type Parser interface {
|
||
|
|
Next() error
|
||
|
|
Current() string
|
||
|
|
}
|
||
|
|
|
||
|
|
var _ Parser = &MysqlParser{}
|
||
|
|
var _ Parser = &PostgresParser{}
|
||
|
|
|
||
|
|
type MysqlParser struct {
|
||
|
|
tokenizer *sqlparser.Tokenizer
|
||
|
|
statement string
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewMysqlParser(reader io.Reader) *MysqlParser {
|
||
|
|
return &MysqlParser{
|
||
|
|
tokenizer: sqlparser.NewReaderTokenizer(reader),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (parser *MysqlParser) Next() error {
|
||
|
|
statement, err := sqlparser.ParseNext(parser.tokenizer)
|
||
|
|
if err != nil {
|
||
|
|
parser.statement = ""
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
parser.statement = sqlparser.String(statement)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (parser *MysqlParser) Current() string {
|
||
|
|
return parser.statement
|
||
|
|
}
|
||
|
|
|
||
|
|
type PostgresParser struct {
|
||
|
|
scanner *bufio.Scanner
|
||
|
|
statement string
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewPostgresParser(reader io.Reader) *PostgresParser {
|
||
|
|
return &PostgresParser{
|
||
|
|
scanner: splitSqls(reader),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (parser *PostgresParser) Next() error {
|
||
|
|
if !parser.scanner.Scan() {
|
||
|
|
return io.EOF
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (parser *PostgresParser) Current() string {
|
||
|
|
return parser.scanner.Text()
|
||
|
|
}
|
||
|
|
|
||
|
|
// 根据;\n切割sql
|
||
|
|
func splitSqls(r io.Reader) *bufio.Scanner {
|
||
|
|
scanner := bufio.NewScanner(r)
|
||
|
|
re := regexp.MustCompile(`\s*;\s*\n`)
|
||
|
|
|
||
|
|
scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||
|
|
if atEOF && len(data) == 0 {
|
||
|
|
return 0, nil, io.EOF
|
||
|
|
}
|
||
|
|
|
||
|
|
match := re.FindIndex(data)
|
||
|
|
|
||
|
|
if match != nil {
|
||
|
|
// 如果找到了";\n",判断是否为最后一行
|
||
|
|
if match[1] == len(data) {
|
||
|
|
// 如果是最后一行,则返回完整的切片
|
||
|
|
return len(data), data, nil
|
||
|
|
}
|
||
|
|
// 否则,返回到";\n"之后,并且包括";\n"本身
|
||
|
|
return match[1], data[:match[1]], nil
|
||
|
|
}
|
||
|
|
|
||
|
|
if atEOF {
|
||
|
|
return len(data), data, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0, nil, nil
|
||
|
|
})
|
||
|
|
|
||
|
|
return scanner
|
||
|
|
}
|
||
|
|
|
||
|
|
func SplitStatementToPieces(sql string) ([]string, error) {
|
||
|
|
return sqlparser.SplitStatementToPieces(sql)
|
||
|
|
}
|