mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 16:30: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)
 | 
						|
}
 |