256 lines
7.3 KiB
Go
256 lines
7.3 KiB
Go
package data
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
gonanoid "github.com/matoous/go-nanoid"
|
|
)
|
|
|
|
type RemoteDatabase struct {
|
|
Connection *sql.DB
|
|
databaseDirectory string
|
|
}
|
|
|
|
func (db *RemoteDatabase) Initialize() error {
|
|
connection, error := sql.Open("sqlite3", filepath.Join(db.databaseDirectory, "remotes.db"))
|
|
if error != nil {
|
|
return error
|
|
}
|
|
db.Connection = connection
|
|
|
|
_, error = db.Connection.Exec(`PRAGMA foreign_keys = ON;`)
|
|
if error != nil {
|
|
return fmt.Errorf("error enabling foreign keys: %s", error)
|
|
}
|
|
|
|
_, error = db.Connection.Exec(`
|
|
CREATE TABLE IF NOT EXISTS Remotes (
|
|
id TEXT PRIMARY KEY,
|
|
title TEXT NOT NULL
|
|
);`)
|
|
if error != nil {
|
|
return fmt.Errorf("error creating remotes table: %s", error)
|
|
}
|
|
|
|
_, error = db.Connection.Exec(`
|
|
CREATE TABLE IF NOT EXISTS Commands (
|
|
id TEXT PRIMARY KEY,
|
|
protocol TEXT,
|
|
commandNumber INTEGER,
|
|
device INTEGER,
|
|
commandType TEXT,
|
|
title TEXT
|
|
);`)
|
|
if error != nil {
|
|
return fmt.Errorf("error creating commands table: %s", error)
|
|
}
|
|
|
|
_, error = db.Connection.Exec(`
|
|
CREATE TABLE IF NOT EXISTS RemoteCommands (
|
|
remote_id TEXT NOT NULL,
|
|
command_id TEXT NOT NULL,
|
|
PRIMARY KEY (remote_id, command_id),
|
|
FOREIGN KEY (remote_id) REFERENCES Remotes(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (command_id) REFERENCES Commands(id) ON DELETE CASCADE
|
|
);`)
|
|
if error != nil {
|
|
return fmt.Errorf("error creating remote-commands table: %s", error)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) Close() error {
|
|
return db.Connection.Close()
|
|
}
|
|
|
|
func (db *RemoteDatabase) CreateRemote(remote Remote) (string, error) {
|
|
remoteId, err := gonanoid.Nanoid(8)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
queryString := "INSERT INTO Remotes (id, title) VALUES (?, ?)"
|
|
_, err = db.Connection.Exec(queryString, remoteId, remote.Title)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
commandIds := []string{}
|
|
for _, command := range remote.Commands {
|
|
commandIds = append(commandIds, command.Id)
|
|
}
|
|
err = db.CreateRemoteCommands(remoteId, commandIds)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return remoteId, nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) CreateRemoteCommands(remoteId string, commandIds []string) error {
|
|
for _, commandId := range commandIds {
|
|
queryString := "INSERT INTO RemoteCommands (remote_id, command_id) VALUES (?, ?)"
|
|
_, err := db.Connection.Exec(queryString, remoteId, commandId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) UpdateRemoteCommands(remoteId string, commandIds []string) error {
|
|
queryString := "DELETE FROM RemoteCommands WHERE remote_id = ?"
|
|
_, err := db.Connection.Exec(queryString, remoteId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = db.CreateRemoteCommands(remoteId, commandIds)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) GetRemote(remoteId string) (Remote, error) {
|
|
var remote Remote
|
|
queryString := "SELECT id, title FROM Remotes WHERE id = ?"
|
|
row := db.Connection.QueryRow(queryString, remoteId)
|
|
error := row.Scan(&remote.Id, &remote.Title)
|
|
if error != nil {
|
|
return Remote{}, fmt.Errorf("error scanning remote: %s", error)
|
|
}
|
|
commands, error := db.GetCommandsByRemoteId(remoteId)
|
|
if error != nil {
|
|
return Remote{}, error
|
|
}
|
|
remote.Commands = commands
|
|
return remote, nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) GetRemotes() ([]Remote, error) {
|
|
rows, error := db.Connection.Query("SELECT id, title FROM Remotes")
|
|
if error != nil {
|
|
return nil, fmt.Errorf("error querying remotes: %s", error)
|
|
}
|
|
defer rows.Close()
|
|
|
|
remotes := []Remote{}
|
|
for rows.Next() {
|
|
var remote Remote
|
|
error = rows.Scan(&remote.Id, &remote.Title)
|
|
if error != nil {
|
|
return nil, fmt.Errorf("error scanning remote: %s", error)
|
|
}
|
|
remotes = append(remotes, remote)
|
|
}
|
|
return remotes, nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) UpdateRemote(remote Remote) error {
|
|
queryString := "UPDATE Remotes SET title = ? WHERE id = ?"
|
|
_, error := db.Connection.Exec(queryString, remote.Title, remote.Id)
|
|
if error != nil {
|
|
return fmt.Errorf("error updating remote %s: %s", remote.Id, error)
|
|
}
|
|
commandIds := []string{}
|
|
for _, command := range remote.Commands {
|
|
commandIds = append(commandIds, command.Id)
|
|
}
|
|
err := db.UpdateRemoteCommands(remote.Id, commandIds)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) DeleteRemote(remoteId string) error {
|
|
queryString := "DELETE FROM Remotes WHERE id = ?"
|
|
_, error := db.Connection.Exec(queryString, remoteId)
|
|
if error != nil {
|
|
return fmt.Errorf("error deleting remote %s: %s", remoteId, error)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) GetCommandsByRemoteId(remoteId string) ([]Command, error) {
|
|
rows, error := db.Connection.Query("SELECT id, protocol, commandNumber, device, commandType, title FROM Commands WHERE id IN (SELECT command_id FROM RemoteCommands WHERE remote_id = ?)", remoteId)
|
|
if error != nil {
|
|
return nil, fmt.Errorf("error querying commands for remote %s: %s", remoteId, error)
|
|
}
|
|
defer rows.Close()
|
|
|
|
commands := []Command{}
|
|
for rows.Next() {
|
|
var command Command
|
|
error = rows.Scan(&command.Id, &command.Protocol, &command.CommandNumber, &command.Device, &command.CommandType, &command.Title)
|
|
if error != nil {
|
|
return nil, fmt.Errorf("error scanning command: %s", error)
|
|
}
|
|
commands = append(commands, command)
|
|
}
|
|
return commands, nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) CreateCommand(command Command) (string, error) {
|
|
commandId, err := gonanoid.Nanoid(8)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
queryString := "INSERT INTO Commands (id, protocol, commandNumber, device, commandType, title) VALUES (?, ?, ?, ?, ?, ?)"
|
|
_, err = db.Connection.Exec(queryString, commandId, command.Protocol, command.CommandNumber, command.Device, command.CommandType, command.Title)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return commandId, nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) CreateCommands(commands []Command) error {
|
|
for _, command := range commands {
|
|
_, err := db.CreateCommand(command)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) GetCommands() ([]Command, error) {
|
|
rows, error := db.Connection.Query("SELECT id, protocol, commandNumber, device, commandType, title FROM Commands")
|
|
if error != nil {
|
|
return nil, fmt.Errorf("error querying commands: %s", error)
|
|
}
|
|
defer rows.Close()
|
|
|
|
commands := []Command{}
|
|
for rows.Next() {
|
|
var command Command
|
|
error = rows.Scan(&command.Id, &command.Protocol, &command.CommandNumber, &command.Device, &command.CommandType, &command.Title)
|
|
if error != nil {
|
|
return nil, fmt.Errorf("error scanning command: %s", error)
|
|
}
|
|
commands = append(commands, command)
|
|
}
|
|
return commands, nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) UpdateCommand(command Command) error {
|
|
queryString := "UPDATE Commands SET protocol = ?, commandNumber = ?, device = ?, commandType = ?, title = ? WHERE id = ?"
|
|
_, error := db.Connection.Exec(queryString, command.Protocol, command.CommandNumber, command.Device, command.CommandType, command.Title, command.Id)
|
|
if error != nil {
|
|
return fmt.Errorf("error updating command %s: %s", command.Id, error)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) DeleteCommand(commandId string) error {
|
|
queryString := "DELETE FROM Commands WHERE id = ?"
|
|
_, error := db.Connection.Exec(queryString, commandId)
|
|
if error != nil {
|
|
return fmt.Errorf("error deleting command %s: %s", commandId, error)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *RemoteDatabase) SetDirectory(directory string) {
|
|
db.databaseDirectory = directory
|
|
}
|