Sunday, October 09, 2016

The Power of Grails Metadata is there when you need it . . .

Grails underpins the frameworks and technologies like Spring and Hibernate it was built on top of. With the concept of Convention-over-ConfigurationSensible defaults, GORM and many Architectural & Design decisions and solutions to known issues taken into the framework, it multiplies developer's productivity which can otherwise only be imaginable.

In Java space, as frameworks keep getting better and better over years, they take developer to higher levels of coding with no need to deal with low-level details. It's only a myth and not a fact if one argues "frameworks hide details". A good framework does not do that and gives full access to underlying technologies. Grails is one of such.

Recently I had a need to find out the complete list of database Tables and Columns that are mapped to Boolean/boolean domain object properties in a Grails 2.2.1 project. There are two possible ways this can be achieved in a Grails project. 1) By examining metadata of the database 2) By examining metadata of the Grails application execution environment itself. The second option: Grails way, seemed more reliable to me. I started looking into Grails API and could get the details pretty easily from the metadata it exposes.

Following is the code-snippet with parts of interest highlighted:

/** * boolean-columns-finder.groovy * Grails groovy script which finds persistable Boolean/boolean properties of all domain * objects and finds corresponding database mappings of columns and tables. Generates a * JSON file that contains list of Boolean/boolean column-names for each table-name * mapped to a domain object that contains Boolean/boolean properties. * * @author Giri Pottepalem */ import groovy.json.JsonBuilder def sessionFactory = ctx.getBean("sessionFactory") Map tablesBooleanColumnsMap = [:] //get table names and column names of all domain objects that have Boolean/boolean properties grailsApplication.getArtefacts("Domain").each { domainObject -> def dbTableName = sessionFactory.getClassMetadata(domainObject.clazz).tableName def booleanProperties = domainObject.properties.findAll { it.isPersistent() && it.type.name.contains('oolean') }*.name if (booleanProperties) { def dbBooleanColumnNames = booleanProperties.collect { sessionFactory .getClassMetadata(domainObject.clazz) .propertyMapping .getColumnNames(it) }.flatten() tablesBooleanColumnsMap << [(dbTableName): dbBooleanColumnNames] } } //write the map built to a file as JSON def jsonFile = "${grails.util.Metadata.current.getApplicationName()}TablesBooleanColumns.json" new File(jsonFile).write( new JsonBuilder(tablesBooleanColumnsMap).toPrettyString() ) println "Successfully extracted mappings for Boolean/boolean properties found" + " and created a JSON file: $jsonFile"

Note

Grails makes the main interface to a running application available through grailsApplication variable and it's context through ctx variable. This script can be run from grails console and also from the command line.

To run from command line, run it from the project home directory (assuming that the script is located under src/groovy dir of the grails project) like:
grails run-script src/groovy/boolean-columns-finder.groovy

Summary

Grails puts you on the power steering seat. It only underpins all of the technologies & frameworks it was built on. It does not hide any details from you. When you really need low-level details, you have all available to you.

References

No comments:

Post a Comment