ttimt/Short_Cutteer

View on GitHub
database.go

Summary

Maintainability
A
0 mins
Test Coverage
package main

import (
    "encoding/json"
    "fmt"

    "github.com/HouzuoGuo/tiedot/db"
    "github.com/HouzuoGuo/tiedot/dberr"
)

const (
    dbPath                          = "db"
    dbCollectionCommand             = "Commands"
    dbCollectionCommandFieldTitle   = "title"
    dbCollectionCommandFieldCommand = "command"
)

var (
    myDB               *db.DB
    collectionCommands *db.Col
)

// Open the DB from the path
func initializeDB() {
    // Load DB
    // Create or open the database
    var err error
    if myDB, err = db.OpenDB(dbPath); err != nil {
        panic(err)
    }

    // Setup DB
    setupDB()
}

// Initialize collections and indexes
func setupDB() {
    // Track if command collection exists
    existCommandCollection := myDB.ColExists(dbCollectionCommand)

    // Create collection 'Commands' if does not exists
    if !existCommandCollection {
        // Create collection "Commands"
        if err := myDB.Create(dbCollectionCommand); err != nil {
            panic(err)
        }
    }

    // Select collection 'Commands' for usage
    collectionCommands = myDB.Use(dbCollectionCommand)

    // Create index "title" for querying in 'Commands'
    if !existCommandCollection {
        if err := collectionCommands.Index([]string{dbCollectionCommandFieldTitle}); err != nil {
            panic(err)
        }
    }

    // Read from DB and import to in memory struct
    readAndImportFromDB()
}

// Reset collection by the given name in DB: resetDBCollection
func _(nameCollection string) {
    // Drop the collection
    _ = myDB.Drop(nameCollection)
}

// Read all Commands from DB and import to in memory struct
func readAndImportFromDB() {
    // Temporary store unmarshalled Command
    var c Command

    // Read all documents
    collectionCommands.ForEachDoc(func(id int, doc []byte) (moveOn bool) {
        // Convert Command from stored JSON format
        _ = json.Unmarshal(doc, &c)

        // Add newly read Command to in memory userCommands struct
        updateUserCommand(c)

        // Continue to the next item in the collection
        return true
    })

    // Get all unique user commands length
    updateAllCommandLength()
}

// Write data to the specified collection
func writeToDB(collection *db.Col, data map[string]interface{}) {
    if _, err := collection.Insert(data); err != nil {
        panic(err)
    }
}

// Write a command to the Command collection
func writeCommandToDB(title, description, command, output string) {
    writeToDB(collectionCommands, map[string]interface{}{
        dbCollectionCommandFieldTitle: title,
        "description":                 description,
        "command":                     command,
        "output":                      output,
    })
}

// Delete a command from Command collection
func deleteCommandFromDB(title string) {
    // Get the Command with the title
    queryResult := retrieveCommandsFromTitle(title)

    for id := range queryResult {
        // Get the commandStr(string) of the Command to use for deleting the in memory commandStr in userCommands struct
        commandToBeDeleted, _ := collectionCommands.Read(id)
        commandStr := commandToBeDeleted[dbCollectionCommandFieldCommand].(string)

        // Delete command from collection and check for error
        if err := collectionCommands.Delete(id); dberr.Type(err) == dberr.ErrorNoDoc {
            fmt.Println("The document was already deleted")
        } else if err != nil {
            panic(err)
        } else {
            // Delete from in memory struct userCommands
            delete(userCommands, commandStr)
        }
    }
}

// Return Commands by querying with the specified title
func retrieveCommandsFromTitle(title string) map[int]struct{} {
    // Store the query result
    queryResult := make(map[int]struct{})

    // Retrieve the query string
    query := query(title, dbCollectionCommandFieldTitle)

    // Execute the query
    if err := db.EvalQuery(query, collectionCommands, &queryResult); err != nil {
        panic(err)
    }

    return queryResult
}

// Create a query to find a specific value from the specified index
// Index must first be set in setupDB()
func query(value, index string) (query interface{}) {
    // Create the query with the index
    _ = json.Unmarshal([]byte(`[{"eq": "`+value+`", "in": ["`+index+`"]}]`), &query)

    return
}