github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/sqlfmt/schema_fmt.go (about)

     1  // Copyright 2020 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sqlfmt
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    22  
    23  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    24  )
    25  
    26  //  FmtCol converts a column to a string with a given indent space count, name width, and type width.  If nameWidth or
    27  // typeWidth are 0 or less than the length of the name or type, then the length of the name or type will be used
    28  func FmtCol(indent, nameWidth, typeWidth int, col schema.Column) string {
    29  	sqlType := col.TypeInfo.ToSqlType()
    30  	return FmtColWithNameAndType(indent, nameWidth, typeWidth, col.Name, sqlType.String(), col)
    31  }
    32  
    33  // FmtColWithNameAndType creates a string representing a column within a sql create table statement with a given indent
    34  // space count, name width, and type width.  If nameWidth or typeWidth are 0 or less than the length of the name or
    35  // type, then the length of the name or type will be used.
    36  func FmtColWithNameAndType(indent, nameWidth, typeWidth int, colName, typeStr string, col schema.Column) string {
    37  	colName = QuoteIdentifier(colName)
    38  	fmtStr := fmt.Sprintf("%%%ds%%%ds %%%ds", indent, nameWidth, typeWidth)
    39  	colStr := fmt.Sprintf(fmtStr, "", colName, typeStr)
    40  
    41  	for _, cnst := range col.Constraints {
    42  		switch cnst.GetConstraintType() {
    43  		case schema.NotNullConstraintType:
    44  			colStr += " NOT NULL"
    45  		default:
    46  			panic("FmtColWithNameAndType doesn't know how to format constraint type: " + cnst.GetConstraintType())
    47  		}
    48  	}
    49  
    50  	if col.AutoIncrement {
    51  		colStr += " AUTO_INCREMENT"
    52  	}
    53  
    54  	if col.Default != "" {
    55  		colStr += " DEFAULT " + col.Default
    56  	}
    57  
    58  	if col.Comment != "" {
    59  		colStr += " COMMENT " + QuoteComment(col.Comment)
    60  	}
    61  
    62  	return colStr
    63  }
    64  
    65  // FmtColPrimaryKey creates a string representing a primary key constraint within a sql create table statement with a
    66  // given indent.
    67  func FmtColPrimaryKey(indent int, colStr string) string {
    68  	fmtStr := fmt.Sprintf("%%%ds PRIMARY KEY (%s)\n", indent, colStr)
    69  	return fmt.Sprintf(fmtStr, "")
    70  }
    71  
    72  func FmtIndex(index schema.Index) string {
    73  	sb := strings.Builder{}
    74  	if index.IsUnique() {
    75  		sb.WriteString("UNIQUE ")
    76  	}
    77  	sb.WriteString("INDEX ")
    78  	sb.WriteString(QuoteIdentifier(index.Name()))
    79  	sb.WriteString(" (")
    80  	for i, indexColName := range index.ColumnNames() {
    81  		if i != 0 {
    82  			sb.WriteRune(',')
    83  		}
    84  		sb.WriteString(QuoteIdentifier(indexColName))
    85  	}
    86  	sb.WriteRune(')')
    87  	if len(index.Comment()) > 0 {
    88  		sb.WriteString(" COMMENT ")
    89  		sb.WriteString(QuoteComment(index.Comment()))
    90  	}
    91  	return sb.String()
    92  }
    93  
    94  func FmtForeignKey(fk doltdb.ForeignKey, sch, parentSch schema.Schema) string {
    95  	sb := strings.Builder{}
    96  	sb.WriteString("CONSTRAINT ")
    97  	sb.WriteString(QuoteIdentifier(fk.Name))
    98  	sb.WriteString(" FOREIGN KEY (")
    99  	for i, tag := range fk.TableColumns {
   100  		if i != 0 {
   101  			sb.WriteRune(',')
   102  		}
   103  		c, _ := sch.GetAllCols().GetByTag(tag)
   104  		sb.WriteString(QuoteIdentifier(c.Name))
   105  	}
   106  	sb.WriteString(")\n    REFERENCES ")
   107  	sb.WriteString(QuoteIdentifier(fk.ReferencedTableName))
   108  	sb.WriteString(" (")
   109  	for i, tag := range fk.ReferencedTableColumns {
   110  		if i != 0 {
   111  			sb.WriteRune(',')
   112  		}
   113  		c, _ := parentSch.GetAllCols().GetByTag(tag)
   114  		sb.WriteString(QuoteIdentifier(c.Name))
   115  	}
   116  	sb.WriteRune(')')
   117  	if fk.OnDelete != doltdb.ForeignKeyReferenceOption_DefaultAction {
   118  		sb.WriteString("\n    ON DELETE ")
   119  		sb.WriteString(fk.OnDelete.String())
   120  	}
   121  	if fk.OnUpdate != doltdb.ForeignKeyReferenceOption_DefaultAction {
   122  		sb.WriteString("\n    ON UPDATE ")
   123  		sb.WriteString(fk.OnUpdate.String())
   124  	}
   125  	return sb.String()
   126  }
   127  
   128  func DropTableStmt(tableName string) string {
   129  	var b strings.Builder
   130  	b.WriteString("DROP TABLE ")
   131  	b.WriteString(QuoteIdentifier(tableName))
   132  	b.WriteString(";")
   133  	return b.String()
   134  }
   135  
   136  func DropTableIfExistsStmt(tableName string) string {
   137  	var b strings.Builder
   138  	b.WriteString("DROP TABLE IF EXISTS ")
   139  	b.WriteString(QuoteIdentifier(tableName))
   140  	b.WriteString(";")
   141  	return b.String()
   142  }
   143  
   144  func AlterTableAddColStmt(tableName string, newColDef string) string {
   145  	var b strings.Builder
   146  	b.WriteString("ALTER TABLE ")
   147  	b.WriteString(QuoteIdentifier(tableName))
   148  	b.WriteString(" ADD ")
   149  	b.WriteString(newColDef)
   150  	b.WriteRune(';')
   151  	return b.String()
   152  }
   153  
   154  func AlterTableModifyColStmt(tableName string, newColDef string) string {
   155  	var b strings.Builder
   156  	b.WriteString("ALTER TABLE ")
   157  	b.WriteString(QuoteIdentifier(tableName))
   158  	b.WriteString(" MODIFY COLUMN ")
   159  	b.WriteString(newColDef)
   160  	b.WriteRune(';')
   161  	return b.String()
   162  }
   163  
   164  func AlterTableDropColStmt(tableName string, oldColName string) string {
   165  	var b strings.Builder
   166  	b.WriteString("ALTER TABLE ")
   167  	b.WriteString(QuoteIdentifier(tableName))
   168  	b.WriteString(" DROP ")
   169  	b.WriteString(QuoteIdentifier(oldColName))
   170  	b.WriteRune(';')
   171  	return b.String()
   172  }
   173  
   174  func AlterTableRenameColStmt(tableName string, oldColName string, newColName string) string {
   175  	var b strings.Builder
   176  	b.WriteString("ALTER TABLE ")
   177  	b.WriteString(QuoteIdentifier(tableName))
   178  	b.WriteString(" RENAME COLUMN ")
   179  	b.WriteString(QuoteIdentifier(oldColName))
   180  	b.WriteString(" TO ")
   181  	b.WriteString(QuoteIdentifier(newColName))
   182  	b.WriteRune(';')
   183  	return b.String()
   184  }
   185  
   186  func RenameTableStmt(fromName string, toName string) string {
   187  	var b strings.Builder
   188  	b.WriteString("RENAME TABLE ")
   189  	b.WriteString(QuoteIdentifier(fromName))
   190  	b.WriteString(" TO ")
   191  	b.WriteString(QuoteIdentifier(toName))
   192  	b.WriteString(";")
   193  
   194  	return b.String()
   195  }
   196  
   197  func AlterTableAddIndexStmt(tableName string, idx schema.Index) string {
   198  	var b strings.Builder
   199  	b.WriteString("ALTER TABLE ")
   200  	b.WriteString(QuoteIdentifier(tableName))
   201  	b.WriteString(" ADD INDEX ")
   202  	b.WriteString(QuoteIdentifier(idx.Name()))
   203  	var cols []string
   204  	for _, cn := range idx.ColumnNames() {
   205  		cols = append(cols, QuoteIdentifier(cn))
   206  	}
   207  	b.WriteString("(" + strings.Join(cols, ",") + ");")
   208  	return b.String()
   209  }
   210  
   211  func AlterTableDropIndexStmt(tableName string, idx schema.Index) string {
   212  	var b strings.Builder
   213  	b.WriteString("ALTER TABLE ")
   214  	b.WriteString(QuoteIdentifier(tableName))
   215  	b.WriteString(" DROP INDEX ")
   216  	b.WriteString(QuoteIdentifier(idx.Name()))
   217  	b.WriteRune(';')
   218  	return b.String()
   219  }
   220  
   221  func AlterTableAddForeignKeyStmt(fk doltdb.ForeignKey, sch, parentSch schema.Schema) string {
   222  	var b strings.Builder
   223  	b.WriteString("ALTER TABLE ")
   224  	b.WriteString(QuoteIdentifier(fk.TableName))
   225  	b.WriteString(" ADD CONSTRAINT ")
   226  	b.WriteString(QuoteIdentifier(fk.Name))
   227  	b.WriteString(" FOREIGN KEY ")
   228  	var childCols []string
   229  	for _, tag := range fk.TableColumns {
   230  		c, _ := sch.GetAllCols().GetByTag(tag)
   231  		childCols = append(childCols, QuoteIdentifier(c.Name))
   232  	}
   233  	b.WriteString("(" + strings.Join(childCols, ",") + ")")
   234  	b.WriteString(" REFERENCES ")
   235  	var parentCols []string
   236  	for _, tag := range fk.ReferencedTableColumns {
   237  		c, _ := parentSch.GetAllCols().GetByTag(tag)
   238  		parentCols = append(parentCols, QuoteIdentifier(c.Name))
   239  	}
   240  	b.WriteString(QuoteIdentifier(fk.ReferencedTableName))
   241  	b.WriteString(" (" + strings.Join(parentCols, ",") + ");")
   242  	return b.String()
   243  }
   244  
   245  func AlterTableDropForeignKeyStmt(fk doltdb.ForeignKey) string {
   246  	var b strings.Builder
   247  	b.WriteString("ALTER TABLE ")
   248  	b.WriteString(QuoteIdentifier(fk.TableName))
   249  	b.WriteString(" DROP FOREIGN KEY ")
   250  	b.WriteString(QuoteIdentifier(fk.Name))
   251  	b.WriteRune(';')
   252  	return b.String()
   253  }