(args: string[] = process.argv.slice(2))
| 216 | } |
| 217 | |
| 218 | export const runCleanDb = async (args: string[] = process.argv.slice(2)): Promise<number> => { |
| 219 | const options = parseCleanDbOptions(args) |
| 220 | |
| 221 | if (options.help) { |
| 222 | console.log(HELP_TEXT) |
| 223 | return 0 |
| 224 | } |
| 225 | |
| 226 | if (process.env.NODE_ENV === 'production') { |
| 227 | console.warn('WARNING: NODE_ENV=production detected. This operation permanently deletes data.') |
| 228 | } |
| 229 | |
| 230 | const dbClient = getMasterDbClient() |
| 231 | |
| 232 | try { |
| 233 | if (options.dryRun) { |
| 234 | const matchingEvents = await getMatchingEventsCount(dbClient, options) |
| 235 | console.log(`Dry run: ${matchingEvents} events would be deleted.`) |
| 236 | return 0 |
| 237 | } |
| 238 | |
| 239 | if (!options.force) { |
| 240 | if (!process.stdin.isTTY) { |
| 241 | throw new Error('Interactive confirmation is unavailable. Re-run with --force.') |
| 242 | } |
| 243 | |
| 244 | const confirmed = await askForConfirmation() |
| 245 | if (!confirmed) { |
| 246 | console.log('Aborted. Confirmation text did not match DELETE.') |
| 247 | return 1 |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | if (options.all) { |
| 252 | const deletedEventTags = await runAllDelete(dbClient) |
| 253 | if (deletedEventTags) { |
| 254 | console.log('Deleted all rows from events and event_tags with TRUNCATE.') |
| 255 | } else { |
| 256 | console.log('Deleted all events with TRUNCATE.') |
| 257 | } |
| 258 | return 0 |
| 259 | } |
| 260 | |
| 261 | const deletedRows = await runSelectiveDelete(dbClient, options) |
| 262 | console.log(`Deleted ${deletedRows} events. VACUUM ANALYZE completed.`) |
| 263 | return 0 |
| 264 | } finally { |
| 265 | await dbClient.destroy() |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | if (require.main === module) { |
| 270 | runCleanDb() |
no test coverage detected