@@ -48,6 +48,7 @@ struct _param
4848 char * pg_host ;
4949 int verbose ;
5050 int dry_run ;
51+ long transaction_limit ;
5152};
5253
5354int vacuumlo (char * , struct _param * );
@@ -65,11 +66,12 @@ vacuumlo(char *database, struct _param * param)
6566 PGresult * res ,
6667 * res2 ;
6768 char buf [BUFSIZE ];
68- int matched ;
69- int deleted ;
69+ long matched ;
70+ long deleted ;
7071 int i ;
7172 static char * password = NULL ;
7273 bool new_pass ;
74+ bool success = true;
7375
7476 if (param -> pg_prompt == TRI_YES && password == NULL )
7577 password = simple_prompt ("Password: " , 100 , false);
@@ -280,12 +282,19 @@ vacuumlo(char *database, struct _param * param)
280282 {
281283 fprintf (stderr , "\nFailed to remove lo %u: " , lo );
282284 fprintf (stderr , "%s" , PQerrorMessage (conn ));
285+ if (PQtransactionStatus (conn ) == PQTRANS_INERROR )
286+ {
287+ success = false;
288+ break ;
289+ }
283290 }
284291 else
285292 deleted ++ ;
286293 }
287294 else
288295 deleted ++ ;
296+ if (param -> transaction_limit != 0 && deleted >= param -> transaction_limit )
297+ break ;
289298 }
290299 PQclear (res );
291300
@@ -298,10 +307,20 @@ vacuumlo(char *database, struct _param * param)
298307 PQfinish (conn );
299308
300309 if (param -> verbose )
301- fprintf (stdout , "\r%s %d large objects from %s.\n" ,
302- (param -> dry_run ? "Would remove" : "Removed" ), deleted , database );
310+ {
311+ if (param -> dry_run )
312+ fprintf (stdout , "\rWould remove %ld large objects from %s.\n" ,
313+ deleted , database );
314+ else if (success )
315+ fprintf (stdout ,
316+ "\rSuccessfully removed %ld large objects from %s.\n" ,
317+ deleted , database );
318+ else
319+ fprintf (stdout , "\rRemoval from %s failed at object %ld of %ld.\n" ,
320+ database , deleted , matched );
321+ }
303322
304- return 0 ;
323+ return (( param -> dry_run || success ) ? 0 : -1 ) ;
305324}
306325
307326void
@@ -311,6 +330,7 @@ usage(const char *progname)
311330 printf ("Usage:\n %s [OPTION]... DBNAME...\n\n" , progname );
312331 printf ("Options:\n" );
313332 printf (" -h HOSTNAME database server host or socket directory\n" );
333+ printf (" -l LIMIT stop after removing LIMIT large objects\n" );
314334 printf (" -n don't remove large objects, just show what would be done\n" );
315335 printf (" -p PORT database server port\n" );
316336 printf (" -U USERNAME user name to connect as\n" );
@@ -342,6 +362,7 @@ main(int argc, char **argv)
342362 param .pg_port = NULL ;
343363 param .verbose = 0 ;
344364 param .dry_run = 0 ;
365+ param .transaction_limit = 0 ;
345366
346367 if (argc > 1 )
347368 {
@@ -359,7 +380,7 @@ main(int argc, char **argv)
359380
360381 while (1 )
361382 {
362- c = getopt (argc , argv , "h:U:p:vnwW" );
383+ c = getopt (argc , argv , "h:l: U:p:vnwW" );
363384 if (c == -1 )
364385 break ;
365386
@@ -395,6 +416,16 @@ main(int argc, char **argv)
395416 }
396417 param .pg_port = strdup (optarg );
397418 break ;
419+ case 'l' :
420+ param .transaction_limit = strtol (optarg , NULL , 10 );
421+ if (param .transaction_limit < 0 )
422+ {
423+ fprintf (stderr ,
424+ "%s: transaction limit must not be negative (0 disables)\n" ,
425+ progname );
426+ exit (1 );
427+ }
428+ break ;
398429 case 'h' :
399430 param .pg_host = strdup (optarg );
400431 break ;
0 commit comments