magneticod: add mysql support

This commit is contained in:
Martin Weinelt 2017-08-10 22:47:42 +02:00
parent 374ce0538a
commit 1123c948f9

View File

@ -5,6 +5,7 @@ import (
"database/sql" "database/sql"
"net/url" "net/url"
_ "github.com/go-sql-driver/mysql"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"go.uber.org/zap" "go.uber.org/zap"
@ -14,22 +15,20 @@ import (
"os" "os"
) )
type engineType uint8 type engineType uint8
const ( const (
SQLITE engineType = 0 SQLITE engineType = 0
POSTGRESQL = 1 POSTGRESQL = 1
MYSQL = 2
) )
type Database struct { type Database struct {
database *sql.DB database *sql.DB
engine engineType engine engineType
newTorrents chan bittorrent.Metadata newTorrents chan bittorrent.Metadata
} }
// NewDatabase creates a new Database. // NewDatabase creates a new Database.
// //
// url either starts with "sqlite:" or "postgresql:" // url either starts with "sqlite:" or "postgresql:"
@ -66,6 +65,10 @@ func NewDatabase(rawurl string) (*Database, error) {
db.engine = POSTGRESQL db.engine = POSTGRESQL
db.database, err = sql.Open("postgresql", rawurl) db.database, err = sql.Open("postgresql", rawurl)
case "mysql":
db.engine = MYSQL
db.database, err = sql.Open("mysql", rawurl)
default: default:
return nil, fmt.Errorf("unknown URI scheme (or malformed URI)!") return nil, fmt.Errorf("unknown URI scheme (or malformed URI)!")
} }
@ -88,7 +91,6 @@ func NewDatabase(rawurl string) (*Database, error) {
return &db, nil return &db, nil
} }
// AddNewTorrent adds a new torrent to the *queue* to be flushed to the persistent database. // AddNewTorrent adds a new torrent to the *queue* to be flushed to the persistent database.
func (db *Database) AddNewTorrent(torrent bittorrent.Metadata) error { func (db *Database) AddNewTorrent(torrent bittorrent.Metadata) error {
for { for {
@ -106,7 +108,6 @@ func (db *Database) AddNewTorrent(torrent bittorrent.Metadata) error {
} }
} }
func (db *Database) flushNewTorrents() error { func (db *Database) flushNewTorrents() error {
tx, err := db.database.Begin() tx, err := db.database.Begin()
if err != nil { if err != nil {
@ -154,13 +155,11 @@ func (db *Database) flushNewTorrents() error {
return nil return nil
} }
func (db *Database) Close() { func (db *Database) Close() {
// Be careful to not to get into an infinite loop. =) // Be careful to not to get into an infinite loop. =)
db.database.Close() db.database.Close()
} }
func (db *Database) setupDatabase() error { func (db *Database) setupDatabase() error {
switch db.engine { switch db.engine {
case SQLITE: case SQLITE:
@ -169,6 +168,9 @@ func (db *Database) setupDatabase() error {
case POSTGRESQL: case POSTGRESQL:
zap.L().Fatal("setupDatabase() is not implemented for PostgreSQL yet!") zap.L().Fatal("setupDatabase() is not implemented for PostgreSQL yet!")
case MYSQL:
return setupMySQLDatabase(db.database)
default: default:
zap.L().Sugar().Fatalf("Unknown database engine value %d! (programmer error)", db.engine) zap.L().Sugar().Fatalf("Unknown database engine value %d! (programmer error)", db.engine)
} }
@ -176,7 +178,6 @@ func (db *Database) setupDatabase() error {
return nil return nil
} }
func setupSqliteDatabase(database *sql.DB) error { func setupSqliteDatabase(database *sql.DB) error {
// Enable Write-Ahead Logging for SQLite as "WAL provides more concurrency as readers do not // Enable Write-Ahead Logging for SQLite as "WAL provides more concurrency as readers do not
// block writers and a writer does not block readers. Reading and writing can proceed // block writers and a writer does not block readers. Reading and writing can proceed
@ -226,3 +227,30 @@ func setupSqliteDatabase(database *sql.DB) error {
return nil return nil
} }
func setupMySQLDatabase(database *sql.DB) error {
_, err := database.Exec(
`CREATE TABLE IF NOT EXISTS torrents ("
id INTEGER PRIMARY KEY AUTO_INCREMENT,
info_hash BINARY(20) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
total_size BIGINT UNSIGNED NOT NULL,
discovered_on INTEGER UNSIGNED NOT NULL
);
ALTER TABLE torrents ADD INDEX info_hash_index (info_hash);
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
torrent_id INTEGER REFERENCES torrents (id) ON DELETE CASCADE ON UPDATE RESTRICT,
size BIGINT NOT NULL,
path TEXT NOT NULL
);`,
)
if err != nil {
return err
}
return nil
}