index.go raw

   1  //go:build js && wasm
   2  // +build js,wasm
   3  
   4  package idb
   5  
   6  import (
   7  	"syscall/js"
   8  
   9  	"github.com/hack-pad/safejs"
  10  )
  11  
  12  // IndexOptions contains all options used to create an Index
  13  type IndexOptions struct {
  14  	// Unique disallows duplicate values for a single key.
  15  	Unique bool
  16  	// MultiEntry adds an entry in the index for each array element when the keyPath resolves to an Array. If false, adds one single entry containing the Array.
  17  	MultiEntry bool
  18  }
  19  
  20  // Index provides asynchronous access to an index in a database. An index is a kind of object store for looking up records in another object store, called the referenced object store. You use this to retrieve data.
  21  type Index struct {
  22  	base *baseObjectStore // don't embed to avoid generated docs with the wrong receiver type (Index vs *Index)
  23  }
  24  
  25  func wrapIndex(txn *Transaction, jsIndex safejs.Value) *Index {
  26  	return &Index{wrapBaseObjectStore(txn, jsIndex)}
  27  }
  28  
  29  // ObjectStore returns the object store referenced by this index.
  30  func (i *Index) ObjectStore() (*ObjectStore, error) {
  31  	store, err := i.base.jsObjectStore.Get("objectStore")
  32  	if err != nil {
  33  		return nil, err
  34  	}
  35  	return wrapObjectStore(i.base.txn, store), nil
  36  }
  37  
  38  // Name returns the name of this index
  39  func (i *Index) Name() (string, error) {
  40  	name, err := i.base.jsObjectStore.Get("name")
  41  	if err != nil {
  42  		return "", err
  43  	}
  44  	return name.String()
  45  }
  46  
  47  // KeyPath returns the key path of this index. If js.Null(), this index is not auto-populated.
  48  func (i *Index) KeyPath() (js.Value, error) {
  49  	value, err := i.base.jsObjectStore.Get("keyPath")
  50  	return safejs.Unsafe(value), err
  51  }
  52  
  53  // MultiEntry affects how the index behaves when the result of evaluating the index's key path yields an array. If true, there is one record in the index for each item in an array of keys. If false, then there is one record for each key that is an array.
  54  func (i *Index) MultiEntry() (bool, error) {
  55  	multiEntry, err := i.base.jsObjectStore.Get("multiEntry")
  56  	if err != nil {
  57  		return false, err
  58  	}
  59  	return multiEntry.Bool()
  60  }
  61  
  62  // Unique indicates this index does not allow duplicate values for a key.
  63  func (i *Index) Unique() (bool, error) {
  64  	unique, err := i.base.jsObjectStore.Get("unique")
  65  	if err != nil {
  66  		return false, err
  67  	}
  68  	return unique.Bool()
  69  }
  70  
  71  // Count returns a UintRequest, and, in a separate thread, returns the total number of records in the index.
  72  func (i *Index) Count() (*UintRequest, error) {
  73  	return i.base.Count()
  74  }
  75  
  76  // CountKey returns a UintRequest, and, in a separate thread, returns the total number of records that match the provided key.
  77  func (i *Index) CountKey(key js.Value) (*UintRequest, error) {
  78  	return i.base.CountKey(safejs.Safe(key))
  79  }
  80  
  81  // CountRange returns a UintRequest, and, in a separate thread, returns the total number of records that match the provided KeyRange.
  82  func (i *Index) CountRange(keyRange *KeyRange) (*UintRequest, error) {
  83  	return i.base.CountRange(keyRange)
  84  }
  85  
  86  // GetAllKeys returns an ArrayRequest that retrieves record keys for all objects in the index.
  87  func (i *Index) GetAllKeys() (*ArrayRequest, error) {
  88  	return i.base.GetAllKeys()
  89  }
  90  
  91  // GetAllKeysRange returns an ArrayRequest that retrieves record keys for all objects in the index matching the specified query. If maxCount is 0, retrieves all objects matching the query.
  92  func (i *Index) GetAllKeysRange(query *KeyRange, maxCount uint) (*ArrayRequest, error) {
  93  	return i.base.GetAllKeysRange(query, maxCount)
  94  }
  95  
  96  // Get returns a Request, and, in a separate thread, returns objects selected by the specified key. This is for retrieving specific records from an index.
  97  func (i *Index) Get(key js.Value) (*Request, error) {
  98  	return i.base.Get(safejs.Safe(key))
  99  }
 100  
 101  // GetKey returns a Request, and, in a separate thread retrieves and returns the record key for the object matching the specified parameter.
 102  func (i *Index) GetKey(value js.Value) (*Request, error) {
 103  	return i.base.GetKey(safejs.Safe(value))
 104  }
 105  
 106  // OpenCursor returns a CursorWithValueRequest, and, in a separate thread, returns a new CursorWithValue. Used for iterating through an index by primary key with a cursor.
 107  func (i *Index) OpenCursor(direction CursorDirection) (*CursorWithValueRequest, error) {
 108  	return i.base.OpenCursor(direction)
 109  }
 110  
 111  // OpenCursorKey is the same as OpenCursor, but opens a cursor over the given key instead.
 112  func (i *Index) OpenCursorKey(key js.Value, direction CursorDirection) (*CursorWithValueRequest, error) {
 113  	return i.base.OpenCursorKey(safejs.Safe(key), direction)
 114  }
 115  
 116  // OpenCursorRange is the same as OpenCursor, but opens a cursor over the given range instead.
 117  func (i *Index) OpenCursorRange(keyRange *KeyRange, direction CursorDirection) (*CursorWithValueRequest, error) {
 118  	return i.base.OpenCursorRange(keyRange, direction)
 119  }
 120  
 121  // OpenKeyCursor returns a CursorRequest, and, in a separate thread, returns a new Cursor. Used for iterating through all keys in an object store.
 122  func (i *Index) OpenKeyCursor(direction CursorDirection) (*CursorRequest, error) {
 123  	return i.base.OpenKeyCursor(direction)
 124  }
 125  
 126  // OpenKeyCursorKey is the same as OpenKeyCursor, but opens a cursor over the given key instead.
 127  func (i *Index) OpenKeyCursorKey(key js.Value, direction CursorDirection) (*CursorRequest, error) {
 128  	return i.base.OpenKeyCursorKey(safejs.Safe(key), direction)
 129  }
 130  
 131  // OpenKeyCursorRange is the same as OpenKeyCursor, but opens a cursor over the given key range instead.
 132  func (i *Index) OpenKeyCursorRange(keyRange *KeyRange, direction CursorDirection) (*CursorRequest, error) {
 133  	return i.base.OpenKeyCursorRange(keyRange, direction)
 134  }
 135