feat: PostgreSQL driver support
This commit is contained in:
1 parent
eb9bfabed5
commit
dc5d12348c
24 files changed
+1585
-75
No files matched your search
@@ -28,14 +28,26 @@ type DumpSource interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
var dumpPreamble = []string{
|
||||
"SET NAMES utf8mb4;",
|
||||
"SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';",
|
||||
"SET foreign_key_checks = 0;",
|
||||
type dumpDialect struct {
|
||||
preamble []string
|
||||
postamble []string
|
||||
quote func(name string) string
|
||||
literal func(databaseType string, value []byte) string
|
||||
tableTrailer func(table string, columns []DumpColumn) []string
|
||||
}
|
||||
|
||||
var dumpPostamble = []string{
|
||||
"SET foreign_key_checks = 1;",
|
||||
var mysqlDumpDialect = dumpDialect{
|
||||
preamble: []string{
|
||||
"SET NAMES utf8mb4;",
|
||||
"SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';",
|
||||
"SET foreign_key_checks = 0;",
|
||||
},
|
||||
postamble: []string{
|
||||
"SET foreign_key_checks = 1;",
|
||||
},
|
||||
quote: quoteIdentifier,
|
||||
literal: sqlLiteral,
|
||||
tableTrailer: func(string, []DumpColumn) []string { return nil },
|
||||
}
|
||||
|
||||
var plainNumber = regexp.MustCompile(`^-?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?$`)
|
||||
@@ -50,7 +62,11 @@ var textEscapes = strings.NewReplacer(
|
||||
)
|
||||
|
||||
func WriteDump(output io.Writer, source DumpSource) error {
|
||||
if err := writeStatements(output, dumpPreamble); err != nil {
|
||||
return writeDump(output, source, mysqlDumpDialect)
|
||||
}
|
||||
|
||||
func writeDump(output io.Writer, source DumpSource, dialect dumpDialect) error {
|
||||
if err := writeStatements(output, dialect.preamble); err != nil {
|
||||
return err
|
||||
}
|
||||
tables, err := source.Tables()
|
||||
@@ -58,11 +74,11 @@ func WriteDump(output io.Writer, source DumpSource) error {
|
||||
return err
|
||||
}
|
||||
for _, table := range tables {
|
||||
if err := writeTable(output, source, table); err != nil {
|
||||
if err := writeTable(output, source, table, dialect); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return writeStatements(output, dumpPostamble)
|
||||
return writeStatements(output, dialect.postamble)
|
||||
}
|
||||
|
||||
func writeStatements(output io.Writer, statements []string) error {
|
||||
@@ -74,7 +90,7 @@ func writeStatements(output io.Writer, statements []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTable(output io.Writer, source DumpSource, table string) error {
|
||||
func writeTable(output io.Writer, source DumpSource, table string, dialect dumpDialect) error {
|
||||
create, err := source.CreateStatement(table)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -87,39 +103,42 @@ func writeTable(output io.Writer, source DumpSource, table string) error {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return writeRows(output, table, rows)
|
||||
return writeRows(output, table, rows, dialect)
|
||||
}
|
||||
|
||||
func writeRows(output io.Writer, table string, rows DumpRows) error {
|
||||
func writeRows(output io.Writer, table string, rows DumpRows, dialect dumpDialect) error {
|
||||
columns, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
insertPrefix := insertStatementPrefix(table, columns)
|
||||
insertPrefix := insertStatementPrefix(table, columns, dialect)
|
||||
for rows.Next() {
|
||||
values, err := rows.Values()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(output, "%s%s);\n", insertPrefix, joinLiterals(columns, values)); err != nil {
|
||||
if _, err := fmt.Fprintf(output, "%s%s);\n", insertPrefix, joinLiterals(columns, values, dialect)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return rows.Err()
|
||||
if err := rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeStatements(output, dialect.tableTrailer(table, columns))
|
||||
}
|
||||
|
||||
func insertStatementPrefix(table string, columns []DumpColumn) string {
|
||||
func insertStatementPrefix(table string, columns []DumpColumn, dialect dumpDialect) string {
|
||||
names := make([]string, len(columns))
|
||||
for index, column := range columns {
|
||||
names[index] = quoteIdentifier(column.Name)
|
||||
names[index] = dialect.quote(column.Name)
|
||||
}
|
||||
return fmt.Sprintf("INSERT INTO %s (%s) VALUES (", quoteIdentifier(table), strings.Join(names, ","))
|
||||
return fmt.Sprintf("INSERT INTO %s (%s) VALUES (", dialect.quote(table), strings.Join(names, ","))
|
||||
}
|
||||
|
||||
func joinLiterals(columns []DumpColumn, values [][]byte) string {
|
||||
func joinLiterals(columns []DumpColumn, values [][]byte, dialect dumpDialect) string {
|
||||
literals := make([]string, len(columns))
|
||||
for index, column := range columns {
|
||||
literals[index] = sqlLiteral(column.Type, values[index])
|
||||
literals[index] = dialect.literal(column.Type, values[index])
|
||||
}
|
||||
return strings.Join(literals, ",")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user