mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
Create user last connection datetime (#935)
Each time the a Grist page is reload the `last_connection_at` of the user is updated resolve [#924](https://github.com/gristlabs/grist-core/issues/924)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import {User} from 'app/gen-server/entity/User';
|
||||
import {makeId} from 'app/server/lib/idUtils';
|
||||
import {chunk} from 'lodash';
|
||||
import {MigrationInterface, QueryRunner, TableColumn} from "typeorm";
|
||||
|
||||
export class UserUUID1663851423064 implements MigrationInterface {
|
||||
@@ -16,11 +16,20 @@ export class UserUUID1663851423064 implements MigrationInterface {
|
||||
// Updating so many rows in a multiple queries is not ideal. We will send updates in chunks.
|
||||
// 300 seems to be a good number, for 24k rows we have 80 queries.
|
||||
const userList = await queryRunner.manager.createQueryBuilder()
|
||||
.select("users")
|
||||
.from(User, "users")
|
||||
.select(["users.id", "users.ref"])
|
||||
.from("users", "users")
|
||||
.getMany();
|
||||
userList.forEach(u => u.ref = makeId());
|
||||
await queryRunner.manager.save(userList, { chunk: 300 });
|
||||
|
||||
const userChunks = chunk(userList, 300);
|
||||
for (const users of userChunks) {
|
||||
await queryRunner.connection.transaction(async manager => {
|
||||
const queries = users.map((user: any, _index: number, _array: any[]) => {
|
||||
return queryRunner.manager.update("users", user.id, user);
|
||||
});
|
||||
await Promise.all(queries);
|
||||
});
|
||||
}
|
||||
|
||||
// We are not making this column unique yet, because it can fail
|
||||
// if there are some old workers still running, and any new user
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {User} from 'app/gen-server/entity/User';
|
||||
import {makeId} from 'app/server/lib/idUtils';
|
||||
import {chunk} from 'lodash';
|
||||
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||
|
||||
export class UserRefUnique1664528376930 implements MigrationInterface {
|
||||
@@ -9,12 +9,21 @@ export class UserRefUnique1664528376930 implements MigrationInterface {
|
||||
|
||||
// Update users that don't have unique ref set.
|
||||
const userList = await queryRunner.manager.createQueryBuilder()
|
||||
.select("users")
|
||||
.from(User, "users")
|
||||
.where("ref is null")
|
||||
.getMany();
|
||||
.select(["users.id", "users.ref"])
|
||||
.from("users", "users")
|
||||
.where("users.ref is null")
|
||||
.getMany();
|
||||
userList.forEach(u => u.ref = makeId());
|
||||
await queryRunner.manager.save(userList, {chunk: 300});
|
||||
|
||||
const userChunks = chunk(userList, 300);
|
||||
for (const users of userChunks) {
|
||||
await queryRunner.connection.transaction(async manager => {
|
||||
const queries = users.map((user: any, _index: number, _array: any[]) => {
|
||||
return queryRunner.manager.update("users", user.id, user);
|
||||
});
|
||||
await Promise.all(queries);
|
||||
});
|
||||
}
|
||||
|
||||
// Mark column as unique and non-nullable.
|
||||
const users = (await queryRunner.getTable('users'))!;
|
||||
|
||||
18
app/gen-server/migration/1713186031023-UserLastConnection.ts
Normal file
18
app/gen-server/migration/1713186031023-UserLastConnection.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import {MigrationInterface, QueryRunner, TableColumn} from 'typeorm';
|
||||
|
||||
export class UserLastConnection1713186031023 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||
const sqlite = queryRunner.connection.driver.options.type === 'sqlite';
|
||||
const datetime = sqlite ? "datetime" : "timestamp with time zone";
|
||||
await queryRunner.addColumn('users', new TableColumn({
|
||||
name: 'last_connection_at',
|
||||
type: datetime,
|
||||
isNullable: true
|
||||
}));
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||
await queryRunner.dropColumn('users', 'last_connection_at');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user