diff --git a/certificates/statement.go b/certificates/statement.go new file mode 100644 index 00000000..fd16b528 --- /dev/null +++ b/certificates/statement.go @@ -0,0 +1,80 @@ +package certificates + +import ( + "fmt" + "strconv" + "strings" +) + +// Where struct wraps a where clause. +// Basic usage is Where{"field","value"} for WHERE field = value +// The Operator field can be used if you need < > = != LIKE / NOT LIKE operators +type Where struct { + Field string + Value interface{} + Operator string +} + +// Stringer produces the WHERE condition +func (w Where) String() string { + var operator string = w.Operator + if w.Operator == "" { + operator = "=" + } + + var quotedValue string + switch w.Value.(type) { + case string: + quotedValue = fmt.Sprintf("'%s'", w.Value) + case nil: + operator = "IS" + quotedValue = "NULL" + case bool: + if w.Value.(bool) == true { + quotedValue = "true" + } else { + quotedValue = "false" + } + case []string: // IN("strings...") + operator = "IN" + inValues := w.Value.([]string) + quotedValue = "('" + strings.Join(inValues, "','") + "')" + case int: + quotedValue = strconv.Itoa(w.Value.(int)) + } + + return fmt.Sprintf("%s %s %s", w.Field, operator, quotedValue) +} + +// whereer is for building args passed into a method which finds resources +type whereer interface { + where() string +} + +type WhereAnd []Where + +func (wa WhereAnd) String() string { + var result string + for i, cond := range wa { + result += cond.String() + if i < len(wa)-1 { + result += " AND " + } + } + + return result +} + +type WhereOr []Where + +func (wo WhereOr) String() string { + var result string + for i, cond := range wo { + result += cond.String() + if i < len(wo)-1 { + result += " OR " + } + } + + return result +} diff --git a/certificates/statement_test.go b/certificates/statement_test.go new file mode 100644 index 00000000..bbdd4eb4 --- /dev/null +++ b/certificates/statement_test.go @@ -0,0 +1,68 @@ +package certificates + +import ( + "testing" +) + +var whereTests = []struct { + when Where + then string +}{ + {Where{"field", "value", "="}, "field = 'value'"}, + {Where{"field", 1, "="}, "field = 1"}, + {Where{"field", false, "="}, "field = false"}, + {Where{"field", []string{"foo", "bar"}, "IN"}, "field IN ('foo','bar')"}, + {Where{"field", "%foo%", "LIKE"}, "field LIKE '%foo%'"}, + {Where{"field", "bar", "!="}, "field != 'bar'"}, + {Where{"field", nil, "IS"}, "field IS NULL"}, +} + +func TestWhere_String(t *testing.T) { + for _, test := range whereTests { + v := test.when.String() + if v != test.then { + t.Error( + "Expected", test.then, + "got", v, + ) + } + } +} + +var waTests = []struct { + when WhereAnd + then string +}{ + {WhereAnd{Where{"field", "value", "="}, Where{"field", "bar", "="}}, "field = 'value' AND field = 'bar'"}, +} + +func TestWhereAnd_String(t *testing.T) { + for _, test := range waTests { + v := test.when.String() + if v != test.then { + t.Error( + "Expected", test.then, + "got", v, + ) + } + } +} + +var woTests = []struct { + when WhereOr + then string +}{ + {WhereOr{Where{"field", "value", "="}, Where{"field", "bar", "="}}, "field = 'value' OR field = 'bar'"}, +} + +func TestWhereOr_String(t *testing.T) { + for _, test := range woTests { + v := test.when.String() + if v != test.then { + t.Error( + "Expected", test.then, + "got", v, + ) + } + } +}