Beispiel #1
0
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")
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
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)
	}
}
Beispiel #4
0
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)
	}
}