1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
// Copyright 2023 Roxy Light
// SPDX-License-Identifier: ISC
package sqlite_test
import (
"fmt"
"log"
"zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex"
)
func ExampleVTable() {
conn, err := sqlite.OpenConn(":memory:")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
err = conn.SetModule("templatevtab", &sqlite.Module{
Connect: templatevtabConnect,
})
if err != nil {
log.Fatal(err)
}
err = sqlitex.ExecuteTransient(
conn,
`SELECT a, b FROM templatevtab ORDER BY rowid;`,
&sqlitex.ExecOptions{
ResultFunc: func(stmt *sqlite.Stmt) error {
fmt.Printf("%4d, %4d\n", stmt.ColumnInt(0), stmt.ColumnInt(1))
return nil
},
},
)
if err != nil {
log.Fatal(err)
}
// Output:
// 1001, 2001
// 1002, 2002
// 1003, 2003
// 1004, 2004
// 1005, 2005
// 1006, 2006
// 1007, 2007
// 1008, 2008
// 1009, 2009
// 1010, 2010
}
type templatevtab struct{}
const (
templatevarColumnA = iota
templatevarColumnB
)
func templatevtabConnect(c *sqlite.Conn, opts *sqlite.VTableConnectOptions) (sqlite.VTable, *sqlite.VTableConfig, error) {
vtab := new(templatevtab)
cfg := &sqlite.VTableConfig{
Declaration: "CREATE TABLE x(a,b)",
}
return vtab, cfg, nil
}
func (vt *templatevtab) BestIndex(*sqlite.IndexInputs) (*sqlite.IndexOutputs, error) {
return &sqlite.IndexOutputs{
EstimatedCost: 10,
EstimatedRows: 10,
}, nil
}
func (vt *templatevtab) Open() (sqlite.VTableCursor, error) {
return &templatevtabCursor{rowid: 1}, nil
}
func (vt *templatevtab) Disconnect() error {
return nil
}
func (vt *templatevtab) Destroy() error {
return nil
}
type templatevtabCursor struct {
rowid int64
}
func (cur *templatevtabCursor) Filter(id sqlite.IndexID, argv []sqlite.Value) error {
cur.rowid = 1
return nil
}
func (cur *templatevtabCursor) Next() error {
cur.rowid++
return nil
}
func (cur *templatevtabCursor) Column(i int, noChange bool) (sqlite.Value, error) {
switch i {
case templatevarColumnA:
return sqlite.IntegerValue(1000 + cur.rowid), nil
case templatevarColumnB:
return sqlite.IntegerValue(2000 + cur.rowid), nil
default:
panic("unreachable")
}
}
func (cur *templatevtabCursor) RowID() (int64, error) {
return cur.rowid, nil
}
func (cur *templatevtabCursor) EOF() bool {
return cur.rowid > 10
}
func (cur *templatevtabCursor) Close() error {
return nil
}
|