14
14
import calendar
15
15
import logging
16
16
import time
17
- from typing import TYPE_CHECKING , Dict
17
+ from typing import TYPE_CHECKING , Dict , List , Tuple , cast
18
18
19
19
from synapse .metrics import GaugeBucketCollector
20
20
from synapse .metrics .background_process_metrics import wrap_as_background_process
21
21
from synapse .storage ._base import SQLBaseStore
22
- from synapse .storage .database import DatabasePool , LoggingDatabaseConnection
22
+ from synapse .storage .database import (
23
+ DatabasePool ,
24
+ LoggingDatabaseConnection ,
25
+ LoggingTransaction ,
26
+ )
23
27
from synapse .storage .databases .main .event_push_actions import (
24
28
EventPushActionsWorkerStore ,
25
29
)
26
- from synapse .storage .types import Cursor
27
30
28
31
if TYPE_CHECKING :
29
32
from synapse .server import HomeServer
@@ -73,7 +76,7 @@ def __init__(
73
76
74
77
@wrap_as_background_process ("read_forward_extremities" )
75
78
async def _read_forward_extremities (self ) -> None :
76
- def fetch (txn ) :
79
+ def fetch (txn : LoggingTransaction ) -> List [ Tuple [ int , int ]] :
77
80
txn .execute (
78
81
"""
79
82
SELECT t1.c, t2.c
@@ -86,7 +89,7 @@ def fetch(txn):
86
89
) t2 ON t1.room_id = t2.room_id
87
90
"""
88
91
)
89
- return txn .fetchall ()
92
+ return cast ( List [ Tuple [ int , int ]], txn .fetchall () )
90
93
91
94
res = await self .db_pool .runInteraction ("read_forward_extremities" , fetch )
92
95
@@ -104,20 +107,20 @@ async def count_daily_e2ee_messages(self) -> int:
104
107
call to this function, it will return None.
105
108
"""
106
109
107
- def _count_messages (txn ) :
110
+ def _count_messages (txn : LoggingTransaction ) -> int :
108
111
sql = """
109
112
SELECT COUNT(*) FROM events
110
113
WHERE type = 'm.room.encrypted'
111
114
AND stream_ordering > ?
112
115
"""
113
116
txn .execute (sql , (self .stream_ordering_day_ago ,))
114
- (count ,) = txn .fetchone ()
117
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
115
118
return count
116
119
117
120
return await self .db_pool .runInteraction ("count_e2ee_messages" , _count_messages )
118
121
119
122
async def count_daily_sent_e2ee_messages (self ) -> int :
120
- def _count_messages (txn ) :
123
+ def _count_messages (txn : LoggingTransaction ) -> int :
121
124
# This is good enough as if you have silly characters in your own
122
125
# hostname then that's your own fault.
123
126
like_clause = "%:" + self .hs .hostname
@@ -130,22 +133,22 @@ def _count_messages(txn):
130
133
"""
131
134
132
135
txn .execute (sql , (like_clause , self .stream_ordering_day_ago ))
133
- (count ,) = txn .fetchone ()
136
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
134
137
return count
135
138
136
139
return await self .db_pool .runInteraction (
137
140
"count_daily_sent_e2ee_messages" , _count_messages
138
141
)
139
142
140
143
async def count_daily_active_e2ee_rooms (self ) -> int :
141
- def _count (txn ) :
144
+ def _count (txn : LoggingTransaction ) -> int :
142
145
sql = """
143
146
SELECT COUNT(DISTINCT room_id) FROM events
144
147
WHERE type = 'm.room.encrypted'
145
148
AND stream_ordering > ?
146
149
"""
147
150
txn .execute (sql , (self .stream_ordering_day_ago ,))
148
- (count ,) = txn .fetchone ()
151
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
149
152
return count
150
153
151
154
return await self .db_pool .runInteraction (
@@ -160,20 +163,20 @@ async def count_daily_messages(self) -> int:
160
163
call to this function, it will return None.
161
164
"""
162
165
163
- def _count_messages (txn ) :
166
+ def _count_messages (txn : LoggingTransaction ) -> int :
164
167
sql = """
165
168
SELECT COUNT(*) FROM events
166
169
WHERE type = 'm.room.message'
167
170
AND stream_ordering > ?
168
171
"""
169
172
txn .execute (sql , (self .stream_ordering_day_ago ,))
170
- (count ,) = txn .fetchone ()
173
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
171
174
return count
172
175
173
176
return await self .db_pool .runInteraction ("count_messages" , _count_messages )
174
177
175
178
async def count_daily_sent_messages (self ) -> int :
176
- def _count_messages (txn ) :
179
+ def _count_messages (txn : LoggingTransaction ) -> int :
177
180
# This is good enough as if you have silly characters in your own
178
181
# hostname then that's your own fault.
179
182
like_clause = "%:" + self .hs .hostname
@@ -186,22 +189,22 @@ def _count_messages(txn):
186
189
"""
187
190
188
191
txn .execute (sql , (like_clause , self .stream_ordering_day_ago ))
189
- (count ,) = txn .fetchone ()
192
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
190
193
return count
191
194
192
195
return await self .db_pool .runInteraction (
193
196
"count_daily_sent_messages" , _count_messages
194
197
)
195
198
196
199
async def count_daily_active_rooms (self ) -> int :
197
- def _count (txn ) :
200
+ def _count (txn : LoggingTransaction ) -> int :
198
201
sql = """
199
202
SELECT COUNT(DISTINCT room_id) FROM events
200
203
WHERE type = 'm.room.message'
201
204
AND stream_ordering > ?
202
205
"""
203
206
txn .execute (sql , (self .stream_ordering_day_ago ,))
204
- (count ,) = txn .fetchone ()
207
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
205
208
return count
206
209
207
210
return await self .db_pool .runInteraction ("count_daily_active_rooms" , _count )
@@ -227,7 +230,7 @@ async def count_monthly_users(self) -> int:
227
230
"count_monthly_users" , self ._count_users , thirty_days_ago
228
231
)
229
232
230
- def _count_users (self , txn : Cursor , time_from : int ) -> int :
233
+ def _count_users (self , txn : LoggingTransaction , time_from : int ) -> int :
231
234
"""
232
235
Returns number of users seen in the past time_from period
233
236
"""
@@ -242,7 +245,7 @@ def _count_users(self, txn: Cursor, time_from: int) -> int:
242
245
# Mypy knows that fetchone() might return None if there are no rows.
243
246
# We know better: "SELECT COUNT(...) FROM ..." without any GROUP BY always
244
247
# returns exactly one row.
245
- (count ,) = txn .fetchone () # type: ignore[misc]
248
+ (count ,) = cast ( Tuple [ int ], txn .fetchone ())
246
249
return count
247
250
248
251
async def count_r30_users (self ) -> Dict [str , int ]:
@@ -256,7 +259,7 @@ async def count_r30_users(self) -> Dict[str, int]:
256
259
A mapping of counts globally as well as broken out by platform.
257
260
"""
258
261
259
- def _count_r30_users (txn ) :
262
+ def _count_r30_users (txn : LoggingTransaction ) -> Dict [ str , int ] :
260
263
thirty_days_in_secs = 86400 * 30
261
264
now = int (self ._clock .time ())
262
265
thirty_days_ago_in_secs = now - thirty_days_in_secs
@@ -321,7 +324,7 @@ def _count_r30_users(txn):
321
324
322
325
txn .execute (sql , (thirty_days_ago_in_secs , thirty_days_ago_in_secs ))
323
326
324
- (count ,) = txn .fetchone ()
327
+ (count ,) = cast ( Tuple [ int ], txn .fetchone () )
325
328
results ["all" ] = count
326
329
327
330
return results
@@ -348,7 +351,7 @@ async def count_r30v2_users(self) -> Dict[str, int]:
348
351
- "web" (any web application -- it's not possible to distinguish Element Web here)
349
352
"""
350
353
351
- def _count_r30v2_users (txn ) :
354
+ def _count_r30v2_users (txn : LoggingTransaction ) -> Dict [ str , int ] :
352
355
thirty_days_in_secs = 86400 * 30
353
356
now = int (self ._clock .time ())
354
357
sixty_days_ago_in_secs = now - 2 * thirty_days_in_secs
@@ -445,11 +448,8 @@ def _count_r30v2_users(txn):
445
448
thirty_days_in_secs * 1000 ,
446
449
),
447
450
)
448
- row = txn .fetchone ()
449
- if row is None :
450
- results ["all" ] = 0
451
- else :
452
- results ["all" ] = row [0 ]
451
+ (count ,) = cast (Tuple [int ], txn .fetchone ())
452
+ results ["all" ] = count
453
453
454
454
return results
455
455
@@ -471,7 +471,7 @@ async def generate_user_daily_visits(self) -> None:
471
471
Generates daily visit data for use in cohort/ retention analysis
472
472
"""
473
473
474
- def _generate_user_daily_visits (txn ) :
474
+ def _generate_user_daily_visits (txn : LoggingTransaction ) -> None :
475
475
logger .info ("Calling _generate_user_daily_visits" )
476
476
today_start = self ._get_start_of_day ()
477
477
a_day_in_milliseconds = 24 * 60 * 60 * 1000
0 commit comments