Sony Arouje

a programmer's log

Posts Tagged ‘db

simdb a simple json db in GO

leave a comment »

Some days ago I decided to learn GO. GO is pretty easy to learn and could learn syntax and semantics in 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 created in nodejs to GO and is now live and we are using it. This whole exercise allow me to learn GO in detail.

For me GO looks to be a great simple language with static type checking. Seems like I will be using GO for my future RPi projects than nodejs. In RPi more often I use a simple json as a db to store, retrieve and update execution rules, Sensor details, etc. In nodejs I use tingodb, couldn’t find some thing very similar in GO, so 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 db

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

Insert a new Customer to 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

var customerFirst 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) }

Update and Delete operation uses the ID field of the struct to perform it’s operation.

 

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

Advertisements

Written by Sony Arouje

August 6, 2018 at 2:30 pm

Posted in GO

Tagged with , , ,

Using await in real world asynchronous programming–Part 2

with one comment

This is the continuation to my previous post related to new async ctp. In the previous post I explained the use of await using a webclient. This post I am going to explain how can we use await in real life scenario. In real life you may not only deal with webclient, you may wanted to do a time consuming database call or you wanted to do some time consuming process or whatever in asynchronous manner, at the same time our UI should be responsive.

I did a lot of search to find a scenario to deal expensive process other than calling a webclient but no use. So I thought it will be good to post some real life scenario as most of the blogs explain the async ctp with webclient or in some complex way that person like me cant understand.

Async CTP simplify the way we write asynchronous methods, with async ctp no BeginXXX and no EndXXX. So let’s go through the scenario with a small intro.

Currently am in the process of rewriting one of my app called iTraveller. My prime focus is a very responsive UI with less app loading time. The app requires to load categories and lot of thumbnails at startup. I am doing lot of these process at startup and if we do it synchronously it will affect the application startup speed. When async CTP launched, I jumped into to it, because I know that it’s very useful for me.

Below is a piece of code we normally write to load some data from a database.

public List<LocalCategory> GetAllCategories()
{
    IRepository repository = GenericRepository.GetRepositoryInstance();
    return repository.GetAll<LocalCategory>().ToList<LocalCategory>();
}

 

Here I used the Generic repository model I explained earlier in my blog. The above method is a synchronous call and the caller should wait till the db calls complete. Am going to rewrite the above method in async mode.

public async Task<List<LocalCategory>> GetAllCategoriesAsync()
{
    IRepository repository = GenericRepository.GetRepositoryInstance();
    return await TaskEx.Run(() => 
    {
        //write the time consuming process here
        return repository.GetAll<LocalCategory>().ToList<LocalCategory>();
    }, System.Threading.CancellationToken.None);
}

 

Here I converted a synchronous method to an asynchronous one, It’s as simple as that. Let’s see how can we call the above method.

private async void LoadExistingCategory()
{
    CategoryService categoryService = new CategoryService();
    var categoriesTask=await categoryService.GetAllCategoriesAsync();
    this.ExistingCategories = categoriesTask.ToList<LocalCategory>();
}

 

You can call the async method in button event handler or where ever you want to call. But the caller should marked as async, the above method I added async just after the private.

LocalCategory is one of my entity class in the application.

I wrote a very expensive Euclidean distance algorithm using async mode and it worked very well. The same without async will keep the UI busy for two seconds and the user will be blocked from doing any action. 

Written by Sony Arouje

December 9, 2010 at 11:20 pm

%d bloggers like this: