This patch adds the `--generate-link-to-definition`
argument to `rustdoc` for `docs.rs`. This is using
https://github.com/rust-lang/rust/pull/84176 to add links in the source
code page.
If we already have cross-signing details for the owner of the device at the
point we receive the to-device message, we should store that rather than just
the device info.
create a new method `SenderData::from_device` which does the last few steps of
`SenderDataFinder`: turns out we want it elsewhere. Add some tests to test that
functionality in isolation.
- Doc comment for the SQLite-based state store incorrectly referred to
it as a "cryptostore".
- Consistent capitalisation of SQLite.
- Consistent use of indefinite article "an" before SQLite.
- Fix line length.
Imagine we have the following events:
| event_id | room_id | chunk_id | position |
|----------|---------|----------|----------|
| $ev0 | !r0 | 42 | 0 |
| $ev1 | !r0 | 42 | 1 |
| $ev2 | !r0 | 42 | 2 |
| $ev3 | !r0 | 42 | 3 |
| $ev4 | !r0 | 42 | 4 |
`$ev2` has been removed, then we end up in this state:
| event_id | room_id | chunk_id | position |
|----------|---------|----------|----------|
| $ev0 | !r0 | 42 | 0 |
| $ev1 | !r0 | 42 | 1 |
| | | | | <- no more `$ev2`
| $ev3 | !r0 | 42 | 3 |
| $ev4 | !r0 | 42 | 4 |
We need to shift the `position` of `$ev3` and `$ev4` to `position - 1`,
like so:
| event_id | room_id | chunk_id | position |
|----------|---------|----------|----------|
| $ev0 | !r0 | 42 | 0 |
| $ev1 | !r0 | 42 | 1 |
| $ev3 | !r0 | 42 | 2 |
| $ev4 | !r0 | 42 | 3 |
Usually, it boils down to run the following query:
```sql
UPDATE event_chunks
SET position = position - 1
WHERE position > 2 AND …
```
Okay. But `UPDATE` runs on rows in no particular order. It means that
it can update `$ev4` before `$ev3` for example. What happens in this
particular case? The `position` of `$ev4` becomes `3`, however `$ev3`
already has `position = 3`. Because there is a `UNIQUE` constraint
on `(room_id, chunk_id, position)`, it will result in a constraint
violation.
There is **no way** to control the execution order of `UPDATE` in
SQLite. To persuade yourself, try:
```sql
UPDATE event_chunks
SET position = position - 1
FROM (
SELECT event_id
FROM event_chunks
WHERE position > 2 AND …
ORDER BY position ASC
) as ordered
WHERE event_chunks.event_id = ordered.event_id
```
It will fail the same way.
Thus, we have 2 solutions:
1. Remove the `UNIQUE` constraint,
2. Be creative.
The `UNIQUE` constraint is a safe belt. Normally, we have
`event_cache::Deduplicator` that is responsible to ensure there is no
duplicated event. However, relying on this is “fragile” in the sense it
can contain bugs. Relying on the `UNIQUE` constraint from SQLite is more
robust. It's “braces and belt” as we say here.
So. We need to be creative.
Many solutions exist. Amongst the most popular, we see _dropping and
re-creating the index_, which is no-go for us, it's too expensive. I
(@hywan) have adopted the following one:
- Do `position = position - 1` but in the negative space, so
`position = -(position - 1)`. A position cannot be negative; we are
sure it is unique!
- Once all candidate rows are updated, do `position = -position` to move
back to the positive space.
'told you it's gonna be creative.
This solution is a hack, **but** it is a small number of operations, and
we can keep the `UNIQUE` constraint in place.
This patch updates the `test_linked_chunk_remove_item` to handle
6 events. On _my_ system, with _my_ SQLite version, it triggers the
`UNIQUE` constraint violation without the bug fix.
This is necessary because the `NotificationClient` runs a sliding sync loop and the retrieved data isn't pushed back into the parent client stores (because of cross process locking shenanigans).
This will be used with the previously introduced `org.matrix.msc3401.call.member` required state to check whether a room still has an ongoing call before showing the ringing screen.
This is apparently the right way to do it, both because some HS expect only this mimetype and also so we don't leak the mime type of the encrypted media.
This commit simplifies the filter public api.
Rethinking the public api we only need:
- to know if events can be sent based on the capabilities
- to know if events can be sent to the widget (read) based on the capabilities
- if it even makes sense to sent a cs api read request or if all possibly returned events
would not match the type.
To simplify the code in the machine it also made sense to add `From` implementation
to the FilterInputs instead of gathering the relevant data from all kinds of Raw events.
The new api is simpler:
All possible events we need to check can be converted into filter inputs (using `into()`).
`capabilites` has two allow_read/allow_send that consume filter inputs.
`capabilites` can be asked if there is any filter for specific event types
to allow not send unnecassary requests.
This is (sadly) required since we cannot do `as_str()` for `TimlineEventType` and other `ruma` event types.
So we need to use `String`. We also never used them more specifically than strings.
Previously, the `share_strategy` was breaking the abstraction provided
by `OutboundGroupSession` by accessing its internal fields in an
inconsistent and adhoc way. Now all fields are private and a proper
abstraction was added to access the required state in a consistent API.