Skip to content
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

script based FileMigrationLoader #112

Open
chb0github opened this issue Jan 1, 2018 · 16 comments
Open

script based FileMigrationLoader #112

chb0github opened this issue Jan 1, 2018 · 16 comments

Comments

@chb0github
Copy link
Contributor

The MigrationLoader and the FileMigrationLoaderFactory make things really flexible. But, I would like to propose another implementation that will really open up mybatis to non-java developers and allow for a light-touch

Some background:

The situation I am trying to address requires a custom MigrationLoader. And, it seems to be working the way I would like it to be. But, let's consider what I will need to do to take advantage of it

  1. Create a java project: (pom.xml, directory structures, etc.) because I have to pull in the mybatis interfaces
  2. Build a jar
  3. Release it to an artifact repository
  4. Deploy it. Which, in the case of migrations, means I would have to put it in the drivers directory since I know this will get picked up on the class path. Should I create a custom migrations script to check to see if it has the latest migration loader I wrote before running and download it if needed (including getting around any security issues I might encounter while checking with the artifact repo)? Or, should I just check in the jar into the migration project under drivers and update as needed?

The question thus arises: Where should I put this Java project that consists entirely of 2 java files and 1 meta file?

Should I:

  1. Create a new repo internally to manage it (and a build and release process)
  2. Create maven/java directory structures in the current repo containing nothing but sql scripts meant for migrations? (Which is only really going to be used by DBAs).

Option 1 is really a heavy weight process to get about 40 lines of code in use
Option 2 is bound to really confuse people who are totally unfamiliar with java.

It would really open up migrations to non-java developers (or java developers where a heavy touch process is not desired). We could use the existing scripting configuration/functionality.

I am willing to make the changes and make sure they are backward compatible. I would just like to donate it to the community because I think it would allow for a very light foot-print when customizing and because it would be a stand-out feature from all the other migration tools.

@harawata
Copy link
Member

harawata commented Jan 1, 2018

Thank you for the idea, @chb0github !
I thought about it, but it 1) requires another section in the documentation and 2) complicates the implementation more or less, so I think the current implementation is good enough for a first release.
Let's keep this ticket open and see if it gets other users interests before you start working on it.

To all,
Please use the 'reaction' feature to vote up instead of a '+1' comment.

@chb0github
Copy link
Contributor Author

chb0github commented Jan 2, 2018

@harawata

  1. Documentation: If you can point me to the docs that need updating I will gladly do it
  2. This I don't understand at all. It's an entirely new and independent implementation. How could it complicate anything if it's independent?

Your reply also didn't address any of my points:

  1. Heavy weight build process.
  2. Supporting scripts opens it to non-java devs!

@h3adache
Copy link
Member

h3adache commented Jan 2, 2018

What do you achieve from having this in migrations core vs just adding it as your own ScriptBasedMigrationLoader other than having to be supported in migration core? I can think of a few migration loaders that might be needed (File which is currently there, Directory based one which has been requested twice that I counted, a Jar based on that I use in my own personal development and the java based one). A script based one is just another of those vs a consolidation and simplification of the process of migration loading.

I'm never in favor of complicating especially when it's just to support one off style processes.

@chb0github
Copy link
Contributor Author

I am not working with a Java-based migration project. If I have to implement a FileMigrationLoader then I need to take my non-java project and java-ify it. See above for details.

This approach actually would allow migrations to essentially end the one-off requests. Migrations greatest features are it's commendable flexibility; it doesn't get any better than this.

I think the part that seems to be missing is that: Not all projects using migrations are java based and opening it up to not requiring Java dev skills is really unique and gives migrations an edge against the competition. Frankly, it's a killer feature IMO that can be implemented fairly straightforwardly.

I am a seasoned vet - I'm not proposing some hack and of course, code review it. If it's a matter of support, then I will continue to support it even after release. Though again, it's going to be a pretty easy implementation so I don't imagine there should be any issues.

I am trying to be a positive contributor and I think this is a feature that will generate many stars. Thanks for considering.

@hibaymj
Copy link

hibaymj commented Jan 2, 2018

@h3adache I am having trouble seeing where this is 'one-off', when you acknowledge there are not only a few people asking for similar features, but offering to have their implementations form the foundation of the features themselves.

This feature addresses a legitimate pain with the use of mybatis, namely it needs to be included within a Java based project. The functionality of the tool is excellent, and the applicability of the script based non-annotated invocation of the functionality could be very wide within the software development field.

The benefit to describing rejection of this feature as a simplification is dubious, as it is implemented with interfaces in order to allow this type of extension to be modularized, and independent.

@harawata If @chb0github would like to contribute the documentation fixes as well, this should leave your 2) as your only concern. In which case I would refer to my point above, how does this complicate the implementation at all? The only concern I can see is if this parser could in some way introduce a security vulnerability through the scripting interface.

@litwicki
Copy link

litwicki commented Jan 2, 2018

This would essentially open up mybatis to the entire LAMP stack universe; I'm failing to see the downside..

@chb0github
Copy link
Contributor Author

php
ruby
lua

@h3adache
Copy link
Member

h3adache commented Jan 2, 2018

@hibaymj @litwicki I appreciate the enthusiasm. But I fail to see how it's currently NOT opened up to those other stacks. I use it myself in many non java/jvm projects (js, perl, python, c++).
With the addition of the hooks that @harawata added, there's already scripting language support for all the heavy lifting that migrations does.

@hibaymj again, appreciate the feedback but I said directory based loading was what was requested multiple times and that is now handled by @harawata's commit and can be a drop in plugin to migrations. Please read what was written before attacking me.

@chb0github
Copy link
Contributor Author

@h3adache - in a C++ project: Do you have a custom FileMigrationLoader implemented in C++? It's not that it can't be used in those projects, it just can't be used with a customization. To use a custom FileMigrationLoader in your C++ project you would have to build it in java and put the resulting jar somewhere on the CP

Last I heard @harawata hadn't merged in those changes yet. And, that's handy. He actually opened it up to support his use case. Kudos.

@chb0github
Copy link
Contributor Author

chb0github commented Jan 3, 2018

@h3adache Maybe @hibaymj was a bit harsh. I think the point is: FileMigrationLoader and MigrationLoader are interfaces. Which means they are designed to be independent and thus low-maintenance

@hibaymj
Copy link

hibaymj commented Jan 3, 2018

@h3adache Apologies for the apparently heavy handed response, no attack was initiated or intended. I had to spend the previous 5 hours doing HR related training, nerves were a bit raw apparently.

What I believe @chb0github is saying is that migrations assumes there is a Java build tool being used to build the project, which is clearly not the case when using NPM, Yarn, Phing, Deployer, etc... You would still have the dependency of a JVM in the environment to execute migrations, however you wouldn't be required to use a Java based build tool for your project to build the custom project loader. This is the limitation I believe this issue is attempting to address.

Do the hooks you referenced by @harawata address this concern and allow this flexibility?

@harawata
Copy link
Member

harawata commented Jan 3, 2018

@chb0github
I have to assume that you asked your friends (who obviously do not understand the purpose of this request correctly) to vote this issue up to force us to accept your contribution.
It makes it difficult for us to evaluate what really is beneficial to this project and also is disrespectful to users who actually use this tool.
More than anything, it makes me really disappointed to see a respected developer like you do such a thing.

We try to be deliberate in choosing what to add (e.g. Does it benefit many users? Is it within the scope of the project?, etc.) because, while adding a new feature/option is relatively easy and can be done at any time, it’s quite difficult to remove it once it’s published and it has to be maintained.
If you are not familiar with this idea, here are a few good reads.
https://lord.io/blog/2014/oss-tips/
https://opensource.guide/best-practices/#learning-to-say-no

It is understandable that you feel frustrated to see your idea/PR/request is rejected and it may be our fault if our explanation is not satisfactory.
But we committers are trying to do what is best for the project and if you cannot believe it, you would have to create a new project of your own.

@chb0github
Copy link
Contributor Author

chb0github commented Jan 3, 2018 via email

@hazendaz
Copy link
Member

hazendaz commented Jan 3, 2018 via email

@chb0github
Copy link
Contributor Author

chb0github commented Jan 3, 2018

@hazendaz - Hey Jeremy,

That's a fantastic question and my issue really is directed toward the operational aspect of managing minor changes.

The distinction is this:

  • The jdk is the java development kit which includes the compiler and other build/debug tools.
    You need this to compile java code
  • The jre is just the run time and is required to run any JVM based app. Apps written in languages such as Scala/clojure as well as java
  • Maven is a build and dependency management tool. It does other things too that assist those goals mostly through it's plugin system.

mvn and mvnw (the wrapper) are missing 90% of functionality without the jdk. Most people don't run their apps using maven; though you can

What I am proposing is not "a whole lot of extra code" - Honestly, the implementation might amount to 40-60 lines in a single source file. Also, Java has something called interfaces - software contract that are designed to isolate varying implementations of the same basic concept. They are a bedrock of modern object oriented programming and I am proposing to implement one that eliminates the need for a jdk; you can never get rid of the jre (and this is crucial).

As a devops guys this actually effects you most.

Which would you prefer:

  1. Drop some plain text files (scripts) in a directory and be done

alternately

  1. Install the jdk
  2. Install maven (or use the wrapper)
  3. Build a java jar artifact (mvn install)
  4. Release the artifact to an artifact repository like jfrog or artifactory (mvn release:prepare release:perform).
  5. To perform task 4 either requires the individual doing to to have permissions to upload the artifact or a build pipeline like jenkins that does
  6. To perform task 4 (correctly) maven will create a tag on the repo in question. So you will also need permissions to tag a repo
  7. You then will need to download the artifact from step 4 and put it onto the classpath of mybatis/migrations. Currently you can put jars in the drivers directory of migrations to make this happen.
  8. You will need to check in the jar from step 7 (or leave in place permanently). Until such time as you need to make a change. At which point, please jump back up to step 1 and go have lunch! :)

I am proposing writing 50 lines of code to eliminate 8 operational steps and all the associated permission issues. Permanently if the user chooses to. And, I can do it entirely isolated and backward compatibly. This change is not at all invasive and leveraged existing code to it's fullest

Jeremy: You, as a total non-java guy, could make necessary changes if needed. Mostly people can work their way through script files

To the rest of the migrations team: I understand your concern: You don't want to be implementing and folding in every permutation of someones latest idea. 100% on board. Part of the reason people walk away from a tool/project and using it is because of maintenance. And so they essentially propose the change so that it can be folded into the maintenance process already in place.

If you accept this change, no user going forward will have any case to make for a new implementation being hosted by you guys because they can just use scripts on their end, check them in and have no extra build requirements.

@chb0github
Copy link
Contributor Author

I have production ready code. If a PR is going to be reviewed and potentially accepted I will create one - in addition I will supply a sample project that this approach helps address

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants