Skip to content

Commit

Permalink
StorageIndexList add order param
Browse files Browse the repository at this point in the history
  • Loading branch information
hexun80149128 committed Feb 7, 2024
1 parent 9a03c2d commit f26b747
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 22 deletions.
5 changes: 3 additions & 2 deletions server/runtime_go_nakama.go
Original file line number Diff line number Diff line change
Expand Up @@ -2060,9 +2060,10 @@ func (n *RuntimeGoNakamaModule) StorageDelete(ctx context.Context, deletes []*ru
// @param callerId(type=string, optional=true) User ID of the caller, will apply permissions checks of the user. If empty defaults to system user and permissions are bypassed.
// @param queryString(type=string) Query to filter index entries.
// @param limit(type=int) Maximum number of results to be returned.
// @param order(type=[]string) Strings in the slice are interpreted as the name of a field to sort ascending. - the prefix '-' will sort in descending order
// @return objects(*api.StorageObjectList) A list of storage objects.
// @return error(error) An optional error value if an error occurred.
func (n *RuntimeGoNakamaModule) StorageIndexList(ctx context.Context, callerID, indexName, query string, limit int) (*api.StorageObjects, error) {
func (n *RuntimeGoNakamaModule) StorageIndexList(ctx context.Context, callerID, indexName, query string, limit int, order []string) (*api.StorageObjects, error) {
cid := uuid.Nil
if callerID != "" {
id, err := uuid.FromString(callerID)
Expand All @@ -2080,7 +2081,7 @@ func (n *RuntimeGoNakamaModule) StorageIndexList(ctx context.Context, callerID,
return nil, errors.New("limit must be 1-10000")
}

return n.storageIndex.List(ctx, cid, indexName, query, limit)
return n.storageIndex.List(ctx, cid, indexName, query, limit, order)
}

// @group users
Expand Down
17 changes: 14 additions & 3 deletions server/runtime_javascript_nakama.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ func (n *runtimeJavascriptNakamaModule) stringToBinary(r *goja.Runtime) func(goj
// @param indexName(type=string) Name of the index to list entries from.
// @param queryString(type=string) Query to filter index entries.
// @param limit(type=int) Maximum number of results to be returned.
// @param order(type=[]string) Strings in the slice are interpreted as the name of a field to sort ascending. - the prefix '-' will sort in descending order
// @param callerId(type=string, optional=true) User ID of the caller, will apply permissions checks of the user. If empty defaults to system user and permission checks are bypassed.
// @return objects(nkruntime.StorageObjectList) A list of storage objects.
// @return error(error) An optional error value if an error occurred.
Expand All @@ -362,17 +363,27 @@ func (n *runtimeJavascriptNakamaModule) storageIndexList(r *goja.Runtime) func(g
panic(r.NewTypeError("limit must be 1-10000"))
}
}

ownersArray := f.Argument(3)
if goja.IsUndefined(ownersArray) || goja.IsNull(ownersArray) {
panic(r.NewTypeError("expects an array of fields"))
}
order, err := exportToSlice[[]string](ownersArray)
if err != nil {
panic(r.NewTypeError("expects an array of strings"))
}

callerID := uuid.Nil
if !goja.IsUndefined(f.Argument(3)) && !goja.IsNull(f.Argument(3)) {
callerIdStr := getJsString(r, f.Argument(3))
if !goja.IsUndefined(f.Argument(4)) && !goja.IsNull(f.Argument(4)) {
callerIdStr := getJsString(r, f.Argument(4))
cid, err := uuid.FromString(callerIdStr)
if err != nil {
panic(r.NewTypeError("expects caller id to be valid identifier"))
}
callerID = cid
}

objectList, err := n.storageIndex.List(n.ctx, callerID, idxName, queryString, int(limit))
objectList, err := n.storageIndex.List(n.ctx, callerID, idxName, queryString, int(limit), order)
if err != nil {
panic(r.NewGoError(fmt.Errorf("failed to lookup storage index: %s", err.Error())))
}
Expand Down
17 changes: 14 additions & 3 deletions server/runtime_lua_nakama.go
Original file line number Diff line number Diff line change
Expand Up @@ -9971,6 +9971,7 @@ func (n *RuntimeLuaNakamaModule) channelIdBuild(l *lua.LState) int {
// @param indexName(type=string) Name of the index to list entries from.
// @param queryString(type=string) Query to filter index entries.
// @param limit(type=int) Maximum number of results to be returned.
// @param order(type=[]string) Strings in the slice are interpreted as the name of a field to sort ascending. - the prefix '-' will sort in descending order
// @param callerId(type=string, optional=true) User ID of the caller, will apply permissions checks of the user. If empty defaults to system user and permission checks are bypassed.
// @return objects(table) A list of storage objects.
// @return error(error) An optional error value if an error occurred.
Expand All @@ -9982,18 +9983,28 @@ func (n *RuntimeLuaNakamaModule) storageIndexList(l *lua.LState) int {
l.ArgError(3, "invalid limit: expects value 1-10000")
return 0
}
orderTable := l.CheckTable(4)
orders := make([]string, 0, orderTable.Len())
orderTable.ForEach(func(k, v lua.LValue) {
if v.Type() != lua.LTString {
l.ArgError(4, "expects each field to be string")
return
}
orders = append(orders, v.String())
})

callerID := uuid.Nil
callerIDStr := l.OptString(4, "")
callerIDStr := l.OptString(5, "")
if callerIDStr != "" {
cid, err := uuid.FromString(callerIDStr)
if err != nil {
l.ArgError(4, "expects caller ID to be empty or a valid identifier")
l.ArgError(5, "expects caller ID to be empty or a valid identifier")
return 0
}
callerID = cid
}

objectList, err := n.storageIndex.List(l.Context(), callerID, idxName, queryString, limit)
objectList, err := n.storageIndex.List(l.Context(), callerID, idxName, queryString, limit, orders)
if err != nil {
l.RaiseError(err.Error())
return 0
Expand Down
8 changes: 6 additions & 2 deletions server/storage_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
type StorageIndex interface {
Write(ctx context.Context, objects []*api.StorageObject) (creates int, deletes int)
Delete(ctx context.Context, objects StorageOpDeletes) (deletes int)
List(ctx context.Context, callerID uuid.UUID, indexName, query string, limit int) (*api.StorageObjects, error)
List(ctx context.Context, callerID uuid.UUID, indexName, query string, limit int, order []string) (*api.StorageObjects, error)
Load(ctx context.Context) error
CreateIndex(ctx context.Context, name, collection, key string, fields []string, maxEntries int, indexOnly bool) error
RegisterFilters(runtime *Runtime)
Expand Down Expand Up @@ -217,7 +217,7 @@ func (si *LocalStorageIndex) Delete(ctx context.Context, objects StorageOpDelete
return deletes
}

func (si *LocalStorageIndex) List(ctx context.Context, callerID uuid.UUID, indexName, query string, limit int) (*api.StorageObjects, error) {
func (si *LocalStorageIndex) List(ctx context.Context, callerID uuid.UUID, indexName, query string, limit int, order []string) (*api.StorageObjects, error) {
idx, found := si.indexByName[indexName]
if !found {
return nil, fmt.Errorf("index %q not found", indexName)
Expand All @@ -238,6 +238,10 @@ func (si *LocalStorageIndex) List(ctx context.Context, callerID uuid.UUID, index

searchReq := bluge.NewTopNSearch(limit, parsedQuery)

if len(order) != 0{
searchReq.SortBy(order)
}

indexReader, err := idx.Index.Reader()
if err != nil {
return nil, err
Expand Down
41 changes: 30 additions & 11 deletions server/storage_index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ func TestLocalStorageIndex_Write(t *testing.T) {
t.Fatal(err.Error())
}

entries, err := storageIdx.List(ctx, uuid.Nil, indexName1, "", maxEntries1) // Match all
entries, err := storageIdx.List(ctx, uuid.Nil, indexName1, "", maxEntries1, []string{}) // Match all
if err != nil {
t.Fatal(err.Error())
}
assert.Len(t, entries.Objects, 2, "indexed results length was not 2")

entries, err = storageIdx.List(ctx, uuid.Nil, indexName2, "", maxEntries1) // Match all
entries, err = storageIdx.List(ctx, uuid.Nil, indexName2, "", maxEntries1, []string{}) // Match all
if err != nil {
t.Fatal(err.Error())
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func TestLocalStorageIndex_Write(t *testing.T) {
t.Fatal(err.Error())
}

entries, err := storageIdx.List(ctx, uuid.Nil, indexName1, "+value.three:3", maxEntries1)
entries, err := storageIdx.List(ctx, uuid.Nil, indexName1, "+value.three:3", maxEntries1, []string{})
if err != nil {
t.Fatal(err.Error())
}
Expand Down Expand Up @@ -275,7 +275,7 @@ func TestLocalStorageIndex_Write(t *testing.T) {
t.Fatal(err.Error())
}

entries, err := storageIdx.List(ctx, uuid.Nil, indexName2, "", maxEntries2)
entries, err := storageIdx.List(ctx, uuid.Nil, indexName2, "", maxEntries2, []string{})
if err != nil {
t.Fatal(err.Error())
}
Expand Down Expand Up @@ -371,7 +371,7 @@ func TestLocalStorageIndex_List(t *testing.T) {
t.Fatal(err.Error())
}

entries, err := storageIdx.List(ctx, uuid.Nil, indexName, "value.one:1 value.three:3", 10)
entries, err := storageIdx.List(ctx, uuid.Nil, indexName, "value.one:1 value.three:3", 10, []string{})
if err != nil {
t.Fatal(err.Error())
}
Expand Down Expand Up @@ -412,15 +412,18 @@ func TestLocalStorageIndex_List(t *testing.T) {
maxEntries := 10

valueOneBytes, _ := json.Marshal(map[string]any{
"one": 1,
"one": 1,
"sort": 1,
})
valueOne := string(valueOneBytes)
valueTwoBytes, _ := json.Marshal(map[string]any{
"two": 2,
"two": 2,
"sort": 2,
})
valueTwo := string(valueTwoBytes)
valueThreeBytes, _ := json.Marshal(map[string]any{
"three": 3,
"sort": 3,
})
valueThree := string(valueThreeBytes)

Expand All @@ -429,7 +432,7 @@ func TestLocalStorageIndex_List(t *testing.T) {
t.Fatal(err.Error())
}

if err := storageIdx.CreateIndex(ctx, indexName, collection, key, []string{"one", "two", "three"}, maxEntries, true); err != nil {
if err := storageIdx.CreateIndex(ctx, indexName, collection, key, []string{"one", "two", "three", "sort"}, maxEntries, true); err != nil {
t.Fatal(err.Error())
}

Expand Down Expand Up @@ -464,7 +467,7 @@ func TestLocalStorageIndex_List(t *testing.T) {
t.Fatal(err.Error())
}

entries, err := storageIdx.List(ctx, uuid.Nil, indexName, "value.one:1 value.three:3", 10)
entries, err := storageIdx.List(ctx, uuid.Nil, indexName, "value.one:1 value.three:3", 10, []string{})
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -473,6 +476,22 @@ func TestLocalStorageIndex_List(t *testing.T) {
assert.Equal(t, valueOne, entries.Objects[0].Value, "expected value retrieved from db did not match")
assert.Equal(t, valueThree, entries.Objects[1].Value, "expected value retrieved from db did not match")

sortEntries, err := storageIdx.List(ctx, uuid.Nil, indexName, "value.one:1 value.three:3", 10, []string{"value.sort"})
if err != nil {
t.Fatal(err.Error())
}
assert.Len(t, sortEntries.Objects, 2, "indexed results did not match query params")
assert.Equal(t, valueOne, sortEntries.Objects[0].Value, "expected value retrieved from db did not match")
assert.Equal(t, valueThree, sortEntries.Objects[1].Value, "expected value retrieved from db did not match")

sortDescEntries, err := storageIdx.List(ctx, uuid.Nil, indexName, "value.one:1 value.three:3", 10, []string{"-value.sort"})
if err != nil {
t.Fatal(err.Error())
}
assert.Len(t, sortDescEntries.Objects, 2, "indexed results did not match query params")
assert.Equal(t, valueOne, sortDescEntries.Objects[1].Value, "expected value retrieved from db did not match")
assert.Equal(t, valueThree, sortDescEntries.Objects[0].Value, "expected value retrieved from db did not match")

delOps := make(StorageOpDeletes, 0, len(writeOps))
for _, op := range writeOps {
delOps = append(delOps, &StorageOpDelete{
Expand Down Expand Up @@ -540,7 +559,7 @@ func TestLocalStorageIndex_Delete(t *testing.T) {
t.Fatal(err.Error())
}

entries, err := storageIdx.List(ctx, uuid.Nil, indexName, "", 10)
entries, err := storageIdx.List(ctx, uuid.Nil, indexName, "", 10, []string{})
if err != nil {
t.Fatal(err.Error())
}
Expand All @@ -557,7 +576,7 @@ func TestLocalStorageIndex_Delete(t *testing.T) {
t.Fatal(err.Error())
}

entries, err = storageIdx.List(ctx, uuid.Nil, indexName, "", 10)
entries, err = storageIdx.List(ctx, uuid.Nil, indexName, "", 10, []string{})
if err != nil {
t.Fatal(err.Error())
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f26b747

Please sign in to comment.