mirror of
https://github.com/skidoodle/iphistory.git
synced 2026-04-28 15:57:36 +02:00
v2
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
type Record struct {
|
||||
ID int
|
||||
Timestamp time.Time
|
||||
IP string
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewStore(path string) (*Store, error) {
|
||||
dsn := fmt.Sprintf("%s?_pragma=journal_mode(WAL)&_pragma=synchronous=NORMAL&_pragma=mmap_size=268435456", path)
|
||||
db, err := sql.Open("sqlite", dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
schema := `
|
||||
CREATE TABLE IF NOT EXISTS ip_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ts DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
ip TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_ts ON ip_history(ts DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_ip ON ip_history(ip COLLATE NOCASE);`
|
||||
|
||||
if _, err := db.Exec(schema); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Store{db: db}, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetLatest() (string, error) {
|
||||
var ip string
|
||||
err := s.db.QueryRow("SELECT ip FROM ip_history ORDER BY ts DESC LIMIT 1").Scan(&ip)
|
||||
if err == sql.ErrNoRows {
|
||||
return "", nil
|
||||
}
|
||||
return ip, err
|
||||
}
|
||||
|
||||
func (s *Store) Insert(ip string) error {
|
||||
_, err := s.db.Exec("INSERT INTO ip_history (ip, ts) VALUES (?, ?)", ip, time.Now().UTC())
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) FetchPage(query string, page, pageSize int) ([]Record, bool, error) {
|
||||
offset := (page - 1) * pageSize
|
||||
limit := pageSize + 1
|
||||
|
||||
q := query + "%"
|
||||
if query == "" {
|
||||
q = "%"
|
||||
}
|
||||
|
||||
rows, err := s.db.Query(
|
||||
"SELECT id, ts, ip FROM ip_history WHERE ip LIKE ? ORDER BY ts DESC LIMIT ? OFFSET ?",
|
||||
q, limit, offset,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var records []Record
|
||||
for rows.Next() {
|
||||
var r Record
|
||||
if err := rows.Scan(&r.ID, &r.Timestamp, &r.IP); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
records = append(records, r)
|
||||
}
|
||||
|
||||
hasMore := len(records) > pageSize
|
||||
if hasMore {
|
||||
records = records[:pageSize]
|
||||
}
|
||||
return records, hasMore, nil
|
||||
}
|
||||
Reference in New Issue
Block a user