Show logs when editing a code
All checks were successful
/ build-container (push) Successful in 8m14s

This commit is contained in:
Finn 2024-11-24 16:08:06 -08:00
parent 060b5705c8
commit a26b9cc63e
7 changed files with 113 additions and 5 deletions

View file

@ -49,10 +49,11 @@ func Migrate() error {
} }
func NullString(s string) sql.NullString { func NullString(s string) sql.NullString {
return sql.NullString{ return sql.NullString{Valid: s != "", String: s}
Valid: s != "", }
String: s,
} func NullInt64(i int64) sql.NullInt64 {
return sql.NullInt64{Valid: true, Int64: i}
} }
type loggingDBTX struct { type loggingDBTX struct {

View file

@ -25,6 +25,44 @@ func (q *Queries) AddLogEntry(ctx context.Context, arg AddLogEntryParams) error
return err return err
} }
const getLastLogForSlot = `-- name: GetLastLogForSlot :many
SELECT lock, timestamp, state, code, issued_code FROM lock_log WHERE lock = ? AND code = ? ORDER BY timestamp DESC LIMIT 1
`
type GetLastLogForSlotParams struct {
Lock int64
Code sql.NullInt64
}
func (q *Queries) GetLastLogForSlot(ctx context.Context, arg GetLastLogForSlotParams) ([]LockLog, error) {
rows, err := q.db.QueryContext(ctx, getLastLogForSlot, arg.Lock, arg.Code)
if err != nil {
return nil, err
}
defer rows.Close()
var items []LockLog
for rows.Next() {
var i LockLog
if err := rows.Scan(
&i.Lock,
&i.Timestamp,
&i.State,
&i.Code,
&i.IssuedCode,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getLogForLock = `-- name: GetLogForLock :many const getLogForLock = `-- name: GetLogForLock :many
SELECT lock, timestamp, state, code, issued_code FROM lock_log WHERE lock = ? ORDER BY timestamp DESC SELECT lock, timestamp, state, code, issued_code FROM lock_log WHERE lock = ? ORDER BY timestamp DESC
` `
@ -57,3 +95,41 @@ func (q *Queries) GetLogForLock(ctx context.Context, lock int64) ([]LockLog, err
} }
return items, nil return items, nil
} }
const getLogForSlot = `-- name: GetLogForSlot :many
SELECT lock, timestamp, state, code, issued_code FROM lock_log WHERE lock = ? AND code = ? ORDER BY timestamp DESC
`
type GetLogForSlotParams struct {
Lock int64
Code sql.NullInt64
}
func (q *Queries) GetLogForSlot(ctx context.Context, arg GetLogForSlotParams) ([]LockLog, error) {
rows, err := q.db.QueryContext(ctx, getLogForSlot, arg.Lock, arg.Code)
if err != nil {
return nil, err
}
defer rows.Close()
var items []LockLog
for rows.Next() {
var i LockLog
if err := rows.Scan(
&i.Lock,
&i.Timestamp,
&i.State,
&i.Code,
&i.IssuedCode,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

View file

@ -3,3 +3,9 @@ INSERT INTO lock_log (lock, state, code) VALUES (?, ?, ?);
-- name: GetLogForLock :many -- name: GetLogForLock :many
SELECT * FROM lock_log WHERE lock = ? ORDER BY timestamp DESC; SELECT * FROM lock_log WHERE lock = ? ORDER BY timestamp DESC;
-- name: GetLogForSlot :many
SELECT * FROM lock_log WHERE lock = ? AND code = ? ORDER BY timestamp DESC;
-- name: GetLastLogForSlot :many
SELECT * FROM lock_log WHERE lock = ? AND code = ? ORDER BY timestamp DESC LIMIT 1;

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"html/template" "html/template"
"io/fs" "io/fs"
"time"
"git.janky.solutions/finn/lockserver/config" "git.janky.solutions/finn/lockserver/config"
) )
@ -19,7 +20,8 @@ var (
Templates *template.Template Templates *template.Template
funcs = template.FuncMap{ funcs = template.FuncMap{
"version": func() string { return fmt.Sprintf("better-zwave-locks %s", config.Version) }, "version": func() string { return fmt.Sprintf("better-zwave-locks %s", config.Version) },
"time_since": func(t time.Time) string { return time.Since(t).Round(time.Second).String() },
} }
) )

View file

@ -8,4 +8,11 @@
<br /> <br />
<input type="submit" value="save" /> <input type="submit" value="save" />
</form> </form>
<br /><br />
<ul>
{{ range $_, $entry := .Data.log }}
<li>{{ $entry.State }} (<i>{{ $entry.Timestamp | time_since }} ago</i>)</li>
{{ end }}
</ul>
{{ template "footer.html" }} {{ template "footer.html" }}

View file

@ -20,4 +20,7 @@
</tr> </tr>
{{ end }} {{ end }}
</table> </table>
<br /><br />
{{ template "footer.html" }} {{ template "footer.html" }}

View file

@ -1,6 +1,8 @@
package httpserver package httpserver
import ( import (
"database/sql"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
@ -8,6 +10,7 @@ import (
"git.janky.solutions/finn/lockserver/db" "git.janky.solutions/finn/lockserver/db"
"git.janky.solutions/finn/lockserver/zwavejs" "git.janky.solutions/finn/lockserver/zwavejs"
echo "github.com/labstack/echo/v4" echo "github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
) )
func lockHandler(c echo.Context) error { func lockHandler(c echo.Context) error {
@ -109,9 +112,19 @@ func lockCodeEditHandler(c echo.Context) error {
} }
if c.Request().Method == http.MethodGet { if c.Request().Method == http.MethodGet {
logrus.WithField("lock", lockID).WithField("code", code.ID).Debug("querying logs")
log, err := queries.GetLogForSlot(ctx, db.GetLogForSlotParams{
Lock: lockID,
Code: db.NullInt64(code.ID),
})
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return err
}
return c.Render(http.StatusFound, "lock-code-edit.html", map[string]interface{}{ return c.Render(http.StatusFound, "lock-code-edit.html", map[string]interface{}{
"lock": lock, "lock": lock,
"code": code, "code": code,
"log": log,
}) })
} }