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.

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