mirror of
https://github.com/dolthub/dolt.git
synced 2026-03-15 19:31:03 -05:00
Starting work on migrating dolt diff:
- temporarily disable `dolt show` - introduce TableInfo struct to maintain SQL table state - update diffWriter to use non-doltdb primitives - update diff.go to use non-doltdb primitives and load most data from SQL
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -28,24 +28,21 @@ import (
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/cli"
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/diff"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/table/editor"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/table/typed/json"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/table/untyped/sqlexport"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/table/untyped/tabular"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/iohelp"
|
||||
"github.com/dolthub/dolt/go/store/atomicerr"
|
||||
)
|
||||
|
||||
// diffWriter is an interface that lets us write diffs in a variety of output formats
|
||||
type diffWriter interface {
|
||||
// BeginTable is called when a new table is about to be written, before any schema or row diffs are written
|
||||
BeginTable(ctx context.Context, td diff.TableDelta) error
|
||||
BeginTable(fromTableName, toTableName string, isAdd, isDrop bool) error
|
||||
// WriteTableSchemaDiff is called to write a schema diff for the table given (if requested by args)
|
||||
WriteTableSchemaDiff(ctx context.Context, fromRoot *doltdb.RootValue, toRoot *doltdb.RootValue, td diff.TableDelta) error
|
||||
WriteTableSchemaDiff(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary) error
|
||||
// WriteEventDiff is called to write an event diff
|
||||
WriteEventDiff(ctx context.Context, eventName, oldDefn, newDefn string) error
|
||||
// WriteTriggerDiff is called to write a trigger diff
|
||||
@@ -54,7 +51,7 @@ type diffWriter interface {
|
||||
WriteViewDiff(ctx context.Context, viewName, oldDefn, newDefn string) error
|
||||
// RowWriter returns a row writer for the table delta provided, which will have Close() called on it when rows are
|
||||
// done being written.
|
||||
RowWriter(ctx context.Context, td diff.TableDelta, unionSch sql.Schema) (diff.SqlRowDiffWriter, error)
|
||||
RowWriter(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary, unionSch sql.Schema) (diff.SqlRowDiffWriter, error)
|
||||
// Close finalizes the work of the writer
|
||||
Close(ctx context.Context) error
|
||||
}
|
||||
@@ -73,34 +70,20 @@ func newDiffWriter(diffOutput diffOutput) (diffWriter, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func printDiffStat(ctx context.Context, td diff.TableDelta, oldColLen, newColLen int) errhand.VerboseError {
|
||||
// todo: use errgroup.Group
|
||||
ae := atomicerr.New()
|
||||
ch := make(chan diff.DiffStatProgress)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
err := diff.StatForTableDelta(ctx, ch, td)
|
||||
|
||||
ae.SetIfError(err)
|
||||
}()
|
||||
|
||||
func printDiffStat(diffStats []diffStatistics, oldColLen, newColLen int, areTablesKeyless bool) errhand.VerboseError {
|
||||
acc := diff.DiffStatProgress{}
|
||||
var count int64
|
||||
var pos int
|
||||
eP := cli.NewEphemeralPrinter()
|
||||
for p := range ch {
|
||||
if ae.IsSet() {
|
||||
break
|
||||
}
|
||||
|
||||
acc.Adds += p.Adds
|
||||
acc.Removes += p.Removes
|
||||
acc.Changes += p.Changes
|
||||
acc.CellChanges += p.CellChanges
|
||||
acc.NewRowSize += p.NewRowSize
|
||||
acc.OldRowSize += p.OldRowSize
|
||||
acc.NewCellSize += p.NewCellSize
|
||||
acc.OldCellSize += p.OldCellSize
|
||||
for _, diffStat := range diffStats {
|
||||
acc.Adds += diffStat.RowsAdded
|
||||
acc.Removes += diffStat.RowsDeleted
|
||||
acc.Changes += diffStat.RowsModified
|
||||
acc.CellChanges += diffStat.CellsModified
|
||||
acc.NewRowSize += diffStat.NewRowCount
|
||||
acc.OldRowSize += diffStat.OldRowCount
|
||||
acc.NewCellSize += diffStat.NewCellCount
|
||||
acc.OldCellSize += diffStat.OldCellCount
|
||||
|
||||
if count%10000 == 0 {
|
||||
eP.Printf("prev size: %d, new size: %d, adds: %d, deletes: %d, modifications: %d\n", acc.OldRowSize, acc.NewRowSize, acc.Adds, acc.Removes, acc.Changes)
|
||||
@@ -112,21 +95,12 @@ func printDiffStat(ctx context.Context, td diff.TableDelta, oldColLen, newColLen
|
||||
|
||||
pos = cli.DeleteAndPrint(pos, "")
|
||||
|
||||
if err := ae.Get(); err != nil {
|
||||
return errhand.BuildDError("").AddCause(err).Build()
|
||||
}
|
||||
|
||||
keyless, err := td.IsKeyless(ctx)
|
||||
if err != nil {
|
||||
return errhand.BuildDError("").AddCause(err).Build()
|
||||
}
|
||||
|
||||
if (acc.Adds+acc.Removes+acc.Changes) == 0 && (acc.OldCellSize-acc.NewCellSize) == 0 {
|
||||
cli.Println("No data changes. See schema changes by using -s or --schema.")
|
||||
return nil
|
||||
}
|
||||
|
||||
if keyless {
|
||||
if areTablesKeyless {
|
||||
printKeylessStat(acc)
|
||||
} else {
|
||||
printStat(acc, oldColLen, newColLen)
|
||||
@@ -195,56 +169,31 @@ func (t tabularDiffWriter) Close(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t tabularDiffWriter) BeginTable(ctx context.Context, td diff.TableDelta) error {
|
||||
func (t tabularDiffWriter) BeginTable(fromTableName, toTableName string, isAdd, isDrop bool) error {
|
||||
bold := color.New(color.Bold)
|
||||
if td.IsDrop() {
|
||||
_, _ = bold.Printf("diff --dolt a/%s b/%s\n", td.FromName, td.FromName)
|
||||
if isDrop {
|
||||
_, _ = bold.Printf("diff --dolt a/%s b/%s\n", fromTableName, fromTableName)
|
||||
_, _ = bold.Println("deleted table")
|
||||
} else if td.IsAdd() {
|
||||
_, _ = bold.Printf("diff --dolt a/%s b/%s\n", td.ToName, td.ToName)
|
||||
} else if isAdd {
|
||||
_, _ = bold.Printf("diff --dolt a/%s b/%s\n", toTableName, toTableName)
|
||||
_, _ = bold.Println("added table")
|
||||
} else {
|
||||
_, _ = bold.Printf("diff --dolt a/%s b/%s\n", td.FromName, td.ToName)
|
||||
h1, err := td.FromTable.HashOf()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, _ = bold.Printf("--- a/%s @ %s\n", td.FromName, h1.String())
|
||||
|
||||
h2, err := td.ToTable.HashOf()
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, _ = bold.Printf("+++ b/%s @ %s\n", td.ToName, h2.String())
|
||||
_, _ = bold.Printf("diff --dolt a/%s b/%s\n", fromTableName, toTableName)
|
||||
_, _ = bold.Printf("--- a/%s\n", fromTableName)
|
||||
_, _ = bold.Printf("+++ b/%s\n", toTableName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t tabularDiffWriter) WriteTableSchemaDiff(ctx context.Context, fromRoot *doltdb.RootValue, toRoot *doltdb.RootValue, td diff.TableDelta) error {
|
||||
func (t tabularDiffWriter) WriteTableSchemaDiff(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary) error {
|
||||
var fromCreateStmt = ""
|
||||
if td.FromTable != nil {
|
||||
sqlDb := sqle.NewUserSpaceDatabase(fromRoot, editor.Options{})
|
||||
sqlCtx, engine, _ := sqle.PrepareCreateTableStmt(ctx, sqlDb)
|
||||
var err error
|
||||
fromCreateStmt, err = sqle.GetCreateTableStmt(sqlCtx, engine, td.FromName)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
if fromTableInfo != nil {
|
||||
fromCreateStmt = fromTableInfo.CreateStmt
|
||||
}
|
||||
|
||||
var toCreateStmt = ""
|
||||
if td.ToTable != nil {
|
||||
sqlDb := sqle.NewUserSpaceDatabase(toRoot, editor.Options{})
|
||||
sqlCtx, engine, _ := sqle.PrepareCreateTableStmt(ctx, sqlDb)
|
||||
var err error
|
||||
toCreateStmt, err = sqle.GetCreateTableStmt(sqlCtx, engine, td.ToName)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
if toTableInfo != nil {
|
||||
toCreateStmt = toTableInfo.CreateStmt
|
||||
}
|
||||
|
||||
if fromCreateStmt != toCreateStmt {
|
||||
@@ -252,18 +201,22 @@ func (t tabularDiffWriter) WriteTableSchemaDiff(ctx context.Context, fromRoot *d
|
||||
}
|
||||
|
||||
resolvedFromFks := map[string]struct{}{}
|
||||
for _, fk := range td.FromFks {
|
||||
if len(fk.ReferencedTableColumns) > 0 {
|
||||
resolvedFromFks[fk.Name] = struct{}{}
|
||||
if fromTableInfo != nil {
|
||||
for _, fk := range fromTableInfo.Fks {
|
||||
if len(fk.ReferencedTableColumns) > 0 {
|
||||
resolvedFromFks[fk.Name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, fk := range td.ToFks {
|
||||
if _, ok := resolvedFromFks[fk.Name]; ok {
|
||||
continue
|
||||
}
|
||||
if len(fk.ReferencedTableColumns) > 0 {
|
||||
cli.Println(fmt.Sprintf("resolved foreign key `%s` on table `%s`", fk.Name, fk.TableName))
|
||||
if toTableInfo != nil {
|
||||
for _, fk := range toTableInfo.Fks {
|
||||
if _, ok := resolvedFromFks[fk.Name]; ok {
|
||||
continue
|
||||
}
|
||||
if len(fk.ReferencedTableColumns) > 0 {
|
||||
cli.Println(fmt.Sprintf("resolved foreign key `%s` on table `%s`", fk.Name, fk.TableName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +239,7 @@ func (t tabularDiffWriter) WriteViewDiff(ctx context.Context, viewName, oldDefn,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t tabularDiffWriter) RowWriter(ctx context.Context, td diff.TableDelta, unionSch sql.Schema) (diff.SqlRowDiffWriter, error) {
|
||||
func (t tabularDiffWriter) RowWriter(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary, unionSch sql.Schema) (diff.SqlRowDiffWriter, error) {
|
||||
return tabular.NewFixedWidthDiffTableWriter(unionSch, iohelp.NopWrCloser(cli.CliOut), 100), nil
|
||||
}
|
||||
|
||||
@@ -298,17 +251,16 @@ func (s sqlDiffWriter) Close(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s sqlDiffWriter) BeginTable(ctx context.Context, td diff.TableDelta) error {
|
||||
func (s sqlDiffWriter) BeginTable(fromTableName, toTableName string, isAdd, isDrop bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s sqlDiffWriter) WriteTableSchemaDiff(ctx context.Context, fromRoot *doltdb.RootValue, toRoot *doltdb.RootValue, td diff.TableDelta) error {
|
||||
toSchemas, err := toRoot.GetAllSchemas(ctx)
|
||||
if err != nil {
|
||||
return errhand.BuildDError("could not read schemas from toRoot").AddCause(err).Build()
|
||||
}
|
||||
func (s sqlDiffWriter) WriteTableSchemaDiff(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary) error {
|
||||
//for _, stmt := range tds.AlterStmts {
|
||||
// cli.Println(stmt)
|
||||
//}
|
||||
|
||||
ddlStatements, err := diff.SqlSchemaDiff(ctx, td, toSchemas)
|
||||
ddlStatements, err := diff.SqlSchemaDiff(fromTableInfo, toTableInfo, tds)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
@@ -362,13 +314,16 @@ func (s sqlDiffWriter) WriteViewDiff(ctx context.Context, viewName, oldDefn, new
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s sqlDiffWriter) RowWriter(ctx context.Context, td diff.TableDelta, unionSch sql.Schema) (diff.SqlRowDiffWriter, error) {
|
||||
targetSch := td.ToSch
|
||||
func (s sqlDiffWriter) RowWriter(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary, unionSch sql.Schema) (diff.SqlRowDiffWriter, error) {
|
||||
var targetSch schema.Schema
|
||||
if toTableInfo != nil {
|
||||
targetSch = toTableInfo.Sch
|
||||
}
|
||||
if targetSch == nil {
|
||||
targetSch = td.FromSch
|
||||
targetSch = fromTableInfo.Sch
|
||||
}
|
||||
|
||||
return sqlexport.NewSqlDiffWriter(td.ToName, targetSch, iohelp.NopWrCloser(cli.CliOut)), nil
|
||||
return sqlexport.NewSqlDiffWriter(tds.ToTableName, targetSch, iohelp.NopWrCloser(cli.CliOut)), nil
|
||||
}
|
||||
|
||||
type jsonDiffWriter struct {
|
||||
@@ -402,7 +357,7 @@ func (j *jsonDiffWriter) beginDocumentIfNecessary() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j *jsonDiffWriter) BeginTable(ctx context.Context, td diff.TableDelta) error {
|
||||
func (j *jsonDiffWriter) BeginTable(fromTableName, toTableName string, isAdd, isDrop bool) error {
|
||||
err := j.beginDocumentIfNecessary()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -420,9 +375,9 @@ func (j *jsonDiffWriter) BeginTable(ctx context.Context, td diff.TableDelta) err
|
||||
}
|
||||
}
|
||||
|
||||
tableName := td.FromName
|
||||
tableName := fromTableName
|
||||
if len(tableName) == 0 {
|
||||
tableName = td.ToName
|
||||
tableName = toTableName
|
||||
}
|
||||
|
||||
err = iohelp.WriteAll(j.wr, []byte(fmt.Sprintf(jsonDiffTableHeader, tableName)))
|
||||
@@ -436,19 +391,21 @@ func (j *jsonDiffWriter) BeginTable(ctx context.Context, td diff.TableDelta) err
|
||||
return err
|
||||
}
|
||||
|
||||
func (j *jsonDiffWriter) WriteTableSchemaDiff(ctx context.Context, fromRoot *doltdb.RootValue, toRoot *doltdb.RootValue, td diff.TableDelta) error {
|
||||
toSchemas, err := toRoot.GetAllSchemas(ctx)
|
||||
if err != nil {
|
||||
return errhand.BuildDError("could not read schemas from toRoot").AddCause(err).Build()
|
||||
}
|
||||
func (j *jsonDiffWriter) WriteTableSchemaDiff(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary) error {
|
||||
//for _, stmt := range tds.AlterStmts {
|
||||
// err := j.schemaDiffWriter.WriteSchemaDiff(stmt)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//}
|
||||
|
||||
stmts, err := diff.SqlSchemaDiff(ctx, td, toSchemas)
|
||||
stmts, err := diff.SqlSchemaDiff(fromTableInfo, toTableInfo, tds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, stmt := range stmts {
|
||||
err := j.schemaDiffWriter.WriteSchemaDiff(ctx, stmt)
|
||||
err := j.schemaDiffWriter.WriteSchemaDiff(stmt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -457,7 +414,7 @@ func (j *jsonDiffWriter) WriteTableSchemaDiff(ctx context.Context, fromRoot *dol
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j *jsonDiffWriter) RowWriter(ctx context.Context, td diff.TableDelta, unionSch sql.Schema) (diff.SqlRowDiffWriter, error) {
|
||||
func (j *jsonDiffWriter) RowWriter(fromTableInfo, toTableInfo *diff.TableInfo, tds diff.TableDeltaSummary, unionSch sql.Schema) (diff.SqlRowDiffWriter, error) {
|
||||
// close off the schema diff block, start the data block
|
||||
err := iohelp.WriteAll(j.wr, []byte(jsonDiffDataDiffHeader))
|
||||
if err != nil {
|
||||
|
||||
@@ -14,353 +14,353 @@
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/cli"
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
|
||||
eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/env"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/argparser"
|
||||
"github.com/dolthub/dolt/go/store/datas"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/util/outputpager"
|
||||
)
|
||||
|
||||
var hashRegex = regexp.MustCompile(`^#?[0-9a-v]{32}$`)
|
||||
|
||||
type showOpts struct {
|
||||
showParents bool
|
||||
pretty bool
|
||||
decoration string
|
||||
specRefs []string
|
||||
|
||||
*diffDisplaySettings
|
||||
}
|
||||
|
||||
var showDocs = cli.CommandDocumentationContent{
|
||||
ShortDesc: `Show information about a specific commit`,
|
||||
LongDesc: `Show information about a specific commit`,
|
||||
Synopsis: []string{
|
||||
`[{{.LessThan}}revision{{.GreaterThan}}]`,
|
||||
},
|
||||
}
|
||||
|
||||
type ShowCmd struct{}
|
||||
|
||||
// Name returns the name of the Dolt cli command. This is what is used on the command line to invoke the command
|
||||
func (cmd ShowCmd) Name() string {
|
||||
return "show"
|
||||
}
|
||||
|
||||
// Description returns a description of the command
|
||||
func (cmd ShowCmd) Description() string {
|
||||
return "Show information about a specific commit."
|
||||
}
|
||||
|
||||
// EventType returns the type of the event to log
|
||||
func (cmd ShowCmd) EventType() eventsapi.ClientEventType {
|
||||
return eventsapi.ClientEventType_SHOW
|
||||
}
|
||||
|
||||
func (cmd ShowCmd) Docs() *cli.CommandDocumentation {
|
||||
ap := cmd.ArgParser()
|
||||
return cli.NewCommandDocumentation(showDocs, ap)
|
||||
}
|
||||
|
||||
func (cmd ShowCmd) ArgParser() *argparser.ArgParser {
|
||||
ap := argparser.NewArgParserWithVariableArgs(cmd.Name())
|
||||
// Flags inherited from Log
|
||||
ap.SupportsFlag(cli.ParentsFlag, "", "Shows all parents of each commit in the log.")
|
||||
ap.SupportsString(cli.DecorateFlag, "", "decorate_fmt", "Shows refs next to commits. Valid options are short, full, no, and auto")
|
||||
ap.SupportsFlag(cli.NoPrettyFlag, "", "Show the object without making it pretty.")
|
||||
|
||||
// Flags inherited from Diff
|
||||
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(StatFlag, "", "Show stats of data changes")
|
||||
ap.SupportsFlag(SummaryFlag, "", "Show summary of data and schema changes")
|
||||
ap.SupportsString(FormatFlag, "r", "result output format", "How to format diff output. Valid values are tabular, sql, json. Defaults to tabular.")
|
||||
ap.SupportsString(whereParam, "", "column", "filters columns based on values in the diff. See {{.EmphasisLeft}}dolt diff --help{{.EmphasisRight}} for details.")
|
||||
ap.SupportsInt(limitParam, "", "record_count", "limits to the first N diffs.")
|
||||
ap.SupportsFlag(cli.CachedFlag, "c", "Show only the staged data changes.")
|
||||
ap.SupportsFlag(SkinnyFlag, "sk", "Shows only primary key columns and any columns with data changes.")
|
||||
ap.SupportsFlag(MergeBase, "", "Uses merge base of the first commit and second commit (or HEAD if not supplied) as the first commit")
|
||||
ap.SupportsString(DiffMode, "", "diff mode", "Determines how to display modified rows with tabular output. Valid values are row, line, in-place, context. Defaults to context.")
|
||||
return ap
|
||||
}
|
||||
|
||||
// Exec executes the command
|
||||
func (cmd ShowCmd) Exec(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv, cliCtx cli.CliContext) int {
|
||||
ap := cmd.ArgParser()
|
||||
help, usage := cli.HelpAndUsagePrinters(cli.CommandDocsForCommandString(commandStr, showDocs, ap))
|
||||
apr := cli.ParseArgsOrDie(ap, args, help)
|
||||
|
||||
opts, err := parseShowArgs(ctx, dEnv, apr)
|
||||
if err != nil {
|
||||
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
}
|
||||
|
||||
if err := cmd.validateArgs(apr); err != nil {
|
||||
return handleErrAndExit(err)
|
||||
}
|
||||
|
||||
if !opts.pretty && !dEnv.DoltDB.Format().UsesFlatbuffers() {
|
||||
cli.PrintErrln("dolt show --no-pretty is not supported when using old LD_1 storage format.")
|
||||
return 1
|
||||
}
|
||||
|
||||
opts.diffDisplaySettings = parseDiffDisplaySettings(ctx, dEnv, apr)
|
||||
|
||||
err = showObjects(ctx, dEnv, opts)
|
||||
|
||||
return handleErrAndExit(err)
|
||||
}
|
||||
|
||||
func (cmd ShowCmd) validateArgs(apr *argparser.ArgParseResults) errhand.VerboseError {
|
||||
if apr.Contains(StatFlag) || apr.Contains(SummaryFlag) {
|
||||
if apr.Contains(SchemaFlag) || apr.Contains(DataFlag) {
|
||||
return errhand.BuildDError("invalid Arguments: --stat and --summary cannot be combined with --schema or --data").Build()
|
||||
}
|
||||
}
|
||||
|
||||
f, _ := apr.GetValue(FormatFlag)
|
||||
switch strings.ToLower(f) {
|
||||
case "tabular", "sql", "json", "":
|
||||
default:
|
||||
return errhand.BuildDError("invalid output format: %s", f).Build()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseShowArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults) (*showOpts, error) {
|
||||
|
||||
decorateOption := apr.GetValueOrDefault(cli.DecorateFlag, "auto")
|
||||
switch decorateOption {
|
||||
case "short", "full", "auto", "no":
|
||||
default:
|
||||
return nil, fmt.Errorf("fatal: invalid --decorate option: %s", decorateOption)
|
||||
}
|
||||
|
||||
return &showOpts{
|
||||
showParents: apr.Contains(cli.ParentsFlag),
|
||||
pretty: !apr.Contains(cli.NoPrettyFlag),
|
||||
decoration: decorateOption,
|
||||
specRefs: apr.Args,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func showObjects(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts) error {
|
||||
if len(opts.specRefs) == 0 {
|
||||
headRef, err := dEnv.RepoStateReader().CWBHeadSpec()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return showCommitSpec(ctx, dEnv, opts, headRef)
|
||||
}
|
||||
|
||||
for _, specRef := range opts.specRefs {
|
||||
err := showSpecRef(ctx, dEnv, opts, specRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseHashString converts a string representing a hash into a hash.Hash.
|
||||
func parseHashString(hashStr string) (hash.Hash, error) {
|
||||
unprefixed := strings.TrimPrefix(hashStr, "#")
|
||||
parsedHash, ok := hash.MaybeParse(unprefixed)
|
||||
if !ok {
|
||||
return hash.Hash{}, errors.New("invalid hash: " + hashStr)
|
||||
}
|
||||
return parsedHash, nil
|
||||
}
|
||||
|
||||
func showSpecRef(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, specRef string) error {
|
||||
roots, err := dEnv.Roots(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
upperCaseSpecRef := strings.ToUpper(specRef)
|
||||
if upperCaseSpecRef == doltdb.Working || upperCaseSpecRef == doltdb.Staged || hashRegex.MatchString(specRef) {
|
||||
var refHash hash.Hash
|
||||
var err error
|
||||
if upperCaseSpecRef == doltdb.Working {
|
||||
refHash, err = roots.Working.HashOf()
|
||||
} else if upperCaseSpecRef == doltdb.Staged {
|
||||
refHash, err = roots.Staged.HashOf()
|
||||
} else {
|
||||
refHash, err = parseHashString(specRef)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value, err := dEnv.DoltDB.ValueReadWriter().ReadValue(ctx, refHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if value == nil {
|
||||
return fmt.Errorf("Unable to resolve object ref %s", specRef)
|
||||
}
|
||||
|
||||
if !opts.pretty {
|
||||
cli.Println(value.Kind(), value.HumanReadableString())
|
||||
}
|
||||
|
||||
// If this is a commit, use the pretty printer. To determine whether it's a commit, try calling NewCommitFromValue.
|
||||
commit, err := doltdb.NewCommitFromValue(ctx, dEnv.DoltDB.ValueReadWriter(), dEnv.DoltDB.NodeStore(), value)
|
||||
|
||||
if err == datas.ErrNotACommit {
|
||||
if !dEnv.DoltDB.Format().UsesFlatbuffers() {
|
||||
return fmt.Errorf("dolt show cannot show non-commit objects when using the old LD_1 storage format: %s is not a commit", specRef)
|
||||
}
|
||||
cli.Println(value.Kind(), value.HumanReadableString())
|
||||
} else if err == nil {
|
||||
showCommit(ctx, dEnv, opts, commit)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else { // specRef is a CommitSpec, which must resolve to a Commit.
|
||||
commitSpec, err := getCommitSpec(specRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = showCommitSpec(ctx, dEnv, opts, commitSpec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func showCommitSpec(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, commitSpec *doltdb.CommitSpec) error {
|
||||
|
||||
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commit, err := dEnv.DoltDB.Resolve(ctx, commitSpec, headRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.pretty {
|
||||
err = showCommit(ctx, dEnv, opts, commit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
value := commit.Value()
|
||||
cli.Println(value.Kind(), value.HumanReadableString())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func showCommit(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, comm *doltdb.Commit) error {
|
||||
|
||||
cHashToRefs, err := getHashToRefs(ctx, dEnv, opts.decoration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
meta, mErr := comm.GetCommitMeta(ctx)
|
||||
if mErr != nil {
|
||||
cli.PrintErrln("error: failed to get commit metadata")
|
||||
return err
|
||||
}
|
||||
pHashes, pErr := comm.ParentHashes(ctx)
|
||||
if pErr != nil {
|
||||
cli.PrintErrln("error: failed to get parent hashes")
|
||||
return err
|
||||
}
|
||||
cmHash, cErr := comm.HashOf()
|
||||
if cErr != nil {
|
||||
cli.PrintErrln("error: failed to get commit hash")
|
||||
return err
|
||||
}
|
||||
|
||||
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cwbHash, err := dEnv.DoltDB.GetHashForRefStr(ctx, headRef.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cli.ExecuteWithStdioRestored(func() {
|
||||
pager := outputpager.Start()
|
||||
defer pager.Stop()
|
||||
|
||||
PrintCommit(pager, 0, opts.showParents, opts.decoration, logNode{
|
||||
commitMeta: meta,
|
||||
commitHash: cmHash,
|
||||
parentHashes: pHashes,
|
||||
branchNames: cHashToRefs[cmHash],
|
||||
isHead: cmHash == *cwbHash})
|
||||
})
|
||||
|
||||
if comm.NumParents() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if comm.NumParents() > 1 {
|
||||
return fmt.Errorf("requested commit is a merge commit. 'dolt show' currently only supports viewing non-merge commits")
|
||||
}
|
||||
|
||||
commitRoot, err := comm.GetRootValue(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parent, err := comm.GetParent(ctx, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parentRoot, err := parent.GetRootValue(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parentHash, err := parent.HashOf()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
datasets := &diffDatasets{
|
||||
fromRoot: parentRoot,
|
||||
toRoot: commitRoot,
|
||||
fromRef: parentHash.String(),
|
||||
toRef: cmHash.String(),
|
||||
}
|
||||
|
||||
// An empty string will cause all tables to be printed.
|
||||
var tableNames []string
|
||||
|
||||
tableSet, err := parseDiffTableSet(ctx, dEnv, datasets, tableNames)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dArgs := &diffArgs{
|
||||
diffDisplaySettings: opts.diffDisplaySettings,
|
||||
diffDatasets: datasets,
|
||||
tableSet: tableSet,
|
||||
}
|
||||
|
||||
return diffUserTables(ctx, dEnv, dArgs)
|
||||
}
|
||||
//import (
|
||||
// "context"
|
||||
// "fmt"
|
||||
// "regexp"
|
||||
// "strings"
|
||||
//
|
||||
// "github.com/pkg/errors"
|
||||
//
|
||||
// "github.com/dolthub/dolt/go/cmd/dolt/cli"
|
||||
// "github.com/dolthub/dolt/go/cmd/dolt/errhand"
|
||||
// eventsapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/eventsapi/v1alpha1"
|
||||
// "github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
// "github.com/dolthub/dolt/go/libraries/doltcore/env"
|
||||
// "github.com/dolthub/dolt/go/libraries/utils/argparser"
|
||||
// "github.com/dolthub/dolt/go/store/datas"
|
||||
// "github.com/dolthub/dolt/go/store/hash"
|
||||
// "github.com/dolthub/dolt/go/store/util/outputpager"
|
||||
//)
|
||||
//
|
||||
//var hashRegex = regexp.MustCompile(`^#?[0-9a-v]{32}$`)
|
||||
//
|
||||
//type showOpts struct {
|
||||
// showParents bool
|
||||
// pretty bool
|
||||
// decoration string
|
||||
// specRefs []string
|
||||
//
|
||||
// *diffDisplaySettings
|
||||
//}
|
||||
//
|
||||
//var showDocs = cli.CommandDocumentationContent{
|
||||
// ShortDesc: `Show information about a specific commit`,
|
||||
// LongDesc: `Show information about a specific commit`,
|
||||
// Synopsis: []string{
|
||||
// `[{{.LessThan}}revision{{.GreaterThan}}]`,
|
||||
// },
|
||||
//}
|
||||
//
|
||||
//type ShowCmd struct{}
|
||||
//
|
||||
//// Name returns the name of the Dolt cli command. This is what is used on the command line to invoke the command
|
||||
//func (cmd ShowCmd) Name() string {
|
||||
// return "show"
|
||||
//}
|
||||
//
|
||||
//// Description returns a description of the command
|
||||
//func (cmd ShowCmd) Description() string {
|
||||
// return "Show information about a specific commit."
|
||||
//}
|
||||
//
|
||||
//// EventType returns the type of the event to log
|
||||
//func (cmd ShowCmd) EventType() eventsapi.ClientEventType {
|
||||
// return eventsapi.ClientEventType_SHOW
|
||||
//}
|
||||
//
|
||||
//func (cmd ShowCmd) Docs() *cli.CommandDocumentation {
|
||||
// ap := cmd.ArgParser()
|
||||
// return cli.NewCommandDocumentation(showDocs, ap)
|
||||
//}
|
||||
//
|
||||
//func (cmd ShowCmd) ArgParser() *argparser.ArgParser {
|
||||
// ap := argparser.NewArgParserWithVariableArgs(cmd.Name())
|
||||
// // Flags inherited from Log
|
||||
// ap.SupportsFlag(cli.ParentsFlag, "", "Shows all parents of each commit in the log.")
|
||||
// ap.SupportsString(cli.DecorateFlag, "", "decorate_fmt", "Shows refs next to commits. Valid options are short, full, no, and auto")
|
||||
// ap.SupportsFlag(cli.NoPrettyFlag, "", "Show the object without making it pretty.")
|
||||
//
|
||||
// // Flags inherited from Diff
|
||||
// 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(StatFlag, "", "Show stats of data changes")
|
||||
// ap.SupportsFlag(SummaryFlag, "", "Show summary of data and schema changes")
|
||||
// ap.SupportsString(FormatFlag, "r", "result output format", "How to format diff output. Valid values are tabular, sql, json. Defaults to tabular.")
|
||||
// ap.SupportsString(whereParam, "", "column", "filters columns based on values in the diff. See {{.EmphasisLeft}}dolt diff --help{{.EmphasisRight}} for details.")
|
||||
// ap.SupportsInt(limitParam, "", "record_count", "limits to the first N diffs.")
|
||||
// ap.SupportsFlag(cli.CachedFlag, "c", "Show only the staged data changes.")
|
||||
// ap.SupportsFlag(SkinnyFlag, "sk", "Shows only primary key columns and any columns with data changes.")
|
||||
// ap.SupportsFlag(MergeBase, "", "Uses merge base of the first commit and second commit (or HEAD if not supplied) as the first commit")
|
||||
// ap.SupportsString(DiffMode, "", "diff mode", "Determines how to display modified rows with tabular output. Valid values are row, line, in-place, context. Defaults to context.")
|
||||
// return ap
|
||||
//}
|
||||
//
|
||||
//// Exec executes the command
|
||||
//func (cmd ShowCmd) Exec(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv, cliCtx cli.CliContext) int {
|
||||
// ap := cmd.ArgParser()
|
||||
// help, usage := cli.HelpAndUsagePrinters(cli.CommandDocsForCommandString(commandStr, showDocs, ap))
|
||||
// apr := cli.ParseArgsOrDie(ap, args, help)
|
||||
//
|
||||
// opts, err := parseShowArgs(ctx, dEnv, apr)
|
||||
// if err != nil {
|
||||
// return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
|
||||
// }
|
||||
//
|
||||
// if err := cmd.validateArgs(apr); err != nil {
|
||||
// return handleErrAndExit(err)
|
||||
// }
|
||||
//
|
||||
// if !opts.pretty && !dEnv.DoltDB.Format().UsesFlatbuffers() {
|
||||
// cli.PrintErrln("dolt show --no-pretty is not supported when using old LD_1 storage format.")
|
||||
// return 1
|
||||
// }
|
||||
//
|
||||
// opts.diffDisplaySettings = parseDiffDisplaySettings(ctx, dEnv, apr)
|
||||
//
|
||||
// err = showObjects(ctx, dEnv, opts)
|
||||
//
|
||||
// return handleErrAndExit(err)
|
||||
//}
|
||||
//
|
||||
//func (cmd ShowCmd) validateArgs(apr *argparser.ArgParseResults) errhand.VerboseError {
|
||||
// if apr.Contains(StatFlag) || apr.Contains(SummaryFlag) {
|
||||
// if apr.Contains(SchemaFlag) || apr.Contains(DataFlag) {
|
||||
// return errhand.BuildDError("invalid Arguments: --stat and --summary cannot be combined with --schema or --data").Build()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// f, _ := apr.GetValue(FormatFlag)
|
||||
// switch strings.ToLower(f) {
|
||||
// case "tabular", "sql", "json", "":
|
||||
// default:
|
||||
// return errhand.BuildDError("invalid output format: %s", f).Build()
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func parseShowArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults) (*showOpts, error) {
|
||||
//
|
||||
// decorateOption := apr.GetValueOrDefault(cli.DecorateFlag, "auto")
|
||||
// switch decorateOption {
|
||||
// case "short", "full", "auto", "no":
|
||||
// default:
|
||||
// return nil, fmt.Errorf("fatal: invalid --decorate option: %s", decorateOption)
|
||||
// }
|
||||
//
|
||||
// return &showOpts{
|
||||
// showParents: apr.Contains(cli.ParentsFlag),
|
||||
// pretty: !apr.Contains(cli.NoPrettyFlag),
|
||||
// decoration: decorateOption,
|
||||
// specRefs: apr.Args,
|
||||
// }, nil
|
||||
//}
|
||||
//
|
||||
//func showObjects(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts) error {
|
||||
// if len(opts.specRefs) == 0 {
|
||||
// headRef, err := dEnv.RepoStateReader().CWBHeadSpec()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return showCommitSpec(ctx, dEnv, opts, headRef)
|
||||
// }
|
||||
//
|
||||
// for _, specRef := range opts.specRefs {
|
||||
// err := showSpecRef(ctx, dEnv, opts, specRef)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//// parseHashString converts a string representing a hash into a hash.Hash.
|
||||
//func parseHashString(hashStr string) (hash.Hash, error) {
|
||||
// unprefixed := strings.TrimPrefix(hashStr, "#")
|
||||
// parsedHash, ok := hash.MaybeParse(unprefixed)
|
||||
// if !ok {
|
||||
// return hash.Hash{}, errors.New("invalid hash: " + hashStr)
|
||||
// }
|
||||
// return parsedHash, nil
|
||||
//}
|
||||
//
|
||||
//func showSpecRef(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, specRef string) error {
|
||||
// roots, err := dEnv.Roots(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// upperCaseSpecRef := strings.ToUpper(specRef)
|
||||
// if upperCaseSpecRef == doltdb.Working || upperCaseSpecRef == doltdb.Staged || hashRegex.MatchString(specRef) {
|
||||
// var refHash hash.Hash
|
||||
// var err error
|
||||
// if upperCaseSpecRef == doltdb.Working {
|
||||
// refHash, err = roots.Working.HashOf()
|
||||
// } else if upperCaseSpecRef == doltdb.Staged {
|
||||
// refHash, err = roots.Staged.HashOf()
|
||||
// } else {
|
||||
// refHash, err = parseHashString(specRef)
|
||||
// }
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// value, err := dEnv.DoltDB.ValueReadWriter().ReadValue(ctx, refHash)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if value == nil {
|
||||
// return fmt.Errorf("Unable to resolve object ref %s", specRef)
|
||||
// }
|
||||
//
|
||||
// if !opts.pretty {
|
||||
// cli.Println(value.Kind(), value.HumanReadableString())
|
||||
// }
|
||||
//
|
||||
// // If this is a commit, use the pretty printer. To determine whether it's a commit, try calling NewCommitFromValue.
|
||||
// commit, err := doltdb.NewCommitFromValue(ctx, dEnv.DoltDB.ValueReadWriter(), dEnv.DoltDB.NodeStore(), value)
|
||||
//
|
||||
// if err == datas.ErrNotACommit {
|
||||
// if !dEnv.DoltDB.Format().UsesFlatbuffers() {
|
||||
// return fmt.Errorf("dolt show cannot show non-commit objects when using the old LD_1 storage format: %s is not a commit", specRef)
|
||||
// }
|
||||
// cli.Println(value.Kind(), value.HumanReadableString())
|
||||
// } else if err == nil {
|
||||
// showCommit(ctx, dEnv, opts, commit)
|
||||
// } else {
|
||||
// return err
|
||||
// }
|
||||
// } else { // specRef is a CommitSpec, which must resolve to a Commit.
|
||||
// commitSpec, err := getCommitSpec(specRef)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// err = showCommitSpec(ctx, dEnv, opts, commitSpec)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func showCommitSpec(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, commitSpec *doltdb.CommitSpec) error {
|
||||
//
|
||||
// headRef, err := dEnv.RepoStateReader().CWBHeadRef()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// commit, err := dEnv.DoltDB.Resolve(ctx, commitSpec, headRef)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// if opts.pretty {
|
||||
// err = showCommit(ctx, dEnv, opts, commit)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// } else {
|
||||
// value := commit.Value()
|
||||
// cli.Println(value.Kind(), value.HumanReadableString())
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func showCommit(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, comm *doltdb.Commit) error {
|
||||
//
|
||||
// cHashToRefs, err := getHashToRefs(ctx, dEnv, opts.decoration)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// meta, mErr := comm.GetCommitMeta(ctx)
|
||||
// if mErr != nil {
|
||||
// cli.PrintErrln("error: failed to get commit metadata")
|
||||
// return err
|
||||
// }
|
||||
// pHashes, pErr := comm.ParentHashes(ctx)
|
||||
// if pErr != nil {
|
||||
// cli.PrintErrln("error: failed to get parent hashes")
|
||||
// return err
|
||||
// }
|
||||
// cmHash, cErr := comm.HashOf()
|
||||
// if cErr != nil {
|
||||
// cli.PrintErrln("error: failed to get commit hash")
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// headRef, err := dEnv.RepoStateReader().CWBHeadRef()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// cwbHash, err := dEnv.DoltDB.GetHashForRefStr(ctx, headRef.String())
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// cli.ExecuteWithStdioRestored(func() {
|
||||
// pager := outputpager.Start()
|
||||
// defer pager.Stop()
|
||||
//
|
||||
// PrintCommit(pager, 0, opts.showParents, opts.decoration, logNode{
|
||||
// commitMeta: meta,
|
||||
// commitHash: cmHash,
|
||||
// parentHashes: pHashes,
|
||||
// branchNames: cHashToRefs[cmHash],
|
||||
// isHead: cmHash == *cwbHash})
|
||||
// })
|
||||
//
|
||||
// if comm.NumParents() == 0 {
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// if comm.NumParents() > 1 {
|
||||
// return fmt.Errorf("requested commit is a merge commit. 'dolt show' currently only supports viewing non-merge commits")
|
||||
// }
|
||||
//
|
||||
// commitRoot, err := comm.GetRootValue(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// parent, err := comm.GetParent(ctx, 0)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// parentRoot, err := parent.GetRootValue(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// parentHash, err := parent.HashOf()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// datasets := &diffDatasets{
|
||||
// fromRoot: parentRoot,
|
||||
// toRoot: commitRoot,
|
||||
// fromRef: parentHash.String(),
|
||||
// toRef: cmHash.String(),
|
||||
// }
|
||||
//
|
||||
// // An empty string will cause all tables to be printed.
|
||||
// var tableNames []string
|
||||
//
|
||||
// tableSet, err := parseDiffTableSet(ctx, dEnv, datasets, tableNames)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// dArgs := &diffArgs{
|
||||
// diffDisplaySettings: opts.diffDisplaySettings,
|
||||
// diffDatasets: datasets,
|
||||
// tableSet: tableSet,
|
||||
// }
|
||||
//
|
||||
// return diffUserTables(ctx, dEnv, dArgs)
|
||||
//}
|
||||
|
||||
@@ -80,7 +80,7 @@ var doltSubCommands = []cli.Command{
|
||||
sqlserver.SqlServerCmd{VersionStr: Version},
|
||||
sqlserver.SqlClientCmd{VersionStr: Version},
|
||||
commands.LogCmd{},
|
||||
commands.ShowCmd{},
|
||||
//commands.ShowCmd{},
|
||||
commands.BranchCmd{},
|
||||
commands.CheckoutCmd{},
|
||||
commands.MergeCmd{},
|
||||
@@ -121,14 +121,12 @@ var doltSubCommands = []cli.Command{
|
||||
}
|
||||
|
||||
var commandsWithoutCliCtx = []cli.Command{
|
||||
commands.DiffCmd{},
|
||||
commands.ResetCmd{},
|
||||
commands.CleanCmd{},
|
||||
admin.Commands,
|
||||
sqlserver.SqlServerCmd{VersionStr: Version},
|
||||
sqlserver.SqlClientCmd{VersionStr: Version},
|
||||
commands.LogCmd{},
|
||||
commands.ShowCmd{},
|
||||
commands.CheckoutCmd{},
|
||||
cnfcmds.Commands,
|
||||
commands.CloneCmd{},
|
||||
|
||||
@@ -85,7 +85,7 @@ type SqlRowDiffWriter interface {
|
||||
type SchemaDiffWriter interface {
|
||||
// WriteSchemaDiff writes the schema diff given (a SQL statement) and returns any error. A single table may have
|
||||
// many SQL statements for a single diff. WriteSchemaDiff will be called before any row diffs via |WriteRow|
|
||||
WriteSchemaDiff(ctx context.Context, schemaDiffStatement string) error
|
||||
WriteSchemaDiff(schemaDiffStatement string) error
|
||||
// Close finalizes the work of this writer.
|
||||
Close(ctx context.Context) error
|
||||
}
|
||||
|
||||
@@ -21,12 +21,10 @@ import (
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb/durable"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlfmt"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/set"
|
||||
"github.com/dolthub/dolt/go/store/prolly/tree"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
@@ -41,6 +39,11 @@ const (
|
||||
RemovedTable
|
||||
)
|
||||
|
||||
type TableInfo struct {
|
||||
Name string
|
||||
Sch schema.Schema
|
||||
CreateStmt string
|
||||
}
|
||||
// TableDelta represents the change of a single table between two roots.
|
||||
// FromFKs and ToFKs contain Foreign Keys that constrain columns in this table,
|
||||
// they do not contain Foreign Keys that reference this table.
|
||||
@@ -68,6 +71,24 @@ type TableDeltaSummary struct {
|
||||
TableName string
|
||||
FromTableName string
|
||||
ToTableName string
|
||||
AlterStmts []string
|
||||
}
|
||||
// IsAdd returns true if the table was added between the fromRoot and toRoot.
|
||||
func (tds TableDeltaSummary) IsAdd() bool {
|
||||
return tds.FromTableName == "" && tds.ToTableName != ""
|
||||
}
|
||||
|
||||
// IsDrop returns true if the table was dropped between the fromRoot and toRoot.
|
||||
func (tds TableDeltaSummary) IsDrop() bool {
|
||||
return tds.FromTableName != "" && tds.ToTableName == ""
|
||||
}
|
||||
|
||||
// IsRename return true if the table was renamed between the fromRoot and toRoot.
|
||||
func (tds TableDeltaSummary) IsRename() bool {
|
||||
if tds.IsAdd() || tds.IsDrop() {
|
||||
return false
|
||||
}
|
||||
return tds.FromTableName != tds.ToTableName
|
||||
}
|
||||
|
||||
// GetStagedUnstagedTableDeltas represents staged and unstaged changes as TableDelta slices.
|
||||
@@ -562,27 +583,15 @@ func (td TableDelta) GetRowData(ctx context.Context) (from, to durable.Index, er
|
||||
|
||||
// SqlSchemaDiff returns a slice of DDL statements that will transform the schema in the from delta to the schema in
|
||||
// the to delta.
|
||||
func SqlSchemaDiff(ctx context.Context, td TableDelta, toSchemas map[string]schema.Schema) ([]string, error) {
|
||||
fromSch, toSch, err := td.GetSchemas(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot retrieve schema for table %s, cause: %s", td.ToName, err.Error())
|
||||
}
|
||||
func SqlSchemaDiff(fromTableInfo, toTableInfo *TableInfo, tds TableDeltaSummary) ([]string, error) {
|
||||
|
||||
var ddlStatements []string
|
||||
if td.IsDrop() {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.DropTableStmt(td.FromName))
|
||||
} else if td.IsAdd() {
|
||||
toPkSch, err := sqlutil.FromDoltSchema(td.ToName, td.ToSch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stmt, err := GenerateCreateTableStatement(td.ToName, td.ToSch, toPkSch, td.ToFks, td.ToFksParentSch)
|
||||
if err != nil {
|
||||
return nil, errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
ddlStatements = append(ddlStatements, stmt)
|
||||
if tds.IsDrop() {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.DropTableStmt(tds.FromTableName))
|
||||
} else if tds.IsAdd() {
|
||||
ddlStatements = append(ddlStatements, toTableInfo.CreateStmt)
|
||||
} else {
|
||||
stmts, err := GetNonCreateNonDropTableSqlSchemaDiff(td, toSchemas, fromSch, toSch)
|
||||
stmts, err := GetNonCreateNonDropTableSqlSchemaDiff(tds, fromTableInfo, toTableInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -593,47 +602,32 @@ func SqlSchemaDiff(ctx context.Context, td TableDelta, toSchemas map[string]sche
|
||||
}
|
||||
|
||||
// GetNonCreateNonDropTableSqlSchemaDiff returns any schema diff in SQL statements that is NEITHER 'CREATE TABLE' NOR 'DROP TABLE' statements.
|
||||
func GetNonCreateNonDropTableSqlSchemaDiff(td TableDelta, toSchemas map[string]schema.Schema, fromSch, toSch schema.Schema) ([]string, error) {
|
||||
if td.IsAdd() || td.IsDrop() {
|
||||
func GetNonCreateNonDropTableSqlSchemaDiff(tds TableDeltaSummary, fromTableInfo, toTableInfo *TableInfo) ([]string, error) {
|
||||
if tds.IsAdd() || tds.IsDrop() {
|
||||
// use add and drop specific methods
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var ddlStatements []string
|
||||
if td.FromName != td.ToName {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.RenameTableStmt(td.FromName, td.ToName))
|
||||
if tds.FromTableName != tds.ToTableName {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.RenameTableStmt(tds.FromTableName, tds.ToTableName))
|
||||
}
|
||||
|
||||
fromSch := fromTableInfo.Sch
|
||||
toSch := toTableInfo.Sch
|
||||
|
||||
eq := schema.SchemasAreEqual(fromSch, toSch)
|
||||
if eq && !td.HasFKChanges() {
|
||||
if eq && !hasFkChanges(fromTableInfo, toTableInfo) {
|
||||
return ddlStatements, nil
|
||||
}
|
||||
|
||||
colDiffs, unionTags := DiffSchColumns(fromSch, toSch)
|
||||
for _, tag := range unionTags {
|
||||
cd := colDiffs[tag]
|
||||
switch cd.DiffType {
|
||||
case SchDiffNone:
|
||||
case SchDiffAdded:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddColStmt(td.ToName, sqlfmt.GenerateCreateTableColumnDefinition(*cd.New)))
|
||||
case SchDiffRemoved:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropColStmt(td.ToName, cd.Old.Name))
|
||||
case SchDiffModified:
|
||||
// Ignore any primary key set changes here
|
||||
if cd.Old.IsPartOfPK != cd.New.IsPartOfPK {
|
||||
continue
|
||||
}
|
||||
if cd.Old.Name != cd.New.Name {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableRenameColStmt(td.ToName, cd.Old.Name, cd.New.Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
ddlStatements = append(ddlStatements, tds.AlterStmts...)
|
||||
|
||||
// Print changes between a primary key set change. It contains an ALTER TABLE DROP and an ALTER TABLE ADD
|
||||
if !schema.ColCollsAreEqual(fromSch.GetPKCols(), toSch.GetPKCols()) {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropPks(td.ToName))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropPks(tds.ToTableName))
|
||||
if toSch.GetPKCols().Size() > 0 {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddPrimaryKeys(td.ToName, toSch.GetPKCols()))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddPrimaryKeys(tds.ToTableName, toSch.GetPKCols().GetColumnNames()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,28 +635,27 @@ func GetNonCreateNonDropTableSqlSchemaDiff(td TableDelta, toSchemas map[string]s
|
||||
switch idxDiff.DiffType {
|
||||
case SchDiffNone:
|
||||
case SchDiffAdded:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddIndexStmt(td.ToName, idxDiff.To))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddIndexStmt(tds.ToTableName, idxDiff.To))
|
||||
case SchDiffRemoved:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropIndexStmt(td.FromName, idxDiff.From))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropIndexStmt(tds.FromTableName, idxDiff.From))
|
||||
case SchDiffModified:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropIndexStmt(td.FromName, idxDiff.From))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddIndexStmt(td.ToName, idxDiff.To))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropIndexStmt(tds.FromTableName, idxDiff.From))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddIndexStmt(tds.ToTableName, idxDiff.To))
|
||||
}
|
||||
}
|
||||
|
||||
for _, fkDiff := range DiffForeignKeys(td.FromFks, td.ToFks) {
|
||||
for _, fkDiff := range DiffForeignKeyInfos(fromTableInfo.Fks, toTableInfo.Fks) {
|
||||
switch fkDiff.DiffType {
|
||||
case SchDiffNone:
|
||||
case SchDiffAdded:
|
||||
parentSch := toSchemas[fkDiff.To.ReferencedTableName]
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddForeignKeyStmt(fkDiff.To, toSch, parentSch))
|
||||
to := fkDiff.To
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddForeignKeyStmtSimple(to.TableName, to.Name, to.ReferencedTableName, to.TableColumns, to.ReferencedTableColumns))
|
||||
case SchDiffRemoved:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropForeignKeyStmt(fkDiff.From))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropForeignKeyStmt(fkDiff.From.TableName, fkDiff.From.Name))
|
||||
case SchDiffModified:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropForeignKeyStmt(fkDiff.From))
|
||||
|
||||
parentSch := toSchemas[fkDiff.To.ReferencedTableName]
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddForeignKeyStmt(fkDiff.To, toSch, parentSch))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropForeignKeyStmt(fkDiff.From.TableName, fkDiff.From.Name))
|
||||
to := fkDiff.To
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddForeignKeyStmtSimple(to.TableName, to.Name, to.ReferencedTableName, to.TableColumns, to.ReferencedTableColumns))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ func getSchemaSqlPatch(ctx *sql.Context, toRoot *doltdb.RootValue, td diff.Table
|
||||
}
|
||||
ddlStatements = append(ddlStatements, stmt)
|
||||
} else {
|
||||
stmts, err := diff.GetNonCreateNonDropTableSqlSchemaDiff(td, toSchemas, fromSch, toSch)
|
||||
stmts, err := GetNonCreateNonDropTableSqlSchemaDiff(td, toSchemas, fromSch, toSch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -498,6 +498,85 @@ func getDataSqlPatchResults(ctx *sql.Context, diffQuerySch, targetSch sql.Schema
|
||||
}
|
||||
}
|
||||
|
||||
// GetNonCreateNonDropTableSqlSchemaDiff returns any schema diff in SQL statements that is NEITHER 'CREATE TABLE' NOR 'DROP TABLE' statements.
|
||||
func GetNonCreateNonDropTableSqlSchemaDiff(td diff.TableDelta, toSchemas map[string]schema.Schema, fromSch, toSch schema.Schema) ([]string, error) {
|
||||
if td.IsAdd() || td.IsDrop() {
|
||||
// use add and drop specific methods
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var ddlStatements []string
|
||||
if td.FromName != td.ToName {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.RenameTableStmt(td.FromName, td.ToName))
|
||||
}
|
||||
|
||||
eq := schema.SchemasAreEqual(fromSch, toSch)
|
||||
if eq && !td.HasFKChanges() {
|
||||
return ddlStatements, nil
|
||||
}
|
||||
|
||||
colDiffs, unionTags := diff.DiffSchColumns(fromSch, toSch)
|
||||
for _, tag := range unionTags {
|
||||
cd := colDiffs[tag]
|
||||
switch cd.DiffType {
|
||||
case diff.SchDiffNone:
|
||||
case diff.SchDiffAdded:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddColStmt(td.ToName, sqlfmt.GenerateCreateTableColumnDefinition(*cd.New)))
|
||||
case diff.SchDiffRemoved:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropColStmt(td.ToName, cd.Old.Name))
|
||||
case diff.SchDiffModified:
|
||||
// Ignore any primary key set changes here
|
||||
if cd.Old.IsPartOfPK != cd.New.IsPartOfPK {
|
||||
continue
|
||||
}
|
||||
if cd.Old.Name != cd.New.Name {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableRenameColStmt(td.ToName, cd.Old.Name, cd.New.Name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print changes between a primary key set change. It contains an ALTER TABLE DROP and an ALTER TABLE ADD
|
||||
if !schema.ColCollsAreEqual(fromSch.GetPKCols(), toSch.GetPKCols()) {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropPks(td.ToName))
|
||||
if toSch.GetPKCols().Size() > 0 {
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddPrimaryKeys(td.ToName, toSch.GetPKCols().GetColumnNames()))
|
||||
}
|
||||
}
|
||||
|
||||
for _, idxDiff := range diff.DiffSchIndexes(fromSch, toSch) {
|
||||
switch idxDiff.DiffType {
|
||||
case diff.SchDiffNone:
|
||||
case diff.SchDiffAdded:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddIndexStmt(td.ToName, idxDiff.To))
|
||||
case diff.SchDiffRemoved:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropIndexStmt(td.FromName, idxDiff.From))
|
||||
case diff.SchDiffModified:
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropIndexStmt(td.FromName, idxDiff.From))
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddIndexStmt(td.ToName, idxDiff.To))
|
||||
}
|
||||
}
|
||||
|
||||
for _, fkDiff := range diff.DiffForeignKeys(td.FromFks, td.ToFks) {
|
||||
switch fkDiff.DiffType {
|
||||
case diff.SchDiffNone:
|
||||
case diff.SchDiffAdded:
|
||||
parentSch := toSchemas[fkDiff.To.ReferencedTableName]
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddForeignKeyStmt(fkDiff.To, toSch, parentSch))
|
||||
case diff.SchDiffRemoved:
|
||||
from := fkDiff.From
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropForeignKeyStmt(from.TableName, from.Name))
|
||||
case diff.SchDiffModified:
|
||||
from := fkDiff.From
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableDropForeignKeyStmt(from.TableName, from.Name))
|
||||
|
||||
parentSch := toSchemas[fkDiff.To.ReferencedTableName]
|
||||
ddlStatements = append(ddlStatements, sqlfmt.AlterTableAddForeignKeyStmt(fkDiff.To, toSch, parentSch))
|
||||
}
|
||||
}
|
||||
|
||||
return ddlStatements, nil
|
||||
}
|
||||
|
||||
// getDiffQuery returns diff schema for specified columns and array of sql.Expression as projection to be used
|
||||
// on diff table function row iter. This function attempts to imitate running a query
|
||||
// fmt.Sprintf("select %s, %s from dolt_diff('%s', '%s', '%s')", columnsWithDiff, "diff_type", fromRef, toRef, tableName)
|
||||
|
||||
@@ -148,17 +148,17 @@ func AlterTableDropPks(tableName string) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func AlterTableAddPrimaryKeys(tableName string, pks *schema.ColCollection) string {
|
||||
func AlterTableAddPrimaryKeys(tableName string, pkColNames []string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("ALTER TABLE ")
|
||||
b.WriteString(QuoteIdentifier(tableName))
|
||||
b.WriteString(" ADD PRIMARY KEY (")
|
||||
|
||||
for i := 0; i < pks.Size(); i++ {
|
||||
for i := 0; i < len(pkColNames); i++ {
|
||||
if i == 0 {
|
||||
b.WriteString(pks.GetByIndex(i).Name)
|
||||
b.WriteString(pkColNames[i])
|
||||
} else {
|
||||
b.WriteString("," + pks.GetByIndex(i).Name)
|
||||
b.WriteString("," + pkColNames[i])
|
||||
}
|
||||
}
|
||||
b.WriteRune(')')
|
||||
@@ -225,12 +225,26 @@ func AlterTableAddForeignKeyStmt(fk doltdb.ForeignKey, sch, parentSch schema.Sch
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func AlterTableDropForeignKeyStmt(fk doltdb.ForeignKey) string {
|
||||
func AlterTableAddForeignKeyStmtSimple(tableName, fkName, fkReferencedTableName string, fkTableColumns, fkReferencedTableColumns []string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("ALTER TABLE ")
|
||||
b.WriteString(QuoteIdentifier(fk.TableName))
|
||||
b.WriteString(QuoteIdentifier(tableName))
|
||||
b.WriteString(" ADD CONSTRAINT ")
|
||||
b.WriteString(QuoteIdentifier(fkName))
|
||||
b.WriteString(" FOREIGN KEY ")
|
||||
b.WriteString("(" + strings.Join(fkTableColumns, ",") + ")")
|
||||
b.WriteString(" REFERENCES ")
|
||||
b.WriteString(QuoteIdentifier(fkReferencedTableName))
|
||||
b.WriteString(" (" + strings.Join(fkReferencedTableColumns, ",") + ");")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func AlterTableDropForeignKeyStmt(tableName, fkName string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("ALTER TABLE ")
|
||||
b.WriteString(QuoteIdentifier(tableName))
|
||||
b.WriteString(" DROP FOREIGN KEY ")
|
||||
b.WriteString(QuoteIdentifier(fk.Name))
|
||||
b.WriteString(QuoteIdentifier(fkName))
|
||||
b.WriteRune(';')
|
||||
return b.String()
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func NewSchemaDiffWriter(wr io.WriteCloser) (*SchemaDiffWriter, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (j *SchemaDiffWriter) WriteSchemaDiff(ctx context.Context, schemaDiffStatement string) error {
|
||||
func (j *SchemaDiffWriter) WriteSchemaDiff(schemaDiffStatement string) error {
|
||||
if j.schemaStmtsWritten > 0 {
|
||||
err := iohelp.WriteAll(j.wr, []byte(","))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user