After the study, I got sidetracked on other projects. The data lived on the server for a long time, until I got a notification that the server was being decommissioned. The most valuable thing for a researcher may well be the data, so I quickly wrote a SQL dump out and put it in my archives.
"Hey, maybe I don't have to download the JAR and put it in the lib directory. Maybe I can try this whole 'automatic dependency resolution' thing."
So I did the following in my BuildConfig.groovy
repositories {
inherits true // Whether to inherit repository definitions from plugins
grailsPlugins()
grailsHome()
grailsCentral()
// uncomment these to enable remote dependency resolution from public Maven repositories
mavenCentral()
//mavenLocal()
//mavenRepo "http://snapshots.repository.codehaus.org"
//mavenRepo "http://repository.codehaus.org"
mavenRepo "http://download.java.net/maven/2/"
//mavenRepo "http://repository.jboss.com/maven2/"
}
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.16'
runtime 'net.sf.opencsv:opencsv:2.3'
}
My tummy bumbled a little bit as my IDE kept yelling at me that my classes were undefined. As much fun as dynamic languages are, there's a comfort to not having those red squiggles telling you you fail at basic namespace resolution...but I resisted the urge to revert to the old school way. I ran the app...Happily, it did in fact download the dependency at runtime!
With the dependency resolved (hopefully), I turned my attention to loading the data in Bootstrap.groovy. Reading the bit on JavaBean binding gave me an idea...but I remained skeptical. Could it be so easy? On first run, the ColumnMappingStrategy didn't work. The Grails error log told me that the 2 of the values of my instance class that I expected to be filled were null. But 1 was not.
class Institution {
String name
String carnegieClassification
String schedule
static constraints = {
name blank:false, unique:true
carnegieClassification nullable:true
schedule inList:(["semester","quarter"])
}
}
universityName carnegieClassification schedule
Brown University RU/VH: Research Universities (very high research activity) semester
Ah, the carnegieClassification was binding correctly, but the other two fields were not because of mismatch in the named columns. Would the JavaBean thing fail utterly?
I minor edit later...
def createInstitutions() {
CSVReader reader = new CSVReader(new FileReader("universities.csv"));
String [] nextLine;
HeaderColumnNameTranslateMappingStrategy strat = new HeaderColumnNameTranslateMappingStrategy();
strat.setType(Institution.class);
strat.setColumnMapping(["universityName":"name", "carnegieClassification":"carnegieClassification", "schedule":"schedule"]);
CsvToBean csv = new CsvToBean();
List list = csv.parse(strat, reader);
list.each {
def already = Institution.findByName(it.name) ?: it.save(failOnError:true)
}
}
Just like that, part of the old data loaded and a roadmap found for the rest of it. No fuss, no muss, in less than 10 minutes. Wow.
Less than 3, Grails. Less than 3.
No comments:
Post a Comment