route/vendor/github.com/gchaincl/dotsql/dotsql.go

132 lines
3.0 KiB
Go

// Package dotsql provides a way to separate your code from SQL queries.
//
// It is not an ORM, it is not a query builder.
// Dotsql is a library that helps you keep sql files in one place and use it with ease.
//
// For more usage examples see https://github.com/gchaincl/dotsql
package dotsql
import (
"bufio"
"bytes"
"database/sql"
"fmt"
"io"
"os"
)
// Preparer is an interface used by Prepare.
type Preparer interface {
Prepare(query string) (*sql.Stmt, error)
}
// Queryer is an interface used by Query.
type Queryer interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
}
// Execer is an interface used by Exec.
type Execer interface {
Exec(query string, args ...interface{}) (sql.Result, error)
}
// DotSql represents a dotSQL queries holder.
type DotSql struct {
queries map[string]string
}
func (d DotSql) lookupQuery(name string) (query string, err error) {
query, ok := d.queries[name]
if !ok {
err = fmt.Errorf("dotsql: '%s' could not be found", name)
}
return
}
// Query is a wrapper for database/sql's Prepare(), using dotsql named query.
func (d DotSql) Prepare(db Preparer, name string) (*sql.Stmt, error) {
query, err := d.lookupQuery(name)
if err != nil {
return nil, err
}
return db.Prepare(query)
}
// Query is a wrapper for database/sql's Query(), using dotsql named query.
func (d DotSql) Query(db Queryer, name string, args ...interface{}) (*sql.Rows, error) {
query, err := d.lookupQuery(name)
if err != nil {
return nil, err
}
return db.Query(query, args...)
}
// Exec is a wrapper for database/sql's Exec(), using dotsql named query.
func (d DotSql) Exec(db Execer, name string, args ...interface{}) (sql.Result, error) {
query, err := d.lookupQuery(name)
if err != nil {
return nil, err
}
return db.Exec(query, args...)
}
// Raw returns the query, everything after the --name tag
func (d DotSql) Raw(name string) (string, error) {
return d.lookupQuery(name)
}
// QueryMap returns a map[string]string of loaded queries
func (d DotSql) QueryMap() map[string]string {
return d.queries
}
// Load imports sql queries from any io.Reader.
func Load(r io.Reader) (*DotSql, error) {
scanner := &Scanner{}
queries := scanner.Run(bufio.NewScanner(r))
dotsql := &DotSql{
queries: queries,
}
return dotsql, nil
}
// LoadFromFile imports SQL queries from the file.
func LoadFromFile(sqlFile string) (*DotSql, error) {
f, err := os.Open(sqlFile)
if err != nil {
return nil, err
}
defer f.Close()
return Load(f)
}
// LoadFromString imports SQL queries from the string.
func LoadFromString(sql string) (*DotSql, error) {
buf := bytes.NewBufferString(sql)
return Load(buf)
}
// Merge takes one or more *DotSql and merge its queries
// It's in-order, so the last source will override queries with the same name
// in the previous arguments if any.
func Merge(dots ...*DotSql) *DotSql {
queries := make(map[string]string)
for _, dot := range dots {
for k, v := range dot.QueryMap() {
queries[k] = v
}
}
return &DotSql{
queries: queries,
}
}