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