created library methods for schema modification sql statements

This commit is contained in:
Andy Arthur
2019-12-04 15:46:38 -08:00
parent e29e9cf900
commit e08f1848fd
8 changed files with 98 additions and 35 deletions

View File

@@ -509,18 +509,11 @@ func sqlSchemaDiff(tableName string, tags []uint64, diffs map[uint64]diff.Schema
switch dff.DiffType {
case diff.SchDiffNone:
case diff.SchDiffColAdded:
colStr := sql.FmtCol(0, 0, 0, *dff.New)
tableName = sql.QuoteIdentifier(tableName)
cli.Println("ALTER TABLE", tableName, "ADD", colStr, ";")
cli.Println(sql.AlterTableAddColStmt(tableName, sql.FmtCol(0, 0, 0, *dff.New)))
case diff.SchDiffColRemoved:
oldColumnName := sql.QuoteIdentifier(dff.Old.Name)
tableName = sql.QuoteIdentifier(tableName)
cli.Println("ALTER TABLE", tableName, "DROP", oldColumnName, ";")
cli.Print(sql.AlterTableDropColStmt(tableName, dff.Old.Name))
case diff.SchDiffColModified:
oldColName := sql.QuoteIdentifier(dff.Old.Name)
newColName := sql.QuoteIdentifier(dff.New.Name)
tableName = sql.QuoteIdentifier(tableName)
cli.Println("ALTER TABLE", tableName, "RENAME COLUMN", oldColName, "TO", newColName, ";")
cli.Print(sql.AlterTableRenameColStmt(tableName, dff.Old.Name, dff.New.Name))
}
}
}

View File

@@ -122,34 +122,32 @@ func (sds *SQLDiffSink) Close() error {
}
func PrintSqlTableDiffs(ctx context.Context, r1, r2 *doltdb.RootValue, wr io.WriteCloser) error {
adds, _, drops, err := r1.TableDiff(ctx, r2)
creates, _, drops, err := r1.TableDiff(ctx, r2)
if err != nil {
return err
}
adds, drops, renames, err := findRenames(ctx, r1, r2, adds, drops)
creates, drops, renames, err := findRenames(ctx, r1, r2, creates, drops)
if err != nil {
return err
}
// rename tables
for k, v := range renames {
if err = iohelp.WriteLine(wr, "RENAME TABLE "+sql.QuoteIdentifier(k)+" TO "+sql.QuoteIdentifier(v)); err != nil {
if err = iohelp.WriteLine(wr, sql.RenameTableStmt(k, v)); err != nil {
return err
}
}
// drop tables
for _, tblName := range drops {
if err = iohelp.WriteLine(wr, "DROP TABLE "+sql.QuoteIdentifier(tblName)+";"); err != nil {
if err = iohelp.WriteLine(wr, sql.DropTableStmt(tblName)); err != nil {
return err
}
}
// add tables
for _, tblName := range adds {
// create tables and insert rows
for _, tblName := range creates {
if tbl, ok, err := r1.GetTable(ctx, tblName); err != nil {
return errors.New("error: unable to write SQL diff output for new table")
} else if !ok {

View File

@@ -124,7 +124,7 @@ func TestSqlTableDiffRename(t *testing.T) {
assert.Equal(t, []string{}, removed)
assert.Equal(t, []string{}, added)
expectedOutput := "RENAME TABLE `renameTable` TO `newTableName`\n"
expectedOutput := "RENAME TABLE `renameTable` TO `newTableName`;\n"
var stringWr StringBuilderCloser
_ = PrintSqlTableDiffs(ctx, newRoot, oldRoot, &stringWr)
assert.Equal(t, expectedOutput, stringWr.String())

View File

@@ -34,7 +34,7 @@ func FmtCol(indent, nameWidth, typeWidth int, col schema.Column) string {
// space count, name width, and type width. If nameWidth or typeWidth are 0 or less than the length of the name or
// type, then the length of the name or type will be used.
func FmtColWithNameAndType(indent, nameWidth, typeWidth int, colName, typeStr string, col schema.Column) string {
colName = "`" + colName + "`"
colName = QuoteIdentifier(colName)
fmtStr := fmt.Sprintf("%%%ds%%%ds %%%ds", indent, nameWidth, typeWidth)
colStr := fmt.Sprintf(fmtStr, "", colName, typeStr)

View File

@@ -24,6 +24,11 @@ import (
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
)
// Quotes the identifier given with backticks.
func QuoteIdentifier(s string) string {
return "`" + s + "`"
}
// SchemaAsCreateStmt takes a Schema and returns a string representing a SQL create table command that could be used to
// create this table
func SchemaAsCreateStmt(tableName string, sch schema.Schema) string {
@@ -65,7 +70,7 @@ func SchemaAsCreateStmt(tableName string, sch schema.Schema) string {
return sb.String()
}
func TableDropStmt(tableName string) string {
func DropTableStmt(tableName string) string {
var b strings.Builder
b.WriteString("DROP TABLE ")
b.WriteString(QuoteIdentifier(tableName))
@@ -73,7 +78,7 @@ func TableDropStmt(tableName string) string {
return b.String()
}
func TableDropIfExistsStmt(tableName string) string {
func DropTableIfExistsStmt(tableName string) string {
var b strings.Builder
b.WriteString("DROP TABLE IF EXISTS ")
b.WriteString(QuoteIdentifier(tableName))
@@ -81,6 +86,49 @@ func TableDropIfExistsStmt(tableName string) string {
return b.String()
}
func AlterTableAddColStmt(tableName string, newColDef string) string {
var b strings.Builder
b.WriteString("ALTER TABLE ")
b.WriteString(QuoteIdentifier(tableName))
b.WriteString(" ADD ")
b.WriteString(newColDef)
b.WriteRune(';')
return b.String()
}
func AlterTableDropColStmt(tableName string, oldColName string) string {
var b strings.Builder
b.WriteString("ALTER TABLE ")
b.WriteString(QuoteIdentifier(tableName))
b.WriteString(" DROP ")
b.WriteString(QuoteIdentifier(oldColName))
b.WriteRune(';')
return b.String()
}
func AlterTableRenameColStmt(tableName string, oldColName string, newColName string) string {
var b strings.Builder
b.WriteString("ALTER TABLE ")
b.WriteString(QuoteIdentifier(tableName))
b.WriteString(" RENAME COLUMN ")
b.WriteString(QuoteIdentifier(oldColName))
b.WriteString(" TO ")
b.WriteString(QuoteIdentifier(newColName))
b.WriteRune(';')
return b.String()
}
func RenameTableStmt(fromName string, toName string) string {
var b strings.Builder
b.WriteString("RENAME TABLE ")
b.WriteString(QuoteIdentifier(fromName))
b.WriteString(" TO ")
b.WriteString(QuoteIdentifier(toName))
b.WriteString(";")
return b.String()
}
func RowAsInsertStmt(r row.Row, tableName string, tableSch schema.Schema) (string, error) {
var b strings.Builder
b.WriteString("INSERT INTO ")
@@ -219,11 +267,6 @@ func RowAsUpdateStmt(r row.Row, tableName string, tableSch schema.Schema) (strin
return b.String(), nil
}
// Quotes the identifier given with backticks.
func QuoteIdentifier(s string) string {
return "`" + s + "`"
}
func valueAsSqlString(value types.Value) (string, error) {
if types.IsNull(value) {
return "NULL", nil

View File

@@ -40,6 +40,10 @@ const expectedCreateSQL = "CREATE TABLE `table_name` (\n" +
");"
const expectedDropSql = "DROP TABLE `table_name`;"
const expectedDropIfExistsSql = "DROP TABLE IF EXISTS `table_name`;"
const expectedAddColSql = "ALTER TABLE `table_name` ADD `c0` BIGINT NOT NULL COMMENT 'tag:9';"
const expectedDropColSql = "ALTER TABLE `table_name` DROP `first`;"
const expectedRenameColSql = "ALTER TABLE `table_name` RENAME COLUMN `id` TO `pk`;"
const expectedRenameTableSql = "RENAME TABLE `table_name` TO `new_table_name`;"
type test struct {
name string
@@ -50,21 +54,46 @@ type test struct {
func TestSchemaAsCreateStmt(t *testing.T) {
tSchema := sqltestutil.PeopleTestSchema
str := SchemaAsCreateStmt("table_name", tSchema)
stmt := SchemaAsCreateStmt("table_name", tSchema)
assert.Equal(t, expectedCreateSQL, str)
assert.Equal(t, expectedCreateSQL, stmt)
}
func TestTableDropStmt(t *testing.T) {
str := TableDropStmt("table_name")
stmt := DropTableStmt("table_name")
assert.Equal(t, expectedDropSql, str)
assert.Equal(t, expectedDropSql, stmt)
}
func TestTableDropIfExistsStmt(t *testing.T) {
str := TableDropIfExistsStmt("table_name")
stmt := DropTableIfExistsStmt("table_name")
assert.Equal(t, expectedDropIfExistsSql, str)
assert.Equal(t, expectedDropIfExistsSql, stmt)
}
func TestAlterTableAddColStmt(t *testing.T) {
newColDef := "`c0` BIGINT NOT NULL COMMENT 'tag:9'"
stmt := AlterTableAddColStmt("table_name", newColDef)
assert.Equal(t, expectedAddColSql, stmt)
}
func TestAlterTableDropColStmt(t *testing.T) {
stmt := AlterTableDropColStmt("table_name", "first")
assert.Equal(t, expectedDropColSql, stmt)
}
func TestAlterTableRenameColStmt(t *testing.T) {
stmt := AlterTableRenameColStmt("table_name", "id", "pk")
assert.Equal(t, expectedRenameColSql, stmt)
}
func TestRenameTableStmt(t *testing.T) {
stmt := RenameTableStmt("table_name", "new_table_name")
assert.Equal(t, expectedRenameTableSql, stmt)
}
func TestRowAsInsertStmt(t *testing.T) {

View File

@@ -79,7 +79,7 @@ func (w *SqlExportWriter) WriteRow(ctx context.Context, r row.Row) error {
func (w *SqlExportWriter) maybeWriteDropCreate() error {
if !w.writtenFirstRow {
var b strings.Builder
b.WriteString(sql.TableDropIfExistsStmt(w.tableName))
b.WriteString(sql.DropTableIfExistsStmt(w.tableName))
b.WriteRune('\n')
b.WriteString(sql.SchemaAsCreateStmt(w.tableName, w.sch))
if err := iohelp.WriteLine(w.wr, b.String()); err != nil {

View File

@@ -47,7 +47,7 @@ func TestEndToEnd(t *testing.T) {
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
tableName := "people"
dropCreateStatement := sql.TableDropIfExistsStmt(tableName) + "\n" + sql.SchemaAsCreateStmt(tableName, dtestutils.TypedSchema)
dropCreateStatement := sql.DropTableIfExistsStmt(tableName) + "\n" + sql.SchemaAsCreateStmt(tableName, dtestutils.TypedSchema)
type test struct {
name string