-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
question: how to refactor? #15
Comments
I'm not entirely sure what you're asking, but I think what you are looking for is a way to make sure all tables you create have the same standard columns. Something like this: changeSet(id: 'myId', author: 'me') {
createStandardTable(tableName: 'my_table') {
column(name: 'code', type: 'varchar(50)
}
} The magic would have to be in the createStandardTable method. You could define a method like this: def createStandardTable(map, closure) {
createTable(map) {
column(name: 'id', type: int)
colum(name: 'create_date', type: 'datetime')
closure.call
}
} I'm not sure this would actually do the job, but I think this would be on the right track. I think the method would need to be defined inside the As for reuse, this solution would work great within a project, but not so well across projects. To do that, you'd probably need to define a custom change and include it in your classpath. In your case, you could probably extend the Liquibase I hope this helps point you in a good direction. |
I can't define method inside databaseChangeLog :(. Defining it as a clojure didn't work also. |
You should be able to put any legal Groovy code a closure. I guess defining another method is not legal in a closure. :-( It makes sense now that I think about it, but it means we'll need to come up with another way. When I inherited the project, there was a comment in the code that we needed to find a way to support custom changes that take a closure. It looks like that is something I should take another look at. I'm not sure when I'll get time to look at this, but I'll keep you posted. |
Thanks! Btw I'm giving a small presentation about liquibase and it's groovy DSL today :)! Should I close this issue? |
I've been struggling with this issue too. The benefits of Groovy DSL over XML, for me anyway, is that I can better standardize the management of various database structures. For example, I can add a set of bookkeeping columns to a table (e.g. versioning and auditing), or use a naming strategy for FOREIGN KEYs (e.g. FK_TABLE1_COL1_...COLN_TABLE2_COL1...COLM). The list goes on. I accomplished a bit of this with XML entities, but there is quite a bit they cannot handle (e.g. attributes). My current strategy is to make all utility closures requiring Map parameters, with a "delegate" passed in. If not, I raise a nice error saying to add it on the call. I then set the delegate, so the DSL usage inside the closure works properly. The general structure is something like this... def autoSetDelegate(closure) {
// Utility to setup a closure to chain a delegate found in a provided Map, and give good error messages
}
def addColumnWithForeignKey = autoSetDelegate { params ->
// This is a custom closure with Groovy DSL statements, delegate is assumed set properly
}
databaseChangeLog {
createTable {
addColumnWithForeignKey(delegate: delegate, ...) // Call to custom closure, have to deal with delegate
}
...
createTable {
addColumnWithForeignKey(delegate: delegate, ...) // Call to custom closure
}
} It would be nice to not have to specify the delegate everywhere. Perhaps, if I could dynamically bind additional closures onto the delegates used by the DSL, they would then be usable throughout the DSL. Not to muddy the waters, but since we're talking about delegates, it would also be nice to access information from the enclosing DSL blocks. For example, inside the body of a |
You can create templates in most modern IDEs. The solution would be to create a 'createTable' template that you can easily insert with a shortcut. Here's an example for Intellij's Live Templates that can do what you want (in Groovy DSL, you can make something similar in XML as well):
I didn't add all of your fields, but you get the idea. You also mentioned that you don't want to be copy-pasting that piece of config everywhere, but I think it keeps things cleaner that way. |
@jrsall92 sorry, but i disagree. Here is just some thoughts about such template abuse:
Well, I don't think templates gonna solve all that, especially problems that @ryan-gustafson mentioned above. P.S. I mean no offence by this comment |
You can't define a method inside a changelog, but you can still define custom methods like this: org.liquibase.groovy.delegate.DatabaseChangeLogDelegate.metaClass.createStandardTable = { properties ->
// whatever code you need here
}
databaseChangeLog {
// standard Liquibase stuff here, and you can use your new method, for example...
createStandardTable(tableName: 'myTable', schemaName: "mySchema")
} The key is that it needs to be declared outside the databaseChangeLog section. In my case, I put it in my In my case, I wanted to pass a map of properties to my new method, but you could pass anything you wanted, including closures, and your method can do just about anything you'd need. Using the Groovy DSL's source code as a guide, you can probably find a way to make a |
The problem I'm trying to solve is the following:
How can I factor this peace of "code" for reuse? The only thing I came up with is to define a closure and then call it like this:
But this isn't very ellegant :(
The text was updated successfully, but these errors were encountered: