131 lines
4.5 KiB
Go
Raw Normal View History

2024-02-11 01:44:20 +02:00
package repositories
2024-02-12 01:54:12 +02:00
import (
2024-02-24 20:00:47 +02:00
"fmt"
2024-02-12 01:54:12 +02:00
"log"
2024-02-24 20:00:47 +02:00
"time"
2024-02-12 01:54:12 +02:00
2024-02-24 20:00:47 +02:00
"github.com/google/uuid"
repositorymodels "github.com/pikami/cosmium/internal/repository_models"
"github.com/pikami/cosmium/internal/resourceid"
2024-02-12 01:54:12 +02:00
"github.com/pikami/cosmium/parsers"
"github.com/pikami/cosmium/parsers/nosql"
memoryexecutor "github.com/pikami/cosmium/query_executors/memory_executor"
"golang.org/x/exp/maps"
2024-02-12 01:54:12 +02:00
)
2024-02-11 01:44:20 +02:00
func (r *DataRepository) GetAllDocuments(databaseId string, collectionId string) ([]repositorymodels.Document, repositorymodels.RepositoryStatus) {
r.storeState.RLock()
defer r.storeState.RUnlock()
2024-12-08 17:54:58 +02:00
if _, ok := r.storeState.Databases[databaseId]; !ok {
return make([]repositorymodels.Document, 0), repositorymodels.StatusNotFound
}
2024-02-11 01:44:20 +02:00
if _, ok := r.storeState.Collections[databaseId][collectionId]; !ok {
return make([]repositorymodels.Document, 0), repositorymodels.StatusNotFound
2024-02-11 01:44:20 +02:00
}
return maps.Values(r.storeState.Documents[databaseId][collectionId]), repositorymodels.StatusOk
2024-02-11 01:44:20 +02:00
}
func (r *DataRepository) GetDocument(databaseId string, collectionId string, documentId string) (repositorymodels.Document, repositorymodels.RepositoryStatus) {
r.storeState.RLock()
defer r.storeState.RUnlock()
2024-12-08 17:54:58 +02:00
if _, ok := r.storeState.Databases[databaseId]; !ok {
return repositorymodels.Document{}, repositorymodels.StatusNotFound
}
if _, ok := r.storeState.Collections[databaseId][collectionId]; !ok {
return repositorymodels.Document{}, repositorymodels.StatusNotFound
}
2024-02-11 01:44:20 +02:00
if _, ok := r.storeState.Documents[databaseId][collectionId][documentId]; !ok {
return repositorymodels.Document{}, repositorymodels.StatusNotFound
2024-02-11 01:44:20 +02:00
}
return r.storeState.Documents[databaseId][collectionId][documentId], repositorymodels.StatusOk
2024-02-11 01:44:20 +02:00
}
func (r *DataRepository) DeleteDocument(databaseId string, collectionId string, documentId string) repositorymodels.RepositoryStatus {
r.storeState.Lock()
defer r.storeState.Unlock()
2024-12-08 17:54:58 +02:00
if _, ok := r.storeState.Databases[databaseId]; !ok {
return repositorymodels.StatusNotFound
2024-02-11 01:44:20 +02:00
}
if _, ok := r.storeState.Collections[databaseId][collectionId]; !ok {
return repositorymodels.StatusNotFound
2024-02-11 01:44:20 +02:00
}
if _, ok := r.storeState.Documents[databaseId][collectionId][documentId]; !ok {
return repositorymodels.StatusNotFound
2024-02-11 01:44:20 +02:00
}
delete(r.storeState.Documents[databaseId][collectionId], documentId)
return repositorymodels.StatusOk
}
2024-02-11 01:44:20 +02:00
func (r *DataRepository) CreateDocument(databaseId string, collectionId string, document map[string]interface{}) (repositorymodels.Document, repositorymodels.RepositoryStatus) {
r.storeState.Lock()
defer r.storeState.Unlock()
2024-12-08 17:54:58 +02:00
var ok bool
var documentId string
var database repositorymodels.Database
var collection repositorymodels.Collection
if documentId, ok = document["id"].(string); !ok || documentId == "" {
documentId = fmt.Sprint(uuid.New())
document["id"] = documentId
2024-02-11 01:44:20 +02:00
}
if database, ok = r.storeState.Databases[databaseId]; !ok {
return repositorymodels.Document{}, repositorymodels.StatusNotFound
}
2024-02-12 01:54:12 +02:00
if collection, ok = r.storeState.Collections[databaseId][collectionId]; !ok {
return repositorymodels.Document{}, repositorymodels.StatusNotFound
}
2024-02-12 01:54:12 +02:00
if _, ok := r.storeState.Documents[databaseId][collectionId][documentId]; ok {
return repositorymodels.Document{}, repositorymodels.Conflict
2024-02-11 01:44:20 +02:00
}
2024-02-24 20:00:47 +02:00
document["_ts"] = time.Now().Unix()
document["_rid"] = resourceid.NewCombined(database.ResourceID, collection.ResourceID, resourceid.New())
document["_etag"] = fmt.Sprintf("\"%s\"", uuid.New())
document["_self"] = fmt.Sprintf("dbs/%s/colls/%s/docs/%s/", database.ResourceID, collection.ResourceID, document["_rid"])
2024-02-11 01:44:20 +02:00
r.storeState.Documents[databaseId][collectionId][documentId] = document
return document, repositorymodels.StatusOk
2024-02-11 01:44:20 +02:00
}
2024-02-12 01:54:12 +02:00
func (r *DataRepository) ExecuteQueryDocuments(databaseId string, collectionId string, query string, queryParameters map[string]interface{}) ([]memoryexecutor.RowType, repositorymodels.RepositoryStatus) {
2024-02-12 01:54:12 +02:00
parsedQuery, err := nosql.Parse("", []byte(query))
if err != nil {
log.Printf("Failed to parse query: %s\nerr: %v", query, err)
return nil, repositorymodels.BadRequest
2024-02-12 01:54:12 +02:00
}
collectionDocuments, status := r.GetAllDocuments(databaseId, collectionId)
if status != repositorymodels.StatusOk {
2024-02-12 01:54:12 +02:00
return nil, status
}
covDocs := make([]memoryexecutor.RowType, 0)
for _, doc := range collectionDocuments {
covDocs = append(covDocs, map[string]interface{}(doc))
}
2024-02-16 00:13:11 +02:00
if typedQuery, ok := parsedQuery.(parsers.SelectStmt); ok {
typedQuery.Parameters = queryParameters
2024-12-07 22:29:26 +02:00
return memoryexecutor.ExecuteQuery(typedQuery, covDocs), repositorymodels.StatusOk
2024-02-16 00:13:11 +02:00
}
return nil, repositorymodels.BadRequest
2024-02-12 01:54:12 +02:00
}