]> Sergey Matveev's repositories - btrtrc.git/blob - storage/sqlite/direct.go
bd656e60a389c05b670c98e2ec4a0da1daabc1ba
[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 func NewWrappingClient(cache *squirrel.Cache) storage.ClientImpl {
30         return &client{
31                 cache,
32                 cache.GetCapacity,
33         }
34 }
35
36 type client struct {
37         *squirrel.Cache
38         capacity func() (int64, bool)
39 }
40
41 func (c *client) OpenTorrent(*metainfo.Info, metainfo.Hash) (storage.TorrentImpl, error) {
42         t := torrent{c.Cache}
43         return storage.TorrentImpl{Piece: t.Piece, Close: t.Close, Capacity: &c.capacity}, nil
44 }
45
46 type torrent struct {
47         c *squirrel.Cache
48 }
49
50 func (t torrent) Piece(p metainfo.Piece) storage.PieceImpl {
51         ret := piece{
52                 sb: t.c.OpenWithLength(p.Hash().HexString(), p.Length()),
53         }
54         ret.ReaderAt = &ret.sb
55         ret.WriterAt = &ret.sb
56         return ret
57 }
58
59 func (t torrent) Close() error {
60         return nil
61 }
62
63 type piece struct {
64         sb squirrel.Blob
65         io.ReaderAt
66         io.WriterAt
67 }
68
69 func (p piece) MarkComplete() error {
70         return p.sb.SetTag("verified", true)
71 }
72
73 func (p piece) MarkNotComplete() error {
74         return p.sb.SetTag("verified", false)
75 }
76
77 func (p piece) Completion() (ret storage.Completion) {
78         err := p.sb.GetTag("verified", func(stmt *sqlite.Stmt) {
79                 ret.Complete = stmt.ColumnInt(0) != 0
80         })
81         ret.Ok = err == nil
82         ret.Err = err
83         return
84 }