elvish/store/store.go

59 lines
1.2 KiB
Go
Raw Normal View History

2016-01-29 10:00:41 +08:00
// Package store abstracts the persistent storage used by elvish.
2014-10-01 06:57:38 +08:00
package store
import (
"database/sql"
"fmt"
2014-10-01 06:57:38 +08:00
"net/url"
"sync"
2014-10-01 06:57:38 +08:00
2016-02-20 10:04:44 +08:00
_ "github.com/mattn/go-sqlite3" // enable the "sqlite3" SQL driver
2014-10-01 06:57:38 +08:00
)
2016-02-08 06:23:16 +08:00
// Store is the permanent storage backend for elvish.
2014-10-01 06:57:38 +08:00
type Store struct {
db *sql.DB
Waits sync.WaitGroup
2014-10-01 06:57:38 +08:00
}
var initTable = map[string](func(*sql.DB) error){}
2014-10-01 06:57:38 +08:00
// DefaultDB returns the default database for storage.
2016-02-13 07:35:33 +08:00
func DefaultDB(dbname string) (*sql.DB, error) {
uri := "file:" + url.QueryEscape(dbname) +
2014-10-01 06:57:38 +08:00
"?mode=rwc&cache=shared&vfs=unix-dotfile"
return sql.Open("sqlite3", uri)
}
// NewStore creates a new Store with the default database.
2016-02-13 07:35:33 +08:00
func NewStore(dbname string) (*Store, error) {
db, err := DefaultDB(dbname)
2014-10-01 06:57:38 +08:00
if err != nil {
return nil, err
}
return NewStoreDB(db)
}
// NewStoreDB creates a new Store with a custom database. The database must be
// a SQLite database.
func NewStoreDB(db *sql.DB) (*Store, error) {
st := &Store{db, sync.WaitGroup{}}
for name, fn := range initTable {
err := fn(db)
if err != nil {
return nil, fmt.Errorf("failed to initialize table %s: %v", name, err)
}
2014-10-01 06:57:38 +08:00
}
return st, nil
2014-10-01 06:57:38 +08:00
}
func (s *Store) Close() error {
if s == nil || s.db == nil {
2016-02-20 08:37:38 +08:00
return nil
}
s.Waits.Wait()
return s.db.Close()
}