Lets make a Query builder using Go

To understand the uses of factory pattern and singleton pattern in real life application.

Now a days we can’t think to write raw sql query in our applications. Because writing sql queries are boring also you have to think about lot of security staff all the time. ORM (Object-relational mapping) and query builder makes it very much easy and convenient.

If you are a Laravel guy like me you should fall in love with its ORM called Eloquent . In golang I have used the GORM ORM for several times. Most of the orm comes with a query builder .

When you are using a framework like Laravel, django for rapid application development, you can any choose any database like mysql, postgres, mssql, mongodb, sqlite from different flavors. And after completion of your application you can change the database by typing a word (driver/database name).

Now the question is, does all the different database query language same? The plain answer is NO. All the database has different DML for its own.

For an example, when we perform a get method call on some model, depending on the selected driver the query executed in different dialects.

In an imaginary ORM, when we perform this operation userModel.Get() It will generate different queries depending on the database, like in mysql it’ll generate query SELECT * FROM users and in mongodb it’ll generate query db.users.find()


Factory pattern?

Factory pattern is a creational pattern that provides one of the best way to create object. In this case you don’t have to take panic how the object created, what is going on underneath. Learn more about it here…

Singleton pattern?

In singleton pattern ensure a class can only one object is created. If you want to create another instance from that particular class it will provide you the previously created object. Read more about it here…

Lets build a fake Query builder to simulate the factory + singleton pattern

Make a querybuilder directory inside $GOPATH/src/ and create these files.

Directory Structure

In this case we are building a package db inside the querybuilder directory where our main package resides.

Create a db.go file inside db directory and write the code like below:

db.go

In the above db.go file between line 12–17 we created a type interface which contains four method signatures. Between line 40–50, the databaseFactory function take a driver constant as argument and based on that argument it create an instance of that database driver, in this case it just create the object, but it may need some more argument, some dependencies to create the object. So we hide the process of the object creation, which known as factory pattern. All the types (Mysql /Sqlite/MongoDb) are implementing the DB interface so our return type is DB. If we need to add more driver in future, we can simply implement the DB interface and add this inside our switch statement like the previous drivers.

Lets take a look to line between 30–36, where we used another creation pattern known as singleton pattern. Here we restricted the users to obtain multiple object from types (Mysql/Sqlite/MongoDb) so that the connection remains single. We used sync package to get a singleton object and in this case the object will be thread safe (In different goroutine the object will remain the same object).

Lets create 3 more files mysql.go , sqlite.go , mongodb.go inside db to make the driver types.

mysql.go
sqlite.go
mongodb.go

Now we just finished building the query builder lets use it, to use it we are going to create a main.go file inside the querybuilder directory.

main.db

In line 5 we imported our library querybuilder/db and line 11 we create an instance of our db library using db.New() passing MySql as our database.

Our factory and singleton remains alive in the New() method. When we passed the constant db.MYSQL a factory created our object based on input, and we used sync package to create only a single object from that particular type. No matter where we used the db object we always receive the same object over and over. In line 11 we created our first db object and used several method form the object. In line 18 we set the table name on which the query will be performed and used in line 20, 23 and 26 to perform some query. But if you look carefully you can see in line 31 we create another object from the query builder and assigned in db1 variable. Then we performed a Get query in line 37, this time we did not said the table name but it will perform the query on the users table because we set the table name before on the same object. No matter how many time you asked to create a db object you will get the same object with previous connection.

Though we did not make a working query builder but we simulate an idea to create them, basically we focused on how can we use the factory pattern, singleton pattern. If you need the full source code you’ll find it here.


Note: I’ll try to update all of my articles in this series. To get update follow me on twitter or medium. One more thing, if you find any mistake or misleading in these articles please knock me or write a comment. Thank you
If you like my writing please follow me Saddam H.