//go:build sqlite_vtable || vtable package vtab import "git.fsdpf.net/go/db/exp" // FilterValue 是一个 WHERE 约束值,包含实际值和操作符类型。 // 用于 BestIndex/Filter 阶段向上层传递结构化的过滤条件。 type FilterValue struct { Value any Op exp.BooleanOperation } // Module 是虚拟表工厂,每个数据库连接各调用一次。 type Module interface { // Create 在 CREATE VIRTUAL TABLE 时调用。 // args 是 CREATE VIRTUAL TABLE 语句括号内的参数列表(已去除引号): // args[0] = 模块名, args[1] = 数据库名, args[2] = 表名, args[3..] = 用户参数 // declare 必须被调用以声明表结构,例如: // declare("CREATE TABLE t(id INTEGER, name TEXT)") Create(args []string, declare func(schema string) error) (Table, error) // Connect 在重新连接到已有虚拟表时调用(通常与 Create 实现相同)。 Connect(args []string, declare func(schema string) error) (Table, error) } // Table 是虚拟表实例(只读),每个连接持有一个。 // 若需要写操作,同时实现 WritableTable 接口即可,框架会自动识别。 type Table interface { // BestIndex 告知 SQLite 本表能处理哪些 WHERE 约束。 // 返回的 IndexOutput.Used 长度必须与传入的 constraints 长度一致。 // 简单实现:返回 Used 全为 false,让 SQLite 做全表扫描后自行过滤。 BestIndex(constraints []ConstraintInfo, orderBy []OrderByInfo) (*IndexOutput, error) // Open 为每次查询创建一个游标实例。 Open() (Cursor, error) // Disconnect 在连接关闭时调用,用于释放连接级资源。 Disconnect() error // Destroy 在 DROP TABLE 时调用,用于清理持久化资源。 Destroy() error } // WritableTable 在 Table 基础上增加写操作支持。 // 只需让 Table 实现同时满足该接口,框架会自动启用写操作。 type WritableTable interface { Table // Insert 插入一行,values 顺序与 DeclareVTab 中列的顺序一致。 // 返回新行的 rowid(若表有整型主键,应返回主键值)。 Insert(values []any) (rowid int64, err error) // Update 更新 rowid 对应的行,values 同 Insert。 Update(rowid any, values []any) error // Delete 删除 rowid 对应的行。 Delete(rowid any) error } // Cursor 是行迭代器,每次查询(SELECT)创建一个独立实例。 type Cursor interface { // Filter 开始或重置扫描。 // idxNum 来自 BestIndex 返回的 IndexOutput.IdxNum,可用于区分查询计划。 // constraints 是 BestIndex 中 Used=true 的约束,适配层已自动绑定值(ConstraintInfo.Value), // 无需手动编解码 idxStr。 Filter(idxNum int, constraints []ConstraintInfo) error // Next 移动到下一行。 Next() error // EOF 返回 true 表示已无更多行。 EOF() bool // Column 返回第 col 列的值。nil 表示 SQL NULL。 // 支持的类型:int/int32/int64、float32/float64、bool、string、[]byte。 // 其他类型会被 fmt.Sprint 转为字符串。 Column(col int) (any, error) // Rowid 返回当前行的 rowid。 Rowid() (int64, error) // Close 释放游标资源。 Close() error }