Reputation: 125
In the project I'm working on (in Grails 2.5.4/Hibernate 4.3) I have a bunch of different classes, using a few different dataSources. I need to determine whether two given Class objects use the same dataSource. What I would like to do is something like:
Boolean doDataSourcesMatch(Class a, Class b)
{
return a.mapping.datasource == b.mapping.datasource
}
But of course that doesn't work since a.mapping
is a closure. Does anyone know how to access the dataSource used by a class? I don't need to know any of the properties of the connection, just whether queries on the two classes will use the same connection.
Many thanks!
Upvotes: 1
Views: 1040
Reputation: 8587
Although none of these spell anything concrete out, they may help:
I haven't found anything specific, but this is all rather strange. I mean you already know and I presume this is some dynamic query otherwise you coding it would know what to query together etc.
Anyhow as a workaround, unsure if it can be since it depends on how many domainClasses we are talking about, and if this is something you have already put in place or thinking of writing up i.e nothing written in either case if you could add your own getter to all the domain classes in question
//
static String getDataSrc() {
return 'data_source_a'
}
//or
static boolean canQuery() {
return true/false
}
You could just check from anywhere something like this:
boolean canQuery = UserAttributes.canQuery()
String currentDataSource = UserAttributes.dataSrc
Since they are static methods, no instantiation is required. This means if you have
userObject(1) you don't need to do:
User user = User.get(1)
if (user.canQuery()) {
// this is ok
}
You can just call out the method directly from anywhere By referencing the upperCase class name and its method.
String currentDataSource = UserAttributes.dataSrc
//Where this is exactly the same as above
String currentDataSource = UserAttributes.getDataSrc()
E2A: The answer is:
import org.grails.orm.hibernate.cfg.GrailsDomainBinder
class TestController {
//either this method
def binder = new org.grails.orm.hibernate.cfg.GrailsDomainBinder().getMapping(Photos.class)
println "binder : ${binder.table.name}"
println "b: ${binder.datasources}"
//Or this
def dc=GrailsDomainBinder.getMapping(Photos.class)
println "-dc is ${dc}"
println "${dc.datasources}"
}
dc.datasources
is a list so you need to compare lists.
Of course silly me, if you are querying something like in HQL where you are giving dynamic table names ${tableA} ${tableB}
You will need to access actual domain class to be able to call GrailsDomainBinder
So something like: def domainClass = grailsApplication.getDomainClass(domain).clazz
would give you your actual domainClass for a given tableName. But your domain would have to be a fully qualified packaged name so that will cause you issues again.
If you querying com.domain.users.tableA
and com.domain.info.tableB
So You could instead use If outside of service/controller):
def domainClass=Holders.grailsApplication?.domainClasses?.find { it.clazz.simpleName == tableName }?.clazz
or without Holders if you are declaring grailsApplication in controller service:
def domainClass=grailsApplication?.domainClasses?.find { it.clazz.simpleName == tableName }?.clazz
Upvotes: 2