mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-30 16:24:26 +00:00
Initial Spec done. More work to do. Need to bring in Argitek designs
This commit is contained in:
76
pkg/resolvespec/apiHandler.go
Normal file
76
pkg/resolvespec/apiHandler.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package resolvespec
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Warky-Devs/ResolveSpec/pkg/logger"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type HandlerFunc func(http.ResponseWriter, *http.Request)
|
||||
|
||||
type APIHandler struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewAPIHandler creates a new API handler instance
|
||||
func NewAPIHandler(db *gorm.DB) *APIHandler {
|
||||
return &APIHandler{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// Main handler method
|
||||
func (h *APIHandler) Handle(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
||||
var req RequestBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
logger.Error("Failed to decode request body: %v", err)
|
||||
h.sendError(w, http.StatusBadRequest, "invalid_request", "Invalid request body", err)
|
||||
return
|
||||
}
|
||||
|
||||
schema := params["schema"]
|
||||
entity := params["entity"]
|
||||
id := params["id"]
|
||||
|
||||
logger.Info("Handling %s operation for %s.%s", req.Operation, schema, entity)
|
||||
|
||||
switch req.Operation {
|
||||
case "read":
|
||||
h.handleRead(w, r, schema, entity, id, req.Options)
|
||||
case "create":
|
||||
h.handleCreate(w, r, schema, entity, req.Data, req.Options)
|
||||
case "update":
|
||||
h.handleUpdate(w, r, schema, entity, id, req.ID, req.Data, req.Options)
|
||||
case "delete":
|
||||
h.handleDelete(w, r, schema, entity, id)
|
||||
default:
|
||||
logger.Error("Invalid operation: %s", req.Operation)
|
||||
h.sendError(w, http.StatusBadRequest, "invalid_operation", "Invalid operation", nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *APIHandler) sendResponse(w http.ResponseWriter, data interface{}, metadata *Metadata) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(Response{
|
||||
Success: true,
|
||||
Data: data,
|
||||
Metadata: metadata,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *APIHandler) sendError(w http.ResponseWriter, status int, code, message string, details interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
json.NewEncoder(w).Encode(Response{
|
||||
Success: false,
|
||||
Error: &APIError{
|
||||
Code: code,
|
||||
Message: message,
|
||||
Details: details,
|
||||
Detail: fmt.Sprintf("%v", details),
|
||||
},
|
||||
})
|
||||
}
|
||||
250
pkg/resolvespec/crud.go
Normal file
250
pkg/resolvespec/crud.go
Normal file
@@ -0,0 +1,250 @@
|
||||
package resolvespec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/Warky-Devs/ResolveSpec/pkg/logger"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Read handler
|
||||
func (h *APIHandler) handleRead(w http.ResponseWriter, r *http.Request, schema, entity, id string, options RequestOptions) {
|
||||
logger.Info("Reading records from %s.%s", schema, entity)
|
||||
|
||||
// Get the model struct for the entity
|
||||
model, err := h.getModelForEntity(schema, entity)
|
||||
if err != nil {
|
||||
logger.Error("Invalid entity: %v", err)
|
||||
h.sendError(w, http.StatusBadRequest, "invalid_entity", "Invalid entity", err)
|
||||
return
|
||||
}
|
||||
|
||||
GormTableNameInterface, ok := model.(GormTableNameInterface)
|
||||
if !ok {
|
||||
logger.Error("Model does not implement GormTableNameInterface")
|
||||
h.sendError(w, http.StatusInternalServerError, "model_error", "Model does not implement GormTableNameInterface", nil)
|
||||
return
|
||||
}
|
||||
query := h.db.Model(model).Table(GormTableNameInterface.TableName())
|
||||
|
||||
// Apply column selection
|
||||
if len(options.Columns) > 0 {
|
||||
logger.Debug("Selecting columns: %v", options.Columns)
|
||||
query = query.Select(options.Columns)
|
||||
}
|
||||
|
||||
// Apply preloading
|
||||
for _, preload := range options.Preload {
|
||||
logger.Debug("Applying preload for relation: %s", preload.Relation)
|
||||
query = query.Preload(preload.Relation, func(db *gorm.DB) *gorm.DB {
|
||||
|
||||
if len(preload.Columns) > 0 {
|
||||
db = db.Select(preload.Columns)
|
||||
}
|
||||
if len(preload.Filters) > 0 {
|
||||
for _, filter := range preload.Filters {
|
||||
db = h.applyFilter(db, filter)
|
||||
}
|
||||
}
|
||||
return db
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Apply filters
|
||||
for _, filter := range options.Filters {
|
||||
logger.Debug("Applying filter: %s %s %v", filter.Column, filter.Operator, filter.Value)
|
||||
query = h.applyFilter(query, filter)
|
||||
}
|
||||
|
||||
// Apply sorting
|
||||
for _, sort := range options.Sort {
|
||||
direction := "ASC"
|
||||
if strings.ToLower(sort.Direction) == "desc" {
|
||||
direction = "DESC"
|
||||
}
|
||||
logger.Debug("Applying sort: %s %s", sort.Column, direction)
|
||||
query = query.Order(fmt.Sprintf("%s %s", sort.Column, direction))
|
||||
}
|
||||
|
||||
// Get total count before pagination
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
logger.Error("Error counting records: %v", err)
|
||||
h.sendError(w, http.StatusInternalServerError, "query_error", "Error counting records", err)
|
||||
return
|
||||
}
|
||||
logger.Debug("Total records before filtering: %d", total)
|
||||
|
||||
// Apply pagination
|
||||
if options.Limit != nil && *options.Limit > 0 {
|
||||
logger.Debug("Applying limit: %d", *options.Limit)
|
||||
query = query.Limit(*options.Limit)
|
||||
}
|
||||
if options.Offset != nil && *options.Offset > 0 {
|
||||
logger.Debug("Applying offset: %d", *options.Offset)
|
||||
query = query.Offset(*options.Offset)
|
||||
}
|
||||
|
||||
// Execute query
|
||||
var result interface{}
|
||||
if id != "" {
|
||||
logger.Debug("Querying single record with ID: %s", id)
|
||||
singleResult := model
|
||||
if err := query.First(singleResult, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
logger.Warn("Record not found with ID: %s", id)
|
||||
h.sendError(w, http.StatusNotFound, "not_found", "Record not found", nil)
|
||||
return
|
||||
}
|
||||
logger.Error("Error querying record: %v", err)
|
||||
h.sendError(w, http.StatusInternalServerError, "query_error", "Error executing query", err)
|
||||
return
|
||||
}
|
||||
result = singleResult
|
||||
} else {
|
||||
logger.Debug("Querying multiple records")
|
||||
sliceType := reflect.SliceOf(reflect.TypeOf(model))
|
||||
results := reflect.New(sliceType).Interface()
|
||||
|
||||
if err := query.Find(results).Error; err != nil {
|
||||
logger.Error("Error querying records: %v", err)
|
||||
h.sendError(w, http.StatusInternalServerError, "query_error", "Error executing query", err)
|
||||
return
|
||||
}
|
||||
result = reflect.ValueOf(results).Elem().Interface()
|
||||
}
|
||||
|
||||
logger.Info("Successfully retrieved records")
|
||||
h.sendResponse(w, result, &Metadata{
|
||||
Total: total,
|
||||
Filtered: total,
|
||||
Limit: optionalInt(options.Limit),
|
||||
Offset: optionalInt(options.Offset),
|
||||
})
|
||||
}
|
||||
|
||||
// Create handler
|
||||
func (h *APIHandler) handleCreate(w http.ResponseWriter, r *http.Request, schema, entity string, data any, options RequestOptions) {
|
||||
logger.Info("Creating records for %s.%s", schema, entity)
|
||||
query := h.db.Table(fmt.Sprintf("%s.%s", schema, entity))
|
||||
|
||||
switch v := data.(type) {
|
||||
case map[string]interface{}:
|
||||
result := query.Create(v)
|
||||
if result.Error != nil {
|
||||
logger.Error("Error creating record: %v", result.Error)
|
||||
h.sendError(w, http.StatusInternalServerError, "create_error", "Error creating record", result.Error)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully created record")
|
||||
h.sendResponse(w, v, nil)
|
||||
|
||||
case []map[string]interface{}:
|
||||
result := query.Create(v)
|
||||
if result.Error != nil {
|
||||
logger.Error("Error creating records: %v", result.Error)
|
||||
h.sendError(w, http.StatusInternalServerError, "create_error", "Error creating records", result.Error)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully created %d records", len(v))
|
||||
h.sendResponse(w, v, nil)
|
||||
case []interface{}:
|
||||
list := make([]interface{}, 0)
|
||||
for _, item := range v {
|
||||
result := query.Create(item)
|
||||
list = append(list, item)
|
||||
if result.Error != nil {
|
||||
logger.Error("Error creating records: %v", result.Error)
|
||||
h.sendError(w, http.StatusInternalServerError, "create_error", "Error creating records", result.Error)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully created %d records", len(v))
|
||||
}
|
||||
h.sendResponse(w, list, nil)
|
||||
default:
|
||||
logger.Error("Invalid data type for create operation: %T", data)
|
||||
}
|
||||
}
|
||||
|
||||
// Update handler
|
||||
func (h *APIHandler) handleUpdate(w http.ResponseWriter, r *http.Request, schema, entity string, urlID string, reqID any, data any, options RequestOptions) {
|
||||
logger.Info("Updating records for %s.%s", schema, entity)
|
||||
query := h.db.Table(fmt.Sprintf("%s.%s", schema, entity))
|
||||
|
||||
switch {
|
||||
case urlID != "":
|
||||
logger.Debug("Updating by URL ID: %s", urlID)
|
||||
result := query.Where("id = ?", urlID).Updates(data)
|
||||
handleUpdateResult(w, h, result, data)
|
||||
|
||||
case reqID != nil:
|
||||
switch id := reqID.(type) {
|
||||
case string:
|
||||
logger.Debug("Updating by request ID: %s", id)
|
||||
result := query.Where("id = ?", id).Updates(data)
|
||||
handleUpdateResult(w, h, result, data)
|
||||
|
||||
case []string:
|
||||
logger.Debug("Updating by multiple IDs: %v", id)
|
||||
result := query.Where("id IN ?", id).Updates(data)
|
||||
handleUpdateResult(w, h, result, data)
|
||||
}
|
||||
|
||||
case data != nil:
|
||||
switch v := data.(type) {
|
||||
case []map[string]interface{}:
|
||||
logger.Debug("Performing bulk update with %d records", len(v))
|
||||
err := h.db.Transaction(func(tx *gorm.DB) error {
|
||||
for _, item := range v {
|
||||
if id, ok := item["id"].(string); ok {
|
||||
if err := tx.Where("id = ?", id).Updates(item).Error; err != nil {
|
||||
logger.Error("Error in bulk update transaction: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
h.sendError(w, http.StatusInternalServerError, "update_error", "Error in bulk update", err)
|
||||
return
|
||||
}
|
||||
logger.Info("Bulk update completed successfully")
|
||||
h.sendResponse(w, data, nil)
|
||||
}
|
||||
default:
|
||||
logger.Error("Invalid data type for update operation: %T", data)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Delete handler
|
||||
func (h *APIHandler) handleDelete(w http.ResponseWriter, r *http.Request, schema, entity, id string) {
|
||||
logger.Info("Deleting records from %s.%s", schema, entity)
|
||||
query := h.db.Table(fmt.Sprintf("%s.%s", schema, entity))
|
||||
|
||||
if id == "" {
|
||||
logger.Error("Delete operation requires an ID")
|
||||
h.sendError(w, http.StatusBadRequest, "missing_id", "Delete operation requires an ID", nil)
|
||||
return
|
||||
}
|
||||
|
||||
result := query.Delete("id = ?", id)
|
||||
if result.Error != nil {
|
||||
logger.Error("Error deleting record: %v", result.Error)
|
||||
h.sendError(w, http.StatusInternalServerError, "delete_error", "Error deleting record", result.Error)
|
||||
return
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
logger.Warn("No record found to delete with ID: %s", id)
|
||||
h.sendError(w, http.StatusNotFound, "not_found", "Record not found", nil)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("Successfully deleted record with ID: %s", id)
|
||||
h.sendResponse(w, nil, nil)
|
||||
}
|
||||
9
pkg/resolvespec/interfaces.go
Normal file
9
pkg/resolvespec/interfaces.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package resolvespec
|
||||
|
||||
type GormTableNameInterface interface {
|
||||
TableName() string
|
||||
}
|
||||
|
||||
type GormTableSchemaInterface interface {
|
||||
TableSchema() string
|
||||
}
|
||||
131
pkg/resolvespec/meta.go
Normal file
131
pkg/resolvespec/meta.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package resolvespec
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/Warky-Devs/ResolveSpec/pkg/logger"
|
||||
)
|
||||
|
||||
func (h *APIHandler) HandleGet(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
||||
schema := params["schema"]
|
||||
entity := params["entity"]
|
||||
|
||||
logger.Info("Getting metadata for %s.%s", schema, entity)
|
||||
|
||||
// Get model for the entity
|
||||
model, err := h.getModelForEntity(schema, entity)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get model: %v", err)
|
||||
h.sendError(w, http.StatusBadRequest, "invalid_entity", "Invalid entity", err)
|
||||
return
|
||||
}
|
||||
|
||||
modelType := reflect.TypeOf(model)
|
||||
if modelType.Kind() == reflect.Ptr {
|
||||
modelType = modelType.Elem()
|
||||
}
|
||||
|
||||
metadata := TableMetadata{
|
||||
Schema: schema,
|
||||
Table: entity,
|
||||
Columns: make([]Column, 0),
|
||||
Relations: make([]string, 0),
|
||||
}
|
||||
|
||||
// Get field information using reflection
|
||||
for i := 0; i < modelType.NumField(); i++ {
|
||||
field := modelType.Field(i)
|
||||
|
||||
// Skip unexported fields
|
||||
if !field.IsExported() {
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse GORM tags
|
||||
gormTag := field.Tag.Get("gorm")
|
||||
jsonTag := field.Tag.Get("json")
|
||||
|
||||
// Skip if json tag is "-"
|
||||
if jsonTag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get JSON field name
|
||||
jsonName := strings.Split(jsonTag, ",")[0]
|
||||
if jsonName == "" {
|
||||
jsonName = field.Name
|
||||
}
|
||||
|
||||
// Check if it's a relation
|
||||
if field.Type.Kind() == reflect.Slice ||
|
||||
(field.Type.Kind() == reflect.Struct && field.Type.Name() != "Time") {
|
||||
metadata.Relations = append(metadata.Relations, jsonName)
|
||||
continue
|
||||
}
|
||||
|
||||
column := Column{
|
||||
Name: jsonName,
|
||||
Type: getColumnType(field),
|
||||
IsNullable: isNullable(field),
|
||||
IsPrimary: strings.Contains(gormTag, "primaryKey"),
|
||||
IsUnique: strings.Contains(gormTag, "unique") || strings.Contains(gormTag, "uniqueIndex"),
|
||||
HasIndex: strings.Contains(gormTag, "index") || strings.Contains(gormTag, "uniqueIndex"),
|
||||
}
|
||||
|
||||
metadata.Columns = append(metadata.Columns, column)
|
||||
}
|
||||
|
||||
h.sendResponse(w, metadata, nil)
|
||||
}
|
||||
|
||||
func getColumnType(field reflect.StructField) string {
|
||||
// Check GORM type tag first
|
||||
gormTag := field.Tag.Get("gorm")
|
||||
if strings.Contains(gormTag, "type:") {
|
||||
parts := strings.Split(gormTag, "type:")
|
||||
if len(parts) > 1 {
|
||||
typePart := strings.Split(parts[1], ";")[0]
|
||||
return typePart
|
||||
}
|
||||
}
|
||||
|
||||
// Map Go types to SQL types
|
||||
switch field.Type.Kind() {
|
||||
case reflect.String:
|
||||
return "string"
|
||||
case reflect.Int, reflect.Int32:
|
||||
return "integer"
|
||||
case reflect.Int64:
|
||||
return "bigint"
|
||||
case reflect.Float32:
|
||||
return "float"
|
||||
case reflect.Float64:
|
||||
return "double"
|
||||
case reflect.Bool:
|
||||
return "boolean"
|
||||
default:
|
||||
if field.Type.Name() == "Time" {
|
||||
return "timestamp"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func isNullable(field reflect.StructField) bool {
|
||||
// Check if it's a pointer type
|
||||
if field.Type.Kind() == reflect.Ptr {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if it's a null type from sql package
|
||||
typeName := field.Type.Name()
|
||||
if strings.HasPrefix(typeName, "Null") {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check GORM tags
|
||||
gormTag := field.Tag.Get("gorm")
|
||||
return !strings.Contains(gormTag, "not null")
|
||||
}
|
||||
95
pkg/resolvespec/types.go
Normal file
95
pkg/resolvespec/types.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package resolvespec
|
||||
|
||||
type RequestBody struct {
|
||||
Operation string `json:"operation"`
|
||||
Data interface{} `json:"data"`
|
||||
ID *int64 `json:"id"`
|
||||
Options RequestOptions `json:"options"`
|
||||
}
|
||||
|
||||
type RequestOptions struct {
|
||||
Preload []PreloadOption `json:"preload"`
|
||||
Columns []string `json:"columns"`
|
||||
OmitColumns []string `json:"omit_columns"`
|
||||
Filters []FilterOption `json:"filters"`
|
||||
Sort []SortOption `json:"sort"`
|
||||
Limit *int `json:"limit"`
|
||||
Offset *int `json:"offset"`
|
||||
CustomOperators []CustomOperator `json:"customOperators"`
|
||||
ComputedColumns []ComputedColumn `json:"computedColumns"`
|
||||
Parameters []Parameter `json:"parameters"`
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
Sequence *int `json:"sequence"`
|
||||
}
|
||||
|
||||
type PreloadOption struct {
|
||||
Relation string `json:"relation"`
|
||||
Columns []string `json:"columns"`
|
||||
OmitColumns []string `json:"omit_columns"`
|
||||
Filters []FilterOption `json:"filters"`
|
||||
Limit *int `json:"limit"`
|
||||
Offset *int `json:"offset"`
|
||||
}
|
||||
|
||||
type FilterOption struct {
|
||||
Column string `json:"column"`
|
||||
Operator string `json:"operator"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
type SortOption struct {
|
||||
Column string `json:"column"`
|
||||
Direction string `json:"direction"`
|
||||
}
|
||||
|
||||
type CustomOperator struct {
|
||||
Name string `json:"name"`
|
||||
SQL string `json:"sql"`
|
||||
}
|
||||
|
||||
type ComputedColumn struct {
|
||||
Name string `json:"name"`
|
||||
Expression string `json:"expression"`
|
||||
}
|
||||
|
||||
// Response structures
|
||||
type Response struct {
|
||||
Success bool `json:"success"`
|
||||
Data interface{} `json:"data"`
|
||||
Metadata *Metadata `json:"metadata,omitempty"`
|
||||
Error *APIError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
Total int64 `json:"total"`
|
||||
Filtered int64 `json:"filtered"`
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
}
|
||||
|
||||
type APIError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Details interface{} `json:"details,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
}
|
||||
|
||||
type Column struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
IsNullable bool `json:"is_nullable"`
|
||||
IsPrimary bool `json:"is_primary"`
|
||||
IsUnique bool `json:"is_unique"`
|
||||
HasIndex bool `json:"has_index"`
|
||||
}
|
||||
|
||||
type TableMetadata struct {
|
||||
Schema string `json:"schema"`
|
||||
Table string `json:"table"`
|
||||
Columns []Column `json:"columns"`
|
||||
Relations []string `json:"relations"`
|
||||
}
|
||||
67
pkg/resolvespec/utils.go
Normal file
67
pkg/resolvespec/utils.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package resolvespec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Warky-Devs/ResolveSpec/pkg/logger"
|
||||
"github.com/Warky-Devs/ResolveSpec/pkg/models"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func handleUpdateResult(w http.ResponseWriter, h *APIHandler, result *gorm.DB, data interface{}) {
|
||||
if result.Error != nil {
|
||||
logger.Error("Update error: %v", result.Error)
|
||||
h.sendError(w, http.StatusInternalServerError, "update_error", "Error updating record(s)", result.Error)
|
||||
return
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
logger.Warn("No records found to update")
|
||||
h.sendError(w, http.StatusNotFound, "not_found", "No records found to update", nil)
|
||||
return
|
||||
}
|
||||
logger.Info("Successfully updated %d records", result.RowsAffected)
|
||||
h.sendResponse(w, data, nil)
|
||||
}
|
||||
|
||||
func optionalInt(ptr *int) int {
|
||||
if ptr == nil {
|
||||
return 0
|
||||
}
|
||||
return *ptr
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
func (h *APIHandler) applyFilter(query *gorm.DB, filter FilterOption) *gorm.DB {
|
||||
switch filter.Operator {
|
||||
case "eq":
|
||||
return query.Where(fmt.Sprintf("%s = ?", filter.Column), filter.Value)
|
||||
case "neq":
|
||||
return query.Where(fmt.Sprintf("%s != ?", filter.Column), filter.Value)
|
||||
case "gt":
|
||||
return query.Where(fmt.Sprintf("%s > ?", filter.Column), filter.Value)
|
||||
case "gte":
|
||||
return query.Where(fmt.Sprintf("%s >= ?", filter.Column), filter.Value)
|
||||
case "lt":
|
||||
return query.Where(fmt.Sprintf("%s < ?", filter.Column), filter.Value)
|
||||
case "lte":
|
||||
return query.Where(fmt.Sprintf("%s <= ?", filter.Column), filter.Value)
|
||||
case "like":
|
||||
return query.Where(fmt.Sprintf("%s LIKE ?", filter.Column), filter.Value)
|
||||
case "ilike":
|
||||
return query.Where(fmt.Sprintf("%s ILIKE ?", filter.Column), filter.Value)
|
||||
case "in":
|
||||
return query.Where(fmt.Sprintf("%s IN (?)", filter.Column), filter.Value)
|
||||
default:
|
||||
return query
|
||||
}
|
||||
}
|
||||
|
||||
func (h *APIHandler) getModelForEntity(schema, name string) (interface{}, error) {
|
||||
model, err := models.GetModelByName(fmt.Sprintf("%s.%s", schema, name))
|
||||
|
||||
if err != nil {
|
||||
model, err = models.GetModelByName(name)
|
||||
}
|
||||
return model, err
|
||||
}
|
||||
Reference in New Issue
Block a user