fix sqlite/postgres incompatibility in reap_monthly_active_users

This commit is contained in:
Neil Johnson 2018-08-11 22:38:34 +01:00
parent a001038b92
commit 31fa743567

View file

@ -64,23 +64,27 @@ class MonthlyActiveUsersStore(SQLBaseStore):
Deferred[] Deferred[]
""" """
def _reap_users(txn): def _reap_users(txn):
# Purge stale users
thirty_days_ago = ( thirty_days_ago = (
int(self._clock.time_msec()) - (1000 * 60 * 60 * 24 * 30) int(self._clock.time_msec()) - (1000 * 60 * 60 * 24 * 30)
) )
# Purge stale users
# questionmarks is a hack to overcome sqlite not supporting
# tuples in 'WHERE IN %s'
questionmarks = '?' * len(self.reserved_users)
query_args = [thirty_days_ago] query_args = [thirty_days_ago]
query_args.extend(self.reserved_users) base_sql = "DELETE FROM monthly_active_users WHERE timestamp < ?"
sql = """ # Need if/else since 'AND user_id NOT IN ({})' fails on Postgres
DELETE FROM monthly_active_users # when len(reserved_users) == 0. Works fine on sqlite.
WHERE timestamp < ? if len(self.reserved_users) > 0:
AND user_id NOT IN ({}) # questionmarks is a hack to overcome sqlite not supporting
""".format(','.join(questionmarks)) # tuples in 'WHERE IN %s'
questionmarks = '?' * len(self.reserved_users)
query_args.extend(self.reserved_users)
sql = base_sql + """ AND user_id NOT IN ({})""".format(
','.join(questionmarks)
)
else:
sql = base_sql
txn.execute(sql, query_args) txn.execute(sql, query_args)
@ -93,16 +97,24 @@ class MonthlyActiveUsersStore(SQLBaseStore):
# negative LIMIT values. So there is no way to write it that both can # negative LIMIT values. So there is no way to write it that both can
# support # support
query_args = [self.hs.config.max_mau_value] query_args = [self.hs.config.max_mau_value]
query_args.extend(self.reserved_users)
sql = """ base_sql = """
DELETE FROM monthly_active_users DELETE FROM monthly_active_users
WHERE user_id NOT IN ( WHERE user_id NOT IN (
SELECT user_id FROM monthly_active_users SELECT user_id FROM monthly_active_users
ORDER BY timestamp DESC ORDER BY timestamp DESC
LIMIT ? LIMIT ?
) )
AND user_id NOT IN ({}) """
""".format(','.join(questionmarks)) # Need if/else since 'AND user_id NOT IN ({})' fails on Postgres
# when len(reserved_users) == 0. Works fine on sqlite.
if len(self.reserved_users) > 0:
query_args.extend(self.reserved_users)
sql = base_sql + """ AND user_id NOT IN ({})""".format(
','.join(questionmarks)
)
else:
sql = base_sql
txn.execute(sql, query_args) txn.execute(sql, query_args)
yield self.runInteraction("reap_monthly_active_users", _reap_users) yield self.runInteraction("reap_monthly_active_users", _reap_users)