You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
5.0 KiB

  1. package remotedb
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/tendermint/tmlibs/db"
  6. "github.com/tendermint/tmlibs/grpcdb"
  7. protodb "github.com/tendermint/tmlibs/proto"
  8. )
  9. type RemoteDB struct {
  10. ctx context.Context
  11. dc protodb.DBClient
  12. }
  13. func NewRemoteDB(serverAddr string, serverKey string) (*RemoteDB, error) {
  14. return newRemoteDB(grpcdb.NewClient(serverAddr, serverKey))
  15. }
  16. func newRemoteDB(gdc protodb.DBClient, err error) (*RemoteDB, error) {
  17. if err != nil {
  18. return nil, err
  19. }
  20. return &RemoteDB{dc: gdc, ctx: context.Background()}, nil
  21. }
  22. type Init struct {
  23. Dir string
  24. Name string
  25. Type string
  26. }
  27. func (rd *RemoteDB) InitRemote(in *Init) error {
  28. _, err := rd.dc.Init(rd.ctx, &protodb.Init{Dir: in.Dir, Type: in.Type, Name: in.Name})
  29. return err
  30. }
  31. var _ db.DB = (*RemoteDB)(nil)
  32. // Close is a noop currently
  33. func (rd *RemoteDB) Close() {
  34. }
  35. func (rd *RemoteDB) Delete(key []byte) {
  36. if _, err := rd.dc.Delete(rd.ctx, &protodb.Entity{Key: key}); err != nil {
  37. panic(fmt.Sprintf("RemoteDB.Delete: %v", err))
  38. }
  39. }
  40. func (rd *RemoteDB) DeleteSync(key []byte) {
  41. if _, err := rd.dc.DeleteSync(rd.ctx, &protodb.Entity{Key: key}); err != nil {
  42. panic(fmt.Sprintf("RemoteDB.DeleteSync: %v", err))
  43. }
  44. }
  45. func (rd *RemoteDB) Set(key, value []byte) {
  46. if _, err := rd.dc.Set(rd.ctx, &protodb.Entity{Key: key, Value: value}); err != nil {
  47. panic(fmt.Sprintf("RemoteDB.Set: %v", err))
  48. }
  49. }
  50. func (rd *RemoteDB) SetSync(key, value []byte) {
  51. if _, err := rd.dc.SetSync(rd.ctx, &protodb.Entity{Key: key, Value: value}); err != nil {
  52. panic(fmt.Sprintf("RemoteDB.SetSync: %v", err))
  53. }
  54. }
  55. func (rd *RemoteDB) Get(key []byte) []byte {
  56. res, err := rd.dc.Get(rd.ctx, &protodb.Entity{Key: key})
  57. if err != nil {
  58. panic(fmt.Sprintf("RemoteDB.Get error: %v", err))
  59. }
  60. return res.Value
  61. }
  62. func (rd *RemoteDB) Has(key []byte) bool {
  63. res, err := rd.dc.Has(rd.ctx, &protodb.Entity{Key: key})
  64. if err != nil {
  65. panic(fmt.Sprintf("RemoteDB.Has error: %v", err))
  66. }
  67. return res.Exists
  68. }
  69. func (rd *RemoteDB) ReverseIterator(start, end []byte) db.Iterator {
  70. dic, err := rd.dc.ReverseIterator(rd.ctx, &protodb.Entity{Start: start, End: end})
  71. if err != nil {
  72. panic(fmt.Sprintf("RemoteDB.Iterator error: %v", err))
  73. }
  74. return makeReverseIterator(dic)
  75. }
  76. // TODO: Implement NewBatch
  77. func (rd *RemoteDB) NewBatch() db.Batch {
  78. panic("Unimplemented")
  79. }
  80. // TODO: Implement Print when db.DB implements a method
  81. // to print to a string and not db.Print to stdout.
  82. func (rd *RemoteDB) Print() {
  83. panic("Unimplemented")
  84. }
  85. func (rd *RemoteDB) Stats() map[string]string {
  86. stats, err := rd.dc.Stats(rd.ctx, &protodb.Nothing{})
  87. if err != nil {
  88. panic(fmt.Sprintf("RemoteDB.Stats error: %v", err))
  89. }
  90. if stats == nil {
  91. return nil
  92. }
  93. return stats.Data
  94. }
  95. func (rd *RemoteDB) Iterator(start, end []byte) db.Iterator {
  96. dic, err := rd.dc.Iterator(rd.ctx, &protodb.Entity{Start: start, End: end})
  97. if err != nil {
  98. panic(fmt.Sprintf("RemoteDB.Iterator error: %v", err))
  99. }
  100. return makeIterator(dic)
  101. }
  102. func makeIterator(dic protodb.DB_IteratorClient) db.Iterator {
  103. return &iterator{dic: dic}
  104. }
  105. func makeReverseIterator(dric protodb.DB_ReverseIteratorClient) db.Iterator {
  106. return &reverseIterator{dric: dric}
  107. }
  108. type reverseIterator struct {
  109. dric protodb.DB_ReverseIteratorClient
  110. cur *protodb.Iterator
  111. }
  112. var _ db.Iterator = (*iterator)(nil)
  113. func (rItr *reverseIterator) Valid() bool {
  114. return rItr.cur != nil && rItr.cur.Valid
  115. }
  116. func (rItr *reverseIterator) Domain() (start, end []byte) {
  117. if rItr.cur == nil || rItr.cur.Domain == nil {
  118. return nil, nil
  119. }
  120. return rItr.cur.Domain.Start, rItr.cur.Domain.End
  121. }
  122. // Next advances the current reverseIterator
  123. func (rItr *reverseIterator) Next() {
  124. var err error
  125. rItr.cur, err = rItr.dric.Recv()
  126. if err != nil {
  127. panic(fmt.Sprintf("RemoteDB.ReverseIterator.Next error: %v", err))
  128. }
  129. }
  130. func (rItr *reverseIterator) Key() []byte {
  131. if rItr.cur == nil {
  132. return nil
  133. }
  134. return rItr.cur.Key
  135. }
  136. func (rItr *reverseIterator) Value() []byte {
  137. if rItr.cur == nil {
  138. return nil
  139. }
  140. return rItr.cur.Value
  141. }
  142. func (rItr *reverseIterator) Close() {
  143. }
  144. // iterator implements the db.Iterator by retrieving
  145. // streamed iterators from the remote backend as
  146. // needed. It is NOT safe for concurrent usage,
  147. // matching the behavior of other iterators.
  148. type iterator struct {
  149. dic protodb.DB_IteratorClient
  150. cur *protodb.Iterator
  151. }
  152. var _ db.Iterator = (*iterator)(nil)
  153. func (itr *iterator) Valid() bool {
  154. return itr.cur != nil && itr.cur.Valid
  155. }
  156. func (itr *iterator) Domain() (start, end []byte) {
  157. if itr.cur == nil || itr.cur.Domain == nil {
  158. return nil, nil
  159. }
  160. return itr.cur.Domain.Start, itr.cur.Domain.End
  161. }
  162. // Next advances the current iterator
  163. func (itr *iterator) Next() {
  164. var err error
  165. itr.cur, err = itr.dic.Recv()
  166. if err != nil {
  167. panic(fmt.Sprintf("RemoteDB.Iterator.Next error: %v", err))
  168. }
  169. }
  170. func (itr *iterator) Key() []byte {
  171. if itr.cur == nil {
  172. return nil
  173. }
  174. return itr.cur.Key
  175. }
  176. func (itr *iterator) Value() []byte {
  177. if itr.cur == nil {
  178. return nil
  179. }
  180. return itr.cur.Value
  181. }
  182. func (itr *iterator) Close() {
  183. // TODO: Shut down the iterator
  184. }