summaryrefslogtreecommitdiff
path: root/vendor/github.com/ncruces/go-sqlite3/util/sql3util
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-10-25 16:09:18 +0000
committerLibravatar GitHub <noreply@github.com>2024-10-25 16:09:18 +0000
commit51cb6cae166388110388b128953cd01c781660d8 (patch)
tree5526ecd37d1d60a3394b8a796191407c8cf093c5 /vendor/github.com/ncruces/go-sqlite3/util/sql3util
parent[bugfix] incorrect /api/v_/instance domain uri fields (#3477) (diff)
downloadgotosocial-51cb6cae166388110388b128953cd01c781660d8.tar.xz
update go-sqlite3 => v0.20.0 (#3483)
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/util/sql3util')
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/README.md9
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/arg.go65
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/const.go61
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse.go210
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasmbin0 -> 17538 bytes
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/sql3util.go9
6 files changed, 354 insertions, 0 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/README.md b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/README.md
new file mode 100644
index 000000000..9f47f5a9f
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/README.md
@@ -0,0 +1,9 @@
+# SQLite utility functions
+
+This package implements assorted SQLite utilities
+useful to extension writers.
+
+It also wraps a [parser](https://github.com/marcobambini/sqlite-createtable-parser)
+for the [`CREATE`](https://sqlite.org/lang_createtable.html) and
+[`ALTER TABLE`](https://sqlite.org/lang_altertable.html) commands,
+created by [Marco Bambini](https://github.com/marcobambini). \ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/arg.go b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/arg.go
new file mode 100644
index 000000000..3e8c728b0
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/arg.go
@@ -0,0 +1,65 @@
+package sql3util
+
+import "strings"
+
+// NamedArg splits an named arg into a key and value,
+// around an equals sign.
+// Spaces are trimmed around both key and value.
+func NamedArg(arg string) (key, val string) {
+ key, val, _ = strings.Cut(arg, "=")
+ key = strings.TrimSpace(key)
+ val = strings.TrimSpace(val)
+ return
+}
+
+// Unquote unquotes a string.
+//
+// https://sqlite.org/lang_keywords.html
+func Unquote(val string) string {
+ if len(val) < 2 {
+ return val
+ }
+ fst := val[0]
+ lst := val[len(val)-1]
+ rst := val[1 : len(val)-1]
+ if fst == '[' && lst == ']' {
+ return rst
+ }
+ if fst != lst {
+ return val
+ }
+ var old, new string
+ switch fst {
+ default:
+ return val
+ case '`':
+ old, new = "``", "`"
+ case '"':
+ old, new = `""`, `"`
+ case '\'':
+ old, new = `''`, `'`
+ }
+ return strings.ReplaceAll(rst, old, new)
+}
+
+// ParseBool parses a boolean.
+//
+// https://sqlite.org/pragma.html#syntax
+func ParseBool(s string) (b, ok bool) {
+ if len(s) == 0 {
+ return false, false
+ }
+ if s[0] == '0' {
+ return false, true
+ }
+ if '1' <= s[0] && s[0] <= '9' {
+ return true, true
+ }
+ switch strings.ToLower(s) {
+ case "true", "yes", "on":
+ return true, true
+ case "false", "no", "off":
+ return false, true
+ }
+ return false, false
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/const.go b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/const.go
new file mode 100644
index 000000000..10e8af35a
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/const.go
@@ -0,0 +1,61 @@
+package sql3util
+
+const (
+ _NONE = iota
+ _MEMORY
+ _SYNTAX
+ _UNSUPPORTEDSQL
+)
+
+type ConflictClause uint32
+
+const (
+ CONFLICT_NONE ConflictClause = iota
+ CONFLICT_ROLLBACK
+ CONFLICT_ABORT
+ CONFLICT_FAIL
+ CONFLICT_IGNORE
+ CONFLICT_REPLACE
+)
+
+type OrderClause uint32
+
+const (
+ ORDER_NONE OrderClause = iota
+ ORDER_ASC
+ ORDER_DESC
+)
+
+type FKAction uint32
+
+const (
+ FKACTION_NONE FKAction = iota
+ FKACTION_SETNULL
+ FKACTION_SETDEFAULT
+ FKACTION_CASCADE
+ FKACTION_RESTRICT
+ FKACTION_NOACTION
+)
+
+type FKDefType uint32
+
+const (
+ DEFTYPE_NONE FKDefType = iota
+ DEFTYPE_DEFERRABLE
+ DEFTYPE_DEFERRABLE_INITIALLY_DEFERRED
+ DEFTYPE_DEFERRABLE_INITIALLY_IMMEDIATE
+ DEFTYPE_NOTDEFERRABLE
+ DEFTYPE_NOTDEFERRABLE_INITIALLY_DEFERRED
+ DEFTYPE_NOTDEFERRABLE_INITIALLY_IMMEDIATE
+)
+
+type StatementType uint32
+
+const (
+ CREATE_UNKNOWN StatementType = iota
+ CREATE_TABLE
+ ALTER_RENAME_TABLE
+ ALTER_RENAME_COLUMN
+ ALTER_ADD_COLUMN
+ ALTER_DROP_COLUMN
+)
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse.go b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse.go
new file mode 100644
index 000000000..7326f7dbb
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse.go
@@ -0,0 +1,210 @@
+package sql3util
+
+import (
+ "context"
+ _ "embed"
+ "sync"
+
+ "github.com/tetratelabs/wazero"
+ "github.com/tetratelabs/wazero/api"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+)
+
+const (
+ errp = 4
+ sqlp = 8
+)
+
+var (
+ //go:embed parse/sql3parse_table.wasm
+ binary []byte
+ once sync.Once
+ runtime wazero.Runtime
+ compiled wazero.CompiledModule
+)
+
+// ParseTable parses a [CREATE] or [ALTER TABLE] command.
+//
+// [CREATE]: https://sqlite.org/lang_createtable.html
+// [ALTER TABLE]: https://sqlite.org/lang_altertable.html
+func ParseTable(sql string) (_ *Table, err error) {
+ once.Do(func() {
+ ctx := context.Background()
+ cfg := wazero.NewRuntimeConfigInterpreter()
+ runtime = wazero.NewRuntimeWithConfig(ctx, cfg)
+ compiled, err = runtime.CompileModule(ctx, binary)
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ ctx := context.Background()
+ mod, err := runtime.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithName(""))
+ if err != nil {
+ return nil, err
+ }
+ defer mod.Close(ctx)
+
+ if buf, ok := mod.Memory().Read(sqlp, uint32(len(sql))); ok {
+ copy(buf, sql)
+ }
+
+ stack := [...]uint64{sqlp, uint64(len(sql)), errp}
+ err = mod.ExportedFunction("sql3parse_table").CallWithStack(ctx, stack[:])
+ if err != nil {
+ return nil, err
+ }
+
+ c, _ := mod.Memory().ReadUint32Le(errp)
+ switch c {
+ case _MEMORY:
+ panic(util.OOMErr)
+ case _SYNTAX:
+ return nil, util.ErrorString("sql3parse: invalid syntax")
+ case _UNSUPPORTEDSQL:
+ return nil, util.ErrorString("sql3parse: unsupported SQL")
+ }
+
+ var tab Table
+ tab.load(mod, uint32(stack[0]), sql)
+ return &tab, nil
+}
+
+// Table holds metadata about a table.
+type Table struct {
+ Name string
+ Schema string
+ Comment string
+ IsTemporary bool
+ IsIfNotExists bool
+ IsWithoutRowID bool
+ IsStrict bool
+ Columns []Column
+ Type StatementType
+ CurrentName string
+ NewName string
+}
+
+func (t *Table) load(mod api.Module, ptr uint32, sql string) {
+ t.Name = loadString(mod, ptr+0, sql)
+ t.Schema = loadString(mod, ptr+8, sql)
+ t.Comment = loadString(mod, ptr+16, sql)
+
+ t.IsTemporary = loadBool(mod, ptr+24)
+ t.IsIfNotExists = loadBool(mod, ptr+25)
+ t.IsWithoutRowID = loadBool(mod, ptr+26)
+ t.IsStrict = loadBool(mod, ptr+27)
+
+ t.Columns = loadSlice(mod, ptr+28, func(ptr uint32, res *Column) {
+ p, _ := mod.Memory().ReadUint32Le(ptr)
+ res.load(mod, p, sql)
+ })
+
+ t.Type = loadEnum[StatementType](mod, ptr+44)
+ t.CurrentName = loadString(mod, ptr+48, sql)
+ t.NewName = loadString(mod, ptr+56, sql)
+}
+
+// Column holds metadata about a column.
+type Column struct {
+ Name string
+ Type string
+ Length string
+ ConstraintName string
+ Comment string
+ IsPrimaryKey bool
+ IsAutoIncrement bool
+ IsNotNull bool
+ IsUnique bool
+ PKOrder OrderClause
+ PKConflictClause ConflictClause
+ NotNullConflictClause ConflictClause
+ UniqueConflictClause ConflictClause
+ CheckExpr string
+ DefaultExpr string
+ CollateName string
+ ForeignKeyClause *ForeignKey
+}
+
+func (c *Column) load(mod api.Module, ptr uint32, sql string) {
+ c.Name = loadString(mod, ptr+0, sql)
+ c.Type = loadString(mod, ptr+8, sql)
+ c.Length = loadString(mod, ptr+16, sql)
+ c.ConstraintName = loadString(mod, ptr+24, sql)
+ c.Comment = loadString(mod, ptr+32, sql)
+
+ c.IsPrimaryKey = loadBool(mod, ptr+40)
+ c.IsAutoIncrement = loadBool(mod, ptr+41)
+ c.IsNotNull = loadBool(mod, ptr+42)
+ c.IsUnique = loadBool(mod, ptr+43)
+
+ c.PKOrder = loadEnum[OrderClause](mod, ptr+44)
+ c.PKConflictClause = loadEnum[ConflictClause](mod, ptr+48)
+ c.NotNullConflictClause = loadEnum[ConflictClause](mod, ptr+52)
+ c.UniqueConflictClause = loadEnum[ConflictClause](mod, ptr+56)
+
+ c.CheckExpr = loadString(mod, ptr+60, sql)
+ c.DefaultExpr = loadString(mod, ptr+68, sql)
+ c.CollateName = loadString(mod, ptr+76, sql)
+
+ if ptr, _ := mod.Memory().ReadUint32Le(ptr + 84); ptr != 0 {
+ c.ForeignKeyClause = &ForeignKey{}
+ c.ForeignKeyClause.load(mod, ptr, sql)
+ }
+}
+
+type ForeignKey struct {
+ Table string
+ Columns []string
+ OnDelete FKAction
+ OnUpdate FKAction
+ Match string
+ Deferrable FKDefType
+}
+
+func (f *ForeignKey) load(mod api.Module, ptr uint32, sql string) {
+ f.Table = loadString(mod, ptr+0, sql)
+
+ f.Columns = loadSlice(mod, ptr+8, func(ptr uint32, res *string) {
+ *res = loadString(mod, ptr, sql)
+ })
+
+ f.OnDelete = loadEnum[FKAction](mod, ptr+16)
+ f.OnUpdate = loadEnum[FKAction](mod, ptr+20)
+ f.Match = loadString(mod, ptr+24, sql)
+ f.Deferrable = loadEnum[FKDefType](mod, ptr+32)
+}
+
+func loadString(mod api.Module, ptr uint32, sql string) string {
+ off, _ := mod.Memory().ReadUint32Le(ptr + 0)
+ if off == 0 {
+ return ""
+ }
+ len, _ := mod.Memory().ReadUint32Le(ptr + 4)
+ return sql[off-sqlp : off+len-sqlp]
+}
+
+func loadSlice[T any](mod api.Module, ptr uint32, fn func(uint32, *T)) []T {
+ ref, _ := mod.Memory().ReadUint32Le(ptr + 4)
+ if ref == 0 {
+ return nil
+ }
+ len, _ := mod.Memory().ReadUint32Le(ptr + 0)
+ res := make([]T, len)
+ for i := range res {
+ fn(ref, &res[i])
+ ref += 4
+ }
+ return res
+}
+
+func loadEnum[T ~uint32](mod api.Module, ptr uint32) T {
+ val, _ := mod.Memory().ReadUint32Le(ptr)
+ return T(val)
+}
+
+func loadBool(mod api.Module, ptr uint32) bool {
+ val, _ := mod.Memory().ReadByte(ptr)
+ return val != 0
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm
new file mode 100644
index 000000000..f0b3819c8
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm
Binary files differ
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/sql3util.go b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/sql3util.go
new file mode 100644
index 000000000..6be61927d
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/sql3util.go
@@ -0,0 +1,9 @@
+// Package sql3util implements SQLite utilities.
+package sql3util
+
+// ValidPageSize returns true if s is a valid page size.
+//
+// https://sqlite.org/fileformat.html#pages
+func ValidPageSize(s int) bool {
+ return 512 <= s && s <= 65536 && s&(s-1) == 0
+}