Gisle Aune
2 years ago
27 changed files with 1336 additions and 35 deletions
-
6bus.go
-
24cmd/lucifer4-color/main.go
-
8commands/assign.go
-
8commands/device.go
-
33device/pointer.go
-
2effects/serializable.go
-
21events/alias.go
-
34events/assignment.go
-
21events/device.go
-
2events/log.go
-
7events/program.go
-
9go.mod
-
4go.sum
-
47services/effectenforcer.go
-
21services/hue/bridge.go
-
16services/mysqldb/migrations/20221229182826_device_hwstate.sql
-
15services/mysqldb/migrations/20221229213541_device_assignment.sql
-
14services/mysqldb/migrations/20221230104518_device_auth.sql
-
15services/mysqldb/migrations/20221231155702_device_alias.sql
-
238services/mysqldb/mysqlgen/db.go
-
301services/mysqldb/mysqlgen/device.sql.go
-
36services/mysqldb/mysqlgen/models.go
-
74services/mysqldb/queries/device.sql
-
321services/mysqldb/service.go
-
36services/mysqldb/sqltypes/nullrawmessage.go
-
30services/resolver.go
-
28sqlc.yaml
@ -0,0 +1,24 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"fmt" |
|||
"git.aiterp.net/lucifer3/server/internal/color" |
|||
"os" |
|||
) |
|||
|
|||
func main() { |
|||
col := color.MustParse(os.Args[len(os.Args)-1]) |
|||
|
|||
if col, ok := col.ToXY(); ok { |
|||
fmt.Println(col.String()) |
|||
} |
|||
if col, ok := col.ToHS(); ok { |
|||
fmt.Println(col.String()) |
|||
} |
|||
if col, ok := col.ToHSK(); ok { |
|||
fmt.Println(col.String()) |
|||
} |
|||
if col, ok := col.ToRGB(); ok { |
|||
fmt.Println(col.String()) |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
package events |
|||
|
|||
import "fmt" |
|||
|
|||
type AliasAdded struct { |
|||
ID string |
|||
Alias string |
|||
} |
|||
|
|||
func (e AliasAdded) EventDescription() string { |
|||
return fmt.Sprintf("AliasAdded(id=%s, alias=%s)", e.ID, e.Alias) |
|||
} |
|||
|
|||
type AliasRemoved struct { |
|||
ID string |
|||
Alias string |
|||
} |
|||
|
|||
func (e AliasRemoved) EventDescription() string { |
|||
return fmt.Sprintf("AliasRemoved(id=%s, alias=%s)", e.ID, e.Alias) |
|||
} |
@ -0,0 +1,34 @@ |
|||
package events |
|||
|
|||
import ( |
|||
"fmt" |
|||
lucifer3 "git.aiterp.net/lucifer3/server" |
|||
"github.com/google/uuid" |
|||
) |
|||
|
|||
type AssignmentCreated struct { |
|||
ID uuid.UUID |
|||
Match string |
|||
Effect lucifer3.Effect |
|||
} |
|||
|
|||
func (e AssignmentCreated) EventDescription() string { |
|||
return fmt.Sprintf("AssignmentCreated(id=%s, match=%s, effect=%s)", e.ID, e.Match, e.Effect.EffectDescription()) |
|||
} |
|||
|
|||
type AssignmentRemoved struct { |
|||
ID uuid.UUID |
|||
} |
|||
|
|||
func (e AssignmentRemoved) EventDescription() string { |
|||
return fmt.Sprintf("AssignmentRemoved(id=%s)", e.ID) |
|||
} |
|||
|
|||
type DeviceAssigned struct { |
|||
DeviceID string `json:"deviceId"` |
|||
AssignmentID *uuid.UUID `json:"assignmentId"` |
|||
} |
|||
|
|||
func (e DeviceAssigned) EventDescription() string { |
|||
return fmt.Sprintf("DeviceAssigned(device=%s, %s)", e.DeviceID, e.AssignmentID) |
|||
} |
@ -0,0 +1,7 @@ |
|||
package events |
|||
|
|||
type Started struct{} |
|||
|
|||
func (Started) EventDescription() string { |
|||
return "Started()" |
|||
} |
@ -1,5 +1,9 @@ |
|||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= |
|||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= |
|||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= |
|||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= |
|||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= |
|||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
|||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= |
|||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= |
|||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= |
|||
|
@ -0,0 +1,16 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE device_info |
|||
( |
|||
id VARCHAR(255) NOT NULL, |
|||
kind VARCHAR(255) NOT NULL, |
|||
data JSON NOT NULL, |
|||
|
|||
PRIMARY KEY (id, kind) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE device_info; |
|||
-- +goose StatementEnd |
@ -0,0 +1,15 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE device_assignment |
|||
( |
|||
id CHAR(36) NOT NULL PRIMARY KEY, |
|||
created_date TIMESTAMP NOT NULL, |
|||
`match` TEXT NOT NULL, |
|||
effect JSON NOT NULL |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE device_assignment; |
|||
-- +goose StatementEnd |
@ -0,0 +1,14 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE device_auth |
|||
( |
|||
id VARCHAR(255) NOT NULL PRIMARY KEY, |
|||
api_key TEXT NOT NULL, |
|||
extras JSON NOT NULL |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE device_auth; |
|||
-- +goose StatementEnd |
@ -0,0 +1,15 @@ |
|||
-- +goose Up |
|||
-- +goose StatementBegin |
|||
CREATE TABLE device_alias |
|||
( |
|||
id VARCHAR(255) NOT NULL, |
|||
alias VARCHAR(1023) NOT NULL, |
|||
|
|||
PRIMARY KEY (id, alias) |
|||
); |
|||
-- +goose StatementEnd |
|||
|
|||
-- +goose Down |
|||
-- +goose StatementBegin |
|||
DROP TABLE device_alias; |
|||
-- +goose StatementEnd |
@ -0,0 +1,238 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
|
|||
package mysqlgen |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"fmt" |
|||
) |
|||
|
|||
type DBTX interface { |
|||
ExecContext(context.Context, string, ...interface{}) (sql.Result, error) |
|||
PrepareContext(context.Context, string) (*sql.Stmt, error) |
|||
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) |
|||
QueryRowContext(context.Context, string, ...interface{}) *sql.Row |
|||
} |
|||
|
|||
func New(db DBTX) *Queries { |
|||
return &Queries{db: db} |
|||
} |
|||
|
|||
func Prepare(ctx context.Context, db DBTX) (*Queries, error) { |
|||
q := Queries{db: db} |
|||
var err error |
|||
if q.deleteDeviceAliasStmt, err = db.PrepareContext(ctx, deleteDeviceAlias); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceAlias: %w", err) |
|||
} |
|||
if q.deleteDeviceAliasByIDStmt, err = db.PrepareContext(ctx, deleteDeviceAliasByID); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceAliasByID: %w", err) |
|||
} |
|||
if q.deleteDeviceAliasByIDLikeStmt, err = db.PrepareContext(ctx, deleteDeviceAliasByIDLike); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceAliasByIDLike: %w", err) |
|||
} |
|||
if q.deleteDeviceAssignmentStmt, err = db.PrepareContext(ctx, deleteDeviceAssignment); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceAssignment: %w", err) |
|||
} |
|||
if q.deleteDeviceAuthStmt, err = db.PrepareContext(ctx, deleteDeviceAuth); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceAuth: %w", err) |
|||
} |
|||
if q.deleteDeviceInfoStmt, err = db.PrepareContext(ctx, deleteDeviceInfo); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceInfo: %w", err) |
|||
} |
|||
if q.deleteDeviceInfoByIDStmt, err = db.PrepareContext(ctx, deleteDeviceInfoByID); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceInfoByID: %w", err) |
|||
} |
|||
if q.deleteDeviceInfoLikeStmt, err = db.PrepareContext(ctx, deleteDeviceInfoLike); err != nil { |
|||
return nil, fmt.Errorf("error preparing query DeleteDeviceInfoLike: %w", err) |
|||
} |
|||
if q.insertDeviceAliasStmt, err = db.PrepareContext(ctx, insertDeviceAlias); err != nil { |
|||
return nil, fmt.Errorf("error preparing query InsertDeviceAlias: %w", err) |
|||
} |
|||
if q.listDeviceAliasesStmt, err = db.PrepareContext(ctx, listDeviceAliases); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListDeviceAliases: %w", err) |
|||
} |
|||
if q.listDeviceAssignmentsStmt, err = db.PrepareContext(ctx, listDeviceAssignments); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListDeviceAssignments: %w", err) |
|||
} |
|||
if q.listDeviceAuthStmt, err = db.PrepareContext(ctx, listDeviceAuth); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListDeviceAuth: %w", err) |
|||
} |
|||
if q.listDeviceInfosStmt, err = db.PrepareContext(ctx, listDeviceInfos); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ListDeviceInfos: %w", err) |
|||
} |
|||
if q.replaceDeviceAssignmentStmt, err = db.PrepareContext(ctx, replaceDeviceAssignment); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ReplaceDeviceAssignment: %w", err) |
|||
} |
|||
if q.replaceDeviceAuthStmt, err = db.PrepareContext(ctx, replaceDeviceAuth); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ReplaceDeviceAuth: %w", err) |
|||
} |
|||
if q.replaceDeviceInfoStmt, err = db.PrepareContext(ctx, replaceDeviceInfo); err != nil { |
|||
return nil, fmt.Errorf("error preparing query ReplaceDeviceInfo: %w", err) |
|||
} |
|||
return &q, nil |
|||
} |
|||
|
|||
func (q *Queries) Close() error { |
|||
var err error |
|||
if q.deleteDeviceAliasStmt != nil { |
|||
if cerr := q.deleteDeviceAliasStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceAliasStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceAliasByIDStmt != nil { |
|||
if cerr := q.deleteDeviceAliasByIDStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceAliasByIDStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceAliasByIDLikeStmt != nil { |
|||
if cerr := q.deleteDeviceAliasByIDLikeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceAliasByIDLikeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceAssignmentStmt != nil { |
|||
if cerr := q.deleteDeviceAssignmentStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceAssignmentStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceAuthStmt != nil { |
|||
if cerr := q.deleteDeviceAuthStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceAuthStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceInfoStmt != nil { |
|||
if cerr := q.deleteDeviceInfoStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceInfoStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceInfoByIDStmt != nil { |
|||
if cerr := q.deleteDeviceInfoByIDStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceInfoByIDStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.deleteDeviceInfoLikeStmt != nil { |
|||
if cerr := q.deleteDeviceInfoLikeStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing deleteDeviceInfoLikeStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.insertDeviceAliasStmt != nil { |
|||
if cerr := q.insertDeviceAliasStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing insertDeviceAliasStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listDeviceAliasesStmt != nil { |
|||
if cerr := q.listDeviceAliasesStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listDeviceAliasesStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listDeviceAssignmentsStmt != nil { |
|||
if cerr := q.listDeviceAssignmentsStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listDeviceAssignmentsStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listDeviceAuthStmt != nil { |
|||
if cerr := q.listDeviceAuthStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listDeviceAuthStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.listDeviceInfosStmt != nil { |
|||
if cerr := q.listDeviceInfosStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing listDeviceInfosStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.replaceDeviceAssignmentStmt != nil { |
|||
if cerr := q.replaceDeviceAssignmentStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing replaceDeviceAssignmentStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.replaceDeviceAuthStmt != nil { |
|||
if cerr := q.replaceDeviceAuthStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing replaceDeviceAuthStmt: %w", cerr) |
|||
} |
|||
} |
|||
if q.replaceDeviceInfoStmt != nil { |
|||
if cerr := q.replaceDeviceInfoStmt.Close(); cerr != nil { |
|||
err = fmt.Errorf("error closing replaceDeviceInfoStmt: %w", cerr) |
|||
} |
|||
} |
|||
return err |
|||
} |
|||
|
|||
func (q *Queries) exec(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (sql.Result, error) { |
|||
switch { |
|||
case stmt != nil && q.tx != nil: |
|||
return q.tx.StmtContext(ctx, stmt).ExecContext(ctx, args...) |
|||
case stmt != nil: |
|||
return stmt.ExecContext(ctx, args...) |
|||
default: |
|||
return q.db.ExecContext(ctx, query, args...) |
|||
} |
|||
} |
|||
|
|||
func (q *Queries) query(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) (*sql.Rows, error) { |
|||
switch { |
|||
case stmt != nil && q.tx != nil: |
|||
return q.tx.StmtContext(ctx, stmt).QueryContext(ctx, args...) |
|||
case stmt != nil: |
|||
return stmt.QueryContext(ctx, args...) |
|||
default: |
|||
return q.db.QueryContext(ctx, query, args...) |
|||
} |
|||
} |
|||
|
|||
func (q *Queries) queryRow(ctx context.Context, stmt *sql.Stmt, query string, args ...interface{}) *sql.Row { |
|||
switch { |
|||
case stmt != nil && q.tx != nil: |
|||
return q.tx.StmtContext(ctx, stmt).QueryRowContext(ctx, args...) |
|||
case stmt != nil: |
|||
return stmt.QueryRowContext(ctx, args...) |
|||
default: |
|||
return q.db.QueryRowContext(ctx, query, args...) |
|||
} |
|||
} |
|||
|
|||
type Queries struct { |
|||
db DBTX |
|||
tx *sql.Tx |
|||
deleteDeviceAliasStmt *sql.Stmt |
|||
deleteDeviceAliasByIDStmt *sql.Stmt |
|||
deleteDeviceAliasByIDLikeStmt *sql.Stmt |
|||
deleteDeviceAssignmentStmt *sql.Stmt |
|||
deleteDeviceAuthStmt *sql.Stmt |
|||
deleteDeviceInfoStmt *sql.Stmt |
|||
deleteDeviceInfoByIDStmt *sql.Stmt |
|||
deleteDeviceInfoLikeStmt *sql.Stmt |
|||
insertDeviceAliasStmt *sql.Stmt |
|||
listDeviceAliasesStmt *sql.Stmt |
|||
listDeviceAssignmentsStmt *sql.Stmt |
|||
listDeviceAuthStmt *sql.Stmt |
|||
listDeviceInfosStmt *sql.Stmt |
|||
replaceDeviceAssignmentStmt *sql.Stmt |
|||
replaceDeviceAuthStmt *sql.Stmt |
|||
replaceDeviceInfoStmt *sql.Stmt |
|||
} |
|||
|
|||
func (q *Queries) WithTx(tx *sql.Tx) *Queries { |
|||
return &Queries{ |
|||
db: tx, |
|||
tx: tx, |
|||
deleteDeviceAliasStmt: q.deleteDeviceAliasStmt, |
|||
deleteDeviceAliasByIDStmt: q.deleteDeviceAliasByIDStmt, |
|||
deleteDeviceAliasByIDLikeStmt: q.deleteDeviceAliasByIDLikeStmt, |
|||
deleteDeviceAssignmentStmt: q.deleteDeviceAssignmentStmt, |
|||
deleteDeviceAuthStmt: q.deleteDeviceAuthStmt, |
|||
deleteDeviceInfoStmt: q.deleteDeviceInfoStmt, |
|||
deleteDeviceInfoByIDStmt: q.deleteDeviceInfoByIDStmt, |
|||
deleteDeviceInfoLikeStmt: q.deleteDeviceInfoLikeStmt, |
|||
insertDeviceAliasStmt: q.insertDeviceAliasStmt, |
|||
listDeviceAliasesStmt: q.listDeviceAliasesStmt, |
|||
listDeviceAssignmentsStmt: q.listDeviceAssignmentsStmt, |
|||
listDeviceAuthStmt: q.listDeviceAuthStmt, |
|||
listDeviceInfosStmt: q.listDeviceInfosStmt, |
|||
replaceDeviceAssignmentStmt: q.replaceDeviceAssignmentStmt, |
|||
replaceDeviceAuthStmt: q.replaceDeviceAuthStmt, |
|||
replaceDeviceInfoStmt: q.replaceDeviceInfoStmt, |
|||
} |
|||
} |
@ -0,0 +1,301 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
// source: device.sql
|
|||
|
|||
package mysqlgen |
|||
|
|||
import ( |
|||
"context" |
|||
"encoding/json" |
|||
"time" |
|||
|
|||
"github.com/google/uuid" |
|||
) |
|||
|
|||
const deleteDeviceAlias = `-- name: DeleteDeviceAlias :exec |
|||
DELETE |
|||
FROM device_alias |
|||
WHERE id = ? |
|||
AND alias = ? |
|||
` |
|||
|
|||
type DeleteDeviceAliasParams struct { |
|||
ID string |
|||
Alias string |
|||
} |
|||
|
|||
func (q *Queries) DeleteDeviceAlias(ctx context.Context, arg DeleteDeviceAliasParams) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceAliasStmt, deleteDeviceAlias, arg.ID, arg.Alias) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceAliasByID = `-- name: DeleteDeviceAliasByID :exec |
|||
DELETE |
|||
FROM device_alias |
|||
WHERE id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteDeviceAliasByID(ctx context.Context, id string) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceAliasByIDStmt, deleteDeviceAliasByID, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceAliasByIDLike = `-- name: DeleteDeviceAliasByIDLike :exec |
|||
DELETE |
|||
FROM device_alias |
|||
WHERE id LIKE ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteDeviceAliasByIDLike(ctx context.Context, id string) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceAliasByIDLikeStmt, deleteDeviceAliasByIDLike, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceAssignment = `-- name: DeleteDeviceAssignment :exec |
|||
DELETE |
|||
FROM device_assignment |
|||
WHERE id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteDeviceAssignment(ctx context.Context, id uuid.UUID) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceAssignmentStmt, deleteDeviceAssignment, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceAuth = `-- name: DeleteDeviceAuth :exec |
|||
DELETE |
|||
FROM device_auth |
|||
WHERE id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteDeviceAuth(ctx context.Context, id string) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceAuthStmt, deleteDeviceAuth, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceInfo = `-- name: DeleteDeviceInfo :exec |
|||
DELETE |
|||
FROM device_info |
|||
WHERE id = ? |
|||
AND kind = ? |
|||
` |
|||
|
|||
type DeleteDeviceInfoParams struct { |
|||
ID string |
|||
Kind string |
|||
} |
|||
|
|||
func (q *Queries) DeleteDeviceInfo(ctx context.Context, arg DeleteDeviceInfoParams) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceInfoStmt, deleteDeviceInfo, arg.ID, arg.Kind) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceInfoByID = `-- name: DeleteDeviceInfoByID :exec |
|||
DELETE |
|||
FROM device_info |
|||
WHERE id = ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteDeviceInfoByID(ctx context.Context, id string) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceInfoByIDStmt, deleteDeviceInfoByID, id) |
|||
return err |
|||
} |
|||
|
|||
const deleteDeviceInfoLike = `-- name: DeleteDeviceInfoLike :exec |
|||
DELETE |
|||
FROM device_info |
|||
WHERE id LIKE ? |
|||
` |
|||
|
|||
func (q *Queries) DeleteDeviceInfoLike(ctx context.Context, id string) error { |
|||
_, err := q.exec(ctx, q.deleteDeviceInfoLikeStmt, deleteDeviceInfoLike, id) |
|||
return err |
|||
} |
|||
|
|||
const insertDeviceAlias = `-- name: InsertDeviceAlias :exec |
|||
INSERT INTO device_alias (id, alias) |
|||
VALUES (?, ?) |
|||
` |
|||
|
|||
type InsertDeviceAliasParams struct { |
|||
ID string |
|||
Alias string |
|||
} |
|||
|
|||
func (q *Queries) InsertDeviceAlias(ctx context.Context, arg InsertDeviceAliasParams) error { |
|||
_, err := q.exec(ctx, q.insertDeviceAliasStmt, insertDeviceAlias, arg.ID, arg.Alias) |
|||
return err |
|||
} |
|||
|
|||
const listDeviceAliases = `-- name: ListDeviceAliases :many |
|||
SELECT id, alias |
|||
FROM device_alias |
|||
` |
|||
|
|||
func (q *Queries) ListDeviceAliases(ctx context.Context) ([]DeviceAlias, error) { |
|||
rows, err := q.query(ctx, q.listDeviceAliasesStmt, listDeviceAliases) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []DeviceAlias{} |
|||
for rows.Next() { |
|||
var i DeviceAlias |
|||
if err := rows.Scan(&i.ID, &i.Alias); 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 listDeviceAssignments = `-- name: ListDeviceAssignments :many |
|||
SELECT id, created_date, ` + "`" + `match` + "`" + `, effect |
|||
FROM device_assignment |
|||
ORDER BY created_date |
|||
` |
|||
|
|||
func (q *Queries) ListDeviceAssignments(ctx context.Context) ([]DeviceAssignment, error) { |
|||
rows, err := q.query(ctx, q.listDeviceAssignmentsStmt, listDeviceAssignments) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []DeviceAssignment{} |
|||
for rows.Next() { |
|||
var i DeviceAssignment |
|||
if err := rows.Scan( |
|||
&i.ID, |
|||
&i.CreatedDate, |
|||
&i.Match, |
|||
&i.Effect, |
|||
); 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 listDeviceAuth = `-- name: ListDeviceAuth :many |
|||
SELECT id, api_key, extras |
|||
FROM device_auth |
|||
` |
|||
|
|||
func (q *Queries) ListDeviceAuth(ctx context.Context) ([]DeviceAuth, error) { |
|||
rows, err := q.query(ctx, q.listDeviceAuthStmt, listDeviceAuth) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []DeviceAuth{} |
|||
for rows.Next() { |
|||
var i DeviceAuth |
|||
if err := rows.Scan(&i.ID, &i.ApiKey, &i.Extras); 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 listDeviceInfos = `-- name: ListDeviceInfos :many |
|||
SELECT id, kind, data |
|||
FROM device_info |
|||
` |
|||
|
|||
func (q *Queries) ListDeviceInfos(ctx context.Context) ([]DeviceInfo, error) { |
|||
rows, err := q.query(ctx, q.listDeviceInfosStmt, listDeviceInfos) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer rows.Close() |
|||
items := []DeviceInfo{} |
|||
for rows.Next() { |
|||
var i DeviceInfo |
|||
if err := rows.Scan(&i.ID, &i.Kind, &i.Data); 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 replaceDeviceAssignment = `-- name: ReplaceDeviceAssignment :exec |
|||
REPLACE INTO device_assignment (id, created_date, ` + "`" + `match` + "`" + `, effect) |
|||
VALUES (?, ?, ?, ?) |
|||
` |
|||
|
|||
type ReplaceDeviceAssignmentParams struct { |
|||
ID uuid.UUID |
|||
CreatedDate time.Time |
|||
Match string |
|||
Effect json.RawMessage |
|||
} |
|||
|
|||
func (q *Queries) ReplaceDeviceAssignment(ctx context.Context, arg ReplaceDeviceAssignmentParams) error { |
|||
_, err := q.exec(ctx, q.replaceDeviceAssignmentStmt, replaceDeviceAssignment, |
|||
arg.ID, |
|||
arg.CreatedDate, |
|||
arg.Match, |
|||
arg.Effect, |
|||
) |
|||
return err |
|||
} |
|||
|
|||
const replaceDeviceAuth = `-- name: ReplaceDeviceAuth :exec |
|||
REPLACE INTO device_auth (id, api_key, extras) |
|||
VALUES (?, ?, ?) |
|||
` |
|||
|
|||
type ReplaceDeviceAuthParams struct { |
|||
ID string |
|||
ApiKey string |
|||
Extras json.RawMessage |
|||
} |
|||
|
|||
func (q *Queries) ReplaceDeviceAuth(ctx context.Context, arg ReplaceDeviceAuthParams) error { |
|||
_, err := q.exec(ctx, q.replaceDeviceAuthStmt, replaceDeviceAuth, arg.ID, arg.ApiKey, arg.Extras) |
|||
return err |
|||
} |
|||
|
|||
const replaceDeviceInfo = `-- name: ReplaceDeviceInfo :exec |
|||
REPLACE INTO device_info (id, kind, data) |
|||
VALUES (?, ?, ?) |
|||
` |
|||
|
|||
type ReplaceDeviceInfoParams struct { |
|||
ID string |
|||
Kind string |
|||
Data json.RawMessage |
|||
} |
|||
|
|||
func (q *Queries) ReplaceDeviceInfo(ctx context.Context, arg ReplaceDeviceInfoParams) error { |
|||
_, err := q.exec(ctx, q.replaceDeviceInfoStmt, replaceDeviceInfo, arg.ID, arg.Kind, arg.Data) |
|||
return err |
|||
} |
@ -0,0 +1,36 @@ |
|||
// Code generated by sqlc. DO NOT EDIT.
|
|||
// versions:
|
|||
// sqlc v1.13.0
|
|||
|
|||
package mysqlgen |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"time" |
|||
|
|||
"github.com/google/uuid" |
|||
) |
|||
|
|||
type DeviceAlias struct { |
|||
ID string |
|||
Alias string |
|||
} |
|||
|
|||
type DeviceAssignment struct { |
|||
ID uuid.UUID |
|||
CreatedDate time.Time |
|||
Match string |
|||
Effect json.RawMessage |
|||
} |
|||
|
|||
type DeviceAuth struct { |
|||
ID string |
|||
ApiKey string |
|||
Extras json.RawMessage |
|||
} |
|||
|
|||
type DeviceInfo struct { |
|||
ID string |
|||
Kind string |
|||
Data json.RawMessage |
|||
} |
@ -0,0 +1,74 @@ |
|||
-- name: ListDeviceInfos :many |
|||
SELECT * |
|||
FROM device_info; |
|||
|
|||
-- name: ListDeviceAssignments :many |
|||
SELECT * |
|||
FROM device_assignment |
|||
ORDER BY created_date; |
|||
|
|||
-- name: ListDeviceAuth :many |
|||
SELECT * |
|||
FROM device_auth; |
|||
|
|||
-- name: ListDeviceAliases :many |
|||
SELECT * |
|||
FROM device_alias; |
|||
|
|||
-- name: InsertDeviceAlias :exec |
|||
INSERT INTO device_alias (id, alias) |
|||
VALUES (?, ?); |
|||
|
|||
-- name: ReplaceDeviceAuth :exec |
|||
REPLACE INTO device_auth (id, api_key, extras) |
|||
VALUES (?, ?, ?); |
|||
|
|||
-- name: ReplaceDeviceInfo :exec |
|||
REPLACE INTO device_info (id, kind, data) |
|||
VALUES (?, ?, ?); |
|||
|
|||
-- name: ReplaceDeviceAssignment :exec |
|||
REPLACE INTO device_assignment (id, created_date, `match`, effect) |
|||
VALUES (?, ?, ?, ?); |
|||
|
|||
-- name: DeleteDeviceInfo :exec |
|||
DELETE |
|||
FROM device_info |
|||
WHERE id = ? |
|||
AND kind = ?; |
|||
|
|||
-- name: DeleteDeviceInfoByID :exec |
|||
DELETE |
|||
FROM device_info |
|||
WHERE id = ?; |
|||
|
|||
-- name: DeleteDeviceInfoLike :exec |
|||
DELETE |
|||
FROM device_info |
|||
WHERE id LIKE ?; |
|||
|
|||
-- name: DeleteDeviceAssignment :exec |
|||
DELETE |
|||
FROM device_assignment |
|||
WHERE id = ?; |
|||
|
|||
-- name: DeleteDeviceAuth :exec |
|||
DELETE |
|||
FROM device_auth |
|||
WHERE id = ?; |
|||
|
|||
-- name: DeleteDeviceAlias :exec |
|||
DELETE |
|||
FROM device_alias |
|||
WHERE id = ? |
|||
AND alias = ?; |
|||
|
|||
-- name: DeleteDeviceAliasByID :exec |
|||
DELETE |
|||
FROM device_alias |
|||
WHERE id = ?; |
|||
|
|||
-- name: DeleteDeviceAliasByIDLike :exec |
|||
DELETE |
|||
FROM device_alias |
|||
WHERE id LIKE ?; |
@ -0,0 +1,321 @@ |
|||
package mysqldb |
|||
|
|||
import ( |
|||
"context" |
|||
"database/sql" |
|||
"encoding/json" |
|||
"fmt" |
|||
lucifer3 "git.aiterp.net/lucifer3/server" |
|||
"git.aiterp.net/lucifer3/server/commands" |
|||
"git.aiterp.net/lucifer3/server/effects" |
|||
"git.aiterp.net/lucifer3/server/events" |
|||
"git.aiterp.net/lucifer3/server/internal/gentools" |
|||
"git.aiterp.net/lucifer3/server/services/mysqldb/mysqlgen" |
|||
"time" |
|||
|
|||
_ "github.com/go-sql-driver/mysql" |
|||
) |
|||
|
|||
type database struct { |
|||
db *sql.DB |
|||
} |
|||
|
|||
func (d *database) Active() bool { |
|||
return true |
|||
} |
|||
|
|||
func (d *database) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) { |
|||
q := mysqlgen.New(d.db) |
|||
timeout, cancel := context.WithTimeout(context.Background(), time.Second/2) |
|||
defer cancel() |
|||
|
|||
switch event := event.(type) { |
|||
case events.Started: |
|||
timeout, cancel := context.WithTimeout(context.Background(), time.Second*10) |
|||
defer cancel() |
|||
|
|||
// Fetch all aliases first
|
|||
aliases, err := q.ListDeviceAliases(timeout) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_list_aliases", |
|||
Message: "Database could not list aliases: " + err.Error(), |
|||
}) |
|||
} |
|||
|
|||
auths, err := q.ListDeviceAuth(timeout) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_list_device_infos", |
|||
Message: "Hardware State serialization failed: " + err.Error(), |
|||
}) |
|||
} |
|||
for _, auth := range auths { |
|||
bus.RunCommand(commands.ConnectDevice{ |
|||
ID: auth.ID, |
|||
APIKey: auth.ApiKey, |
|||
}) |
|||
} |
|||
|
|||
infos, err := q.ListDeviceInfos(timeout) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_list_device_infos", |
|||
Message: "Hardware State serialization failed: " + err.Error(), |
|||
}) |
|||
} |
|||
for _, info := range infos { |
|||
switch info.Kind { |
|||
case "hardware_state": |
|||
staleEvent := events.HardwareState{} |
|||
err := json.Unmarshal(info.Data, &staleEvent) |
|||
if err == nil { |
|||
bus.RunEvent(staleEvent) |
|||
} |
|||
case "hardware_metadata": |
|||
staleEvent := events.HardwareMetadata{} |
|||
err := json.Unmarshal(info.Data, &staleEvent) |
|||
if err == nil { |
|||
bus.RunEvent(staleEvent) |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Run the aliases now
|
|||
for _, alias := range aliases { |
|||
bus.RunCommand(commands.AddAlias{ |
|||
Match: alias.ID, |
|||
Alias: alias.Alias, |
|||
}) |
|||
} |
|||
|
|||
assignments, err := q.ListDeviceAssignments(timeout) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_list_assignments", |
|||
Message: "Database could not list assignments: " + err.Error(), |
|||
}) |
|||
} |
|||
for _, ass := range assignments { |
|||
effect := effects.Serializable{} |
|||
err := json.Unmarshal(ass.Effect, &effect) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_deserialize_effect", |
|||
Message: err.Error(), |
|||
}) |
|||
continue |
|||
} |
|||
|
|||
bus.RunCommand(commands.Assign{ |
|||
ID: gentools.ShallowCopy(&ass.ID), |
|||
Match: ass.Match, |
|||
Effect: effect.Effect, |
|||
}) |
|||
} |
|||
|
|||
case events.DeviceAccepted: |
|||
if event.Extras == nil { |
|||
event.Extras = map[string]string{} |
|||
} |
|||
|
|||
extras, err := json.Marshal(event.Extras) |
|||
if err != nil { |
|||
extras = []byte("{}") |
|||
} |
|||
|
|||
err = q.ReplaceDeviceAuth(timeout, mysqlgen.ReplaceDeviceAuthParams{ |
|||
ID: event.ID, |
|||
ApiKey: event.APIKey, |
|||
Extras: extras, |
|||
}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_save_device_auth", |
|||
Message: "Device auth save failed: " + err.Error(), |
|||
}) |
|||
} |
|||
|
|||
case events.HardwareState: |
|||
if event.Stale { |
|||
return |
|||
} |
|||
|
|||
event.Stale = true |
|||
serialized, err := json.Marshal(event) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_serialize_hardware_state", |
|||
Message: "Hardware State serialization failed: " + err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
err = q.ReplaceDeviceInfo(timeout, mysqlgen.ReplaceDeviceInfoParams{ |
|||
ID: event.ID, |
|||
Kind: "hardware_state", |
|||
Data: serialized, |
|||
}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_save_hardware_state", |
|||
Message: err.Error(), |
|||
}) |
|||
|
|||
return |
|||
} |
|||
|
|||
case events.HardwareMetadata: |
|||
if event.Stale { |
|||
return |
|||
} |
|||
|
|||
event.Stale = true |
|||
serialized, err := json.Marshal(event) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_serialize_hardware_state", |
|||
Message: "Hardware State serialization failed: " + err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
err = q.ReplaceDeviceInfo(timeout, mysqlgen.ReplaceDeviceInfoParams{ |
|||
ID: event.ID, |
|||
Kind: "hardware_metadata", |
|||
Data: serialized, |
|||
}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_save_hardware_state", |
|||
Message: err.Error(), |
|||
}) |
|||
|
|||
return |
|||
} |
|||
|
|||
case events.AssignmentCreated: |
|||
serialized, err := json.Marshal(&effects.Serializable{Effect: event.Effect}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_serialize_effect", |
|||
Message: err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
err = q.ReplaceDeviceAssignment(timeout, mysqlgen.ReplaceDeviceAssignmentParams{ |
|||
ID: event.ID, |
|||
CreatedDate: time.Now().UTC(), |
|||
Match: event.Match, |
|||
Effect: serialized, |
|||
}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_save_assignment", |
|||
Message: err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
case events.AssignmentRemoved: |
|||
err := q.DeleteDeviceAssignment(timeout, event.ID) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_remove_assignment", |
|||
Message: err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
case events.AliasAdded: |
|||
err := q.InsertDeviceAlias(timeout, mysqlgen.InsertDeviceAliasParams{ |
|||
ID: event.ID, |
|||
Alias: event.Alias, |
|||
}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_remove_assignment", |
|||
Message: err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
case events.AliasRemoved: |
|||
err := q.DeleteDeviceAlias(timeout, mysqlgen.DeleteDeviceAliasParams{ |
|||
ID: event.ID, |
|||
Alias: event.Alias, |
|||
}) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_remove_assignment", |
|||
Message: err.Error(), |
|||
}) |
|||
return |
|||
} |
|||
|
|||
case events.DeviceForgotten: |
|||
err := q.DeleteDeviceInfoByID(timeout, event.ID) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_remove_info", |
|||
Message: "Failed to remove device info: " + err.Error(), |
|||
}) |
|||
} |
|||
_ = q.DeleteDeviceAuth(timeout, event.ID) |
|||
err = q.DeleteDeviceAliasByID(timeout, event.ID) |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_remove_aliases", |
|||
Message: "Failed to remove device aliases: " + err.Error(), |
|||
}) |
|||
} |
|||
err = q.DeleteDeviceAliasByIDLike(timeout, event.ID+":%") |
|||
if err != nil { |
|||
bus.RunEvent(events.Log{ |
|||
Level: "error", |
|||
Code: "database_could_not_remove_sub_aliases", |
|||
Message: "Failed to remove sub-device aliases: " + err.Error(), |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
|
|||
func (d *database) HandleCommand(*lucifer3.EventBus, lucifer3.Command) {} |
|||
|
|||
func Connect(host string, port int, username, password, dbname string) (lucifer3.ActiveService, error) { |
|||
db, err := sql.Open("mysql", fmt.Sprintf( |
|||
"%s:%s@(%s:%d)/%s?parseTime=true", username, password, host, port, dbname, |
|||
)) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
db.SetMaxOpenConns(10) |
|||
db.SetMaxIdleConns(10) |
|||
db.SetConnMaxIdleTime(time.Minute) |
|||
|
|||
err = db.Ping() |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
return &database{db: db}, nil |
|||
} |
@ -0,0 +1,36 @@ |
|||
package sqltypes |
|||
|
|||
import ( |
|||
"database/sql/driver" |
|||
"encoding/json" |
|||
"errors" |
|||
) |
|||
|
|||
type NullRawMessage struct { |
|||
RawMessage json.RawMessage |
|||
Valid bool |
|||
} |
|||
|
|||
func (n *NullRawMessage) Scan(value interface{}) error { |
|||
if value == nil { |
|||
n.RawMessage, n.Valid = json.RawMessage{}, false |
|||
return nil |
|||
} |
|||
buf, ok := value.([]byte) |
|||
|
|||
if !ok { |
|||
return errors.New("cannot parse to bytes") |
|||
} |
|||
|
|||
n.RawMessage, n.Valid = buf, true |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (n NullRawMessage) Value() (driver.Value, error) { |
|||
if !n.Valid { |
|||
return nil, nil |
|||
} |
|||
|
|||
return []byte(n.RawMessage), nil |
|||
} |
@ -0,0 +1,28 @@ |
|||
version: "1" |
|||
packages: |
|||
- name: "mysqlgen" |
|||
path: "./services/mysqldb/mysqlgen" |
|||
queries: "./services/mysqldb/queries" |
|||
schema: "./services/mysqldb/migrations" |
|||
engine: "mysql" |
|||
emit_prepared_queries: true |
|||
emit_interface: false |
|||
emit_exact_table_names: false |
|||
emit_empty_slices: true |
|||
emit_json_tags: false |
|||
overrides: |
|||
- go_type: "git.aiterp.net/lucifer3/server/services/mysqldb/sqltypes.NullRawMessage" |
|||
db_type: "json" |
|||
nullable: true |
|||
- go_type: "float64" |
|||
db_type: "float" |
|||
- go_type: "float64" |
|||
db_type: "float" |
|||
nullable: true |
|||
- go_type: "int" |
|||
db_type: "int" |
|||
- go_type: "github.com/google/uuid.UUID" |
|||
db_type: "char" |
|||
- go_type: "github.com/google/uuid.NullUUID" |
|||
db_type: "char" |
|||
nullable: true |
Write
Preview
Loading…
Cancel
Save
Reference in new issue