mirror of
https://github.com/r3-team/r3.git
synced 2025-12-30 15:29:37 -06:00
130 lines
3.5 KiB
Go
130 lines
3.5 KiB
Go
package request
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"r3/cache"
|
|
"r3/cluster"
|
|
"r3/handler"
|
|
"r3/login/login_clientEvent"
|
|
"r3/schema/clientEvent"
|
|
"r3/types"
|
|
"strings"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
func clientEventDel_tx(ctx context.Context, tx pgx.Tx, reqJson json.RawMessage) (interface{}, error) {
|
|
|
|
var req struct {
|
|
Id uuid.UUID `json:"id"`
|
|
}
|
|
if err := json.Unmarshal(reqJson, &req); err != nil {
|
|
return nil, err
|
|
}
|
|
return nil, clientEvent.Del_tx(ctx, tx, req.Id)
|
|
}
|
|
|
|
func clientEventSet_tx(ctx context.Context, tx pgx.Tx, reqJson json.RawMessage) (interface{}, error) {
|
|
|
|
var req types.ClientEvent
|
|
if err := json.Unmarshal(reqJson, &req); err != nil {
|
|
return nil, err
|
|
}
|
|
return nil, clientEvent.Set_tx(ctx, tx, req)
|
|
}
|
|
|
|
// fat client requests
|
|
func clientEventGetFatClient_tx(ctx context.Context, tx pgx.Tx, loginId int64) (interface{}, error) {
|
|
|
|
var err error
|
|
var res struct {
|
|
ClientEvents []types.ClientEvent `json:"clientEvents"`
|
|
ClientEventIdMapLogin map[uuid.UUID]types.LoginClientEvent `json:"clientEventIdMapLogin"`
|
|
}
|
|
res.ClientEvents = make([]types.ClientEvent, 0)
|
|
res.ClientEventIdMapLogin = make(map[uuid.UUID]types.LoginClientEvent)
|
|
|
|
// collect login client events for login (currently only used to enable and overwrite hotkeys)
|
|
res.ClientEventIdMapLogin, err = login_clientEvent.Get_tx(ctx, tx, loginId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// collect client events for login
|
|
access, err := cache.GetAccessById(loginId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cache.Schema_mx.RLock()
|
|
for id, ce := range cache.ClientEventIdMap {
|
|
if _, exists := access.ClientEvent[id]; !exists {
|
|
continue // login has no access, ignore
|
|
}
|
|
if ce.Event == "onHotkey" {
|
|
if _, exists := res.ClientEventIdMapLogin[id]; !exists {
|
|
continue // login has not enabled hotkey, ignore
|
|
}
|
|
}
|
|
res.ClientEvents = append(res.ClientEvents, ce)
|
|
}
|
|
cache.Schema_mx.RUnlock()
|
|
return res, nil
|
|
}
|
|
func clientEventExecFatClient_tx(ctx context.Context, tx pgx.Tx, reqJson json.RawMessage, loginId int64, address string) (interface{}, error) {
|
|
|
|
var req struct {
|
|
Id uuid.UUID `json:"id"`
|
|
Arguments []interface{} `json:"arguments"`
|
|
}
|
|
if err := json.Unmarshal(reqJson, &req); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cache.Schema_mx.RLock()
|
|
ce, exists := cache.ClientEventIdMap[req.Id]
|
|
cache.Schema_mx.RUnlock()
|
|
|
|
if !exists {
|
|
return nil, handler.ErrSchemaUnknownClientEvent(req.Id)
|
|
}
|
|
|
|
// execute valid actions
|
|
if ce.Action == "callJsFunction" && ce.JsFunctionId.Valid {
|
|
return nil, cluster.JsFunctionCalled_tx(ctx, tx, true, address, loginId, ce.JsFunctionId.Bytes, req.Arguments)
|
|
}
|
|
if ce.Action == "callPgFunction" && ce.PgFunctionId.Valid {
|
|
|
|
cache.Schema_mx.RLock()
|
|
fnc, exists := cache.PgFunctionIdMap[ce.PgFunctionId.Bytes]
|
|
cache.Schema_mx.RUnlock()
|
|
|
|
if !exists {
|
|
return nil, handler.ErrSchemaUnknownPgFunction(ce.PgFunctionId.Bytes)
|
|
}
|
|
if fnc.IsTrigger {
|
|
return nil, handler.ErrSchemaTriggerPgFunctionCall(ce.PgFunctionId.Bytes)
|
|
}
|
|
|
|
cache.Schema_mx.RLock()
|
|
mod := cache.ModuleIdMap[fnc.ModuleId]
|
|
cache.Schema_mx.RUnlock()
|
|
|
|
placeholders := make([]string, 0)
|
|
for i := range req.Arguments {
|
|
placeholders = append(placeholders, fmt.Sprintf("$%d", i+1))
|
|
}
|
|
|
|
var returnIf interface{}
|
|
err := tx.QueryRow(ctx, fmt.Sprintf(`SELECT "%s"."%s"(%s)`, mod.Name, fnc.Name, strings.Join(placeholders, ",")),
|
|
req.Arguments...).Scan(&returnIf)
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return nil, fmt.Errorf("invalid client event action")
|
|
}
|