gqt

package module
v0.0.0-...-7589d28 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2016 License: BSD-3-Clause Imports: 6 Imported by: 0

README

GQT - Go(lang) SQL Templates

Go Report Card GoDoc

Package gqt is a template engine for SQL queries.

It helps to separate SQL code from Go code and permits to compose the queries with a simple syntax.

The template engine is the standard package "text/template".

Why this package? Read more about ORM is the Vietnam of computer science.

Install/update using go get (no dependencies required by gqt):

go get -u github.com/Davmuz/gqt
Benefits
  • SQL is the best language to write SQL.
  • Separation between Go and SQL source code (your DB administrator will thank you).
  • Simpler template syntax for composing queries than writing Go code.
  • Simplified maintenance of the SQL code.
Compatibility

Go >= 1.6

Usage

Create a template directory tree of .sql files. Here an example template with the definition of three blocks:

-- File /path/to/sql/repository/dir/example.sql
{{define "allUsers"}}
SELECT *
FROM users
WHERE 1=1
{{end}}

{{define "getUser"}}
SELECT *
FROM users
WHERE id=?
{{end}}

{{define "allPosts"}}
SELECT *
FROM posts
WHERE date>=?
{{if ne .Order ""}}ORDER BY date {{.Order}}{{end}}
{{end}}

Then, with Go, add the directory to the default repository and execute the queries:

// Setup
gqt.Add("/path/to/sql/repository/dir", "*.sql")

// Simple query without parameters
db.Query(gqt.Get("allUsers"))
// Query with parameters
db.QueryRow(gqt.Get("getuser"), 1)
// Query with context and parameters
db.Query(gqt.Exec("allPosts", map[string]interface{
	"Order": "DESC",
}), date)

The templates are parsed immediately and recursively.

Namespaces

The templates can be organized in namespaces and stored in multiple root directories.

templates1/
|-- roles/
|	|-- queries.sql
|-- users/
|	|-- queries.sql
|	|-- commands.sql

templates2/
|-- posts/
|	|-- queries.sql
|	|-- commands.sql
|-- users/
|	|-- queries.sql
|-- queries.sql

The blocks inside the sql files are merged, the blocks with the same namespace and name will be overridden following the alphabetical order.

The sub-directories are used as namespaces and accessed like:

gqt.Add("../templates1", "*.sql")
gqt.Add("../templates2", "*.sql")

// Will search inside templates1/users/*.sql and templates2/users/*.sql
gqt.Get("users/allUsers")

Multiple databases

When dealing with multiple databases at the same time, like PostgreSQL and MySQL, just create two repositories:

// Use a common directory
dir := "/path/to/sql/repository/dir"

// Create the PostgreSQL repository
pgsql := gqt.NewRepository()
pgsql.Add(dir, "*.pg.sql")

// Create a separated MySQL repository
mysql := gqt.NewRepository()
mysql.Add(dir, "*.my.sql")

// Then execute
pgsql.Get("queryName")
mysql.Get("queryName")

License

Copyright © 2016 Davide Muzzarelli. All right reserved.

Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

Documentation

Overview

Package gqt is a template engine for SQL queries.

It helps to separate SQL code from Go code and permits to compose the queries with a simple syntax.

The template engine is the standard package "text/template".

Usage

Create a template directory tree of .sql files. Here an example template with the definition of three blocks:

// File /path/to/sql/repository/dir/example.sql
{{define "allUsers"}}
SELECT *
FROM users
WHERE 1=1
{{end}}

{{define "getUser"}}
SELECT *
FROM users
WHERE id=?
{{end}}

{{define "allPosts"}}
SELECT *
FROM posts
WHERE date>=?
{{if ne .Order ""}}ORDER BY date {{.Order}}{{end}}
{{end}}

Then, with Go, add the directory to the default repository and execute the queries:

// Setup
gqt.Add("/path/to/sql/repository/dir", "*.sql")

// Simple query without parameters
db.Query(gqt.Get("allUsers"))
// Query with parameters
db.QueryRow(gqt.Get("getuser"), 1)
// Query with context and parameters
db.Query(gqt.Exec("allPosts", map[string]interface{
	"Order": "DESC",
}), date)

The templates are parsed immediately and recursively.

Namespaces

The templates can be organized in namespaces and stored in multiple root directories.

templates1/
|-- roles/
|	|-- queries.sql
|-- users/
|	|-- queries.sql
|	|-- commands.sql

templates2/
|-- posts/
|	|-- queries.sql
|	|-- commands.sql
|-- users/
|	|-- queries.sql
|-- queries.sql

The blocks inside the sql files are merged, the blocks with the same namespace and name will be overridden following the alphabetical order.

The sub-directories are used as namespaces and accessed like:

gqt.Add("../templates1", "*.sql")
gqt.Add("../templates2", "*.sql")

// Will search inside templates1/users/*.sql and templates2/users/*.sql
gqt.Get("users/allUsers")

Multiple databases

When dealing with multiple databases at the same time, like PostgreSQL and MySQL, just create two repositories:

// Use a common directory
dir := "/path/to/sql/repository/dir"

// Create the PostgreSQL repository
pgsql := gqt.NewRepository()
pgsql.Add(dir, "*.pg.sql")

// Create a separated MySQL repository
mysql := gqt.NewRepository()
mysql.Add(dir, "*.my.sql")

// Then execute
pgsql.Get("queryName")
mysql.Get("queryName")

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Add

func Add(root string, ext string) error

Add method for the default repository.

func Exec

func Exec(name string, data interface{}) string

Exec method for the default repository.

func Get

func Get(name string) string

Get method for the default repository.

func Parse

func Parse(name string, data interface{}) (string, error)

Parse method for the default repository.

Types

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository stores SQL templates.

func NewRepository

func NewRepository() *Repository

NewRepository creates a new Repository.

func (*Repository) Add

func (r *Repository) Add(root string, pattern string) (err error)

Add adds a root directory to the repository, recursively. Match only the given file extension. Blocks on the same namespace will be overridden. Does not follow symbolic links.

func (*Repository) Exec

func (r *Repository) Exec(name string, data interface{}) (s string)

Exec is a shortcut for r.Parse(), but panics if an error occur.

func (*Repository) Get

func (r *Repository) Get(name string) string

Get is a shortcut for r.Exec(), passing nil as data.

func (*Repository) Parse

func (r *Repository) Parse(name string, data interface{}) (string, error)

Parse executes the template and returns the resulting SQL or an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL