mirror of
https://github.com/pikami/cosmium.git
synced 2025-10-14 07:46:03 +01:00
Fix query creation via explorer; Extract header names to constants
This commit is contained in:
parent
51e3311ba4
commit
c988741f8e
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
)
|
)
|
||||||
@ -16,7 +17,7 @@ func (h *Handlers) GetAllCollections(c *gin.Context) {
|
|||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
database, _ := h.dataStore.GetDatabase(databaseId)
|
database, _ := h.dataStore.GetDatabase(databaseId)
|
||||||
|
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(collections)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(collections)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{
|
c.IndentedJSON(http.StatusOK, gin.H{
|
||||||
"_rid": database.ResourceID,
|
"_rid": database.ResourceID,
|
||||||
"DocumentCollections": collections,
|
"DocumentCollections": collections,
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
)
|
)
|
||||||
@ -12,7 +13,7 @@ import (
|
|||||||
func (h *Handlers) GetAllDatabases(c *gin.Context) {
|
func (h *Handlers) GetAllDatabases(c *gin.Context) {
|
||||||
databases, status := h.dataStore.GetAllDatabases()
|
databases, status := h.dataStore.GetAllDatabases()
|
||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(databases)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(databases)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{
|
c.IndentedJSON(http.StatusOK, gin.H{
|
||||||
"_rid": "",
|
"_rid": "",
|
||||||
"Databases": databases,
|
"Databases": databases,
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
jsonpatch "github.com/cosmiumdev/json-patch/v5"
|
jsonpatch "github.com/cosmiumdev/json-patch/v5"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apimodels "github.com/pikami/cosmium/api/api_models"
|
apimodels "github.com/pikami/cosmium/api/api_models"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/converters"
|
"github.com/pikami/cosmium/internal/converters"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
@ -26,7 +27,7 @@ func (h *Handlers) GetAllDocuments(c *gin.Context) {
|
|||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
collection, _ := h.dataStore.GetCollection(databaseId, collectionId)
|
collection, _ := h.dataStore.GetCollection(databaseId, collectionId)
|
||||||
|
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(documents)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(documents)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{
|
c.IndentedJSON(http.StatusOK, gin.H{
|
||||||
"_rid": collection.ID,
|
"_rid": collection.ID,
|
||||||
"Documents": documents,
|
"Documents": documents,
|
||||||
@ -189,7 +190,7 @@ func (h *Handlers) DocumentsPost(c *gin.Context) {
|
|||||||
collectionId := c.Param("collId")
|
collectionId := c.Param("collId")
|
||||||
|
|
||||||
// Handle batch requests
|
// Handle batch requests
|
||||||
isBatchRequest, _ := strconv.ParseBool(c.GetHeader("x-ms-cosmos-is-batch-request"))
|
isBatchRequest, _ := strconv.ParseBool(c.GetHeader(headers.IsBatchRequest))
|
||||||
if isBatchRequest {
|
if isBatchRequest {
|
||||||
h.handleBatchRequest(c)
|
h.handleBatchRequest(c)
|
||||||
return
|
return
|
||||||
@ -201,8 +202,17 @@ func (h *Handlers) DocumentsPost(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
query := requestBody["query"]
|
// Handle query plan requests
|
||||||
if query != nil {
|
isQueryPlanRequest, _ := strconv.ParseBool(c.GetHeader(headers.IsQueryPlanRequest))
|
||||||
|
if isQueryPlanRequest {
|
||||||
|
c.IndentedJSON(http.StatusOK, constants.QueryPlanResponse)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle query requests
|
||||||
|
isQueryRequest, _ := strconv.ParseBool(c.GetHeader(headers.IsQuery))
|
||||||
|
isQueryRequestAltHeader, _ := strconv.ParseBool(c.GetHeader(headers.Query))
|
||||||
|
if isQueryRequest || isQueryRequestAltHeader {
|
||||||
h.handleDocumentQuery(c, requestBody)
|
h.handleDocumentQuery(c, requestBody)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -212,7 +222,7 @@ func (h *Handlers) DocumentsPost(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isUpsert, _ := strconv.ParseBool(c.GetHeader("x-ms-documentdb-is-upsert"))
|
isUpsert, _ := strconv.ParseBool(c.GetHeader(headers.IsUpsert))
|
||||||
if isUpsert {
|
if isUpsert {
|
||||||
h.dataStore.DeleteDocument(databaseId, collectionId, requestBody["id"].(string))
|
h.dataStore.DeleteDocument(databaseId, collectionId, requestBody["id"].(string))
|
||||||
}
|
}
|
||||||
@ -247,11 +257,6 @@ func (h *Handlers) handleDocumentQuery(c *gin.Context, requestBody map[string]in
|
|||||||
databaseId := c.Param("databaseId")
|
databaseId := c.Param("databaseId")
|
||||||
collectionId := c.Param("collId")
|
collectionId := c.Param("collId")
|
||||||
|
|
||||||
if c.GetHeader("x-ms-cosmos-is-query-plan-request") != "" {
|
|
||||||
c.IndentedJSON(http.StatusOK, constants.QueryPlanResponse)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var queryParameters map[string]interface{}
|
var queryParameters map[string]interface{}
|
||||||
if paramsArray, ok := requestBody["parameters"].([]interface{}); ok {
|
if paramsArray, ok := requestBody["parameters"].([]interface{}); ok {
|
||||||
queryParameters = parametersToMap(paramsArray)
|
queryParameters = parametersToMap(paramsArray)
|
||||||
@ -266,7 +271,7 @@ func (h *Handlers) handleDocumentQuery(c *gin.Context, requestBody map[string]in
|
|||||||
}
|
}
|
||||||
|
|
||||||
collection, _ := h.dataStore.GetCollection(databaseId, collectionId)
|
collection, _ := h.dataStore.GetCollection(databaseId, collectionId)
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(docs)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(docs)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{
|
c.IndentedJSON(http.StatusOK, gin.H{
|
||||||
"_rid": collection.ResourceID,
|
"_rid": collection.ResourceID,
|
||||||
"Documents": docs,
|
"Documents": docs,
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pikami/cosmium/api/config"
|
"github.com/pikami/cosmium/api/config"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/authentication"
|
"github.com/pikami/cosmium/internal/authentication"
|
||||||
"github.com/pikami/cosmium/internal/logger"
|
"github.com/pikami/cosmium/internal/logger"
|
||||||
)
|
)
|
||||||
@ -22,8 +23,8 @@ func Authentication(config *config.ServerConfig) gin.HandlerFunc {
|
|||||||
resourceType := urlToResourceType(requestUrl)
|
resourceType := urlToResourceType(requestUrl)
|
||||||
resourceId := requestToResourceId(c)
|
resourceId := requestToResourceId(c)
|
||||||
|
|
||||||
authHeader := c.Request.Header.Get("authorization")
|
authHeader := c.Request.Header.Get(headers.Authorization)
|
||||||
date := c.Request.Header.Get("x-ms-date")
|
date := c.Request.Header.Get(headers.XDate)
|
||||||
expectedSignature := authentication.GenerateSignature(
|
expectedSignature := authentication.GenerateSignature(
|
||||||
c.Request.Method, resourceType, resourceId, date, config.AccountKey)
|
c.Request.Method, resourceType, resourceId, date, config.AccountKey)
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ func requestToResourceId(c *gin.Context) string {
|
|||||||
resourceId += "/udfs/" + udfId
|
resourceId += "/udfs/" + udfId
|
||||||
}
|
}
|
||||||
|
|
||||||
isFeed := c.Request.Header.Get("A-Im") == "Incremental Feed"
|
isFeed := c.Request.Header.Get(headers.AIM) == "Incremental Feed"
|
||||||
if resourceType == "pkranges" && isFeed {
|
if resourceType == "pkranges" && isFeed {
|
||||||
resourceId = collId
|
resourceId = collId
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetOffers(c *gin.Context) {
|
func GetOffers(c *gin.Context) {
|
||||||
c.Header("x-ms-item-count", "0")
|
c.Header(headers.ItemCount, "0")
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{
|
c.IndentedJSON(http.StatusOK, gin.H{
|
||||||
"_rid": "",
|
"_rid": "",
|
||||||
"_count": 0,
|
"_count": 0,
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
"github.com/pikami/cosmium/internal/resourceid"
|
"github.com/pikami/cosmium/internal/resourceid"
|
||||||
@ -14,18 +15,18 @@ func (h *Handlers) GetPartitionKeyRanges(c *gin.Context) {
|
|||||||
databaseId := c.Param("databaseId")
|
databaseId := c.Param("databaseId")
|
||||||
collectionId := c.Param("collId")
|
collectionId := c.Param("collId")
|
||||||
|
|
||||||
if c.Request.Header.Get("if-none-match") != "" {
|
if c.Request.Header.Get(headers.IfNoneMatch) != "" {
|
||||||
c.AbortWithStatus(http.StatusNotModified)
|
c.AbortWithStatus(http.StatusNotModified)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
partitionKeyRanges, status := h.dataStore.GetPartitionKeyRanges(databaseId, collectionId)
|
partitionKeyRanges, status := h.dataStore.GetPartitionKeyRanges(databaseId, collectionId)
|
||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
c.Header("etag", "\"420\"")
|
c.Header(headers.ETag, "\"420\"")
|
||||||
c.Header("lsn", "420")
|
c.Header(headers.LSN, "420")
|
||||||
c.Header("x-ms-cosmos-llsn", "420")
|
c.Header(headers.CosmosLsn, "420")
|
||||||
c.Header("x-ms-global-committed-lsn", "420")
|
c.Header(headers.GlobalCommittedLsn, "420")
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(partitionKeyRanges)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(partitionKeyRanges)))
|
||||||
|
|
||||||
collectionRid := collectionId
|
collectionRid := collectionId
|
||||||
collection, _ := h.dataStore.GetCollection(databaseId, collectionId)
|
collection, _ := h.dataStore.GetCollection(databaseId, collectionId)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
)
|
)
|
||||||
@ -16,7 +17,7 @@ func (h *Handlers) GetAllStoredProcedures(c *gin.Context) {
|
|||||||
sps, status := h.dataStore.GetAllStoredProcedures(databaseId, collectionId)
|
sps, status := h.dataStore.GetAllStoredProcedures(databaseId, collectionId)
|
||||||
|
|
||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(sps)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(sps)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{"_rid": "", "StoredProcedures": sps, "_count": len(sps)})
|
c.IndentedJSON(http.StatusOK, gin.H{"_rid": "", "StoredProcedures": sps, "_count": len(sps)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
)
|
)
|
||||||
@ -16,7 +17,7 @@ func (h *Handlers) GetAllTriggers(c *gin.Context) {
|
|||||||
triggers, status := h.dataStore.GetAllTriggers(databaseId, collectionId)
|
triggers, status := h.dataStore.GetAllTriggers(databaseId, collectionId)
|
||||||
|
|
||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(triggers)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(triggers)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{"_rid": "", "Triggers": triggers, "_count": len(triggers)})
|
c.IndentedJSON(http.StatusOK, gin.H{"_rid": "", "Triggers": triggers, "_count": len(triggers)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/constants"
|
"github.com/pikami/cosmium/internal/constants"
|
||||||
"github.com/pikami/cosmium/internal/datastore"
|
"github.com/pikami/cosmium/internal/datastore"
|
||||||
)
|
)
|
||||||
@ -16,7 +17,7 @@ func (h *Handlers) GetAllUserDefinedFunctions(c *gin.Context) {
|
|||||||
udfs, status := h.dataStore.GetAllUserDefinedFunctions(databaseId, collectionId)
|
udfs, status := h.dataStore.GetAllUserDefinedFunctions(databaseId, collectionId)
|
||||||
|
|
||||||
if status == datastore.StatusOk {
|
if status == datastore.StatusOk {
|
||||||
c.Header("x-ms-item-count", fmt.Sprintf("%d", len(udfs)))
|
c.Header(headers.ItemCount, fmt.Sprintf("%d", len(udfs)))
|
||||||
c.IndentedJSON(http.StatusOK, gin.H{"_rid": "", "UserDefinedFunctions": udfs, "_count": len(udfs)})
|
c.IndentedJSON(http.StatusOK, gin.H{"_rid": "", "UserDefinedFunctions": udfs, "_count": len(udfs)})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
20
api/headers/headers.go
Normal file
20
api/headers/headers.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package headers
|
||||||
|
|
||||||
|
const (
|
||||||
|
AIM = "A-Im"
|
||||||
|
Authorization = "authorization"
|
||||||
|
CosmosLsn = "x-ms-cosmos-llsn"
|
||||||
|
ETag = "etag"
|
||||||
|
GlobalCommittedLsn = "x-ms-global-committed-lsn"
|
||||||
|
IfNoneMatch = "if-none-match"
|
||||||
|
IsBatchRequest = "x-ms-cosmos-is-batch-request"
|
||||||
|
IsQueryPlanRequest = "x-ms-cosmos-is-query-plan-request"
|
||||||
|
IsUpsert = "x-ms-documentdb-is-upsert"
|
||||||
|
ItemCount = "x-ms-item-count"
|
||||||
|
LSN = "lsn"
|
||||||
|
XDate = "x-ms-date"
|
||||||
|
|
||||||
|
// Kinda retarded, but what can I do ¯\_(ツ)_/¯
|
||||||
|
IsQuery = "x-ms-documentdb-isquery" // Sent from python sdk and web explorer
|
||||||
|
Query = "x-ms-documentdb-query" // Sent from Go sdk
|
||||||
|
)
|
@ -8,6 +8,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pikami/cosmium/api/config"
|
"github.com/pikami/cosmium/api/config"
|
||||||
|
"github.com/pikami/cosmium/api/headers"
|
||||||
"github.com/pikami/cosmium/internal/authentication"
|
"github.com/pikami/cosmium/internal/authentication"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -26,8 +27,8 @@ func Test_Documents_Read_Trailing_Slash(t *testing.T) {
|
|||||||
signature := authentication.GenerateSignature("GET", "docs", path, date, config.DefaultAccountKey)
|
signature := authentication.GenerateSignature("GET", "docs", path, date, config.DefaultAccountKey)
|
||||||
httpClient := &http.Client{}
|
httpClient := &http.Client{}
|
||||||
req, _ := http.NewRequest("GET", testUrl, nil)
|
req, _ := http.NewRequest("GET", testUrl, nil)
|
||||||
req.Header.Add("x-ms-date", date)
|
req.Header.Add(headers.XDate, date)
|
||||||
req.Header.Add("authorization", "sig="+url.QueryEscape(signature))
|
req.Header.Add(headers.Authorization, "sig="+url.QueryEscape(signature))
|
||||||
res, err := httpClient.Do(req)
|
res, err := httpClient.Do(req)
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user