Skip to content

Commit

Permalink
User import
Browse files Browse the repository at this point in the history
  • Loading branch information
bhollis committed Dec 30, 2024
1 parent 5f8d56c commit 9b3268a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
8 changes: 8 additions & 0 deletions api/db/migration-state-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ interface MigrationStateRow {
last_error: string | null;
}

export async function getUsersToMigrate(client: ClientBase): Promise<number[]> {
const results = await client.query<MigrationStateRow>({
name: 'get_users_to_migrate',
text: 'select membership_id from settings where membership_id not in (select membership_id from migration_state) limit 1000',
});
return results.rows.map((row) => row.membership_id);
}

export async function getMigrationState(
client: ClientBase,
bungieMembershipId: number,
Expand Down
21 changes: 21 additions & 0 deletions api/stately/init/migrate-users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { readTransaction } from '../../db/index.js';
import { getUsersToMigrate } from '../../db/migration-state-queries.js';
import { delay } from '../../utils.js';
import { migrateUser } from '../migrator/user.js';

while (true) {
try {
const bungieMembershipIds = await readTransaction(async (client) => getUsersToMigrate(client));
for (const bungieMembershipId of bungieMembershipIds) {
try {
await migrateUser(bungieMembershipId);
console.log(`Migrated user ${bungieMembershipId}`);
} catch (e) {
console.error(`Error migrating user ${bungieMembershipId}: ${e}`);
}
}
} catch (e) {
console.error(`Error getting users to migrate: ${e}`);
await delay(1000);
}
}
44 changes: 44 additions & 0 deletions api/stately/migrator/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { isEmpty } from 'es-toolkit/compat';
import { doMigration } from '../../db/migration-state-queries.js';
import { pgExport } from '../../routes/export.js';
import { extractImportData, statelyImport } from '../../routes/import.js';

export async function migrateUser(bungieMembershipId: number): Promise<void> {
const importToStately = async () => {
// Export from Postgres
const exportResponse = await pgExport(bungieMembershipId);

const { settings, loadouts, itemAnnotations, triumphs, searches, itemHashTags } =
extractImportData(exportResponse);

const profileIds = new Set<string>();
exportResponse.loadouts.forEach((l) => profileIds.add(l.platformMembershipId));
exportResponse.tags.forEach((t) => profileIds.add(t.platformMembershipId));
exportResponse.triumphs.forEach((t) => profileIds.add(t.platformMembershipId));

if (
isEmpty(settings) &&
loadouts.length === 0 &&
itemAnnotations.length === 0 &&
triumphs.length === 0 &&
searches.length === 0
) {
// Nothing to import!
return;
}
await statelyImport(
bungieMembershipId,
[...profileIds],
settings,
loadouts,
itemAnnotations,
triumphs,
searches,
itemHashTags,
false,
);
};

// For now let's leave the old data in Postgres as a backup
await doMigration(bungieMembershipId, importToStately);
}

0 comments on commit 9b3268a

Please sign in to comment.