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
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…
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
querybuilder directory inside
$GOPATH/src/ and create these files.
In this case we are building a package
db inside the
querybuilder directory where our main package resides.
db.go file inside
db directory and write the code like below:
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
db to make the driver types.
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
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.