Virtual table API.

This commit is contained in:
Nuno Cruces
2023-11-29 00:46:27 +00:00
parent 9bf14becaf
commit 3f05115cd7
7 changed files with 22 additions and 16 deletions

View File

@@ -15,7 +15,7 @@ import (
// https://sqlite.org/carray.html
func Register(db *sqlite3.Conn) {
sqlite3.CreateModule[array](db, "array", nil,
func(db *sqlite3.Conn, arg ...string) (array, error) {
func(db *sqlite3.Conn, _, _, _ string, _ ...string) (array, error) {
err := db.DeclareVtab(`CREATE TABLE x(value, array HIDDEN)`)
return array{}, err
})

View File

@@ -28,7 +28,7 @@ func Register(db *sqlite3.Conn) {
// RegisterOpen registers the CSV virtual table.
// If a filename is specified, open is used to open the file.
func RegisterOpen(db *sqlite3.Conn, open func(name string) (io.ReaderAt, error)) {
declare := func(db *sqlite3.Conn, arg ...string) (_ *table, err error) {
declare := func(db *sqlite3.Conn, _, _, _ string, arg ...string) (_ *table, err error) {
var (
filename string
data string
@@ -40,7 +40,7 @@ func RegisterOpen(db *sqlite3.Conn, open func(name string) (io.ReaderAt, error))
done = map[string]struct{}{}
)
for _, arg := range arg[3:] {
for _, arg := range arg {
key, val := getParam(arg)
if _, ok := done[key]; ok {
return nil, fmt.Errorf("csv: more than one %q parameter", key)
@@ -93,11 +93,13 @@ func RegisterOpen(db *sqlite3.Conn, open func(name string) (io.ReaderAt, error))
}
}()
if schema == "" && (header || columns < 0) {
csv := table.newReader()
row, err := csv.Read()
if err != nil {
return nil, err
if schema == "" {
var row []string
if header || columns < 0 {
row, err = table.newReader().Read()
if err != nil {
return nil, err
}
}
schema = getSchema(header, columns, row)
}

View File

@@ -23,12 +23,14 @@ func getSchema(header bool, columns int, row []string) string {
str.WriteByte('c')
str.WriteString(strconv.Itoa(i + 1))
}
str.WriteString(" TEXT")
sep = ","
}
for i := len(row); i < columns; i++ {
str.WriteString(sep)
str.WriteByte('c')
str.WriteString(strconv.Itoa(i + 1))
str.WriteString(" TEXT")
sep = ","
}
str.WriteByte(')')

View File

@@ -9,10 +9,12 @@ func Test_getSchema(t *testing.T) {
row []string
want string
}{
{true, 2, nil, `CREATE TABLE x(c1,c2)`},
{false, 2, nil, `CREATE TABLE x(c1,c2)`},
{true, 3, []string{"abc", ""}, `CREATE TABLE x("abc",c2,c3)`},
{true, 1, []string{"abc", "def"}, `CREATE TABLE x("abc")`},
{true, 2, nil, `CREATE TABLE x(c1 TEXT,c2 TEXT)`},
{false, 2, nil, `CREATE TABLE x(c1 TEXT,c2 TEXT)`},
{false, -1, []string{"abc", ""}, `CREATE TABLE x(c1 TEXT,c2 TEXT)`},
{true, 3, []string{"abc", ""}, `CREATE TABLE x("abc" TEXT,c2 TEXT,c3 TEXT)`},
{true, -1, []string{"abc", "def"}, `CREATE TABLE x("abc" TEXT,"def" TEXT)`},
{true, 1, []string{"abc", "def"}, `CREATE TABLE x("abc" TEXT)`},
}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {

View File

@@ -17,13 +17,13 @@ import (
// The lines_read virtual table reads from a file or an [io.ReaderAt].
func Register(db *sqlite3.Conn) {
sqlite3.CreateModule[lines](db, "lines", nil,
func(db *sqlite3.Conn, arg ...string) (lines, error) {
func(db *sqlite3.Conn, _, _, _ string, _ ...string) (lines, error) {
err := db.DeclareVtab(`CREATE TABLE x(line TEXT, data HIDDEN)`)
db.VtabConfig(sqlite3.VTAB_INNOCUOUS)
return false, err
})
sqlite3.CreateModule[lines](db, "lines_read", nil,
func(db *sqlite3.Conn, arg ...string) (lines, error) {
func(db *sqlite3.Conn, _, _, _ string, _ ...string) (lines, error) {
err := db.DeclareVtab(`CREATE TABLE x(line TEXT, data HIDDEN)`)
db.VtabConfig(sqlite3.VTAB_DIRECTONLY)
return true, err