]> Sergey Matveev's repositories - btrtrc.git/blob - storage/sqlite/direct.go
Update squirrel
[btrtrc.git] / storage / sqlite / direct.go
1 //go:build cgo
2 // +build cgo
3
4 package sqliteStorage
5
6 import (
7         "io"
8
9         "crawshaw.io/sqlite"
10         "github.com/anacrolix/squirrel"
11
12         "github.com/anacrolix/torrent/metainfo"
13         "github.com/anacrolix/torrent/storage"
14 )
15
16 // A convenience function that creates a connection pool, resource provider, and a pieces storage
17 // ClientImpl and returns them all with a Close attached.
18 func NewDirectStorage(opts NewDirectStorageOpts) (_ storage.ClientImplCloser, err error) {
19         cache, err := squirrel.NewCache(opts)
20         if err != nil {
21                 return
22         }
23         return &client{
24                 cache,
25                 cache.GetCapacity,
26         }, nil
27 }
28
29 type client struct {
30         *squirrel.Cache
31         capacity func() *int64
32 }
33
34 func (c *client) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (storage.TorrentImpl, error) {
35         t := torrent{c.Cache}
36         return storage.TorrentImpl{Piece: t.Piece, Close: t.Close, Capacity: &c.capacity}, nil
37 }
38
39 type torrent struct {
40         c *squirrel.Cache
41 }
42
43 func (t torrent) Piece(p metainfo.Piece) storage.PieceImpl {
44         ret := piece{
45                 sb: t.c.OpenWithLength(p.Hash().HexString(), p.Length()),
46         }
47         ret.ReaderAt = &ret.sb
48         ret.WriterAt = &ret.sb
49         return ret
50 }
51
52 func (t torrent) Close() error {
53         return nil
54 }
55
56 type piece struct {
57         sb squirrel.Blob
58         io.ReaderAt
59         io.WriterAt
60 }
61
62 func (p piece) MarkComplete() error {
63         return p.sb.SetTag("verified", true)
64 }
65
66 func (p piece) MarkNotComplete() error {
67         return p.sb.SetTag("verified", false)
68 }
69
70 func (p piece) Completion() (ret storage.Completion) {
71         err := p.sb.GetTag("verified", func(stmt *sqlite.Stmt) {
72                 ret.Complete = stmt.ColumnInt(0) != 0
73         })
74         ret.Ok = err == nil
75         if err != nil {
76                 panic(err)
77         }
78         return
79 }