2024-02-10 23:44:20 +00:00
|
|
|
package repositories
|
|
|
|
|
2024-02-11 23:54:12 +00:00
|
|
|
import (
|
2024-02-24 18:00:47 +00:00
|
|
|
"fmt"
|
2024-02-11 23:54:12 +00:00
|
|
|
"log"
|
|
|
|
"strings"
|
2024-02-24 18:00:47 +00:00
|
|
|
"time"
|
2024-02-11 23:54:12 +00:00
|
|
|
|
2024-02-24 18:00:47 +00:00
|
|
|
"github.com/google/uuid"
|
2024-02-12 19:38:03 +00:00
|
|
|
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
|
2024-02-11 23:54:12 +00:00
|
|
|
"github.com/pikami/cosmium/parsers"
|
|
|
|
"github.com/pikami/cosmium/parsers/nosql"
|
|
|
|
memoryexecutor "github.com/pikami/cosmium/query_executors/memory_executor"
|
|
|
|
)
|
2024-02-10 23:44:20 +00:00
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
var documents = []repositorymodels.Document{}
|
2024-02-10 23:44:20 +00:00
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
func GetAllDocuments(databaseId string, collectionId string) ([]repositorymodels.Document, repositorymodels.RepositoryStatus) {
|
|
|
|
filteredDocuments := make([]repositorymodels.Document, 0)
|
2024-02-10 23:44:20 +00:00
|
|
|
|
|
|
|
for _, doc := range documents {
|
|
|
|
docDbId := doc["_internal"].(map[string]interface{})["databaseId"]
|
|
|
|
docCollId := doc["_internal"].(map[string]interface{})["collectionId"]
|
|
|
|
|
|
|
|
if docDbId == databaseId && docCollId == collectionId {
|
|
|
|
doc["_partitionKeyValue"] = doc["_internal"].(map[string]interface{})["partitionKeyValue"]
|
|
|
|
filteredDocuments = append(filteredDocuments, doc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
return filteredDocuments, repositorymodels.StatusOk
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
func GetDocument(databaseId string, collectionId string, documentId string) (repositorymodels.Document, repositorymodels.RepositoryStatus) {
|
2024-02-10 23:44:20 +00:00
|
|
|
for _, doc := range documents {
|
|
|
|
docDbId := doc["_internal"].(map[string]interface{})["databaseId"]
|
|
|
|
docCollId := doc["_internal"].(map[string]interface{})["collectionId"]
|
|
|
|
docId := doc["id"]
|
|
|
|
|
|
|
|
if docDbId == databaseId && docCollId == collectionId && docId == documentId {
|
|
|
|
doc["_partitionKeyValue"] = doc["_internal"].(map[string]interface{})["partitionKeyValue"]
|
2024-02-12 19:38:03 +00:00
|
|
|
return doc, repositorymodels.StatusOk
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
return repositorymodels.Document{}, repositorymodels.StatusNotFound
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
func DeleteDocument(databaseId string, collectionId string, documentId string) repositorymodels.RepositoryStatus {
|
2024-02-10 23:44:20 +00:00
|
|
|
for index, doc := range documents {
|
|
|
|
docDbId := doc["_internal"].(map[string]interface{})["databaseId"]
|
|
|
|
docCollId := doc["_internal"].(map[string]interface{})["collectionId"]
|
|
|
|
docId := doc["id"]
|
|
|
|
|
|
|
|
if docDbId == databaseId && docCollId == collectionId && docId == documentId {
|
|
|
|
documents = append(documents[:index], documents[index+1:]...)
|
2024-02-12 19:38:03 +00:00
|
|
|
return repositorymodels.StatusOk
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
return repositorymodels.StatusNotFound
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
func CreateDocument(databaseId string, collectionId string, document map[string]interface{}) repositorymodels.RepositoryStatus {
|
2024-02-10 23:44:20 +00:00
|
|
|
if document["id"] == "" {
|
2024-02-12 19:38:03 +00:00
|
|
|
return repositorymodels.BadRequest
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
collection, status := GetCollection(databaseId, collectionId)
|
2024-02-12 19:38:03 +00:00
|
|
|
if status != repositorymodels.StatusOk {
|
|
|
|
return repositorymodels.StatusNotFound
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, doc := range documents {
|
|
|
|
docDbId := doc["_internal"].(map[string]interface{})["databaseId"]
|
|
|
|
docCollId := doc["_internal"].(map[string]interface{})["collectionId"]
|
|
|
|
docId := doc["id"]
|
|
|
|
|
|
|
|
if docDbId == databaseId && docCollId == collectionId && docId == document["id"] {
|
2024-02-12 19:38:03 +00:00
|
|
|
return repositorymodels.Conflict
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
partitionKeyValue := make([]string, 0)
|
|
|
|
for _, path := range collection.PartitionKey.Paths {
|
|
|
|
var val interface{}
|
|
|
|
for _, part := range strings.Split(path, "/") {
|
|
|
|
val = document[part]
|
|
|
|
}
|
2024-02-11 23:54:12 +00:00
|
|
|
|
|
|
|
if val == nil {
|
|
|
|
val = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: handle non-string partition keys
|
2024-02-10 23:44:20 +00:00
|
|
|
partitionKeyValue = append(partitionKeyValue, val.(string))
|
|
|
|
}
|
|
|
|
|
2024-02-24 18:00:47 +00:00
|
|
|
document["_ts"] = time.Now().Unix()
|
|
|
|
document["_rid"] = uuid.New().String()
|
|
|
|
document["_etag"] = fmt.Sprintf("\"%s\"", document["_rid"])
|
2024-02-10 23:44:20 +00:00
|
|
|
document["_internal"] = map[string]interface{}{
|
|
|
|
"databaseId": databaseId,
|
|
|
|
"collectionId": collectionId,
|
|
|
|
"partitionKeyValue": partitionKeyValue,
|
|
|
|
}
|
|
|
|
documents = append(documents, document)
|
|
|
|
|
2024-02-12 19:38:03 +00:00
|
|
|
return repositorymodels.StatusOk
|
2024-02-10 23:44:20 +00:00
|
|
|
}
|
2024-02-11 23:54:12 +00:00
|
|
|
|
2024-02-15 22:13:11 +00:00
|
|
|
func ExecuteQueryDocuments(databaseId string, collectionId string, query string, queryParameters map[string]interface{}) ([]memoryexecutor.RowType, repositorymodels.RepositoryStatus) {
|
2024-02-11 23:54:12 +00:00
|
|
|
parsedQuery, err := nosql.Parse("", []byte(query))
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Failed to parse query: %s\nerr: %v", query, err)
|
2024-02-12 19:38:03 +00:00
|
|
|
return nil, repositorymodels.BadRequest
|
2024-02-11 23:54:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
collectionDocuments, status := GetAllDocuments(databaseId, collectionId)
|
2024-02-12 19:38:03 +00:00
|
|
|
if status != repositorymodels.StatusOk {
|
2024-02-11 23:54:12 +00:00
|
|
|
return nil, status
|
|
|
|
}
|
|
|
|
|
|
|
|
covDocs := make([]memoryexecutor.RowType, 0)
|
|
|
|
for _, doc := range collectionDocuments {
|
|
|
|
covDocs = append(covDocs, map[string]interface{}(doc))
|
|
|
|
}
|
|
|
|
|
2024-02-15 22:13:11 +00:00
|
|
|
if typedQuery, ok := parsedQuery.(parsers.SelectStmt); ok {
|
|
|
|
typedQuery.Parameters = queryParameters
|
|
|
|
return memoryexecutor.Execute(typedQuery, covDocs), repositorymodels.StatusOk
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, repositorymodels.BadRequest
|
2024-02-11 23:54:12 +00:00
|
|
|
}
|