Skip to content

Commit

Permalink
Base32 encoding and decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
cube2222 committed May 2, 2020
1 parent 7fe775d commit 35621cd
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 37 deletions.
23 changes: 23 additions & 0 deletions execution/functions/functions.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package functions

import (
"encoding/base32"
"fmt"
"log"
"math"
Expand Down Expand Up @@ -1266,6 +1267,28 @@ var FuncParseTime = execution.Function{
},
}

var FuncDecodeBase32 = execution.Function{
Name: "decode_base32",
ArgumentNames: [][]string{
{"text"},
},
Description: docs.List(
docs.Text("Decodes the text from Base32. Especially useful when using a datasource which stores text as byte fields."),
),
Validator: All(
ExactlyNArgs(1),
AllArgs(TypeOf(ZeroString())),
),
Logic: func(args ...Value) (Value, error) {
data, err := base32.StdEncoding.DecodeString(args[0].AsString())
if err != nil {
return ZeroValue(), errors.Wrap(err, "couldn't decode base32")
}

return MakeString(string(data)), nil
},
}

/* Auxiliary functions */
func intMin(x, y int) int {
if x <= y {
Expand Down
1 change: 1 addition & 0 deletions execution/functions/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ var usableFunctions = []execution.Function{
FuncCoalesce,
FuncNullIf,
FuncParseTime,
FuncDecodeBase32,
}

func init() {
Expand Down
9 changes: 5 additions & 4 deletions storage/parquet/datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package parquet

import (
"context"
"encoding/base32"
"testing"

"github.com/cube2222/octosql"
Expand Down Expand Up @@ -37,19 +38,19 @@ func TestParquetRecordStream_Get(t *testing.T) {
[]*execution.Record{
execution.NewRecordFromSliceWithNormalize(
[]octosql.VariableName{"b.color", "b.id", "b.ownerid", "b.wheels", "b.year"},
[]interface{}{"green", 1, 152849, 3, 2014},
[]interface{}{base32.StdEncoding.EncodeToString([]byte("green")), 1, 152849, 3, 2014},
),
execution.NewRecordFromSliceWithNormalize(
[]octosql.VariableName{"b.color", "b.id", "b.ownerid", "b.wheels", "b.year"},
[]interface{}{"black", 2, 106332, 2, 1988},
[]interface{}{base32.StdEncoding.EncodeToString([]byte("black")), 2, 106332, 2, 1988},
),
execution.NewRecordFromSliceWithNormalize(
[]octosql.VariableName{"b.color", "b.id", "b.ownerid", "b.wheels", "b.year"},
[]interface{}{"purple", 3, 99148, 2, 2009},
[]interface{}{base32.StdEncoding.EncodeToString([]byte("purple")), 3, 99148, 2, 2009},
),
execution.NewRecordFromSliceWithNormalize(
[]octosql.VariableName{"b.color", "b.id", "b.ownerid", "b.wheels", "b.year"},
[]interface{}{"orange", 4, 97521, 2, 1979},
[]interface{}{base32.StdEncoding.EncodeToString([]byte("orange")), 4, 97521, 2, 1979},
),
},
),
Expand Down
15 changes: 1 addition & 14 deletions values.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package octosql

import (
"bytes"
"encoding/base32"
"fmt"
"log"
Expand Down Expand Up @@ -149,19 +148,7 @@ func NormalizeType(value interface{}) Value {
case float64:
return MakeFloat(value)
case []byte:
var buf bytes.Buffer
enc := base32.NewEncoder(base32.StdEncoding, &buf)
n, err := enc.Write(value)
if err != nil {
panic(fmt.Sprintf("couldn't base64 encode bytes: %s", err.Error()))
}
if n != len(value) {
panic(fmt.Sprintf("couldn't base64 encode bytes: wrote only %d of %d bytes", n, len(value)))
}
if err := enc.Close(); err != nil {
panic(fmt.Sprintf("couldn't close base64 encode bytes: %s", err.Error()))
}
return MakeString(buf.String())
return MakeString(base32.StdEncoding.EncodeToString(value))
case string:
return MakeString(value)
case []interface{}:
Expand Down
20 changes: 1 addition & 19 deletions values_test.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,14 @@
package octosql

import (
"bytes"
"encoding/base32"
"fmt"
"math"
"testing"
"time"

"github.com/golang/protobuf/proto"
)

func stringToBase32(str string) string {
var buf bytes.Buffer
enc := base32.NewEncoder(base32.StdEncoding, &buf)
n, err := enc.Write([]byte(str))
if err != nil {
panic(fmt.Sprintf("couldn't base64 encode bytes: %s", err.Error()))
}
if n != len(str) {
panic(fmt.Sprintf("couldn't base64 encode bytes: wrote only %d of %d bytes", n, len(str)))
}
if err := enc.Close(); err != nil {
panic(fmt.Sprintf("couldn't close base64 encode bytes: %s", err.Error()))
}
return buf.String()
}

func TestNormalizeType(t *testing.T) {
tests := []struct {
name string
Expand All @@ -45,7 +27,7 @@ func TestNormalizeType(t *testing.T) {
"array": []interface{}{[]interface{}{float32(1), uint8(2), int64(3)}, true},
},
want: MakeObject(map[string]Value{
"name": MakeString(stringToBase32("Jakub")),
"name": MakeString(base32.StdEncoding.EncodeToString([]byte("Jakub"))),
"age": MakeInt(3),
"city": MakeObject(map[string]Value{
"name": MakeString("warsaw"),
Expand Down

0 comments on commit 35621cd

Please sign in to comment.