simple readme and example_test
This commit is contained in:
20
README.md
20
README.md
@@ -1 +1,21 @@
|
|||||||
# gocqlx [](http://godoc.org/github.com/mmatczuk/gocqlx) [](https://goreportcard.com/report/github.com/mmatczuk/gocqlx) [](https://travis-ci.org/mmatczuk/gocqlx)
|
# gocqlx [](http://godoc.org/github.com/mmatczuk/gocqlx) [](https://goreportcard.com/report/github.com/mmatczuk/gocqlx) [](https://travis-ci.org/mmatczuk/gocqlx)
|
||||||
|
|
||||||
|
Package `gocqlx` is a `gocql` extension, similar to what `sqlx` is to `database/sql`.
|
||||||
|
|
||||||
|
It provides a new type that seamlessly wraps `gocql.Iter` and provide
|
||||||
|
convenience methods which are useful in the development of database driven
|
||||||
|
applications. None of the underlying gocql.Iter methods are changed.
|
||||||
|
Instead all extended behavior is implemented through new methods defined on
|
||||||
|
wrapper type.
|
||||||
|
|
||||||
|
The wrapper type enables you to bind iterator row into a struct. Under the
|
||||||
|
hood it uses `sqlx/reflectx` package, models / structs working whit `sqlx` will
|
||||||
|
also work with `gocqlx`.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
go get github.com/mmatczuk/gocqlx
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See [example test](https://github.com/mmatczuk/gocqlx/blob/master/example_test.go).
|
||||||
|
|||||||
9
doc.go
9
doc.go
@@ -13,7 +13,14 @@
|
|||||||
// Example, read all items for a given id
|
// Example, read all items for a given id
|
||||||
//
|
//
|
||||||
// var v []*Item
|
// var v []*Item
|
||||||
// if err := gocqlx.Select(session.Query(`SELECT * FROM items WHERE id = ?`, id), &v); err != nil {
|
// if err := gocqlx.Select(&v, session.Query(`SELECT * FROM items WHERE id = ?`, id)); err != nil {
|
||||||
// log.Fatal("select failed", err)
|
// log.Fatal("select failed", err)
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
// Example, read first item for a given id
|
||||||
|
//
|
||||||
|
// var v Item
|
||||||
|
// if err := gocqlx.Get(&v, session.Query(`SELECT * FROM items WHERE id = ?`, id)); err != nil {
|
||||||
|
// log.Fatal("get failed", err)
|
||||||
|
// }
|
||||||
package gocqlx
|
package gocqlx
|
||||||
|
|||||||
100
example_test.go
Normal file
100
example_test.go
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
// +build all integration
|
||||||
|
|
||||||
|
package gocqlx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
"github.com/mmatczuk/gocqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var personSchema = `
|
||||||
|
CREATE TABLE gocqlx_test.person (
|
||||||
|
first_name text,
|
||||||
|
last_name text,
|
||||||
|
email list<text>,
|
||||||
|
PRIMARY KEY(first_name, last_name)
|
||||||
|
)`
|
||||||
|
|
||||||
|
var placeSchema = `
|
||||||
|
CREATE TABLE gocqlx_test.place (
|
||||||
|
country text,
|
||||||
|
city text,
|
||||||
|
telcode int,
|
||||||
|
PRIMARY KEY(country, city)
|
||||||
|
)`
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
FirstName string `db:"first_name"`
|
||||||
|
LastName string `db:"last_name"`
|
||||||
|
Email []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Place struct {
|
||||||
|
Country string
|
||||||
|
City string
|
||||||
|
TelCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExample(t *testing.T) {
|
||||||
|
session := createSession(t)
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
// Exec the schema or fail
|
||||||
|
mustExec := func(q *gocql.Query) {
|
||||||
|
if err := q.Exec(); err != nil {
|
||||||
|
t.Fatal("insert:", q, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mustExec(session.Query(personSchema))
|
||||||
|
mustExec(session.Query(placeSchema))
|
||||||
|
|
||||||
|
mustExec(session.Query("INSERT INTO gocqlx_test.person (first_name, last_name, email) VALUES (?, ?, ?)", "Jason", "Moiron", []string{"jmoiron@jmoiron.net"}))
|
||||||
|
mustExec(session.Query("INSERT INTO gocqlx_test.person (first_name, last_name, email) VALUES (?, ?, ?)", "John", "Doe", []string{"johndoeDNE@gmail.net"}))
|
||||||
|
mustExec(session.Query("INSERT INTO gocqlx_test.place (country, city, telcode) VALUES (?, ?, ?)", "United States", "New York", 1))
|
||||||
|
mustExec(session.Query("INSERT INTO gocqlx_test.place (country, city, telcode) VALUES (?, ?, ?)", "Hong Kong", "", 852))
|
||||||
|
mustExec(session.Query("INSERT INTO gocqlx_test.place (country, city, telcode) VALUES (?, ?, ?)", "Singapore", "", 65))
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// tx.NamedExec("INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &Person{"Jane", "Citizen", "jane.citzen@gocqlx_test.com"})
|
||||||
|
|
||||||
|
// Query the database, storing results in a []Person (wrapped in []interface{})
|
||||||
|
{
|
||||||
|
people := []Person{}
|
||||||
|
if err := gocqlx.Select(&people, session.Query("SELECT * FROM person")); err != nil {
|
||||||
|
t.Fatal("select:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%#v\n%#v\n", people[0], people[1])
|
||||||
|
// gocqlx_test.Person{FirstName:"John", LastName:"Doe", Email:[]string{"johndoeDNE@gmail.net"}}
|
||||||
|
// gocqlx_test.Person{FirstName:"Jason", LastName:"Moiron", Email:[]string{"jmoiron@jmoiron.net"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a single result, a la QueryRow
|
||||||
|
{
|
||||||
|
var jason Person
|
||||||
|
if err := gocqlx.Get(&jason, session.Query("SELECT * FROM person WHERE first_name=?", "Jason")); err != nil {
|
||||||
|
t.Fatal("get:", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%#v\n", jason)
|
||||||
|
// gocqlx_test.Person{FirstName:"Jason", LastName:"Moiron", Email:[]string{"jmoiron@jmoiron.net"}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through rows using only one struct
|
||||||
|
{
|
||||||
|
var place Place
|
||||||
|
iter := gocqlx.Iter(session.Query("SELECT * FROM place"))
|
||||||
|
for iter.StructScan(&place) {
|
||||||
|
fmt.Printf("%#v\n", place)
|
||||||
|
}
|
||||||
|
iter.Close()
|
||||||
|
if err := iter.Err(); err != nil {
|
||||||
|
t.Fatal("iter:", err)
|
||||||
|
}
|
||||||
|
// gocqlx_test.Place{Country:"Hong Kong", City:"", TelCode:852}
|
||||||
|
// gocqlx_test.Place{Country:"United States", City:"New York", TelCode:1}
|
||||||
|
// gocqlx_test.Place{Country:"Singapore", City:"", TelCode:65}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
gocqlx.go
22
gocqlx.go
@@ -17,12 +17,12 @@ import (
|
|||||||
var DefaultMapper = reflectx.NewMapperFunc("db", strings.ToLower)
|
var DefaultMapper = reflectx.NewMapperFunc("db", strings.ToLower)
|
||||||
|
|
||||||
// Get is a convenience function for creating iterator and calling Get on it.
|
// Get is a convenience function for creating iterator and calling Get on it.
|
||||||
func Get(q *gocql.Query, dest interface{}) error {
|
func Get(dest interface{}, q *gocql.Query) error {
|
||||||
return Iter(q).Get(dest)
|
return Iter(q).Get(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select is a convenience function for creating iterator and calling Select on it.
|
// Select is a convenience function for creating iterator and calling Select on it.
|
||||||
func Select(q *gocql.Query, dest interface{}) error {
|
func Select(dest interface{}, q *gocql.Query) error {
|
||||||
return Iter(q).Select(dest)
|
return Iter(q).Select(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +55,7 @@ func (iter *Iterx) Get(dest interface{}) error {
|
|||||||
iter.err = err
|
iter.err = err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := iter.Close(); err != nil {
|
iter.Close()
|
||||||
iter.err = err
|
|
||||||
}
|
|
||||||
|
|
||||||
return iter.err
|
return iter.err
|
||||||
}
|
}
|
||||||
@@ -100,9 +98,7 @@ func (iter *Iterx) Select(dest interface{}) error {
|
|||||||
iter.err = err
|
iter.err = err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := iter.Close(); err != nil {
|
iter.Close()
|
||||||
iter.err = err
|
|
||||||
}
|
|
||||||
|
|
||||||
return iter.err
|
return iter.err
|
||||||
}
|
}
|
||||||
@@ -218,6 +214,16 @@ func columnNames(ci []gocql.ColumnInfo) []string {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the iterator and returns any errors that happened during
|
||||||
|
// the query or the iteration.
|
||||||
|
func (iter *Iterx) Close() error {
|
||||||
|
err := iter.Iter.Close()
|
||||||
|
if err != nil && iter.err == nil {
|
||||||
|
iter.err = err
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Err returns the error encountered while scanning.
|
// Err returns the error encountered while scanning.
|
||||||
func (iter *Iterx) Err() error {
|
func (iter *Iterx) Err() error {
|
||||||
return iter.err
|
return iter.err
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
"github.com/mmatczuk/gocqlx"
|
||||||
|
|
||||||
"gopkg.in/inf.v0"
|
"gopkg.in/inf.v0"
|
||||||
)
|
)
|
||||||
@@ -43,7 +44,7 @@ func TestScannable(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("get", func(t *testing.T) {
|
t.Run("get", func(t *testing.T) {
|
||||||
var v FullName
|
var v FullName
|
||||||
if err := Get(session.Query(`SELECT testfullname FROM scannable_table`), &v); err != nil {
|
if err := gocqlx.Get(&v, session.Query(`SELECT testfullname FROM scannable_table`)); err != nil {
|
||||||
t.Fatal("get failed", err)
|
t.Fatal("get failed", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ func TestScannable(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("select", func(t *testing.T) {
|
t.Run("select", func(t *testing.T) {
|
||||||
var v []FullName
|
var v []FullName
|
||||||
if err := Select(session.Query(`SELECT testfullname FROM scannable_table`), &v); err != nil {
|
if err := gocqlx.Select(&v, session.Query(`SELECT testfullname FROM scannable_table`)); err != nil {
|
||||||
t.Fatal("get failed", err)
|
t.Fatal("get failed", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ func TestScannable(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("select ptr", func(t *testing.T) {
|
t.Run("select ptr", func(t *testing.T) {
|
||||||
var v []*FullName
|
var v []*FullName
|
||||||
if err := Select(session.Query(`SELECT testfullname FROM scannable_table`), &v); err != nil {
|
if err := gocqlx.Select(&v, session.Query(`SELECT testfullname FROM scannable_table`)); err != nil {
|
||||||
t.Fatal("get failed", err)
|
t.Fatal("get failed", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +174,7 @@ func TestStruct(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("get", func(t *testing.T) {
|
t.Run("get", func(t *testing.T) {
|
||||||
var v StructTable
|
var v StructTable
|
||||||
if err := Get(session.Query(`SELECT * FROM struct_table`), &v); err != nil {
|
if err := gocqlx.Get(&v, session.Query(`SELECT * FROM struct_table`)); err != nil {
|
||||||
t.Fatal("get failed", err)
|
t.Fatal("get failed", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +185,7 @@ func TestStruct(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("select", func(t *testing.T) {
|
t.Run("select", func(t *testing.T) {
|
||||||
var v []StructTable
|
var v []StructTable
|
||||||
if err := Select(session.Query(`SELECT * FROM struct_table`), &v); err != nil {
|
if err := gocqlx.Select(&v, session.Query(`SELECT * FROM struct_table`)); err != nil {
|
||||||
t.Fatal("select failed", err)
|
t.Fatal("select failed", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +200,7 @@ func TestStruct(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("select ptr", func(t *testing.T) {
|
t.Run("select ptr", func(t *testing.T) {
|
||||||
var v []*StructTable
|
var v []*StructTable
|
||||||
if err := Select(session.Query(`SELECT * FROM struct_table`), &v); err != nil {
|
if err := gocqlx.Select(&v, session.Query(`SELECT * FROM struct_table`)); err != nil {
|
||||||
t.Fatal("select failed", err)
|
t.Fatal("select failed", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user