2025-01-16 22:53:04 +00:00
|
|
|
package core
|
2025-01-16 19:46:37 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2025-01-16 21:46:30 +00:00
|
|
|
"fmt"
|
2025-01-16 19:46:37 +00:00
|
|
|
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
|
|
)
|
|
|
|
|
2025-01-16 21:46:30 +00:00
|
|
|
type Item struct {
|
|
|
|
source string
|
|
|
|
id string
|
|
|
|
created int
|
|
|
|
active bool
|
|
|
|
title string
|
|
|
|
author string
|
|
|
|
body string
|
|
|
|
link string
|
|
|
|
time int
|
|
|
|
}
|
|
|
|
|
2025-01-16 19:46:37 +00:00
|
|
|
func InitDatabase(db *sql.DB) error {
|
|
|
|
db.Exec(`
|
|
|
|
create table migrations (name text) strict;
|
|
|
|
`)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func MigrateDatabase(db *sql.DB) error {
|
|
|
|
rows, err := db.Query(`
|
|
|
|
select name from migrations;
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
complete := map[string]bool{}
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
var name string
|
|
|
|
err = rows.Scan(&name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
complete[name] = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if !complete["0000_initial_schema"] {
|
|
|
|
_, err = db.Exec(`
|
|
|
|
create table sources(name text) strict;
|
|
|
|
create table items(
|
|
|
|
source text not null,
|
|
|
|
id text not null,
|
|
|
|
created int not null default (unixepoch()),
|
|
|
|
active int,
|
|
|
|
title text,
|
|
|
|
author text,
|
|
|
|
body text,
|
|
|
|
link text,
|
|
|
|
time int,
|
|
|
|
primary key (source, id),
|
|
|
|
foreign key (source) references sources (name) on delete cascade
|
|
|
|
) strict;
|
|
|
|
insert into migrations (name) values ('0000_initial_schema');
|
|
|
|
`)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2025-01-16 21:46:30 +00:00
|
|
|
|
|
|
|
func AddSource(db *sql.DB, name string) error {
|
|
|
|
_, err := db.Exec(`
|
|
|
|
insert into sources (name)
|
|
|
|
values (?)
|
|
|
|
`, name)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func DeleteSource(db *sql.DB, name string) error {
|
|
|
|
_, err := db.Exec(`
|
|
|
|
delete from sources
|
|
|
|
where name = ?
|
|
|
|
`, name)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func AddItem(
|
|
|
|
db *sql.DB,
|
|
|
|
source string,
|
|
|
|
id string,
|
|
|
|
title string,
|
|
|
|
author string,
|
|
|
|
body string,
|
|
|
|
link string,
|
|
|
|
time int,
|
|
|
|
) error {
|
|
|
|
_, err := db.Exec(`
|
|
|
|
insert into items (source, id, active, title, author, body, link, time)
|
|
|
|
values (?, ?, ?, ?, ?, ?, ?, ?)
|
|
|
|
`, source, id, true, title, author, body, link, time)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func DeactivateItem(db *sql.DB, source string, id string) error {
|
|
|
|
res, err := db.Exec(`
|
|
|
|
update items
|
|
|
|
set active = 0
|
|
|
|
where source = ? and id = ?
|
|
|
|
`, source, id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
num, err := res.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if num == 0 {
|
|
|
|
return fmt.Errorf("item %s/%s not found", source, id)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetActiveItems(db *sql.DB, source string) ([]Item, error) {
|
|
|
|
rows, err := db.Query(`
|
|
|
|
select
|
|
|
|
source,
|
|
|
|
id,
|
|
|
|
created,
|
|
|
|
active,
|
|
|
|
title,
|
|
|
|
author,
|
|
|
|
body,
|
|
|
|
link,
|
|
|
|
time
|
|
|
|
from items
|
|
|
|
where
|
|
|
|
source = ?
|
|
|
|
and active <> 0
|
|
|
|
`, source)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var items []Item
|
|
|
|
for rows.Next() {
|
|
|
|
var item Item
|
|
|
|
rows.Scan(&item.source, &item.id, &item.created, &item.active, &item.title, &item.author, &item.body, &item.link, &item.time)
|
|
|
|
items = append(items, item)
|
|
|
|
}
|
|
|
|
return items, nil
|
|
|
|
}
|