simple readme and example_test

This commit is contained in:
Michał Matczuk
2017-07-24 16:22:30 +02:00
parent 0286a6dca9
commit f31e47d7bb
5 changed files with 149 additions and 15 deletions

View File

@@ -1 +1,21 @@
# gocqlx [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/mmatczuk/gocqlx) [![Go Report Card](https://goreportcard.com/badge/github.com/mmatczuk/gocqlx)](https://goreportcard.com/report/github.com/mmatczuk/gocqlx) [![Build Status](http://img.shields.io/travis/mmatczuk/gocqlx.svg?style=flat-square)](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
View File

@@ -13,7 +13,14 @@
// Example, read all items for a given id
//
// 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)
// }
//
// 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

100
example_test.go Normal file
View 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}
}
}

View File

@@ -17,12 +17,12 @@ import (
var DefaultMapper = reflectx.NewMapperFunc("db", strings.ToLower)
// 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)
}
// 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)
}
@@ -55,9 +55,7 @@ func (iter *Iterx) Get(dest interface{}) error {
iter.err = err
}
if err := iter.Close(); err != nil {
iter.err = err
}
iter.Close()
return iter.err
}
@@ -100,9 +98,7 @@ func (iter *Iterx) Select(dest interface{}) error {
iter.err = err
}
if err := iter.Close(); err != nil {
iter.err = err
}
iter.Close()
return iter.err
}
@@ -218,6 +214,16 @@ func columnNames(ci []gocql.ColumnInfo) []string {
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.
func (iter *Iterx) Err() error {
return iter.err

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/gocql/gocql"
"github.com/mmatczuk/gocqlx"
"gopkg.in/inf.v0"
)
@@ -43,7 +44,7 @@ func TestScannable(t *testing.T) {
t.Run("get", func(t *testing.T) {
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)
}
@@ -54,7 +55,7 @@ func TestScannable(t *testing.T) {
t.Run("select", func(t *testing.T) {
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)
}
@@ -69,7 +70,7 @@ func TestScannable(t *testing.T) {
t.Run("select ptr", func(t *testing.T) {
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)
}
@@ -173,7 +174,7 @@ func TestStruct(t *testing.T) {
t.Run("get", func(t *testing.T) {
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)
}
@@ -184,7 +185,7 @@ func TestStruct(t *testing.T) {
t.Run("select", func(t *testing.T) {
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)
}
@@ -199,7 +200,7 @@ func TestStruct(t *testing.T) {
t.Run("select ptr", func(t *testing.T) {
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)
}