mirror of
https://github.com/pocketbase/pocketbase.git
synced 2024-11-24 17:07:00 +02:00
315 lines
6.1 KiB
Go
315 lines
6.1 KiB
Go
package dbutils_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/pocketbase/pocketbase/tools/dbutils"
|
|
)
|
|
|
|
func TestParseIndex(t *testing.T) {
|
|
scenarios := []struct {
|
|
index string
|
|
expected dbutils.Index
|
|
}{
|
|
// invalid
|
|
{
|
|
`invalid`,
|
|
dbutils.Index{},
|
|
},
|
|
// simple (multiple spaces between the table and columns list)
|
|
{
|
|
`create index indexname on tablename (col1)`,
|
|
dbutils.Index{
|
|
IndexName: "indexname",
|
|
TableName: "tablename",
|
|
Columns: []dbutils.IndexColumn{
|
|
{Name: "col1"},
|
|
},
|
|
},
|
|
},
|
|
// simple (no space between the table and the columns list)
|
|
{
|
|
`create index indexname on tablename(col1)`,
|
|
dbutils.Index{
|
|
IndexName: "indexname",
|
|
TableName: "tablename",
|
|
Columns: []dbutils.IndexColumn{
|
|
{Name: "col1"},
|
|
},
|
|
},
|
|
},
|
|
// all fields
|
|
{
|
|
`CREATE UNIQUE INDEX IF NOT EXISTS "schemaname".[indexname] on 'tablename' (
|
|
col0,
|
|
` + "`" + `col1` + "`" + `,
|
|
json_extract("col2", "$.a") asc,
|
|
"col3" collate NOCASE,
|
|
"col4" collate RTRIM desc
|
|
) where test = 1`,
|
|
dbutils.Index{
|
|
Unique: true,
|
|
Optional: true,
|
|
SchemaName: "schemaname",
|
|
IndexName: "indexname",
|
|
TableName: "tablename",
|
|
Columns: []dbutils.IndexColumn{
|
|
{Name: "col0"},
|
|
{Name: "col1"},
|
|
{Name: `json_extract("col2", "$.a")`, Sort: "ASC"},
|
|
{Name: `col3`, Collate: "NOCASE"},
|
|
{Name: `col4`, Collate: "RTRIM", Sort: "DESC"},
|
|
},
|
|
Where: "test = 1",
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, s := range scenarios {
|
|
t.Run(fmt.Sprintf("scenario_%d", i), func(t *testing.T) {
|
|
result := dbutils.ParseIndex(s.index)
|
|
|
|
resultRaw, err := json.Marshal(result)
|
|
if err != nil {
|
|
t.Fatalf("Faild to marshalize parse result: %v", err)
|
|
}
|
|
|
|
expectedRaw, err := json.Marshal(s.expected)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshalize expected index: %v", err)
|
|
}
|
|
|
|
if !bytes.Equal(resultRaw, expectedRaw) {
|
|
t.Errorf("Expected \n%s \ngot \n%s", expectedRaw, resultRaw)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIndexIsValid(t *testing.T) {
|
|
scenarios := []struct {
|
|
name string
|
|
index dbutils.Index
|
|
expected bool
|
|
}{
|
|
{
|
|
"empty",
|
|
dbutils.Index{},
|
|
false,
|
|
},
|
|
{
|
|
"no index name",
|
|
dbutils.Index{
|
|
TableName: "table",
|
|
Columns: []dbutils.IndexColumn{{Name: "col"}},
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"no table name",
|
|
dbutils.Index{
|
|
IndexName: "index",
|
|
Columns: []dbutils.IndexColumn{{Name: "col"}},
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"no columns",
|
|
dbutils.Index{
|
|
IndexName: "index",
|
|
TableName: "table",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"min valid",
|
|
dbutils.Index{
|
|
IndexName: "index",
|
|
TableName: "table",
|
|
Columns: []dbutils.IndexColumn{{Name: "col"}},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"all fields",
|
|
dbutils.Index{
|
|
Optional: true,
|
|
Unique: true,
|
|
SchemaName: "schema",
|
|
IndexName: "index",
|
|
TableName: "table",
|
|
Columns: []dbutils.IndexColumn{{Name: "col"}},
|
|
Where: "test = 1 OR test = 2",
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, s := range scenarios {
|
|
t.Run(s.name, func(t *testing.T) {
|
|
result := s.index.IsValid()
|
|
if result != s.expected {
|
|
t.Fatalf("Expected %v, got %v", s.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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 {
|
|
t.Run(s.name, func(t *testing.T) {
|
|
result := s.index.Build()
|
|
if result != s.expected {
|
|
t.Fatalf("Expected \n%v \ngot \n%v", s.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasSingleColumnUniqueIndex(t *testing.T) {
|
|
scenarios := []struct {
|
|
name string
|
|
column string
|
|
indexes []string
|
|
expected bool
|
|
}{
|
|
{
|
|
"empty indexes",
|
|
"test",
|
|
nil,
|
|
false,
|
|
},
|
|
{
|
|
"empty column",
|
|
"",
|
|
[]string{
|
|
"CREATE UNIQUE INDEX `index1` ON `example` (`test`)",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"mismatched column",
|
|
"test",
|
|
[]string{
|
|
"CREATE UNIQUE INDEX `index1` ON `example` (`test2`)",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"non unique index",
|
|
"test",
|
|
[]string{
|
|
"CREATE INDEX `index1` ON `example` (`test`)",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"matching columnd and unique index",
|
|
"test",
|
|
[]string{
|
|
"CREATE UNIQUE INDEX `index1` ON `example` (`test`)",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"multiple columns",
|
|
"test",
|
|
[]string{
|
|
"CREATE UNIQUE INDEX `index1` ON `example` (`test`, `test2`)",
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"multiple indexes",
|
|
"test",
|
|
[]string{
|
|
"CREATE UNIQUE INDEX `index1` ON `example` (`test`, `test2`)",
|
|
"CREATE UNIQUE INDEX `index2` ON `example` (`test`)",
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"partial unique index",
|
|
"test",
|
|
[]string{
|
|
"CREATE UNIQUE INDEX `index` ON `example` (`test`) where test != ''",
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for _, s := range scenarios {
|
|
t.Run(s.name, func(t *testing.T) {
|
|
result := dbutils.HasSingleColumnUniqueIndex(s.column, s.indexes)
|
|
if result != s.expected {
|
|
t.Fatalf("Expected %v got %v", s.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|