@@ -128,6 +128,7 @@ def database_init():
128
128
create_message_details_deleter ,
129
129
check_for_hacks ,
130
130
seqno_etc_updates ,
131
+ user_perm_future_updates ,
131
132
):
132
133
with transaction (conn ):
133
134
if migrate (conn ):
@@ -479,6 +480,76 @@ def seqno_etc_updates(conn):
479
480
return True
480
481
481
482
483
+ def user_perm_future_updates (conn ):
484
+ """
485
+ Break up user_permission_futures to not be (room,user) unique, and to move ban futures to a
486
+ separate table.
487
+ """
488
+
489
+ if 'user_ban_futures' in metadata .tables :
490
+ return False
491
+
492
+ logging .warning ("Updating user_permission_futures" )
493
+
494
+ if engine .name == 'sqlite' :
495
+ # Under sqlite we have to drop and recreate the whole thing. (Since we didn't have a
496
+ # release out that was using futures yet, we don't bother trying to migrate data).
497
+ conn .execute ("DROP TABLE user_permission_futures" )
498
+ conn .execute (
499
+ """
500
+ CREATE TABLE user_permission_futures (
501
+ room INTEGER NOT NULL REFERENCES rooms ON DELETE CASCADE,
502
+ user INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
503
+ at FLOAT NOT NULL, /* when the change should take effect (unix epoch) */
504
+ read BOOLEAN, /* Set this value @ at, if non-null */
505
+ write BOOLEAN, /* Set this value @ at, if non-null */
506
+ upload BOOLEAN /* Set this value @ at, if non-null */
507
+ )
508
+ """
509
+ )
510
+ conn .execute ("CREATE INDEX user_permission_futures_at ON user_permission_futures(at)" )
511
+ conn .execute (
512
+ """
513
+ CREATE INDEX user_permission_futures_room_user ON user_permission_futures(room, user)
514
+ """
515
+ )
516
+
517
+ conn .execute (
518
+ """
519
+ CREATE TABLE user_ban_futures (
520
+ room INTEGER REFERENCES rooms ON DELETE CASCADE,
521
+ user INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
522
+ at FLOAT NOT NULL, /* when the change should take effect (unix epoch) */
523
+ banned BOOLEAN NOT NULL /* if true then ban at `at`, if false then unban */
524
+ );
525
+ """
526
+ )
527
+ conn .execute ("CREATE INDEX user_ban_futures_at ON user_ban_futures(at)" )
528
+ conn .execute ("CREATE INDEX user_ban_futures_room_user ON user_ban_futures(room, user)" )
529
+
530
+ else : # postgresql
531
+ conn .execute (
532
+ """
533
+ CREATE TABLE user_ban_futures (
534
+ room INTEGER NOT NULL REFERENCES rooms ON DELETE CASCADE,
535
+ "user" INTEGER NOT NULL REFERENCES users ON DELETE CASCADE,
536
+ at FLOAT NOT NULL, /* when the change should take effect (unix epoch) */
537
+ banned BOOLEAN NOT NULL /* if true then ban at `at`, if false then unban */
538
+ );
539
+ CREATE INDEX user_ban_futures_at ON user_ban_futures(at);
540
+ CREATE INDEX user_ban_futures_room_user ON user_ban_futures(room, "user");
541
+
542
+ INSERT INTO user_ban_futures (room, "user", at, banned)
543
+ SELECT room, "user", at, banned FROM user_permission_futures WHERE banned is NOT NULL;
544
+
545
+ ALTER TABLE user_permission_futures DROP PRIMARY KEY;
546
+ ALTER TABLE user_permission_futures DROP COLUMN banned;
547
+ """
548
+ )
549
+
550
+ return True
551
+
552
+
482
553
def create_admin_user (dbconn ):
483
554
"""
484
555
We create a dummy user (with id 0) for system tasks such as changing moderators from
0 commit comments