SQL diff writer implementation and interface

This commit is contained in:
Zach Musgrave
2022-06-23 15:08:15 -07:00
parent 094782af66
commit b79bbc9646
4 changed files with 83 additions and 12 deletions

View File

@@ -19,6 +19,7 @@ import (
"fmt"
"time"
"github.com/dolthub/go-mysql-server/sql"
"golang.org/x/sync/errgroup"
"github.com/dolthub/dolt/go/libraries/doltcore/row"
@@ -75,6 +76,16 @@ type RowDiffer interface {
Close() error
}
// SqlRowDiffWriter knows how to write diff rows to an arbitrary format and destination.
type SqlRowDiffWriter interface {
// WriteRow writes the diff row given, of the diff type provided. colDiffTypes is guaranteed to be the same length as
// the input row.
WriteRow(ctx context.Context, row sql.Row, diffType ChangeType, colDiffTypes []ChangeType) error
// Close finalizes the work of this writer.
Close(ctx context.Context) error
}
func NewRowDiffer(ctx context.Context, fromSch, toSch schema.Schema, buf int) RowDiffer {
ad := NewAsyncDiffer(buf)

View File

@@ -15,27 +15,85 @@
package sqlexport
import (
"context"
"fmt"
"io"
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlfmt"
"github.com/dolthub/dolt/go/libraries/doltcore/table/editor"
"github.com/dolthub/dolt/go/libraries/utils/iohelp"
"github.com/dolthub/dolt/go/libraries/utils/set"
"github.com/dolthub/go-mysql-server/sql"
)
type SqlDiffWriter struct {
tableName string
sch sql.Schema
sch schema.Schema
writtenFirstRow bool
writtenAutocommitOff bool
writeCloser io.WriteCloser
writeCloser io.WriteCloser
editOpts editor.Options
autocommitOff bool
}
func NewSqlDiffWriter(tableName string, schema sql.Schema, wr io.WriteCloser) *SqlDiffWriter {
func NewSqlDiffWriter(tableName string, schema schema.Schema, wr io.WriteCloser) *SqlDiffWriter {
return &SqlDiffWriter{
tableName: tableName,
sch: schema,
writtenFirstRow: false,
writeCloser: wr,
tableName: tableName,
sch: schema,
writtenFirstRow: false,
writeCloser: wr,
}
}
func (w SqlDiffWriter) WriteRow(
ctx context.Context,
row sql.Row,
rowDiffType diff.ChangeType,
colDiffTypes []diff.ChangeType,
) error {
if len(row) != len(colDiffTypes) {
return fmt.Errorf("expected the same size for columns and diff types, got %d and %d", len(row), len(colDiffTypes))
}
switch rowDiffType {
case diff.Inserted:
stmt, err := sqlfmt.SqlRowAsInsertStmt(row, w.tableName, w.sch)
if err != nil {
return err
}
return iohelp.WriteLine(w.writeCloser, stmt)
case diff.Deleted:
stmt, err := sqlfmt.SqlRowAsDeleteStmt(row, w.tableName, w.sch)
if err != nil {
return err
}
return iohelp.WriteLine(w.writeCloser, stmt)
case diff.ModifiedNew:
updatedCols := set.NewEmptyStrSet()
for i, diffType := range colDiffTypes {
if diffType != diff.None {
updatedCols.Add(w.sch.GetAllCols().GetByIndex(i).Name)
}
}
stmt, err := sqlfmt.SqlRowAsUpdateStmt(row, w.tableName, w.sch, updatedCols)
if err != nil {
return err
}
return iohelp.WriteLine(w.writeCloser, stmt)
case diff.ModifiedOld:
// do nothing, we only issue UPDATE for ModifiedNew
return nil
default:
return fmt.Errorf("unexpected row diff type: %v", rowDiffType)
}
}
func (w SqlDiffWriter) Close(ctx context.Context) error {
return w.writeCloser.Close()
}

View File

@@ -82,7 +82,7 @@ func colorsForDiffTypes(colDiffTypes []diff.ChangeType) []*color.Color {
return colors
}
func (w FixedWidthDiffTableWriter) Close(ctx *sql.Context) error {
func (w FixedWidthDiffTableWriter) Close(ctx context.Context) error {
return w.tableWriter.Close(ctx)
}

View File

@@ -31,15 +31,17 @@ type StrSet struct {
func newStrSet(items []string, caseSensitive bool) *StrSet {
s := &StrSet{make(map[string]bool, len(items)), caseSensitive}
if items != nil {
for _, item := range items {
s.items[item] = true
}
for _, item := range items {
s.items[item] = true
}
return s
}
func NewEmptyStrSet() *StrSet {
return newStrSet(nil, true)
}
func NewStrSet(items []string) *StrSet {
return newStrSet(items, true)
}