From e5d6f4c02b757c83244ba5e04fead08623a27299 Mon Sep 17 00:00:00 2001 From: Alexander Neonxp Kiryukhin Date: Sat, 14 Mar 2026 00:44:19 +0300 Subject: =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/database/db.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 internal/database/db.go (limited to 'internal/database/db.go') 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 +} -- cgit v1.2.3