mirror of
https://github.com/pikami/cosmium.git
synced 2026-06-14 16:27:17 +01:00
Compare commits
4 Commits
0.1.21
...
e20a6ca7cd
| Author | SHA1 | Date | |
|---|---|---|---|
| e20a6ca7cd | |||
| 7e0c10479b | |||
| 30195fae96 | |||
| 598f2837af |
@@ -77,8 +77,13 @@ func (c *ServerConfig) PopulateCalculatedFields() {
|
||||
logger.SetLogLevel(logger.LogLevelInfo)
|
||||
}
|
||||
|
||||
if c.PersistDataFilePath != "" {
|
||||
fileInfo, _ := os.Stat(c.PersistDataFilePath)
|
||||
fileInfo, err := os.Stat(c.PersistDataFilePath)
|
||||
if c.PersistDataFilePath != "" && !os.IsNotExist(err) {
|
||||
if err != nil {
|
||||
logger.ErrorLn("Failed to get file info for persist path:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if c.DataStore == DataStoreJson && fileInfo.IsDir() {
|
||||
logger.ErrorLn("--Persist cannot be a directory when using json data store")
|
||||
os.Exit(1)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pikami/cosmium/internal/constants"
|
||||
"github.com/pikami/cosmium/internal/datastore"
|
||||
)
|
||||
|
||||
@@ -24,7 +25,7 @@ func (h *Handlers) GetAllCollections(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) GetCollection(c *gin.Context) {
|
||||
@@ -38,11 +39,11 @@ func (h *Handlers) GetCollection(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DeleteCollection(c *gin.Context) {
|
||||
@@ -56,11 +57,11 @@ func (h *Handlers) DeleteCollection(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) CreateCollection(c *gin.Context) {
|
||||
@@ -73,13 +74,13 @@ func (h *Handlers) CreateCollection(c *gin.Context) {
|
||||
}
|
||||
|
||||
if newCollection.ID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"message": "BadRequest"})
|
||||
c.JSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdCollection, status := h.dataStore.CreateCollection(databaseId, newCollection)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -88,5 +89,5 @@ func (h *Handlers) CreateCollection(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pikami/cosmium/internal/constants"
|
||||
"github.com/pikami/cosmium/internal/datastore"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func (h *Handlers) GetAllDatabases(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) GetDatabase(c *gin.Context) {
|
||||
@@ -33,11 +34,11 @@ func (h *Handlers) GetDatabase(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DeleteDatabase(c *gin.Context) {
|
||||
@@ -50,11 +51,11 @@ func (h *Handlers) DeleteDatabase(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) CreateDatabase(c *gin.Context) {
|
||||
@@ -66,13 +67,13 @@ func (h *Handlers) CreateDatabase(c *gin.Context) {
|
||||
}
|
||||
|
||||
if newDatabase.ID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"message": "BadRequest"})
|
||||
c.JSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdDatabase, status := h.dataStore.CreateDatabase(newDatabase)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -81,5 +82,5 @@ func (h *Handlers) CreateDatabase(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
+15
-15
@@ -35,7 +35,7 @@ func (h *Handlers) GetAllDocuments(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) GetDocument(c *gin.Context) {
|
||||
@@ -50,11 +50,11 @@ func (h *Handlers) GetDocument(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DeleteDocument(c *gin.Context) {
|
||||
@@ -69,11 +69,11 @@ func (h *Handlers) DeleteDocument(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
// TODO: Maybe move "replace" logic to data store
|
||||
@@ -90,13 +90,13 @@ func (h *Handlers) ReplaceDocument(c *gin.Context) {
|
||||
|
||||
status := h.dataStore.DeleteDocument(databaseId, collectionId, documentId)
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdDocument, status := h.dataStore.CreateDocument(databaseId, collectionId, requestBody)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func (h *Handlers) ReplaceDocument(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) PatchDocument(c *gin.Context) {
|
||||
@@ -115,7 +115,7 @@ func (h *Handlers) PatchDocument(c *gin.Context) {
|
||||
|
||||
document, status := h.dataStore.GetDocument(databaseId, collectionId, documentId)
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -166,13 +166,13 @@ func (h *Handlers) PatchDocument(c *gin.Context) {
|
||||
|
||||
status = h.dataStore.DeleteDocument(databaseId, collectionId, documentId)
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdDocument, status := h.dataStore.CreateDocument(databaseId, collectionId, modifiedDocument)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ func (h *Handlers) PatchDocument(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DocumentsPost(c *gin.Context) {
|
||||
@@ -208,7 +208,7 @@ func (h *Handlers) DocumentsPost(c *gin.Context) {
|
||||
}
|
||||
|
||||
if requestBody["id"] == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"message": "BadRequest"})
|
||||
c.JSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ func (h *Handlers) DocumentsPost(c *gin.Context) {
|
||||
|
||||
createdDocument, status := h.dataStore.CreateDocument(databaseId, collectionId, requestBody)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ func (h *Handlers) DocumentsPost(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func parametersToMap(pairs []interface{}) map[string]interface{} {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pikami/cosmium/internal/constants"
|
||||
"github.com/pikami/cosmium/internal/datastore"
|
||||
"github.com/pikami/cosmium/internal/resourceid"
|
||||
)
|
||||
@@ -42,9 +43,9 @@ func (h *Handlers) GetPartitionKeyRanges(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pikami/cosmium/internal/constants"
|
||||
"github.com/pikami/cosmium/internal/datastore"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func (h *Handlers) GetAllStoredProcedures(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) GetStoredProcedure(c *gin.Context) {
|
||||
@@ -36,11 +37,11 @@ func (h *Handlers) GetStoredProcedure(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DeleteStoredProcedure(c *gin.Context) {
|
||||
@@ -55,11 +56,11 @@ func (h *Handlers) DeleteStoredProcedure(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) ReplaceStoredProcedure(c *gin.Context) {
|
||||
@@ -69,19 +70,19 @@ func (h *Handlers) ReplaceStoredProcedure(c *gin.Context) {
|
||||
|
||||
var sp datastore.StoredProcedure
|
||||
if err := c.BindJSON(&sp); err != nil {
|
||||
c.IndentedJSON(http.StatusBadRequest, gin.H{"message": "Invalid body"})
|
||||
c.IndentedJSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
status := h.dataStore.DeleteStoredProcedure(databaseId, collectionId, spId)
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdSP, status := h.dataStore.CreateStoredProcedure(databaseId, collectionId, sp)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ func (h *Handlers) ReplaceStoredProcedure(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) CreateStoredProcedure(c *gin.Context) {
|
||||
@@ -99,13 +100,13 @@ func (h *Handlers) CreateStoredProcedure(c *gin.Context) {
|
||||
|
||||
var sp datastore.StoredProcedure
|
||||
if err := c.BindJSON(&sp); err != nil {
|
||||
c.IndentedJSON(http.StatusBadRequest, gin.H{"message": "Invalid body"})
|
||||
c.IndentedJSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdSP, status := h.dataStore.CreateStoredProcedure(databaseId, collectionId, sp)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -114,5 +115,5 @@ func (h *Handlers) CreateStoredProcedure(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
+13
-12
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pikami/cosmium/internal/constants"
|
||||
"github.com/pikami/cosmium/internal/datastore"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func (h *Handlers) GetAllTriggers(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) GetTrigger(c *gin.Context) {
|
||||
@@ -36,11 +37,11 @@ func (h *Handlers) GetTrigger(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DeleteTrigger(c *gin.Context) {
|
||||
@@ -55,11 +56,11 @@ func (h *Handlers) DeleteTrigger(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) ReplaceTrigger(c *gin.Context) {
|
||||
@@ -69,19 +70,19 @@ func (h *Handlers) ReplaceTrigger(c *gin.Context) {
|
||||
|
||||
var trigger datastore.Trigger
|
||||
if err := c.BindJSON(&trigger); err != nil {
|
||||
c.IndentedJSON(http.StatusBadRequest, gin.H{"message": "Invalid body"})
|
||||
c.IndentedJSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
status := h.dataStore.DeleteTrigger(databaseId, collectionId, triggerId)
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdTrigger, status := h.dataStore.CreateTrigger(databaseId, collectionId, trigger)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ func (h *Handlers) ReplaceTrigger(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) CreateTrigger(c *gin.Context) {
|
||||
@@ -99,13 +100,13 @@ func (h *Handlers) CreateTrigger(c *gin.Context) {
|
||||
|
||||
var trigger datastore.Trigger
|
||||
if err := c.BindJSON(&trigger); err != nil {
|
||||
c.IndentedJSON(http.StatusBadRequest, gin.H{"message": "Invalid body"})
|
||||
c.IndentedJSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdTrigger, status := h.dataStore.CreateTrigger(databaseId, collectionId, trigger)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -114,5 +115,5 @@ func (h *Handlers) CreateTrigger(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pikami/cosmium/internal/constants"
|
||||
"github.com/pikami/cosmium/internal/datastore"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func (h *Handlers) GetAllUserDefinedFunctions(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) GetUserDefinedFunction(c *gin.Context) {
|
||||
@@ -36,11 +37,11 @@ func (h *Handlers) GetUserDefinedFunction(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) DeleteUserDefinedFunction(c *gin.Context) {
|
||||
@@ -55,11 +56,11 @@ func (h *Handlers) DeleteUserDefinedFunction(c *gin.Context) {
|
||||
}
|
||||
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) ReplaceUserDefinedFunction(c *gin.Context) {
|
||||
@@ -69,19 +70,19 @@ func (h *Handlers) ReplaceUserDefinedFunction(c *gin.Context) {
|
||||
|
||||
var udf datastore.UserDefinedFunction
|
||||
if err := c.BindJSON(&udf); err != nil {
|
||||
c.IndentedJSON(http.StatusBadRequest, gin.H{"message": "Invalid body"})
|
||||
c.IndentedJSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
status := h.dataStore.DeleteUserDefinedFunction(databaseId, collectionId, udfId)
|
||||
if status == datastore.StatusNotFound {
|
||||
c.IndentedJSON(http.StatusNotFound, gin.H{"message": "NotFound"})
|
||||
c.IndentedJSON(http.StatusNotFound, constants.NotFoundResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdUdf, status := h.dataStore.CreateUserDefinedFunction(databaseId, collectionId, udf)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ func (h *Handlers) ReplaceUserDefinedFunction(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
func (h *Handlers) CreateUserDefinedFunction(c *gin.Context) {
|
||||
@@ -99,13 +100,13 @@ func (h *Handlers) CreateUserDefinedFunction(c *gin.Context) {
|
||||
|
||||
var udf datastore.UserDefinedFunction
|
||||
if err := c.BindJSON(&udf); err != nil {
|
||||
c.IndentedJSON(http.StatusBadRequest, gin.H{"message": "Invalid body"})
|
||||
c.IndentedJSON(http.StatusBadRequest, constants.BadRequestResponse)
|
||||
return
|
||||
}
|
||||
|
||||
createdUdf, status := h.dataStore.CreateUserDefinedFunction(databaseId, collectionId, udf)
|
||||
if status == datastore.Conflict {
|
||||
c.IndentedJSON(http.StatusConflict, gin.H{"message": "Conflict"})
|
||||
c.IndentedJSON(http.StatusConflict, constants.ConflictResponse)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -114,5 +115,5 @@ func (h *Handlers) CreateUserDefinedFunction(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.IndentedJSON(http.StatusInternalServerError, gin.H{"message": "Unknown error"})
|
||||
c.IndentedJSON(http.StatusInternalServerError, constants.UnknownErrorResponse)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func Test_Authentication(t *testing.T) {
|
||||
t.Run("Should get 200 when correct account key is used", func(t *testing.T) {
|
||||
ts.DataStore.DeleteDatabase(testDatabaseName)
|
||||
client, err := azcosmos.NewClientFromConnectionString(
|
||||
fmt.Sprintf("AccountEndpoint=%s;AccountKey=%s", ts.URL, config.DefaultAccountKey),
|
||||
formatConnectionString(ts.URL, config.DefaultAccountKey),
|
||||
&azcosmos.ClientOptions{},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
@@ -35,7 +35,7 @@ func Test_Authentication(t *testing.T) {
|
||||
t.Run("Should get 401 when wrong account key is used", func(t *testing.T) {
|
||||
ts.DataStore.DeleteDatabase(testDatabaseName)
|
||||
client, err := azcosmos.NewClientFromConnectionString(
|
||||
fmt.Sprintf("AccountEndpoint=%s;AccountKey=%s", ts.URL, "AAAA"),
|
||||
formatConnectionString(ts.URL, "AAAA"),
|
||||
&azcosmos.ClientOptions{},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
@@ -72,7 +72,7 @@ func Test_Authentication_Disabled(t *testing.T) {
|
||||
t.Run("Should get 200 when wrong account key is used, but authentication is dissabled", func(t *testing.T) {
|
||||
ts.DataStore.DeleteDatabase(testDatabaseName)
|
||||
client, err := azcosmos.NewClientFromConnectionString(
|
||||
fmt.Sprintf("AccountEndpoint=%s;AccountKey=%s", ts.URL, "AAAA"),
|
||||
formatConnectionString(ts.URL, "AAAA"),
|
||||
&azcosmos.ClientOptions{},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
@@ -85,3 +85,7 @@ func Test_Authentication_Disabled(t *testing.T) {
|
||||
assert.Equal(t, createResponse.DatabaseProperties.ID, testDatabaseName)
|
||||
})
|
||||
}
|
||||
|
||||
func formatConnectionString(endpoint, key string) string {
|
||||
return fmt.Sprintf("AccountEndpoint=%s;AccountKey=%s", endpoint, key)
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ Cosmium strives to support the core features of Cosmos DB, including:
|
||||
|
||||
| Function | Implemented |
|
||||
| -------- | ----------- |
|
||||
| IIF | No |
|
||||
| IIF | Yes |
|
||||
|
||||
### Date and time Functions
|
||||
|
||||
|
||||
@@ -3,34 +3,34 @@ module github.com/pikami/cosmium
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v1.3.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v1.4.0
|
||||
github.com/cosmiumdev/json-patch/v5 v5.9.11
|
||||
github.com/dgraph-io/badger/v4 v4.6.0
|
||||
github.com/dgraph-io/badger/v4 v4.7.0
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/bytedance/sonic v1.13.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gin-contrib/sse v1.0.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.25.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.26.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/google/flatbuffers v25.2.10+incompatible // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -40,7 +40,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
@@ -50,11 +50,11 @@ require (
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
golang.org/x/arch v0.15.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
golang.org/x/arch v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.38.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -2,16 +2,26 @@ github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v1.3.0 h1:RGcdpSElvcXCwxydI0xzOBu1Gvp88OoiTGfbtO/z1m0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v1.3.0/go.mod h1:YwUyrNUtcZcibA99JcfCP6UUp95VVQKO2MJfBzgJDwA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v1.4.0 h1:TSaH6Lj0m8bDr4vX1+LC1KLQTnLzZb3tOxrx/PLqw+c=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos v1.4.0/go.mod h1:Krtog/7tz27z75TwM5cIS8bxEH4dcBUezcq+kGVeZEo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
||||
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
|
||||
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
@@ -27,16 +37,25 @@ 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/dgraph-io/badger/v4 v4.6.0 h1:acOwfOOZ4p1dPRnYzvkVm7rUk2Y21TgPVepCy5dJdFQ=
|
||||
github.com/dgraph-io/badger/v4 v4.6.0/go.mod h1:KSJ5VTuZNC3Sd+YhvVjk2nYua9UZnnTr/SkXvdtiPgI=
|
||||
github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y=
|
||||
github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA=
|
||||
github.com/dgraph-io/ristretto/v2 v2.1.0 h1:59LjpOJLNDULHh8MC4UaegN52lC4JnO2dITsie/Pa8I=
|
||||
github.com/dgraph-io/ristretto/v2 v2.1.0/go.mod h1:uejeqfYXpUomfse0+lO+13ATz4TypQYLJZzBSAemuB4=
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
|
||||
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -52,10 +71,13 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
|
||||
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
@@ -88,6 +110,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/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.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -126,19 +150,33 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=
|
||||
golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
||||
golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU=
|
||||
golang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -30,3 +30,8 @@ var QueryPlanResponse = gin.H{
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var UnknownErrorResponse = gin.H{"message": "Unknown error"}
|
||||
var NotFoundResponse = gin.H{"message": "NotFound"}
|
||||
var ConflictResponse = gin.H{"message": "Conflict"}
|
||||
var BadRequestResponse = gin.H{"message": "BadRequest"}
|
||||
|
||||
@@ -15,6 +15,7 @@ type BadgerDataStoreOptions struct {
|
||||
|
||||
func NewBadgerDataStore(options BadgerDataStoreOptions) *BadgerDataStore {
|
||||
badgerOpts := badger.DefaultOptions(options.PersistDataFilePath)
|
||||
badgerOpts = badgerOpts.WithLogger(newBadgerLogger())
|
||||
if options.PersistDataFilePath == "" {
|
||||
badgerOpts = badgerOpts.WithInMemory(true)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package badgerdatastore
|
||||
|
||||
import (
|
||||
"github.com/dgraph-io/badger/v4"
|
||||
"github.com/pikami/cosmium/internal/logger"
|
||||
)
|
||||
|
||||
type badgerLogger struct{}
|
||||
|
||||
func newBadgerLogger() badger.Logger {
|
||||
return &badgerLogger{}
|
||||
}
|
||||
|
||||
func (l *badgerLogger) Errorf(format string, v ...interface{}) {
|
||||
logger.Errorf(format, v...)
|
||||
}
|
||||
|
||||
func (l *badgerLogger) Warningf(format string, v ...interface{}) {
|
||||
logger.Infof(format, v...)
|
||||
}
|
||||
|
||||
func (l *badgerLogger) Infof(format string, v ...interface{}) {
|
||||
logger.Infof(format, v...)
|
||||
}
|
||||
|
||||
func (l *badgerLogger) Debugf(format string, v ...interface{}) {
|
||||
logger.Debugf(format, v...)
|
||||
}
|
||||
@@ -134,6 +134,8 @@ const (
|
||||
FunctionCallSetIntersect FunctionCallType = "SetIntersect"
|
||||
FunctionCallSetUnion FunctionCallType = "SetUnion"
|
||||
|
||||
FunctionCallIif FunctionCallType = "Iif"
|
||||
|
||||
FunctionCallMathAbs FunctionCallType = "MathAbs"
|
||||
FunctionCallMathAcos FunctionCallType = "MathAcos"
|
||||
FunctionCallMathAsin FunctionCallType = "MathAsin"
|
||||
|
||||
@@ -163,4 +163,27 @@ func Test_Parse(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse IIF function", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT IIF(true, c.pk, c.id) FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIif,
|
||||
Arguments: []interface{}{
|
||||
testutils.SelectItem_Constant_Bool(true),
|
||||
testutils.SelectItem_Path("c", "pk"),
|
||||
testutils.SelectItem_Path("c", "id"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
+1740
-1580
File diff suppressed because it is too large
Load Diff
@@ -289,6 +289,11 @@ SelectArray <- "[" ws columns:ColumnList ws "]" {
|
||||
|
||||
SelectObject <- "{" ws field:SelectObjectField ws other_fields:(ws "," ws coll:SelectObjectField {return coll, nil })* ws "}" {
|
||||
return makeSelectObject(field, other_fields)
|
||||
} / "{" ws "}" {
|
||||
return parsers.SelectItem{
|
||||
SelectItems: []parsers.SelectItem{},
|
||||
Type: parsers.SelectItemTypeObject,
|
||||
}, nil
|
||||
}
|
||||
|
||||
SelectObjectField <- name:(Identifier / "\"" key:Identifier "\"" { return key, nil }) ws ":" ws selectItem:SelectItem {
|
||||
@@ -442,6 +447,7 @@ BooleanLiteral <- ("true"i / "false"i) {
|
||||
FunctionCall <- StringFunctions
|
||||
/ TypeCheckingFunctions
|
||||
/ ArrayFunctions
|
||||
/ ConditionalFunctions
|
||||
/ InFunction
|
||||
/ AggregateFunctions
|
||||
/ MathFunctions
|
||||
@@ -489,6 +495,8 @@ ArrayFunctions <- ArrayConcatExpression
|
||||
/ SetIntersectExpression
|
||||
/ SetUnionExpression
|
||||
|
||||
ConditionalFunctions <- IifExpression
|
||||
|
||||
MathFunctions <- MathAbsExpression
|
||||
/ MathAcosExpression
|
||||
/ MathAsinExpression
|
||||
@@ -681,6 +689,10 @@ SetUnionExpression <- "SetUnion"i ws "(" ws set1:SelectItem ws "," ws set2:Selec
|
||||
return createFunctionCall(parsers.FunctionCallSetUnion, []interface{}{set1, set2})
|
||||
}
|
||||
|
||||
IifExpression <- "IIF"i ws "(" ws condition:SelectItem ws "," ws trueValue:SelectItem ws "," ws falseValue:SelectItem ws ")" {
|
||||
return createFunctionCall(parsers.FunctionCallIif, []interface{}{condition, trueValue, falseValue})
|
||||
}
|
||||
|
||||
MathAbsExpression <- "ABS"i ws "(" ws ex:SelectItem ws ")" { return createFunctionCall(parsers.FunctionCallMathAbs, []interface{}{ex}) }
|
||||
MathAcosExpression <- "ACOS"i ws "(" ws ex:SelectItem ws ")" { return createFunctionCall(parsers.FunctionCallMathAcos, []interface{}{ex}) }
|
||||
MathAsinExpression <- "ASIN"i ws "(" ws ex:SelectItem ws ")" { return createFunctionCall(parsers.FunctionCallMathAsin, []interface{}{ex}) }
|
||||
|
||||
@@ -178,4 +178,21 @@ func Test_Parse_Select(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should parse SELECT empty object", func(t *testing.T) {
|
||||
testQueryParse(
|
||||
t,
|
||||
`SELECT {} AS obj FROM c`,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Alias: "obj",
|
||||
Type: parsers.SelectItemTypeObject,
|
||||
SelectItems: []parsers.SelectItem{},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -209,6 +209,9 @@ func (r rowContext) selectItem_SelectItemTypeFunctionCall(functionCall parsers.F
|
||||
case parsers.FunctionCallSetUnion:
|
||||
return r.set_Union(functionCall.Arguments)
|
||||
|
||||
case parsers.FunctionCallIif:
|
||||
return r.misc_Iif(functionCall.Arguments)
|
||||
|
||||
case parsers.FunctionCallMathAbs:
|
||||
return r.math_Abs(functionCall.Arguments)
|
||||
case parsers.FunctionCallMathAcos:
|
||||
|
||||
@@ -16,3 +16,16 @@ func (r rowContext) misc_In(arguments []interface{}) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (r rowContext) misc_Iif(arguments []interface{}) interface{} {
|
||||
if len(arguments) != 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
condition := r.resolveSelectItem(arguments[0].(parsers.SelectItem))
|
||||
if condition != nil && condition == true {
|
||||
return r.resolveSelectItem(arguments[1].(parsers.SelectItem))
|
||||
}
|
||||
|
||||
return r.resolveSelectItem(arguments[2].(parsers.SelectItem))
|
||||
}
|
||||
|
||||
@@ -210,4 +210,35 @@ func Test_Execute(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute function IIF()", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
testutils.SelectItem_Path("c", "id"),
|
||||
{
|
||||
Alias: "coolness",
|
||||
Type: parsers.SelectItemTypeFunctionCall,
|
||||
Value: parsers.FunctionCall{
|
||||
Type: parsers.FunctionCallIif,
|
||||
Arguments: []interface{}{
|
||||
testutils.SelectItem_Path("c", "isCool"),
|
||||
testutils.SelectItem_Constant_String("real cool"),
|
||||
testutils.SelectItem_Constant_String("not cool"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"id": "12345", "coolness": "not cool"},
|
||||
map[string]interface{}{"id": "67890", "coolness": "real cool"},
|
||||
map[string]interface{}{"id": "456", "coolness": "real cool"},
|
||||
map[string]interface{}{"id": "123", "coolness": "real cool"},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -205,4 +205,27 @@ func Test_Execute_Select(t *testing.T) {
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("Should execute SELECT empty object", func(t *testing.T) {
|
||||
testQueryExecute(
|
||||
t,
|
||||
parsers.SelectStmt{
|
||||
SelectItems: []parsers.SelectItem{
|
||||
{
|
||||
Alias: "obj",
|
||||
Type: parsers.SelectItemTypeObject,
|
||||
SelectItems: []parsers.SelectItem{},
|
||||
},
|
||||
},
|
||||
Table: parsers.Table{SelectItem: testutils.SelectItem_Path("c")},
|
||||
},
|
||||
mockData,
|
||||
[]memoryexecutor.RowType{
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
map[string]interface{}{"obj": map[string]interface{}{}},
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user