Closed hoxu closed 3 years ago
There isn't any support for property substitution at the moment, but I'd be open to adding that as a feature.
I just added support on a branch here. Could you take a look to see if that matches what you were thinking, and if it looks good I could push out a new version with the feature.
That was fast, thanks!
I read the README.md
diff. I think taking properties only from the environment variables is not flexible enough, although I do think either environment or System properties are one good way to allow providing these.
For comparison, Liquibase allows:
- Passed as a attribute to your Liquibase runner. See the Ant, Maven, or Servlet Listener documentation for more information on how to pass them.
- As a JVM system property.
- As an environment variable.
- As a CLI attribute if executed from the command line.
- In the liquibase.properties file if used or executed from the command line. See the Creating and configuring a liquibase.properties file for more information.
- In the parameters block (property element of the DATABASECHANGELOG table itself.
Flyway:
- Via environment variables. FLYWAY_PLACEHOLDERS_MYPLACEHOLDER=value
- Via configuration parameters. flyway.placeholders.myplaceholder=value
- Via the api. .placeholders(Map.of("myplaceholder", "value"))
The usual usecase with property substitution that I have seen is having things like
GRANT SELECT,INSERT ON example_table TO ${database.user};
Then you can run the same migrations for different users.
For production providing this as an environment variable or a JVM system property is fine.
For development being able to run the migrations multiple times with different properties is nice (eg. separate development and integration test databases), so only ENV variables are not enough.
If you want to keep things really simple with Migratus, I think the best would be to just allow providing a map, like so:
:custom-properties {:database {:user "username"}}
Now ${database.user}
would be substituted with username
.
This way if people want to dig the properties from environment, JVM properties, or where ever, they can write explicit code.
In any case, please allow providing an explicit substitution map!
Thanks for the feedback, I added the option to specify :custom-properties
as you suggested:
custom env property names will now be specified using the :custom-env-properties
key and a map of custom properties can be assigned to the :custom-properties
key:
{:store :database
:inject-properties? true
:custom-env-properties ["database.table"]
:custom-properties {:database {:user "bob"}}}
The database.table
key will replace ${database.table}
in the template with the value found in the environment, while {:database {:user "bob"}}
will replace ${database.user}
with "bob"
.
GRANT SELECT,INSERT ON ${database.table} TO ${database.user};
let me know if that looks good.
Looks promising!
Is there a snapshot I could test before merging?
Easiest if you just build locally by running lein install
from the branch, that will install it in your local maven repo at ~/.m2/repository/migratus/migratus/1.3.3
. And then projects using it will pull it from there.
I tested this and glanced through the code changes. Some comments:
inject-properties?
necessary? I think it would be enough to just check for presence of :custom-env-properties
or :custom-properties
, and do the substitutions if either exists. I actually forgot to set inject-properties?
and spent some time debugging what's wrong.Otherwise looking good and does what I would expect, great work!
Yeah that's a good point about inject-properties?
being superfulous, I updated the config to look as follows:
:properties
{:custom-env-properties [...]
:custom-properties {...}}
And a good idea with the warning for any unmatched properties, agree that will help with the typos. I've updated the code that injects the properties to run a regex after substitution and generate warnings.
Generally, agree with the formatting sentiment but what's done is done. :)
Let me know if the latest looks good.
Reviewed changes and tested the warning, too.
One last nitpick, about properties
being repeated in the keys:
I would just rename the keys like so:
:properties
{:env [...]
:map {...}}
Sounds good, just pushed an update.
Looks good to me!
Excellent, just pushed out 1.3.4
to Clojars with the feature. 🎉
Thank you!
Is there anything similar to Liquibase's property substitution and Flyway's placeholders?