func dbStart(dbFile string) { lib.Trace(0, "dbStart Begin") var err error db, err = bolt.Open(dbFile, 0600, nil) if err != nil { log.Fatal("db open fail", err) } dbWriteChan = make(chan request, 100) go dbWriteDispatch() // if 1st run for db, following will create bkts for startup db.Update(func(tx *bolt.Tx) error { _, err1 := tx.CreateBucketIfNotExists(bs("books")) _, err2 := tx.CreateBucketIfNotExists(bs("control")) return lib.CheckErrs(errFatal, "db startup error", err1, err2) }) lib.Trace(0, "dbStart Complete") }
func (this *Tab) process(action string, resultChan chan Result) { switch action { case "addTab": this.Id = getNextid() this.LastAccessTime = time.Now() this.ETag = fmt.Sprint(time.Now().UnixNano()) if bookTabs[this.Bookid] == nil { log.Fatal("addTab - book tabMap not found for bookid =", this.Bookid) } bookTabs[this.Bookid][this.Id] = this tabPrevids[this.Id] = make(previdMap) // see previd.go dbWrite("saveNewTab", this, resultChan) // save new Tab to db case "saveNewTab": var err, err1, err2, err3 error var k, v []byte var bktBook, bktTabs, bktTab *bolt.Bucket tx, _ := db.Begin(true) bumpSequentialid(tx) // required for all db doc adds // --- add new tab to "tabs" bkt inside parent book bkt --- bktBook = openBook(tx, this.Bookid) bktTabs = openTabs(bktBook) k = bs(this.Id) v, err1 = json.Marshal(this) err2 = bktTabs.Put(k, v) // --- create bkt for this tab to hold its notes & Commit --- bktBook.CreateBucket(bs("tab_" + this.Id)) err3 = tx.Commit() if err = lib.CheckErrs(errNotFatal, action, err1, err2, err3); err != nil { tx.Rollback() log.Fatal("Fatal DB Error-creating new tab bkts, Ending Program") } // --- create "notes","previds" bkts inside new tab's bkt & Commit --- tx, _ = db.Begin(true) bktBook = openBook(tx, this.Bookid) bktTab = openTab(bktBook, this.Id) _, err1 = bktTab.CreateBucket(bs("notes")) bktTab.CreateBucket(bs("previds")) err2 = tx.Commit() if err = lib.CheckErrs(errNotFatal, action, err1, err2); err != nil { tx.Rollback() log.Fatal("Fatal DB Error-creating notes bkt, Ending Program") } resultChan <- Result{DataOk, this.Id} case "changeTab": var tab *Tab if tab = bookTabs[this.Bookid][this.Id]; tab == nil { log.Fatal("changeTab, tab not found (bookid, tabid)", this.Bookid, this.Id) } tab.TabName = this.TabName tab.TabNumber = this.TabNumber tab.Hidden = this.Hidden tab.LastAccessTime = time.Now() tab.ETag = fmt.Sprint(time.Now().UnixNano()) dbWrite("saveTabChange", this, resultChan) // save Tab to db case "saveTabChange": db.Update(func(tx *bolt.Tx) error { bktBook := openBook(tx, this.Bookid) bktTabs := openTabs(bktBook) k := bs(this.Id) v, err1 := json.Marshal(this) err2 := bktTabs.Put(k, v) return lib.CheckErrs(errFatal, action, err1, err2) }) resultChan <- Result{DataOk, nil} default: log.Fatal("data Tab.process() invalid action ", action) } }
func (this *NoteParms) process(action string, resultChan chan Result) { var tab *Tab if tab = bookTabs[this.Bookid][this.Tabid]; tab == nil { log.Fatal("NoteParms.process Tab Not Found (bookid, tabid)", this.Bookid, this.Tabid) } // all NoteParm actions are changes, so ETag must be updated tab.ETag = fmt.Sprint(time.Now().UnixNano()) tab.LastAccessTime = time.Now() switch action { case "addNote": this.Note.Id = getNextid() previdMap := tabPrevids[this.Tabid] this.OrderChanges = previdMap.add(this.Note.Id, this.Previd) dbWrite("saveNewNote", this, resultChan) case "saveNewNote": var err1, err2, err3 error var k, v []byte db.Update(func(tx *bolt.Tx) error { bumpSequentialid(tx) // required for all database adds bktBook := openBook(tx, this.Bookid) _, bktNotes, bktPrevids := openTabAll(bktBook, this.Tabid) k = bs(this.Note.Id) v, err1 = json.Marshal(this.Note) err2 = bktNotes.Put(k, v) for noteid, previd := range this.OrderChanges { if err3 = bktPrevids.Put(bs(noteid), bs(previd)); err3 != nil { break } } return lib.CheckErrs(errFatal, action, err1, err2, err3) }) resultChan <- Result{DataOk, nil} case "changeNote": dbWrite("saveNoteChange", this, resultChan) case "saveNoteChange": db.Update(func(tx *bolt.Tx) error { bktBook := openBook(tx, this.Bookid) bktTab := openTab(bktBook, this.Tabid) bktNotes := openNotes(bktTab) k := bs(this.Note.Id) v, err1 := json.Marshal(this.Note) err2 := bktNotes.Put(k, v) return lib.CheckErrs(errFatal, action, err1, err2) }) resultChan <- Result{DataOk, nil} case "positionNote": // delete, add back in new position previdMap := tabPrevids[this.Tabid] this.OrderChanges = previdMap.delete(this.Note.Id) addChanges := previdMap.add(this.Note.Id, this.Previd) for noteid, previd := range addChanges { // merge addChanges, replacing delete with add entry this.OrderChanges[noteid] = previd } dbWrite("savePositionNote", this, resultChan) case "savePositionNote": var err1 error db.Update(func(tx *bolt.Tx) error { bktBook := openBook(tx, this.Bookid) bktTab := openTab(bktBook, this.Tabid) bktPrevids := openPrevids(bktTab) for noteid, previd := range this.OrderChanges { if previd == "delete" { err1 = bktPrevids.Delete(bs(noteid)) } else { err1 = bktPrevids.Put(bs(noteid), bs(previd)) } if err1 != nil { break } } return lib.CheckErrs(errFatal, action, err1) }) resultChan <- Result{DataOk, nil} case "deleteNote": previdMap := tabPrevids[this.Tabid] this.OrderChanges = previdMap.delete(this.Note.Id) dbWrite("saveDeleteNote", this, resultChan) case "saveDeleteNote": var err1, err2 error db.Update(func(tx *bolt.Tx) error { bktBook := openBook(tx, this.Bookid) _, bktNotes, bktPrevids := openTabAll(bktBook, this.Tabid) err1 = bktNotes.Delete(bs(this.Note.Id)) for noteid, previd := range this.OrderChanges { if previd == "delete" { err2 = bktPrevids.Delete(bs(noteid)) } else { err2 = bktPrevids.Put(bs(noteid), bs(previd)) } if err2 != nil { break } } return lib.CheckErrs(errFatal, action, err1, err2) }) resultChan <- Result{DataOk, nil} default: log.Fatal("data NoteParms.process() invalid action ", action) } }
func (this *Book) process(action string, resultChan chan Result) { switch action { // getBook options: // if Id is loaded, match on Id // if AccessCode is loaded, match on AccessCode & BookName // if only BookName is loaded, match on BookName case "getBook": // all book docs loaded into bookMap at startup var book *Book if this.Id != "" { // match on book id book = bookMap[this.Id] } else if this.AccessCode != "" { // match on AccessCode and BookName for _, v := range bookMap { if v.AccessCode == this.AccessCode { if v.PlainBookName == lib.PlainString(this.BookName) { book = v break } } } } else { // match on BookName matchBookName := lib.PlainString(this.BookName) for _, v := range bookMap { if v.PlainBookName == matchBookName { book = v break } } } if book != nil { this.Id = book.Id this.BookName = book.BookName this.Email = book.Email this.AccessCode = book.AccessCode this.PlainBookName = book.PlainBookName resultChan <- Result{DataOk, nil} } else { resultChan <- Result{DataNotFound, "Book Not Found"} } case "addBook": // check for dupe book name newName := lib.PlainString(this.BookName) for _, v := range bookMap { if newName == v.PlainBookName { resultChan <- Result{DataDuplicate, "Duplicate - Notebook Name Already Exists"} lib.Trace(0, "dupe book name", newName) return } } this.Id = getNextid() this.PlainBookName = newName bookMap[this.Id] = this bookTabs[this.Id] = make(tabMap) dbWrite("saveNewBook", this, resultChan) // save new Book to db case "saveNewBook": var err, err1, err2, err3 error var k, v []byte tx, _ := db.Begin(true) bumpSequentialid(tx) // required for all db adds // --- save book to "books" bkt ----------------------- bktBooks := openBooks(tx) k = bs(this.Id) v, err1 = json.Marshal(this) err2 = bktBooks.Put(k, v) // --- create bkt to hold this book's data & Commit --- tx.CreateBucket(bs("book_" + this.Id)) err3 = tx.Commit() if err = lib.CheckErrs(errNotFatal, action, err1, err2, err3); err != nil { tx.Rollback() log.Fatal("Fatal DB Error-creating book bkts, Ending Program") } // --- create "tabs" bkt inside this book's bkt & Commit --- tx, _ = db.Begin(true) bktBook := openBook(tx, this.Id) _, err1 = bktBook.CreateBucket(bs("tabs")) err2 = tx.Commit() if err = lib.CheckErrs(errNotFatal, action, err1, err2); err != nil { tx.Rollback() log.Fatal("Fatal DB Error-creating tabs bkt, Ending Program") } resultChan <- Result{DataOk, this.Id} case "saveBookChange": // not currently used db.Update(func(tx *bolt.Tx) error { bktBooks := openBooks(tx) k := bs(this.Id) v, _ := json.Marshal(this) err := bktBooks.Put(k, v) if err != nil { log.Fatal("book not changed", err) } return nil }) default: log.Fatal("Book.process action invalid", action) } }