Files
tether/engine.go
T

88 lines
2.8 KiB
Go

package tether
import (
"log/slog"
"net/http"
"github.com/wisplite/tether/reactivity"
"gorm.io/gorm"
)
type Engine struct {
db *gorm.DB
dbType string // sqlite or postgres
mutations map[string]func(ctx *MutationCtx) error
queries map[string]func(ctx *QueryCtx) error
tracker *reactivity.Tracker
}
func NewEngine(db *gorm.DB, dbType string) *Engine {
slog.SetLogLoggerLevel(slog.LevelDebug)
tracker := reactivity.NewTracker()
if dbType != "sqlite" && dbType != "postgres" {
panic("Invalid database type")
}
return &Engine{db: db, dbType: dbType, mutations: make(map[string]func(ctx *MutationCtx) error), queries: make(map[string]func(ctx *QueryCtx) error), tracker: tracker}
}
func (e *Engine) RegisterMutation(name string, mutation func(ctx *MutationCtx) error) {
e.mutations[name] = mutation // stores the mutation in the list of valid mutations
slog.Debug("Registered mutation", "name", name)
}
func (e *Engine) RegisterQuery(name string, query func(ctx *QueryCtx) error, dependencies []string) {
e.queries[name] = query // stores the query in the list of valid queries
slog.Debug("Registered query", "name", name)
}
func (e *Engine) CreateTable(name string, schema interface{}) {
e.db.AutoMigrate(schema)
slog.Debug("Created table", "name", name)
}
func (e *Engine) Handle(w http.ResponseWriter, r *http.Request) {
reactivity.Handle(w, r, e, e.tracker) // wraps the raw websocket connection with the engine handler
}
func (e *Engine) OnConnect(clientID string) error {
slog.Debug("Connected to websocket", "client", clientID)
// TODO: implement the logic to handle the connection
return nil
}
func (e *Engine) OnDisconnect(clientID string) error {
slog.Debug("Disconnected from websocket", "client", clientID)
// TODO: implement the logic to handle the disconnection
return nil
}
func (e *Engine) ExecuteQuery(query string) (interface{}, error) {
/*
TODO: implement the logic to execute the query
Steps needed:
1. Check which tables updated
2. Get the queries that rely on the tables
3. Get the subscriptions that need updating
4. Calculate hash for every query
5. Send the updated queries if hash changed
*/
return nil, nil
}
func (e *Engine) ExecuteMutation(mutation string, params map[string]interface{}) (interface{}, error) {
result := e.mutations[mutation](&MutationCtx{DB: e.db, AuthCtx: &AuthCtx{UserID: "", IsLoggedIn: true}, Params: params})
return result, nil
}
func (e *Engine) OnReceiveMessage(clientID string, msg map[string]interface{}) error {
slog.Debug("Received message", "from", clientID, "message", msg)
switch msg["type"] {
case "query":
query := msg["location"].(string) + "?" + msg["params"].(string)
e.tracker.SubscribeToQuery(clientID, query)
case "mutation":
e.ExecuteMutation(msg["location"].(string), msg["params"].(map[string]interface{}))
}
return nil
}