-
Notifications
You must be signed in to change notification settings - Fork 93
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 import readMigrations function in the Database class #179
base: master
Are you sure you want to change the base?
Add import readMigrations function in the Database class #179
Conversation
…e comments from 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.
I'm not against the idea but I think we need to make some usability improvements
Thanks for also writing tests too
src/utils/migrate.ts
Outdated
|
||
delete migration.filename |
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.
Why 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.
For the types consistency.
Do you want to save all parameters from migration that may be add in the future?
So maybe we will make another type in Migration class for the readMigrations function and in the migrate function we will just require needed arguments but not the exact object as MigrationData.
What do you think?
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.
That sounds appropriate
src/Database.ts
Outdated
* @returns List of objects with name, id of migrations and SQL code for up and down migration | ||
* You can run up and down with `db.exec(migrations[0].up)` or `db.exec(migrations[0].down)`. Or with other commands that can run SQL code. | ||
*/ | ||
readMigrations (migrationPath?: string): Promise<IMigrate.MigrationData[]> { |
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.
Is the intent to just read a list of migrations and then execute them?
It almost feels like this should belong in its own Migrations class and the constructor would accept a Database instance
then you can have a method for just reading the list of migrations / status
and then have another method(s) for executing up / down based on the list of migrations passed through
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, I understand that it's better. But it'll take some time. So let's me finish my tasks and I plan to make this changes on the next week
Changes:
- add Migration class
- add run, show, reverse migration functions
- add a commander to run these functions to look on the migrations
- add config options where to look for Database instance or config options. With default behaviour. But I plan to add config as a parameter in the command line
WDYT?
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.
The overall idea sounds good. I'd have to see the impl / interface to have additional thoughts
Thanks for doing this. We could also probably move the migration logic to the migration class too.
The Database instance can still keep the migrate
method for backwards-compat but would call the new Migration class
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.
Hi, I replied a little later but I have time to make changes)
…ve migration's methods from Database, move tests and update tests
Hi, I just moved all the staff to the Migrations class and have updated for prettier-standard. I'll fix what's needed. And I'll use your code structure. Do we need to bump the versions of the packages in dev dependencies? |
Just briefly looking at the changes, there's too many things going on.
So here's what we need to do here. Let's close this PR and create another one. Don't bother with linting if you can't get it to work, I can do that for you. Make a PR that only makes the changes necessary for your Migration class to work.
In general, keep the PRs small (if possible) and specific to what you are doing, one feature at a time. Thanks for taking the time to do all that work, but let's make sure we follow and learn best practices here. I'm happy to help you get better at it. |
Thank you for your kind explanation 😊 I'll check about arrow functions. And I agree to your comments. Let's do the best practice! Do I need to leave readMigrations function exported in this PR or move to another one? Do you know a resource where I can read shortly about PRs best practices? Features:
I see that we need 3 PRs from points above Notes:
|
/** | ||
* Performs a database migration. | ||
*/ | ||
async migrate (config?: MigrationParams) { |
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.
Keep, but we'll create a new instance of your migration class here, like
const migrate = new Migration(<params >)
// do migration
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'll do it in another PR
|
||
export class Migrations< | ||
Driver extends Database, | ||
Config extends IMigrate.MigrationParams = IMigrate.MigrationParams |
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.
This is strange. Why would configuration options be a generic?
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.
Oh, I don't understand what I've done. I've just copied from the Database class.
I've read what Generic means and now I understand that we don't need it here because Config is not changing by the user. It's just parameters that the user can set. For the Database, we need generic because a User can use another Driver instead of our but will extends our Database
|
||
constructor (db: Driver, config?: Config) { | ||
this.db = db | ||
/** Sequence in the properties definitions is IMPORTANT */ |
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.
it's not important. if it is then you're doing something wrong
in JS, object property ordering isn't guaranteed
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 think I understand what you mean here - you need the default on the migrationsPath
. You don't need the comment for that though.
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, about default on the migrationsPath
. And also for force
and table
options. Because
const config = {
force: true
}
const configTest = {
table: DEFAULT_MIGRATIONS_DIR_NAME,
...config,
force: false,
migrationsPath: path.resolve(
config?.migrationsPath ?? DEFAULT_MIGRATIONS_DIR_PATH
)
}
Force
will be false
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.
That's why I wrote sequence
is important. I don't know how to say it correctly and easy for others to understand. Maybe you can help write a comment if we need one
Config extends IMigrate.MigrationParams = IMigrate.MigrationParams | ||
> { | ||
db: Driver | ||
config: Config |
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.
Did you mean for this to be IMigrate.MigrationParams?
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, I updated it
db: Driver | ||
config: Config | ||
|
||
constructor (db: Driver, config?: Config) { |
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.
did you mean IMigrate.MigrationParams?
* { id: 1, name: 'initial', filename: '001-initial.sql', up: ..., down: ... } | ||
* { id: 2, name: 'feature', filename: '002-feature.sql', up: ..., down: ... } | ||
*/ | ||
readMigrations = async (): Promise<MigrationData[]> => { |
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.
classes in general do not use arrow functions to define methods. there are specific cases where you would use an arrow function, but the methods in this file isn't one of them
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.
Okay, I understand what you mean)
It's very interesting to go deep in learning JS and other languages. I understand now that I'm just using some part that I know how it works for some purposes but not for everything because I don't know in the depth the under hood processes
}) | ||
const migrationsInstanceForce = new Migrations(db, { force: true }) | ||
await migrationsInstanceForce.migrate() | ||
console.log('heer') |
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.
stray console log
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.
Forgot about this one)
I couldn't really understand what you mean, but I might be able to when I see the new PR where it's easier to read the changes and can give you guidance from then.
I think this falls under the topic of general software engineering practices. I did try looking up best practices around PRs and feature branches, but they seem to be focused on documentation and formatting. I think I learned via just code reviews from other peers over time.
That sounds almost right, although the version bump would happen during the CI process or in the PR itself depending on the project. I don't know what this commander is, but looking forward to knowing more about it!
Assuming you mainly copy/pasted the original merge code into your new class, the existing SQL files should work-as-is without modifications. If it's not working, then your new code may have bugs in it. When you create a new PR for this feature, I can get a better look / understanding of it.
If you're introducing a new feature and it's something developers would access, then the readme would have to be updated with usage and example information. |
Let's move to another PR to not remove all. And for clear goal purpose |
Hi, the main point is to import the readMigrations function but for the minor changes, it was updated to remove the comments mechanism and wrote tests!
Can you have a look?
It's better to update early for me because I'm creating a project based on this module.
But if it needs time to check and update this module it's okay)
I agree to apply your suggesting in the Pull Request so I'll update the code
Thank you!