database_core.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //go:build !mipsle && !riscv64
  2. // +build !mipsle,!riscv64
  3. package database
  4. import (
  5. "encoding/json"
  6. "errors"
  7. "log"
  8. "sync"
  9. "github.com/boltdb/bolt"
  10. )
  11. func newDatabase(dbfile string, readOnlyMode bool) (*Database, error) {
  12. db, err := bolt.Open(dbfile, 0600, nil)
  13. if err != nil {
  14. return nil, err
  15. }
  16. tableMap := sync.Map{}
  17. //Build the table list from database
  18. err = db.View(func(tx *bolt.Tx) error {
  19. return tx.ForEach(func(name []byte, _ *bolt.Bucket) error {
  20. tableMap.Store(string(name), "")
  21. return nil
  22. })
  23. })
  24. return &Database{
  25. Db: db,
  26. Tables: tableMap,
  27. ReadOnly: readOnlyMode,
  28. }, err
  29. }
  30. //Dump the whole db into a log file
  31. func (d *Database) dump(filename string) ([]string, error) {
  32. results := []string{}
  33. d.Tables.Range(func(tableName, v interface{}) bool {
  34. entries, err := d.ListTable(tableName.(string))
  35. if err != nil {
  36. log.Println("Reading table " + tableName.(string) + " failed: " + err.Error())
  37. return false
  38. }
  39. for _, keypairs := range entries {
  40. results = append(results, string(keypairs[0])+":"+string(keypairs[1])+"\n")
  41. }
  42. return true
  43. })
  44. return results, nil
  45. }
  46. //Create a new table
  47. func (d *Database) newTable(tableName string) error {
  48. if d.ReadOnly == true {
  49. return errors.New("Operation rejected in ReadOnly mode")
  50. }
  51. err := d.Db.(*bolt.DB).Update(func(tx *bolt.Tx) error {
  52. _, err := tx.CreateBucketIfNotExists([]byte(tableName))
  53. if err != nil {
  54. return err
  55. }
  56. return nil
  57. })
  58. d.Tables.Store(tableName, "")
  59. return err
  60. }
  61. //Check is table exists
  62. func (d *Database) tableExists(tableName string) bool {
  63. if _, ok := d.Tables.Load(tableName); ok {
  64. return true
  65. }
  66. return false
  67. }
  68. //Drop the given table
  69. func (d *Database) dropTable(tableName string) error {
  70. if d.ReadOnly == true {
  71. return errors.New("Operation rejected in ReadOnly mode")
  72. }
  73. err := d.Db.(*bolt.DB).Update(func(tx *bolt.Tx) error {
  74. err := tx.DeleteBucket([]byte(tableName))
  75. if err != nil {
  76. return err
  77. }
  78. return nil
  79. })
  80. return err
  81. }
  82. //Write to table
  83. func (d *Database) write(tableName string, key string, value interface{}) error {
  84. if d.ReadOnly {
  85. return errors.New("Operation rejected in ReadOnly mode")
  86. }
  87. jsonString, err := json.Marshal(value)
  88. if err != nil {
  89. return err
  90. }
  91. err = d.Db.(*bolt.DB).Update(func(tx *bolt.Tx) error {
  92. _, err := tx.CreateBucketIfNotExists([]byte(tableName))
  93. if err != nil {
  94. return err
  95. }
  96. b := tx.Bucket([]byte(tableName))
  97. err = b.Put([]byte(key), jsonString)
  98. return err
  99. })
  100. return err
  101. }
  102. func (d *Database) read(tableName string, key string, assignee interface{}) error {
  103. err := d.Db.(*bolt.DB).View(func(tx *bolt.Tx) error {
  104. b := tx.Bucket([]byte(tableName))
  105. v := b.Get([]byte(key))
  106. json.Unmarshal(v, &assignee)
  107. return nil
  108. })
  109. return err
  110. }
  111. func (d *Database) keyExists(tableName string, key string) bool {
  112. resultIsNil := false
  113. if !d.TableExists(tableName) {
  114. //Table not exists. Do not proceed accessing key
  115. log.Println("[DB] ERROR: Requesting key from table that didn't exist!!!")
  116. return false
  117. }
  118. err := d.Db.(*bolt.DB).View(func(tx *bolt.Tx) error {
  119. b := tx.Bucket([]byte(tableName))
  120. v := b.Get([]byte(key))
  121. if v == nil {
  122. resultIsNil = true
  123. }
  124. return nil
  125. })
  126. if err != nil {
  127. return false
  128. } else {
  129. if resultIsNil {
  130. return false
  131. } else {
  132. return true
  133. }
  134. }
  135. }
  136. func (d *Database) delete(tableName string, key string) error {
  137. if d.ReadOnly {
  138. return errors.New("Operation rejected in ReadOnly mode")
  139. }
  140. err := d.Db.(*bolt.DB).Update(func(tx *bolt.Tx) error {
  141. tx.Bucket([]byte(tableName)).Delete([]byte(key))
  142. return nil
  143. })
  144. return err
  145. }
  146. func (d *Database) listTable(tableName string) ([][][]byte, error) {
  147. var results [][][]byte
  148. err := d.Db.(*bolt.DB).View(func(tx *bolt.Tx) error {
  149. b := tx.Bucket([]byte(tableName))
  150. c := b.Cursor()
  151. for k, v := c.First(); k != nil; k, v = c.Next() {
  152. results = append(results, [][]byte{k, v})
  153. }
  154. return nil
  155. })
  156. return results, err
  157. }
  158. func (d *Database) close() {
  159. d.Db.(*bolt.DB).Close()
  160. }