sonr/internal/db/idb/idb.go
Prad Nukala b593245fe6
feature/implement vault allocation (#11)
* feat: add authentication middleware

* feat: add REST API endpoints for database interactions

* refactor: move DiscoveryDocument Pkl schema to oidc module

* fix: replace sonrd with test_node.sh

* feat: use NFT keeper to mint DID namespace NFT

* refactor: move NFT class configuration to types

* feat: add GlobalIntegrity genesis state

* fix: ensure GlobalIntegrity is initialized in genesis

* refactor: update all references to transactions module

* refactor: improve genesis state struct

* chore(did): update discovery endpoint to reflect base url

* feat: remove unused context cache and client code

* refactor: remove middleware dependency from keeper

* feat: Add new query handlers for DID module

* feat: Implement unimplemented params queries

* feat: add support for first-party caveats

* refactor: move motr command to cmd directory

* feat: add support for GitHub releases

* fix(motr): build app.wasm for motr package

* feat: add card component

* feat: add IndexedDB support for persistent storage

* feat: Add Row and Column components

* feat: add  and  components

* refactor: improve button component

* refactor: remove unnecessary button parameter in renderButton

* feat: add vault service endpoint

* feat: add input component
2024-09-14 12:47:25 -04:00

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()
}