Open superstator opened 11 months ago
Interesting, can you disclose you usecase for this? And why comparing the name would not be enough? Thanks!
Sure, it's just an extension of the usecase for iteration. For example, if my app stores metadata in sqlite but also stores complex binary data on disk, I might need to initialize a directory structure after the initial migration, and then reshuffle a bunch of files during a later migration.
fn main() -> Result<(), Error> {
let mut conn = Connection::open("test.db").unwrap();
for migration in embedded::migrations::runner().run_iter(&mut conn) {
match migration?.try_into()? {
EmbeddedMigration::Initial(_) => init_filesystem(),
EmbeddedMigration::AddCarsAndMotosTable(_) => migrate_v2(),
_ => ()
}
}
Ok(())
}
fn init_filesystem() -> Result<(), Error> {
// create fs junk
Ok(())
}
fn migrate_v2() -> Result<(), Error> {
// update fs junk folowing db changes
Ok(())
}
I can absolutely achieve this just matching names, but enums would allow for compile-time checking. My thought was to use the migration version as the enum discriminant so strictly speaking I'd be matching an i32
instead of a string which would be more efficient and much less error prone.
The idea seems interesting, but if it's a TryInto
it means there's still going to be a runtime check, which I assume is converting the migration name from string into the matching enum right?
My thought was to have the macro output a TryInto
impl that maps migration.version
to the enum discriminant, so no runtime string comparisons. That way the only failure mode for TryInto
would be somehow instantiating a Migration
struct with an invalid version number, and I think the only obvious way for that to happen would be to monkey with the schema history table or delete applied migrations.
then I'd say it can be an Into
right?
It would have to panic on a bad migration version but otherwise sure
and isn't that most probably unreachable!
?
Off the top of my head the obvious way to get there (short of unsafe
) would be to have two sets of embedded migrations for two databases, and then try to convert one into the wrapping enum for the other. I'm fine with that being a panic if you are, and it would eliminate the need to make changes in error.rs
.
Now that I have a way to iterate over migrations as I run them, I'd like to be able to match strongly against them. Something like:
I think this could be done without any changes to
Migration
orRunner
, but just by emitting an enum andimpl TryFrom<Migration>
withembed_migrations!
. Is this something you'd be open to another PR for?