| 477 | |
| 478 | // REMOVE 10,000 record per batch |
| 479 | async function batchDeleteAndThenUpdate( |
| 480 | sequelize: Sequelize, |
| 481 | model: ModelStatic<any>, |
| 482 | transaction: Transaction, |
| 483 | targetBlockUnit: number, // Height or timestamp |
| 484 | batchSize = 10000 |
| 485 | ): Promise<void> { |
| 486 | let destroyCompleted = false; |
| 487 | let updateCompleted = false; |
| 488 | while (!destroyCompleted || !updateCompleted) { |
| 489 | try { |
| 490 | const [numDestroyRows, [numUpdatedRows]] = await Promise.all([ |
| 491 | destroyCompleted |
| 492 | ? 0 |
| 493 | : model.destroy({ |
| 494 | transaction, |
| 495 | hooks: false, |
| 496 | limit: batchSize, |
| 497 | where: sequelize.where(sequelize.fn('lower', sequelize.col('_block_range')), Op.gt, targetBlockUnit), |
| 498 | }), |
| 499 | updateCompleted |
| 500 | ? [0] |
| 501 | : model.update( |
| 502 | { |
| 503 | __block_range: sequelize.fn('int8range', sequelize.fn('lower', sequelize.col('_block_range')), null), |
| 504 | }, |
| 505 | { |
| 506 | transaction, |
| 507 | limit: batchSize, |
| 508 | hooks: false, |
| 509 | where: { |
| 510 | [Op.and]: [ |
| 511 | { |
| 512 | __block_range: { |
| 513 | [Op.contains]: targetBlockUnit, |
| 514 | }, |
| 515 | }, |
| 516 | sequelize.where(sequelize.fn('upper', sequelize.col('_block_range')), Op.not, null), |
| 517 | ], |
| 518 | }, |
| 519 | } |
| 520 | ), |
| 521 | ]); |
| 522 | logger.debug(`${model.name} deleted ${numDestroyRows} records, updated ${numUpdatedRows} records`); |
| 523 | if (numDestroyRows === 0) { |
| 524 | destroyCompleted = true; |
| 525 | } |
| 526 | if (numUpdatedRows === 0) { |
| 527 | updateCompleted = true; |
| 528 | } |
| 529 | } catch (e) { |
| 530 | throw new Error(`Reindex update model ${model.name} failed, please try to reindex again: ${e}`); |
| 531 | } |
| 532 | } |
| 533 | } |