Merge pull request #207 from liquidata-inc/andy/sqldiffs

Andy/sqldiffs
This commit is contained in:
AndyA
2019-11-13 14:57:04 -08:00
committed by GitHub
18 changed files with 676 additions and 48 deletions
+4
View File
@@ -0,0 +1,4 @@
pk, int, string, boolean, float, uint, uuid
0, 0, "asdf", TRUE, 0.0, 0, "00000000-0000-0000-0000-000000000000"
1, -1, "qwerty", FALSE, -1.0, 1, "00000000-0000-0000-0000-000000000001"
2, 1, "", TRUE, 0.0, 0, "123e4567-e89b-12d3-a456-426655440000"
1 pk int string boolean float uint uuid
2 0 0 asdf TRUE 0.0 0 00000000-0000-0000-0000-000000000000
3 1 -1 qwerty FALSE -1.0 1 00000000-0000-0000-0000-000000000001
4 2 1 TRUE 0.0 0 123e4567-e89b-12d3-a456-426655440000
@@ -0,0 +1,2 @@
INSERT INTO test (pk, int, string, boolean, float, uint, uuid)
VALUES (3, 3, "three", TRUE, 3.3, 3, "00000000-0000-0000-0000-000000000003");
@@ -0,0 +1 @@
DELETE FROM test WHERE pk=1;
@@ -0,0 +1 @@
UPDATE test SET int=-1, boolean=FALSE, uint=2 WHERE pk=2;
+1
View File
@@ -0,0 +1 @@
INSERT INTO test (pk1, pk2, c1, c2, c3, c4, c5) VALUES (2, 2, 1, 2, 3, 4, 5);
@@ -0,0 +1 @@
UPDATE test SET pk1=3, pk2=3 WHERE pk1=1 AND pk2=1;
@@ -0,0 +1 @@
DELETE FROM test WHERE pk1=1 AND pk2=0 ;
@@ -0,0 +1 @@
UPDATE test SET pk1=3 WHERE pk1=0 AND pk2=1;
@@ -0,0 +1 @@
UPDATE test SET c1=9, c3=9, c5=9 WHERE pk1=1 AND pk2=1;
+215
View File
@@ -0,0 +1,215 @@
#!/usr/bin/env bats
load $BATS_TEST_DIRNAME/helper/common.bash
setup() {
setup_common
}
teardown() {
teardown_common
}
@test "diff sql output reconciles INSERT query" {
dolt checkout -b firstbranch
dolt table create -s=`batshelper 1pk5col-ints.schema` test
dolt table import -u test `batshelper 1pk5col-ints.csv`
dolt add test
dolt commit -m "Added one initial row"
dolt checkout -b newbranch
dolt sql -q 'INSERT INTO test (pk, c1, c2, c3, c4, c5) VALUES (2, 11, 0, 0, 0, 0)'
dolt add test
dolt commit -m "Added three rows"
# confirm a difference exists
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" != "" ]] || false
dolt diff --sql newbranch firstbranch > query
dolt checkout firstbranch
dolt sql < query
rm query
dolt add test
dolt commit -m "Reconciled with newbranch"
# confirm that both branches have the same content
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" = "" ]] || false
}
@test "diff sql output reconciles UPDATE query" {
dolt checkout -b firstbranch
dolt table create -s=`batshelper 1pk5col-ints.schema` test
dolt table import -u test `batshelper 1pk5col-ints.csv`
dolt add test
dolt commit -m "Added one initial row"
dolt checkout -b newbranch
dolt sql -q 'UPDATE test SET c1=11, c5=6 WHERE pk=0'
dolt add test
dolt commit -m "modified first row"
# confirm a difference exists
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" != "" ]] || false
dolt diff --sql newbranch firstbranch > query
dolt checkout firstbranch
dolt sql < query
rm query
dolt add test
dolt commit -m "Reconciled with newbranch"
# confirm that both branches have the same content
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" = "" ]] || false
}
@test "diff sql output reconciles DELETE query" {
dolt checkout -b firstbranch
dolt table create -s=`batshelper 1pk5col-ints.schema` test
dolt table import -u test `batshelper 1pk5col-ints.csv`
dolt add test
dolt commit -m "Added one initial row"
dolt checkout -b newbranch
dolt sql -q 'DELETE FROM test WHERE pk=0'
dolt add test
dolt commit -m "deleted first row"
# confirm a difference exists
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" != "" ]] || false
dolt diff --sql newbranch firstbranch > query
dolt checkout firstbranch
dolt sql < query
rm query
dolt add test
dolt commit -m "Reconciled with newbranch"
# confirm that both branches have the same content
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" = "" ]] || false
}
@test "diff sql output reconciles primary key change" {
dolt checkout -b firstbranch
dolt table create -s=`batshelper 1pk5col-ints.schema` test
dolt table import -u test `batshelper 1pk5col-ints.csv`
dolt add test
dolt commit -m "Added one initial row"
dolt checkout -b newbranch
dolt sql -q 'UPDATE test SET pk=2 WHERE pk=1'
dolt add test
dolt commit -m "modified first row"
# confirm a difference exists
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" != "" ]] || false
dolt diff --sql newbranch firstbranch > query
dolt checkout firstbranch
dolt sql < query
rm query
dolt add test
dolt commit -m "Reconciled with newbranch"
# confirm that both branches have the same content
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" = "" ]] || false
}
@test "sql diff supports all types" {
dolt checkout -b firstbranch
dolt table create -s=`batshelper 1pksupportedtypes.schema` test
dolt table import -u test `batshelper 1pksupportedtypes.csv`
dolt add .
dolt commit -m "create/init table test"
# for each query file in helper/queries/1pksuppportedtypes/
# run query on db, create sql diff patch, confirm they're equivalent
dolt branch newbranch
for query in delete add update
do
dolt checkout newbranch
dolt sql < $BATS_TEST_DIRNAME/helper/queries/1pksupportedtypes/$query.sql
dolt add test
dolt commit -m "applied $query query"
# confirm a difference exists
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" != "" ]] || false
dolt diff --sql newbranch firstbranch > patch.sql
dolt checkout firstbranch
dolt sql < patch.sql
rm patch.sql
dolt add test
dolt commit -m "Reconciled with newbranch"
# confirm that both branches have the same content
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" = "" ]] || false
done
}
@test "sql diff supports multiple primary keys" {
dolt checkout -b firstbranch
dolt table create -s=`batshelper 2pk5col-ints.schema` test
dolt table import -u test `batshelper 2pk5col-ints.csv`
dolt add .
dolt commit -m "create/init table test"
# for each query file in helper/queries/2pk5col-ints/
# run query on db, create sql diff patch, confirm they're equivalent
dolt branch newbranch
for query in delete add update single_pk_update all_pk_update
do
dolt checkout newbranch
dolt sql < $BATS_TEST_DIRNAME/helper/queries/2pk5col-ints/$query.sql
dolt add test
dolt diff --sql
dolt commit -m "applied $query query "
# confirm a difference exists
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" != "" ]] || false
dolt diff --sql newbranch firstbranch > patch.sql
dolt checkout firstbranch
dolt sql < patch.sql
rm patch.sql
dolt add test
dolt commit -m "Reconciled with newbranch"
# confirm that both branches have the same content
run dolt diff --sql newbranch firstbranch
[ "$status" -eq 0 ]
[[ "$output" = "" ]] || false
done
}
@test "sql diff correctly exits on schema change" {
dolt table import -c -s=`batshelper employees-sch.json` employees `batshelper employees-tbl.json`
dolt add employees
dolt commit -m "Added employees table with data"
dolt schema add-column employees city string
dolt table put-row employees id:3 "first name":taylor "last name":bantle title:"software engineer" "start date":"" "end date":"" city:"Santa Monica"
run dolt diff --sql
[ "$status" -eq 1 ]
[[ "$output" =~ "SQL output of schema diffs is not yet supported" ]] || false
}
+80 -39
View File
@@ -47,20 +47,33 @@ import (
"github.com/liquidata-inc/dolt/go/store/types"
)
type diffOutput int
type diffPart int
const (
SchemaOnlyDiff = 1 // 0b0001
DataOnlyDiff = 2 // 0b0010
Summary = 4 // 0b0100
SchemaOnlyDiff diffPart = 1 // 0b0001
DataOnlyDiff diffPart = 2 // 0b0010
Summary diffPart = 4 // 0b0100
SchemaAndDataDiff = SchemaOnlyDiff | DataOnlyDiff
TabularDiffOutput diffOutput = 1
SQLDiffOutput diffOutput = 2
DataFlag = "data"
SchemaFlag = "schema"
SummaryFlag = "summary"
whereParam = "where"
limitParam = "limit"
SQLFlag = "sql"
)
type DiffSink interface {
GetSchema() schema.Schema
ProcRowWithProps(r row.Row, props pipeline.ReadableMap) error
Close() error
}
var diffShortDesc = "Show changes between commits, commit and working tree, etc"
var diffLongDesc = `Show changes between the working and staged tables, changes between the working tables and the tables within a commit, or changes between tables at two commits.
@@ -84,9 +97,10 @@ var diffSynopsis = []string{
}
type diffArgs struct {
diffParts int
limit int
where string
diffParts diffPart
diffOutput diffOutput
limit int
where string
}
func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv) int {
@@ -94,6 +108,7 @@ func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltE
ap.SupportsFlag(DataFlag, "d", "Show only the data changes, do not show the schema changes (Both shown by default).")
ap.SupportsFlag(SchemaFlag, "s", "Show only the schema changes, do not show the data changes (Both shown by default).")
ap.SupportsFlag(SummaryFlag, "", "Show summary of data changes")
ap.SupportsFlag(SQLFlag, "q", "Output diff as a SQL patch file of INSERT / UPDATE / DELETE statements")
ap.SupportsString(whereParam, "", "column", "filters columns based on values in the diff. See dolt diff --help for details.")
ap.SupportsInt(limitParam, "", "record_count", "limits to the first N diffs.")
help, _ := cli.HelpAndUsagePrinters(commandStr, diffShortDesc, diffLongDesc, diffSynopsis, ap)
@@ -106,6 +121,11 @@ func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltE
diffParts = SchemaOnlyDiff
}
diffOutput := TabularDiffOutput
if apr.Contains(SQLFlag) {
diffOutput = SQLDiffOutput
}
summary := apr.Contains(SummaryFlag)
if summary {
@@ -125,7 +145,7 @@ func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltE
if verr == nil {
whereClause := apr.GetValueOrDefault(whereParam, "")
verr = diffRoots(ctx, r1, r2, tables, dEnv, &diffArgs{diffParts, limit, whereClause})
verr = diffRoots(ctx, r1, r2, tables, dEnv, &diffArgs{diffParts, diffOutput, limit, whereClause})
}
if verr != nil {
@@ -273,7 +293,9 @@ func diffRoots(ctx context.Context, r1, r2 *doltdb.RootValue, tblNames []string,
}
}
printTableDiffSummary(tblName, tbl1, tbl2)
if dArgs.diffOutput == TabularDiffOutput {
printTableDiffSummary(tblName, tbl1, tbl2)
}
if tbl1 == nil || tbl2 == nil {
continue
@@ -344,12 +366,16 @@ func diffRoots(ctx context.Context, r1, r2 *doltdb.RootValue, tblNames []string,
verr = diffSummary(ctx, rowData1, rowData2, colLen)
}
if sch1Hash != sch2Hash && dArgs.diffOutput == SQLDiffOutput {
return errhand.BuildDError("SQL output of schema diffs is not yet supported").Build()
}
if dArgs.diffParts&SchemaOnlyDiff != 0 && sch1Hash != sch2Hash {
verr = diffSchemas(tblName, sch2, sch1)
}
if dArgs.diffParts&DataOnlyDiff != 0 {
verr = diffRows(ctx, rowData1, rowData2, sch1, sch2, dArgs)
verr = diffRows(ctx, rowData1, rowData2, sch1, sch2, dArgs, tblName)
}
if verr != nil {
@@ -458,7 +484,7 @@ func fromNamer(name string) string {
return diff.From + "_" + name
}
func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch schema.Schema, dArgs *diffArgs) errhand.VerboseError {
func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch schema.Schema, dArgs *diffArgs, tblName string) errhand.VerboseError {
joiner, err := rowconv.NewJoiner(
[]rowconv.NamedSchema{
{Name: diff.From, Sch: oldSch},
@@ -467,7 +493,7 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
map[string]rowconv.ColNamingFunc{diff.To: toNamer, diff.From: fromNamer},
)
untypedUnionSch, ds, verr := createSplitter(newSch, oldSch, joiner)
untypedUnionSch, ds, verr := createSplitter(newSch, oldSch, joiner, dArgs)
if verr != nil {
return verr
}
@@ -497,7 +523,12 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
numHeaderRows = 2
}
sink, err := diff.NewColorDiffSink(iohelp.NopWrCloser(cli.CliOut), untypedUnionSch, numHeaderRows)
var sink DiffSink
if dArgs.diffOutput == TabularDiffOutput {
sink, err = diff.NewColorDiffSink(iohelp.NopWrCloser(cli.CliOut), untypedUnionSch, numHeaderRows)
} else {
sink, err = diff.NewSQLDiffSink(iohelp.NopWrCloser(cli.CliOut), untypedUnionSch, tblName)
}
if err != nil {
return errhand.BuildDError("").AddCause(err).Build()
@@ -516,29 +547,31 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
return verr
}
if schemasEqual {
schRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
if dArgs.diffOutput != SQLDiffOutput {
if schemasEqual {
schRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
if err != nil {
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
if err != nil {
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
}
p.InjectRow(fwtStageName, schRow)
} else {
newSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, oldColNames)
if err != nil {
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
}
p.InjectRowWithProps(fwtStageName, newSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedOld})
oldSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
if err != nil {
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
}
p.InjectRowWithProps(fwtStageName, oldSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedNew})
}
p.InjectRow(fwtStageName, schRow)
} else {
newSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, oldColNames)
if err != nil {
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
}
p.InjectRowWithProps(fwtStageName, newSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedOld})
oldSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
if err != nil {
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
}
p.InjectRowWithProps(fwtStageName, oldSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedNew})
}
p.Start()
@@ -553,7 +586,7 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
return nil
}
func buildPipeline(dArgs *diffArgs, joiner *rowconv.Joiner, ds *diff.DiffSplitter, untypedUnionSch schema.Schema, src *diff.RowDiffSource, sink *diff.ColorDiffSink, badRowCB pipeline.BadRowCallback) (*pipeline.Pipeline, errhand.VerboseError) {
func buildPipeline(dArgs *diffArgs, joiner *rowconv.Joiner, ds *diff.DiffSplitter, untypedUnionSch schema.Schema, src *diff.RowDiffSource, sink DiffSink, badRowCB pipeline.BadRowCallback) (*pipeline.Pipeline, errhand.VerboseError) {
var where FilterFn
var selTrans *SelectTransform
where, err := ParseWhere(joiner.GetSchema(), dArgs.where)
@@ -575,14 +608,17 @@ func buildPipeline(dArgs *diffArgs, joiner *rowconv.Joiner, ds *diff.DiffSplitte
transforms.AppendTransforms(pipeline.NewNamedTransform("select", selTrans.LimitAndFilter))
}
fwtTr := fwt.NewAutoSizingFWTTransformer(untypedUnionSch, fwt.HashFillWhenTooLong, 1000)
nullPrinter := nullprinter.NewNullPrinter(untypedUnionSch)
transforms.AppendTransforms(pipeline.NewNamedTransform("split_diffs", ds.SplitDiffIntoOldAndNew),
transforms.AppendTransforms(
pipeline.NewNamedTransform("split_diffs", ds.SplitDiffIntoOldAndNew),
pipeline.NewNamedTransform(nullprinter.NULL_PRINTING_STAGE, nullPrinter.ProcessRow),
pipeline.NamedTransform{Name: fwtStageName, Func: fwtTr.TransformToFWT},
)
if dArgs.diffOutput == TabularDiffOutput {
fwtTr := fwt.NewAutoSizingFWTTransformer(untypedUnionSch, fwt.HashFillWhenTooLong, 1000)
transforms.AppendTransforms(pipeline.NamedTransform{Name: fwtStageName, Func: fwtTr.TransformToFWT})
}
sinkProcFunc := pipeline.ProcFuncForSinkFunc(sink.ProcRowWithProps)
p := pipeline.NewAsyncPipeline(pipeline.ProcFuncForSourceFunc(src.NextDiff), sinkProcFunc, transforms, badRowCB)
if selTrans != nil {
@@ -614,7 +650,7 @@ func mapTagToColName(sch, untypedUnionSch schema.Schema) (map[uint64]string, err
return tagToCol, nil
}
func createSplitter(newSch schema.Schema, oldSch schema.Schema, joiner *rowconv.Joiner) (schema.Schema, *diff.DiffSplitter, errhand.VerboseError) {
func createSplitter(newSch schema.Schema, oldSch schema.Schema, joiner *rowconv.Joiner, dArgs *diffArgs) (schema.Schema, *diff.DiffSplitter, errhand.VerboseError) {
dumbNewSch, err := dumbDownSchema(newSch)
if err != nil {
@@ -633,6 +669,11 @@ func createSplitter(newSch schema.Schema, oldSch schema.Schema, joiner *rowconv.
return nil, nil, errhand.BuildDError("Failed to merge schemas").Build()
}
if dArgs.diffOutput == SQLDiffOutput {
// sql diffs don't support schema changes yet => newSch == oldSch
untypedUnionSch = newSch
}
newToUnionConv := rowconv.IdentityConverter
if newSch != nil {
newToUnionMapping, err := rowconv.TagMapping(newSch, untypedUnionSch)
-1
View File
@@ -23,7 +23,6 @@ require (
github.com/gocraft/dbr v0.0.0-20190708200302-a54124dfc613
github.com/golang/protobuf v1.3.2
github.com/golang/snappy v0.0.1
github.com/google/btree v1.0.0 // indirect
github.com/google/go-cmp v0.3.0
github.com/google/uuid v1.1.1
github.com/inconshreveable/mousetrap v1.0.0 // indirect
+45
View File
@@ -10,12 +10,17 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CAFxX/gcnotifier v0.0.0-20190112062741-224a280d589d h1:n0G4ckjMEj7bWuGYUX0i8YlBeBBJuZ+HEHvHfyBDZtI=
github.com/CAFxX/gcnotifier v0.0.0-20190112062741-224a280d589d/go.mod h1:Rn2zM2MnHze07LwkneP48TWt6UiZhzQTwCvw6djVGfE=
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895 h1:dmc/C8bpE5VkQn65PNbbyACDC8xw8Hpp/NEurdPmQDQ=
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8=
@@ -29,6 +34,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195 h1:c4mLfegoDw6OhSJXTd2jUEQgZUQuJWtocudb97Qn9EM=
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
@@ -40,15 +46,20 @@ github.com/aws/aws-sdk-go v1.21.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2 h1:M+TYzBcNIRyzPRg66ndEqUMd7oWDmhvdQmaPC6EZNwM=
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2/go.mod h1:RDu/qcrnpEdJC/p8tx34+YBFqqX71lB7dOX9QE+ZC4M=
github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codahale/blake2 v0.0.0-20150924215134-8d10d0420cbf h1:5ZeQB3mThuz5C2MSER6T5GdtXTF9CMMk42F9BOyRsEQ=
github.com/codahale/blake2 v0.0.0-20150924215134-8d10d0420cbf/go.mod h1:BO2rLUAZMrpgh6GBVKi0Gjdqw2MgCtJrtmUdDeZRKjY=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -85,6 +96,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/gocraft/dbr v0.0.0-20190708200302-a54124dfc613 h1:ceTf7nwYVaHrjRyFNWH5q/B9tZYYyUYapvGrgaCPuYU=
github.com/gocraft/dbr v0.0.0-20190708200302-a54124dfc613/go.mod h1:K/9g3pPouf13kP5K7pdriQEJAy272R9yXuWuDIEWJTM=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -103,10 +115,12 @@ github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8l
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -118,26 +132,35 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6YluI=
github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg=
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
@@ -147,6 +170,7 @@ github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4Fw
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7 h1:K//n/AqR5HjG3qxbrBCL4vJPW0MVFSs9CPK1OOJdRME=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
@@ -167,6 +191,7 @@ github.com/klauspost/pgzip v1.2.0/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQ
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/liquidata-inc/go-mysql-server v0.4.1-0.20191113181502-9b6ae60379a4 h1:V7eKj0YpFA9qlflFvfB3Q6gq+VsL99K1XNlxkClYprQ=
github.com/liquidata-inc/go-mysql-server v0.4.1-0.20191113181502-9b6ae60379a4/go.mod h1:DdWE0ku/mNfuLsRJIrHeHpDtB7am+6oopxEsQKmVkx8=
@@ -189,10 +214,12 @@ github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -207,9 +234,12 @@ github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pilosa/pilosa v1.3.0 h1:P27JB4tIqAN4Yc2Fw7wS5neD7JNkFKRUmwfyV87JMwQ=
github.com/pilosa/pilosa v1.3.0/go.mod h1:97yLL9mpUqOj9naKu5XA/b/U6JLe3JGGUlc2HOTDw+A=
github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
@@ -222,13 +252,17 @@ github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3/go.mod h1
github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 h1:YDeskXpkNDhPdWN3REluVa46HQOVuVkjkd2sWnrABNQ=
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.0.0-20190513083848-b9f5b9457d44 h1:XKCbzPvK4/BbMXoMJOkYP2ANxiAEO0HM1xn6psSbXxY=
github.com/rivo/uniseg v0.0.0-20190513083848-b9f5b9457d44/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/samuel/go-zookeeper v0.0.0-20160616024954-e64db453f351/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sanity-io/litter v1.1.0 h1:BllcKWa3VbZmOZbDCoszYLk7zCsKHz5Beossi8SUcTc=
github.com/sanity-io/litter v1.1.0/go.mod h1:CJ0VCw2q4qKU7LaQr3n7UOSHzgEMgcGco7N/SkZQPjw=
github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v0.0.0-20170409071739-feef008d51ad/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM=
@@ -242,6 +276,7 @@ github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e h1:VAzdS5Nw
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
@@ -252,6 +287,7 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/src-d/go-oniguruma v1.0.0 h1:JDk5PUAjreGsGAKLsoDLNmrsaryjJ5RqT3h+Si6aw/E=
github.com/src-d/go-oniguruma v1.0.0/go.mod h1:chVbff8kcVtmrhxtZ3yBVLLquXbzCS6DrxQaAK/CeqM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -264,15 +300,19 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tealeg/xlsx v1.0.4-0.20190601071628-e2d23f3c43dc h1:WhjmAhd6qju7Jf7hseM3Gd26PMjJJbAcEYgfRnznnko=
github.com/tealeg/xlsx v1.0.4-0.20190601071628-e2d23f3c43dc/go.mod h1:uxu5UY2ovkuRPWKQ8Q7JG0JbSivrISjdPzZQKeo74mA=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQGFt7E53bPYqEgug/AoBtY=
github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw=
github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yudai/gojsondiff v0.0.0-20170626131258-081cda2ee950/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
@@ -320,6 +360,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -365,6 +406,7 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -381,6 +423,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ldap.v2 v2.5.0/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
@@ -395,6 +438,8 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
modernc.org/mathutil v1.0.0 h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/strutil v1.0.0 h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+110
View File
@@ -0,0 +1,110 @@
// Copyright 2019 Liquidata, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package diff
import (
"context"
"errors"
"io"
"github.com/liquidata-inc/dolt/go/libraries/doltcore/row"
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/pipeline"
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/untyped/sqlexport"
"github.com/liquidata-inc/dolt/go/store/types"
)
type SQLDiffSink struct {
sch schema.Schema
sw *sqlexport.SqlExportWriter
}
func NewSQLDiffSink(wr io.WriteCloser, sch schema.Schema, tableName string) (*SQLDiffSink, error) {
sw, err := sqlexport.NewSQLDiffWriter(wr, tableName, sch)
if err != nil {
return nil, err
}
return &SQLDiffSink{sch, sw}, nil
}
func (sds *SQLDiffSink) GetSchema() schema.Schema {
return sds.sch
}
func (sds *SQLDiffSink) ProcRowWithProps(r row.Row, props pipeline.ReadableMap) error {
taggedVals := make(row.TaggedValues)
allCols := sds.sch.GetAllCols()
colDiffs := make(map[string]DiffChType)
if prop, ok := props.Get(CollChangesProp); ok {
if convertedVal, convertedOK := prop.(map[string]DiffChType); convertedOK {
colDiffs = convertedVal
}
}
err := allCols.Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
if val, ok := r.GetColVal(tag); ok {
taggedVals[tag] = val
}
return false, nil
})
if err != nil {
return err
}
r, err = row.New(r.Format(), sds.sch, taggedVals)
if err != nil {
return err
}
taggedVals[diffColTag] = types.String(" ")
if prop, ok := props.Get(DiffTypeProp); ok {
if dt, convertedOK := prop.(DiffChType); convertedOK {
switch dt {
case DiffAdded:
return sds.sw.WriteInsertRow(context.TODO(), r)
case DiffRemoved:
return sds.sw.WriteDeleteRow(context.TODO(), r)
case DiffModifiedOld:
return nil
case DiffModifiedNew:
// TODO: minimize update statement to modified rows
return sds.sw.WriteUpdateRow(context.TODO(), r)
}
// Treat the diff indicator string as a diff of the same type
colDiffs[diffColName] = dt
}
}
return err
}
// Close should release resources being held
func (sds *SQLDiffSink) Close() error {
if sds.sw != nil {
if err := sds.sw.Close(context.TODO()); err != nil {
return err
}
sds.sw = nil
return nil
} else {
return errors.New("Already closed.")
}
}
+1
View File
@@ -299,6 +299,7 @@ func (root *RootValue) HashOf() (hash.Hash, error) {
// TableDiff returns the slices of tables added, modified, and removed when compared with another root value. Tables
// In this instance that are not in the other instance are considered added, and tables in the other instance and not
// this instance are considered removed.
// TODO: is this logic redundant of doltcore/diff ?
func (root *RootValue) TableDiff(ctx context.Context, other *RootValue) (added, modified, removed []string, err error) {
added = []string{}
modified = []string{}
@@ -55,6 +55,11 @@ func OpenSQLExportWriter(path string, tableName string, fs filesys.WritableFS, s
return &SqlExportWriter{tableName: tableName, sch: sch, wr: wr}, nil
}
func NewSQLDiffWriter(wr io.WriteCloser, tableName string, sch schema.Schema) (*SqlExportWriter, error) {
// set writtenFirstRow = true to prevent table drop statement from being written
return &SqlExportWriter{tableName: tableName, sch: sch, wr: wr, writtenFirstRow: true}, nil
}
// Returns the schema of this TableWriter.
func (w *SqlExportWriter) GetSchema() schema.Schema {
return w.sch
@@ -98,6 +103,16 @@ func (w *SqlExportWriter) Close(ctx context.Context) error {
return nil
}
func (w *SqlExportWriter) WriteInsertRow(ctx context.Context, r row.Row) error {
stmt, err := w.insertStatementForRow(r)
if err != nil {
return err
}
return iohelp.WriteLine(w.wr, stmt)
}
func (w *SqlExportWriter) insertStatementForRow(r row.Row) (string, error) {
var b strings.Builder
b.WriteString("INSERT INTO ")
@@ -105,7 +120,7 @@ func (w *SqlExportWriter) insertStatementForRow(r row.Row) (string, error) {
b.WriteString(" ")
b.WriteString("(")
var seenOne bool
seenOne := false
err := w.sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
if seenOne {
b.WriteRune(',')
@@ -145,6 +160,97 @@ func (w *SqlExportWriter) insertStatementForRow(r row.Row) (string, error) {
return b.String(), nil
}
func (w *SqlExportWriter) WriteDeleteRow(ctx context.Context, r row.Row) error {
var b strings.Builder
b.WriteString("DELETE FROM ")
b.WriteString(sql.QuoteIdentifier(w.tableName))
b.WriteString(" WHERE (")
seenOne := false
_, err := r.IterSchema(w.sch, func(tag uint64, val types.Value) (stop bool, err error) {
col := w.sch.GetAllCols().TagToCol[tag]
if col.IsPartOfPK {
if seenOne {
b.WriteString(" AND ")
}
sqlString, err := w.sqlString(val)
if err != nil {
return true, err
}
b.WriteString(sql.QuoteIdentifier(col.Name))
b.WriteRune('=')
b.WriteString(sqlString)
seenOne = true
}
return false, nil
})
if err != nil {
return err
}
b.WriteString(");")
return iohelp.WriteLine(w.wr, b.String())
}
func (w *SqlExportWriter) WriteUpdateRow(ctx context.Context, r row.Row) error {
var b strings.Builder
b.WriteString("UPDATE ")
b.WriteString(sql.QuoteIdentifier(w.tableName))
b.WriteString(" ")
b.WriteString("SET ")
seenOne := false
_, err := r.IterSchema(w.sch, func(tag uint64, val types.Value) (stop bool, err error) {
col := w.sch.GetAllCols().TagToCol[tag]
if !col.IsPartOfPK {
if seenOne {
b.WriteRune(',')
}
sqlString, err := w.sqlString(val)
if err != nil {
return true, err
}
b.WriteString(sql.QuoteIdentifier(col.Name))
b.WriteRune('=')
b.WriteString(sqlString)
seenOne = true
}
return false, nil
})
if err != nil {
return err
}
b.WriteString(" WHERE (")
seenOne = false
_, err = r.IterSchema(w.sch, func(tag uint64, val types.Value) (stop bool, err error) {
col := w.sch.GetAllCols().TagToCol[tag]
if col.IsPartOfPK {
if seenOne {
b.WriteString(" AND ")
}
sqlString, err := w.sqlString(val)
if err != nil {
return true, err
}
b.WriteString(sql.QuoteIdentifier(col.Name))
b.WriteRune('=')
b.WriteString(sqlString)
seenOne = true
}
return false, nil
})
if err != nil {
return err
}
b.WriteString(");")
return iohelp.WriteLine(w.wr, b.String())
}
func (w *SqlExportWriter) dropCreateStatement() string {
var b strings.Builder
b.WriteString("DROP TABLE IF EXISTS ")
@@ -37,19 +37,19 @@ func (*StringBuilderCloser) Close() error {
return nil
}
type test struct {
name string
rows []row.Row
sch schema.Schema
expectedOutput string
}
func TestWriteRow(t *testing.T) {
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
tableName := "people"
dropCreateStatement := "DROP TABLE IF EXISTS `people`;\n" + sql.SchemaAsCreateStmt(tableName, dtestutils.TypedSchema)
type test struct {
name string
rows []row.Row
sch schema.Schema
expectedOutput string
}
tests := []test{
{
name: "simple row",
@@ -121,6 +121,102 @@ func TestWriteRow(t *testing.T) {
}
}
func TestDeleteRow(t *testing.T) {
tableName := "tricky"
trickySch := dtestutils.CreateSchema(
schema.NewColumn("anotherCol", 0, types.FloatKind, false),
schema.NewColumn("a name with spaces", 1, types.IntKind, true),
)
tests := []test{
{
name: "negative values and columns with spaces",
rows: rs(dtestutils.NewRow(trickySch, types.Float(-3.14), types.Int(-42))),
sch: trickySch,
expectedOutput: "DELETE FROM `tricky` WHERE (`a name with spaces`=-42);" + "\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var stringWr StringBuilderCloser
w := &SqlExportWriter{
tableName: tableName,
sch: tt.sch,
wr: &stringWr,
}
for _, r := range tt.rows {
assert.NoError(t, w.WriteDeleteRow(context.Background(), r))
}
assert.Equal(t, tt.expectedOutput, stringWr.String())
})
}
}
func TestUpdateRow(t *testing.T) {
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
tableName := "people"
tests := []test{
{
name: "simple row",
rows: rs(dtestutils.NewTypedRow(id, "some guy", 100, false, strPointer("normie"))),
sch: dtestutils.TypedSchema,
expectedOutput: "UPDATE `people` SET `name`=\"some guy\",`age`=100,`is_married`=FALSE,`title`=\"normie\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
},
{
name: "embedded quotes",
rows: rs(dtestutils.NewTypedRow(id, `It's "Mister Perfect" to you`, 100, false, strPointer("normie"))),
sch: dtestutils.TypedSchema,
expectedOutput: "UPDATE `people` SET `name`=\"It's \\\"Mister Perfect\\\" to you\",`age`=100,`is_married`=FALSE,`title`=\"normie\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
},
{
name: "two rows",
rows: rs(
dtestutils.NewTypedRow(id, "some guy", 100, false, strPointer("normie")),
dtestutils.NewTypedRow(id, "guy personson", 0, true, strPointer("officially a person"))),
sch: dtestutils.TypedSchema,
expectedOutput: "UPDATE `people` SET `name`=\"some guy\",`age`=100,`is_married`=FALSE,`title`=\"normie\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n" +
"UPDATE `people` SET `name`=\"guy personson\",`age`=0,`is_married`=TRUE,`title`=\"officially a person\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
},
{
name: "null values",
rows: rs(dtestutils.NewTypedRow(id, "some guy", 100, false, nil)),
sch: dtestutils.TypedSchema,
expectedOutput: "UPDATE `people` SET `name`=\"some guy\",`age`=100,`is_married`=FALSE,`title`=NULL WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
},
}
trickySch := dtestutils.CreateSchema(
schema.NewColumn("a name with spaces", 0, types.FloatKind, false),
schema.NewColumn("anotherColumn", 1, types.IntKind, true),
)
tests = append(tests, test{
name: "negative values and columns with spaces",
rows: rs(dtestutils.NewRow(trickySch, types.Float(-3.14), types.Int(-42))),
sch: trickySch,
expectedOutput: "UPDATE `people` SET `a name with spaces`=-3.14 WHERE (`anotherColumn`=-42);" + "\n",
})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var stringWr StringBuilderCloser
w := &SqlExportWriter{
tableName: tableName,
sch: tt.sch,
wr: &stringWr,
}
for _, r := range tt.rows {
assert.NoError(t, w.WriteUpdateRow(context.Background(), r))
}
assert.Equal(t, tt.expectedOutput, stringWr.String())
})
}
}
func TestEndToEnd(t *testing.T) {
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
tableName := "people"
+2
View File
@@ -25,6 +25,7 @@ import (
var AllowedAuthors = map[string]*struct{}{
"Aaron Son <aaron@liquidata.co>": nil,
"Andy Arthur <andy@liquidata.co>": nil,
"Brian Hendriks <brian@liquidata.co>": nil,
"Daylon Wilkins <daylon@liquidata.co>": nil,
"Dustin Brown <dustin@liquidata.co>": nil,
@@ -41,6 +42,7 @@ var AllowedAuthors = map[string]*struct{}{
var AllowedCommitters = map[string]*struct{}{
"Aaron Son <aaron@liquidata.co>": nil,
"Andy Arthur <andy@liquidata.co>": nil,
"Brian Hendriks <brian@liquidata.co>": nil,
"Daylon Wilkins <daylon@liquidata.co>": nil,
"Dustin Brown <dustin@liquidata.co>": nil,