obrimbasecli/essential/visible/service/helper/retriever/retriever.go

411 lines
9.1 KiB
Go

package retriever
import (
"strings"
)
const (
obrimRetrieverTypeJson = "json"
obrimRetrieverTypeDb = "db"
obrimRetrieverCodeSuccessResource = "SUCCESS_RESOURCE_RETRIEVED"
obrimRetrieverCodeSuccessPath = "SUCCESS_PATH_RETRIEVED"
obrimRetrieverCodeSuccessFields = "SUCCESS_FIELDS_RETRIEVED"
obrimRetrieverCodeFailedUnsupportedType = "FAILED_UNSUPPORTED_TYPE"
obrimRetrieverCodeFailedMissingConfig = "FAILED_MISSING_CONFIGURATION"
obrimRetrieverCodeFailedInvalidConfig = "FAILED_INVALID_CONFIGURATION"
obrimRetrieverCodeFailedResourceNotFound = "FAILED_RESOURCE_NOT_FOUND"
obrimRetrieverCodeFailedPathNotFound = "FAILED_PATH_NOT_FOUND"
obrimRetrieverCodeFailedFieldNotFound = "FAILED_FIELD_NOT_FOUND"
obrimRetrieverCodeFailedNotImplemented = "FAILED_NOT_IMPLEMENTED"
)
// ObrimRetrieverJsonProviderRegistry stores registered JSON providers.
var ObrimRetrieverJsonProviderRegistry = map[string]any{}
// ObrimRetrieverDbProviderRegistry stores registered database providers.
var ObrimRetrieverDbProviderRegistry = map[string]any{}
// ObrimRetrieverResponse defines the standardized utility response structure.
type ObrimRetrieverResponse struct {
Status bool `json:"status"`
Code string `json:"code"`
Payload map[string]any `json:"payload"`
}
// ObrimRetriever retrieves data using a unified retrieval interface.
func ObrimRetriever(retrievalType string, config map[string]any) map[string]any {
if !obrimRetrieverValidateType(retrievalType) {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedUnsupportedType,
nil,
)
}
validationCode := obrimRetrieverValidateConfig(retrievalType, config)
if validationCode != "" {
return obrimRetrieverBuildResponse(
false,
validationCode,
nil,
)
}
switch retrievalType {
case obrimRetrieverTypeJson:
return obrimRetrieverJson(config)
case obrimRetrieverTypeDb:
return obrimRetrieverDb(config)
default:
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedUnsupportedType,
nil,
)
}
}
// ObrimRetrieverJsonRegister registers a JSON provider.
func ObrimRetrieverJsonRegister(resource string, provider any) {
if strings.TrimSpace(resource) == "" {
return
}
ObrimRetrieverJsonProviderRegistry[resource] = provider
}
// ObrimRetrieverDbRegister registers a database provider.
func ObrimRetrieverDbRegister(resource string, provider any) {
if strings.TrimSpace(resource) == "" {
return
}
ObrimRetrieverDbProviderRegistry[resource] = provider
}
// obrimRetrieverValidateType validates a retrieval type.
func obrimRetrieverValidateType(retrievalType string) bool {
switch retrievalType {
case obrimRetrieverTypeJson:
return true
case obrimRetrieverTypeDb:
return true
default:
return false
}
}
// obrimRetrieverValidateConfig validates retrieval configuration.
func obrimRetrieverValidateConfig(
retrievalType string,
config map[string]any,
) string {
if config == nil {
return obrimRetrieverCodeFailedMissingConfig
}
switch retrievalType {
case obrimRetrieverTypeJson:
return obrimRetrieverJsonValidate(config)
case obrimRetrieverTypeDb:
return obrimRetrieverDbValidate(config)
default:
return obrimRetrieverCodeFailedUnsupportedType
}
}
// obrimRetrieverResolveProvider resolves a provider by resource identifier.
func obrimRetrieverResolveProvider(
retrievalType string,
resource string,
) (any, bool) {
switch retrievalType {
case obrimRetrieverTypeJson:
provider, exists := ObrimRetrieverJsonProviderRegistry[resource]
return provider, exists
case obrimRetrieverTypeDb:
provider, exists := ObrimRetrieverDbProviderRegistry[resource]
return provider, exists
default:
return nil, false
}
}
// obrimRetrieverBuildResponse builds a standardized utility response.
func obrimRetrieverBuildResponse(
status bool,
code string,
payload map[string]any,
) map[string]any {
return map[string]any{
"status": status,
"code": code,
"payload": payload,
}
}
// obrimRetrieverJson processes JSON retrieval requests.
func obrimRetrieverJson(config map[string]any) map[string]any {
resource := config["resource"].(string)
provider, exists := obrimRetrieverResolveProvider(
obrimRetrieverTypeJson,
resource,
)
if !exists {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedResourceNotFound,
nil,
)
}
if fields, exists := config["fields"]; exists {
return obrimRetrieverJsonFields(provider, fields)
}
if path, exists := config["path"]; exists {
return obrimRetrieverJsonPath(provider, path.(string))
}
return obrimRetrieverJsonResource(provider)
}
// obrimRetrieverJsonResource retrieves an entire resource.
func obrimRetrieverJsonResource(provider any) map[string]any {
data, success := obrimRetrieverJsonRetrieve(provider)
if !success {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedResourceNotFound,
nil,
)
}
return obrimRetrieverBuildResponse(
true,
obrimRetrieverCodeSuccessResource,
map[string]any{
"data": data,
},
)
}
// obrimRetrieverJsonPath retrieves a value using a dot-notation path.
func obrimRetrieverJsonPath(provider any, path string) map[string]any {
data, success := obrimRetrieverJsonRetrieve(provider)
if !success {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedResourceNotFound,
nil,
)
}
value, found := obrimRetrieverJsonResolvePath(data, path)
if !found {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedPathNotFound,
nil,
)
}
return obrimRetrieverBuildResponse(
true,
obrimRetrieverCodeSuccessPath,
map[string]any{
"data": value,
},
)
}
// obrimRetrieverJsonFields retrieves multiple values using field selection.
func obrimRetrieverJsonFields(provider any, fieldsValue any) map[string]any {
data, success := obrimRetrieverJsonRetrieve(provider)
if !success {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedResourceNotFound,
nil,
)
}
fields, valid := obrimRetrieverJsonNormalizeFields(fieldsValue)
if !valid {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedInvalidConfig,
nil,
)
}
result := map[string]any{}
for _, field := range fields {
value, found := obrimRetrieverJsonResolvePath(data, field)
if !found {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedFieldNotFound,
nil,
)
}
result[field] = value
}
return obrimRetrieverBuildResponse(
true,
obrimRetrieverCodeSuccessFields,
map[string]any{
"data": result,
},
)
}
// obrimRetrieverJsonValidate validates JSON retrieval configuration.
func obrimRetrieverJsonValidate(config map[string]any) string {
resourceValue, exists := config["resource"]
if !exists {
return obrimRetrieverCodeFailedMissingConfig
}
resource, valid := resourceValue.(string)
if !valid {
return obrimRetrieverCodeFailedInvalidConfig
}
if strings.TrimSpace(resource) == "" {
return obrimRetrieverCodeFailedInvalidConfig
}
_, pathExists := config["path"]
_, fieldsExists := config["fields"]
if pathExists && fieldsExists {
return obrimRetrieverCodeFailedInvalidConfig
}
if pathExists {
path, valid := config["path"].(string)
if !valid || strings.TrimSpace(path) == "" {
return obrimRetrieverCodeFailedInvalidConfig
}
}
if fieldsExists {
fields, valid := obrimRetrieverJsonNormalizeFields(config["fields"])
if !valid || len(fields) == 0 {
return obrimRetrieverCodeFailedInvalidConfig
}
}
return ""
}
// obrimRetrieverDb processes database retrieval requests.
func obrimRetrieverDb(config map[string]any) map[string]any {
return obrimRetrieverBuildResponse(
false,
obrimRetrieverCodeFailedNotImplemented,
nil,
)
}
// obrimRetrieverDbValidate validates database retrieval configuration.
func obrimRetrieverDbValidate(config map[string]any) string {
return ""
}
// obrimRetrieverJsonRetrieve retrieves resource data from a provider.
func obrimRetrieverJsonRetrieve(provider any) (any, bool) {
switch retrievalProvider := provider.(type) {
case func() any:
return retrievalProvider(), true
case func() map[string]any:
return retrievalProvider(), true
case func() (any, bool):
return retrievalProvider()
case map[string]any:
return retrievalProvider, true
default:
return nil, false
}
}
// obrimRetrieverJsonResolvePath resolves a dot-notation path.
func obrimRetrieverJsonResolvePath(data any, path string) (any, bool) {
current := data
for _, segment := range strings.Split(path, ".") {
object, valid := current.(map[string]any)
if !valid {
return nil, false
}
value, exists := object[segment]
if !exists {
return nil, false
}
current = value
}
return current, true
}
// obrimRetrieverJsonNormalizeFields normalizes field selections.
func obrimRetrieverJsonNormalizeFields(fieldsValue any) ([]string, bool) {
switch fields := fieldsValue.(type) {
case []string:
return fields, true
case []any:
result := make([]string, 0, len(fields))
for _, field := range fields {
fieldString, valid := field.(string)
if !valid {
return nil, false
}
result = append(result, fieldString)
}
return result, true
default:
return nil, false
}
}