File: vtable_example_test.go

package info (click to toggle)
golang-github-zombiezen-go-sqlite 1.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 816 kB
  • sloc: makefile: 3
file content (123 lines) | stat: -rw-r--r-- 2,355 bytes parent folder | download
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
}