Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
Updates for v0.4.0. Added more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yuce committed Jun 9, 2017
1 parent 2b73979 commit ec77693
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sudo: required
services:
- docker
before_install:
- docker run -d -p 10101:10101 pilosa/pilosa:v0.3.2
- docker run -d -p 10101:10101 pilosa/pilosa:v0.4.0
- go get github.com/mattn/goveralls
addons:
apt:
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Go Client for Pilosa

<a href="https://github.com/pilosa"><img src="https://img.shields.io/badge/pilosa-v0.3.2-blue.svg"></a>
<a href="https://github.com/pilosa"><img src="https://img.shields.io/badge/pilosa-v0.4.0-blue.svg"></a>
<a href="https://godoc.org/github.com/pilosa/go-pilosa"><img src="https://godoc.org/github.com/pilosa/go-pilosa?status.svg" alt="GoDoc"></a>
<a href="https://travis-ci.com/pilosa/go-pilosa"><img src="https://api.travis-ci.com/pilosa/go-pilosa.svg?token=vqssvEWV3KAhu8oVFx9s&branch=master"></a>
<a href="https://goreportcard.com/report/github.com/pilosa/go-pilosa"><img src="https://goreportcard.com/badge/github.com/pilosa/go-pilosa?updated=1"></a>
Expand All @@ -12,9 +12,12 @@ Go client for Pilosa high performance distributed bitmap index.

## Change Log

* **v0.3.2**:
* **v0.4.0** (2017-06-09):
* Supports Pilosa Server v0.4.0.
* Updated the accepted values for index, frame names and labels to match with the Pilosa server.
* `Union` query now accepts zero or more variadic arguments. `Intersect` and `Difference` queries now accept one or more variadic arguments.
* Added `inverse TopN` and `inverse Range` calls.
* Inverse enabled status of frames is not checked on the client side.

* **v0.3.1** (2017-05-01):
* Initial version
Expand Down Expand Up @@ -173,13 +176,18 @@ Index:
Frame:

* `Bitmap(rowID uint64) *PQLBitmapQuery`
* `InverseBitmap(rowID uint64) *PQLBitmapQuery`
* `SetBit(rowID uint64, columnID uint64) *PQLBaseQuery`
* `SetBitTimestamp(rowID uint64, columnID uint64, timestamp time.Time) *PQLBaseQuery`
* `ClearBit(rowID uint64, columnID uint64) *PQLBaseQuery`
* `TopN(n uint64) *PQLBitmapQuery`
* `BitmapTopN(n uint64, bitmap *PQLBitmapQuery) *PQLBitmapQuery`
* `FilterFieldTopN(n uint64, bitmap *PQLBitmapQuery, field string, values ...interface{}) *PQLBitmapQuery`
* `InverseTopN(n uint64) *PQLBitmapQuery`
* `InverseBitmapTopN(n uint64, bitmap *PQLBitmapQuery) *PQLBitmapQuery`
* `InverseFilterFieldTopN(n uint64, bitmap *PQLBitmapQuery, field string, values ...interface{}) *PQLBitmapQuery`
* `Range(rowID uint64, start time.Time, end time.Time) *PQLBitmapQuery`
* `InverseRange(rowID uint64, start time.Time, end time.Time) *PQLBitmapQuery`
* `SetBitmapAttrs(rowID uint64, attrs map[string]interface{}) *PQLBaseQuery`

### Pilosa URI
Expand Down
64 changes: 63 additions & 1 deletion client_it_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build integration
+build integration

// Copyright 2017 Pilosa Corp.
//
Expand Down Expand Up @@ -43,6 +43,7 @@ import (
"reflect"
"strconv"
"testing"
"time"

"github.com/golang/protobuf/proto"
"github.com/pilosa/go-pilosa/internal"
Expand Down Expand Up @@ -179,6 +180,67 @@ func TestSetRowAttrs(t *testing.T) {
}
}

func TestOrmCount(t *testing.T) {
client := getClient()
countFrame, err := index.Frame("count-test", nil)
if err != nil {
t.Fatal(err)
}
err = client.EnsureFrame(countFrame)
if err != nil {
t.Fatal(err)
}
qry := index.BatchQuery(
countFrame.SetBit(10, 20),
countFrame.SetBit(10, 21),
countFrame.SetBit(15, 25),
)
client.Query(qry, nil)
response, err := client.Query(index.Count(countFrame.Bitmap(10)), nil)
if err != nil {
t.Fatal(err)
}
if response.Result().Count != 2 {
t.Fatalf("Count should be 2")
}
}

func TestTopNReturns(t *testing.T) {
client := getClient()
frame, err := index.Frame("topn_test", nil)
if err != nil {
t.Fatal(err)
}
err = client.EnsureFrame(frame)
if err != nil {
t.Fatal(err)
}
qry := index.BatchQuery(
frame.SetBit(10, 5),
frame.SetBit(10, 10),
frame.SetBit(10, 15),
frame.SetBit(20, 5),
frame.SetBit(30, 5),
)
client.Query(qry, nil)
time.Sleep(10 * time.Second)
response, err := client.Query(frame.TopN(2), nil)
if err != nil {
t.Fatal(err)
}
items := response.Result().CountItems
if len(items) != 2 {
t.Fatalf("There should be 2 count items")
}
item := items[0]
if item.ID != 10 {
t.Fatalf("Item[0] ID should be 10")
}
if item.Count != 3 {
t.Fatalf("Item[0] Count should be 3")
}
}

func TestCreateDeleteIndexFrame(t *testing.T) {
client := getClient()
index1, err := NewIndex("to-be-deleted", nil)
Expand Down
52 changes: 43 additions & 9 deletions orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,6 @@ func (f *Frame) Bitmap(rowID uint64) *PQLBitmapQuery {
// Bitmap retrieves the indices of all the set bits in a row or column based on whether the row label or column label is given in the query.
// It also retrieves any attributes set on that row or column.
func (f *Frame) InverseBitmap(columnID uint64) *PQLBaseQuery {
if !f.options.InverseEnabled {
return NewPQLBaseQuery("", f.index, ErrorInverseBitmapsNotEnabled)
}
return NewPQLBaseQuery(fmt.Sprintf("Bitmap(%s=%d, frame='%s')",
f.index.options.ColumnLabel, columnID, f.name), f.index, nil)
}
Expand Down Expand Up @@ -391,34 +388,71 @@ func (f *Frame) ClearBit(rowID uint64, columnID uint64) *PQLBaseQuery {
// TopN creates a TopN query with the given item count.
// Returns the id and count of the top n bitmaps (by count of bits) in the frame.
func (f *Frame) TopN(n uint64) *PQLBitmapQuery {
return NewPQLBitmapQuery(fmt.Sprintf("TopN(frame='%s', n=%d)", f.name, n), f.index, nil)
return NewPQLBitmapQuery(fmt.Sprintf("TopN(frame='%s', n=%d, inverse=false)", f.name, n), f.index, nil)
}

// InverseTopN creates a TopN query with the given item count.
// Returns the id and count of the top n bitmaps (by count of bits) in the frame.
// This variant sets inverse=true
func (f *Frame) InverseTopN(n uint64) *PQLBitmapQuery {
return NewPQLBitmapQuery(fmt.Sprintf("TopN(frame='%s', n=%d, inverse=true)", f.name, n), f.index, nil)
}

// BitmapTopN creates a TopN query with the given item count and bitmap.
// This variant supports customizing the bitmap query.
// This variant supports customizing the bitmap query and sets inverse=true.
func (f *Frame) BitmapTopN(n uint64, bitmap *PQLBitmapQuery) *PQLBitmapQuery {
return NewPQLBitmapQuery(fmt.Sprintf("TopN(%s, frame='%s', n=%d)",
return NewPQLBitmapQuery(fmt.Sprintf("TopN(%s, frame='%s', n=%d, inverse=false)",
bitmap.serialize(), f.name, n), f.index, nil)
}

// InverseBitmapTopN creates a TopN query with the given item count and bitmap.
// This variant supports customizing the bitmap query and sets inverse=true.
func (f *Frame) InverseBitmapTopN(n uint64, bitmap *PQLBitmapQuery) *PQLBitmapQuery {
return NewPQLBitmapQuery(fmt.Sprintf("TopN(%s, frame='%s', n=%d, inverse=true)",
bitmap.serialize(), f.name, n), f.index, nil)
}

// FilterFieldTopN creates a TopN query with the given item count, bitmap, field and the filter for that field
// The field and filters arguments work together to only return Bitmaps which have the attribute specified by field with one of the values specified in filters.
func (f *Frame) FilterFieldTopN(n uint64, bitmap *PQLBitmapQuery, field string, values ...interface{}) *PQLBitmapQuery {
return f.filterFieldTopN(n, bitmap, false, field, values...)
}

// InverseFilterFieldTopN creates a TopN query with the given item count, bitmap, field and the filter for that field
// The field and filters arguments work together to only return Bitmaps which have the attribute specified by field with one of the values specified in filters.
// This variant sets inverse=true.
func (f *Frame) InverseFilterFieldTopN(n uint64, bitmap *PQLBitmapQuery, field string, values ...interface{}) *PQLBitmapQuery {
return f.filterFieldTopN(n, bitmap, true, field, values...)
}

func (f *Frame) filterFieldTopN(n uint64, bitmap *PQLBitmapQuery, inverse bool, field string, values ...interface{}) *PQLBitmapQuery {
if err := validateLabel(field); err != nil {
return NewPQLBitmapQuery("", f.index, err)
}
b, err := json.Marshal(values)
if err != nil {
return NewPQLBitmapQuery("", f.index, err)
}
return NewPQLBitmapQuery(fmt.Sprintf("TopN(%s, frame='%s', n=%d, field='%s', %s)",
bitmap.serialize(), f.name, n, field, string(b)), f.index, nil)
inverseStr := "true"
if !inverse {
inverseStr = "false"
}
return NewPQLBitmapQuery(fmt.Sprintf("TopN(%s, frame='%s', n=%d, inverse=%s, field='%s', %s)",
bitmap.serialize(), f.name, n, inverseStr, field, string(b)), f.index, nil)
}

// Range creates a Range query.
// Similar to Bitmap, but only returns bits which were set with timestamps between the given start and end timestamps.
func (f *Frame) Range(rowID uint64, start time.Time, end time.Time) *PQLBitmapQuery {
return NewPQLBitmapQuery(fmt.Sprintf("Range(%s=%d, frame='%s', start='%s', end='%s')",
return NewPQLBitmapQuery(fmt.Sprintf("Range(%s=%d, frame='%s', start='%s', end='%s', inverse=false)",
f.options.RowLabel, rowID, f.name, start.Format(timeFormat), end.Format(timeFormat)), f.index, nil)
}

// InverseRange creates a Range query.
// Similar to Bitmap, but only returns bits which were set with timestamps between the given start and end timestamps.
// This variant sets inverse=true.
func (f *Frame) InverseRange(rowID uint64, start time.Time, end time.Time) *PQLBitmapQuery {
return NewPQLBitmapQuery(fmt.Sprintf("Range(%s=%d, frame='%s', start='%s', end='%s', inverse=true)",
f.options.RowLabel, rowID, f.name, start.Format(timeFormat), end.Format(timeFormat)), f.index, nil)
}

Expand Down
31 changes: 16 additions & 15 deletions orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,23 @@ func TestDifference(t *testing.T) {

func TestTopN(t *testing.T) {
comparePQL(t,
"TopN(frame='sample-frame', n=27)",
"TopN(frame='sample-frame', n=27, inverse=false)",
sampleFrame.TopN(27))
comparePQL(t,
"TopN(Bitmap(project=3, frame='collaboration'), frame='sample-frame', n=10)",
"TopN(frame='sample-frame', n=27, inverse=true)",
sampleFrame.InverseTopN(27))
comparePQL(t,
"TopN(Bitmap(project=3, frame='collaboration'), frame='sample-frame', n=10, inverse=false)",
sampleFrame.BitmapTopN(10, collabFrame.Bitmap(3)))
comparePQL(t,
"TopN(Bitmap(project=7, frame='collaboration'), frame='sample-frame', n=12, field='category', [80,81])",
"TopN(Bitmap(project=3, frame='collaboration'), frame='sample-frame', n=10, inverse=true)",
sampleFrame.InverseBitmapTopN(10, collabFrame.Bitmap(3)))
comparePQL(t,
"TopN(Bitmap(project=7, frame='collaboration'), frame='sample-frame', n=12, inverse=false, field='category', [80,81])",
sampleFrame.FilterFieldTopN(12, collabFrame.Bitmap(7), "category", 80, 81))
comparePQL(t,
"TopN(Bitmap(project=7, frame='collaboration'), frame='sample-frame', n=12, inverse=true, field='category', [80,81])",
sampleFrame.InverseFilterFieldTopN(12, collabFrame.Bitmap(7), "category", 80, 81))
}

func TestFilterFieldTopNInvalidField(t *testing.T) {
Expand Down Expand Up @@ -296,8 +305,11 @@ func TestRange(t *testing.T) {
start := time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2000, time.February, 2, 3, 4, 0, 0, time.UTC)
comparePQL(t,
"Range(project=10, frame='collaboration', start='1970-01-01T00:00', end='2000-02-02T03:04')",
"Range(project=10, frame='collaboration', start='1970-01-01T00:00', end='2000-02-02T03:04', inverse=false)",
collabFrame.Range(10, start, end))
comparePQL(t,
"Range(project=10, frame='collaboration', start='1970-01-01T00:00', end='2000-02-02T03:04', inverse=true)",
collabFrame.InverseRange(10, start, end))
}

func TestInvalidColumnLabelFails(t *testing.T) {
Expand All @@ -319,17 +331,6 @@ func TestInvalidRowLabelFails(t *testing.T) {
}
}

func TestInverseBitmapFailsIfNotEnabled(t *testing.T) {
frame, err := sampleIndex.Frame("inverse-not-enabled", nil)
if err != nil {
t.Fatal(err)
}
qry := frame.InverseBitmap(5)
if qry.Error() == nil {
t.Fatalf("Creating InverseBitmap query for a frame without inverse frame enabled should fail")
}
}

func TestFrameOptionsToString(t *testing.T) {
frameOptions := &FrameOptions{
RowLabel: "stargazer_id",
Expand Down

0 comments on commit ec77693

Please sign in to comment.