7 "crawshaw.io/sqlite/sqlitex"
8 "github.com/anacrolix/torrent/metainfo"
9 "github.com/anacrolix/torrent/storage"
12 type NewDirectStorageOpts struct {
14 ProvOpts func(*ProviderOpts)
17 // A convenience function that creates a connection pool, resource provider, and a pieces storage
18 // ClientImpl and returns them all with a Close attached.
19 func NewDirectStorage(opts NewDirectStorageOpts) (_ storage.ClientImplCloser, err error) {
20 conns, provOpts, err := NewPool(opts.NewPoolOpts)
24 if f := opts.ProvOpts; f != nil {
27 provOpts.BatchWrites = false
28 prov, err := NewProvider(conns, provOpts)
35 conn: prov.pool.Get(nil),
46 func (c *client) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (storage.TorrentImpl, error) {
47 return torrent{c}, nil
50 func (c *client) Close() error {
54 c.prov.pool.Put(c.conn)
62 func rowidForBlob(c conn, name string, length int64) (rowid int64, err error) {
63 err = sqlitex.Exec(c, "select rowid from blob where name=?", func(stmt *sqlite.Stmt) error {
64 rowid = stmt.ColumnInt64(0)
73 err = sqlitex.Exec(c, "insert into blob(name, data) values(?, zeroblob(?))", nil, name, length)
77 rowid = c.LastInsertRowID()
81 func (t torrent) Piece(p metainfo.Piece) storage.PieceImpl {
84 name := p.Hash().HexString()
85 return piece{t.c.conn, name, &t.c.l, p.Length(), &t.c.blob}
88 func (t torrent) Close() error {
100 func (p2 piece) getBlob() *sqlite.Blob {
102 err := (*p2.blob).Close()
108 rowid, err := rowidForBlob(p2.conn, p2.name, p2.length)
112 *p2.blob, err = p2.conn.OpenBlob("main", "blob", "data", rowid, true)
119 func (p2 piece) ReadAt(p []byte, off int64) (n int, err error) {
123 return blob.ReadAt(p, off)
126 func (p2 piece) WriteAt(p []byte, off int64) (n int, err error) {
129 return p2.getBlob().WriteAt(p, off)
132 func (p2 piece) MarkComplete() error {
135 err := sqlitex.Exec(p2.conn, "update blob set verified=true where name=?", nil, p2.name)
139 changes := p2.conn.Changes()
146 func (p2 piece) MarkNotComplete() error {
147 panic("implement me")
150 func (p2 piece) Completion() (ret storage.Completion) {
153 err := sqlitex.Exec(p2.conn, "select verified from blob where name=?", func(stmt *sqlite.Stmt) error {
154 ret.Complete = stmt.ColumnInt(0) != 0