mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-11 14:39:30 +08:00

* plugin handler and lifecycle * rebase * remove reflect s * remove Config and NewPlugin from plugin template * Remove plugin manager, generation of plugin interface * implement http handlers for services remove log trim path prefix wails/services * update plugine example * Misc updates * Ported plugins to services, rewritten example * Added fileserver * Update OnStartup and use a context for the application * Rename PathPrefix to Route. Create docs. * Use service config copy. Add Name to Service Options. Improve service generation. * Use service config copy. Add Name to Service Options. Improve service generation. Update README * Remove rogue db * Update changelog.md --------- Co-authored-by: Lea O'Anthony <lea.anthony@gmail.com>
162 lines
3.0 KiB
Go
162 lines
3.0 KiB
Go
package kvstore
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"os"
|
|
"sync"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
)
|
|
|
|
type KeyValueStore struct {
|
|
config *Config
|
|
filename string
|
|
data map[string]any
|
|
unsaved bool
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
type Config struct {
|
|
Filename string
|
|
AutoSave bool
|
|
}
|
|
|
|
type Service struct{}
|
|
|
|
func New(config *Config) *KeyValueStore {
|
|
return &KeyValueStore{
|
|
config: config,
|
|
data: make(map[string]any),
|
|
}
|
|
}
|
|
|
|
// OnShutdown will save the store to disk if there are unsaved changes.
|
|
func (kvs *KeyValueStore) OnShutdown() error {
|
|
if kvs.unsaved {
|
|
err := kvs.Save()
|
|
if err != nil {
|
|
return errors.Wrap(err, "Error saving store")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Name returns the name of the plugin.
|
|
func (kvs *KeyValueStore) Name() string {
|
|
return "github.com/wailsapp/wails/v3/plugins/kvstore"
|
|
}
|
|
|
|
// OnStartup is called when the plugin is loaded. This is where you should do any setup.
|
|
func (kvs *KeyValueStore) OnStartup(ctx context.Context, options application.ServiceOptions) error {
|
|
err := kvs.open(kvs.config.Filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (kvs *KeyValueStore) open(filename string) (err error) {
|
|
kvs.filename = filename
|
|
kvs.data = make(map[string]any)
|
|
|
|
file, err := os.Open(filename)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
defer func() {
|
|
err2 := file.Close()
|
|
if err2 != nil {
|
|
application.Get().Logger.Error("Key/Value Store Plugin Error:", "error", err.Error())
|
|
if err == nil {
|
|
err = err2
|
|
}
|
|
}
|
|
}()
|
|
|
|
bytes, err := io.ReadAll(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(bytes) > 0 {
|
|
if err := json.Unmarshal(bytes, &kvs.data); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Save saves the store to disk
|
|
func (kvs *KeyValueStore) Save() error {
|
|
kvs.lock.Lock()
|
|
defer kvs.lock.Unlock()
|
|
|
|
bytes, err := json.Marshal(kvs.data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = os.WriteFile(kvs.filename, bytes, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
kvs.unsaved = false
|
|
|
|
return nil
|
|
}
|
|
|
|
// Get returns the value for the given key. If key is empty, the entire store is returned.
|
|
func (kvs *KeyValueStore) Get(key string) any {
|
|
kvs.lock.RLock()
|
|
defer kvs.lock.RUnlock()
|
|
|
|
if key == "" {
|
|
return kvs.data
|
|
}
|
|
|
|
return kvs.data[key]
|
|
}
|
|
|
|
// Set sets the value for the given key. If AutoSave is true, the store is saved to disk.
|
|
func (kvs *KeyValueStore) Set(key string, value any) error {
|
|
kvs.lock.Lock()
|
|
kvs.data[key] = value
|
|
kvs.lock.Unlock()
|
|
if kvs.config.AutoSave {
|
|
err := kvs.Save()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
kvs.unsaved = false
|
|
} else {
|
|
kvs.unsaved = true
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Delete deletes the key from the store. If AutoSave is true, the store is saved to disk.
|
|
func (kvs *KeyValueStore) Delete(key string) error {
|
|
kvs.lock.Lock()
|
|
delete(kvs.data, key)
|
|
kvs.lock.Unlock()
|
|
if kvs.config.AutoSave {
|
|
err := kvs.Save()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
kvs.unsaved = false
|
|
} else {
|
|
kvs.unsaved = true
|
|
}
|
|
return nil
|
|
}
|