-
-
Notifications
You must be signed in to change notification settings - Fork 0
Support other SQL dialects (MySQL, PostgreSQL) #26
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
base: main
Are you sure you want to change the base?
Conversation
Drop support for `DB::Connection` for `db` in Migrator in order to simplify the types used by it. This helps to reduce the confusion on what to pass to Migrator but also helps with type resolution as `DB::Database | DB::Connection` was presenting some issues when dealing with DB::Database and DB::Connection method overload.
Abstract away SQL-specific elements from Migrator logic into Drift::Dialect-derived implementations. Do this to prepare for other dialects/drivers (MySQL, PostgreSQL, etc).
Perform sorting and filtering on SQLite side to avoid allocating that response and performing the filtering in Crystal side (which is way less optimized that SQLite VM) - Before: 2.25k ops/sec (445µs per operation, 253kB memory) - After: 24.65k ops/sec (40.57µs per operation, 12.2kB memory) Benchmark script: * https://gist.github.com/luislavena/460de5a9cb1e8a4085de14aa6644c64a
95e01c8 to
7a74960
Compare
Preview Binaries - Build #1Built from commit Downloads:
Note: These artifacts will expire in 90 days. View build logs |
As we prepare Drift to be DB-agnostic, move out the SQLite3 dependency to be only used during development.
Almost direct translation from SQLite3 implementation with adjustments for table and arguments placeholders
Introduces DIALECTS hash to support testing against multiple database dialects (SQLite3 and PostgreSQL). Each dialect can be skipped via environment variable. Also adds cleanup_tables helper to drop test tables between PostgreSQL test runs to ensure clean state.
Introduces a macro to run parameterized tests across multiple database dialects. The macro generates test blocks for each configured dialect (SQLite3 and PostgreSQL), providing a clean database connection via a Proc. PostgreSQL connections trigger automatic cleanup of test tables before each test. The macro is defined but not yet used, ensuring no behavior changes to the existing test suite.
Modified ready_migrator to require db parameter instead of using a default value. Updated prepared_migrator to accept db parameter and removed internal database creation. This prepares the helpers for parameterized dialect testing. Tests now fail with compilation errors as expected. These will be resolved in subsequent tasks.
Tests for #prepared? and #prepare! methods now run against both SQLite3 and PostgreSQL dialects using the for_each_dialect macro. Each test properly manages database connections using dialect_db.call and closes connections after assertions complete.
Updates all prepared_migrator calls to pass the required db parameter and adds proper db.close cleanup to prevent resource leaks. This change is part of the multi-dialect testing refactoring.
Wrap #applied?, #applied_ids, #apply_plan, #apply(id), and #apply(ids) test blocks in for_each_dialect macro to run against both SQLite3 and PostgreSQL databases.
Wrap #rollback(id) and #rollback(ids) test blocks in for_each_dialect macro to run against both SQLite3 and PostgreSQL databases.
Updates the macro to properly evaluate SKIP_POSTGRESQL environment variable at compile time using env(). Removes skip flag from DIALECTS configuration hash as it's now handled directly in the macro. PostgreSQL tests now run but fail due to incomplete Dialect implementation (all methods return TODO/empty values).
Slightly adjust used queries inside specs to avoid having to write different queries per-dialect.
Updates documentation to reflect the new database support/compatibility.
Adds crystal-lang/crystal-mysql to support MySQL dialect implementation.
Adds MySQL 8.0 service for local development and testing. Configures health checks and persistent volume storage.
Adds MySQL dialect with INFORMATION_SCHEMA-based schema checking, question mark parameter placeholders, and BIGINT column types.
Adds MySQL to DIALECTS configuration with opt-out via SKIP_MYSQL environment variable. Updates helper functions to handle MySQL-specific SQL syntax. Also fixes MySQL Docker image to 8.0 with native password authentication for compatibility with crystal-mysql driver, and corrects dialect detection for MySql:: namespace.
Tests that MySQL connections are properly detected and return Drift::Dialect::MySQL instance.
Configures MySQL 8.0 container in GitHub Actions workflow to run full test suite against all supported databases.
Requires mysql driver so CLI can connect to MySQL databases.
Updates supported databases list, adds MySQL usage example, and documents testing with multiple databases.
Use MySQL 5.7 instead of 8.0 in CI as crystal-mysql does not support modern authentication plugin and fails regular one.
7a74960 to
0495b73
Compare
Preview Binaries - Build #2Built from commit Downloads:
Note: These artifacts will expire in 90 days. View build logs |
|
Hello @watzon, took a bit but explored adding PostgreSQL support to drift:
😆 You can check out this branch or download one of the pre-compiled binaries from the build artifacts. Let me know what do you think. Cheers. |

Drift was previously limited to SQLite3, which meant it couldn't be used by others who needed PostgreSQL or MySQL for their applications.
This PR adds support for multiple databases by introducing a
Drift::Dialectinterface that encapsulates the SQL syntax differences between SQLite3, PostgreSQL, and MySQL. Now all three databases work seamlessly with both the library API and the CLI.