-
-
Notifications
You must be signed in to change notification settings - Fork 153
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
Add Lotus::Model::Migration #144
Conversation
require 'sequel' | ||
require 'sequel/extensions/migration' | ||
|
||
# Allow users to easily group schema changes # and migrate the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes # and
to
changes and
|
||
module Lotus | ||
module Model | ||
# Allow users to easily group schema changes # and migrate the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/s/changes # and/changes and/
Hi everybody, class SomeMigration < ActiveRecord::Migration
# ... with migration do
# ... which generated the class name automatically, based on the filename. The motivation behind this was that when I wanted to create a new migration (without using Rails' generator), I would always need to come up with a new, unique class name, that I never needed again. Having a short Unfortunately, it introduces magic, but something similar/better could be done in a not-so-magic manner: Lotus::Model::Migration.create "description" do
# ... (the description being also generated, but it is an optional parameter) I propose this little API change, because:
I am happy to write the code for this, if you like the idea. |
@janlelis Thanks much for your detailed feedback. I have been looking into the DSL solution from the very start of this feature. In fact, doing DSL is very straight-forward because Sequel already had DSL for migration. After weighting pros/cons, I decided to stay away from DSL to avoid unnecessary complexity. I acknowledge your pain point regarding unique class constant however I don't think it would be a huge hassle because Lotus would provide migration generator. Besides, your suggestion on class name inflection from filename is not going to work out of the box though, for schema_migration table stores the full _filepath into filename column and should users have migrated (not rollback yet) then rename the filename would create extra record in schema_migration table. Having said all of the above, I am open for feedbacks from other uses, if this is truly a pain point, I am more than happy to make changes. |
@joneslee85 Great work. One small question: is there a good reason to keep the current_version method private. Sometimes it would be helpful to have the possibility for a quick check for the current migrated version. |
@mwallasch there is no particular reason. I did not think of your scenario. Thanks for the feedback. I'll make change. |
@joneslee85 In the description and in the inline docs you say that the default logger is |
# end | ||
# | ||
# # to migrate | ||
# MyMigration.apply(DB, :up) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joneslee85 This comment puzzles me. 😺 DB
derives from Sequel, but what's the meaning here in Lotus::Model?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the Migration
class is low-level class which has access to apply
method and that method takes in a sequel connection. I think I am going to document that for whom who care about this low level detail or should I remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we need to document anyway how to apply a migration. Please keep the documentation, but with a Lotus terminology. 😄
@jodosha I forget to update the description. I don't think it is necessary to extract it to lotus/utils. Btw, I have removed setting logger to |
end | ||
end | ||
|
||
MIGRATION_DIRECTORY = "#{Dir.pwd}/db/migrations".freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we split the composition of this directory? If feel uneasy to leave a frozen constant with the current value that can possibly change. Eg. if someone uses Dir.chdir
. Can we interpolate at the run time?
Example:
MIGRATION_DIRECTORY = 'db/migrations'.freeze
And then in the methods that use it:
directory = "#{ Dir.pwd }/#{ MIGRATION_DIRECTORY }"
We can have a private method to do this tedious interpolation over and over.
else | ||
@logger ||= logger | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the difference bw logging and logger?, according to the sample, it's seem to be the same thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, I'd renamed to def logger(value = nil)
IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are pretty much the same. the logging method acts as accessor DSL (though I hate it), I don't mind doing it the Ruby way, that is:
logger = Something
at all. But I don't want to break the current pattern without running it through with everyone.
end | ||
end | ||
|
||
SUPPORTED_ADAPTERS = [:sql].freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document this constant
👍 ❤️ |
# @since 0.3.0 | ||
# @api private | ||
def _default_migration_directory | ||
"#{Dir.pwd}/db/migrations" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about Pathname.pwd.join('db', 'migrations')
? This will make the code OS independent.
# @api private | ||
class SchemaModifier | ||
def initialize(adapter, logger = nil) | ||
@connection = adapter.instance_variable_get(:@connection) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joneslee85 Shouldn't this be a public method marked as private API? So we can avoid instance_variable_get
and have adapter.connection
.
I may be out but I'd like to suggest to split "schema" and "data" migrations. In Rails days most of developers putting "data" migration into "schema" migration. I often see something like: Model.all.each do |model|
model.update_attributes(some_attribute: 'something')
end After many years I feel this is very bad approach leading to pain and very long time taking migrations. I don't have a concrete idea how it would work. It's just a suggestion. |
@deepj yes, thanks for the input. My intent is to only support schema migration, for data migration I'd let user do it with rake task |
OK, than isn't is better to name the migration class as |
@deepj I don't think it is necessary. Why? Because we follow the same sequel's class naming and so far it has been used just for schema changes only. |
Closed in favor of #196 |
[Fixes #115]
This adds the basic migration feature for Lotus.
Please be noted that this PR does not cover load/dump schema.rb, I am going to have a separate PR for that.
TODO
Migration
It purely base on Sequel::Migration and thus share the same interface as Sequel::Migration:
Migration files are located inside
LOTUS_ROOT/db/migrations
folder by default. However you can configure it withLotus::Model::Configuration#migration_directory
Migrator
To migrate, we use Migrator:
To migrate from a directory
To rollback to previous migration
or migration 4 steps from the last version
Furthermore, I also introduce the ability to set logger for the framework. Please see
Lotus::Model::Configuration#logging
. The migrator will use the framework logger implicitly.Schema Modification API
create_table
Use to create new table. Syntax to add new column is below: