Fluent SQL generation for golang

sqrl - fat-free version of squirrel - fluent SQL generator for Go

Non thread safe fork of squirrel. The same handy fluffy helper, but with extra letters removed :)

import "github.com/elgris/sqrl"

GoDoc Build Status

Requires Go 1.8 and higher

Inspired by

Why to make good squirrel lighter?

Ask benchmarks about that ;). Squirrel is good, reliable and thread-safe with it's immutable query builder. Although immutability is nice, it's resource consuming and sometimes redundant. As authors of dbr say: "100% of our application code was written without the need for this".

Why not to use dbr then?

Although, dbr's query builder is proven to be much faster than squirrel and even faster than sqrl, it doesn't have all syntax sugar. Especially I miss support of JOINs, subqueries and aliases.

Usage

sqrl is not an ORM., it helps you build SQL queries from composable parts. sqrl is non thread safe. SQL builders change their state, so using the same builder in parallel is dangerous.

It's very easy to switch between original squirrel and sqrl, because there is no change in interface:

import sq "github.com/elgris/sqrl" // you can easily use github.com/lann/squirrel here

users := sq.Select("*").From("users").Join("emails USING (email_id)")

active := users.Where(sq.Eq{"deleted_at": nil})

sql, args, err := active.ToSql()

sql == "SELECT * FROM users JOIN emails USING (email_id) WHERE deleted_at IS NULL"
sql, args, err := sq.
    Insert("users").Columns("name", "age").
    Values("moe", 13).Values("larry", sq.Expr("? + 5", 12)).
    ToSql()

sql == "INSERT INTO users (name,age) VALUES (?,?),(?,? + 5)"

Like squirrel, sqrl can execute queries directly:

stooges := users.Where(sq.Eq{"username": []string{"moe", "larry", "curly", "shemp"}})
three_stooges := stooges.Limit(3)
rows, err := three_stooges.RunWith(db).Query()

// Behaves like:
rows, err := db.Query("SELECT * FROM users WHERE username IN (?,?,?,?) LIMIT 3", "moe", "larry", "curly", "shemp")

Build conditional queries with ease:

if len(q) > 0 {
    users = users.Where("name LIKE ?", q)
}

MySQL-specific functions

Multi-table delete

sql, args, err := sq.Delete("a1", "a2").
    From("z1 AS a1").
    JoinClause("INNER JOIN a2 ON a1.id = a2.ref_id").
    Where("b = ?", 1).
    ToSql()
sql, args, err := sq.Delete("a1").
    Using("a2").
    Where("a1.id = a2.ref_id AND a2.num = ?", 42).
    ToSql()

PostgreSQL-specific functions

Package pg contains PostgreSQL specific operators.

Update from

sql, args, err := sq.Update("a1").
    Set("foo", 1).
    From("a2").
    Where("id = a2.ref_id AND a2.num = ?", 42).
    ToSql()

Delete using

sql, args, err := sq.Delete("a1").
    Using("a2").
    Where("id = a2.ref_id AND a2.num = ?", 42).
    ToSql()

Returning clause

sql, args, err := Update("a").
    Set("foo", 1).
    Where("id = ?", 42).
    Returning("bar").
    ToSql()

JSON values

JSON and JSONB use json.Marshal to serialize values and cast them to appropriate column type.

sql, args, err := sq.Insert("posts").
    Columns("content", "tags").
    Values("Lorem Ipsum", pg.JSONB([]string{"foo", "bar"})).
    ToSql()

Array values

Array serializes single and multidimensional slices of string, int, float32 and float64 values.

sql, args, err := sqrl.Insert("posts").
    Columns("content", "tags").
    Values("Lorem Ipsum", pg.Array([]string{"foo", "bar"})).
    ToSql()

License

Sqrl is released under the MIT License.

Owner
Comments
  • Support UPDATE ... FROM and DELETE ... USING queries

    Support UPDATE ... FROM and DELETE ... USING queries

    As described in Postgres docs:

    • https://www.postgresql.org/docs/9.6/static/sql-update.html
    • https://www.postgresql.org/docs/9.6/static/sql-delete.html
  • Add gomodule support

    Add gomodule support

    Hi,

    I was wondering whether you'd be interested in upgrading sqrl to support Go 1.11 modules?

    I think it's fairly straight-forward to do from the instructions here: https://github.com/golang/go/wiki/Modules#quick-start-example

    Because it involves tagging and committing the package name I've not submitted a PR but give me a shout if you want help setting this up :-)

  • Add support for Query and QueryRow in UPDATE and DELETE statements

    Add support for Query and QueryRow in UPDATE and DELETE statements

    PostgreSQL allows to build the following queries:

    UPDATE tbl SET col1 = 'val' WHERE id = 1 RETURNING col2;
    
    DELETE FROM tbl WHERE id = 1 RETURNING col1;
    

    This patch will allow to call Query, QueryRow and Scan directly from UpdateBuilder and DeleteBuilder.

  • Implement support for multiple-table syntax on delete statements

    Implement support for multiple-table syntax on delete statements

    Currently you are not able to create a delete statement, to delete from multiple tables, like in mysql documentation described: http://dev.mysql.com/doc/refman/5.7/en/delete.html#idm140368126356160 Is it possible to implement it?

  • Allow Sqlizer as Expr arguments

    Allow Sqlizer as Expr arguments

    Allow Sqlizer values to be used in expr. To avoid overhead of creating buffer everytime old behaviour is used when no arguments match interface Sqlizer.

    Example of usage:

    sq.Select('foo', 'bar').From('baz').Where(Expr("EXISTS(?)",
      sq.Select('foo').From('bad').Where(Eq{"foo": 42})
    ))
    
  • Add a license file

    Add a license file

    I was unable to view the docs for sqrl on pkg.dev.go. According to the error message it can't determine the license, so this adds a LICENSE.txt file. The text was taken from the MIT license link in the README.

  • "Clone" on assignment?

    Hello to everyone:

    I know that sqrl is not thread safe, but: In a webservice context, What if on every request a cached pointer to an SelectBuilder is dereferenced and assigned to a variable?

    Something like this:

    var sqlSelect sqrl.Select("*").From("users") // *sqr.SelectBuilder . . . func calledOnEveryRequest() (error) { query := *sqlSelect // Is "query" a completely new copy (deep copy) of sqlSelect value? . . . }

    Many thanks in advance.

  • Commit 2178fbc00 does not build

    Commit 2178fbc00 does not build

    When trying to build since commit 2178fbc00 I get this error:

    ../../../github.com/elgris/sqrl/stmtcacher.go:61: stmt.ExecContext undefined (type *sql.Stmt has no field or method ExecContext)
    ../../../github.com/elgris/sqrl/stmtcacher.go:61: not enough arguments to return
    ../../../github.com/elgris/sqrl/stmtcacher.go:69: stmt.QueryContext undefined (type *sql.Stmt has no field or method QueryContext)
    ../../../github.com/elgris/sqrl/stmtcacher.go:69: not enough arguments to return
    ../../../github.com/elgris/sqrl/stmtcacher.go:77: stmt.QueryRowContext undefined (type *sql.Stmt has no field or method QueryRowContext)
    ../../../github.com/elgris/sqrl/stmtcacher.go:109: cannot use db (type *sql.DB) as type Preparer in argument to NewStmtCacher:
    	*sql.DB does not implement Preparer (missing PrepareContext method)
    
  • Invalid DELETE query with alias

    Invalid DELETE query with alias

    For example: DELETE a FROM A a JOIN B b ON a.c = b.c .... sqrl.Delete("s").From("A a").Join("B b ON a.c = b.c). ...

    Due to delete statement builder handling in sqrl.Delete(...), if only a single element (remains after filtering) it is pushed to the From-part instead. Causing an invalid query to be generated at least for MySQL: DELETE FROM A a JOIN B b ON a.c = b.c ....

  • Add Lt, Gt, LtOrEq, GtOrEq

    Add Lt, Gt, LtOrEq, GtOrEq

    These methods were a recent addition and I found about it when i was migrating to sqrl these were missing. It's not a big deal, but since this has the same interface, I thought it'd be nice to have them. I will make a PR with those added.

  • SelectFrom args with wrong placeholder values

    SelectFrom args with wrong placeholder values

    The query params inside a FromSelect are numbered independently from the whole query, so:

    psql.Update(`mytable`).
    		Set("name", "newname").
                    FromSelect(psql.Select("column").From("anothertable").Where(sq.Eq{"column": 3})).
                    Where(sq.Eq{"name": "oldname"})
    

    Args will be ["newname", "oldname", 3], but query string will be:

    update mytable set name = $1
    select column from anothertable where column = $1
    where name = $2
    

    Correct should be:

    update mytable set name = $1
    select column from anothertable where column = $3
    where name = $2
    

    FromSelect should change the placeholder count to start from where the parent Update ends

  • WIP: Support use of subquery as a select

    WIP: Support use of subquery as a select

    Allows the use of subquery as select, specially useful if working with Postgres' functions. It uses the Column method and reserves the first argument to be used as an alias.

  • Add RowsScanner interface

    Add RowsScanner interface

    Currently it is impossible to fully unit test code that is using sqrl since Query method requires *sql.Rows as return value. I am proposing to add RowsScanner interface that would allow *sql.Rows to be replaced by another struct that implements required methods.

    type Queryer interface {
        Query(query string, args ...interface{}) (RowsScanner, error)
    }
    

    As far as I can tell, RowsScanner could look something like this:

    type RowsScanner interface {
        Columns() ([]string, error)
        Next() bool
        Close() error
        Err() error
        RowScanner
    }
    
  • escape reserved symbols

    escape reserved symbols

    It would be nice to tell sqrl to escape column names for example "status" is a reserved symbol in mysql.

    users := sq.Select("status").From("users").Join("emails USING (email_id)")
    fmt.Println(users.ToSql())
    

    output is:

    SELECT status FROM users JOIN emails USING (email_id) [] <nil>
    

    should be:

    SELECT `status` FROM users JOIN emails USING (email_id) [] <nil>
  • How to create dynamic WHERE clause

    How to create dynamic WHERE clause

    Hi,

    Is there support for dynamic where clauses? I could not find any documentation about how to do that. In my case I need to add AND'd conditions with nested OR conditions conditionally, to get something like: WHERE x=? AND (foo>=? OR bar> ?) AND (bar> ?)

    I've tried to create an []sq.Sqlizer and add the OR-expressions in there, then feed that to SelectBuilder.Where() but it fails with the message

    converting Exec argument # 1's type: unsupported type []sqrl.Sqlizer, a slice

    Ideally there is some kind of ConditionBuilder for this I guess.

Type safe SQL builder with code generation and automatic query result data mapping
Type safe SQL builder with code generation and automatic query result data mapping

Jet Jet is a complete solution for efficient and high performance database access, consisting of type-safe SQL builder with code generation and automa

Jan 6, 2023
Squat is an application that provides simple SQL data generation functionality.

Squat Squat is an application that provides simple SQL data generation functionality. It generates synthetic SQL data based on the table definition, t

Sep 22, 2022
Command line tool to generate idiomatic Go code for SQL databases supporting PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server

About xo xo is a command-line tool to generate Go code based on a database schema or a custom query. xo works by using database metadata and SQL intro

Jan 8, 2023
Go fearless SQL. Sqlvet performs static analysis on raw SQL queries in your Go code base.

Sqlvet Sqlvet performs static analysis on raw SQL queries in your Go code base to surface potential runtime errors at build time. Feature highlights:

Dec 19, 2022
A Golang library for using SQL.

dotsql A Golang library for using SQL. 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

Dec 27, 2022
a golang library for sql builder

Gendry gendry is a Go library that helps you operate database. Based on go-sql-driver/mysql, it provides a series of simple but useful tools to prepar

Dec 26, 2022
SQL builder and query library for golang

__ _ ___ __ _ _ _ / _` |/ _ \ / _` | | | | | (_| | (_) | (_| | |_| | \__, |\___/ \__, |\__,_| |___/ |_| goqu is an expressive SQL bu

Dec 30, 2022
A Go (golang) package that enhances the standard database/sql package by providing powerful data retrieval methods as well as DB-agnostic query building capabilities.

ozzo-dbx Summary Description Requirements Installation Supported Databases Getting Started Connecting to Database Executing Queries Binding Parameters

Dec 31, 2022
golang orm and sql builder

gosql gosql is a easy ORM library for Golang. Style: var userList []UserModel err := db.FetchAll(&userList, gosql.Columns("id","name"), gosql.

Dec 22, 2022
This is a SQL Finder, Admin panel finder, and http analyzer that goes basses off requests. Made from 100% golang

This is a SQL Finder, Admin panel finder that goes basses off requests. Made from 100% golang

May 19, 2022
Database Abstraction Layer (dbal) for Go. Support SQL builder and get result easily (now only support mysql)

godbal Database Abstraction Layer (dbal) for go (now only support mysql) Motivation I wanted a DBAL that No ORM、No Reflect、Concurrency Save, support S

Nov 17, 2022
SQL query builder for Go

GoSQL Query builder with some handy utility functions. Documentation For full documentation see the pkg.go.dev or GitBook. Examples // Open database a

Dec 12, 2022
Write your SQL queries in raw files with all benefits of modern IDEs, use them in an easy way inside your application with all the profit of compile time constants

About qry is a general purpose library for storing your raw database queries in .sql files with all benefits of modern IDEs, instead of strings and co

Dec 25, 2022
Type safe SQL query builder and struct mapper for Go

sq (Structured Query) ?? ?? sq is a code-generated, type safe query builder and struct mapper for Go. ?? ?? Documentation • Reference • Examples This

Dec 19, 2022
Fast SQL query builder for Go

sqlf A fast SQL query builder for Go. sqlf statement builder provides a way to: Combine SQL statements from fragments of raw SQL and arguments that ma

Dec 23, 2022
💥 A lightweight DSL & ORM which helps you to write SQL in Go.
💥 A lightweight DSL & ORM which helps you to write SQL in Go.

sqlingo is a SQL DSL (a.k.a. SQL Builder or ORM) library in Go. It generates code from the database and lets you write SQL queries in an elegant way.

Jan 2, 2023
GraphJin - Build APIs in 5 minutes with GraphQL. An instant GraphQL to SQL compiler.
GraphJin - Build APIs in 5 minutes with GraphQL. An instant GraphQL to SQL compiler.

GraphJin - Build APIs in 5 minutes GraphJin gives you a high performance GraphQL API without you having to write any code. GraphQL is automagically co

Jan 4, 2023
Analyzer: helps uncover bugs by reporting a diagnostic for mistakes of *sql.Rows usage.

sqlrows sqlrows is a static code analyzer which helps uncover bugs by reporting a diagnostic for mistakes of sql.Rows usage. Install You can get sqlro

Mar 24, 2022
LBADD: An experimental, distributed SQL database
LBADD: An experimental, distributed SQL database

LBADD Let's build a distributed database. LBADD is an experimental distributed SQL database, written in Go. The goal of this project is to build a dat

Nov 29, 2022