aboutsummaryrefslogtreecommitdiff
path: root/internal/database
diff options
context:
space:
mode:
author2026-03-14 00:44:19 +0300
committer2026-03-14 00:44:19 +0300
commite5d6f4c02b757c83244ba5e04fead08623a27299 (patch)
tree5b5babb9887cafa3dbc165928dc2b0fd65265bda /internal/database
downloadpose-master.tar.gz
pose-master.tar.bz2
pose-master.tar.xz
pose-master.zip
начальный коммитHEADmaster
Diffstat (limited to 'internal/database')
-rw-r--r--internal/database/db.go54
1 files changed, 54 insertions, 0 deletions
diff --git a/internal/database/db.go b/internal/database/db.go
new file mode 100644
index 0000000..2fbfe74
--- /dev/null
+++ b/internal/database/db.go
@@ -0,0 +1,54 @@
+// Package database простейшая БД которая позволяет только два действия:
+//
+// 1. сохранить некую строку - `Append(string) error`
+// 2. ответить на вопрос сохранялась ли уже когда либо эта строка -
+// `Exists(string) bool`
+//
+// Нужна для дедупликации публикуемых записей
+package database
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+)
+
+type DB struct {
+ fp *os.File
+ cache map[string]struct{}
+}
+
+func New(path string) (*DB, error) {
+ cache, _ := os.ReadFile(path) // Ignore if no DB file
+
+ fp, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
+ if err != nil {
+ return nil, fmt.Errorf("failed open db file for write: %w", err)
+ }
+ db := &DB{
+ fp: fp,
+ cache: map[string]struct{}{},
+ }
+ for part := range bytes.SplitSeq(cache, []byte("\n")) {
+ db.cache[string(part)] = struct{}{}
+ }
+
+ return db, nil
+}
+
+func (d *DB) Close() error {
+ return d.fp.Close()
+}
+
+func (d *DB) Exists(s string) bool {
+ _, ok := d.cache[s]
+ return ok
+}
+
+func (d *DB) Append(s string) error {
+ if d.Exists(s) {
+ return nil
+ }
+ _, err := fmt.Fprintln(d.fp, s)
+ return err
+}