Skip to content

Instantly share code, notes, and snippets.

@rhcarvalho
Created July 30, 2013 20:05
Show Gist options
  • Save rhcarvalho/6116399 to your computer and use it in GitHub Desktop.
Save rhcarvalho/6116399 to your computer and use it in GitHub Desktop.
Retrieve `matchinfo` from FTS4 table on SQLite.
package main
import (
"bytes"
"database/sql"
"encoding/binary"
_ "github.com/mattn/go-sqlite3"
"log"
)
func loadDB() *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
log.Fatal(err)
}
var sqliteVersion string
err = db.QueryRow("select sqlite_version()").Scan(&sqliteVersion)
if err != nil {
log.Fatal(err)
}
log.Println("SQLite version:", sqliteVersion)
log.Println("creating FTS index...")
_, err = db.Exec("CREATE VIRTUAL TABLE dict USING fts4(key, entry)")
if err != nil {
log.Fatal(err)
}
insertStmt, err := db.Prepare("INSERT INTO dict(key, entry) VALUES(?, ?)")
if err != nil {
log.Fatal(err)
}
defer insertStmt.Close()
dict := map[string]string{
"Russia": "Moscow",
"Poland": "Warsaw",
}
for key, entry := range dict {
insertStmt.Exec(key, entry)
}
log.Printf("indexed %d entries\n", len(dict))
return db
}
type MatchInfo struct {
P, C uint32
X []uint32
}
func (mi *MatchInfo) Read(b []byte) {
buf := bytes.NewBuffer(b)
binary.Read(buf, binary.LittleEndian, &mi.P)
binary.Read(buf, binary.LittleEndian, &mi.C)
mi.X = make([]uint32, 3*mi.P*mi.C)
binary.Read(buf, binary.LittleEndian, &mi.X)
}
func search(db *sql.DB, term string) map[int]MatchInfo {
rows, err := db.Query("SELECT docid, matchinfo(dict) FROM dict WHERE entry MATCH ?", term)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
results := make(map[int]MatchInfo)
for rows.Next() {
var (
docid int
miBytes *[]byte
mi MatchInfo
)
if err := rows.Scan(&docid, &miBytes); err != nil {
log.Fatal(err)
}
mi.Read(*miBytes)
//log.Println("****", docid, mi)
results[docid] = mi
}
return results
}
func main() {
db := loadDB()
defer db.Close()
log.Println("results:", search(db, "Warsaw"))
}
@rhcarvalho
Copy link
Author

I observe segmentation violation when db.Close() is called. Tested in two environments:

Env 1:

Env 2:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment