2023-05-10 03:21:29 +04:00
|
|
|
package sqlite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
_ "embed"
|
|
|
|
"fmt"
|
2023-05-14 03:35:52 +04:00
|
|
|
"time"
|
2023-05-10 03:21:29 +04:00
|
|
|
|
2023-05-14 03:35:52 +04:00
|
|
|
"git.arav.su/Arav/dwelling-home/pkg/mindflow"
|
2023-05-10 03:21:29 +04:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
//go:embed queries/schema.sql
|
|
|
|
querySchema string
|
|
|
|
|
|
|
|
//go:embed queries/categoryById.sql
|
|
|
|
queryCategoryById string
|
2023-05-22 05:21:53 +04:00
|
|
|
//go:embed queries/categoryGetAll.sql
|
|
|
|
queryCategoryGetAll string
|
2023-05-10 03:21:29 +04:00
|
|
|
//go:embed queries/categoryNew.sql
|
|
|
|
queryCategoryNew string
|
2023-05-22 21:39:38 +04:00
|
|
|
//go:embed queries/categoryDelete.sql
|
|
|
|
queryCategoryDelete string
|
2023-05-10 03:21:29 +04:00
|
|
|
//go:embed queries/postGetAll.sql
|
|
|
|
queryPostGetAll string
|
|
|
|
//go:embed queries/postNew.sql
|
|
|
|
queryPostNew string
|
|
|
|
//go:embed queries/postEdit.sql
|
|
|
|
queryPostEdit string
|
2023-05-14 03:35:52 +04:00
|
|
|
//go:embed queries/postDelete.sql
|
|
|
|
queryPostDelete string
|
2023-05-10 03:21:29 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2023-05-22 05:21:53 +04:00
|
|
|
stmtCategoryById *sql.Stmt
|
|
|
|
stmtCategoryGetAll *sql.Stmt
|
|
|
|
stmtCategoryNew *sql.Stmt
|
2023-05-22 21:39:38 +04:00
|
|
|
stmtCategoryDelete *sql.Stmt
|
2023-05-22 05:21:53 +04:00
|
|
|
stmtPostGetAll *sql.Stmt
|
|
|
|
stmtPostNew *sql.Stmt
|
|
|
|
stmtPostEdit *sql.Stmt
|
|
|
|
stmtPostDelete *sql.Stmt
|
2023-05-10 03:21:29 +04:00
|
|
|
)
|
|
|
|
|
|
|
|
func initDBStatements(db *sql.DB) error {
|
|
|
|
db.Exec("PRAGMA foreign_keys = ON;")
|
|
|
|
|
|
|
|
_, err := db.Exec(querySchema)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to init schema")
|
|
|
|
}
|
|
|
|
|
|
|
|
stmtCategoryById, err = db.Prepare(queryCategoryById)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryCategoryById")
|
|
|
|
}
|
|
|
|
|
2023-05-22 05:21:53 +04:00
|
|
|
stmtCategoryGetAll, err = db.Prepare(queryCategoryGetAll)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryCategoryGetAll")
|
|
|
|
}
|
|
|
|
|
2023-05-10 03:21:29 +04:00
|
|
|
stmtCategoryNew, err = db.Prepare(queryCategoryNew)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryCategoryNew")
|
|
|
|
}
|
|
|
|
|
2023-05-22 21:39:38 +04:00
|
|
|
stmtCategoryDelete, err = db.Prepare(queryCategoryDelete)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryCategoryDelete")
|
|
|
|
}
|
|
|
|
|
2023-05-10 03:21:29 +04:00
|
|
|
stmtPostGetAll, err = db.Prepare(queryPostGetAll)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryPostGetAll")
|
|
|
|
}
|
|
|
|
|
|
|
|
stmtPostNew, err = db.Prepare(queryPostNew)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryPostNew")
|
|
|
|
}
|
|
|
|
|
|
|
|
stmtPostEdit, err = db.Prepare(queryPostEdit)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryPostEdit")
|
|
|
|
}
|
|
|
|
|
2023-05-14 03:35:52 +04:00
|
|
|
stmtPostDelete, err = db.Prepare(queryPostDelete)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to prepare queryPostDelete")
|
|
|
|
}
|
|
|
|
|
2023-05-10 03:21:29 +04:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type SQLiteMindflow struct {
|
|
|
|
db *sql.DB
|
|
|
|
}
|
|
|
|
|
2023-05-14 20:17:30 +04:00
|
|
|
func New(path string) (mindflow.Mindflow, error) {
|
2023-05-10 03:21:29 +04:00
|
|
|
db, err := sql.Open("sqlite3", dsn(path))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := initDBStatements(db); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &SQLiteMindflow{db: db}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func dsn(filePath string) string {
|
|
|
|
return fmt.Sprintf("file:%s?_journal=WAL&_mutex=full", filePath)
|
|
|
|
}
|
2023-05-14 03:35:52 +04:00
|
|
|
|
|
|
|
func (s *SQLiteMindflow) New(post *mindflow.Post) error {
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
r, err := tx.Stmt(stmtPostNew).Exec(post.Category.ID, post.Date.UTC().Unix(), post.Title, post.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
post.ID, err = r.LastInsertId()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-05-14 03:38:17 +04:00
|
|
|
func (s *SQLiteMindflow) Edit(post *mindflow.Post) error {
|
2023-05-14 03:35:52 +04:00
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
_, err = tx.Stmt(stmtPostEdit).Exec(post.Category.ID, post.Title, post.Body, post.ID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SQLiteMindflow) Delete(id int64) error {
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
if _, err = tx.Stmt(stmtPostDelete).Exec(id); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-05-22 05:21:00 +04:00
|
|
|
func (s *SQLiteMindflow) Posts() (posts []mindflow.Post, err error) {
|
2023-05-14 03:35:52 +04:00
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-05-20 06:26:30 +04:00
|
|
|
defer tx.Rollback()
|
2023-05-14 03:35:52 +04:00
|
|
|
|
|
|
|
rows, err := tx.Stmt(stmtPostGetAll).Query()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var post mindflow.Post
|
|
|
|
var date_unix int64
|
|
|
|
|
|
|
|
if err = rows.Scan(&post.ID, &post.Category.ID, &post.Category.Name, &date_unix, &post.Title, &post.Body); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
post.Date = time.Unix(date_unix, 0)
|
|
|
|
|
|
|
|
posts = append(posts, post)
|
|
|
|
}
|
|
|
|
|
2023-05-20 06:26:30 +04:00
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return posts, nil
|
2023-05-14 03:35:52 +04:00
|
|
|
}
|
2023-05-14 03:52:07 +04:00
|
|
|
|
2023-05-22 05:21:53 +04:00
|
|
|
func (s *SQLiteMindflow) Categories() (categories []mindflow.Category, err error) {
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
rows, err := tx.Stmt(stmtCategoryGetAll).Query()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var category mindflow.Category
|
|
|
|
|
|
|
|
if err = rows.Scan(&category.ID, &category.Name); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
categories = append(categories, category)
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return categories, nil
|
|
|
|
}
|
|
|
|
|
2023-05-14 03:52:07 +04:00
|
|
|
func (s *SQLiteMindflow) NewCategory(name string) (int64, error) {
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
2023-05-22 04:10:04 +04:00
|
|
|
r, err := tx.Stmt(stmtCategoryNew).Exec(name)
|
2023-05-14 03:52:07 +04:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
id, err := r.LastInsertId()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return id, nil
|
|
|
|
}
|
|
|
|
|
2023-05-14 04:11:14 +04:00
|
|
|
func (s *SQLiteMindflow) GetCategoryByID(id int64) (name string, err error) {
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
r := tx.Stmt(stmtCategoryById).QueryRow(id)
|
|
|
|
if r.Err() != nil {
|
|
|
|
return "", r.Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := r.Scan(name); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return
|
2023-05-14 03:52:07 +04:00
|
|
|
}
|
2023-05-14 20:17:30 +04:00
|
|
|
|
2023-05-22 21:39:38 +04:00
|
|
|
func (s *SQLiteMindflow) DeleteCategory(id int64) (err error) {
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer tx.Rollback()
|
|
|
|
|
|
|
|
if _, err = tx.Stmt(stmtCategoryDelete).Exec(id); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-05-14 20:17:30 +04:00
|
|
|
func (s *SQLiteMindflow) Close() error {
|
|
|
|
stmtCategoryById.Close()
|
2023-05-22 21:39:55 +04:00
|
|
|
stmtCategoryGetAll.Close()
|
2023-05-14 20:17:30 +04:00
|
|
|
stmtCategoryNew.Close()
|
2023-05-22 21:39:38 +04:00
|
|
|
stmtCategoryDelete.Close()
|
2023-05-14 20:17:30 +04:00
|
|
|
stmtPostDelete.Close()
|
|
|
|
stmtPostEdit.Close()
|
|
|
|
stmtPostGetAll.Close()
|
|
|
|
stmtPostNew.Close()
|
|
|
|
|
|
|
|
return s.db.Close()
|
|
|
|
}
|