mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-12 03:10:04 +08:00
Implemented LoadModules method for loading modules into EchoVault.
Implemented UnloadModules methods for removing module from EchoVault. Removed connection from plugin handler function parameters as it should not be modified by the module.
This commit is contained in:
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/echovault/echovault/internal"
|
||||
"net"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
@@ -58,9 +57,6 @@ type CommandHandlerFunc func(params CommandHandlerFuncParams) ([]byte, error)
|
||||
//
|
||||
// Command is the string slice command containing the command that triggered this handler.
|
||||
//
|
||||
// Connection is the TCP connection that triggered this command. In embedded mode, this will always be nil.
|
||||
// Any TCP client that trigger the custom command will have its connection passed to the handler here.
|
||||
//
|
||||
// KeyExists returns true if the key passed to it exists in the store.
|
||||
//
|
||||
// CreateKeyAndLock creates the new key and immediately write locks it. If the key already exists, then
|
||||
@@ -89,7 +85,6 @@ type CommandHandlerFunc func(params CommandHandlerFuncParams) ([]byte, error)
|
||||
type CommandHandlerFuncParams struct {
|
||||
Context context.Context
|
||||
Command []string
|
||||
Connection *net.Conn
|
||||
KeyExists func(ctx context.Context, key string) bool
|
||||
CreateKeyAndLock func(ctx context.Context, key string) (bool, error)
|
||||
KeyLock func(ctx context.Context, key string) (bool, error)
|
||||
@@ -273,7 +268,6 @@ func (server *EchoVault) AddCommand(command CommandOptions) error {
|
||||
return command.HandlerFunc(CommandHandlerFuncParams{
|
||||
Context: params.Context,
|
||||
Command: params.Command,
|
||||
Connection: params.Connection,
|
||||
KeyLock: params.KeyLock,
|
||||
KeyUnlock: params.KeyUnlock,
|
||||
KeyRLock: params.KeyRLock,
|
||||
@@ -344,7 +338,6 @@ func (server *EchoVault) AddCommand(command CommandOptions) error {
|
||||
return sc.HandlerFunc(CommandHandlerFuncParams{
|
||||
Context: params.Context,
|
||||
Command: params.Command,
|
||||
Connection: params.Connection,
|
||||
KeyLock: params.KeyLock,
|
||||
KeyUnlock: params.KeyUnlock,
|
||||
KeyRLock: params.KeyRLock,
|
||||
|
@@ -1 +1,132 @@
|
||||
package echovault
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/echovault/echovault/internal"
|
||||
"plugin"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (server *EchoVault) LoadModules(path string, args ...string) error {
|
||||
p, err := plugin.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commandSymbol, err := p.Lookup("Command")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
command, ok := commandSymbol.(string)
|
||||
if !ok {
|
||||
return errors.New("command symbol is not a string")
|
||||
}
|
||||
|
||||
categoriesSymbol, err := p.Lookup("Categories")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
categories, ok := categoriesSymbol.([]string)
|
||||
if !ok {
|
||||
return errors.New("categories symbol not a string slice")
|
||||
}
|
||||
|
||||
descriptionSymbol, err := p.Lookup("Description")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
description, ok := descriptionSymbol.(string)
|
||||
if !ok {
|
||||
return errors.New("description symbol is no a string")
|
||||
}
|
||||
|
||||
syncSymbol, err := p.Lookup("Sync")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sync, ok := syncSymbol.(bool)
|
||||
if !ok {
|
||||
return errors.New("sync symbol is not a bool")
|
||||
}
|
||||
|
||||
keyExtractionFuncSymbol, err := p.Lookup("KeyExtractionFunc")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
keyExtractionFunc, ok := keyExtractionFuncSymbol.(func(cmd []string, args ...string) ([]string, []string, error))
|
||||
if !ok {
|
||||
return errors.New("key extraction function has unexpected signature")
|
||||
}
|
||||
|
||||
handlerFuncSymbol, err := p.Lookup("HandlerFunc")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
handlerFunc, ok := handlerFuncSymbol.(func(
|
||||
ctx context.Context,
|
||||
command []string,
|
||||
keyExists func(ctx context.Context, key string) bool,
|
||||
keyLock func(ctx context.Context, key string) (bool, error),
|
||||
keyUnlock func(ctx context.Context, key string),
|
||||
keyRLock func(ctx context.Context, key string) (bool, error),
|
||||
keyRUnlock func(ctx context.Context, key string),
|
||||
createKeyAndLock func(ctx context.Context, key string) (bool, error),
|
||||
getValue func(ctx context.Context, key string) interface{},
|
||||
setValue func(ctx context.Context, key string, value interface{}) error,
|
||||
args ...string,
|
||||
) ([]byte, error))
|
||||
if !ok {
|
||||
return errors.New("handler function has unexpected signature")
|
||||
}
|
||||
|
||||
server.commands = append(server.commands, internal.Command{
|
||||
Command: command,
|
||||
Module: path,
|
||||
Categories: func() []string {
|
||||
// Convert all the categories to lower case for uniformity
|
||||
cats := make([]string, len(categories))
|
||||
for i, cat := range categories {
|
||||
cats[i] = strings.ToLower(cat)
|
||||
}
|
||||
return cats
|
||||
}(),
|
||||
Description: description,
|
||||
Sync: sync,
|
||||
SubCommands: make([]internal.SubCommand, 0),
|
||||
KeyExtractionFunc: func(cmd []string) (internal.KeyExtractionFuncResult, error) {
|
||||
readKeys, writeKeys, err := keyExtractionFunc(cmd, args...)
|
||||
if err != nil {
|
||||
return internal.KeyExtractionFuncResult{}, err
|
||||
}
|
||||
return internal.KeyExtractionFuncResult{
|
||||
Channels: make([]string, 0),
|
||||
ReadKeys: readKeys,
|
||||
WriteKeys: writeKeys,
|
||||
}, nil
|
||||
},
|
||||
HandlerFunc: func(params internal.HandlerFuncParams) ([]byte, error) {
|
||||
return handlerFunc(
|
||||
params.Context,
|
||||
params.Command,
|
||||
params.KeyExists,
|
||||
params.KeyLock,
|
||||
params.KeyUnlock,
|
||||
params.KeyRLock,
|
||||
params.KeyRUnlock,
|
||||
params.CreateKeyAndLock,
|
||||
params.GetValue,
|
||||
params.SetValue,
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *EchoVault) UnloadModules(module string) {
|
||||
server.commands = slices.DeleteFunc(server.commands, func(command internal.Command) bool {
|
||||
return strings.EqualFold(command.Module, module)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user