2017-11-03 00:15:13 +01:00
|
|
|
package persistence
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
2018-03-03 18:09:49 +01:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
2017-11-03 00:15:13 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Database interface {
|
|
|
|
Engine() databaseEngine
|
|
|
|
DoesTorrentExist(infoHash []byte) (bool, error)
|
|
|
|
AddNewTorrent(infoHash []byte, name string, files []File) error
|
|
|
|
Close() error
|
|
|
|
|
|
|
|
// GetNumberOfTorrents returns the number of torrents saved in the database. Might be an
|
|
|
|
// approximation.
|
|
|
|
GetNumberOfTorrents() (uint, error)
|
|
|
|
// QueryTorrents returns @n torrents
|
|
|
|
// * that are discovered before the @timePoint if @isAfter is false, else that are
|
|
|
|
// discovered after the @timePoint,
|
|
|
|
// * that match the @query if it's not empty,
|
|
|
|
// ordered by the @orderBy in ascending order if @isDescending is false, else in descending
|
|
|
|
// order.
|
2018-03-03 18:09:49 +01:00
|
|
|
QueryTorrents(query string, discoveredOnBefore int64, orderBy orderingCriteria, ascending bool, page uint, pageSize uint) ([]TorrentMetadata, error)
|
2017-11-03 00:15:13 +01:00
|
|
|
// GetTorrents returns the TorrentExtMetadata for the torrent of the given InfoHash. Might return
|
|
|
|
// nil, nil if the torrent does not exist in the database.
|
|
|
|
GetTorrent(infoHash []byte) (*TorrentMetadata, error)
|
|
|
|
GetFiles(infoHash []byte) ([]File, error)
|
2018-03-03 18:09:49 +01:00
|
|
|
GetStatistics(n uint, granularity Granularity, to time.Time) (*Statistics, error)
|
2017-11-03 00:15:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type orderingCriteria uint8
|
|
|
|
const (
|
2018-03-03 18:09:49 +01:00
|
|
|
ByRelevance orderingCriteria = iota
|
|
|
|
BySize
|
|
|
|
ByDiscoveredOn
|
|
|
|
ByNFiles
|
2017-11-03 00:15:13 +01:00
|
|
|
)
|
|
|
|
|
2018-03-03 18:09:49 +01:00
|
|
|
type Granularity uint8
|
2017-11-03 00:15:13 +01:00
|
|
|
const (
|
2018-03-03 18:09:49 +01:00
|
|
|
Yearly Granularity = iota
|
|
|
|
Monthly
|
|
|
|
Weekly
|
|
|
|
Daily
|
|
|
|
Hourly
|
2017-11-03 00:15:13 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type databaseEngine uint8
|
|
|
|
const (
|
2018-03-03 18:09:49 +01:00
|
|
|
Sqlite3 databaseEngine = 1
|
2017-11-03 00:15:13 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Statistics struct {
|
2018-03-03 18:09:49 +01:00
|
|
|
N uint
|
2017-11-03 00:15:13 +01:00
|
|
|
|
|
|
|
// All these slices below have the exact length equal to the Period.
|
|
|
|
NTorrentsDiscovered []uint
|
|
|
|
NFilesDiscovered []uint
|
|
|
|
}
|
|
|
|
|
|
|
|
type File struct {
|
|
|
|
Size int64
|
|
|
|
Path string
|
|
|
|
}
|
|
|
|
|
|
|
|
type TorrentMetadata struct {
|
|
|
|
InfoHash []byte
|
|
|
|
Name string
|
2018-03-03 18:09:49 +01:00
|
|
|
TotalSize uint64
|
2017-11-03 00:15:13 +01:00
|
|
|
DiscoveredOn int64
|
|
|
|
NFiles uint
|
|
|
|
}
|
|
|
|
|
|
|
|
func MakeDatabase(rawURL string, enableFTS bool, logger *zap.Logger) (Database, error) {
|
|
|
|
if logger != nil {
|
|
|
|
zap.ReplaceGlobals(logger)
|
|
|
|
}
|
|
|
|
|
|
|
|
url_, err := url.Parse(rawURL)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
switch url_.Scheme {
|
|
|
|
case "sqlite3":
|
|
|
|
return makeSqlite3Database(url_, enableFTS)
|
|
|
|
|
|
|
|
case "postgresql":
|
|
|
|
return nil, fmt.Errorf("postgresql is not yet supported!")
|
|
|
|
|
|
|
|
case "mysql":
|
|
|
|
return nil, fmt.Errorf("mysql is not yet supported!")
|
|
|
|
|
2018-03-03 18:09:49 +01:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unknown URI scheme (database engine)!")
|
|
|
|
}
|
2017-11-03 00:15:13 +01:00
|
|
|
}
|