GORM repository
The last repository we want to create in this tutorial is a repository based on the ORM package GORM. Create a new file repository_postgresql_gorm.go
in our domain package website
and copy the contents of the repository there.
You will need the gorm.io/gorm
package to make everything work, so add it to your project:
go get gorm.io/gorm
Let’s go through what our repository looks like.
Check out GORM great documentation if you want to learn more about how to use it.
The gormWebsite
structure
GORM is based on models, i.e., structs that represent a database row and describe the table schema using struct tags. In our repository, we have defined the gormWebsite
model, which describes the structure of the websites
table. Look at how the struct tags define the table columns, and the TableName()
method sets the table name. As you can probably guess, since the entire table is defined in code, we do not have to use SQL to perform operations on the database, even to create the table.
If you want to learn more about declaring models in GORM, check out the documentation.
The repository constructor
The repository structure PostgreSQLGORMRepository
(and the constructor NewPostgreSQLGORMRepository
) takes only one argument, the gorm.DB
object that represents, as in the previous cases, a concurrent safe connection to the database.
Migrate()
method
GORM has the AutoMigrate()
method to perform automatic migration, which is, creating or modifying a table schema as defined in the model struct. Look at the line 34
. We create a database object that respects the passed context.Context
using the WithContext()
function, and then call the AutoMigrate()
method with the model object as an argument. It is enough to create websites
table in the database with the columns defined in the model.
Create()
method
To insert records into a DB table, we can use the GORM DB.Create()
method, which takes a model object as an argument. Since we are operating on a domain object of type Website
, we should remember to convert it to gormWebsite
, which we do in lines 38-42
. After successfully inserting the record, the GORM function DB.Create()
also updates the value of the inserted object with the generated ID. So we just need to convert the inserted value back to Website
(line 54
) and return this object from our Create()
method as an inserted Website
record. In this method, as with previous repository implementations, we also handle the unique constraint violation error. Since the PostgreSQL driver for GORM internally uses the pgx
package, all we need to do is check that we get an appropriate error of type pgconn.PgError
.
All()
method
To get all the records from the table, we just need to initialize an empty slice of gormWebsite
objects for results and set it as an argument to GORM’s Find()
method (line 61
). Then, to be able to return a slice of type []Website
, the result needs to be converted, which we do in lines 65-68
.
GetByName()
method
The GetByName()
method is very similar to All()
except that we use the GORM Where()
function to add the SQL WHERE
clause to our query, and we handle the gorm.ErrRecordNotFound
error that is returned when there is no record with the given criteria. Note that the GORM requires ?
instead of $1
as a placeholder in the Where()
query. As with the All()
method, we use the Find()
function here to get the result, but this time with a single gormWebsite
object as an argument. In the end, we convert the result to our Website
domain object.
Update()
method
If you have followed the previous methods, then Update()
is nothing new for you. We use the GORM Save()
function here to update the value of a gormWebsite
object in the database. Finally, in addition to checking that we did not create a duplicate by updating, we also get the number of rows affected by this change. If it is equal to 0, we return the ErrUpdateFailed
error, as in previous repository implementations.
Delete()
method
To delete a record, we use the GORM Delete()
function in a variant that removes a row with the specified primary key. If no row has been affected by the delete, we return the ErrDeleteFailed
error.
website/repository_postgresql_gorm.go
|
|