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 }