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

Refactor/common index interface #4

Merged
merged 5 commits into from
Nov 8, 2022
Merged
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
21 changes: 15 additions & 6 deletions api/apicollectionv1/0_traverse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package apicollectionv1

import (
"encoding/json"
"fmt"
"sort"

"github.com/SierraSoftworks/connor"
Expand Down Expand Up @@ -59,22 +60,30 @@ func traverseFullscan(input []byte, col *collection.Collection, f func(row *coll
func traverseUnique(input []byte, col *collection.Collection, f func(row *collection.Row)) error {

params := &struct {
Field string
Index string
Value string
}{}
err := json.Unmarshal(input, &params)
if err != nil {
return err
}

row, err := col.FindByRow(params.Field, params.Value)
index, exist := col.Indexes[params.Index]
if !exist {
return fmt.Errorf("index '%s' does not exist", params.Index)
}

traverseOptions, err := json.Marshal(collection.IndexMapTraverse{
Value: params.Value,
})
if err != nil {
return err
// w.WriteHeader(http.StatusNotFound)
// return fmt.Errorf("item %s='%s' does not exist", params.Field, params.Value)
return fmt.Errorf("marshal traverse options: %s", err.Error())
}

f(row)
index.Traverse(traverseOptions, func(row *collection.Row) bool {
f(row)
return true
})

return nil
}
Expand Down
14 changes: 7 additions & 7 deletions api/apicollectionv1/createIndex.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ import (
"github.com/fulldump/inceptiondb/service"
)

func createIndex(ctx context.Context, options *collection.IndexOptions) (*listIndexesItem, error) {
func createIndex(ctx context.Context, input *collection.CreateIndexOptions) (*listIndexesItem, error) {

s := GetServicer(ctx)
collectionName := box.GetUrlParameter(ctx, "collectionName")
collection, err := s.GetCollection(collectionName)
col, err := s.GetCollection(collectionName)
if err == service.ErrorCollectionNotFound {
collection, err = s.CreateCollection(collectionName)
col, err = s.CreateCollection(collectionName)
}
if err != nil {
return nil, err // todo: handle/wrap this properly
}

err = collection.Index(options)
err = col.Index(input)
if err != nil {
return nil, err
}

box.GetResponse(ctx).WriteHeader(http.StatusCreated)

return &listIndexesItem{
Name: options.Field,
Field: options.Field,
Sparse: options.Sparse,
Name: input.Name,
Kind: input.Kind,
// todo: return parameteres somehow
}, nil
}
32 changes: 20 additions & 12 deletions api/apicollectionv1/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package apicollectionv1
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

"github.com/fulldump/box"

Expand All @@ -21,31 +19,41 @@ func find(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
}

input := struct {
Mode string
Index string
}{
Mode: "fullscan",
Index: "",
}
err = json.Unmarshal(rquestBody, &input)
if err != nil {
return err
}

f, exist := findModes[input.Mode]
if !exist {
box.GetResponse(ctx).WriteHeader(http.StatusBadRequest)
return fmt.Errorf("bad mode '%s', must be [%s]. See docs: TODO", input.Mode, strings.Join(GetKeys(findModes), "|"))
}

s := GetServicer(ctx)
collectionName := box.GetUrlParameter(ctx, "collectionName")
collection, err := s.GetCollection(collectionName)
col, err := s.GetCollection(collectionName)
if err != nil {
return err // todo: handle/wrap this properly
}

return f(rquestBody, collection, w)
index, exists := col.Indexes[input.Index]
if !exists {
traverseFullscan(rquestBody, col, func(row *collection.Row) {
w.Write(row.Payload)
w.Write([]byte("\n"))
})
return nil
}

index.Traverse(rquestBody, func(row *collection.Row) bool {
w.Write(row.Payload)
w.Write([]byte("\n"))
return true
})

return nil
}

// TODO: remove this
var findModes = map[string]func(input []byte, col *collection.Collection, w http.ResponseWriter) error{
"fullscan": func(input []byte, col *collection.Collection, w http.ResponseWriter) error {
return traverseFullscan(input, col, writeRow(w))
Expand Down
8 changes: 5 additions & 3 deletions api/apicollectionv1/getIndex.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ func getIndex(ctx context.Context, input getIndexInput) (*listIndexesItem, error
}

for name, index := range collection.Indexes {
_ = index
if name == input.Name {
return &listIndexesItem{
Name: name,
Field: name,
Sparse: index.Sparse,
Name: name,
// Field: name,
// Sparse: index.Sparse,
// todo: fild properly
}, nil
}
}
Expand Down
13 changes: 7 additions & 6 deletions api/apicollectionv1/listIndexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package apicollectionv1

import (
"context"
"encoding/json"
"net/http"

"github.com/fulldump/box"
)

type listIndexesItem struct {
Name string `json:"name"`
Field string `json:"field"`
Sparse bool `json:"sparse"`
Name string `json:"name"`
Kind string `json:"kind"`
Parameters json.RawMessage `json:"parameters"` // todo: find a better name
}

func listIndexes(ctx context.Context, w http.ResponseWriter) ([]*listIndexesItem, error) {
Expand All @@ -24,10 +25,10 @@ func listIndexes(ctx context.Context, w http.ResponseWriter) ([]*listIndexesItem

result := []*listIndexesItem{}
for name, index := range collection.Indexes {
_ = index
result = append(result, &listIndexesItem{
Name: name,
Field: name,
Sparse: index.Sparse,
Name: name,
// TODO: complete the rest of fields
})
}

Expand Down
54 changes: 25 additions & 29 deletions api/apicollectionv1/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package apicollectionv1
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

"github.com/fulldump/box"

Expand All @@ -21,48 +19,46 @@ func patch(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
}

input := struct {
Mode string
Index string
}{
Mode: "fullscan",
Index: "",
}
err = json.Unmarshal(rquestBody, &input)
if err != nil {
return err
}

f, exist := patchModes[input.Mode]
if !exist {
box.GetResponse(ctx).WriteHeader(http.StatusBadRequest)
return fmt.Errorf("bad mode '%s', must be [%s]. See docs: TODO", input.Mode, strings.Join(GetKeys(patchModes), "|"))
}

s := GetServicer(ctx)
collectionName := box.GetUrlParameter(ctx, "collectionName")
collection, err := s.GetCollection(collectionName)
col, err := s.GetCollection(collectionName)
if err != nil {
return err // todo: handle/wrap this properly
}

return f(rquestBody, collection, w)
}
e := json.NewEncoder(w)

var patchModes = map[string]func(input []byte, col *collection.Collection, w http.ResponseWriter) error{
"fullscan": func(input []byte, col *collection.Collection, w http.ResponseWriter) error {
return traverseFullscan(input, col, patchRow(input, col, json.NewEncoder(w)))
},
"unique": func(input []byte, col *collection.Collection, w http.ResponseWriter) (err error) {
return traverseUnique(input, col, patchRow(input, col, json.NewEncoder(w)))
},
index, exists := col.Indexes[input.Index]
if !exists {
traverseFullscan(rquestBody, col, func(row *collection.Row) {
patchRow(rquestBody, col, row, e)
})
return nil
}

index.Traverse(rquestBody, func(row *collection.Row) bool {
patchRow(rquestBody, col, row, e)
return true
})

return nil
}

func patchRow(input []byte, col *collection.Collection, e *json.Encoder) func(row *collection.Row) {
return func(row *collection.Row) {
patch := struct {
Patch interface{}
}{}
json.Unmarshal(input, &patch) // TODO: handle err
func patchRow(input []byte, col *collection.Collection, row *collection.Row, e *json.Encoder) {
patch := struct {
Patch interface{}
}{}
json.Unmarshal(input, &patch) // TODO: handle err

_ = col.Patch(row, patch.Patch) // TODO: handle err
e.Encode(row.Payload)
}
_ = col.Patch(row, patch.Patch) // TODO: handle err
e.Encode(row.Payload)
}
52 changes: 22 additions & 30 deletions api/apicollectionv1/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package apicollectionv1
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

"github.com/fulldump/box"

Expand All @@ -21,50 +19,44 @@ func remove(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
}

input := struct {
Mode string
Index string
}{
Mode: "fullscan",
Index: "",
}
err = json.Unmarshal(rquestBody, &input)
if err != nil {
return err
}

f, exist := removeModes[input.Mode]
if !exist {
box.GetResponse(ctx).WriteHeader(http.StatusBadRequest)
return fmt.Errorf("bad mode '%s', must be [%s]. See docs: TODO", input.Mode, strings.Join(GetKeys(removeModes), "|"))
}

s := GetServicer(ctx)
collectionName := box.GetUrlParameter(ctx, "collectionName")
collection, err := s.GetCollection(collectionName)
col, err := s.GetCollection(collectionName)
if err != nil {
return err // todo: handle/wrap this properly
}

return f(rquestBody, collection, w)
}

var removeModes = map[string]func(input []byte, col *collection.Collection, w http.ResponseWriter) error{
"fullscan": func(input []byte, col *collection.Collection, w http.ResponseWriter) error {
traverseFullscan(input, col, removeRow(col, w))
index, exists := col.Indexes[input.Index]
if !exists {
traverseFullscan(rquestBody, col, func(row *collection.Row) {
removeRow(col, row, w)
})
return nil
},
"unique": func(input []byte, col *collection.Collection, w http.ResponseWriter) (err error) {
return traverseUnique(input, col, removeRow(col, w))
},
}
}

func removeRow(col *collection.Collection, w http.ResponseWriter) func(row *collection.Row) {
return func(row *collection.Row) {
index.Traverse(rquestBody, func(row *collection.Row) bool {
removeRow(col, row, w)
return true
})

err := col.Remove(row)
if err != nil {
return
}
return nil
}

w.Write(row.Payload)
w.Write([]byte("\n"))
func removeRow(col *collection.Collection, row *collection.Row, w http.ResponseWriter) {
err := col.Remove(row)
if err != nil {
return
}

w.Write(row.Payload)
w.Write([]byte("\n"))
}
Loading