Skip to content

Fix handling of executed migrations with the withDatetimeMicroseconds driver option - #67

Merged
roxblnfk merged 3 commits into
4.xfrom
issue-66-datetime-microseconds
Aug 12, 2026
Merged

Fix handling of executed migrations with the withDatetimeMicroseconds driver option#67
roxblnfk merged 3 commits into
4.xfrom
issue-66-datetime-microseconds

Conversation

@roxblnfk

Copy link
Copy Markdown
Member

🔍 What was changed

  • Migrator::fetchMigrationData() passes created_at to the WHERE clause as a DateTimeInterface instead of a pre-formatted string, so the driver formats it exactly as it did on insert. Previously, with withDatetimeMicroseconds enabled, the stored value (...12:30:45.000000) never matched the lookup string (...12:30:45) on SQLite, so executed migrations were resolved as pending and re-run.
  • The migration table's datetime columns are now declared with datetime(6). On SQL Server the legacy DATETIME type rejects values with six fractional digits, so with the option enabled even the bookkeeping insert failed; datetime2(6) accepts them.
  • isConfigured() additionally compares the existing migration table with the declared schema, so tables created by previous versions are upgraded on configure().

How it works

  • On SQL Server and Postgres the schema comparator detects the precision change and configure() alters the table once; the check then passes.
  • MySQL and SQLite exclude column size from comparison, so existing tables keep their columns — both work with either datetime format as is.

Review notes

  • Rows written while the option was toggled to a different value than the current one still won't match on SQLite (the stored text differs) — that pre-existing limitation is out of scope here.

Checklist

The Migrator cannot resolve executed migrations when the driver is
configured with withDatetimeMicroseconds: fetchMigrationData() compares
created_at against a string formatted without microseconds, while the
inserted value is formatted by the driver with them. Fails on SQLite
(text comparison) and SQL Server (DATETIME rejects 6 fractional digits
on insert); MySQL and Postgres pass.

See #66

Assisted-By: Claude Fable 5 <noreply@anthropic.com>
Pass created_at to the WHERE clause as a DateTimeInterface instead of a
pre-formatted string, so the driver formats it the same way as on
insert. A string formatted without microseconds never matches the
stored value on SQLite, where datetime comparison is textual.

Fixes #66

Assisted-By: Claude Fable 5 <noreply@anthropic.com>
On SQL Server the legacy DATETIME type rejects values with six
fractional digits, so inserting into the migration table fails when the
driver is configured with withDatetimeMicroseconds. datetime(6) maps to
datetime2(6) there and keeps the other drivers' behavior intact.

isConfigured() now also compares the existing table with the declared
schema, so tables created by previous versions are upgraded on
configure(). The comparison is driver-aware for free: SQL Server and
Postgres detect the precision change and alter once; MySQL and SQLite
exclude size from column comparison, keep their old columns and work
either way.

Assisted-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.33%. Comparing base (c1712b6) to head (7532343).

Files with missing lines Patch % Lines
src/Migrator.php 88.88% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                4.x      #67      +/-   ##
============================================
+ Coverage     95.29%   95.33%   +0.04%     
- Complexity      248      250       +2     
============================================
  Files            30       30              
  Lines           786      793       +7     
============================================
+ Hits            749      756       +7     
  Misses           37       37              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@roxblnfk
roxblnfk merged commit 7dd0580 into 4.x Aug 12, 2026
14 of 15 checks passed
@roxblnfk
roxblnfk deleted the issue-66-datetime-microseconds branch August 12, 2026 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: migrations does not works if driver option withDatetimeMicroseconds is ture

1 participant