Skip to content

Commit

Permalink
Merge branch 'develop' into nasdf/fix/gql-error-response
Browse files Browse the repository at this point in the history
  • Loading branch information
nasdf committed Sep 20, 2024
2 parents 2c648fc + 55e56a5 commit cf52fed
Show file tree
Hide file tree
Showing 30 changed files with 1,680 additions and 170 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The following keys are loaded from the keyring on start:
- `peer-key` Ed25519 private key (required)
- `encryption-key` AES-128, AES-192, or AES-256 key (optional)

A secret to unlock the keyring is required on start and must be provided via the `DEFRADB_KEYRING_SECRET` environment variable. If a `.env` file is available in the working directory, the secret can be stored there or via a file at a path defined by the `--keyring-secret-file` flag.
A secret to unlock the keyring is required on start and must be provided via the `DEFRA_KEYRING_SECRET` environment variable. If a `.env` file is available in the working directory, the secret can be stored there or via a file at a path defined by the `--secret-file` flag.

The keys will be randomly generated on the inital start of the node if they are not found.

Expand Down
2 changes: 1 addition & 1 deletion cli/keyring_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Prints the hexadecimal representation of a private key.
The DEFRA_KEYRING_SECRET environment variable must be set to unlock the keyring.
This can also be done with a .env file in the working directory or at a path
defined with the --keyring-secret-file flag.
defined with the --secret-file flag.
Example:
defradb keyring export encryption-key`,
Expand Down
2 changes: 1 addition & 1 deletion cli/keyring_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ By default peer and encryption keys will be generated.
The DEFRA_KEYRING_SECRET environment variable must be set to unlock the keyring.
This can also be done with a .env file in the working directory or at a path
defined with the --keyring-secret-file flag.
defined with the --secret-file flag.
WARNING: This will overwrite existing keys in the keyring.
Expand Down
2 changes: 1 addition & 1 deletion cli/keyring_import.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Store an externally generated key in the keyring.
The DEFRA_KEYRING_SECRET environment variable must be set to unlock the keyring.
This can also be done with a .env file in the working directory or at a path
defined with the --keyring-secret-file flag.
defined with the --secret-file flag.
Example:
defradb keyring import encryption-key 0000000000000000`,
Expand Down
2 changes: 1 addition & 1 deletion docs/website/references/cli/defradb_keyring_export.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Prints the hexadecimal representation of a private key.

The DEFRA_KEYRING_SECRET environment variable must be set to unlock the keyring.
This can also be done with a .env file in the working directory or at a path
defined with the --keyring-secret-file flag.
defined with the --secret-file flag.

Example:
defradb keyring export encryption-key
Expand Down
2 changes: 1 addition & 1 deletion docs/website/references/cli/defradb_keyring_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ By default peer and encryption keys will be generated.

The DEFRA_KEYRING_SECRET environment variable must be set to unlock the keyring.
This can also be done with a .env file in the working directory or at a path
defined with the --keyring-secret-file flag.
defined with the --secret-file flag.

WARNING: This will overwrite existing keys in the keyring.

Expand Down
2 changes: 1 addition & 1 deletion docs/website/references/cli/defradb_keyring_import.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Store an externally generated key in the keyring.

The DEFRA_KEYRING_SECRET environment variable must be set to unlock the keyring.
This can also be done with a .env file in the working directory or at a path
defined with the --keyring-secret-file flag.
defined with the --secret-file flag.

Example:
defradb keyring import encryption-key 0000000000000000
Expand Down
53 changes: 53 additions & 0 deletions internal/connor/all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package connor

import (
"github.com/sourcenetwork/defradb/client"

"github.com/sourcenetwork/immutable"
)

// all is an operator which allows the evaluation of
// a number of conditions over a list of values
// matching if all of them match.
func all(condition, data any) (bool, error) {
switch t := data.(type) {
case []string:
return allSlice(condition, t)

case []immutable.Option[string]:
return allSlice(condition, t)

case []int64:
return allSlice(condition, t)

case []immutable.Option[int64]:
return allSlice(condition, t)

case []bool:
return allSlice(condition, t)

case []immutable.Option[bool]:
return allSlice(condition, t)

case []float64:
return allSlice(condition, t)

case []immutable.Option[float64]:
return allSlice(condition, t)

default:
return false, client.NewErrUnhandledType("data", data)
}
}

func allSlice[T any](condition any, data []T) (bool, error) {
for _, c := range data {
m, err := eq(condition, c)
if err != nil {
return false, err
} else if !m {
return false, nil
}
}
return true, nil
}
2 changes: 1 addition & 1 deletion internal/connor/and.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ func and(condition, data any) (bool, error) {
return false, nil
}
}

return true, nil

default:
return false, client.NewErrUnhandledType("condition", cn)
}
Expand Down
53 changes: 53 additions & 0 deletions internal/connor/any.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package connor

import (
"github.com/sourcenetwork/defradb/client"

"github.com/sourcenetwork/immutable"
)

// anyOp is an operator which allows the evaluation of
// a number of conditions over a list of values
// matching if any of them match.
func anyOp(condition, data any) (bool, error) {
switch t := data.(type) {
case []string:
return anySlice(condition, t)

case []immutable.Option[string]:
return anySlice(condition, t)

case []int64:
return anySlice(condition, t)

case []immutable.Option[int64]:
return anySlice(condition, t)

case []bool:
return anySlice(condition, t)

case []immutable.Option[bool]:
return anySlice(condition, t)

case []float64:
return anySlice(condition, t)

case []immutable.Option[float64]:
return anySlice(condition, t)

default:
return false, client.NewErrUnhandledType("data", data)
}
}

func anySlice[T any](condition any, data []T) (bool, error) {
for _, c := range data {
m, err := eq(condition, c)
if err != nil {
return false, err
} else if m {
return true, nil
}
}
return false, nil
}
6 changes: 6 additions & 0 deletions internal/connor/connor.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ func matchWith(op string, conditions, data any) (bool, error) {
switch op {
case "_and":
return and(conditions, data)
case "_any":
return anyOp(conditions, data)
case "_all":
return all(conditions, data)
case "_eq":
return eq(conditions, data)
case "_ge":
Expand All @@ -44,6 +48,8 @@ func matchWith(op string, conditions, data any) (bool, error) {
return ilike(conditions, data)
case "_nilike":
return nilike(conditions, data)
case "_none":
return none(conditions, data)
case "_not":
return not(conditions, data)
default:
Expand Down
69 changes: 27 additions & 42 deletions internal/connor/eq.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,74 +16,59 @@ import (
func eq(condition, data any) (bool, error) {
switch arr := data.(type) {
case []core.Doc:
for _, item := range arr {
m, err := eq(condition, item)
if err != nil {
return false, err
}

if m {
return true, nil
}
}
return false, nil
return anySlice(condition, arr)

case immutable.Option[bool]:
if !arr.HasValue() {
return condition == nil, nil
}
data = arr.Value()
data = immutableValueOrNil(arr)

case immutable.Option[int64]:
if !arr.HasValue() {
return condition == nil, nil
}
data = arr.Value()
data = immutableValueOrNil(arr)

case immutable.Option[float64]:
if !arr.HasValue() {
return condition == nil, nil
}
data = arr.Value()
data = immutableValueOrNil(arr)

case immutable.Option[string]:
if !arr.HasValue() {
return condition == nil, nil
}
data = arr.Value()
data = immutableValueOrNil(arr)
}

switch cn := condition.(type) {
case map[FilterKey]any:
for prop, cond := range cn {
m, err := matchWith(prop.GetOperatorOrDefault("_eq"), cond, prop.GetProp(data))
if err != nil {
return false, err
} else if !m {
return false, nil
}
}
return true, nil

case string:
if d, ok := data.(string); ok {
return d == cn, nil
}
return false, nil

case int64:
return numbers.Equal(cn, data), nil

case int32:
return numbers.Equal(cn, data), nil

case float64:
return numbers.Equal(cn, data), nil
case map[FilterKey]any:
m := true
for prop, cond := range cn {
var err error
m, err = matchWith(prop.GetOperatorOrDefault("_eq"), cond, prop.GetProp(data))
if err != nil {
return false, err
}

if !m {
// No need to evaluate after we fail
break
}
}

return m, nil
case time.Time:
return ctime.Equal(cn, data), nil

default:
return reflect.DeepEqual(condition, data), nil
}
}

func immutableValueOrNil[T any](data immutable.Option[T]) any {
if data.HasValue() {
return data.Value()
}
return nil
}
12 changes: 12 additions & 0 deletions internal/connor/none.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package connor

// none is an operator which allows the evaluation of
// a number of conditions over a list of values
// matching if all of them do not match.
func none(condition, data any) (bool, error) {
m, err := anyOp(condition, data)
if err != nil {
return false, err
}
return !m, nil
}
8 changes: 5 additions & 3 deletions internal/planner/mapper/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -1348,13 +1348,15 @@ func toFilterMap(
returnClause := map[connor.FilterKey]any{}
for innerSourceKey, innerSourceValue := range typedClause {
var innerMapping *core.DocumentMapping
switch innerSourceValue.(type) {
case map[string]any:
// innerSourceValue may refer to a child mapping or
// an inline array if we don't have a child mapping
_, ok := innerSourceValue.(map[string]any)
if ok && index < len(mapping.ChildMappings) {
// If the innerSourceValue is also a map, then we should parse the nested clause
// using the child mapping, as this key must refer to a host property in a join
// and deeper keys must refer to properties on the child items.
innerMapping = mapping.ChildMappings[index]
default:
} else {
innerMapping = mapping
}
rKey, rValue := toFilterMap(innerSourceKey, innerSourceValue, innerMapping)
Expand Down
11 changes: 9 additions & 2 deletions internal/planner/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,15 @@ func (p *parallelNode) nextMerge(_ int, plan planNode) (bool, error) {
return false, err
}

doc := plan.Value()
copy(p.currentValue.Fields, doc.Fields)
// Field-by-fields check is necessary because parallelNode can have multiple children, and
// each child can return the same doc, but with different related fields available
// depending on what is requested.
newFields := plan.Value().Fields
for i := range newFields {
if p.currentValue.Fields[i] == nil {
p.currentValue.Fields[i] = newFields[i]
}
}

return true, nil
}
Expand Down
Loading

0 comments on commit cf52fed

Please sign in to comment.