| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // modernc.org/sqlite depends on modernc.org/libc which doesn't work for JS (and probably wasm but I
- // think JS is the stronger signal).
- //go:build cgo && !nosqlite
- // +build cgo,!nosqlite
- package storage
- import (
- "errors"
- "path/filepath"
- "sync"
- "github.com/go-llsqlite/adapter"
- "github.com/go-llsqlite/adapter/sqlitex"
- "github.com/anacrolix/torrent/metainfo"
- )
- // sqlite is always the default when available.
- func NewDefaultPieceCompletionForDir(dir string) (PieceCompletion, error) {
- return NewSqlitePieceCompletion(dir)
- }
- type sqlitePieceCompletion struct {
- mu sync.Mutex
- closed bool
- db *sqlite.Conn
- }
- var _ PieceCompletion = (*sqlitePieceCompletion)(nil)
- func NewSqlitePieceCompletion(dir string) (ret *sqlitePieceCompletion, err error) {
- p := filepath.Join(dir, ".torrent.db")
- db, err := sqlite.OpenConn(p, 0)
- if err != nil {
- return
- }
- err = sqlitex.ExecScript(db, `create table if not exists piece_completion(infohash, "index", complete, unique(infohash, "index"))`)
- if err != nil {
- db.Close()
- return
- }
- ret = &sqlitePieceCompletion{db: db}
- return
- }
- func (me *sqlitePieceCompletion) Get(pk metainfo.PieceKey) (c Completion, err error) {
- me.mu.Lock()
- defer me.mu.Unlock()
- err = sqlitex.Exec(
- me.db, `select complete from piece_completion where infohash=? and "index"=?`,
- func(stmt *sqlite.Stmt) error {
- c.Complete = stmt.ColumnInt(0) != 0
- c.Ok = true
- return nil
- },
- pk.InfoHash.HexString(), pk.Index)
- return
- }
- func (me *sqlitePieceCompletion) Set(pk metainfo.PieceKey, b bool) error {
- me.mu.Lock()
- defer me.mu.Unlock()
- if me.closed {
- return errors.New("closed")
- }
- return sqlitex.Exec(
- me.db,
- `insert or replace into piece_completion(infohash, "index", complete) values(?, ?, ?)`,
- nil,
- pk.InfoHash.HexString(), pk.Index, b)
- }
- func (me *sqlitePieceCompletion) Close() (err error) {
- me.mu.Lock()
- defer me.mu.Unlock()
- if me.closed {
- return
- }
- err = me.db.Close()
- me.db = nil
- me.closed = true
- return
- }
|