1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-02-08 11:47:48 +02:00

added Index.Build helper method

This commit is contained in:
Gani Georgiev 2023-03-21 14:26:44 +02:00
parent 1b45e23c81
commit 981de64c7f
2 changed files with 161 additions and 1 deletions

View File

@ -35,7 +35,95 @@ func (idx Index) IsValid() bool {
return idx.IndexName != "" && idx.TableName != "" && len(idx.Columns) > 0
}
// ParseIndex parses the provided `CREATE INDEX` SQL string into Index struct.
// Build returns a "CREATE INDEX" SQL string from the current index parts.
//
// Returns empty string if idx.IsValid() is false.
func (idx Index) Build() string {
if !idx.IsValid() {
return ""
}
var str strings.Builder
str.WriteString("CREATE ")
if idx.Unique {
str.WriteString("UNIQUE ")
}
str.WriteString("INDEX ")
if idx.Optional {
str.WriteString("IF NOT EXISTS ")
}
if idx.SchemaName != "" {
str.WriteString("`")
str.WriteString(idx.SchemaName)
str.WriteString("`.")
}
str.WriteString("`")
str.WriteString(idx.IndexName)
str.WriteString("` ")
str.WriteString("ON `")
str.WriteString(idx.TableName)
str.WriteString("` (")
if len(idx.Columns) > 1 {
str.WriteString("\n ")
}
var hasCol bool
for _, col := range idx.Columns {
trimmedColName := strings.TrimSpace(col.Name)
if trimmedColName == "" {
continue
}
if hasCol {
str.WriteString(",\n ")
}
if strings.Contains(col.Name, "(") || strings.Contains(col.Name, " ") {
// most likely an expression
str.WriteString(trimmedColName)
} else {
// regular identifier
str.WriteString("`")
str.WriteString(trimmedColName)
str.WriteString("`")
}
if col.Collate != "" {
str.WriteString(" COLLATE ")
str.WriteString(col.Collate)
}
if col.Sort != "" {
str.WriteString(" ")
str.WriteString(strings.ToUpper(col.Sort))
}
hasCol = true
}
if hasCol && len(idx.Columns) > 1 {
str.WriteString("\n")
}
str.WriteString(")")
if idx.Where != "" {
str.WriteString(" WHERE ")
str.WriteString(idx.Where)
}
return str.String()
}
// ParseIndex parses the provided "CREATE INDEX" SQL string into Index struct.
func ParseIndex(createIndexExpr string) Index {
result := Index{}

View File

@ -142,3 +142,75 @@ func TestIndexIsValid(t *testing.T) {
}
}
}
func TestIndexBuild(t *testing.T) {
scenarios := []struct {
name string
index dbutils.Index
expected string
}{
{
"empty",
dbutils.Index{},
"",
},
{
"no index name",
dbutils.Index{
TableName: "table",
Columns: []dbutils.IndexColumn{{Name: "col"}},
},
"",
},
{
"no table name",
dbutils.Index{
IndexName: "index",
Columns: []dbutils.IndexColumn{{Name: "col"}},
},
"",
},
{
"no columns",
dbutils.Index{
IndexName: "index",
TableName: "table",
},
"",
},
{
"min valid",
dbutils.Index{
IndexName: "index",
TableName: "table",
Columns: []dbutils.IndexColumn{{Name: "col"}},
},
"CREATE INDEX `index` ON `table` (`col`)",
},
{
"all fields",
dbutils.Index{
Optional: true,
Unique: true,
SchemaName: "schema",
IndexName: "index",
TableName: "table",
Columns: []dbutils.IndexColumn{
{Name: "col1", Collate: "NOCASE", Sort: "asc"},
{Name: "col2", Sort: "desc"},
{Name: `json_extract("col3", "$.a")`, Collate: "NOCASE"},
},
Where: "test = 1 OR test = 2",
},
"CREATE UNIQUE INDEX IF NOT EXISTS `schema`.`index` ON `table` (\n `col1` COLLATE NOCASE ASC,\n `col2` DESC,\n " + `json_extract("col3", "$.a")` + " COLLATE NOCASE\n) WHERE test = 1 OR test = 2",
},
}
for _, s := range scenarios {
result := s.index.Build()
if result != s.expected {
t.Errorf("[%s] Expected \n%v \ngot \n%v", s.name, s.expected, result)
}
}
}