package index
import (
"context"
"database/sql"
sqldriver "database/sql/driver"
"github.com/ncruces/go-sqlite3"
"github.com/ncruces/go-sqlite3/driver"
"github.com/ncruces/go-sqlite3/ext/fts5"
)
// connMaxMemory is how much memory one index connection may use. The
// driver's own ceiling is 256MB per connection (go-sqlite3 wrap.go),
// and a store of millions of artifacts went past it: netbsd-src (2.5M
// artifacts) ran SQLite out of memory folding and opening its index
// (#357). Memory grows only as a connection uses it, so this is a
// ceiling, not a reservation; wasm32 cannot address more than 4GB.
var connMaxMemory int64 = 1 << 30
// openDB opens an index handle whose every connection carries
// connMaxMemory and the fts5 module. The limit travels on the context
// the connection is opened with, which database/sql supplies, so the
// driver's connector is wrapped rather than configured.
func openDB(dsn string) (*sql.DB, error) {
c, err := (&driver.SQLite{}).OpenConnector(dsn)
if err != nil {
return nil, err
}
return sql.OpenDB(memConnector{c}), nil
}
type memConnector struct{ inner sqldriver.Connector }
func (m memConnector) Connect(ctx context.Context) (sqldriver.Conn, error) {
c, err := m.inner.Connect(sqlite3.WithMaxMemory(ctx, connMaxMemory))
if err != nil {
return nil, err
}
if err := fts5.Register(c.(interface{ Raw() *sqlite3.Conn }).Raw()); err != nil {
c.Close()
return nil, err
}
return c, nil
}
func (m memConnector) Driver() sqldriver.Driver { return m.inner.Driver() }