Support MySQL and PostgreSQL databases - #32
Open
luislavena wants to merge 12 commits into
Open
Conversation
The library only needs the crystal-db common API, and applications already require their own driver. Only the CLI and the specs use the real drivers, and both are built from this repository.
The upcoming Dialect abstraction returns these entries, so the type needs to live outside Migrator.
Moving the SQL that tracks applied migrations behind a dialect allows supporting multiple database engines without touching the Migrator API. Crystal's DB API cannot expose the URI of a live connection, so the dialect is picked from the connection class name.
The Migrator keeps orchestration only and the dialect owns every query. Behavior on SQLite stays the same.
Only schema creation and catalog inspection need MySQL specific SQL, the shared tracking queries work unchanged. Coverage against a live server is gated behind MYSQL_DATABASE_URL.
crystal-pg only accepts numbered placeholders, so the parameterized queries are redefined as complete statements instead of patching the shared SQL. Coverage against a live server is gated behind POSTGRES_DATABASE_URL.
Writing the Migrator contract once and registering it per engine holds every dialect to identical expectations. SQLite runs it first, MySQL and PostgreSQL hook in next.
A fresh clone still runs the SQLite suite with zero setup, while the development container wires the database URLs automatically. Skipped engines show as pending instead of silently shrinking the suite. MySQL 8.4 defaults to caching_sha2_password, which the crystal-mysql driver does not implement. Startup flags enable the native password plugin and make the entrypoint create the root user with it.
The binary can now migrate any of the three engines by connection URI. Both drivers are pure Crystal, so static builds stay self-contained.
Service containers keep the gated groups always running on pull requests, so a dialect regression fails the build even when it was never exercised locally. MySQL needs server flags that service containers cannot pass, so it starts via docker run instead.
Readers need to know which driver to require and what to expect from each engine, including MySQL's implicit commits during failed batches.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Drift only worked with SQLite, so any project running on MySQL or PostgreSQL had to pick a different migration tool. This change extends both the library and the CLI to all three engines, keeping the same plain SQL files in a folder approach independently of the database you choose.
A new
Dialectabstraction owns the SQL used to track applied migrations on each engine and is picked automatically from the live connection, so theMigratorAPI does not change. The library still depends only oncrystal-db; applications require the driver they use. The CLI remains a standalone executable and selects the engine from the connection URI.The shared lifecycle spec now runs against real MySQL and PostgreSQL servers, wired automatically in the development container and in CI.
Note: MySQL cannot roll back a failed migration batch, since DDL statements trigger an implicit commit. SQLite and PostgreSQL roll back the whole batch. The README covers this caveat.
Breaking changes for library consumers:
Drift::Migrator::MigrationEntryis nowDrift::MigrationEntry.This type is internal, so it should not impact anyone (and if
someone out there depends on it, we have a different problem to
talk about).