diff --git a/README.md b/README.md index 1d2dd7c..98e8689 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Go client for Pilosa high performance distributed bitmap index. * **v0.3.2**: * 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. * **v0.3.1** (2017-05-01): * Initial version @@ -163,9 +164,9 @@ Please check [Pilosa documentation](https://www.pilosa.com/docs) for PQL details Index: -* `Union(bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, ...) *PQLBitmapQuery` -* `Intersect(bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, ...) *PQLBitmapQuery` -* `Difference(bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, ...) *PQLBitmapQuery` +* `Union(bitmaps *PQLBitmapQuery...) *PQLBitmapQuery` +* `Intersect(bitmaps *PQLBitmapQuery...) *PQLBitmapQuery` +* `Difference(bitmaps *PQLBitmapQuery...) *PQLBitmapQuery` * `Count(bitmap *PQLBitmapQuery) *PQLBaseQuery` * `SetColumnAttrs(columnID uint64, attrs map[string]interface{}) *PQLBaseQuery` diff --git a/orm.go b/orm.go index ebeef20..ef62ec7 100644 --- a/orm.go +++ b/orm.go @@ -239,20 +239,26 @@ func (d *Index) RawQuery(query string) *PQLBaseQuery { // Union creates a Union query. // Union performs a logical OR on the results of each BITMAP_CALL query passed to it. -func (d *Index) Union(bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { - return d.bitmapOperation("Union", bitmap1, bitmap2, bitmaps...) +func (d *Index) Union(bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { + return d.bitmapOperation("Union", bitmaps...) } // Intersect creates an Intersect query. // Intersect performs a logical AND on the results of each BITMAP_CALL query passed to it. -func (d *Index) Intersect(bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { - return d.bitmapOperation("Intersect", bitmap1, bitmap2, bitmaps...) +func (d *Index) Intersect(bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { + if len(bitmaps) < 1 { + return NewPQLBitmapQuery("", d, NewError("Intersect operation requires at least 1 bitmap")) + } + return d.bitmapOperation("Intersect", bitmaps...) } // Difference creates an Intersect query. // Difference returns all of the bits from the first BITMAP_CALL argument passed to it, without the bits from each subsequent BITMAP_CALL. -func (d *Index) Difference(bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { - return d.bitmapOperation("Difference", bitmap1, bitmap2, bitmaps...) +func (d *Index) Difference(bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { + if len(bitmaps) < 1 { + return NewPQLBitmapQuery("", d, NewError("Difference operation requires at least 1 bitmap")) + } + return d.bitmapOperation("Difference", bitmaps...) } // Count creates a Count query. @@ -273,16 +279,9 @@ func (d *Index) SetColumnAttrs(columnID uint64, attrs map[string]interface{}) *P d.options.ColumnLabel, columnID, attrsString), d, nil) } -func (d *Index) bitmapOperation(name string, bitmap1 *PQLBitmapQuery, bitmap2 *PQLBitmapQuery, bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { +func (d *Index) bitmapOperation(name string, bitmaps ...*PQLBitmapQuery) *PQLBitmapQuery { var err error - if err = bitmap1.Error(); err != nil { - return NewPQLBitmapQuery("", d, err) - } - if err = bitmap2.Error(); err != nil { - return NewPQLBitmapQuery("", d, err) - } - args := make([]string, 0, 2+len(bitmaps)) - args = append(args, bitmap1.serialize(), bitmap2.serialize()) + args := make([]string, 0, len(bitmaps)) for _, bitmap := range bitmaps { if err = bitmap.Error(); err != nil { return NewPQLBitmapQuery("", d, err) diff --git a/orm_test.go b/orm_test.go index 458bd1d..5189faf 100644 --- a/orm_test.go +++ b/orm_test.go @@ -132,6 +132,12 @@ func TestUnion(t *testing.T) { comparePQL(t, "Union(Bitmap(rowID=10, frame='sample-frame'), Bitmap(project=2, frame='collaboration'))", sampleIndex.Union(b1, b4)) + comparePQL(t, + "Union(Bitmap(rowID=10, frame='sample-frame'))", + sampleIndex.Union(b1)) + comparePQL(t, + "Union()", + sampleIndex.Union()) } func TestIntersect(t *testing.T) { @@ -144,6 +150,9 @@ func TestIntersect(t *testing.T) { comparePQL(t, "Intersect(Bitmap(rowID=10, frame='sample-frame'), Bitmap(project=2, frame='collaboration'))", sampleIndex.Intersect(b1, b4)) + comparePQL(t, + "Intersect(Bitmap(rowID=10, frame='sample-frame'))", + sampleIndex.Intersect(b1)) } func TestDifference(t *testing.T) { @@ -156,6 +165,9 @@ func TestDifference(t *testing.T) { comparePQL(t, "Difference(Bitmap(rowID=10, frame='sample-frame'), Bitmap(project=2, frame='collaboration'))", sampleIndex.Difference(b1, b4)) + comparePQL(t, + "Difference(Bitmap(rowID=10, frame='sample-frame'))", + sampleIndex.Difference(b1)) } func TestTopN(t *testing.T) { @@ -201,6 +213,16 @@ func TestBitmapOperationInvalidArg(t *testing.T) { if q.Error() == nil { t.Fatalf("should have failed") } + // not enough bitmaps supplied + q = sampleIndex.Difference() + if q.Error() == nil { + t.Fatalf("should have failed") + } + // not enough bitmaps supplied + q = sampleIndex.Intersect() + if q.Error() == nil { + t.Fatalf("should have failed") + } } func TestSetColumnAttrsTest(t *testing.T) {