All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gorm.tools.mango.jpql.ComboKeyExistsQuery.groovy Maven / Gradle / Ivy

There is a newer version: 7.3.74
Show newest version
/*
* Copyright 2022 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.jpql

import groovy.transform.CompileStatic
import groovy.transform.MapConstructor
import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy

import org.grails.datastore.gorm.GormEnhancer
import org.grails.orm.hibernate.HibernateGormStaticApi
import org.hibernate.Session
import org.hibernate.query.Query

/**
 * Simple performant way to check if a Composite Key value combination exists in the db for an entity.
 * see the single field KeyExistsQuery for more explanation
 */
@SuppressWarnings(['VariableName'])
@Builder(builderStrategy= SimpleStrategy, prefix="")
@MapConstructor
@CompileStatic
class ComboKeyExistsQuery {
    Class entityClass

    /** property/column to query */
    List keyNames

    // org.hibernate.query.Query query
    HibernateGormStaticApi staticApi

    ComboKeyExistsQuery(Class entityClass) {
        this.entityClass = entityClass
        staticApi = (HibernateGormStaticApi) GormEnhancer.findStaticApi(entityClass)
    }

    static  ComboKeyExistsQuery of(Class entityClass) {
        def inst = new ComboKeyExistsQuery(entityClass)
        inst.staticApi = (HibernateGormStaticApi) GormEnhancer.findStaticApi(entityClass)
        return inst
    }

    boolean exists(Map params){
        //key set should match
        if(params.keySet().toList() != keyNames)
            throw new IllegalArgumentException("params mismatch, params keys dont match the keyNames")

        //NOTE: this is not sql, its hql so entityClass.name is the domain name that hql translates to the sql.
        String queryString = buildQueryString(params)

        return (Boolean) staticApi.hibernateTemplate.execute { Session session ->
            Query q = (Query) session.createQuery(queryString)
            q.setReadOnly(true).setMaxResults(1)

            params.each{ key, val ->
                String valKey = paramValName(key)
                q.setParameter(valKey, val)
            }

            return q.list().size() == 1
        }
    }

    String buildQueryString(Map params){
        //NOTE: this is not sql, its hql so entityClass.name is the domain name that hql translates to the sql.
        String queryString = "select 1 from ${entityClass.name} where"
        String whereClause = ""
        for(String keyName : keyNames){
            //if no whereClause then no AND
            String AND = whereClause ? "AND" : ""
            whereClause = "$whereClause $AND $keyName = :${paramValName(keyName)}"
        }
        queryString = "$queryString ${whereClause.trim()}"
        return queryString
    }

    protected String paramValName(String keyName){
        return "${keyName.replace(".", "_")}Val"
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy