Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc6a3fce

Browse files
committed
Add \watch [SEC] command to psql.
This allows convenient re-execution of commands.Will Leinweber, reviewed by Peter Eisentraut, Daniel Farina, and Tom Lane
1 parente75feb2 commitc6a3fce

File tree

4 files changed

+145
-2
lines changed

4 files changed

+145
-2
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,6 +2478,18 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
24782478
</varlistentry>
24792479

24802480

2481+
<varlistentry>
2482+
<term><literal>\watch [ <replaceable class="parameter">seconds</replaceable> ]</literal></term>
2483+
<listitem>
2484+
<para>
2485+
Repeatedly execute the current query buffer (like <literal>\g</>)
2486+
until interrupted or the query fails. Wait the specified number of
2487+
seconds (default 2) between executions.
2488+
</para>
2489+
</listitem>
2490+
</varlistentry>
2491+
2492+
24812493
<varlistentry>
24822494
<term><literal>\x [ <replaceable class="parameter">on</replaceable> | <replaceable class="parameter">off</replaceable> | <replaceable class="parameter">auto</replaceable> ]</literal></term>
24832495
<listitem>

‎src/bin/psql/command.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
6060
intlineno,bool*edited);
6161
staticbooldo_connect(char*dbname,char*user,char*host,char*port);
6262
staticbooldo_shell(constchar*command);
63+
staticbooldo_watch(PQExpBufferquery_buf,longsleep);
6364
staticboollookup_function_oid(PGconn*conn,constchar*desc,Oid*foid);
6465
staticboolget_create_function_cmd(PGconn*conn,Oidoid,PQExpBufferbuf);
6566
staticintstrip_lineno_from_funcdesc(char*func);
@@ -1433,6 +1434,29 @@ exec_command(const char *cmd,
14331434
free(fname);
14341435
}
14351436

1437+
/* \watch -- execute a query every N seconds */
1438+
elseif (strcmp(cmd,"watch")==0)
1439+
{
1440+
char*opt=psql_scan_slash_option(scan_state,
1441+
OT_NORMAL,NULL, true);
1442+
longsleep=2;
1443+
1444+
/* Convert optional sleep-length argument */
1445+
if (opt)
1446+
{
1447+
sleep=strtol(opt,NULL,10);
1448+
if (sleep <=0)
1449+
sleep=1;
1450+
free(opt);
1451+
}
1452+
1453+
success=do_watch(query_buf,sleep);
1454+
1455+
/* Reset the query buffer as though for \r */
1456+
resetPQExpBuffer(query_buf);
1457+
psql_scan_reset(scan_state);
1458+
}
1459+
14361460
/* \x -- set or toggle expanded table representation */
14371461
elseif (strcmp(cmd,"x")==0)
14381462
{
@@ -2555,6 +2579,112 @@ do_shell(const char *command)
25552579
return true;
25562580
}
25572581

2582+
/*
2583+
* do_watch -- handler for \watch
2584+
*
2585+
* We break this out of exec_command to avoid having to plaster "volatile"
2586+
* onto a bunch of exec_command's variables to silence stupider compilers.
2587+
*/
2588+
staticbool
2589+
do_watch(PQExpBufferquery_buf,longsleep)
2590+
{
2591+
printQueryOptmyopt=pset.popt;
2592+
chartitle[50];
2593+
2594+
if (!query_buf||query_buf->len <=0)
2595+
{
2596+
psql_error(_("\\watch cannot be used with an empty query\n"));
2597+
return false;
2598+
}
2599+
2600+
/*
2601+
* Set up rendering options, in particular, disable the pager, because
2602+
* nobody wants to be prompted while watching the output of 'watch'.
2603+
*/
2604+
myopt.nullPrint=NULL;
2605+
myopt.topt.pager=0;
2606+
2607+
for (;;)
2608+
{
2609+
PGresult*res;
2610+
time_ttimer;
2611+
longi;
2612+
2613+
/*
2614+
* Prepare title for output. XXX would it be better to use the time
2615+
* of completion of the command?
2616+
*/
2617+
timer=time(NULL);
2618+
snprintf(title,sizeof(title),_("Watch every %lds\t%s"),
2619+
sleep,asctime(localtime(&timer)));
2620+
myopt.title=title;
2621+
2622+
/*
2623+
* Run the query. We use PSQLexec, which is kind of cheating, but
2624+
* SendQuery doesn't let us suppress autocommit behavior.
2625+
*/
2626+
res=PSQLexec(query_buf->data, false);
2627+
2628+
/* PSQLexec handles failure results and returns NULL */
2629+
if (res==NULL)
2630+
break;
2631+
2632+
/*
2633+
* If SIGINT is sent while the query is processing, PSQLexec will
2634+
* consume the interrupt. The user's intention, though, is to cancel
2635+
* the entire watch process, so detect a sent cancellation request and
2636+
* exit in this case.
2637+
*/
2638+
if (cancel_pressed)
2639+
{
2640+
PQclear(res);
2641+
break;
2642+
}
2643+
2644+
switch (PQresultStatus(res))
2645+
{
2646+
casePGRES_TUPLES_OK:
2647+
printQuery(res,&myopt,pset.queryFout,pset.logfile);
2648+
break;
2649+
2650+
casePGRES_EMPTY_QUERY:
2651+
psql_error(_("\\watch cannot be used with an empty query\n"));
2652+
PQclear(res);
2653+
return false;
2654+
2655+
default:
2656+
/* should we fail for non-tuple-result commands? */
2657+
break;
2658+
}
2659+
2660+
PQclear(res);
2661+
2662+
/*
2663+
* Set up cancellation of 'watch' via SIGINT. We redo this each time
2664+
* through the loop since it's conceivable something inside PSQLexec
2665+
* could change sigint_interrupt_jmp.
2666+
*/
2667+
if (sigsetjmp(sigint_interrupt_jmp,1)!=0)
2668+
break;
2669+
2670+
/*
2671+
* Enable 'watch' cancellations and wait a while before running the
2672+
* query again. Break the sleep into short intervals since pg_usleep
2673+
* isn't interruptible on some platforms.
2674+
*/
2675+
sigint_interrupt_enabled= true;
2676+
for (i=0;i<sleep;i++)
2677+
{
2678+
pg_usleep(1000000L);
2679+
if (cancel_pressed)
2680+
break;
2681+
}
2682+
sigint_interrupt_enabled= false;
2683+
}
2684+
2685+
return true;
2686+
}
2687+
25582688
/*
25592689
* This function takes a function description, e.g. "x" or "x(int)", and
25602690
* issues a query on the given connection to retrieve the function's OID

‎src/bin/psql/help.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ slashUsage(unsigned short int pager)
165165

166166
currdb=PQdb(pset.db);
167167

168-
output=PageOutput(95,pager);
168+
output=PageOutput(96,pager);
169169

170170
/* if you add/remove a line here, change the row count above */
171171

@@ -175,6 +175,7 @@ slashUsage(unsigned short int pager)
175175
fprintf(output,_(" \\gset [PREFIX] execute query and store results in psql variables\n"));
176176
fprintf(output,_(" \\h [NAME] help on syntax of SQL commands, * for all commands\n"));
177177
fprintf(output,_(" \\q quit psql\n"));
178+
fprintf(output,_(" \\watch [SEC] execute query every SEC seconds\n"));
178179
fprintf(output,"\n");
179180

180181
fprintf(output,_("Query Buffer\n"));

‎src/bin/psql/tab-complete.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ psql_completion(char *text, int start, int end)
900900
"\\lo_import","\\lo_export","\\lo_list","\\lo_unlink",
901901
"\\o","\\p","\\password","\\prompt","\\pset","\\q","\\qecho","\\r",
902902
"\\set","\\sf","\\t","\\T",
903-
"\\timing","\\unset","\\x","\\w","\\z","\\!",NULL
903+
"\\timing","\\unset","\\x","\\w","\\watch","\\z","\\!",NULL
904904
};
905905

906906
(void)end;/* not used */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp