mirror of
https://github.com/pikami/cosmium.git
synced 2026-06-12 07:17:06 +01:00
129 lines
3.7 KiB
Go
129 lines
3.7 KiB
Go
package rntbd
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"github.com/pikami/cosmium/api/headers"
|
|
)
|
|
|
|
func (f *RntbdFrame) ToHttpRequest() *http.Request {
|
|
req := &http.Request{
|
|
Method: operationTypeToHttpMethod(f.OperationType),
|
|
URL: &url.URL{Path: frameToPath(f)},
|
|
Body: io.NopCloser(bytes.NewReader(f.Payload)),
|
|
Header: http.Header{},
|
|
}
|
|
|
|
switch f.OperationType {
|
|
case RntbdOperationTypeQuery, RntbdOperationTypeSQLQuery:
|
|
req.Header.Set(headers.Query, "true")
|
|
case RntbdOperationTypeUpsert:
|
|
req.Header.Set(headers.IsUpsert, "true")
|
|
}
|
|
|
|
if ifMatch, ok := f.RequestHeaders[RntbdRequestHeaderMatch]; ok {
|
|
if ifMatchString, ok := ifMatch.(string); ok {
|
|
req.Header.Set(headers.IfMatch, ifMatchString)
|
|
}
|
|
}
|
|
|
|
if continuationToken, ok := f.RequestHeaders[RntbdRequestHeaderContinuationToken]; ok {
|
|
if continuationTokenString, ok := continuationToken.(string); ok {
|
|
req.Header.Set(headers.ContinuationToken, continuationTokenString)
|
|
}
|
|
}
|
|
|
|
if maxItemCount, ok := f.RequestHeaders[RntbdRequestHeaderPageSize]; ok {
|
|
if maxItemCountString, ok := maxItemCount.(uint64); ok {
|
|
req.Header.Set(headers.MaxItemCount, fmt.Sprintf("%d", maxItemCountString))
|
|
}
|
|
}
|
|
|
|
return req
|
|
}
|
|
|
|
func ToRntbdResponseFrame(responseWriter *httptest.ResponseRecorder) *RntbdResponseFrameBuilder {
|
|
builder := &RntbdResponseFrameBuilder{}
|
|
builder.SetStatusCode(uint16(responseWriter.Code))
|
|
|
|
if responseWriter.Header().Get(headers.ETag) != "" {
|
|
builder.AddHeader(uint16(RntbdResponseHeaderETag), RntbdTokenTypeString, responseWriter.Header().Get(headers.ETag))
|
|
}
|
|
|
|
if responseWriter.Header().Get(headers.ContinuationToken) != "" {
|
|
builder.AddHeader(uint16(RntbdResponseHeaderContinuationToken), RntbdTokenTypeString, responseWriter.Header().Get(headers.ContinuationToken))
|
|
}
|
|
|
|
if responseWriter.Header().Get(headers.ItemCount) != "" {
|
|
itemCount, err := strconv.ParseUint(responseWriter.Header().Get(headers.ItemCount), 10, 32)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
builder.AddHeader(uint16(RntbdResponseHeaderItemCount), RntbdTokenTypeULong, uint32(itemCount))
|
|
}
|
|
|
|
if responseWriter.Body.Len() > 0 {
|
|
builder.AddHeader(uint16(RntbdResponseHeaderPayloadPresent), RntbdTokenTypeByte, []byte{1})
|
|
builder.AddPayload(responseWriter.Body.Bytes())
|
|
} else {
|
|
builder.AddHeader(uint16(RntbdResponseHeaderPayloadPresent), RntbdTokenTypeByte, []byte{0})
|
|
}
|
|
|
|
return builder
|
|
}
|
|
|
|
func operationTypeToHttpMethod(operationType RntbdOperationType) string {
|
|
switch operationType {
|
|
case RntbdOperationTypeRead,
|
|
RntbdOperationTypeReadFeed:
|
|
return http.MethodGet
|
|
case RntbdOperationTypeCreate,
|
|
RntbdOperationTypeUpsert,
|
|
RntbdOperationTypeQuery,
|
|
RntbdOperationTypeSQLQuery:
|
|
return http.MethodPost
|
|
case RntbdOperationTypeUpdate,
|
|
RntbdOperationTypeReplace:
|
|
return http.MethodPut
|
|
case RntbdOperationTypeDelete:
|
|
return http.MethodDelete
|
|
}
|
|
|
|
panic(fmt.Sprintf("Unknown operation type: %d", operationType))
|
|
}
|
|
|
|
func frameToPath(frame *RntbdFrame) string {
|
|
databaseName, databaseOk := frame.RequestHeaders[RntbdRequestHeaderDatabaseName]
|
|
collectionName, collectionOk := frame.RequestHeaders[RntbdRequestHeaderCollectionName]
|
|
documentName, documentOk := frame.RequestHeaders[RntbdRequestHeaderDocumentName]
|
|
|
|
urlPath := ""
|
|
|
|
if databaseOk {
|
|
urlPath += fmt.Sprintf("/dbs/%s", databaseName)
|
|
} else if frame.ResourceType == RntbdResourceTypeDatabase {
|
|
urlPath += "/dbs"
|
|
}
|
|
|
|
if collectionOk {
|
|
urlPath += fmt.Sprintf("/colls/%s", collectionName)
|
|
} else if frame.ResourceType == RntbdResourceTypeCollection {
|
|
urlPath += "/colls"
|
|
}
|
|
|
|
if documentOk {
|
|
urlPath += fmt.Sprintf("/docs/%s", documentName)
|
|
} else if frame.ResourceType == RntbdResourceTypeDocument {
|
|
urlPath += "/docs"
|
|
}
|
|
|
|
return urlPath
|
|
}
|