mirror of
https://github.com/onsonr/sonr.git
synced 2025-03-11 13:29:12 +00:00
![github-actions[bot]](/assets/img/avatar_default.png)
* Squash merge develop into master * feat: add automated production release workflow * feat: add Gitflow workflow for syncing branches * ci: update workflow runner to latest ubuntu version * feat: enable buf.build publishing on master and develop branches --------- Co-authored-by: Prad Nukala <prad@sonr.io>
132 lines
2.7 KiB
Go
132 lines
2.7 KiB
Go
//go:build js && wasm
|
|
// +build js,wasm
|
|
|
|
package idb
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"syscall/js"
|
|
|
|
"github.com/hack-pad/go-indexeddb/idb"
|
|
)
|
|
|
|
// Model is an interface that must be implemented by types used with Table
|
|
type Model interface {
|
|
Table() string
|
|
}
|
|
|
|
// Table is a generic wrapper around IDB for easier database operations on a specific table
|
|
type Table[T Model] struct {
|
|
db *idb.Database
|
|
dbName string
|
|
keyPath string
|
|
}
|
|
|
|
// NewTable creates a new Table instance
|
|
func NewTable[T Model](dbName string, version uint, keyPath string) (*Table[T], error) {
|
|
ctx := context.Background()
|
|
factory := idb.Global()
|
|
|
|
var model T
|
|
tableName := model.Table()
|
|
|
|
openRequest, err := factory.Open(ctx, dbName, version, func(db *idb.Database, oldVersion, newVersion uint) error {
|
|
_, err := db.CreateObjectStore(tableName, idb.ObjectStoreOptions{
|
|
KeyPath: js.ValueOf(keyPath),
|
|
})
|
|
return err
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
db, err := openRequest.Await(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Table[T]{
|
|
db: db,
|
|
dbName: dbName,
|
|
keyPath: keyPath,
|
|
}, nil
|
|
}
|
|
|
|
// Insert adds a new record to the table
|
|
func (t *Table[T]) Insert(data T) error {
|
|
tx, err := t.db.Transaction(idb.TransactionReadWrite, data.Table())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer tx.Commit()
|
|
|
|
objectStore, err := tx.ObjectStore(data.Table())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = objectStore.Add(js.ValueOf(string(jsonData)))
|
|
return err
|
|
}
|
|
|
|
// Query retrieves a record from the table based on a key
|
|
func (t *Table[T]) Query(key interface{}) (T, error) {
|
|
var result T
|
|
|
|
tx, err := t.db.Transaction(idb.TransactionReadOnly, result.Table())
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
defer tx.Commit()
|
|
|
|
objectStore, err := tx.ObjectStore(result.Table())
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
request, err := objectStore.Get(js.ValueOf(key))
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
value, err := request.Await(context.Background())
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
if value.IsUndefined() || value.IsNull() {
|
|
return result, errors.New("record not found")
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(value.String()), &result)
|
|
return result, err
|
|
}
|
|
|
|
// Delete removes a record from the table based on a key
|
|
func (t *Table[T]) Delete(key interface{}) error {
|
|
var model T
|
|
tx, err := t.db.Transaction(idb.TransactionReadWrite, model.Table())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer tx.Commit()
|
|
|
|
objectStore, err := tx.ObjectStore(model.Table())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = objectStore.Delete(js.ValueOf(key))
|
|
return err
|
|
}
|
|
|
|
// Close closes the database connection
|
|
func (t *Table[T]) Close() error {
|
|
return t.db.Close()
|
|
}
|