A library for generating the repository pattern.
We heavily use the repository pattern in our codebases and we often write our queries manually. It becomes tedious and repetitive as we have more tables/models to maintain. So, we decided to experiment on creating this library to generate our repositories automatically.
- Decouple implementation from the
Repository
interface - Easy integration with existing codebase
- Minimal API
$ go get github.com/stevenferrer/nero
See the official example and integration test for a more complete demo.
import (
"database/sql"
// import the generated package
"github.com/stevenferrer/nero-example/productrepo"
)
func main() {
dsn := "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"
db, err := sql.Open("postgres", dsn)
...
ctx := context.Background()
// initialize the repository (and optionally enable debug)
productRepo := productrepo.NewPostgresRepository(db).Debug()
// create
creator := productrepo.NewCreator().Name("Product 1")
productID, err := productRepo.Create(ctx, creator)
...
// query
queryer := productrepo.NewQueryer().Where(productrepo.IDEq(product1ID))
product, err := productRepo.QueryOne(ctx, queryer)
...
// update
now := time.Now()
updater := productrepo.NewUpdater().Name("Updated Product 1").
UpdatedAt(&now).Where(productrepo.IDEq(product1ID))
_, err = productRepo.Update(ctx, updater)
...
// delete
deleter := productrepo.NewDeleter().Where(productrepo.IDEq(product1ID))
_, err = productRepo.Delete(ctx, deleter)
...
}
Below is the list of supported back-ends.
Back-end | Library |
---|---|
PostgreSQL | lib/pq |
SQLite | mattn/go-sqlite3 |
MySQL/MariaDB (soon) | go-sql-driver/mysql |
If your your back-end is not yet supported, you can implement your own custom back-end.
Implementing a custom back-end is very easy. In fact, you don't have to use the official back-ends. You can implement custom back-ends (Oracle, MSSQL, BoltDB, MongoDB, etc.) by implementing the Template interface.
See official postgres template for reference.
Currently, we only support basic CRUD and aggregate operations (i.e. count, sum). If you have more complex requirements other than that, we suggest that you just write your repositories manually, at least for now.
We're still in the process of brain-storming how to elegantly support other operations such as joins. If you have any ideas, we'd love to hear from you!
This project wouldn't be possible without the amazing open-source projects it was built upon:
- Masterminds/squirrel - Fluent SQL generation in golang
- lib/pq - Pure Go Postgres driver for database/sql
- mattn/go-sqlite3 - sqlite3 driver conforming to the built-in database/sql interface
- pkg/errors - Simple error handling primitives
- hashicorp/multierror - A Go (golang) package for representing a list of errors as a single error.
- jinzhu/inflection - Pluralizes and singularizes English nouns
- stretchr/testify - A toolkit with common assertions and mocks that plays nicely with the standard library
Also, the following have a huge influence on this project and deserves most of the credits:
- ent - An entity framework for Go. Simple, yet powerful ORM for modeling and querying data.
- SQLBoiler - Generate a Go ORM tailored to your database schema.
The project name is inspired by an anti-bird in an anime called Black Clover. The anti-bird, which the Black Bulls squad calls Nero is apparently a human named Secre Swallowtail. It's a really cool anime with lots of magic!
Any suggestions and ideas are very much welcome, feel free to open an issue or make a pull request!