1use std::collections::HashMap;
2
3use diesel::prelude::*;
4use rand::seq::SliceRandom;
5use serde::Deserialize;
6
7use crate::core::canonical_json::CanonicalJsonObject;
8use crate::core::directory::RoomTypeFilter;
9use crate::core::events::direct::DirectEventContent;
10use crate::core::events::room::create::RoomCreateEventContent;
11use crate::core::events::room::guest_access::{GuestAccess, RoomGuestAccessEventContent};
12use crate::core::events::room::member::MembershipState;
13use crate::core::events::{
14 AnyStrippedStateEvent, AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType,
15};
16use crate::core::identifiers::*;
17use crate::core::room::RoomType;
18use crate::core::serde::{default_false, JsonValue, RawJson};
19use crate::core::{MatrixError, MatrixResult, Seqnum, UnixMillis};
20use crate::schema::*;
21use crate::{diesel_exists, DataResult};
22
23#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
24#[diesel(table_name = rooms)]
25pub struct DbRoom {
26 pub id: OwnedRoomId,
27 pub sn: Seqnum,
28 pub version: String,
29 pub is_public: bool,
30 pub min_depth: i64,
31 pub state_frame_id: Option<i64>,
32 pub has_auth_chain_index: bool,
33 pub disabled: bool,
34 pub created_at: UnixMillis,
35}
36#[derive(Insertable, Debug, Clone)]
37#[diesel(table_name = rooms)]
38pub struct NewDbRoom {
39 pub id: OwnedRoomId,
40 pub version: String,
41 pub is_public: bool,
42 pub min_depth: i64,
43 pub has_auth_chain_index: bool,
44 pub created_at: UnixMillis,
45}
46
47#[derive(Insertable, Identifiable, Queryable, AsChangeset, Debug, Clone)]
48#[diesel(table_name = stats_room_currents, primary_key(room_id))]
49pub struct DbRoomCurrent {
50 pub room_id: OwnedRoomId,
51 pub state_events: i64,
52 pub joined_members: i64,
53 pub invited_members: i64,
54 pub left_members: i64,
55 pub banned_members: i64,
56 pub knocked_members: i64,
57 pub local_users_in_room: i64,
58 pub completed_delta_stream_id: i64,
59}
60
61#[derive(Identifiable, Queryable, Debug, Clone)]
62#[diesel(table_name = event_relations)]
63pub struct DbEventRelation {
64 pub id: i64,
65
66 pub room_id: OwnedRoomId,
67 pub event_id: OwnedEventId,
68 pub event_sn: i64,
69 pub event_ty: String,
70 pub child_id: OwnedEventId,
71 pub child_sn: i64,
72 pub child_ty: String,
73 pub rel_type: Option<String>,
74}
75#[derive(Insertable, Debug, Clone)]
76#[diesel(table_name = event_relations)]
77pub struct NewDbEventRelation {
78 pub room_id: OwnedRoomId,
79 pub event_id: OwnedEventId,
80 pub event_sn: i64,
81 pub event_ty: String,
82 pub child_id: OwnedEventId,
83 pub child_sn: i64,
84 pub child_ty: String,
85 pub rel_type: Option<String>,
86}
87
88#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
89#[diesel(table_name = room_aliases, primary_key(alias_id))]
90pub struct DbRoomAlias {
91 pub alias_id: OwnedRoomAliasId,
92 pub room_id: OwnedRoomId,
93 pub created_by: OwnedUserId,
94 pub created_at: UnixMillis,
95}
96
97#[derive(Identifiable, Queryable, Debug, Clone)]
98#[diesel(table_name = room_state_fields)]
99pub struct DbRoomStateField {
100 pub id: i64,
101 pub event_ty: StateEventType,
102 pub state_key: String,
103}
104
105#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
106#[diesel(table_name = room_state_deltas, primary_key(frame_id))]
107pub struct DbRoomStateDelta {
108 pub frame_id: i64,
109 pub room_id: OwnedRoomId,
110 pub parent_id: Option<i64>,
111 pub appended: Vec<u8>,
112 pub disposed: Vec<u8>,
113}
114
115#[derive(Identifiable, Queryable, Debug, Clone)]
116#[diesel(table_name = event_receipts)]
117pub struct DbReceipt {
118 pub id: i64,
119 pub ty: String,
120 pub room_id: OwnedRoomId,
121 pub user_id: OwnedUserId,
122 pub event_id: OwnedEventId,
123 pub occur_sn: Seqnum,
124 pub json_data: JsonValue,
125 pub receipt_at: UnixMillis,
126}
127
128#[derive(Insertable, AsChangeset, Debug, Clone)]
129#[diesel(table_name = event_receipts)]
130pub struct NewDbReceipt {
131 pub ty: String,
132 pub room_id: OwnedRoomId,
133 pub user_id: OwnedUserId,
134 pub event_id: OwnedEventId,
135 pub occur_sn: i64,
136 pub json_data: JsonValue,
137 pub receipt_at: UnixMillis,
138}
139
140#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
141#[diesel(table_name = room_users)]
142pub struct DbRoomUser {
143 pub id: i64,
144 pub event_id: OwnedEventId,
145 pub event_sn: i64,
146 pub room_id: OwnedRoomId,
147 pub room_server_id: OwnedServerName,
148 pub user_id: OwnedUserId,
149 pub user_server_id: OwnedServerName,
150 pub sender_id: OwnedUserId,
151 pub membership: String,
152 pub forgotten: bool,
153 pub display_name: Option<String>,
154 pub avatar_url: Option<String>,
155 pub state_data: Option<JsonValue>,
156 pub created_at: UnixMillis,
157}
158#[derive(Insertable, AsChangeset, Debug, Clone)]
159#[diesel(table_name = room_users)]
160pub struct NewDbRoomUser {
161 pub event_id: OwnedEventId,
162 pub event_sn: i64,
163 pub room_id: OwnedRoomId,
164 pub room_server_id: OwnedServerName,
165 pub user_id: OwnedUserId,
166 pub user_server_id: OwnedServerName,
167 pub sender_id: OwnedUserId,
168 pub membership: String,
169 pub forgotten: bool,
170 pub display_name: Option<String>,
171 pub avatar_url: Option<String>,
172 pub state_data: Option<JsonValue>,
173 pub created_at: UnixMillis,
174}
175
176#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
177#[diesel(table_name = threads, primary_key(event_id))]
178pub struct DbThread {
179 pub event_id: OwnedEventId,
180 pub event_sn: i64,
181 pub room_id: OwnedRoomId,
182 pub last_id: OwnedEventId,
183 pub last_sn: i64,
184}
185
186#[derive(Insertable, Identifiable, AsChangeset, Queryable, Debug, Clone)]
187#[diesel(table_name = event_datas, primary_key(event_id))]
188pub struct DbEventData {
189 pub event_id: OwnedEventId,
190 pub event_sn: i64,
191 pub room_id: OwnedRoomId,
192 pub internal_metadata: Option<JsonValue>,
193 pub json_data: JsonValue,
194 pub format_version: Option<i64>,
195}
196
197#[derive(Identifiable, Insertable, Queryable, Debug, Clone)]
198#[diesel(table_name = events, primary_key(id))]
199pub struct DbEvent {
200 pub id: OwnedEventId,
201 pub sn: i64,
202 pub ty: String,
203 pub room_id: OwnedRoomId,
204 pub depth: i64,
205 pub topological_ordering: i64,
206 pub stream_ordering: i64,
207 pub unrecognized_keys: Option<String>,
208 pub origin_server_ts: Option<UnixMillis>,
209 pub received_at: Option<i64>,
210 pub sender_id: Option<OwnedUserId>,
211 pub contains_url: bool,
212 pub worker_id: Option<String>,
213 pub state_key: Option<String>,
214 pub is_outlier: bool,
215 pub is_redacted: bool,
216 pub soft_failed: bool,
217 pub rejection_reason: Option<String>,
218}
219#[derive(Insertable, AsChangeset, Deserialize, Debug, Clone)]
220#[diesel(table_name = events, primary_key(id))]
221pub struct NewDbEvent {
222 pub id: OwnedEventId,
223 pub sn: i64,
224 #[serde(rename = "type")]
225 pub ty: String,
226 pub room_id: OwnedRoomId,
227 pub depth: i64,
228 pub topological_ordering: i64,
229 pub stream_ordering: i64,
230 pub unrecognized_keys: Option<String>,
231 pub origin_server_ts: Option<UnixMillis>,
232 pub received_at: Option<i64>,
233 pub sender_id: Option<OwnedUserId>,
234 #[serde(default = "default_false")]
235 pub contains_url: bool,
236 pub worker_id: Option<String>,
237 pub state_key: Option<String>,
238 #[serde(default = "default_false")]
239 pub is_outlier: bool,
240 #[serde(default = "default_false")]
241 pub soft_failed: bool,
242 pub rejection_reason: Option<String>,
243}
244
245impl NewDbEvent {
246 pub fn from_canonical_json(id: &EventId, sn: Seqnum, value: &CanonicalJsonObject) -> DataResult<Self> {
247 Self::from_json_value(id, sn, serde_json::to_value(value)?)
248 }
249 pub fn from_json_value(id: &EventId, sn: Seqnum, mut value: JsonValue) -> DataResult<Self> {
250 let depth = value.get("depth").cloned().unwrap_or(0.into());
251 let obj = value.as_object_mut().ok_or(MatrixError::bad_json("Invalid event"))?;
252 obj.insert("id".into(), id.as_str().into());
253 obj.insert("sn".into(), sn.into());
254 obj.insert("topological_ordering".into(), depth);
255 obj.insert("stream_ordering".into(), 0.into());
256 Ok(serde_json::from_value(value).map_err(|e| MatrixError::bad_json("invalid json for event"))?)
257 }
258}
259
260#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
261#[diesel(table_name = event_txn_ids, primary_key(event_id))]
262pub struct DbEventTxnId {
263 pub id: i64,
264 pub txn_id: OwnedTransactionId,
265 pub room_id: OwnedRoomId,
266 pub user_id: OwnedUserId,
267 pub device_id: Option<OwnedDeviceId>,
268 pub event_id: Option<OwnedEventId>,
269 pub created_at: UnixMillis,
270}
271
272#[derive(Insertable, Identifiable, Queryable, Debug, Clone)]
273#[diesel(table_name = event_txn_ids, primary_key(event_id))]
274pub struct NewDbEventTxnId {
275 pub txn_id: OwnedTransactionId,
276 pub user_id: OwnedUserId,
277 pub room_id: Option<OwnedRoomId>,
278 pub device_id: Option<OwnedDeviceId>,
279 pub event_id: Option<OwnedEventId>,
280 pub created_at: UnixMillis,
281}