PromucFlow_constructor/app/server/services/query.go

74 lines
2.2 KiB
Go

package services
import (
"fmt"
"log"
"github.com/cbroglie/mustache"
"github.com/jinzhu/gorm"
"gitlab.com/mobtools/internal-tools-server/models"
"gitlab.com/mobtools/internal-tools-server/storage"
)
// ExecuteQuery runs a custom SQL query on the client database
func ExecuteQuery(queryBody models.ExecQuery) ([]map[string]interface{}, error) {
datastore := storage.StorageEngine.GetDatastore()
queryDAO := &models.Query{}
if err := datastore.Where("name = ?", queryBody.Name).First(queryDAO).Error; gorm.IsRecordNotFoundError(err) {
return nil, fmt.Errorf("Invalid queryName: %s provided", queryBody.Name)
}
//TODO: Move to a factory method for better readability
if queryDAO.QueryType == "sql" {
// Get the actual query from the DB
queryStr := queryDAO.Executable
// Extract the key-value pairs from the request
templateKeyValue := make(map[string]string)
if len(queryBody.Params.QueryParams) > 0 {
for _, elem := range queryBody.Params.QueryParams {
templateKeyValue[elem.Key] = elem.Value
}
}
// Substitute it in the template string
log.Printf("Going to parse string: %s", queryStr)
renderedStr, err := mustache.Render(queryStr, templateKeyValue)
if err != nil {
log.Printf("Error while parsing the mustache template. %s", err.Error())
return nil, err
}
mapArray, err := storage.StorageEngine.ExecuteQuery(renderedStr)
if err != nil {
return nil, err
}
return mapArray, nil
}
return nil, fmt.Errorf("QueryType: %s not supported", queryDAO.QueryType)
}
// CreateQuery creates a new query that can be executed by name at runtime
func CreateQuery(queryBody models.Query) (models.Query, error) {
datastore := storage.StorageEngine.GetDatastore()
if err := datastore.Create(&queryBody).Error; err != nil {
return models.Query{}, err
}
return queryBody, nil
}
// UpdateQuery updates an existing query in the database
func UpdateQuery(query models.Query) (models.Query, error) {
datastore := storage.StorageEngine.GetDatastore()
// Update only the non-nil values in the struct
datastore.Model(&query).Updates(query)
// Select the updated record to return back to the client
datastore.First(&query)
return query, nil
}