From cbb07318e54e96d57b4e06007888572891a7e141 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 29 Dec 2023 12:53:49 +0800 Subject: [PATCH] get the unchanged result set of sub query by checking updated_at --- packages/api/src/services/library_item.ts | 51 ++++++----------------- 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/packages/api/src/services/library_item.ts b/packages/api/src/services/library_item.ts index add98f09c..6bca196b6 100644 --- a/packages/api/src/services/library_item.ts +++ b/packages/api/src/services/library_item.ts @@ -991,54 +991,29 @@ export const batchUpdateLibraryItems = async ( } // generate raw sql because postgres doesn't support prepared statements in DO blocks - const countSql = queryBuilderToRawSql( - queryBuilder.select('COUNT(1) INTO total_rows') - ) - const subQuery = queryBuilderToRawSql( - queryBuilder.select('id').orderBy('id') - ) + const countSql = queryBuilderToRawSql(queryBuilder.select('COUNT(1)')) + const subQuery = queryBuilderToRawSql(queryBuilder.select('id')) const valuesSql = valuesToRawSql(values) - const batchSize = 100 + const start = new Date().toISOString() + const batchSize = 1000 const sql = ` -- Set batch size DO $$ DECLARE batch_size INT := ${batchSize}; - total_rows INT; - num_batches INT; - batch_id UUID; - batch_cursor CURSOR FOR - ${subQuery}; BEGIN - -- Get the total count of rows to be updated - ${countSql}; - - -- Calculate the number of batches - num_batches := CEIL(total_rows * 1.0 / batch_size); - - -- Open a cursor - OPEN batch_cursor; - -- Loop through batches - FOR i IN 0..num_batches-1 LOOP - -- Fetch the next batch of IDs - FOR j IN 0..batch_size-1 LOOP - -- Fetch the next ID - FETCH batch_cursor INTO batch_id; - - -- Exit the loop if no more rows - EXIT WHEN NOT FOUND; - - -- Perform incremental update for the current ID - UPDATE omnivore.library_item - SET ${valuesSql} - WHERE id = batch_id; - END LOOP; + FOR i IN 0..CEIL((${countSql}) * 1.0 / batch_size) - 1 LOOP + -- Update the batch + UPDATE omnivore.library_item + SET ${valuesSql} + WHERE id = ANY( + ${subQuery} + AND updated_at < '${start}' + LIMIT batch_size + ); END LOOP; - - -- Close the cursor - CLOSE batch_cursor; END $$ `