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