@@ -48,6 +48,7 @@ struct _param
4848char * pg_host ;
4949int verbose ;
5050int dry_run ;
51+ long transaction_limit ;
5152};
5253
5354int vacuumlo (char * ,struct _param * );
@@ -65,11 +66,12 @@ vacuumlo(char *database, struct _param * param)
6566PGresult * res ,
6667* res2 ;
6768char buf [BUFSIZE ];
68- int matched ;
69- int deleted ;
69+ long matched ;
70+ long deleted ;
7071int i ;
7172static char * password = NULL ;
7273bool new_pass ;
74+ bool success = true;
7375
7476if (param -> pg_prompt == TRI_YES && password == NULL )
7577password = simple_prompt ("Password: " ,100 , false);
@@ -280,12 +282,19 @@ vacuumlo(char *database, struct _param * param)
280282{
281283fprintf (stderr ,"\nFailed to remove lo %u: " ,lo );
282284fprintf (stderr ,"%s" ,PQerrorMessage (conn ));
285+ if (PQtransactionStatus (conn )== PQTRANS_INERROR )
286+ {
287+ success = false;
288+ break ;
289+ }
283290}
284291else
285292deleted ++ ;
286293}
287294else
288295deleted ++ ;
296+ if (param -> transaction_limit != 0 && deleted >=param -> transaction_limit )
297+ break ;
289298}
290299PQclear (res );
291300
@@ -298,10 +307,20 @@ vacuumlo(char *database, struct _param * param)
298307PQfinish (conn );
299308
300309if (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)
311330printf ("Usage:\n %s [OPTION]... DBNAME...\n\n" ,progname );
312331printf ("Options:\n" );
313332printf (" -h HOSTNAME database server host or socket directory\n" );
333+ printf (" -l LIMIT stop after removing LIMIT large objects\n" );
314334printf (" -n don't remove large objects, just show what would be done\n" );
315335printf (" -p PORT database server port\n" );
316336printf (" -U USERNAME user name to connect as\n" );
@@ -342,6 +362,7 @@ main(int argc, char **argv)
342362param .pg_port = NULL ;
343363param .verbose = 0 ;
344364param .dry_run = 0 ;
365+ param .transaction_limit = 0 ;
345366
346367if (argc > 1 )
347368{
@@ -359,7 +380,7 @@ main(int argc, char **argv)
359380
360381while (1 )
361382{
362- c = getopt (argc ,argv ,"h:U:p:vnwW" );
383+ c = getopt (argc ,argv ,"h:l: U:p:vnwW" );
363384if (c == -1 )
364385break ;
365386
@@ -395,6 +416,16 @@ main(int argc, char **argv)
395416}
396417param .pg_port = strdup (optarg );
397418break ;
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 ;
398429case 'h' :
399430param .pg_host = strdup (optarg );
400431break ;