mirror of
https://github.com/pikami/cosmium.git
synced 2026-04-21 05:48:51 +01:00
Compare commits
4 Commits
363f822e5a
...
v0.1.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5b8453995 | ||
|
|
928ca29fe4 | ||
|
|
39cd9e2357 | ||
|
|
bcf4b513b6 |
@@ -6,11 +6,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
jsonpatch "github.com/evanphx/json-patch/v5"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/logger"
|
"github.com/pikami/cosmium/internal/logger"
|
||||||
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
||||||
|
jsonpatch "github.com/pikami/json-patch/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handlers) GetAllDocuments(c *gin.Context) {
|
func (h *Handlers) GetAllDocuments(c *gin.Context) {
|
||||||
|
|||||||
@@ -147,6 +147,21 @@ func Test_Documents(t *testing.T) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should query document with query parameters as accessor", func(t *testing.T) {
|
||||||
|
testCosmosQuery(t, collectionClient,
|
||||||
|
`select c.id
|
||||||
|
FROM c
|
||||||
|
WHERE c[@param]="67890"
|
||||||
|
ORDER BY c.id`,
|
||||||
|
[]azcosmos.QueryParameter{
|
||||||
|
{Name: "@param", Value: "id"},
|
||||||
|
},
|
||||||
|
[]interface{}{
|
||||||
|
map[string]interface{}{"id": "67890"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("Should query array accessor", func(t *testing.T) {
|
t.Run("Should query array accessor", func(t *testing.T) {
|
||||||
testCosmosQuery(t, collectionClient,
|
testCosmosQuery(t, collectionClient,
|
||||||
`SELECT c.id,
|
`SELECT c.id,
|
||||||
@@ -220,11 +235,14 @@ func Test_Documents_Patch(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("Should PATCH document", func(t *testing.T) {
|
t.Run("Should PATCH document", func(t *testing.T) {
|
||||||
context := context.TODO()
|
context := context.TODO()
|
||||||
expectedData := map[string]interface{}{"id": "67890", "pk": "456", "newField": "newValue"}
|
expectedData := map[string]interface{}{"id": "67890", "pk": "666", "newField": "newValue", "incr": 15., "setted": "isSet"}
|
||||||
|
|
||||||
patch := azcosmos.PatchOperations{}
|
patch := azcosmos.PatchOperations{}
|
||||||
patch.AppendAdd("/newField", "newValue")
|
patch.AppendAdd("/newField", "newValue")
|
||||||
|
patch.AppendIncrement("/incr", 15)
|
||||||
patch.AppendRemove("/isCool")
|
patch.AppendRemove("/isCool")
|
||||||
|
patch.AppendReplace("/pk", "666")
|
||||||
|
patch.AppendSet("/setted", "isSet")
|
||||||
|
|
||||||
itemResponse, err := collectionClient.PatchItem(
|
itemResponse, err := collectionClient.PatchItem(
|
||||||
context,
|
context,
|
||||||
@@ -237,13 +255,15 @@ func Test_Documents_Patch(t *testing.T) {
|
|||||||
)
|
)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
var itemResponseBody map[string]string
|
var itemResponseBody map[string]interface{}
|
||||||
json.Unmarshal(itemResponse.Value, &itemResponseBody)
|
json.Unmarshal(itemResponse.Value, &itemResponseBody)
|
||||||
|
|
||||||
assert.Equal(t, expectedData["id"], itemResponseBody["id"])
|
assert.Equal(t, expectedData["id"], itemResponseBody["id"])
|
||||||
assert.Equal(t, expectedData["pk"], itemResponseBody["pk"])
|
assert.Equal(t, expectedData["pk"], itemResponseBody["pk"])
|
||||||
assert.Empty(t, itemResponseBody["isCool"])
|
assert.Empty(t, itemResponseBody["isCool"])
|
||||||
assert.Equal(t, expectedData["newField"], itemResponseBody["newField"])
|
assert.Equal(t, expectedData["newField"], itemResponseBody["newField"])
|
||||||
|
assert.Equal(t, expectedData["incr"], itemResponseBody["incr"])
|
||||||
|
assert.Equal(t, expectedData["setted"], itemResponseBody["setted"])
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Should not allow to PATCH document ID", func(t *testing.T) {
|
t.Run("Should not allow to PATCH document ID", func(t *testing.T) {
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -5,9 +5,9 @@ go 1.22.0
|
|||||||
require (
|
require (
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v0.3.6
|
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v0.3.6
|
||||||
github.com/evanphx/json-patch/v5 v5.9.0
|
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
|
github.com/pikami/json-patch/v5 v5.9.2
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67
|
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67
|
||||||
)
|
)
|
||||||
@@ -39,7 +39,7 @@ require (
|
|||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
golang.org/x/arch v0.12.0 // indirect
|
golang.org/x/arch v0.12.0 // indirect
|
||||||
golang.org/x/crypto v0.31.0 // indirect
|
golang.org/x/crypto v0.31.0 // indirect
|
||||||
golang.org/x/net v0.32.0 // indirect
|
golang.org/x/net v0.33.0 // indirect
|
||||||
golang.org/x/sys v0.28.0 // indirect
|
golang.org/x/sys v0.28.0 // indirect
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.0 // indirect
|
google.golang.org/protobuf v1.36.0 // indirect
|
||||||
|
|||||||
8
go.sum
8
go.sum
@@ -22,8 +22,6 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
|
|
||||||
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
|
|
||||||
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
@@ -66,6 +64,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
|||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||||
|
github.com/pikami/json-patch/v5 v5.9.2 h1:ciTlocWccYVE3DEa45dsMm02c/tOvcaBY7PpEUNZhrU=
|
||||||
|
github.com/pikami/json-patch/v5 v5.9.2/go.mod h1:eJIScZ4xgf2aBHLi2UMzYtjlWESUBDOBf7EAx3JW0nI=
|
||||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
|
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
|
||||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
|
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
@@ -92,8 +92,8 @@ golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
|||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
|
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
|
||||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -325,6 +325,7 @@ DotFieldAccess <- "." id:Identifier {
|
|||||||
|
|
||||||
ArrayFieldAccess <- "[\"" id:Identifier "\"]" { return id, nil }
|
ArrayFieldAccess <- "[\"" id:Identifier "\"]" { return id, nil }
|
||||||
/ "[" id:Integer "]" { return strconv.Itoa(id.(int)), nil }
|
/ "[" id:Integer "]" { return strconv.Itoa(id.(int)), nil }
|
||||||
|
/ "[" id:ParameterConstant "]" { return id.(parsers.Constant).Value.(string), nil }
|
||||||
|
|
||||||
Identifier <- [a-zA-Z_][a-zA-Z0-9_]* {
|
Identifier <- [a-zA-Z_][a-zA-Z0-9_]* {
|
||||||
return string(c.text), nil
|
return string(c.text), nil
|
||||||
|
|||||||
@@ -22,6 +22,20 @@ func Test_Parse_Select(t *testing.T) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should parse SELECT with query parameters as accessor", func(t *testing.T) {
|
||||||
|
testQueryParse(
|
||||||
|
t,
|
||||||
|
`SELECT c.id, c[@param] FROM c`,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{Path: []string{"c", "id"}},
|
||||||
|
{Path: []string{"c", "@param"}},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("Should parse SELECT DISTINCT", func(t *testing.T) {
|
t.Run("Should parse SELECT DISTINCT", func(t *testing.T) {
|
||||||
testQueryParse(
|
testQueryParse(
|
||||||
t,
|
t,
|
||||||
|
|||||||
@@ -317,6 +317,10 @@ func (r rowContext) applyProjection(selectItems []parsers.SelectItem) RowType {
|
|||||||
} else {
|
} else {
|
||||||
destinationName = fmt.Sprintf("$%d", index+1)
|
destinationName = fmt.Sprintf("$%d", index+1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if destinationName[0] == '@' {
|
||||||
|
destinationName = r.parameters[destinationName].(string)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
row[destinationName] = r.resolveSelectItem(selectItem)
|
row[destinationName] = r.resolveSelectItem(selectItem)
|
||||||
@@ -572,6 +576,9 @@ func (r rowContext) selectItem_SelectItemTypeField(selectItem parsers.SelectItem
|
|||||||
|
|
||||||
if len(selectItem.Path) > 1 {
|
if len(selectItem.Path) > 1 {
|
||||||
for _, pathSegment := range selectItem.Path[1:] {
|
for _, pathSegment := range selectItem.Path[1:] {
|
||||||
|
if pathSegment[0] == '@' {
|
||||||
|
pathSegment = r.parameters[pathSegment].(string)
|
||||||
|
}
|
||||||
|
|
||||||
switch nestedValue := value.(type) {
|
switch nestedValue := value.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
|
|||||||
@@ -35,6 +35,29 @@ func Test_Execute_Select(t *testing.T) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Should execute SELECT with query parameters as accessor", func(t *testing.T) {
|
||||||
|
testQueryExecute(
|
||||||
|
t,
|
||||||
|
parsers.SelectStmt{
|
||||||
|
SelectItems: []parsers.SelectItem{
|
||||||
|
{Path: []string{"c", "id"}},
|
||||||
|
{Path: []string{"c", "@param"}},
|
||||||
|
},
|
||||||
|
Table: parsers.Table{Value: "c"},
|
||||||
|
Parameters: map[string]interface{}{
|
||||||
|
"@param": "pk",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockData,
|
||||||
|
[]memoryexecutor.RowType{
|
||||||
|
map[string]interface{}{"id": "12345", "pk": 123},
|
||||||
|
map[string]interface{}{"id": "67890", "pk": 456},
|
||||||
|
map[string]interface{}{"id": "456", "pk": 456},
|
||||||
|
map[string]interface{}{"id": "123", "pk": 456},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("Should execute SELECT DISTINCT", func(t *testing.T) {
|
t.Run("Should execute SELECT DISTINCT", func(t *testing.T) {
|
||||||
testQueryExecute(
|
testQueryExecute(
|
||||||
t,
|
t,
|
||||||
|
|||||||
89
sharedlibrary/collections.go
Normal file
89
sharedlibrary/collections.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//export CreateCollection
|
||||||
|
func CreateCollection(serverName *C.char, databaseId *C.char, collectionJson *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionStr := C.GoString(collectionJson)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var collection repositorymodels.Collection
|
||||||
|
err := json.Unmarshal([]byte(collectionStr), &collection)
|
||||||
|
if err != nil {
|
||||||
|
return ResponseFailedToParseRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
_, code := serverInstance.repository.CreateCollection(databaseIdStr, collection)
|
||||||
|
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export GetCollection
|
||||||
|
func GetCollection(serverName *C.char, databaseId *C.char, collectionId *C.char) *C.char {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
collection, code := serverInstance.repository.GetCollection(databaseIdStr, collectionIdStr)
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionJson, _ := json.Marshal(collection)
|
||||||
|
return C.CString(string(collectionJson))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export GetAllCollections
|
||||||
|
func GetAllCollections(serverName *C.char, databaseId *C.char) *C.char {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
collections, code := serverInstance.repository.GetAllCollections(databaseIdStr)
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionsJson, _ := json.Marshal(collections)
|
||||||
|
return C.CString(string(collectionsJson))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export DeleteCollection
|
||||||
|
func DeleteCollection(serverName *C.char, databaseId *C.char, collectionId *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
code := serverInstance.repository.DeleteCollection(databaseIdStr, collectionIdStr)
|
||||||
|
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
89
sharedlibrary/databases.go
Normal file
89
sharedlibrary/databases.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//export CreateDatabase
|
||||||
|
func CreateDatabase(serverName *C.char, databaseJson *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseStr := C.GoString(databaseJson)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var database repositorymodels.Database
|
||||||
|
err := json.Unmarshal([]byte(databaseStr), &database)
|
||||||
|
if err != nil {
|
||||||
|
return ResponseFailedToParseRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
_, code := serverInstance.repository.CreateDatabase(database)
|
||||||
|
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export GetDatabase
|
||||||
|
func GetDatabase(serverName *C.char, databaseId *C.char) *C.char {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
database, code := serverInstance.repository.GetDatabase(databaseIdStr)
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
databaseJson, _ := json.Marshal(database)
|
||||||
|
return C.CString(string(databaseJson))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export GetAllDatabases
|
||||||
|
func GetAllDatabases(serverName *C.char) *C.char {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
databases, code := serverInstance.repository.GetAllDatabases()
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
databasesJson, err := json.Marshal(databases)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
return C.CString(string(databasesJson))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export DeleteDatabase
|
||||||
|
func DeleteDatabase(serverName *C.char, databaseId *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
code := serverInstance.repository.DeleteDatabase(databaseIdStr)
|
||||||
|
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
122
sharedlibrary/documents.go
Normal file
122
sharedlibrary/documents.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//export CreateDocument
|
||||||
|
func CreateDocument(serverName *C.char, databaseId *C.char, collectionId *C.char, documentJson *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
documentStr := C.GoString(documentJson)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var document repositorymodels.Document
|
||||||
|
err := json.Unmarshal([]byte(documentStr), &document)
|
||||||
|
if err != nil {
|
||||||
|
return ResponseFailedToParseRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
_, code := serverInstance.repository.CreateDocument(databaseIdStr, collectionIdStr, document)
|
||||||
|
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export GetDocument
|
||||||
|
func GetDocument(serverName *C.char, databaseId *C.char, collectionId *C.char, documentId *C.char) *C.char {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
documentIdStr := C.GoString(documentId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
document, code := serverInstance.repository.GetDocument(databaseIdStr, collectionIdStr, documentIdStr)
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
documentJson, _ := json.Marshal(document)
|
||||||
|
return C.CString(string(documentJson))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export GetAllDocuments
|
||||||
|
func GetAllDocuments(serverName *C.char, databaseId *C.char, collectionId *C.char) *C.char {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
documents, code := serverInstance.repository.GetAllDocuments(databaseIdStr, collectionIdStr)
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
|
||||||
|
documentsJson, _ := json.Marshal(documents)
|
||||||
|
return C.CString(string(documentsJson))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export UpdateDocument
|
||||||
|
func UpdateDocument(serverName *C.char, databaseId *C.char, collectionId *C.char, documentId *C.char, documentJson *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
documentIdStr := C.GoString(documentId)
|
||||||
|
documentStr := C.GoString(documentJson)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
var document repositorymodels.Document
|
||||||
|
err := json.Unmarshal([]byte(documentStr), &document)
|
||||||
|
if err != nil {
|
||||||
|
return ResponseFailedToParseRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
code := serverInstance.repository.DeleteDocument(databaseIdStr, collectionIdStr, documentIdStr)
|
||||||
|
if code != repositorymodels.StatusOk {
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, code = serverInstance.repository.CreateDocument(databaseIdStr, collectionIdStr, document)
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export DeleteDocument
|
||||||
|
func DeleteDocument(serverName *C.char, databaseId *C.char, collectionId *C.char, documentId *C.char) int {
|
||||||
|
serverNameStr := C.GoString(serverName)
|
||||||
|
databaseIdStr := C.GoString(databaseId)
|
||||||
|
collectionIdStr := C.GoString(collectionId)
|
||||||
|
documentIdStr := C.GoString(documentId)
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = getInstance(serverNameStr); !ok {
|
||||||
|
return ResponseServerInstanceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
code := serverInstance.repository.DeleteDocument(databaseIdStr, collectionIdStr, documentIdStr)
|
||||||
|
|
||||||
|
return repositoryStatusToResponseCode(code)
|
||||||
|
}
|
||||||
86
sharedlibrary/shared.go
Normal file
86
sharedlibrary/shared.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pikami/cosmium/api"
|
||||||
|
"github.com/pikami/cosmium/internal/repositories"
|
||||||
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServerInstance struct {
|
||||||
|
server *api.ApiServer
|
||||||
|
repository *repositories.DataRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
var serverInstances map[string]*ServerInstance
|
||||||
|
var mutex sync.RWMutex
|
||||||
|
|
||||||
|
const (
|
||||||
|
ResponseSuccess = 0
|
||||||
|
|
||||||
|
ResponseUnknown = 100
|
||||||
|
ResponseFailedToParseConfiguration = 101
|
||||||
|
ResponseFailedToLoadState = 102
|
||||||
|
ResponseFailedToParseRequest = 103
|
||||||
|
ResponseServerInstanceAlreadyExists = 104
|
||||||
|
ResponseServerInstanceNotFound = 105
|
||||||
|
|
||||||
|
ResponseRepositoryNotFound = 200
|
||||||
|
ResponseRepositoryConflict = 201
|
||||||
|
ResponseRepositoryBadRequest = 202
|
||||||
|
)
|
||||||
|
|
||||||
|
func getInstance(serverName string) (*ServerInstance, bool) {
|
||||||
|
mutex.RLock()
|
||||||
|
defer mutex.RUnlock()
|
||||||
|
|
||||||
|
if serverInstances == nil {
|
||||||
|
serverInstances = make(map[string]*ServerInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ok bool
|
||||||
|
var serverInstance *ServerInstance
|
||||||
|
if serverInstance, ok = serverInstances[serverName]; !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverInstance, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func addInstance(serverName string, serverInstance *ServerInstance) {
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
if serverInstances == nil {
|
||||||
|
serverInstances = make(map[string]*ServerInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverInstances[serverName] = serverInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeInstance(serverName string) {
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
|
||||||
|
if serverInstances == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(serverInstances, serverName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func repositoryStatusToResponseCode(status repositorymodels.RepositoryStatus) int {
|
||||||
|
switch status {
|
||||||
|
case repositorymodels.StatusOk:
|
||||||
|
return ResponseSuccess
|
||||||
|
case repositorymodels.StatusNotFound:
|
||||||
|
return ResponseRepositoryNotFound
|
||||||
|
case repositorymodels.Conflict:
|
||||||
|
return ResponseRepositoryConflict
|
||||||
|
case repositorymodels.BadRequest:
|
||||||
|
return ResponseRepositoryBadRequest
|
||||||
|
default:
|
||||||
|
return ResponseUnknown
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,32 +9,12 @@ import (
|
|||||||
"github.com/pikami/cosmium/internal/repositories"
|
"github.com/pikami/cosmium/internal/repositories"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerInstance struct {
|
|
||||||
server *api.ApiServer
|
|
||||||
repository *repositories.DataRepository
|
|
||||||
}
|
|
||||||
|
|
||||||
var serverInstances map[string]*ServerInstance
|
|
||||||
|
|
||||||
const (
|
|
||||||
ResponseSuccess = 0
|
|
||||||
ResponseUnknown = 1
|
|
||||||
ResponseServerInstanceAlreadyExists = 2
|
|
||||||
ResponseFailedToParseConfiguration = 3
|
|
||||||
ResponseServerInstanceNotFound = 4
|
|
||||||
ResponseFailedToLoadState = 5
|
|
||||||
)
|
|
||||||
|
|
||||||
//export CreateServerInstance
|
//export CreateServerInstance
|
||||||
func CreateServerInstance(serverName *C.char, configurationJSON *C.char) int {
|
func CreateServerInstance(serverName *C.char, configurationJSON *C.char) int {
|
||||||
configStr := C.GoString(configurationJSON)
|
configStr := C.GoString(configurationJSON)
|
||||||
serverNameStr := C.GoString(serverName)
|
serverNameStr := C.GoString(serverName)
|
||||||
|
|
||||||
if serverInstances == nil {
|
if _, ok := getInstance(serverNameStr); ok {
|
||||||
serverInstances = make(map[string]*ServerInstance)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := serverInstances[serverNameStr]; ok {
|
|
||||||
return ResponseServerInstanceAlreadyExists
|
return ResponseServerInstanceAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,19 +35,21 @@ func CreateServerInstance(serverName *C.char, configurationJSON *C.char) int {
|
|||||||
server := api.NewApiServer(repository, configuration)
|
server := api.NewApiServer(repository, configuration)
|
||||||
server.Start()
|
server.Start()
|
||||||
|
|
||||||
serverInstances[serverNameStr] = &ServerInstance{
|
addInstance(serverNameStr, &ServerInstance{
|
||||||
server: server,
|
server: server,
|
||||||
repository: repository,
|
repository: repository,
|
||||||
}
|
})
|
||||||
|
|
||||||
return ResponseSuccess
|
return ResponseSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
//export StopServerInstance
|
//export StopServerInstance
|
||||||
func StopServerInstance(serverName *C.char) int {
|
func StopServerInstance(serverName *C.char) int {
|
||||||
if serverInstance, ok := serverInstances[C.GoString(serverName)]; ok {
|
serverNameStr := C.GoString(serverName)
|
||||||
|
|
||||||
|
if serverInstance, ok := getInstance(serverNameStr); ok {
|
||||||
serverInstance.server.Stop()
|
serverInstance.server.Stop()
|
||||||
delete(serverInstances, C.GoString(serverName))
|
removeInstance(serverNameStr)
|
||||||
return ResponseSuccess
|
return ResponseSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +58,9 @@ func StopServerInstance(serverName *C.char) int {
|
|||||||
|
|
||||||
//export GetServerInstanceState
|
//export GetServerInstanceState
|
||||||
func GetServerInstanceState(serverName *C.char) *C.char {
|
func GetServerInstanceState(serverName *C.char) *C.char {
|
||||||
if serverInstance, ok := serverInstances[C.GoString(serverName)]; ok {
|
serverNameStr := C.GoString(serverName)
|
||||||
|
|
||||||
|
if serverInstance, ok := getInstance(serverNameStr); ok {
|
||||||
stateJSON, err := serverInstance.repository.GetState()
|
stateJSON, err := serverInstance.repository.GetState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -92,7 +76,7 @@ func LoadServerInstanceState(serverName *C.char, stateJSON *C.char) int {
|
|||||||
serverNameStr := C.GoString(serverName)
|
serverNameStr := C.GoString(serverName)
|
||||||
stateJSONStr := C.GoString(stateJSON)
|
stateJSONStr := C.GoString(stateJSON)
|
||||||
|
|
||||||
if serverInstance, ok := serverInstances[serverNameStr]; ok {
|
if serverInstance, ok := getInstance(serverNameStr); ok {
|
||||||
err := serverInstance.repository.LoadStateJSON(stateJSONStr)
|
err := serverInstance.repository.LoadStateJSON(stateJSONStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ResponseFailedToLoadState
|
return ResponseFailedToLoadState
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
void test_CreateServerInstance();
|
int test_CreateServerInstance();
|
||||||
void test_StopServerInstance();
|
int test_StopServerInstance();
|
||||||
void test_ServerInstanceStateMethods();
|
int test_ServerInstanceStateMethods();
|
||||||
|
int test_Databases();
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -21,9 +22,24 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Running tests for library: %s\n", libPath);
|
printf("Running tests for library: %s\n", libPath);
|
||||||
test_CreateServerInstance();
|
int results[] = {
|
||||||
test_ServerInstanceStateMethods();
|
test_CreateServerInstance(),
|
||||||
test_StopServerInstance();
|
test_Databases(),
|
||||||
|
test_ServerInstanceStateMethods(),
|
||||||
|
test_StopServerInstance(),
|
||||||
|
};
|
||||||
|
|
||||||
|
int numTests = sizeof(results) / sizeof(results[0]);
|
||||||
|
int numPassed = 0;
|
||||||
|
for (int i = 0; i < numTests; i++)
|
||||||
|
{
|
||||||
|
if (results[i])
|
||||||
|
{
|
||||||
|
numPassed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Tests passed: %d/%d\n", numPassed, numTests);
|
||||||
|
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
void test_CreateServerInstance()
|
int test_CreateServerInstance()
|
||||||
{
|
{
|
||||||
typedef int (*CreateServerInstanceFn)(char *, char *);
|
typedef int (*CreateServerInstanceFn)(char *, char *);
|
||||||
CreateServerInstanceFn CreateServerInstance = (CreateServerInstanceFn)load_function("CreateServerInstance");
|
CreateServerInstanceFn CreateServerInstance = (CreateServerInstanceFn)load_function("CreateServerInstance");
|
||||||
@@ -8,7 +8,7 @@ void test_CreateServerInstance()
|
|||||||
if (!CreateServerInstance)
|
if (!CreateServerInstance)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find CreateServerInstance function\n");
|
fprintf(stderr, "Failed to find CreateServerInstance function\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *serverName = "TestServer";
|
char *serverName = "TestServer";
|
||||||
@@ -22,5 +22,8 @@ void test_CreateServerInstance()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("CreateServerInstance: FAILED (result = %d)\n", result);
|
printf("CreateServerInstance: FAILED (result = %d)\n", result);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
47
sharedlibrary/tests/test_databases.c
Normal file
47
sharedlibrary/tests/test_databases.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "shared.h"
|
||||||
|
|
||||||
|
int test_Databases()
|
||||||
|
{
|
||||||
|
typedef int (*CreateDatabaseFn)(char *, char *);
|
||||||
|
CreateDatabaseFn CreateDatabase = (CreateDatabaseFn)load_function("CreateDatabase");
|
||||||
|
if (!CreateDatabase)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to find CreateDatabase function\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *serverName = "TestServer";
|
||||||
|
char *configJSON = "{\"id\":\"test-db\"}";
|
||||||
|
|
||||||
|
int result = CreateDatabase(serverName, configJSON);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
printf("CreateDatabase: SUCCESS\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("CreateDatabase: FAILED (result = %d)\n", result);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef char *(*GetDatabaseFn)(char *, char *);
|
||||||
|
GetDatabaseFn GetDatabase = (GetDatabaseFn)load_function("GetDatabase");
|
||||||
|
if (!GetDatabase)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to find GetDatabase function\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *database = GetDatabase(serverName, "test-db");
|
||||||
|
if (database)
|
||||||
|
{
|
||||||
|
printf("GetDatabase: SUCCESS (database = %s)\n", database);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("GetDatabase: FAILED\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
void test_ServerInstanceStateMethods()
|
int test_ServerInstanceStateMethods()
|
||||||
{
|
{
|
||||||
typedef int (*LoadServerInstanceStateFn)(char *, char *);
|
typedef int (*LoadServerInstanceStateFn)(char *, char *);
|
||||||
LoadServerInstanceStateFn LoadServerInstanceState = (LoadServerInstanceStateFn)load_function("LoadServerInstanceState");
|
LoadServerInstanceStateFn LoadServerInstanceState = (LoadServerInstanceStateFn)load_function("LoadServerInstanceState");
|
||||||
if (!LoadServerInstanceState)
|
if (!LoadServerInstanceState)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find LoadServerInstanceState function\n");
|
fprintf(stderr, "Failed to find LoadServerInstanceState function\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *serverName = "TestServer";
|
char *serverName = "TestServer";
|
||||||
@@ -20,6 +20,7 @@ void test_ServerInstanceStateMethods()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("LoadServerInstanceState: FAILED (result = %d)\n", result);
|
printf("LoadServerInstanceState: FAILED (result = %d)\n", result);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef char *(*GetServerInstanceStateFn)(char *);
|
typedef char *(*GetServerInstanceStateFn)(char *);
|
||||||
@@ -27,7 +28,7 @@ void test_ServerInstanceStateMethods()
|
|||||||
if (!GetServerInstanceState)
|
if (!GetServerInstanceState)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find GetServerInstanceState function\n");
|
fprintf(stderr, "Failed to find GetServerInstanceState function\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *state = GetServerInstanceState(serverName);
|
char *state = GetServerInstanceState(serverName);
|
||||||
@@ -38,6 +39,7 @@ void test_ServerInstanceStateMethods()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("GetServerInstanceState: FAILED\n");
|
printf("GetServerInstanceState: FAILED\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *expected_state = "{\"databases\":{\"test-db\":{\"id\":\"test-db\",\"_ts\":0,\"_rid\":\"\",\"_etag\":\"\",\"_self\":\"\"}},\"collections\":{\"test-db\":{}},\"documents\":{\"test-db\":{}}}";
|
const char *expected_state = "{\"databases\":{\"test-db\":{\"id\":\"test-db\",\"_ts\":0,\"_rid\":\"\",\"_etag\":\"\",\"_self\":\"\"}},\"collections\":{\"test-db\":{}},\"documents\":{\"test-db\":{}}}";
|
||||||
@@ -45,7 +47,7 @@ void test_ServerInstanceStateMethods()
|
|||||||
if (!compact_state)
|
if (!compact_state)
|
||||||
{
|
{
|
||||||
free(state);
|
free(state);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(compact_state, expected_state) == 0)
|
if (strcmp(compact_state, expected_state) == 0)
|
||||||
@@ -57,8 +59,10 @@ void test_ServerInstanceStateMethods()
|
|||||||
printf("GetServerInstanceState: State does not match expected value.\n");
|
printf("GetServerInstanceState: State does not match expected value.\n");
|
||||||
printf("Expected: %s\n", expected_state);
|
printf("Expected: %s\n", expected_state);
|
||||||
printf("Actual: %s\n", compact_state);
|
printf("Actual: %s\n", compact_state);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(state);
|
free(state);
|
||||||
free(compact_state);
|
free(compact_state);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
void test_StopServerInstance()
|
int test_StopServerInstance()
|
||||||
{
|
{
|
||||||
typedef int (*StopServerInstanceFn)(char *);
|
typedef int (*StopServerInstanceFn)(char *);
|
||||||
StopServerInstanceFn StopServerInstance = (StopServerInstanceFn)load_function("StopServerInstance");
|
StopServerInstanceFn StopServerInstance = (StopServerInstanceFn)load_function("StopServerInstance");
|
||||||
@@ -8,7 +8,7 @@ void test_StopServerInstance()
|
|||||||
if (!StopServerInstance)
|
if (!StopServerInstance)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to find StopServerInstance function\n");
|
fprintf(stderr, "Failed to find StopServerInstance function\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *serverName = "TestServer";
|
char *serverName = "TestServer";
|
||||||
@@ -20,5 +20,8 @@ void test_StopServerInstance()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("StopServerInstance: FAILED (result = %d)\n", result);
|
printf("StopServerInstance: FAILED (result = %d)\n", result);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user