Repository navigation
Conversation
Add `DatabaseField` implementations for `jiff::Timestamp` and
`jiff::civil::{Date, Time, DateTime}`, and a new public
`cot::common_types::WeekdaySet` built on `jiff::civil::Weekday`.
SQLx doesn't support jiff natively yet (and sea-query-sqlx panics when
binding jiff values for PostgreSQL and MySQL), so the values are
represented as `DbValue::Jiff*` in Cot and converted right before
binding: to `time` types for PostgreSQL and MySQL, and to text for
SQLite. The SQLite text format is the same as the one used for chrono
values, so the existing data stays comparable with the new values.
`chrono::WeekdaySet` is now stored through the new `WeekdaySet` type;
the on-disk representation is unchanged.
m4tx
added this pull request to stack #700
October 12, 2026 16:50
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Several new compatibility tests use dates inconsistent with their fixtures, and two assertions rely on unspecified database row ordering.
4 open findings
What changed in this PR
Adds database support for jiff date/time types while preserving compatibility with existing chrono storage.
Changes:
- Adds
DatabaseFieldimplementations and backend conversions forjiff. - Introduces the public
WeekdaySettype. - Adds cross-backend storage and compatibility tests.
| File | Description |
|---|---|
cot/tests/db_testing/fields.rs |
Tests new field types. |
cot/tests/db_testing/datetime_storage.rs |
Tests chrono/jiff compatibility. |
cot/src/utils/jiff.rs |
Converts between jiff and time. |
cot/src/utils.rs |
Registers conversion utilities. |
cot/src/db/impl_sqlite.rs |
Prepares SQLite values. |
cot/src/db/impl_postgres.rs |
Prepares PostgreSQL values. |
cot/src/db/impl_mysql.rs |
Prepares MySQL values. |
cot/src/db/fields/jiff_fields.rs |
Implements jiff database fields. |
cot/src/db/fields/chrono_wrapper.rs |
Bridges chrono::WeekdaySet. |
cot/src/db/fields.rs |
Registers field implementations. |
cot/src/common_types.rs |
Adds public WeekdaySet. |
cot/Cargo.toml |
Enables required crate features. |
Cargo.toml |
Adds the workspace dependency. |
Cargo.lock |
Locks new dependencies. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+261
to
+263
| expected[1].datetime_fixed = "2023-01-02T11:34:56.789+00:00".to_owned(); | ||
| expected[2].datetime_fixed = "2023-01-02T15:04:56.123456+00:00".to_owned(); | ||
| expected[3].datetime_fixed = "2023-01-02T06:49:56.123456789+00:00".to_owned(); |
| expected[2].datetime_fixed = "2023-01-02T15:04:56.123456+00:00".to_owned(); | ||
| expected[3].datetime_fixed = "2023-01-02T06:49:56.123456789+00:00".to_owned(); | ||
|
|
||
| let text_models = TextModel::objects().all(&**db).await.unwrap(); |
| let mut third = models[2].clone(); | ||
| third.save(&**db).await.unwrap(); | ||
|
|
||
| let threshold: jiff::Timestamp = "2023-01-02T12:34:56.5Z".parse().unwrap(); |
Comment on lines
+390
to
+405
| let datetime_threshold = jiff::civil::date(2023, 1, 2).at(12, 34, 56, 500_000_000); | ||
| let earlier = query!(JiffModel, $datetime < datetime_threshold) | ||
| .order_by([<JiffModel as Model>::Fields::datetime.asc()]) | ||
| .all(&**db) | ||
| .await | ||
| .unwrap(); | ||
| assert_eq!( | ||
| earlier | ||
| .iter() | ||
| .map(|model| model.datetime) | ||
| .collect::<Vec<_>>(), | ||
| [ | ||
| jiff::civil::date(2023, 1, 2).at(12, 34, 56, 0), | ||
| jiff::civil::date(2023, 1, 2).at(12, 34, 56, 123_456_000), | ||
| ] | ||
| ); |
|
| Project | cot |
| Branch | jiff-2 |
| Testbed | github-ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result milliseconds (ms) (Result Δ%) | Upper Boundary milliseconds (ms) (Limit %) |
|---|---|---|---|
| empty_router/empty_router | 📈 view plot 🚷 view threshold | 13.15 ms(+13.48%)Baseline: 11.59 ms | 18.61 ms (70.67%) |
| json_api/json_api | 📈 view plot 🚷 view threshold | 1.11 ms(+9.99%)Baseline: 1.01 ms | 1.35 ms (82.66%) |
| nested_routers/nested_routers | 📈 view plot 🚷 view threshold | 1.07 ms(+12.58%)Baseline: 0.95 ms | 1.25 ms (85.69%) |
| single_root_route/single_root_route | 📈 view plot 🚷 view threshold | 1.00 ms(+9.35%)Baseline: 0.92 ms | 1.21 ms (82.73%) |
| single_root_route_burst/single_root_route_burst | 📈 view plot 🚷 view threshold | 16.96 ms(+0.88%)Baseline: 16.81 ms | 22.15 ms (76.57%) |
This branch has not been deployed
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.

Related issue or discussion
#631
Description
Add
DatabaseFieldimplementations forjiff::Timestampandjiff::civil::{Date, Time, DateTime}, and a new publiccot::common_types::WeekdaySetbuilt onjiff::civil::Weekday.SQLx doesn't support jiff natively yet (and sea-query-sqlx panics when binding jiff values for PostgreSQL and MySQL), so the values are represented as
DbValue::Jiff*in Cot and converted right before binding: totimetypes for PostgreSQL and MySQL, and to text for SQLite. The SQLite text format is the same as the one used for chrono values, so the existing data stays comparable with the new values.chrono::WeekdaySetis now stored through the newWeekdaySettype; the on-disk representation is unchanged.Type of change