Skip to content

Commit

Permalink
chore: Refactoring package management (#51)
Browse files Browse the repository at this point in the history
**Description**

refactoring packages for clearer code, remove duplications, etc

**Checklist**

- [x] Code compiles correctly and linting passes locally
- [x] For all _code_ changes, an entry added to the `CHANGELOG.md` file
describing and linking to
      this PR
- [ ] Tests added for new functionality, or regression tests for bug
fixes added as applicable
- [ ] For public APIs, new features, etc., PR on [docs
repo](https://github.com/hypermodeinc/docs)
      staged and linked here
  • Loading branch information
jairad26 authored Jan 3, 2025
1 parent bcd42e1 commit dd2ea80
Show file tree
Hide file tree
Showing 15 changed files with 985 additions and 892 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- feat: add readfrom json tag to support reverse edges
[#49](https://github.com/hypermodeinc/modusDB/pull/49)

- chore: Refactoring package management #51 [#51](https://github.com/hypermodeinc/modusDB/pull/51)

## 2025-01-02 - Version 0.1.0

Baseline for the changelog.
Expand Down
22 changes: 9 additions & 13 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/dgraph-io/dgraph/v24/dql"
"github.com/dgraph-io/dgraph/v24/schema"
"github.com/hypermodeinc/modusdb/api/utils"
)

func Create[T any](db *DB, object T, ns ...uint64) (uint64, T, error) {
Expand All @@ -34,7 +35,7 @@ func Create[T any](db *DB, object T, ns ...uint64) (uint64, T, error) {

dms := make([]*dql.Mutation, 0)
sch := &schema.ParsedSchema{}
err = generateCreateDqlMutationsAndSchema[T](ctx, n, object, gid, &dms, sch)
err = generateSetDqlMutationsAndSchema[T](ctx, n, object, gid, &dms, sch)
if err != nil {
return 0, object, err
}
Expand Down Expand Up @@ -66,14 +67,14 @@ func Upsert[T any](db *DB, object T, ns ...uint64) (uint64, T, bool, error) {
return 0, object, false, err
}

gid, cf, err := getUniqueConstraint[T](object)
gid, cf, err := GetUniqueConstraint[T](object)
if err != nil {
return 0, object, false, err
}

dms := make([]*dql.Mutation, 0)
sch := &schema.ParsedSchema{}
err = generateCreateDqlMutationsAndSchema[T](ctx, n, object, gid, &dms, sch)
err = generateSetDqlMutationsAndSchema[T](ctx, n, object, gid, &dms, sch)
if err != nil {
return 0, object, false, err
}
Expand All @@ -83,19 +84,14 @@ func Upsert[T any](db *DB, object T, ns ...uint64) (uint64, T, bool, error) {
return 0, object, false, err
}

if gid != 0 {
gid, _, err = getByGidWithObject[T](ctx, n, gid, object)
if err != nil && err != ErrNoObjFound {
return 0, object, false, err
}
wasFound = err == nil
} else if cf != nil {
gid, _, err = getByConstrainedFieldWithObject[T](ctx, n, *cf, object)
if err != nil && err != ErrNoObjFound {
if gid != 0 || cf != nil {
gid, err = getExistingObject[T](ctx, n, gid, cf, object)
if err != nil && err != utils.ErrNoObjFound {
return 0, object, false, err
}
wasFound = err == nil
}

if gid == 0 {
gid, err = db.z.nextUID()
if err != nil {
Expand All @@ -104,7 +100,7 @@ func Upsert[T any](db *DB, object T, ns ...uint64) (uint64, T, bool, error) {
}

dms = make([]*dql.Mutation, 0)
err = generateCreateDqlMutationsAndSchema[T](ctx, n, object, gid, &dms, sch)
err = generateSetDqlMutationsAndSchema[T](ctx, n, object, gid, &dms, sch)
if err != nil {
return 0, object, false, err
}
Expand Down
71 changes: 71 additions & 0 deletions api/mutations/mutations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package mutations

import (
"fmt"
"reflect"
"strings"

"github.com/dgraph-io/dgo/v240/protos/api"
"github.com/dgraph-io/dgraph/v24/protos/pb"
"github.com/dgraph-io/dgraph/v24/schema"
"github.com/hypermodeinc/modusdb/api/utils"
)

func HandleReverseEdge(jsonName string, value reflect.Type, nsId uint64, sch *schema.ParsedSchema,
jsonToReverseEdgeTags map[string]string) error {
if jsonToReverseEdgeTags[jsonName] == "" {
return nil
}

if value.Kind() != reflect.Slice || value.Elem().Kind() != reflect.Struct {
return fmt.Errorf("reverse edge %s should be a slice of structs", jsonName)
}

reverseEdge := jsonToReverseEdgeTags[jsonName]
typeName := strings.Split(reverseEdge, ".")[0]
u := &pb.SchemaUpdate{
Predicate: utils.AddNamespace(nsId, reverseEdge),
ValueType: pb.Posting_UID,
Directive: pb.SchemaUpdate_REVERSE,
}

sch.Preds = append(sch.Preds, u)
sch.Types = append(sch.Types, &pb.TypeUpdate{
TypeName: utils.AddNamespace(nsId, typeName),
Fields: []*pb.SchemaUpdate{u},
})
return nil
}

func CreateNQuadAndSchema(value any, gid uint64, jsonName string, t reflect.Type,
nsId uint64) (*api.NQuad, *pb.SchemaUpdate, error) {
valType, err := utils.ValueToPosting_ValType(value)
if err != nil {
return nil, nil, err
}

val, err := utils.ValueToApiVal(value)
if err != nil {
return nil, nil, err
}

nquad := &api.NQuad{
Namespace: nsId,
Subject: fmt.Sprint(gid),
Predicate: utils.GetPredicateName(t.Name(), jsonName),
}

u := &pb.SchemaUpdate{
Predicate: utils.AddNamespace(nsId, utils.GetPredicateName(t.Name(), jsonName)),
ValueType: valType,
}

if valType == pb.Posting_UID {
nquad.ObjectId = fmt.Sprint(value)
u.Directive = pb.SchemaUpdate_REVERSE
} else {
nquad.ObjectValue = val
}

return nquad, u, nil
}
173 changes: 173 additions & 0 deletions api/query_gen/dql_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package query_gen

import (
"fmt"
"strconv"
"strings"
)

type QueryFunc func() string

const (
ObjQuery = `
{
obj(func: %s) {
gid: uid
expand(_all_) {
gid: uid
expand(_all_)
dgraph.type
}
dgraph.type
%s
}
}
`

ObjsQuery = `
{
objs(func: type("%s")%s) @filter(%s) {
gid: uid
expand(_all_) {
gid: uid
expand(_all_)
dgraph.type
}
dgraph.type
%s
}
}
`

ReverseEdgeQuery = `
%s: ~%s {
gid: uid
expand(_all_)
dgraph.type
}
`

FuncUid = `uid(%d)`
FuncEq = `eq(%s, %s)`
FuncSimilarTo = `similar_to(%s, %d, "[%s]")`
FuncAllOfTerms = `allofterms(%s, "%s")`
FuncAnyOfTerms = `anyofterms(%s, "%s")`
FuncAllOfText = `alloftext(%s, "%s")`
FuncAnyOfText = `anyoftext(%s, "%s")`
FuncRegExp = `regexp(%s, /%s/)`
FuncLe = `le(%s, %s)`
FuncGe = `ge(%s, %s)`
FuncGt = `gt(%s, %s)`
FuncLt = `lt(%s, %s)`
)

func BuildUidQuery(gid uint64) QueryFunc {
return func() string {
return fmt.Sprintf(FuncUid, gid)
}
}

func BuildEqQuery(key string, value any) QueryFunc {
return func() string {
return fmt.Sprintf(FuncEq, key, value)
}
}

func BuildSimilarToQuery(indexAttr string, topK int64, vec []float32) QueryFunc {
vecStrArr := make([]string, len(vec))
for i := range vec {
vecStrArr[i] = strconv.FormatFloat(float64(vec[i]), 'f', -1, 32)
}
vecStr := strings.Join(vecStrArr, ",")
return func() string {
return fmt.Sprintf(FuncSimilarTo, indexAttr, topK, vecStr)
}
}

func BuildAllOfTermsQuery(attr string, terms string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncAllOfTerms, attr, terms)
}
}

func BuildAnyOfTermsQuery(attr string, terms string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncAnyOfTerms, attr, terms)
}
}

func BuildAllOfTextQuery(attr, text string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncAllOfText, attr, text)
}
}

func BuildAnyOfTextQuery(attr, text string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncAnyOfText, attr, text)
}
}

func BuildRegExpQuery(attr, pattern string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncRegExp, attr, pattern)
}
}

func BuildLeQuery(attr, value string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncLe, attr, value)
}
}

func BuildGeQuery(attr, value string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncGe, attr, value)
}
}

func BuildGtQuery(attr, value string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncGt, attr, value)
}
}

func BuildLtQuery(attr, value string) QueryFunc {
return func() string {
return fmt.Sprintf(FuncLt, attr, value)
}
}

func And(qfs ...QueryFunc) QueryFunc {
return func() string {
qs := make([]string, len(qfs))
for i, qf := range qfs {
qs[i] = qf()
}
return strings.Join(qs, " AND ")
}
}

func Or(qfs ...QueryFunc) QueryFunc {
return func() string {
qs := make([]string, len(qfs))
for i, qf := range qfs {
qs[i] = qf()
}
return strings.Join(qs, " OR ")
}
}

func Not(qf QueryFunc) QueryFunc {
return func() string {
return "NOT " + qf()
}
}

func FormatObjQuery(qf QueryFunc, extraFields string) string {
return fmt.Sprintf(ObjQuery, qf(), extraFields)
}

func FormatObjsQuery(typeName string, qf QueryFunc, paginationAndSorting string, extraFields string) string {
return fmt.Sprintf(ObjsQuery, typeName, paginationAndSorting, qf(), extraFields)
}
Loading

0 comments on commit dd2ea80

Please sign in to comment.