From 4aea3a80556cf1d540eb5ef9d346f9a522062973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 5 Mar 2026 20:31:36 -0500 Subject: [PATCH] refactor: switch to cursor --- src/database/mongo/main.js | 16 ++++++++++--- src/database/postgres/main.js | 45 ++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/database/mongo/main.js b/src/database/mongo/main.js index 67ff7ac8fa..77f1f1409c 100644 --- a/src/database/mongo/main.js +++ b/src/database/mongo/main.js @@ -40,9 +40,19 @@ module.exports = function (module) { module.scan = async function (params) { const match = dbHelpers.globToRegex(params.match); - return await module.client.collection('objects').distinct( - '_key', { _key: { $regex: new RegExp(match) } } - ); + const cursor = await module.client.collection('objects').find({ + _key: { $regex: new RegExp(match) }, + }, { + projection: { _id: 0, _key: 1 }, + }).batchSize(params.batch || 1000); + const found = new Set(); + // eslint-disable-next-line no-await-in-loop + while (await cursor.hasNext()) { + // eslint-disable-next-line no-await-in-loop + const item = await cursor.next(); + found.add(item._key); + } + return Array.from(found); }; module.delete = async function (key) { diff --git a/src/database/postgres/main.js b/src/database/postgres/main.js index 6c397b8879..163e97fb13 100644 --- a/src/database/postgres/main.js +++ b/src/database/postgres/main.js @@ -1,6 +1,7 @@ 'use strict'; module.exports = function (module) { + const Cursor = require('pg-cursor'); const helpers = require('./helpers'); const dbHelpers = require('../helpers'); @@ -85,17 +86,43 @@ module.exports = function (module) { }; module.scan = async function (params) { - const regex = dbHelpers.globToRegex(params.match); + const match = dbHelpers.globToRegex(params.match); + const batchSize = params.batch || 1000; + const found = new Set(); - const res = await module.pool.query({ - text: ` - SELECT o."_key" - FROM "legacy_object_live" o - WHERE o."_key" ~ $1`, - values: [regex], - }); + const client = await module.pool.connect(); - return res.rows.map(r => r._key); + const cursor = client.query(new Cursor(` + SELECT "_key" + FROM "legacy_object_live" + WHERE "_key" ~ $1 + `, [match])); + + try { + const fetchRows = () => { + return new Promise((resolve, reject) => { + cursor.read(batchSize, (err, rows) => { + if (err) return reject(err); + resolve(rows); + }); + }); + }; + + let rows; + do { + // eslint-disable-next-line no-await-in-loop + rows = await fetchRows(); + for (const row of rows) { + found.add(row._key); + } + } while (rows.length > 0); + } finally { + cursor.close(() => { + client.release(); + }); + } + + return Array.from(found); }; module.delete = async function (key) {