base_object_store.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //go:build js && wasm
  2. // +build js,wasm
  3. package idb
  4. import (
  5. "github.com/hack-pad/safejs"
  6. )
  7. // baseObjectStore is the common implementation for both object stores and indexes.
  8. type baseObjectStore struct {
  9. txn *Transaction
  10. jsObjectStore safejs.Value
  11. }
  12. func wrapBaseObjectStore(txn *Transaction, jsObjectStore safejs.Value) *baseObjectStore {
  13. if txn == nil {
  14. txn = (*Transaction)(nil)
  15. }
  16. return &baseObjectStore{
  17. txn: txn,
  18. jsObjectStore: jsObjectStore,
  19. }
  20. }
  21. // Count returns a UintRequest, and, in a separate thread, returns the total number of records in the store or index.
  22. func (b *baseObjectStore) Count() (*UintRequest, error) {
  23. reqValue, err := b.jsObjectStore.Call("count")
  24. if err != nil {
  25. return nil, tryAsDOMException(err)
  26. }
  27. req := wrapRequest(b.txn, reqValue)
  28. return newUintRequest(req), nil
  29. }
  30. // CountKey returns a UintRequest, and, in a separate thread, returns the total number of records that match the provided key.
  31. func (b *baseObjectStore) CountKey(key safejs.Value) (*UintRequest, error) {
  32. reqValue, err := b.jsObjectStore.Call("count", key)
  33. if err != nil {
  34. return nil, tryAsDOMException(err)
  35. }
  36. req := wrapRequest(b.txn, reqValue)
  37. return newUintRequest(req), nil
  38. }
  39. // CountRange returns a UintRequest, and, in a separate thread, returns the total number of records that match the provided KeyRange.
  40. func (b *baseObjectStore) CountRange(keyRange *KeyRange) (*UintRequest, error) {
  41. reqValue, err := b.jsObjectStore.Call("count", keyRange.jsKeyRange)
  42. if err != nil {
  43. return nil, tryAsDOMException(err)
  44. }
  45. req := wrapRequest(b.txn, reqValue)
  46. return newUintRequest(req), nil
  47. }
  48. // GetAllKeys returns an ArrayRequest that retrieves record keys for all objects in the object store or index.
  49. func (b *baseObjectStore) GetAllKeys() (*ArrayRequest, error) {
  50. reqValue, err := b.jsObjectStore.Call("getAllKeys")
  51. if err != nil {
  52. return nil, tryAsDOMException(err)
  53. }
  54. req := wrapRequest(b.txn, reqValue)
  55. return newArrayRequest(req), nil
  56. }
  57. // GetAllKeysRange returns an ArrayRequest that retrieves record keys for all objects in the object store or index matching the specified query. If maxCount is 0, retrieves all objects matching the query.
  58. func (b *baseObjectStore) GetAllKeysRange(query *KeyRange, maxCount uint) (*ArrayRequest, error) {
  59. args := []interface{}{query.jsKeyRange}
  60. if maxCount > 0 {
  61. args = append(args, maxCount)
  62. }
  63. reqValue, err := b.jsObjectStore.Call("getAllKeys", args...)
  64. if err != nil {
  65. return nil, tryAsDOMException(err)
  66. }
  67. req := wrapRequest(b.txn, reqValue)
  68. return newArrayRequest(req), nil
  69. }
  70. // Get returns a Request, and, in a separate thread, returns the objects selected by the specified key. This is for retrieving specific records from an object store or index.
  71. func (b *baseObjectStore) Get(key safejs.Value) (*Request, error) {
  72. reqValue, err := b.jsObjectStore.Call("get", key)
  73. if err != nil {
  74. return nil, tryAsDOMException(err)
  75. }
  76. return wrapRequest(b.txn, reqValue), nil
  77. }
  78. // GetKey returns a Request, and, in a separate thread retrieves and returns the record key for the object matching the specified parameter.
  79. func (b *baseObjectStore) GetKey(value safejs.Value) (*Request, error) {
  80. reqValue, err := b.jsObjectStore.Call("getKey", value)
  81. if err != nil {
  82. return nil, tryAsDOMException(err)
  83. }
  84. return wrapRequest(b.txn, reqValue), nil
  85. }
  86. // OpenCursor returns a CursorWithValueRequest, and, in a separate thread, returns a new CursorWithValue. Used for iterating through an object store or index by primary key with a cursor.
  87. func (b *baseObjectStore) OpenCursor(direction CursorDirection) (*CursorWithValueRequest, error) {
  88. reqValue, err := b.jsObjectStore.Call("openCursor", safejs.Null(), direction.jsValue())
  89. if err != nil {
  90. return nil, tryAsDOMException(err)
  91. }
  92. req := wrapRequest(b.txn, reqValue)
  93. return newCursorWithValueRequest(req), nil
  94. }
  95. // OpenCursorKey is the same as OpenCursor, but opens a cursor over the given key instead.
  96. func (b *baseObjectStore) OpenCursorKey(key safejs.Value, direction CursorDirection) (*CursorWithValueRequest, error) {
  97. reqValue, err := b.jsObjectStore.Call("openCursor", key, direction.jsValue())
  98. if err != nil {
  99. return nil, tryAsDOMException(err)
  100. }
  101. req := wrapRequest(b.txn, reqValue)
  102. return newCursorWithValueRequest(req), nil
  103. }
  104. // OpenCursorRange is the same as OpenCursor, but opens a cursor over the given range instead.
  105. func (b *baseObjectStore) OpenCursorRange(keyRange *KeyRange, direction CursorDirection) (*CursorWithValueRequest, error) {
  106. reqValue, err := b.jsObjectStore.Call("openCursor", keyRange.jsKeyRange, direction.jsValue())
  107. if err != nil {
  108. return nil, tryAsDOMException(err)
  109. }
  110. req := wrapRequest(b.txn, reqValue)
  111. return newCursorWithValueRequest(req), nil
  112. }
  113. // OpenKeyCursor returns a CursorRequest, and, in a separate thread, returns a new Cursor. Used for iterating through all keys in an object store or index.
  114. func (b *baseObjectStore) OpenKeyCursor(direction CursorDirection) (*CursorRequest, error) {
  115. reqValue, err := b.jsObjectStore.Call("openKeyCursor", safejs.Null(), direction.jsValue())
  116. if err != nil {
  117. return nil, tryAsDOMException(err)
  118. }
  119. req := wrapRequest(b.txn, reqValue)
  120. return newCursorRequest(req), nil
  121. }
  122. // OpenKeyCursorKey is the same as OpenKeyCursor, but opens a cursor over the given key instead.
  123. func (b *baseObjectStore) OpenKeyCursorKey(key safejs.Value, direction CursorDirection) (*CursorRequest, error) {
  124. reqValue, err := b.jsObjectStore.Call("openKeyCursor", key, direction.jsValue())
  125. if err != nil {
  126. return nil, tryAsDOMException(err)
  127. }
  128. req := wrapRequest(b.txn, reqValue)
  129. return newCursorRequest(req), nil
  130. }
  131. // OpenKeyCursorRange is the same as OpenKeyCursor, but opens a cursor over the given key range instead.
  132. func (b *baseObjectStore) OpenKeyCursorRange(keyRange *KeyRange, direction CursorDirection) (*CursorRequest, error) {
  133. reqValue, err := b.jsObjectStore.Call("openKeyCursor", keyRange.jsKeyRange, direction.jsValue())
  134. if err != nil {
  135. return nil, tryAsDOMException(err)
  136. }
  137. req := wrapRequest(b.txn, reqValue)
  138. return newCursorRequest(req), nil
  139. }