sqlx is a library which provides a set of extensions on go's standard database/sql library

Related tags

Database tools sqlx
Overview

sqlx

Build Status Coverage Status Godoc license

sqlx is a library which provides a set of extensions on go's standard database/sql library. The sqlx versions of sql.DB, sql.TX, sql.Stmt, et al. all leave the underlying interfaces untouched, so that their interfaces are a superset on the standard ones. This makes it relatively painless to integrate existing codebases using database/sql with sqlx.

Major additional concepts are:

  • Marshal rows into structs (with embedded struct support), maps, and slices
  • Named parameter support including prepared statements
  • Get and Select to go quickly from query to struct/slice

In addition to the godoc API documentation, there is also some user documentation that explains how to use database/sql along with sqlx.

Recent Changes

1.3.0:

  • sqlx.DB.Connx(context.Context) *sqlx.Conn
  • sqlx.BindDriver(driverName, bindType)
  • support for []map[string]interface{} to do "batch" insertions
  • allocation & perf improvements for sqlx.In

DB.Connx returns an sqlx.Conn, which is an sql.Conn-alike consistent with sqlx's wrapping of other types.

BindDriver allows users to control the bindvars that sqlx will use for drivers, and add new drivers at runtime. This results in a very slight performance hit when resolving the driver into a bind type (~40ns per call), but it allows users to specify what bindtype their driver uses even when sqlx has not been updated to know about it by default.

Backwards Compatibility

Compatibility with the most recent two versions of Go is a requirement for any new changes. Compatibility beyond that is not guaranteed.

Versioning is done with Go modules. Breaking changes (eg. removing deprecated API) will get major version number bumps.

install

go get github.com/jmoiron/sqlx

issues

Row headers can be ambiguous (SELECT 1 AS a, 2 AS a), and the result of Columns() does not fully qualify column names in queries like:

SELECT a.id, a.name, b.id, b.name FROM foos AS a JOIN foos AS b ON a.parent = b.id;

making a struct or map destination ambiguous. Use AS in your queries to give columns distinct names, rows.Scan to scan them manually, or SliceScan to get a slice of results.

usage

Below is an example which shows some common use cases for sqlx. Check sqlx_test.go for more usage.

package main

import (
    "database/sql"
    "fmt"
    "log"
    
    _ "github.com/lib/pq"
    "github.com/jmoiron/sqlx"
)

var schema = `
CREATE TABLE person (
    first_name text,
    last_name text,
    email text
);

CREATE TABLE place (
    country text,
    city text NULL,
    telcode integer
)`

type Person struct {
    FirstName string `db:"first_name"`
    LastName  string `db:"last_name"`
    Email     string
}

type Place struct {
    Country string
    City    sql.NullString
    TelCode int
}

func main() {
    // this Pings the database trying to connect
    // use sqlx.Open() for sql.Open() semantics
    db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
    if err != nil {
        log.Fatalln(err)
    }

    // exec the schema or fail; multi-statement Exec behavior varies between
    // database drivers;  pq will exec them all, sqlite3 won't, ymmv
    db.MustExec(schema)
    
    tx := db.MustBegin()
    tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "Jason", "Moiron", "[email protected]")
    tx.MustExec("INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)", "John", "Doe", "[email protected]")
    tx.MustExec("INSERT INTO place (country, city, telcode) VALUES ($1, $2, $3)", "United States", "New York", "1")
    tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Hong Kong", "852")
    tx.MustExec("INSERT INTO place (country, telcode) VALUES ($1, $2)", "Singapore", "65")
    // Named queries can use structs, so if you have an existing struct (i.e. person := &Person{}) that you have populated, you can pass it in as &person
    tx.NamedExec("INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &Person{"Jane", "Citizen", "[email protected]"})
    tx.Commit()

    // Query the database, storing results in a []Person (wrapped in []interface{})
    people := []Person{}
    db.Select(&people, "SELECT * FROM person ORDER BY first_name ASC")
    jason, john := people[0], people[1]

    fmt.Printf("%#v\n%#v", jason, john)
    // Person{FirstName:"Jason", LastName:"Moiron", Email:"[email protected]"}
    // Person{FirstName:"John", LastName:"Doe", Email:"[email protected]"}

    // You can also get a single result, a la QueryRow
    jason = Person{}
    err = db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason")
    fmt.Printf("%#v\n", jason)
    // Person{FirstName:"Jason", LastName:"Moiron", Email:"[email protected]"}

    // if you have null fields and use SELECT *, you must use sql.Null* in your struct
    places := []Place{}
    err = db.Select(&places, "SELECT * FROM place ORDER BY telcode ASC")
    if err != nil {
        fmt.Println(err)
        return
    }
    usa, singsing, honkers := places[0], places[1], places[2]
    
    fmt.Printf("%#v\n%#v\n%#v\n", usa, singsing, honkers)
    // Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1}
    // Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65}
    // Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852}

    // Loop through rows using only one struct
    place := Place{}
    rows, err := db.Queryx("SELECT * FROM place")
    for rows.Next() {
        err := rows.StructScan(&place)
        if err != nil {
            log.Fatalln(err)
        } 
        fmt.Printf("%#v\n", place)
    }
    // Place{Country:"United States", City:sql.NullString{String:"New York", Valid:true}, TelCode:1}
    // Place{Country:"Hong Kong", City:sql.NullString{String:"", Valid:false}, TelCode:852}
    // Place{Country:"Singapore", City:sql.NullString{String:"", Valid:false}, TelCode:65}

    // Named queries, using `:name` as the bindvar.  Automatic bindvar support
    // which takes into account the dbtype based on the driverName on sqlx.Open/Connect
    _, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`, 
        map[string]interface{}{
            "first": "Bin",
            "last": "Smuth",
            "email": "[email protected]",
    })

    // Selects Mr. Smith from the database
    rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:fn`, map[string]interface{}{"fn": "Bin"})

    // Named queries can also use structs.  Their bind names follow the same rules
    // as the name -> db mapping, so struct fields are lowercased and the `db` tag
    // is taken into consideration.
    rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:first_name`, jason)
    
    
    // batch insert
    
    // batch insert with structs
    personStructs := []Person{
        {FirstName: "Ardie", LastName: "Savea", Email: "[email protected]"},
        {FirstName: "Sonny Bill", LastName: "Williams", Email: "[email protected]"},
        {FirstName: "Ngani", LastName: "Laumape", Email: "[email protected]"},
    }

    _, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)
        VALUES (:first_name, :last_name, :email)`, personStructs)

    // batch insert with maps
    personMaps := []map[string]interface{}{
        {"first_name": "Ardie", "last_name": "Savea", "email": "[email protected]"},
        {"first_name": "Sonny Bill", "last_name": "Williams", "email": "[email protected]"},
        {"first_name": "Ngani", "last_name": "Laumape", "email": "[email protected]"},
    }

    _, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)
        VALUES (:first_name, :last_name, :email)`, personMaps)
}
Issues
  • Close #238, support batch insert.

    Close #238, support batch insert.

    usage: places := []*Place{&place1, &place2} db.NamedExec("INSERT INTO place (country, telcode) VALUES (:country, :telcode)", places)

    opened by hmgle 52
  • StructScan infinite loop

    StructScan infinite loop

    I had a case earlier which made me pull my hair for a full day and half :

    Let's say we have the following structs :

    type Entity struct {
        ID int64 `db:"id"`
        Service *Service
    }
    
    type Service struct {
        Entity *Entity
    }
    
    func NewEntity(id int64) *Entity {
        e := &Entity{}
        e.Service = &Service{}
        e.Service.Entity = e
        return e
    }
    

    When StructScaning, the function tries to establish a field map by exploring the tree of embedded types of the struct. I my case, the exploration never end because of the pointers.

    This issue bring the following question to my mind : what is the point of exploring non-embedded fields ? It seem rather non-semantic to me… And independantly, why making a field map and not simply look for the fields as needed when scanning ?

    opened by elwinar 20
  • 1.8 Not Supported

    1.8 Not Supported

    Currently working on a project that uses vendoring. I updated all the references to the latest on master (even tried tagged versions) but it seems that I cannot build with this package in Go 1.8.1. When downgrading to 1.7.4_2 it works great. If I may advise to use sql/driver package as that was included in 1.8. There were some changes that they said were minor but maybe not but recommend driver packages to look at the above link Go1.8 Minor Changes.

    vendor/github.com/jmoiron/sqlx/sqlx_context.go:20: db.PingContext undefined (type *DB has no field or method PingContext)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:122: cannot use db (type *DB) as type namedPreparerContext in argument to prepareNamedContext:
    	*DB does not implement namedPreparerContext (missing PrepareContext method)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:128: cannot use db (type *DB) as type ExtContext in argument to NamedQueryContext:
    	*DB does not implement ExtContext (missing ExecContext method)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:134: cannot use db (type *DB) as type ExtContext in argument to NamedExecContext:
    	*DB does not implement ExtContext (missing ExecContext method)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:140: cannot use db (type *DB) as type QueryerContext in argument to SelectContext:
    	*DB does not implement QueryerContext (missing QueryContext method)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:147: cannot use db (type *DB) as type QueryerContext in argument to GetContext:
    	*DB does not implement QueryerContext (missing QueryContext method)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:155: cannot use db (type *DB) as type PreparerContext in argument to PreparexContext:
    	*DB does not implement PreparerContext (missing PrepareContext method)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:161: db.DB.QueryContext undefined (type *sql.DB has no field or method QueryContext)
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:182: undefined: sql.TxOptions
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:203: undefined: sql.TxOptions
    vendor/github.com/jmoiron/sqlx/sqlx_context.go:161: too many errors
    
    opened by dixonwille 15
  • Problem with a simple select/get

    Problem with a simple select/get

    Hi,

    Im using sqlx now, but i have problems on my first select/get.

    type Device struct {
        Id int64 `db:"id"`
    }
    
    var device = Device{}
    err := sqlx.Get(&device, "SELECT id FROM device WHERE imei = :imei LIMIT 1", imei)
    

    What is wrong with it?

    opened by paulocoutinhox 13
  • sqlx.Connect(

    sqlx.Connect("postgres", addr) freezes

    I'm building a docker image with a simple sqlx connection and running it in docker-compose. For some reason, the statement see snippet below does not connect or error out, it just freezes. No idea why. It is related to using alpine:latest docker base image. I have not tracked down the issue completely but connecting to the image from the psql cli works like a charm (with the same connection string as used for in the statement (addr).

    The code I've used in my setup:

    package main
    
    import (
    	"fmt"
    	"github.com/jmoiron/sqlx"
    	_ "github.com/lib/pq"
    	"os"
    )
    
    func main() {
    	addr := os.Getenv("DB")
    	fmt.Println("Postgres addr: " + addr)
    
    	_, err := sqlx.Connect("postgres", addr)
    
    	if err != nil {
    		fmt.Println("Could not connect...")
    	} else {
    		fmt.Println("Connecting successful")
    	}
    }
    

    As stated above, this code causes problem when building a go executable that is run within a container based on the image alpine:latest, together with *docker-compose`.

    I have set up a test project to reproduce the problems I am facing with: https://github.com/mraxus/mystery-golang-alpine

    Would love to get some help into this and hope this is an actual bug in your lib (otherwise I am wasting your time, which is not my intention)

    Cheers, Marcus

    opened by mraxus 12
  • compilation failed for go1.6rc2

    compilation failed for go1.6rc2

    Hi,

    I tried to run "go get github.com/jmoiron/sqlx" *_# runtime /usr/local/go/src/runtime/os2_linux_generic.go:12: _SS_DISABLE redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:8 /usr/local/go/src/runtime/os2_linux_generic.go:13: _NSIG redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:9 /usr/local/go/src/runtime/os2_linux_generic.go:14: _SI_USER redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:10 /usr/local/go/src/runtime/os2_linux_generic.go:15: _SIG_BLOCK redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:11 /usr/local/go/src/runtime/os2_linux_generic.go:16: _SIG_UNBLOCK redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:12 /usr/local/go/src/runtime/os2_linux_generic.go:17: _SIG_SETMASK redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:13 /usr/local/go/src/runtime/os2_linux_generic.go:18: RLIMIT_AS redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:14 /usr/local/go/src/runtime/os2_linux_generic.go:24: sigset redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:20 /usr/local/go/src/runtime/os2_linux_generic.go:26: rlimit redeclared in this block previous declaration at /usr/local/go/src/runtime/os2_linux.go:22 /usr/local/go/src/runtime/panic1.go:11: paniclk redeclared in this block previous declaration at /usr/local/go/src/runtime/panic.go:535 /usr/local/go/src/runtime/panic1.go:11: too many errors *

    Could you take a look.

    Best Regards,

    opened by Son-Lam 12
  • got XXXX parameters but the statement requires YY - potential BUG in 1.3.0

    got XXXX parameters but the statement requires YY - potential BUG in 1.3.0

    Hello,

    Seems after upgrading to version 1.3.0 this do not work anymore:

    // batch insert with structs
    
    personStructs := []Person{
        {FirstName: "Ardie", LastName: "Savea", Email: "[email protected]"},
        {FirstName: "Sonny Bill", LastName: "Williams", Email: "[email protected]"},
        {FirstName: "Ngani", LastName: "Laumape", Email: "[email protected]"},
    }
    
    _, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)
        VALUES (:first_name, :last_name, :email)`, personStructs)
    

    I on my queries getting: pq: got XXXX parameters but the statement requires YY

    but YY is not 65535 it is number of columns, in above example would be YY=3.

    This is since >=1.3.0 version, earlier versions everything works.

    Best regards, Alexandar

    opened by drsasa 11
  • Missing destination name id

    Missing destination name id

    I'm trying to get all rows from a table in a postgres database but I get the following error "Missing destination name id" even if the id exists on the model.

    Can anyone help?

    Thanks,

    opened by mahaben 11
  • LastInsertedId should be LastInsertedID?

    LastInsertedId should be LastInsertedID?

    opened by Narven 11
  • NamedStatement cast issues

    NamedStatement cast issues

    I have the following code:

        sql :=
        `UPDATE giftcards
              SET balance = balance + :purchase
              WHERE account =
                (SELECT account
                 FROM giftcards g JOIN giftcard_txs t ON g.id = t.giftcard_id
                 WHERE t.invoice_no = :invoice_no
                   AND t.ref_no = :ref_no
                   AND t.location_id = :location_id
                   AND t.command = :command
                   AND t.purchase = :purchase) AND org_id = :org_id AND issued = TRUE
            RETURNING *;`
        nstmt, err := tx.PrepareNamed(sql)
        if err != nil {
            return abandon(tx, err, "could not prepare named statement")
        }
        var card api.GiftCard
        params := map[string]interface{}{
            "purchase":    100.00,
            "invoice_no":  "1234567890",
            "ref_no":      "xl9gO6BvvhAIqg==",
            "location_id": 1,
            "command":     "Sale",
            "org_id":      1,
        }
        log.Debug(sql, "params", params)
        if err := nstmt.QueryRowx(params).StructScan(&card); err != nil {
            return abandon(tx, err, "could not update giftcard balance to void sale")
        }
    

    This code executes OK, and indeed, if I plug the query into psql and execute with values instead of named params, it executes fine.

    The trouble is when I construct the map like this (referencing fields off a go struct instead of pasting in literals like above):

    var purchase = gctx.Authorize + gctx.Gratuity
    params := map[string]interface{}{
        "purchase":    purchase,
        "invoice_no":  gctx.InvoiceNo,
        "ref_no":      gctx.RefNo,
        "location_id": loc.ID,
        "command":     api.Sale,
        "org_id":      loc.OrgID,
    }
    

    It errors out with: pq: syntax error at or near "invoice_no". It seems like it is casting InvoiceNo to a numeric type?

    When I print the params map with:

    fmt.Printf("\nMAP %#v\n", params)
    

    It prints as

    MAP map[string]interface {}{"location_id":1, "command":"Sale", "org_id":1, "purchase":100, "invoice_no":"1234567890", "ref_no":"DNoet3vY2RgBtQ=="}
    

    So, the types are there, and as expected, i.e. "invoice_no" is a string.

    The table structure in question giftcard_txs:

    +-------------+--------------------------+--------------------------------------------------+
    | Column      | Type                     | Modifiers                                        |
    |-------------+--------------------------+--------------------------------------------------|
    | id          | bigint                   | not null default nextval('txs_id_seq'::regclass) |
    | created_at  | timestamp with time zone | not null                                         |
    | command     | command                  | not null                                         |
    | invoice_no  | character varying(25)    | not null                                         |
    | ref_no      | character varying(25)    | not null                                         |
    | authorize   | numeric(10,2)            | not null                                         |
    | gratuity    | numeric(10,2)            | not null default 0.00                            |
    | purchase    | numeric(10,2)            | not null                                         |
    | memo        | character varying(50)    |                                                  |
    | terminal    | character varying(35)    |                                                  |
    | operator    | character varying(35)    |                                                  |
    | hash        | character varying(100)   | not null                                         |
    | voided      | boolean                  | default false                                    |
    | giftcard_id | integer                  | not null                                         |
    | location_id | integer                  | not null                                         |
    | void_id     | bigint                   |                                                  |
    +-------------+--------------------------+--------------------------------------------------+
    

    Any idea what the deal is here?

    opened by davisford 11
  • README updates.

    README updates.

    Just a couple of README fixes:

    • I've fixed the syntax error around sqlx.Open (which returns both a *DB and an error)
    • I've added an example for inserting a struct as although the README indicates it can be done, it doesn't show an example.

    I also wouldn't mind adding an example for using rows.Next() to scan into a slice of structs, but before I do that: is there any intention to provide a rows.ScanAll(interface{}) method to do this automatically?

    opened by elithrar 10
  • Invalid character error

    Invalid character error

    If you use go-ora v2 driver (https://github.com/sijms/go-ora) and try to execute an INSERT statement you get "ORA-00911: invalid character" error when parameters are being substituted.

    This is how the code looks like:

    type Mini struct {
    	Id int32 `db:"id"`
    }
    func (db *sqlx.DB) Save() error {
        testInsert := []Mini{
            { Id: 77 },
        }
        stmt := "INSERT INTO table_a (ID, CODE) VALUES (:id, 9)"
        _, err : = db.NamedExec(stmt, testInsert)
        return err
    }
    

    Adding "oracle" to the defaultBinds in file binds.go solves the issue.

    var defaultBinds = map[int][]string{
    	DOLLAR:   []string{"postgres", "pgx", "pq-timeouts", "cloudsqlpostgres", "ql", "nrpostgres", "cockroach"},
    	QUESTION: []string{"mysql", "sqlite3", "nrmysql", "nrsqlite3"},
    	NAMED:    []string{"oci8", "ora", "goracle", "godror", "oracle"},
    	AT:       []string{"sqlserver"},
    }
    

    I submitted a pull request with this fix (https://github.com/jmoiron/sqlx/pull/819). Let me know if you have any concerns.

    opened by ifletcher5 0
  • MapScan issue on Mssql with numeric type

    MapScan issue on Mssql with numeric type

    If I try get select data (value of type numeric) from server using StructScan and db tag on struct - everything works OK? but when I use MapScan I got []byte instead of float64. Code to reproduce :

    package main

    import ( "fmt" "log" "strings"

    _ "github.com/denisenkom/go-mssqldb"
    "github.com/jmoiron/sqlx"
    

    )

    func main() {

    db, err := sqlx.Connect("sqlserver", "sqlserver://***@***?database=***")
    if err != nil {
    	log.Fatalf("Cann not connect to DB: %s", err)
    }
    db.MapperFunc(strings.ToUpper)
    getMap(db)
    getStruct(db)
    

    }

    func getMap(db *sqlx.DB) { r := []map[string]interface{}{} rows, err := db.Queryx(" select cast( 10.8 as numeric) val") if err != nil { log.Fatalf("Can not query %s:", err) } for rows.Next() { res := map[string]interface{}{} rows.MapScan(res) r = append(r, res)

    }
    
    for _, v := range r {
    	for k, val := range v {
    
    		fmt.Printf("%s value: %s", k, isNull(val))
    
    		fmt.Printf("\n")
    
    	}
    }
    

    }

    type Prod struct { Val float64 db:"val" }

    func getStruct(db *sqlx.DB) { r := []Prod{} rows, err := db.Queryx(" select cast( 10.8 as numeric) val") if err != nil { log.Fatalf("Can not query %s:", err) } for rows.Next() { res := Prod{} rows.StructScan(&res) //fmt.Printf("Result:%#v\n", res) r = append(r, res)

    }
    
    fmt.Printf("val value: %#v", r)
    

    }

    func isNull(v interface{}) string { if v == nil { return "NULL" } else {

    	switch val := v.(type) {
    	case string:
    		return fmt.Sprintf("'%v'", val)
    	case int64:
    		return fmt.Sprintf("%v", val)
    	case float64:
    		return fmt.Sprintf("%v", val)
    
    	default:
    		return fmt.Sprintf("%#v", val)
    
    	}
    
    }
    

    }

    Execution result:
    val value: []byte{0x31, 0x31} val value: []main.Prod{main.Prod{Val:11}} How can I fix it?

    opened by Ivan-Nikulin 0
  • fix: bindArray on SELECT from VALUES list

    fix: bindArray on SELECT from VALUES list

    • fixBound currently assumes named var in VALUES is only from INSERT
    • bindArrayis not populating the right number of placeholders

    Ideally the regex should be something like: (?<!(?i)into)\W+(?i)VALUES\s*\( but Golang regex doesn't support look around

    opened by Phoenix1708 1
  • use NamedExec to batch update,but got error

    use NamedExec to batch update,but got error

    modifyRulesSql := update public."casbin_rule_auth" set v2=:v2 where v0=:v0 and v1=:v1 _, err = db.NamedExec(testSql, roleAuthPs) when i use update, got this error: pq: got 15 parameters but the statement requires 3

    testSql := insert into public."casbin_rule_auth"(p_type, v0, v1, v2) values('p', :v0, :v1, :v2) _, err = db.NamedExec(testSql, roleAuthPs) if i use insert, it can work

    how can i solve this problem.i want to batch update,how can i do?

    opened by liwilljinx 2
  • Add Queryable interface

    Add Queryable interface

    I came across https://github.com/jmoiron/sqlx/issues/344 and thought it may be useful to open a PR proposing this change since it looks like a few folks could find it useful.


    When writing applications it's useful to pass a sqlx.DB and a sqlx.Tx interchangeably so that you can compose functions that are runnable in isolation or as part of a transaction.

    This introduces the Queryable interface, which includes the common exportable methods shared between sqlx.DB and sqlx.Tx so users of the package don't have to implement it themselves.

    This also adds tests that validate any new shared methods are added to the interface.

    opened by BlakeWilliams 0
PolarDB Cluster Manager is the cluster management component of PolarDB for PostgreSQL, responsible for topology management, high availability, configuration management, and plugin extensions.

What is PolarDB Cluster Manager PolarDB Cluster Manager is the cluster management component of PolarDB for PostgreSQL, responsible for topology manage

null 8 Dec 15, 2021
write APIs using direct SQL queries with no hassle, let's rethink about SQL

SQLer SQL-er is a tiny portable server enables you to write APIs using SQL query to be executed when anyone hits it, also it enables you to define val

Mohammed Al Ashaal 2k Jun 24, 2022
Parses a file and associate SQL queries to a map. Useful for separating SQL from code logic

goyesql This package is based on nleof/goyesql but is not compatible with it any more. This package introduces support for arbitrary tag types and cha

null 0 Oct 20, 2021
Go-sql-reader - Go utility to read the externalised sql with predefined tags

go-sql-reader go utility to read the externalised sql with predefined tags Usage

null 0 Jan 25, 2022
A go Library for scan database/sql rows to struct、slice、other types. And it support multiple databases connection management

ploto A go Library for scan database/sql rows to struct、slice、other types. And it support multiple databases connection management It's not an ORM. wo

solar 2 Mar 16, 2022
Dumpling is a fast, easy-to-use tool written by Go for dumping data from the database(MySQL, TiDB...) to local/cloud(S3, GCP...) in multifarious formats(SQL, CSV...).

?? Dumpling Dumpling is a tool and a Go library for creating SQL dump from a MySQL-compatible database. It is intended to replace mysqldump and mydump

PingCAP 260 Jun 10, 2022
Additions to Go's database/sql for super fast performance and convenience.

gocraft/dbr (database records) gocraft/dbr provides additions to Go's database/sql for super fast performance and convenience. $ go get -u github.com/

null 1.7k Jun 29, 2022
Interceptors for database/sql

sqlmw sqlmw provides an absurdly simple API that allows a caller to wrap a database/sql driver with middleware. This provides an abstraction similar t

null 407 Jun 23, 2022
OpenTelemetry instrumentation for database/sql

otelsql It is an OpenTelemetry instrumentation for Golang database/sql, a port from https://github.com/open-telemetry/opentelemetry-go-contrib/pull/50

Sam Xie 92 Jun 18, 2022
Scan database/sql rows directly to structs, slices, and primitive types

Scan Scan standard lib database rows directly to structs or slices. For the most comprehensive and up-to-date docs see the godoc Examples Multiple Row

Brett Jones 273 Jun 22, 2022
Prometheus metrics for Go database/sql via VictoriaMetrics/metrics

sqlmetrics Prometheus metrics for Go database/sql via VictoriaMetrics/metrics Features Simple API. Easy to integrate. Install Go version 1.16+ go get

cristaltech 21 Jan 22, 2022
Attach hooks to any database/sql driver

sqlhooks Attach hooks to any database/sql driver. The purpose of sqlhooks is to provide a way to instrument your sql statements, making really easy to

Gustavo Chaín 551 Jun 23, 2022
Go database/sql

Go database/sql 源码阅读 基于 release-branch.go1.17 Benchmark 连接池测试 简单介绍 database/sql 库,包括结构体和主要的方法 介绍主要函数的调用逻辑 用OneNote看源码:Link 介绍最近几个版本的commit changes 结合实

x509 0 Dec 18, 2021
Sqlbench runs benchmarks on an SQL database

sqlbench runs benchmarks on an SQL database. Right now this works for PostgreSQL

Martin Tournoij 1 Dec 20, 2021
Lightweight SQL database written in Go for prototyping and playing with text (CSV, JSON) data

gopicosql Lightweight SQL database written in Go for prototyping and playing wit

null 2 May 17, 2022
BigQuery database/sql golang driver

BigQuery SQL Driver This library is compatible with Go 1.17+ Please refer to CHA

Viant, Inc 5 Jun 7, 2022
A minimal, single-table No-SQL database.

SimpleDB SimpleDB is a very basic No-SQL database format for long-term data storage in Golang. It is WIP, has a LOT of drawbacks, and definitely is no

Konnor Klashinsky 0 Jan 16, 2022
Otelsql - OpenTelemetry SQL database driver wrapper for Go

OpenTelemetry SQL database driver wrapper for Go Add a OpenTelemetry wrapper to

Nhat 24 Jun 15, 2022