Files
gocqlx/README.md
2017-08-02 11:16:31 +02:00

4.5 KiB

gocqlx GoDoc Go Report Card Build Status

Package gocqlx is a Scylla / Cassandra productivity toolkit for gocql. It's similar to what sqlx is to database/sql.

It contains wrappers over gocql types that provide convenience methods which are useful in the development of database driven applications. Under the hood it uses sqlx/reflectx package so sqlx models will also work with gocqlx.

Installation

go get github.com/scylladb/gocqlx

Features

Fast, boilerplate free and flexible SELECTS, INSERTS, UPDATES and DELETES.

type Person struct {
	FirstName string  // no need to add `db:"first_name"` etc.
	LastName  string
	Email     []string
}

p := &Person{
	"Patricia",
	"Citizen",
	[]string{"patricia.citzen@gocqlx_test.com"},
}

// Insert
{
    stmt, names := qb.Insert("person").Columns("first_name", "last_name", "email").ToCql()
    q := gocqlx.Query(session.Query(stmt), names)

    if err := q.BindStruct(p).Exec(); err != nil {
        log.Fatal(err)
    }
}

// Insert with TTL
{
    stmt, names := qb.Insert("person").Columns("first_name", "last_name", "email").TTL().ToCql()
    q := gocqlx.Query(session.Query(stmt), names)

    if err := q.BindStructMap(p, qb.M{"_ttl": qb.TTL(86400 * time.Second)}).Exec(); err != nil {
        log.Fatal(err)
    }
}

// Update
{
    p.Email = append(p.Email, "patricia1.citzen@gocqlx_test.com")

    stmt, names := qb.Update("person").Set("email").Where(qb.Eq("first_name"), qb.Eq("last_name")).ToCql()
    q := gocqlx.Query(session.Query(stmt), names)

    if err := q.BindStruct(p).Exec(); err != nil {
        log.Fatal(err)
    }
}

// Select
{
    stmt, names := qb.Select("person").Where(qb.In("first_name")).ToCql()
    q := gocqlx.Query(session.Query(stmt), names)

    q.BindMap(qb.M{"first_name": []string{"Patricia", "John"}})
    if err := q.Err(); err != nil {
        log.Fatal(err)
    }

    var people []Person
    if err := gocqlx.Select(&people, q.Query); err != nil {
        log.Fatal("select:", err)
    }
    log.Println(people)

    // [{Patricia Citizen [patricia.citzen@com patricia1.citzen@com]} {John Doe [johndoeDNE@gmail.net]}]
}

For more details see example test.

Performance

Gocqlx is fast, below is a benchmark result comparing gocqlx to raw gocql on my machine, see the benchmark here.

For query binding gocqlx is faster as it does not require parameter rewriting while binding. For get and insert the performance is comparable.

BenchmarkE2EGocqlInsert-4           1000           1580420 ns/op            2624 B/op         59 allocs/op
BenchmarkE2EGocqlxInsert-4          2000            648769 ns/op            1557 B/op         34 allocs/op
BenchmarkE2EGocqlGet-4              3000            664618 ns/op            1086 B/op         29 allocs/op
BenchmarkE2EGocqlxGet-4             3000            631415 ns/op            1440 B/op         32 allocs/op
BenchmarkE2EGocqlSelect-4             50          35646283 ns/op           34072 B/op        922 allocs/op
BenchmarkE2EGocqlxSelect-4            50          37128897 ns/op           28304 B/op        933 allocs/op

Gocqlx comes with automatic snake case support for field names and does not require manual tagging. This is also fast, below is a comparison to strings.ToLower function (sqlx default).

BenchmarkSnakeCase-4            10000000               124 ns/op              32 B/op          2 allocs/op
BenchmarkToLower-4              100000000               57.9 ns/op             0 B/op          0 allocs/op

Building queries is fast and low on allocations too.

BenchmarkCmp-4                   3000000               464 ns/op             112 B/op          3 allocs/op
BenchmarkDeleteBuilder-4        10000000               214 ns/op             112 B/op          2 allocs/op
BenchmarkInsertBuilder-4        20000000               103 ns/op              64 B/op          1 allocs/op
BenchmarkSelectBuilder-4        10000000               214 ns/op             112 B/op          2 allocs/op
BenchmarkUpdateBuilder-4        10000000               212 ns/op             112 B/op          2 allocs/op

Enyoy!