Files
sqlite3/func_win_test.go

103 lines
1.7 KiB
Go
Raw Normal View History

2023-07-01 15:14:45 +01:00
package sqlite3_test
import (
"fmt"
"log"
"unicode"
"github.com/ncruces/go-sqlite3"
_ "github.com/ncruces/go-sqlite3/embed"
)
func ExampleConn_CreateWindowFunction() {
db, err := sqlite3.Open(":memory:")
if err != nil {
log.Fatal(err)
}
err = db.Exec(`CREATE TABLE IF NOT EXISTS words (word VARCHAR(10))`)
if err != nil {
log.Fatal(err)
}
err = db.Exec(`INSERT INTO words (word) VALUES ('côte'), ('cote'), ('coter'), ('coté'), ('cotée'), ('côté')`)
if err != nil {
log.Fatal(err)
}
2023-07-03 15:45:16 +01:00
err = db.CreateWindowFunction("count_ascii", 1, sqlite3.INNOCUOUS, newASCIICounter)
2023-07-01 15:14:45 +01:00
if err != nil {
log.Fatal(err)
}
2023-07-03 15:45:16 +01:00
stmt, _, err := db.Prepare(`SELECT count_ascii(word) OVER (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM words`)
2023-07-01 15:14:45 +01:00
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
for stmt.Step() {
fmt.Println(stmt.ColumnInt(0))
}
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:
2023-07-03 15:45:16 +01:00
// 1
2023-07-01 15:14:45 +01:00
// 2
2023-07-03 15:45:16 +01:00
// 2
// 1
// 0
// 0
2023-07-01 15:14:45 +01:00
}
2023-07-03 15:45:16 +01:00
type countASCII struct {
result int
}
2023-07-01 15:14:45 +01:00
2023-07-03 15:45:16 +01:00
func newASCIICounter() sqlite3.AggregateFunction {
return &countASCII{}
}
func (f *countASCII) Final(ctx sqlite3.Context) {
f.Value(ctx)
}
func (f *countASCII) Value(ctx sqlite3.Context) {
ctx.ResultInt(f.result)
}
func (f *countASCII) Step(ctx sqlite3.Context, arg ...sqlite3.Value) {
if f.isASCII(arg[0]) {
f.result++
2023-07-01 15:14:45 +01:00
}
2023-07-03 15:45:16 +01:00
}
func (f *countASCII) Inverse(ctx sqlite3.Context, arg ...sqlite3.Value) {
if f.isASCII(arg[0]) {
f.result--
2023-07-01 15:14:45 +01:00
}
}
2023-07-03 15:45:16 +01:00
func (f *countASCII) isASCII(arg sqlite3.Value) bool {
if arg.Type() != sqlite3.TEXT {
return false
}
for _, c := range arg.RawText() {
if c > unicode.MaxASCII {
return false
}
2023-07-01 15:14:45 +01:00
}
2023-07-03 15:45:16 +01:00
return true
2023-07-01 15:14:45 +01:00
}