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"
|
2022-11-12 14:20:29 +00:00
|
|
|
"fmt"
|
|
|
|
"sync"
|
2023-11-23 16:55:57 +00:00
|
|
|
|
|
|
|
"th7/data/config"
|
2022-11-13 17:21:03 +00:00
|
|
|
"th7/data/core"
|
2023-11-23 16:55:57 +00:00
|
|
|
"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 {
|
2023-11-23 16:55:57 +00:00
|
|
|
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
|
|
|
)
|
|
|
|
|
2023-11-23 16:55:57 +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 ...
|
2023-11-23 16:55:57 +00:00
|
|
|
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
|
2023-11-23 16:55:57 +00:00
|
|
|
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,
|
2023-11-23 16:55:57 +00:00
|
|
|
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()
|
|
|
|
|
2023-11-23 16:55:57 +00:00
|
|
|
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-23 20:46:54 +00:00
|
|
|
fmt.Println(err)
|
2023-11-23 12:39:49 +00:00
|
|
|
}
|
|
|
|
|
2023-11-23 16:55:57 +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-23 12:39:49 +00:00
|
|
|
for c := range channels {
|
2023-11-23 16:55:57 +00:00
|
|
|
|
|
|
|
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-24 15:37:55 +00:00
|
|
|
fmt.Printf("[%s] SQLite3: logged %d channels.\n", timestamp, len(channels))
|
|
|
|
|
2022-11-16 00:07:01 +00:00
|
|
|
return nil
|
2022-11-12 14:20:29 +00:00
|
|
|
}
|