Files
go-kit/sqr
Jan Tytgat cf9614f48e
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
Add README for package sqr
Signed-off-by: Jan Tytgat <jan.tytgat@corelayer.eu>
2025-05-21 21:29:56 +02:00
..
2025-05-21 21:09:05 +02:00
2025-05-21 21:09:05 +02:00
2025-05-21 21:09:05 +02:00
2025-05-21 21:09:05 +02:00
2025-05-21 21:29:56 +02:00
2025-05-21 21:09:05 +02:00

go-sql-sqr - SQL Query Repository for Go

This library enables the use of centralized storage for all SQL queries used in an application. You can either choose to load all queries into a repository, or load them from a filesystem as necessary.

The main intention is to embed a directory structure into the binary as embed.FS, which can then used in the application.

Go Reference


Basics

Add the package to your project

go get git.flexabyte.io/flexabyte/go-kit

Import

Next, you can manually add the import statement to your .go-file, or have it added automatically when using it.

import git.flexabyte.io/flexabyte/go-kit/sqr

Embed assets containing queries.

Important

The root folder embedded in the application cannot have nested directories.
This means that the directory structure is limited to 1 level of collections, each containing a set of text files with a .sql extension.

Files with another extension will fail to load!

Let's assume to following directory structure in an embedded filesystem:

/assets
|-- /queries
    |-- collection1
    |   |-- create.sql
    |   |-- read.sql
    |   |-- update.sql
    |   |-- delete.sql
    |-- collection2
        |-- list.sql

You can now embed the statement files as follows:

//go:embed assets/queries/*
var f embed.FS

With repository

Create a new repository

// Create query repository from embedded files
var r *sqr.Repository
if r, err = sqr.NewFromFs(f, "assets/queries"); err != nil {
    panic(err)
}

Load a query from the repository

Now the repository has been initialized, we can get a query from a collection:

var query string
if query, err = r.Get("collection1", "create"); err != nil {
    panic(err)
}
fmt.Println("Query:", query)

Without repository

If you don't want to initialize a repository, but rather choose to load SQL queries straight from the filesystem, you can do so as follows:

var query string
if query, err = sqr.LoadQueryFromFs(f, "assets/queries", "collection2", "list"); err != nil {
    panic(err)
}

Prepared statements

We also provide the means to create prepared statements for the queries, either with or without using a repository, as long as a Preparer is passed into the functions.

type Preparer interface {
	Prepare(query string) (*sql.Stmt, error)
}

For example:

  • *sql.Db
  • *sql.Tx
func Prepare[T Preparer](t T, r *Repository, collectionName, queryName string) (*sql.Stmt, error) {}
func PrepareFromFs[T Preparer](t T, f fs.FS, rootPath, collectionName, queryName string) (*sql.Stmt, error) {}

With repository

var createStmt *sql.Stmt
if createStmt, err = sqr.Prepare(db, r, "collection1", "create"); err != nil {
    panic(err)
}

Without repository

var createStmt *sql.Stmt
if createStmt, err = sqr.PrepareFromFs(db, f, "assets/queries", "collection1", "create"); err != nil {
    panic(err)
}

Examples

Two examples are available:

  • embbededSqlWithRepository
  • embeddedSqlWithoutRepository