Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2019 Yak.Works - Licensed under the Apache License, Version 2.0 (the "License")
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
package gorm.tools.mango
import java.util.UUID
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.codehaus.groovy.runtime.InvokerHelper
import org.grails.datastore.mapping.model.PersistentProperty
import org.grails.datastore.mapping.model.types.Association
import org.grails.datastore.mapping.query.Query
import org.grails.datastore.mapping.query.api.QueryableCriteria
import org.springframework.beans.factory.annotation.Autowired
import gorm.tools.databinding.EntityMapBinder
import gorm.tools.mango.api.QueryArgs
import grails.gorm.DetachedCriteria
import yakworks.commons.lang.ClassUtils
import yakworks.commons.lang.EnumUtils
import yakworks.commons.model.IdEnum
import yakworks.gorm.api.IncludesConfig
import yakworks.gorm.api.IncludesKey
import static gorm.tools.mango.MangoOps.CompareOp
import static gorm.tools.mango.MangoOps.ExistOp
import static gorm.tools.mango.MangoOps.JunctionOp
import static gorm.tools.mango.MangoOps.OverrideOp
import static gorm.tools.mango.MangoOps.PropertyOp
import static gorm.tools.mango.MangoOps.QSEARCH
import static gorm.tools.mango.MangoOps.SORT
/**
* the main builder to turn Mango QL Maps or json into DetachedCriteria for Gorm
*
* @author Joshua Burnett (@basejump)
* @since 6.1
*/
@SuppressWarnings(['FieldName', 'ConfusingMethodName']) //codenarc doesn't like the names we use to make this builder clean
@CompileStatic
@Slf4j
class MangoBuilder {
@Autowired IncludesConfig includesConfig
public MangoDetachedCriteria build(Class clazz, Map map, @DelegatesTo(MangoDetachedCriteria) Closure callable = null) {
MangoDetachedCriteria detachedCriteria = new MangoDetachedCriteria(clazz)
return build(detachedCriteria, map, callable)
}
public MangoDetachedCriteria build(MangoDetachedCriteria criteria, Map map,
@DelegatesTo(MangoDetachedCriteria) Closure callable = null) {
MangoDetachedCriteria newCriteria = cloneCriteria(criteria)
def tidyMap = MangoTidyMap.tidy(map)
applyMapOrList(newCriteria, tidyMap)
if (callable) {
final Closure clonedClosure = (Closure) callable.clone()
clonedClosure.setResolveStrategy(Closure.DELEGATE_FIRST)
newCriteria.with(clonedClosure)
}
return newCriteria
}
@CompileDynamic //dynamic so it can access the protected criteria.clone
static MangoDetachedCriteria cloneCriteria(DetachedCriteria criteria) {
(MangoDetachedCriteria)criteria.clone()
}
public MangoDetachedCriteria buildWithQueryArgs(Class clazz, QueryArgs qargs, @DelegatesTo(MangoDetachedCriteria) Closure callable = null) {
MangoDetachedCriteria mangoCriteria = new MangoDetachedCriteria(clazz)
Map criteria = qargs.buildCriteria()
//will be copy if sort exists
def tidyMap = MangoTidyMap.tidy(criteria)
applyMapOrList(mangoCriteria, tidyMap)
if (callable) {
final Closure clonedClosure = (Closure) callable.clone()
clonedClosure.setResolveStrategy(Closure.DELEGATE_FIRST)
mangoCriteria.with(clonedClosure)
}
//$sort was probably on the criteria as its added in QueryArgs?? but if not then use the property
if(qargs.sort && !criteria.containsKey(SORT)){
order(mangoCriteria, qargs.sort)
}
if(qargs.projections){
applyProjections(mangoCriteria, qargs.projections)
}
return mangoCriteria
}
/**
* calls list for the criteria, if criteria has projections then calls mapList
* which uses JpqlQueryBuilder
*/
static List list(MangoDetachedCriteria criteria, Map args) {
List resList
if(criteria.projections){
resList = criteria.mapList(args)
} else {
//return standard list
resList = criteria.list(args)
}
return resList
}
/**
* Apply projections from map in form [key:type] where type is sum, group, count, min, max or avg
*
* @param criteria the criteria to apply the project
* @param projs the map of projections to apply
*/
void applyProjections(MangoDetachedCriteria criteria, Map projs) {
//assume its a map
(projs as Map).each { String k, String v ->
if(v == 'sum'){
criteria.sum(k)
} else if (v == 'group'){
criteria.groupBy(k)
} else if (v == 'avg'){
criteria.avg(k)
} else if (v == 'count'){
criteria.countDistinct(k)
} else if (v == 'min'){
criteria.min(k)
} else if (v == 'max'){
criteria.max(k)
}
}
}
void applyMapOrList(DetachedCriteria criteria, Object mapOrList) {
if (mapOrList instanceof Map) {
applyMap(criteria, mapOrList)
} else if (mapOrList instanceof List