github.com/rpdict/ponzu@v0.10.1-0.20190226054626-477f29d6bf5e/system/db/init.go (about) 1 // Package db contains all interfaces to the databases used by Ponzu, including 2 // exported functions to easily manage addons, users, indices, search, content, 3 // and configuration. 4 package db 5 6 import ( 7 "log" 8 9 "github.com/rpdict/ponzu/system/item" 10 "github.com/rpdict/ponzu/system/search" 11 12 "github.com/boltdb/bolt" 13 "github.com/nilslice/jwt" 14 ) 15 16 var ( 17 store *bolt.DB 18 19 buckets = []string{ 20 "__config", "__users", 21 "__addons", "__uploads", 22 "__contentIndex", 23 } 24 25 bucketsToAdd []string 26 ) 27 28 // Store provides access to the underlying *bolt.DB store 29 func Store() *bolt.DB { 30 return store 31 } 32 33 // Close exports the abillity to close our db file. Should be called with defer 34 // after call to Init() from the same place. 35 func Close() { 36 err := store.Close() 37 if err != nil { 38 log.Println(err) 39 } 40 } 41 42 // Init creates a db connection, initializes db with required info, sets secrets 43 func Init() { 44 if store != nil { 45 return 46 } 47 48 var err error 49 store, err = bolt.Open("system.db", 0666, nil) 50 if err != nil { 51 log.Fatalln(err) 52 } 53 54 err = store.Update(func(tx *bolt.Tx) error { 55 // initialize db with all content type buckets & sorted bucket for type 56 for t := range item.Types { 57 _, err := tx.CreateBucketIfNotExists([]byte(t)) 58 if err != nil { 59 return err 60 } 61 62 _, err = tx.CreateBucketIfNotExists([]byte(t + "__sorted")) 63 if err != nil { 64 return err 65 } 66 } 67 68 // init db with other buckets as needed 69 buckets = append(buckets, bucketsToAdd...) 70 71 for _, name := range buckets { 72 _, err := tx.CreateBucketIfNotExists([]byte(name)) 73 if err != nil { 74 return err 75 } 76 } 77 78 return nil 79 }) 80 if err != nil { 81 log.Fatalln("Coudn't initialize db with buckets.", err) 82 } 83 84 err = LoadCacheConfig() 85 if err != nil { 86 log.Fatalln("Failed to load config cache.", err) 87 } 88 89 clientSecret := ConfigCache("client_secret").(string) 90 91 if clientSecret != "" { 92 jwt.Secret([]byte(clientSecret)) 93 } 94 95 // invalidate cache on system start 96 err = InvalidateCache() 97 if err != nil { 98 log.Fatalln("Failed to invalidate cache.", err) 99 } 100 } 101 102 // AddBucket adds a bucket to be created if it doesn't already exist 103 func AddBucket(name string) { 104 bucketsToAdd = append(bucketsToAdd, name) 105 } 106 107 // InitSearchIndex initializes Search Index for search to be functional 108 // This was moved out of db.Init and put to main(), because addon checker was initializing db together with 109 // search indexing initialisation in time when there were no item.Types defined so search index was always 110 // empty when using addons. We still have no guarentee whatsoever that item.Types is defined 111 // Should be called from a goroutine after SetContent is successful (SortContent requirement) 112 func InitSearchIndex() { 113 for t := range item.Types { 114 err := search.MapIndex(t) 115 if err != nil { 116 log.Fatalln(err) 117 return 118 } 119 SortContent(t) 120 } 121 } 122 123 // SystemInitComplete checks if there is at least 1 admin user in the db which 124 // would indicate that the system has been configured to the minimum required. 125 func SystemInitComplete() bool { 126 complete := false 127 128 err := store.View(func(tx *bolt.Tx) error { 129 users := tx.Bucket([]byte("__users")) 130 if users == nil { 131 return bolt.ErrBucketNotFound 132 } 133 134 err := users.ForEach(func(k, v []byte) error { 135 complete = true 136 return nil 137 }) 138 if err != nil { 139 return err 140 } 141 142 return nil 143 }) 144 if err != nil { 145 complete = false 146 log.Fatalln(err) 147 } 148 149 return complete 150 }