th7/db/sqlite3.go

117 lines
2.3 KiB
Go
Raw Normal View History

2022-11-12 14:20:29 +00:00
package db
import (
2023-11-24 10:46:49 +00:00
"context"
2022-11-12 14:20:29 +00:00
"database/sql"
2022-11-12 16:22:55 +00:00
"errors"
2023-11-25 10:37:02 +00:00
"log"
2022-11-12 14:20:29 +00:00
"sync"
"th7/data/config"
"th7/data/core"
"th7/data/thermocouple"
2023-11-23 12:39:49 +00:00
"time"
2022-11-12 14:20:29 +00:00
_ "github.com/mattn/go-sqlite3"
)
type SQLite3Adapter struct {
mu sync.Mutex
db *sql.DB
cfg config.Config
2022-11-12 14:20:29 +00:00
}
2023-11-24 10:46:49 +00:00
const (
2023-11-24 15:37:55 +00:00
SQLITE3_MAX_INIT_DUR = 3000 * time.Millisecond
SQLITE3_MAX_SAVE_DUR = 3000 * time.Millisecond
2023-11-24 10:46:49 +00:00
)
func NewSQLite3Adapter(config config.Config) (*SQLite3Adapter, error) {
2022-11-12 14:20:29 +00:00
var adapter SQLite3Adapter
2022-11-12 16:22:55 +00:00
// if path is given ...
if _, ok := config.DB["path"]; !ok {
2022-11-12 16:22:55 +00:00
return &adapter, errors.New("sqlite3 requires a path config variable")
}
2023-11-23 20:46:54 +00:00
path := config.DB["path"].(string)
2022-11-12 16:22:55 +00:00
2022-11-12 14:20:29 +00:00
db, err := sql.Open("sqlite3", path)
if err != nil {
return &adapter, err
}
adapter.db = db
adapter.cfg = config
2022-11-12 14:20:29 +00:00
2023-11-24 10:46:49 +00:00
initContext, cancel := context.WithTimeout(context.Background(), SQLITE3_MAX_INIT_DUR)
defer cancel()
2022-11-12 14:20:29 +00:00
const create string = `
CREATE TABLE IF NOT EXISTS logs (
id INTEGER NOT NULL,
type TEXT NOT NULL,
gain REAL NOT NULL,
offset REAL NOT NULL,
2022-11-12 14:20:29 +00:00
value REAL NOT NULL,
timestamp TEXT NOT NULL
);`
2023-11-24 10:46:49 +00:00
if _, err := adapter.db.ExecContext(initContext, create); err != nil {
2022-11-12 14:20:29 +00:00
return &adapter, err
}
return &adapter, nil
}
func (ad *SQLite3Adapter) Close() {
ad.db.Close()
}
2023-11-23 12:39:49 +00:00
func (ad *SQLite3Adapter) Save(channels []core.Channel) error {
2022-11-12 14:20:29 +00:00
ad.mu.Lock()
defer ad.mu.Unlock()
insertLogSQL := `INSERT INTO logs (id, type, gain, offset, value, timestamp) VALUES (?, ?, ?, ?, ?, ?)`
2023-11-23 12:39:49 +00:00
statement, err := ad.db.Prepare(insertLogSQL)
if err != nil {
2023-11-25 10:37:02 +00:00
log.Println(err)
2023-11-23 12:39:49 +00:00
}
timestamp := time.Now().Format(time.DateTime)
2023-11-23 12:39:49 +00:00
2023-11-24 11:00:20 +00:00
saveContext, cancel := context.WithTimeout(context.Background(), SQLITE3_MAX_SAVE_DUR)
2023-11-24 10:46:49 +00:00
defer cancel()
2023-11-25 10:37:02 +00:00
logged := 0
2023-11-23 12:39:49 +00:00
for c := range channels {
2023-11-25 10:37:02 +00:00
if !ad.cfg.Channels[c].Log {
continue
}
id := channels[c].Id
value := channels[c].Value
gain := ad.cfg.Channels[c].Gain
offset := ad.cfg.Channels[c].Offset
thermo := thermocouple.ThermoStringLookup[ad.cfg.Channels[c].Thermo]
2023-11-24 10:46:49 +00:00
_, err = statement.ExecContext(saveContext, id, thermo, gain, offset, value, timestamp)
2023-11-23 12:39:49 +00:00
if err != nil {
2023-11-23 20:55:10 +00:00
return err
2023-11-23 12:39:49 +00:00
}
2023-11-25 10:37:02 +00:00
logged++
}
if logged == 0 {
log.Printf("[%s] SQLite3: nothing to do.\n", timestamp)
return nil
2023-11-23 12:39:49 +00:00
}
2023-11-25 10:37:02 +00:00
log.Printf("[%s] SQLite3: logged %d channels.\n", timestamp, logged)
2023-11-24 15:37:55 +00:00
return nil
2022-11-12 14:20:29 +00:00
}