Skip to content

Commit

Permalink
Server: Fixed items.owner_id migration
Browse files Browse the repository at this point in the history
  • Loading branch information
laurent22 committed Oct 27, 2021
1 parent dca13b3 commit a753429
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 33 deletions.
7 changes: 4 additions & 3 deletions packages/server/src/commands/MigrateCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum ArgvCommand {

interface Argv {
command: ArgvCommand;
disableTransactions?: boolean;
}

export default class MigrateCommand extends BaseCommand {
Expand Down Expand Up @@ -53,13 +54,13 @@ export default class MigrateCommand extends BaseCommand {
public async run(argv: Argv, runContext: RunContext): Promise<void> {
const commands: Record<ArgvCommand, Function> = {
up: async () => {
await migrateUp(runContext.db);
await migrateUp(runContext.db, argv.disableTransactions);
},
down: async () => {
await migrateDown(runContext.db);
await migrateDown(runContext.db, argv.disableTransactions);
},
latest: async () => {
await migrateLatest(runContext.db);
await migrateLatest(runContext.db, argv.disableTransactions);
},
list: async () => {
const s = (await migrateList(runContext.db)) as string;
Expand Down
71 changes: 41 additions & 30 deletions packages/server/src/migrations/20211027112530_item_owner.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,52 @@
import { Knex } from 'knex';
import { DbConnection, isPostgres } from '../db';
import { DbConnection } from '../db';

export async function up(db: DbConnection): Promise<any> {
await db.schema.alterTable('items', (table: Knex.CreateTableBuilder) => {
table.string('owner_id', 32).defaultTo('').notNullable();
});
if (!(await db.schema.hasColumn('items', 'owner_id'))) {
await db.schema.alterTable('items', (table: Knex.CreateTableBuilder) => {
table.string('owner_id', 32).defaultTo('').notNullable();
});
}

if (isPostgres(db)) {
await db.raw(`
UPDATE items
SET owner_id = user_items.user_id
FROM user_items
WHERE user_items.item_id = items.id
`);
} else {
// Very inefficient way to set the owner_id but SQLite is probably not
// used with very large dataset.

interface Row {
id: string;
user_id: string;
}
// This query never finishes - so can't use it

// await db.raw(`
// UPDATE items^
// SET owner_id = user_items.user_id
// FROM user_items
// WHERE user_items.item_id = items.id
// `);

interface Row {
id: string;
user_id: string;
}

const pageSize = 10000;

const itemCount = (await db('items')
.count('id', { as: 'total' })
.where('owner_id', '=', '')
.first())['total'];

while (true) {
const items: Row[] = await
db('items')
.join('user_items', 'items.id', 'user_items.item_id')
.select(['items.id', 'user_items.user_id'])
.where('owner_id', '=', '')
.limit(10000);
let itemDone = 0;

if (!items.length) break;
while (true) {
const items: Row[] = await db('items')
.join('user_items', 'items.id', 'user_items.item_id')
.select(['items.id', 'user_items.user_id'])
.where('owner_id', '=', '')
.limit(pageSize);

for (const item of items) {
await db('items').update({ owner_id: item.user_id }).where('id', '=', item.id);
}
if (!items.length) break;

console.info(`Processing items ${itemDone} / ${itemCount}`);

for (const item of items) {
await db('items').update({ owner_id: item.user_id }).where('id', '=', item.id);
}

itemDone += items.length;
}

await db.schema.alterTable('items', (table: Knex.CreateTableBuilder) => {
Expand Down

0 comments on commit a753429

Please sign in to comment.