diff --git a/go.mod b/go.mod index 61035d9..8f1fd89 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/influxdata/influxdb-client-go/v2 v2.14.0 github.com/jmoiron/sqlx v1.4.0 + github.com/lib/pq v1.10.9 github.com/spf13/viper v1.19.0 modernc.org/sqlite v1.32.0 ) diff --git a/internal/db/choose_db.go b/internal/db/choose_db.go new file mode 100644 index 0000000..dbb2a95 --- /dev/null +++ b/internal/db/choose_db.go @@ -0,0 +1,54 @@ +package db + +import ( + "log/slog" + + "github.com/aceberg/WatchYourLAN/internal/models" +) + +// Data to connect to DB +type Data struct { + Use string + SQLitePath string + PGConnect string + PrimaryKey string +} + +var currentDB Data + +func dbExec(sqlStatement string) { + + if currentDB.Use == "postgres" { + dbExecPG(sqlStatement) + } else { + dbExecLite(sqlStatement) + } +} + +// Select - select all from table +func Select(table string) (dbHosts []models.Host) { + + if currentDB.Use == "postgres" { + dbHosts = selectPG(table) + } else { + dbHosts = selectLite(table) + } + + return dbHosts +} + +// SetCurrent - set paths and which DB to use +func SetCurrent(config models.Conf) { + + currentDB.Use = config.UseDB + currentDB.SQLitePath = config.DBPath + currentDB.PGConnect = config.PGConnect + + if currentDB.Use == "postgres" { + currentDB.PrimaryKey = "BIGSERIAL PRIMARY KEY" + } else { + currentDB.PrimaryKey = "INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE" + } + + slog.Info("Using DB", "type", currentDB.Use) +} diff --git a/internal/db/edit.go b/internal/db/edit.go index 12d62e8..34a556e 100644 --- a/internal/db/edit.go +++ b/internal/db/edit.go @@ -7,10 +7,10 @@ import ( ) // Create - create DB if not exists -func Create(path string) { +func Create() { sqlStatement := `CREATE TABLE IF NOT EXISTS "now" ( - "ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + "ID" ` + currentDB.PrimaryKey + `, "NAME" TEXT NOT NULL, "DNS" TEXT NOT NULL, "IFACE" TEXT, @@ -21,10 +21,10 @@ func Create(path string) { "KNOWN" INTEGER DEFAULT 0, "NOW" INTEGER DEFAULT 0 );` - dbExec(path, sqlStatement) + dbExec(sqlStatement) sqlStatement = `CREATE TABLE IF NOT EXISTS "history" ( - "ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + "ID" ` + currentDB.PrimaryKey + `, "NAME" TEXT NOT NULL, "DNS" TEXT NOT NULL, "IFACE" TEXT, @@ -35,43 +35,41 @@ func Create(path string) { "KNOWN" INTEGER DEFAULT 0, "NOW" INTEGER DEFAULT 0 );` - dbExec(path, sqlStatement) + dbExec(sqlStatement) } // Insert - insert host into table -func Insert(path, table string, oneHost models.Host) { +func Insert(table string, oneHost models.Host) { oneHost.Name = quoteStr(oneHost.Name) oneHost.Hw = quoteStr(oneHost.Hw) - sqlStatement := `INSERT INTO '%s' (NAME, DNS, IFACE, IP, MAC, HW, DATE, KNOWN, NOW) - VALUES ('%s','%s','%s','%s','%s','%s','%s','%d','%d');` + sqlStatement := `INSERT INTO %s ("NAME", "DNS", "IFACE", "IP", "MAC", "HW", "DATE", "KNOWN", "NOW") VALUES ('%s','%s','%s','%s','%s','%s','%s','%d','%d');` sqlStatement = fmt.Sprintf(sqlStatement, table, oneHost.Name, oneHost.DNS, oneHost.Iface, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now) - dbExec(path, sqlStatement) + dbExec(sqlStatement) } // Update - update host -func Update(path, table string, oneHost models.Host) { +func Update(table string, oneHost models.Host) { oneHost.Name = quoteStr(oneHost.Name) oneHost.Hw = quoteStr(oneHost.Hw) - sqlStatement := `UPDATE '%s' set - NAME = '%s', DNS = '%s', IFACE = '%s', IP = '%s', MAC = '%s', HW = '%s', DATE = '%s', - KNOWN = '%d', NOW = '%d' - WHERE ID = '%d';` + sqlStatement := `UPDATE %s set + "NAME" = '%s', "DNS" = '%s', "IFACE" = '%s', "IP" = '%s', "MAC" = '%s', "HW" = '%s', "DATE" = '%s', "KNOWN" = '%d', "NOW" = '%d' + WHERE "ID" = '%d';` sqlStatement = fmt.Sprintf(sqlStatement, table, oneHost.Name, oneHost.DNS, oneHost.Iface, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now, oneHost.ID) - dbExec(path, sqlStatement) + dbExec(sqlStatement) } // Delete - delete host from DB -func Delete(path, table string, id int) { - sqlStatement := `DELETE FROM '%s' WHERE ID='%d';` +func Delete(table string, id int) { + sqlStatement := `DELETE FROM %s WHERE "ID"='%d';` sqlStatement = fmt.Sprintf(sqlStatement, table, id) - dbExec(path, sqlStatement) + dbExec(sqlStatement) } // Clear - delete all hosts from table -func Clear(path, table string) { - sqlStatement := `DELETE FROM '%s';` +func Clear(table string) { + sqlStatement := `DELETE FROM %s;` sqlStatement = fmt.Sprintf(sqlStatement, table) - dbExec(path, sqlStatement) + dbExec(sqlStatement) } diff --git a/internal/db/postgres.go b/internal/db/postgres.go new file mode 100644 index 0000000..233a7ab --- /dev/null +++ b/internal/db/postgres.go @@ -0,0 +1,40 @@ +package db + +import ( + // "log/slog" + + "github.com/jmoiron/sqlx" + + // import postgres + _ "github.com/lib/pq" + + "github.com/aceberg/WatchYourLAN/internal/check" + "github.com/aceberg/WatchYourLAN/internal/models" +) + +func dbExecPG(sqlStatement string) { + + // slog.Debug("PG Exec " + sqlStatement) + + db, err := sqlx.Connect("postgres", currentDB.PGConnect) + check.IfError(err) + defer db.Close() + + _, err = db.Exec(sqlStatement) + check.IfError(err) +} + +func selectPG(table string) (dbHosts []models.Host) { + + sqlStatement := `SELECT * FROM ` + table + ` ORDER BY "DATE" DESC` + + // slog.Debug("PG Select " + sqlStatement) + + db, _ := sqlx.Connect("postgres", currentDB.PGConnect) + defer db.Close() + + err := db.Select(&dbHosts, sqlStatement) + check.IfError(err) + + return dbHosts +} diff --git a/internal/db/sqlite.go b/internal/db/sqlite.go index 1cbba43..e06d434 100644 --- a/internal/db/sqlite.go +++ b/internal/db/sqlite.go @@ -14,10 +14,10 @@ import ( var mu sync.Mutex -func dbExec(path, sqlStatement string) { +func dbExecLite(sqlStatement string) { mu.Lock() - db, err := sqlx.Connect("sqlite", path) + db, err := sqlx.Connect("sqlite", currentDB.SQLitePath) check.IfError(err) defer db.Close() @@ -27,13 +27,12 @@ func dbExec(path, sqlStatement string) { check.IfError(err) } -// Select - select all hosts -func Select(path, table string) (dbHosts []models.Host) { +func selectLite(table string) (dbHosts []models.Host) { sqlStatement := "SELECT * FROM " + table + " ORDER BY DATE DESC" mu.Lock() - db, _ := sqlx.Connect("sqlite", path) + db, _ := sqlx.Connect("sqlite", currentDB.SQLitePath) defer db.Close() err := db.Select(&dbHosts, sqlStatement) diff --git a/internal/web/api.go b/internal/web/api.go index 63dd8c1..8745b1f 100644 --- a/internal/web/api.go +++ b/internal/web/api.go @@ -13,7 +13,7 @@ import ( func apiAll(c *gin.Context) { - allHosts = db.Select(appConfig.DBPath, "now") + allHosts = db.Select("now") c.IndentedJSON(http.StatusOK, allHosts) } @@ -21,7 +21,7 @@ func apiAll(c *gin.Context) { func apiHistory(c *gin.Context) { var hosts []models.Host - histHosts := db.Select(appConfig.DBPath, "history") + histHosts := db.Select("history") mac := c.Param("mac") @@ -48,8 +48,8 @@ func apiHostDel(c *gin.Context) { idStr := c.Param("id") host := getHostByID(idStr, allHosts) // functions.go - db.Delete(appConfig.DBPath, "now", host.ID) - allHosts = db.Select(appConfig.DBPath, "now") + db.Delete("now", host.ID) + allHosts = db.Select("now") slog.Info("Deleting from DB", "host", host) @@ -80,8 +80,8 @@ func apiEdit(c *gin.Context) { } // log.Println("EDIT: ", host) - db.Update(appConfig.DBPath, "now", host) - allHosts = db.Select(appConfig.DBPath, "now") + db.Update("now", host) + allHosts = db.Select("now") } c.IndentedJSON(http.StatusOK, "OK") diff --git a/internal/web/routines-upd.go b/internal/web/routines-upd.go index 7fcdd56..7a1c7d5 100644 --- a/internal/web/routines-upd.go +++ b/internal/web/routines-upd.go @@ -13,9 +13,10 @@ func updateRoutines() { setLogLevel() - db.Create(appConfig.DBPath) + db.SetCurrent(appConfig) + db.Create() - allHosts = db.Select(appConfig.DBPath, "now") + allHosts = db.Select("now") quitScan = make(chan bool) go startScan(quitScan) // scan-routine.go diff --git a/internal/web/scan-routine.go b/internal/web/scan-routine.go index 57e4b2f..35b15ec 100644 --- a/internal/web/scan-routine.go +++ b/internal/web/scan-routine.go @@ -28,7 +28,7 @@ func startScan(quit chan bool) { foundHosts = arp.Scan(appConfig.Ifaces) compareHosts(foundHosts) - allHosts = db.Select(appConfig.DBPath, "now") + allHosts = db.Select("now") lastDate = time.Now() } @@ -61,10 +61,10 @@ func compareHosts(foundHosts []models.Host) { } else { aHost.Now = 0 } - db.Update(appConfig.DBPath, "now", aHost) + db.Update("now", aHost) aHost.Date = time.Now().Format("2006-01-02 15:04:05") - db.Insert(appConfig.DBPath, "history", aHost) + db.Insert("history", aHost) if appConfig.InfluxEnable { influx.Add(appConfig, aHost) } @@ -77,6 +77,6 @@ func compareHosts(foundHosts []models.Host) { notify.Shout(msg, appConfig.ShoutURL) // Notify through Shoutrrr fHost.Name, fHost.DNS = updateDNS(fHost) - db.Insert(appConfig.DBPath, "now", fHost) + db.Insert("now", fHost) } } diff --git a/internal/web/templates/host.html b/internal/web/templates/host.html index 879238f..f608521 100644 --- a/internal/web/templates/host.html +++ b/internal/web/templates/host.html @@ -20,7 +20,7 @@