simdb: A Simple JSON DB in GO

Some days ago I decided to learn Go. Go is pretty easy to learn and and an experienced dev could learn its syntax and semantics in a couple of hours. To completely learn a language, I normally write a small app in that language. So, in my free time, I rewrote the expense service I created in Node.js using Go. This whole exercise allowed me to learn Go in detail.

For me, Go looks to be a great, yet simple language with static type checking. It seems like I will be using Go for my future RPi projects rather than Nodejs. In RPi, I often use a simple JSON file as a DB to store, retrieve, and update execution rules, sensor details, etc. In Node.js I use tingodb, but I couldn't find something similar in Go, so I decided to write one, and is called simdb, a simple JSON DB.

Using simdb, I can persist stuct or retrieve or update or delete them from the JSON DB. The DB file created by simdb is a simple JSON file. Let's see some of the functions in simdb.

Create a new instance of the DB: 

driver, err:=db.New("customer")

Insert a new customer to the DB: 

 customer:=Customer {
        CustID:"CUST1",
        Name:"sarouje",
        Address: "address",
        Contact: Contact {
            Phone:"45533355",
            Email:"someone@gmail.com",
        },
    }

    err=driver.Insert(customer)
    if(err!=nil){
        panic(err)
    }

Get a customer:

   err=driver.Open(Customer{}).Where("custid","=","CUST1").First().AsEntity(&customerFirst)
    if(err!=nil){
        panic(err)
    }

Update a customer:

customerFirst.Name="Sony Arouje"
err=driver.Update(customerFirst)
if(err!=nil){
    panic(err)
}

Delete a customer: 

toDel:=Customer{
        CustID:"CUST1",
    }
    err=driver.Delete(toDel)
    if(err!=nil){
        panic(err)
    }

The Update and Delete operations use the ID field of the struct to perform their operations.

Let's see the full code:

package main

import (
    "github.com/sonyarouje/simdb/db"
    "fmt"
)

type Customer struct {
    CustID string `json:"custid"`
    Name string `json:"name"`
    Address string `json:"address"`
    Contact Contact
}

type Contact struct {
    Phone string `json:"phone"`
    Email string `json:"email"`
}
//ID any struct that needs to persist should implement this function defined 
//in Entity interface.
func (c Customer) ID() (jsonField string, value interface{}) {
    value=c.CustID
    jsonField="custid"
    return
}

func main(){
    fmt.Println("starting....")

    driver, err:=db.New("dbs")

    if(err!=nil){
        panic(err)
    }

    customer:=Customer {
        CustID:"CUST1",
        Name:"sarouje",
        Address: "address",
        Contact: Contact {
            Phone:"45533355",
            Email:"someone@gmail.com",
        },
    }
    //creates a new Customer file inside the directory passed as the 
    //parameter to New(). If the Customer file already exist 
    //then insert operation will add the customer data to the array
    err=driver.Insert(customer)
    if(err!=nil){
        panic(err)
    }

    //GET ALL Customer
    //opens the customer json file and filter all the customers with name sarouje.
    //AsEntity takes an address to Customer array and fills the result to it.
    //we can loop through the customers array and retireve the data.
    var customers []Customer
    err=driver.Open(Customer{}).Where("name","=","sarouje").Get().AsEntity(&customers)
    if(err!=nil){
        panic(err)
    }
    // fmt.Printf("%#v \n", customers)

    //GET ONE Customer
    //First() will return the first record from the results 
    //AsEntity takes the address to Customer variable (not an array pointer)
    var customerFirst Customer
    err=driver.Open(Customer{}).Where("custid","=","CUST1").First().AsEntity(&customerFirst)
    if(err!=nil){
        panic(err)
    }

    //Update function uses the ID() to get the Id field/value to find the record and update the data.
    customerFirst.Name="Sony Arouje"
    err=driver.Update(customerFirst)
    if(err!=nil){
        panic(err)
    }
    driver.Open(Customer{}).Where("custid","=","CUST1").First().AsEntity(&customerFirst)
    fmt.Printf("%#v \n", customerFirst)

    // Delete
    toDel:=Customer{
        CustID:"CUST1",
    }
    err=driver.Delete(toDel)
    if(err!=nil){
        panic(err)
    }
}

TODO

The query syntax in simdb is not really great; I need to find a better approach.

Source Code: https://github.com/sonyarouje/simdb

 

 

 

 

Top