Skip to content

Commit

Permalink
More String() methods, and test cleanup (#435)
Browse files Browse the repository at this point in the history
* More String() methods, and test cleanup

* cleanup
  • Loading branch information
phliar authored Apr 16, 2020
1 parent 6e49381 commit 2dd444c
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 201 deletions.
2 changes: 1 addition & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ type Client interface {
Read(ctx context.Context, fieldsToRead []string, objectToRead DomainObject) error

// MultiRead fetches several rows by primary key. A list of fields can be
// specified. Use All() or nil for all fields.
// specified. Use All() or nil for all fields. All entities MUST be on the same partition.
// The domainObject will be filled by corresponding values if the object is fetched successfully.
// Otherwise the DomainObject as key and an error message as value will be saved into
// MultiResult map.
Expand Down
70 changes: 64 additions & 6 deletions conditioner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,77 @@ import (
)

func TestConvertConditions(t *testing.T) {
rangeTestCases := []struct {
descript string
rop *RangeOp
converted string
err string
}{
{
descript: "empty rangeop, valid",
rop: NewRangeOp(&AllTypes{}),
converted: "()",
},
{
descript: "single string, valid",
rop: NewRangeOp(&AllTypes{}).Eq("StringType", "word"),
converted: "(stringtype == word)",
},
{
descript: "bad field name, invalid",
rop: NewRangeOp(&AllTypes{}).Eq("badfield", "data"),
err: "badfield",
},
{
descript: "numeric in string field, invalid",
rop: NewRangeOp(&AllTypes{}).Gt("StringType", 1),
err: "invalid value for string",
},
{
descript: "two conditions, valid",
rop: NewRangeOp(&AllTypes{}).GtOrEq("Int32Type", int32(5)).LtOrEq("Int32Type", int32(10)),
converted: "((int32type <= 10) && (int32type >= 5))",
},
{
descript: "empty with limit",
rop: NewRangeOp(&AllTypes{}).Limit(10),
converted: "()",
},
{
descript: "empty with adaptive limit",
rop: NewRangeOp(&AllTypes{}).Limit(AdaptiveRangeLimit),
converted: "()",
},
{
descript: "empty with token",
rop: NewRangeOp(&AllTypes{}).Offset("toketoketoke"),
converted: "()",
},
{
descript: "error in one field",
rop: NewRangeOp(&AllTypes{}).Lt("badfieldpropogate", "oopsie").Lt("StringType", "42").Limit(10),
err: "badfieldpropogate",
},
{
descript: "valid, mixed types",
rop: NewRangeOp(&AllTypes{}).Eq("stringtype", "word").Eq("int32type", int32(-1)),
converted: "((int32type == -1) && (stringtype == word))",
},
{
descript: "with valid field list",
rop: NewRangeOp(&AllTypes{}).Fields([]string{"StringType"}),
converted: "()",
},
}

alltypesTable, _ := TableFromInstance((*AllTypes)(nil))
for _, test := range rangeTestCases {
result, err := ConvertConditions(test.rop.conditions, alltypesTable)
if err != nil {
assert.Contains(t, err.Error(), test.err, test.descript)
} else {
if assert.NoError(t, err) {
// we don't have a stringify method on just the conditions bit
// so just build a new RangeOp from the old one
newRop := *test.rop
newRop.conditions = result
final := (&newRop).String()
assert.Equal(t, test.converted, final, test.descript)
assert.Equal(t, test.converted, ConditionsString(result), test.descript)
}
}
}
Expand Down
30 changes: 23 additions & 7 deletions connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@ import (
"time"
)

//go:generate stringer -type=Operator

// Operator defines an operator against some data for range scans
type Operator int

// order of appearance matter here
const (
_ Operator = iota

// Eq is the equals operator
Eq Operator = iota + 1
Eq

// Lt is the less than operator
Lt
Expand All @@ -49,11 +48,11 @@ const (

// GtOrEq is the greater than or equal operator
GtOrEq

// InvalidVersion is version which is less than 1
InvalidVersion = -1
)

// InvalidVersion is an invalid value for a schema version.
const InvalidVersion = -1

// FieldNameValuePair is a field name and value
type FieldNameValuePair struct {
Name string
Expand Down Expand Up @@ -265,3 +264,20 @@ func (f ScopeFlagType) String() string {
}
return "{" + strings.Join(fs, ", ") + "}"
}

func (op Operator) String() string {
switch op {
case Eq:
return "=="
case Lt:
return "<"
case LtOrEq:
return "<="
case Gt:
return ">"
case GtOrEq:
return ">="
default:
return "?"
}
}
37 changes: 0 additions & 37 deletions operator_string.go

This file was deleted.

45 changes: 0 additions & 45 deletions operator_string_test.go

This file was deleted.

27 changes: 1 addition & 26 deletions range.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ package dosa

import (
"bytes"
"fmt"
"sort"

"github.com/pkg/errors"
)
Expand Down Expand Up @@ -75,30 +73,7 @@ func (r *RangeOp) Fields(fields []string) *RangeOp {
// String satisfies the Stringer interface
func (r *RangeOp) String() string {
result := &bytes.Buffer{}
if r.conditions == nil || len(r.conditions) == 0 {
result.WriteString("<empty>")
} else {
// sort the fields by name for deterministic results
keys := make([]string, 0, len(r.conditions))
for key := range r.conditions {
keys = append(keys, key)
}
sort.Strings(keys)
for _, field := range keys {
conds := r.conditions[field]
if result.Len() > 0 {
result.WriteString(", ")
}
result.WriteString(field)
result.WriteString(" ")
for i, cond := range conds {
if i > 0 {
_, _ = fmt.Fprintf(result, ", %s ", field)
}
_, _ = fmt.Fprintf(result, "%s %v", cond.Op.String(), cond.Value)
}
}
}
result.WriteString(ConditionsString(r.conditions))
addLimitTokenString(result, r.limit, r.token)
return result.String()
}
Expand Down
20 changes: 20 additions & 0 deletions range_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package dosa

import (
"bytes"
"fmt"
"sort"
"strings"
"time"
Expand All @@ -41,6 +42,10 @@ type ColumnCondition struct {
Condition *Condition
}

func (cc *ColumnCondition) String() string {
return fmt.Sprintf("(%s %v %v)", cc.Name, cc.Condition.Op, cc.Condition.Value)
}

// SortedColumnCondition implements sorting of an array of columnConditions
type sortedColumnCondition []*ColumnCondition

Expand Down Expand Up @@ -75,6 +80,21 @@ func NormalizeConditions(columnConditions map[string][]*Condition) []*ColumnCond
return cc
}

func ConditionsString(columnConditions map[string][]*Condition) string {
if len(columnConditions) == 0 {
return "()"
}
nc := NormalizeConditions(columnConditions)
s := make([]string, 0, len(nc))
for _, cc := range nc {
s = append(s, cc.String())
}
if len(s) == 1 {
return s[0]
}
return "(" + strings.Join(s, " && ") + ")"
}

// EnsureValidRangeConditions checks the conditions for a PK Range(). "transform" is a name-prettifying function.
func EnsureValidRangeConditions(ed *EntityDefinition, pk *PrimaryKey, columnConditions map[string][]*Condition, transform func(string) string) error {
// The requirements for range conditions on the PK being valid:
Expand Down
Loading

0 comments on commit 2dd444c

Please sign in to comment.