summaryrefslogtreecommitdiff
path: root/storage/sqlite
diff options
context:
space:
mode:
Diffstat (limited to 'storage/sqlite')
-rw-r--r--storage/sqlite/sqlite.go132
1 files changed, 132 insertions, 0 deletions
diff --git a/storage/sqlite/sqlite.go b/storage/sqlite/sqlite.go
new file mode 100644
index 0000000..9372828
--- /dev/null
+++ b/storage/sqlite/sqlite.go
@@ -0,0 +1,132 @@
+package sqlite
+
+import (
+ "database/sql"
+ "delayed.link/storage"
+ "encoding/json"
+ "errors"
+ "github.com/google/uuid"
+ _ "github.com/mattn/go-sqlite3"
+ "github.com/spf13/pflag"
+ "log"
+)
+
+var (
+ dbFile = pflag.StringP("dbfile", "d", "delayedlink.db", "")
+)
+
+type SqliteStorage struct {
+ *sql.DB
+}
+
+func (s *SqliteStorage) Close() error {
+ return s.DB.Close()
+}
+
+func (s *SqliteStorage) Save(item storage.Link) (uuid.UUID, error) {
+ stmt, err := s.Prepare("INSERT INTO links VALUES (?, ?)")
+ if err != nil {
+ return storage.Null, err
+ }
+ id := uuid.New()
+ item.Id = id
+ obj, err := item.Serialize()
+ if err != nil {
+ return storage.Null, err
+ }
+ _, err = stmt.Exec(id, obj)
+ if err != nil {
+ return storage.Null, err
+ }
+ return id, nil
+}
+
+const insertStatement = `SELECT (obj) FROM links WHERE id = ? LIMIT 1`
+
+func (s *SqliteStorage) Load(key uuid.UUID) (*storage.Link, error) {
+ stmt, err := s.DB.Prepare(insertStatement)
+ if err != nil {
+ return nil, err
+ }
+ rows, err := stmt.Query(key.String())
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var link *storage.Link
+ var data []byte
+ if !rows.Next() {
+ return nil, storage.NotFoundError
+ }
+ err = rows.Scan(&data)
+ if err != nil {
+ return nil, err
+ }
+ err = json.Unmarshal(data, &link)
+ if err != nil {
+ return nil, err
+ }
+
+ return link, nil
+}
+
+const creation_sql = `CREATE TABLE IF NOT EXISTS links (
+ id UUID PRIMARY KEY,
+ obj JSONB NOT NULL
+);`
+
+func New() *SqliteStorage {
+ db, err := sql.Open("sqlite3", *dbFile)
+ if err != nil {
+ log.Panic(err)
+ }
+
+ _, err = db.Exec(creation_sql)
+ if err != nil {
+ panic(err)
+ }
+
+ return &SqliteStorage{
+ db,
+ }
+}
+
+const deleteQuery = `DELETE FROM links WHERE id = ?`
+
+var NotFoundError = errors.New("entry not found")
+
+func (s *SqliteStorage) Delete(item storage.Link) error {
+ stmt, err := s.DB.Prepare(deleteQuery)
+ if err != nil {
+ return err
+ }
+ res, err := stmt.Exec(item.Id)
+ if err != nil {
+ return err
+ }
+ if aff, err := res.RowsAffected(); aff < 1 || err != nil {
+ if err == nil {
+ return NotFoundError
+ }
+ return err
+ }
+ return nil
+}
+
+const updateQuery = `UPDATE links SET obj = ? WHERE id = ?`
+
+func (s *SqliteStorage) Update(item storage.Link) error {
+ stmt, err := s.DB.Prepare(updateQuery)
+ if err != nil {
+ return err
+ }
+ obj, err := item.Serialize()
+ if err != nil {
+ return err
+ }
+ _, err = stmt.Exec(item.Id, obj)
+ if err != nil {
+ return err
+ }
+ return nil
+}