First commit
This commit is contained in:
123
db.js
Normal file
123
db.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* db.js – SQLite-Modul für Wetterdaten
|
||||
*
|
||||
* Exports:
|
||||
* openDb(path) – DB öffnen / anlegen
|
||||
* getLatestTs(db) – letzten archivierten Zeitstempel lesen
|
||||
* insertRecord(db, record, source) – einzelnen Datensatz einfügen
|
||||
* insertRecords(db, records, source) – Batch-Insert (Transaktion)
|
||||
*/
|
||||
|
||||
import Database from "better-sqlite3";
|
||||
|
||||
// ── Schema ─────────────────────────────────────────────────────────────────
|
||||
|
||||
const SCHEMA = `
|
||||
CREATE TABLE IF NOT EXISTS readings (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ts INTEGER NOT NULL, -- Unix-Zeit in Sekunden (UTC)
|
||||
source TEXT NOT NULL, -- 'archive' | 'loop'
|
||||
temp_out REAL, -- °C
|
||||
temp_out_high REAL, -- °C (nur Archiv)
|
||||
temp_out_low REAL, -- °C (nur Archiv)
|
||||
temp_in REAL, -- °C
|
||||
hum_out INTEGER, -- %
|
||||
hum_in INTEGER, -- %
|
||||
wind_avg REAL, -- km/h
|
||||
wind_high REAL, -- km/h (nur Archiv)
|
||||
wind_dir TEXT, -- Himmelsrichtung
|
||||
wind_high_dir TEXT, -- Himmelsrichtung (nur Archiv)
|
||||
pressure REAL, -- hPa
|
||||
rain REAL, -- mm (Archiv: Intervall; Loop: Tagessumme)
|
||||
rain_rate REAL, -- mm/h
|
||||
solar_rad INTEGER, -- W/m²
|
||||
UNIQUE(ts, source)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_readings_ts ON readings(ts);
|
||||
`;
|
||||
|
||||
// ── Öffnen ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Öffnet (oder erstellt) die SQLite-Datenbank und initialisiert das Schema.
|
||||
* @param {string} dbPath – Pfad zur .db-Datei
|
||||
* @returns {Database} better-sqlite3 Instanz
|
||||
*/
|
||||
export function openDb(dbPath) {
|
||||
const db = new Database(dbPath);
|
||||
db.pragma("journal_mode = WAL");
|
||||
db.exec(SCHEMA);
|
||||
return db;
|
||||
}
|
||||
|
||||
// ── Lesen ──────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Gibt den Unix-Zeitstempel (Sekunden) des neuesten Archiv-Eintrags zurück,
|
||||
* oder null wenn die Tabelle leer ist.
|
||||
*/
|
||||
export function getLatestTs(db) {
|
||||
const row = db.prepare(
|
||||
"SELECT MAX(ts) AS ts FROM readings WHERE source = 'archive'"
|
||||
).get();
|
||||
return row?.ts ?? null;
|
||||
}
|
||||
|
||||
// ── Schreiben ──────────────────────────────────────────────────────────────
|
||||
|
||||
const INSERT_SQL = `
|
||||
INSERT OR IGNORE INTO readings
|
||||
(ts, source, temp_out, temp_out_high, temp_out_low, temp_in,
|
||||
hum_out, hum_in, wind_avg, wind_high, wind_dir, wind_high_dir,
|
||||
pressure, rain, rain_rate, solar_rad)
|
||||
VALUES
|
||||
(@ts, @source, @temp_out, @temp_out_high, @temp_out_low, @temp_in,
|
||||
@hum_out, @hum_in, @wind_avg, @wind_high, @wind_dir, @wind_high_dir,
|
||||
@pressure, @rain, @rain_rate, @solar_rad)
|
||||
`;
|
||||
|
||||
function toRow(record, source) {
|
||||
return {
|
||||
ts: Math.floor(record.time.getTime() / 1000),
|
||||
source,
|
||||
temp_out: record.tempOut ?? null,
|
||||
temp_out_high: record.tempOutHigh ?? null,
|
||||
temp_out_low: record.tempOutLow ?? null,
|
||||
temp_in: record.tempIn ?? null,
|
||||
hum_out: record.humOut ?? null,
|
||||
hum_in: record.humIn ?? null,
|
||||
wind_avg: record.windAvg ?? null,
|
||||
wind_high: record.windHigh ?? null,
|
||||
wind_dir: record.windDir ?? null,
|
||||
wind_high_dir: record.windHighDir ?? null,
|
||||
pressure: record.pressure ?? null,
|
||||
rain: record.rain ?? null,
|
||||
rain_rate: record.rainRate ?? null,
|
||||
solar_rad: record.solarRad ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt einen einzelnen Datensatz in die DB ein.
|
||||
* Ignoriert Duplikate (gleiche ts + source) dank UNIQUE-Constraint.
|
||||
*/
|
||||
export function insertRecord(db, record, source) {
|
||||
db.prepare(INSERT_SQL).run(toRow(record, source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt ein Array von Datensätzen in einer einzigen Transaktion ein.
|
||||
* Gibt die Anzahl tatsächlich eingefügter Zeilen zurück.
|
||||
*/
|
||||
export function insertRecords(db, records, source) {
|
||||
const stmt = db.prepare(INSERT_SQL);
|
||||
const run = db.transaction(recs => {
|
||||
let count = 0;
|
||||
for (const r of recs) {
|
||||
const info = stmt.run(toRow(r, source));
|
||||
count += info.changes;
|
||||
}
|
||||
return count;
|
||||
});
|
||||
return run(records);
|
||||
}
|
||||
Reference in New Issue
Block a user