Skip to content

All-In-One: CQL query builder, ORM and migration tool

License

Notifications You must be signed in to change notification settings

Ivan-Feofanov/gocqlx

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 GocqlX GoDoc Go Report Card Build Status

GocqlX makes working with Scylla easy and less error-prone. It’s inspired by Sqlx, a tool for working with SQL databases, but it goes beyond what Sqlx provides.

Features

  • Binding query parameters from struct fields, map, or both
  • Scanning query results into structs based on field names
  • Convenient functions for common tasks such as loading a single row into a struct or all rows into a slice (list) of structs
  • Making any struct a UDT without implementing marshalling functions
  • GocqlX is fast. Its performance is comparable to raw driver. You can find some benchmarks here.

Subpackages provide additional functionality:

Installation

    go get -u github.com/scylladb/gocqlx/v2

Getting started

Wrap gocql Session:

// Create gocql cluster.
cluster := gocql.NewCluster(hosts...)
// Wrap session on creation, gocqlx session embeds gocql.Session pointer. 
session, err := gocqlx.WrapSession(cluster.CreateSession())
if err != nil {
	t.Fatal(err)
}

Specify table model:

// metadata specifies table name and columns it must be in sync with schema.
var personMetadata = table.Metadata{
	Name:    "person",
	Columns: []string{"first_name", "last_name", "email"},
	PartKey: []string{"first_name"},
	SortKey: []string{"last_name"},
}

// personTable allows for simple CRUD operations based on personMetadata.
var personTable = table.New(personMetadata)

// Person represents a row in person table.
// Field names are converted to camel case by default, no need to add special tags.
// A field will not be persisted by adding the `db:"-"` tag or making it unexported.
type Person struct {
	FirstName string
	LastName  string
	Email     []string
	HairColor string `db:"-"`  // exported and skipped
	eyeColor  string           // unexported also skipped
}

Bind data from a struct and insert a row:

p := Person{
	"Michał",
	"Matczuk",
	[]string{"michal@scylladb.com"},
	"red",    // not persisted
	"hazel"   // not persisted
}
q := session.Query(personTable.Insert()).BindStruct(p)
if err := q.ExecRelease(); err != nil {
	t.Fatal(err)
}

Load a single row to a struct:

p := Person{
	"Michał",
	"Matczuk",
	nil, // no email
}
q := session.Query(personTable.Get()).BindStruct(p)
if err := q.GetRelease(&p); err != nil {
	t.Fatal(err)
}
t.Log(p)
// stdout: {Michał Matczuk [michal@scylladb.com]}

Load all rows in to a slice:

var people []Person
q := session.Query(personTable.Select()).BindMap(qb.M{"first_name": "Michał"})
if err := q.SelectRelease(&people); err != nil {
	t.Fatal(err)
}
t.Log(people)
// stdout: [{Michał Matczuk [michal@scylladb.com]}]

Generating table metadata with schemagen

Installation

go get -u "github.com/scylladb/gocqlx/v2/cmd/schemagen"

Usage:

$GOBIN/schemagen [flags]

Flags:
  -cluster string
    	a comma-separated list of host:port tuples (default "127.0.0.1")
  -keyspace string
    	keyspace to inspect (required)
  -output string
    	the name of the folder to output to (default "models")
  -pkgname string
    	the name you wish to assign to your generated package (default "models") 

Example:

Running the following command for examples keyspace:

$GOBIN/schemagen -cluster="127.0.0.1:9042" -keyspace="examples" -output="models" -pkgname="models"

Generates models/models.go as follows:

// Code generated by "gocqlx/cmd/schemagen"; DO NOT EDIT.

package models

import "github.com/scylladb/gocqlx/v2/table"

// Table models.
var (
	Playlists = table.New(table.Metadata{
		Name: "playlists",
		Columns: []string{
			"album",
			"artist",
			"id",
			"song_id",
			"title",
		},
		PartKey: []string{
			"id",
		},
		SortKey: []string{
			"title",
			"album",
			"artist",
		},
	})

	Songs = table.New(table.Metadata{
		Name: "songs",
		Columns: []string{
			"album",
			"artist",
			"data",
			"id",
			"tags",
			"title",
		},
		PartKey: []string{
			"id",
		},
		SortKey: []string{},
	})
)

Examples

You can find lots of examples in example_test.go.

Go and run them locally:

make run-scylla
make run-examples

Testing

For the testing purpose you can use gocqlxtest package:

session := gocqlxtest.CreateSession(t)

To configure test session connection you can use both command-line arguments and environment variables:

CLI flag Environment Variable Type Description Default
cluster CLUSTER string Comma-separated list of host:port tuples 127.0.0.1
keyspace KEYSPACE string Keyspace name gocqlx_test
proto PROTO int Protocol version 0
cql CQL string CQL version 3.0.0
rf RF int Replication factor for test keyspace 1
retries RETRIES int Number of times to retry queries 5
compressor COMPRESSOR string Compressor to use
gocql.timeout GOCQL.TIMEOUT duration Sets the connection timeout for all operations 5s

Performance

GocqlX performance is comparable to the raw gocql driver. Below benchmark results running on my laptop.

BenchmarkBaseGocqlInsert            2392            427491 ns/op            7804 B/op         39 allocs/op
BenchmarkGocqlxInsert               2479            435995 ns/op            7803 B/op         39 allocs/op
BenchmarkBaseGocqlGet               2853            452384 ns/op            7309 B/op         35 allocs/op
BenchmarkGocqlxGet                  2706            442645 ns/op            7646 B/op         38 allocs/op
BenchmarkBaseGocqlSelect             747           1664365 ns/op           49415 B/op        927 allocs/op
BenchmarkGocqlxSelect                667           1877859 ns/op           42521 B/op        932 allocs/op

See the benchmark in benchmark_test.go.

License

Copyright (C) 2017 ScyllaDB

This project is distributed under the Apache 2.0 license. See the LICENSE file for details. It contains software from:

Apache®, Apache Cassandra® are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries. No endorsement by The Apache Software Foundation is implied by the use of these marks.

GitHub star is always appreciated!

About

All-In-One: CQL query builder, ORM and migration tool

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 99.4%
  • Makefile 0.6%