gocqlx

package module
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 8, 2020 License: Apache-2.0 Imports: 8 Imported by: 36

README

GoCQLX GoDoc Go Report Card Build Status

Package gocqlx is an idiomatic extension to gocql that provides usability features. With gocqlx you can bind the query parameters from maps and structs, use named query parameters (:identifier) and scan the query results into structs and slices. It comes with a fluent and flexible CQL query builder and a database migrations module.

Installation

go get -u github.com/scylladb/gocqlx

Features

  • Binding query parameters form struct or map
  • Scanning results directly into struct or slice
  • CQL query builder (package qb)
  • Super simple CRUD operations based on table model (package table)
  • Database migrations (package migrate)
  • Fast!

Training and Scylla University

Scylla University includes training material and online courses which will help you become a Scylla NoSQL database expert. The course Using Scylla Drivers explains how to use drivers in different languages to interact with a Scylla cluster. The lesson, Golang and Scylla Part 3 includes a sample application that uses the GoCQXL package. It connects to a Scylla cluster, displays the contents of a table, inserts and deletes data, and shows the contents of the table after each action. Courses in Scylla University cover a variety of topics dealing with Scylla data modeling, administration, architecture and also covering some basic NoSQL concepts.

Example

// Person represents a row in person table.
// Field names are converted to camel case by default, no need to add special tags.
// If you want to disable a field add `db:"-"` tag, it will not be persisted.
type Person struct {
    FirstName string
    LastName  string
    Email     []string
}

// Insert, bind data from struct.
{
    stmt, names := qb.Insert("gocqlx_test.person").Columns("first_name", "last_name", "email").ToCql()
    q := gocqlx.Query(session.Query(stmt), names).BindStruct(p)

    if err := q.ExecRelease(); err != nil {
        t.Fatal(err)
    }
}
// Get first result into a struct.
{
    var p Person
    stmt, names := qb.Select("gocqlx_test.person").Where(qb.Eq("first_name")).ToCql()
    q := gocqlx.Query(session.Query(stmt), names).BindMap(qb.M{
        "first_name": "Patricia",
    })
    if err := q.GetRelease(&p); err != nil {
        t.Fatal(err)
    }
}
// Load all the results into a slice.
{
    var people []Person
    stmt, names := qb.Select("gocqlx_test.person").Where(qb.In("first_name")).ToCql()
    q := gocqlx.Query(session.Query(stmt), names).BindMap(qb.M{
        "first_name": []string{"Patricia", "Igy", "Ian"},
    })
    if err := q.SelectRelease(&people); err != nil {
        t.Fatal(err)
    }
}

// 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)

// Get by primary key.
{
    p := Person{
        "Patricia",
        "Citizen",
        nil, // no email
    }
    stmt, names := personTable.Get() // you can filter columns too
    q := gocqlx.Query(session.Query(stmt), names).BindStruct(p)
    if err := q.GetRelease(&p); err != nil {
        t.Fatal(err)
    }
}

See more examples in example_test.go and table/example_test.go.

Performance

Gocqlx is fast, this is a benchmark result comparing gocqlx to raw gocql on a local machine, Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz.

BenchmarkE2EGocqlInsert            20000             86713 ns/op            2030 B/op         33 allocs/op
BenchmarkE2EGocqlxInsert           20000             87882 ns/op            2030 B/op         33 allocs/op
BenchmarkE2EGocqlGet               20000             94308 ns/op            1504 B/op         29 allocs/op
BenchmarkE2EGocqlxGet              20000             95722 ns/op            2128 B/op         33 allocs/op
BenchmarkE2EGocqlSelect             1000           1792469 ns/op           43595 B/op        921 allocs/op
BenchmarkE2EGocqlxSelect            1000           1839574 ns/op           36986 B/op        927 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!

Documentation

Overview

Package gocqlx is an idiomatic extension to gocql that provides usability features. With gocqlx you can bind the query parameters from maps and structs, use named query parameters (:identifier) and scan the query results into structs and slices. It comes with a fluent and flexible CQL query builder and a database migrations module.

Index

Constants

This section is empty.

Variables

View Source
var DefaultMapper = reflectx.NewMapperFunc("db", reflectx.CamelToSnakeASCII)

DefaultMapper uses `db` tag and automatically converts struct field names to snake case. It can be set to whatever you want, but it is encouraged to be set before gocqlx is used as name-to-field mappings are cached after first use on a type.

View Source
var DefaultUnsafe bool

DefaultUnsafe enables the behavior of forcing the iterator to ignore missing fields for all queries. See Unsafe below for more information.

Functions

func CompileNamedQuery

func CompileNamedQuery(qs []byte) (stmt string, names []string, err error)

CompileNamedQuery translates query with named parameters in a form ':<identifier>' to query with '?' placeholders and a list of parameter names. If you need to use ':' in a query, i.e. with maps or UDTs use '::' instead.

func Get

func Get(dest interface{}, q *gocql.Query) error

Get is a convenience function for creating iterator and calling Get.

DEPRECATED use Queryx.Get or Queryx.GetRelease.

func Select

func Select(dest interface{}, q *gocql.Query) error

Select is a convenience function for creating iterator and calling Select.

DEPRECATED use Queryx.Select or Queryx.SelectRelease.

Types

type Iterx

type Iterx struct {
	*gocql.Iter

	Mapper *reflectx.Mapper
	// contains filtered or unexported fields
}

Iterx is a wrapper around gocql.Iter which adds struct scanning capabilities.

func Iter

func Iter(q *gocql.Query) *Iterx

Iter creates a new Iterx from gocql.Query using a default mapper.

func (*Iterx) Close

func (iter *Iterx) Close() error

Close closes the iterator and returns any errors that happened during the query or the iteration.

func (*Iterx) Get

func (iter *Iterx) Get(dest interface{}) error

Get scans first row into a destination and closes the iterator. If the destination type is a struct pointer, then StructScan will be used. If the destination is some other type, then the row must only have one column which can scan into that type.

If no rows were selected, ErrNotFound is returned.

func (*Iterx) Select

func (iter *Iterx) Select(dest interface{}) error

Select scans all rows into a destination, which must be a pointer to slice of any type and closes the iterator. If the destination slice type is a struct, then StructScan will be used on each row. If the destination is some other type, then each row must only have one column which can scan into that type.

If no rows were selected, ErrNotFound is NOT returned.

func (*Iterx) StructScan

func (iter *Iterx) StructScan(dest interface{}) bool

StructScan is like gocql.Iter.Scan, but scans a single row into a single struct. Use this and iterate manually when the memory load of Select() might be prohibitive. StructScan caches the reflect work of matching up column positions to fields to avoid that overhead per scan, which means it is not safe to run StructScan on the same Iterx instance with different struct types.

func (*Iterx) Unsafe

func (iter *Iterx) Unsafe() *Iterx

Unsafe forces the iterator to ignore missing fields. By default when scanning a struct if result row has a column that cannot be mapped to any destination field an error is reported. With unsafe such columns are ignored.

type Queryx

type Queryx struct {
	*gocql.Query
	Names  []string
	Mapper *reflectx.Mapper
	// contains filtered or unexported fields
}

Queryx is a wrapper around gocql.Query which adds struct binding capabilities.

func Query

func Query(q *gocql.Query, names []string) *Queryx

Query creates a new Queryx from gocql.Query using a default mapper.

func (*Queryx) Bind added in v1.2.0

func (q *Queryx) Bind(v ...interface{}) *Queryx

Bind sets query arguments of query. This can also be used to rebind new query arguments to an existing query instance.

func (*Queryx) BindMap

func (q *Queryx) BindMap(arg map[string]interface{}) *Queryx

BindMap binds query named parameters using map.

func (*Queryx) BindStruct

func (q *Queryx) BindStruct(arg interface{}) *Queryx

BindStruct binds query named parameters to values from arg using mapper. If value cannot be found error is reported.

func (*Queryx) BindStructMap

func (q *Queryx) BindStructMap(arg0 interface{}, arg1 map[string]interface{}) *Queryx

BindStructMap binds query named parameters to values from arg0 and arg1 using a mapper. If value cannot be found in arg0 it's looked up in arg1 before reporting an error.

func (*Queryx) Consistency added in v1.2.0

func (q *Queryx) Consistency(c gocql.Consistency) *Queryx

Consistency sets the consistency level for this query. If no consistency level have been set, the default consistency level of the cluster is used.

func (*Queryx) CustomPayload added in v1.2.0

func (q *Queryx) CustomPayload(customPayload map[string][]byte) *Queryx

CustomPayload sets the custom payload level for this query.

func (*Queryx) DefaultTimestamp added in v1.2.0

func (q *Queryx) DefaultTimestamp(enable bool) *Queryx

DefaultTimestamp will enable the with default timestamp flag on the query. If enable, this will replace the server side assigned timestamp as default timestamp. Note that a timestamp in the query itself will still override this timestamp. This is entirely optional.

Only available on protocol >= 3

func (*Queryx) Err

func (q *Queryx) Err() error

Err returns any binding errors.

func (*Queryx) Exec

func (q *Queryx) Exec() error

Exec executes the query without returning any rows.

func (*Queryx) ExecRelease

func (q *Queryx) ExecRelease() error

ExecRelease calls Exec and releases the query, a released query cannot be reused.

func (*Queryx) Get

func (q *Queryx) Get(dest interface{}) error

Get scans first row into a destination. If the destination type is a struct pointer, then Iter.StructScan will be used. If the destination is some other type, then the row must only have one column which can scan into that type.

If no rows were selected, ErrNotFound is returned.

func (*Queryx) GetRelease

func (q *Queryx) GetRelease(dest interface{}) error

GetRelease calls Get and releases the query, a released query cannot be reused.

func (*Queryx) Idempotent added in v1.2.0

func (q *Queryx) Idempotent(value bool) *Queryx

Idempotent marks the query as being idempotent or not depending on the value.

func (*Queryx) Iter added in v1.1.0

func (q *Queryx) Iter() *Iterx

Iter returns Iterx instance for the query. It should be used when data is too big to be loaded with Select in order to do row by row iteration. See Iterx StructScan function.

func (*Queryx) NoSkipMetadata added in v1.2.0

func (q *Queryx) NoSkipMetadata() *Queryx

NoSkipMetadata will override the internal result metadata cache so that the driver does not send skip_metadata for queries, this means that the result will always contain the metadata to parse the rows and will not reuse the metadata from the prepared staement. This should only be used to work around cassandra bugs, such as when using CAS operations which do not end in Cas.

See https://issues.apache.org/jira/browse/CASSANDRA-11099 https://github.com/gocql/gocql/issues/612

func (*Queryx) Observer added in v1.2.0

func (q *Queryx) Observer(observer gocql.QueryObserver) *Queryx

Observer enables query-level observer on this query. The provided observer will be called every time this query is executed.

func (*Queryx) PageSize added in v1.2.0

func (q *Queryx) PageSize(n int) *Queryx

PageSize will tell the iterator to fetch the result in pages of size n. This is useful for iterating over large result sets, but setting the page size too low might decrease the performance. This feature is only available in Cassandra 2 and onwards.

func (*Queryx) PageState added in v1.2.0

func (q *Queryx) PageState(state []byte) *Queryx

PageState sets the paging state for the query to resume paging from a specific point in time. Setting this will disable to query paging for this query, and must be used for all subsequent pages.

func (*Queryx) Prefetch added in v1.2.0

func (q *Queryx) Prefetch(p float64) *Queryx

Prefetch sets the default threshold for pre-fetching new pages. If there are only p*pageSize rows remaining, the next page will be requested automatically.

func (*Queryx) RetryPolicy added in v1.2.0

func (q *Queryx) RetryPolicy(r gocql.RetryPolicy) *Queryx

RetryPolicy sets the policy to use when retrying the query.

func (*Queryx) RoutingKey added in v1.2.0

func (q *Queryx) RoutingKey(routingKey []byte) *Queryx

RoutingKey sets the routing key to use when a token aware connection pool is used to optimize the routing of this query.

func (*Queryx) Select

func (q *Queryx) Select(dest interface{}) error

Select scans all rows into a destination, which must be a pointer to slice of any type. If the destination slice type is a struct, then Iter.StructScan will be used on each row. If the destination is some other type, then each row must only have one column which can scan into that type.

If no rows were selected, ErrNotFound is NOT returned.

func (*Queryx) SelectRelease

func (q *Queryx) SelectRelease(dest interface{}) error

SelectRelease calls Select and releases the query, a released query cannot be reused.

func (*Queryx) SerialConsistency added in v1.2.0

func (q *Queryx) SerialConsistency(cons gocql.SerialConsistency) *Queryx

SerialConsistency sets the consistency level for the serial phase of conditional updates. That consistency can only be either SERIAL or LOCAL_SERIAL and if not present, it defaults to SERIAL. This option will be ignored for anything else that a conditional update/insert.

func (*Queryx) SetSpeculativeExecutionPolicy added in v1.2.0

func (q *Queryx) SetSpeculativeExecutionPolicy(sp gocql.SpeculativeExecutionPolicy) *Queryx

SetSpeculativeExecutionPolicy sets the execution policy.

func (*Queryx) Trace added in v1.2.0

func (q *Queryx) Trace(trace gocql.Tracer) *Queryx

Trace enables tracing of this query. Look at the documentation of the Tracer interface to learn more about tracing.

func (*Queryx) WithContext added in v1.2.0

func (q *Queryx) WithContext(ctx context.Context) *Queryx

WithContext returns a shallow copy of q with its context set to ctx.

The provided context controls the entire lifetime of executing a query, queries will be canceled and return once the context is canceled.

func (*Queryx) WithTimestamp added in v1.2.0

func (q *Queryx) WithTimestamp(timestamp int64) *Queryx

WithTimestamp will enable the with default timestamp flag on the query like DefaultTimestamp does. But also allows to define value for timestamp. It works the same way as USING TIMESTAMP in the query itself, but should not break prepared query optimization

Only available on protocol >= 3

Directories

Path Synopsis
Package migrate provides simple and flexible CLQ migrations.
Package migrate provides simple and flexible CLQ migrations.
Package qb provides CQL query builders.
Package qb provides CQL query builders.
Package table adds support for super simple CRUD operations based on table model.
Package table adds support for super simple CRUD operations based on table model.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL