mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 14:09:13 +00:00
185 lines
3.5 KiB
Go
185 lines
3.5 KiB
Go
package closure_test
|
|
|
|
import (
|
|
_ "embed"
|
|
"fmt"
|
|
"log"
|
|
"testing"
|
|
|
|
"github.com/ncruces/go-sqlite3"
|
|
_ "github.com/ncruces/go-sqlite3/embed"
|
|
"github.com/ncruces/go-sqlite3/ext/closure"
|
|
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
sqlite3.AutoExtension(closure.Register)
|
|
m.Run()
|
|
}
|
|
|
|
func Example() {
|
|
db, err := sqlite3.Open(":memory:")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
closure.Register(db)
|
|
|
|
err = db.Exec(`
|
|
CREATE TABLE employees (
|
|
id INTEGER PRIMARY KEY,
|
|
parent_id INTEGER,
|
|
name TEXT
|
|
);
|
|
CREATE INDEX employees_parent_idx ON employees(parent_id);
|
|
INSERT INTO employees (id, parent_id, name) VALUES
|
|
(11, NULL, 'Diane'),
|
|
(12, 11, 'Bob'),
|
|
(21, 11, 'Emma'),
|
|
(22, 21, 'Grace'),
|
|
(23, 21, 'Henry'),
|
|
(24, 21, 'Irene'),
|
|
(25, 21, 'Frank'),
|
|
(31, 11, 'Cindy'),
|
|
(32, 31, 'Dave'),
|
|
(33, 31, 'Alice');
|
|
CREATE VIRTUAL TABLE hierarchy USING transitive_closure(
|
|
tablename = "employees",
|
|
idcolumn = "id",
|
|
parentcolumn = "parent_id"
|
|
);
|
|
`)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
stmt, _, err := db.Prepare(`
|
|
SELECT employees.id, name FROM employees, hierarchy
|
|
WHERE employees.id = hierarchy.id AND hierarchy.root = 31
|
|
`)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer stmt.Close()
|
|
|
|
for stmt.Step() {
|
|
fmt.Println(stmt.ColumnInt(0), stmt.ColumnText(1))
|
|
}
|
|
if err := stmt.Err(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
err = stmt.Close()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
err = db.Close()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
// Output:
|
|
// 31 Cindy
|
|
// 32 Dave
|
|
// 33 Alice
|
|
}
|
|
|
|
func TestRegister(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
db, err := sqlite3.Open(":memory:")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
err = db.Exec(`
|
|
CREATE TABLE employees (
|
|
id INTEGER PRIMARY KEY,
|
|
parent_id INTEGER,
|
|
name TEXT
|
|
);
|
|
CREATE INDEX employees_parent_idx ON employees(parent_id);
|
|
INSERT INTO employees (id, parent_id, name) VALUES
|
|
(11, NULL, 'Diane'),
|
|
(12, 11, 'Bob'),
|
|
(21, 11, 'Emma'),
|
|
(22, 21, 'Grace'),
|
|
(23, 21, 'Henry'),
|
|
(24, 21, 'Irene'),
|
|
(25, 21, 'Frank'),
|
|
(31, 11, 'Cindy'),
|
|
(32, 31, 'Dave'),
|
|
(33, 31, 'Alice');
|
|
CREATE VIRTUAL TABLE temp.closure USING transitive_closure;
|
|
`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
stmt, _, err := db.Prepare(`
|
|
SELECT employees.id, name FROM employees, closure
|
|
WHERE employees.id = closure.id
|
|
AND closure.root = 31
|
|
AND closure.depth < 1
|
|
AND closure.tablename='employees'
|
|
AND closure.idcolumn='id'
|
|
AND closure.parentcolumn='parent_id'
|
|
`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer stmt.Close()
|
|
|
|
if !stmt.Step() {
|
|
t.Error("want row")
|
|
}
|
|
if stmt.Step() {
|
|
t.Error("don't want row")
|
|
}
|
|
if err := stmt.Err(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = stmt.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = db.Close()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func Test_errors(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
db, err := sqlite3.Open(":memory:")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
err = db.Exec(`CREATE VIRTUAL TABLE hierarchy USING transitive_closure(table='employees')`)
|
|
if err == nil {
|
|
t.Error("want error")
|
|
}
|
|
|
|
err = db.Exec(`CREATE VIRTUAL TABLE hierarchy USING transitive_closure(tablename='employees', tablename="employees")`)
|
|
if err == nil {
|
|
t.Error("want error")
|
|
}
|
|
|
|
err = db.Exec("CREATE VIRTUAL TABLE hierarchy USING transitive_closure(tablename=`employees`)")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
err = db.Exec(`SELECT * FROM hierarchy`)
|
|
if err == nil {
|
|
t.Error("want error")
|
|
}
|
|
}
|