Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable native byte array fields on structs #766

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 0 additions & 91 deletions go.sum

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion graph/graphtest/graphtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,10 @@ func TestLoadTypedQuads(t testing.TB, gen testutil.DatabaseFunc, conf *Config) {
quad.Float(-12345e-6),
quad.Bool(true),
quad.Time(time.Now()),
quad.IRI("C"), quad.IRI("bytes"),
quad.Bytes([]byte{'b', 'y', 't', 'e', 's', 0x00}),
quad.Raw("<bytes>"),
quad.Bytes([]byte("<bytes>")),
}

err := w.AddQuadSet([]quad.Quad{
Expand All @@ -717,6 +721,8 @@ func TestLoadTypedQuads(t testing.TB, gen testutil.DatabaseFunc, conf *Config) {
{values[0], values[1], values[9], nil},
{values[0], values[1], values[10], nil},
{values[0], values[1], values[11], nil},
{values[12], values[13], values[14], nil},
{values[15], values[13], values[16], nil},
})
require.NoError(t, err)
for _, pq := range values {
Expand Down Expand Up @@ -755,7 +761,7 @@ func TestLoadTypedQuads(t testing.TB, gen testutil.DatabaseFunc, conf *Config) {
}
exp := int64(19)
if conf.NoPrimitives {
exp = 7
exp = 9
}
require.Equal(t, exp, qs.Size(), "Unexpected quadstore size")
}
Expand Down
4 changes: 2 additions & 2 deletions graph/kv/indexing.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import (

"github.com/cayleygraph/cayley/clog"
"github.com/cayleygraph/cayley/graph"
"github.com/cayleygraph/cayley/graph/log"
graphlog "github.com/cayleygraph/cayley/graph/log"
"github.com/cayleygraph/cayley/graph/proto"
"github.com/cayleygraph/cayley/quad"
"github.com/cayleygraph/cayley/quad/pquads"
"github.com/tylertreat/BoomFilters"
boom "github.com/tylertreat/BoomFilters"
)

var (
Expand Down
4 changes: 3 additions & 1 deletion quad/pquads/quads.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func MakeValue(qv quad.Value) *Value {
// return &Value{&Value_Raw{[]byte(v)}}
case quad.String:
return &Value{&Value_Str{string(v)}}
case quad.Bytes:
return &Value{&Value_Raw{[]byte(v)}}
case quad.IRI:
return &Value{&Value_Iri{string(v)}}
case quad.BNode:
Expand Down Expand Up @@ -79,7 +81,7 @@ func (m *Value) ToNative() (qv quad.Value) {
}
switch v := m.Value.(type) {
case *Value_Raw:
return quad.StringToValue(string(v.Raw))
return quad.Bytes(v.Raw)
case *Value_Str:
return quad.String(v.Str)
case *Value_Iri:
Expand Down
47 changes: 45 additions & 2 deletions quad/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package quad

import (
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"math/rand"
Expand Down Expand Up @@ -60,8 +61,15 @@ func HashTo(v Value, p []byte) {
panic("buffer too small to fit the hash")
}
if v != nil {
// TODO(kortschak,dennwc) Remove dependence on String() method.
h.Write([]byte(v.String()))
if vv, ok := v.(Bytes); ok {
// TODO(fungl164,dennwc) Ensure prefix byte on is strong enough
// of a differentiator for hash value
h.Write([]byte{0x00})
h.Write([]byte(vv))
} else {
// TODO(kortschak,dennwc) Remove dependence on String() method.
h.Write([]byte(v.String()))
}
}
h.Sum(p[:0])
}
Expand Down Expand Up @@ -91,6 +99,8 @@ func AsValue(v interface{}) (out Value, ok bool) {
switch v := v.(type) {
case Value:
out = v
case []byte:
out = Bytes(v)
case string:
out = String(v)
case int:
Expand Down Expand Up @@ -272,6 +282,7 @@ const (
defaultFloatType IRI = schema.Float
defaultBoolType IRI = schema.Boolean
defaultTimeType IRI = schema.DateTime
defaultBytesType IRI = schema.Bytes
)

func init() {
Expand All @@ -288,6 +299,9 @@ func init() {
// time types
RegisterStringConversion(defaultTimeType, stringToTime)
RegisterStringConversion(nsXSD+`dateTime`, stringToTime)
// []byte types
RegisterStringConversion(defaultBytesType, stringToBytes)
RegisterStringConversion(nsXSD+`bytes`, stringToBytes)
}

var knownConversions = make(map[IRI]StringConversion)
Expand Down Expand Up @@ -342,6 +356,11 @@ func stringToTime(s string) (Value, error) {
return Time(v), nil
}

func stringToBytes(s string) (Value, error) {
v := base64.StdEncoding.EncodeToString([]byte(s))
return Bytes(v), nil
}

// Int is a native wrapper for int64 type.
//
// It uses NQuad notation similar to TypedString.
Expand Down Expand Up @@ -423,6 +442,30 @@ func (s Time) TypedString() TypedString {
}
}

// Bytes is representation of []byte as a value
type Bytes string

func (b Bytes) String() string {
return string(b)
}
func (b Bytes) Native() interface{} {
return []byte(b)
}
func (b Bytes) Equal(v Value) bool {
t, ok := v.(Bytes)
if !ok {
return false
}
return b == t
}
func (b Bytes) TypedString() TypedString {
return TypedString{
// TODO(dennwc): this is used to compute hash
Value: String(string(b)),
Type: defaultBytesType,
}
}

type ByValueString []Value

func (o ByValueString) Len() int { return len(o) }
Expand Down
1 change: 1 addition & 0 deletions schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
)

var reflQuadValue = reflect.TypeOf((*quad.Value)(nil)).Elem()
var byteArrayType = reflect.TypeOf([]byte(nil))

type ErrReqFieldNotSet struct {
Field string
Expand Down
4 changes: 3 additions & 1 deletion schema/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func (c *Config) WriteAsQuads(w quad.Writer, o interface{}) (quad.Value, error)
return wr.writeAsQuads(reflect.ValueOf(o))
}

var BytesType = reflect.TypeOf([]byte(nil))

type writer struct {
c *Config
w quad.Writer
Expand Down Expand Up @@ -92,7 +94,7 @@ func (w *writer) writeValueAs(id quad.Value, rv reflect.Value, pref string, rule
return err
}
case saveRule:
if f.Type.Kind() == reflect.Slice {
if f.Type.Kind() == reflect.Slice && f.Type != byteArrayType {
sl := rv.Field(i)
for j := 0; j < sl.Len(); j++ {
if err := w.writeOneValReflect(id, r.Pred, sl.Index(j), r.Rev); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions voc/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const (
True = Prefix + `True`
// Data type: Text.
Text = Prefix + `Text`
// Data type: Bytes.
Bytes = Prefix + "Bytes"
// Data type: URL.
URL = Prefix + `URL`
// Data type: Number.
Expand Down