Skip to content

Instantly share code, notes, and snippets.

@skhatri
Created April 28, 2012 06:51
Show Gist options
  • Save skhatri/2516634 to your computer and use it in GitHub Desktop.
Save skhatri/2516634 to your computer and use it in GitHub Desktop.
Reverse Engineer MySQL Dump to Grails Domain Class
/**
1. extract using
mysqldump -udev -p -d --xml movies > movies.xml
2. run this
*/
class DBRev {
private String res = 'movies.xml'
private String dir = 'grails-app/domain'
private String packageName = 'com.mycompany.app.domain'
private File packageDir
public DBRev() {
new File(dir).mkdirs()
String packagePath = packageName.replaceAll('\\.', '/')
packageDir = new File(dir, packagePath)
packageDir.mkdirs()
}
private void db() {
def xml = new XmlSlurper().parse(new File(res))
println "Next set of commands to run\n"
xml.database.children().each {tbl->
def obj = new Entity(packageName: packageName)
String name = tbl.'@name'
def val = createClass(name)
obj.name = val
def fields = tbl.children().findAll{it.name() =='field'}
def keys = tbl.children().findAll {it.name() == 'key'}
doWithFields(obj, fields)
doWithKeys(obj, keys)
//println obj
new File(packageDir, "${obj.name}.groovy").write(obj.toString())
println "grails create-scaffold-controller ${packageName}.${obj.name}"
}
println "grails run-app"
}
private String createClass(name) {
String[] parts = name.split('_')
parts.collect ({
it.substring(0, 1).toUpperCase() + it.substring(1)
}).join('')
}
private String createField(name) {
String className = createClass(name)
className.substring(0, 1).toLowerCase() + className.substring(1)
}
private String getJavaTypeName(String sqlTypeText) {
if (sqlTypeText.contains('int')) {
return 'Long'
} else if (sqlTypeText.contains('decimal')) {
return 'BigDecimal'
} else if (sqlTypeText.contains('time') || sqlTypeText.contains('date')) {
return 'Date'
}
return 'String'
}
private doWithKeys(obj, fields) {
fields.each {field->
if (field.'@Key_name'.text() != 'PRIMARY') {
def fex = new Field()
String keyColumn = field.'@Column_name'.text()
fex.name = createField(keyColumn)
fex.type = createClass(keyColumn)
fex.isref = true
obj.keys.add(fex)
}
}
}
private doWithFields(obj, fields) {
fields.each {field->
def fex = new Field()
fex.name = createField(field.'@Field'.text())
fex.type = getJavaTypeName(field.'@Type'.text())
fex.isrequired = (field.'@Null'.text() == 'NO')
fex.isref = (field.'@Key'.text() == 'MUL')
obj.fields.add(fex)
}
}
class Entity {
String packageName
String name
def fields = []
def keys = []
private getKey(field) {
return keys.find {it.name == field.name}
}
private String getConstraints() {
StringBuilder constraintsBuilder = new StringBuilder('\n static constraints = {\n')
fields.findAll({it.name != 'id'}).each {field->
constraintsBuilder.append(' ').append(field.name).append(' ').append(field.type =='String'?'blank':'nullable').append(':')
.append(!field.isrequired).append('\n')
}
return constraintsBuilder.append(' }').toString()
}
private String getParentRef() {
StringBuilder parentRefBuilder = new StringBuilder('\n static belongsTo = [')
String refList = fields.findAll({it.isref}).collect ({field->
def key = getKey(field)
"${key.name}:${key.type}"
}).join(', ')
return refList.empty?'':parentRefBuilder.append(refList).append(']').toString()
}
String toString() {
StringBuilder entityStr = new StringBuilder('package ').append(packageName)
.append('\n\n')
.append('public class ').append(name).append(' {\n')
entityStr.append(getConstraints()).append('\n')
fields.each {field ->
def key = getKey(field)
entityStr.append(' ').append(key?:field).append('\n')
}
entityStr.append(getParentRef()).append('\n')
return entityStr.append('}').toString()
}
}
class Field {
String name
String type
boolean isrequired
boolean isref
String toString() {
return "${type} ${name}"
}
}
public static void main(String[] args) {
new DBRev().db()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment