Обсуждение: psql: customizable readline history filename
Hi,
the following patch makes the filename used to store the readline
history customizable through a variable named HISTFILE, analogous to
psql's already implemented HISTCONTROL and HISTSIZE variables, and
bash's HISTFILE-Variable.
The motivation was to be able to get psql to maintain separate
histories for separate databases. This is now easily achievable
through a line like the following in ~/.psqlrc:
\set HISTFILE ~/.psql_history- :DBNAME
regards,
Andreas
Index: doc/src/sgml/ref/psql-ref.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v
retrieving revision 1.123
diff -c -r1.123 psql-ref.sgml
*** doc/src/sgml/ref/psql-ref.sgml 6 Oct 2004 18:39:15 -0000 1.123
--- doc/src/sgml/ref/psql-ref.sgml 26 Oct 2004 05:57:57 -0000
***************
*** 1973,1978 ****
--- 1973,2001 ----
</varlistentry>
<varlistentry>
+ <term><varname>HISTFILE</varname></term>
+ <listitem>
+ <para>
+ This variable contains the filename used to save the history.
+ Its default value is <filename>~/.psql_history</filename>.
+ When unset or empty, the command history is not saved upon
+ program termination. For example,
+ <programlisting>
+ \set HISTFILE ~/.psql_history- :DBNAME
+ </programlisting>
+ in your <filename>~/.psqlrc</filename> will get psql to
+ maintain a separate history for each database.
+ </para>
+ <note>
+ <para>
+ This feature was shamelessly plagiarized from
+ <application>Bash</application>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>HISTSIZE</varname></term>
<listitem>
<para>
Index: src/bin/psql/input.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.c,v
retrieving revision 1.41
diff -c -r1.41 input.c
*** src/bin/psql/input.c 12 Oct 2004 21:54:44 -0000 1.41
--- src/bin/psql/input.c 26 Oct 2004 05:57:57 -0000
***************
*** 38,46 ****
static void finishInput(int, void *);
#endif
- #define PSQLHISTORY ".psql_history"
-
-
#ifdef USE_READLINE
static enum histcontrol
GetHistControlConfig(void)
--- 38,43 ----
***************
*** 167,173 ****
#ifdef USE_READLINE
if (flags & 1)
{
! char home[MAXPGPATH];
useReadline = true;
initialize_readline();
--- 164,171 ----
#ifdef USE_READLINE
if (flags & 1)
{
! const char *psql_history;
! char *tilde_expanded;
useReadline = true;
initialize_readline();
***************
*** 176,191 ****
if (GetVariable(pset.vars, "HISTSIZE") == NULL)
SetVariable(pset.vars, "HISTSIZE", "500");
using_history();
- if (get_home_path(home))
- {
- char *psql_history;
! psql_history = pg_malloc(strlen(home) + 1 +
! strlen(PSQLHISTORY) + 1);
! sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
! read_history(psql_history);
! free(psql_history);
! }
}
#endif
--- 174,189 ----
if (GetVariable(pset.vars, "HISTSIZE") == NULL)
SetVariable(pset.vars, "HISTSIZE", "500");
using_history();
! if (GetVariable(pset.vars, "HISTFILE") == NULL)
! SetVariable(pset.vars, "HISTFILE", "~/.psql_history");
!
! psql_history = GetVariable(pset.vars, "HISTFILE");
!
! tilde_expanded = pg_strdup(psql_history);
! expand_tilde(&tilde_expanded);
! read_history(tilde_expanded);
! free(tilde_expanded);
}
#endif
***************
*** 228,252 ****
#ifdef USE_READLINE
if (useHistory)
{
! char home[MAXPGPATH];
!
! if (get_home_path(home))
! {
! char *psql_history;
! int hist_size;
! psql_history = pg_malloc(strlen(home) + 1 +
! strlen(PSQLHISTORY) + 1);
! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true);
! if (hist_size >= 0)
! stifle_history(hist_size);
!
! sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
! write_history(psql_history);
! free(psql_history);
! }
}
#endif
}
--- 226,251 ----
#ifdef USE_READLINE
if (useHistory)
{
! const char *psql_history;
! char *tilde_expanded;
! int hist_size;
!
! psql_history = GetVariable(pset.vars, "HISTFILE");
!
! if (!psql_history || !strlen(psql_history))
! return;
!
! tilde_expanded = pg_strdup(psql_history);
! expand_tilde(&tilde_expanded);
!
! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true);
! if (hist_size >= 0)
! stifle_history(hist_size);
! saveHistory(tilde_expanded);
! free(tilde_expanded);
}
#endif
}
This has been saved for the 8.1 release:
http:/momjian.postgresql.org/cgi-bin/pgpatches2
---------------------------------------------------------------------------
Andreas Seltenreich wrote:
> Hi,
>
> the following patch makes the filename used to store the readline
> history customizable through a variable named HISTFILE, analogous to
> psql's already implemented HISTCONTROL and HISTSIZE variables, and
> bash's HISTFILE-Variable.
>
> The motivation was to be able to get psql to maintain separate
> histories for separate databases. This is now easily achievable
> through a line like the following in ~/.psqlrc:
>
> \set HISTFILE ~/.psql_history- :DBNAME
>
> regards,
> Andreas
>
> Index: doc/src/sgml/ref/psql-ref.sgml
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v
> retrieving revision 1.123
> diff -c -r1.123 psql-ref.sgml
> *** doc/src/sgml/ref/psql-ref.sgml 6 Oct 2004 18:39:15 -0000 1.123
> --- doc/src/sgml/ref/psql-ref.sgml 26 Oct 2004 05:57:57 -0000
> ***************
> *** 1973,1978 ****
> --- 1973,2001 ----
> </varlistentry>
>
> <varlistentry>
> + <term><varname>HISTFILE</varname></term>
> + <listitem>
> + <para>
> + This variable contains the filename used to save the history.
> + Its default value is <filename>~/.psql_history</filename>.
> + When unset or empty, the command history is not saved upon
> + program termination. For example,
> + <programlisting>
> + \set HISTFILE ~/.psql_history- :DBNAME
> + </programlisting>
> + in your <filename>~/.psqlrc</filename> will get psql to
> + maintain a separate history for each database.
> + </para>
> + <note>
> + <para>
> + This feature was shamelessly plagiarized from
> + <application>Bash</application>.
> + </para>
> + </note>
> + </listitem>
> + </varlistentry>
> +
> + <varlistentry>
> <term><varname>HISTSIZE</varname></term>
> <listitem>
> <para>
> Index: src/bin/psql/input.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/bin/psql/input.c,v
> retrieving revision 1.41
> diff -c -r1.41 input.c
> *** src/bin/psql/input.c 12 Oct 2004 21:54:44 -0000 1.41
> --- src/bin/psql/input.c 26 Oct 2004 05:57:57 -0000
> ***************
> *** 38,46 ****
> static void finishInput(int, void *);
> #endif
>
> - #define PSQLHISTORY ".psql_history"
> -
> -
> #ifdef USE_READLINE
> static enum histcontrol
> GetHistControlConfig(void)
> --- 38,43 ----
> ***************
> *** 167,173 ****
> #ifdef USE_READLINE
> if (flags & 1)
> {
> ! char home[MAXPGPATH];
>
> useReadline = true;
> initialize_readline();
> --- 164,171 ----
> #ifdef USE_READLINE
> if (flags & 1)
> {
> ! const char *psql_history;
> ! char *tilde_expanded;
>
> useReadline = true;
> initialize_readline();
> ***************
> *** 176,191 ****
> if (GetVariable(pset.vars, "HISTSIZE") == NULL)
> SetVariable(pset.vars, "HISTSIZE", "500");
> using_history();
> - if (get_home_path(home))
> - {
> - char *psql_history;
>
> ! psql_history = pg_malloc(strlen(home) + 1 +
> ! strlen(PSQLHISTORY) + 1);
> ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
> ! read_history(psql_history);
> ! free(psql_history);
> ! }
> }
> #endif
>
> --- 174,189 ----
> if (GetVariable(pset.vars, "HISTSIZE") == NULL)
> SetVariable(pset.vars, "HISTSIZE", "500");
> using_history();
>
> ! if (GetVariable(pset.vars, "HISTFILE") == NULL)
> ! SetVariable(pset.vars, "HISTFILE", "~/.psql_history");
> !
> ! psql_history = GetVariable(pset.vars, "HISTFILE");
> !
> ! tilde_expanded = pg_strdup(psql_history);
> ! expand_tilde(&tilde_expanded);
> ! read_history(tilde_expanded);
> ! free(tilde_expanded);
> }
> #endif
>
> ***************
> *** 228,252 ****
> #ifdef USE_READLINE
> if (useHistory)
> {
> ! char home[MAXPGPATH];
> !
> ! if (get_home_path(home))
> ! {
> ! char *psql_history;
> ! int hist_size;
>
> ! psql_history = pg_malloc(strlen(home) + 1 +
> ! strlen(PSQLHISTORY) + 1);
>
> ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true);
>
> ! if (hist_size >= 0)
> ! stifle_history(hist_size);
> !
> ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY);
> ! write_history(psql_history);
> ! free(psql_history);
> ! }
> }
> #endif
> }
> --- 226,251 ----
> #ifdef USE_READLINE
> if (useHistory)
> {
> ! const char *psql_history;
> ! char *tilde_expanded;
> ! int hist_size;
> !
> ! psql_history = GetVariable(pset.vars, "HISTFILE");
> !
> ! if (!psql_history || !strlen(psql_history))
> ! return;
> !
> ! tilde_expanded = pg_strdup(psql_history);
> ! expand_tilde(&tilde_expanded);
> !
> ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true);
>
> ! if (hist_size >= 0)
> ! stifle_history(hist_size);
>
> ! saveHistory(tilde_expanded);
>
> ! free(tilde_expanded);
> }
> #endif
> }
>
> ---------------------------(end of broadcast)---------------------------
> TIP 7: don't forget to increase your free space map settings
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Andreas Seltenreich wrote: > Hi, > > the following patch makes the filename used to store the readline > history customizable through a variable named HISTFILE, analogous to > psql's already implemented HISTCONTROL and HISTSIZE variables, and > bash's HISTFILE-Variable. > > The motivation was to be able to get psql to maintain separate > histories for separate databases. This is now easily achievable > through a line like the following in ~/.psqlrc: > > \set HISTFILE ~/.psql_history- :DBNAME I have applied your patch with slight modifications; new version attached. Win32 doesn't have tilde expansion, so your idea of using "~/.psql_history" as a default would not work --- I had to keep the get_home_path() code in there. I decided to make psql_history a file static variable, so we would not have to recompute its value when writing the history file. I noticed your documentation example had a space before :DBNAME --- I removed the space. You had the idea of not saving the history on exit if HISTFILE is not set. I don't think we have community agreement on that change, and I bet we wouldn't get it. (I have removed your documentation mention of this.) I think setting HISTSIZE to zero has that effect already if people want it. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: doc/src/sgml/ref/psql-ref.sgml =================================================================== RCS file: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v retrieving revision 1.139 diff -c -c -r1.139 psql-ref.sgml *** doc/src/sgml/ref/psql-ref.sgml 9 Jun 2005 15:27:26 -0000 1.139 --- doc/src/sgml/ref/psql-ref.sgml 10 Jun 2005 15:33:22 -0000 *************** *** 1988,1993 **** --- 1988,2015 ---- </varlistentry> <varlistentry> + <term><varname>HISTFILE</varname></term> + <listitem> + <para> + This variable contains the filename used to save the history. + Its default value is <filename>~/.psql_history</filename>. + For example, use: + <programlisting> + \set HISTFILE ~/.psql_history-:DBNAME + </programlisting> + in your <filename>~/.psqlrc</filename> will get psql to + maintain a separate history for each database. + </para> + <note> + <para> + This feature was shamelessly plagiarized from + <application>Bash</application>. + </para> + </note> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>HISTSIZE</varname></term> <listitem> <para> Index: src/bin/psql/input.c =================================================================== RCS file: /cvsroot/pgsql/src/bin/psql/input.c,v retrieving revision 1.43 diff -c -c -r1.43 input.c *** src/bin/psql/input.c 6 Jan 2005 18:29:09 -0000 1.43 --- src/bin/psql/input.c 10 Jun 2005 15:33:23 -0000 *************** *** 24,29 **** --- 24,31 ---- #ifdef USE_READLINE static bool useReadline; static bool useHistory; + char *psql_history; + enum histcontrol { *************** *** 177,192 **** if (GetVariable(pset.vars, "HISTSIZE") == NULL) SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); ! if (get_home_path(home)) { ! char *psql_history; ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); read_history(psql_history); - free(psql_history); - } } #endif --- 179,202 ---- if (GetVariable(pset.vars, "HISTSIZE") == NULL) SetVariable(pset.vars, "HISTSIZE", "500"); using_history(); ! ! if (GetVariable(pset.vars, "HISTFILE") == NULL) ! { ! if (get_home_path(home)) ! { ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! snprintf(psql_history, MAXPGPATH, "%s/%s", home, PSQLHISTORY); ! } ! } ! else { ! psql_history = pg_strdup(GetVariable(pset.vars, "HISTFILE")); ! expand_tilde(&psql_history); ! } ! if (psql_history) read_history(psql_history); } #endif *************** *** 227,251 **** #endif { #ifdef USE_READLINE ! if (useHistory) { ! char home[MAXPGPATH]; ! if (get_home_path(home)) ! { ! char *psql_history; ! int hist_size; ! ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); ! if (hist_size >= 0) ! stifle_history(hist_size); ! ! psql_history = pg_malloc(strlen(home) + 1 + ! strlen(PSQLHISTORY) + 1); ! sprintf(psql_history, "%s/%s", home, PSQLHISTORY); ! write_history(psql_history); ! free(psql_history); ! } } #endif } --- 237,253 ---- #endif { #ifdef USE_READLINE ! if (useHistory && psql_history) { ! int hist_size; ! hist_size = GetVariableNum(pset.vars, "HISTSIZE", -1, -1, true); ! if (hist_size >= 0) ! stifle_history(hist_size); ! ! saveHistory(psql_history); ! free(psql_history); ! psql_history = NULL; } #endif }
Bruce Momjian schrob: > I noticed your documentation example had a space before :DBNAME --- I > removed the space. This space is necessary for proper expansion of the parameter. The \set-Command concatenates all its arguments after expansion: --8<---------------cut here---------------start------------->8--- scratch=# \set HISTFILE .psql_history-:DBNAME scratch=# \echo :HISTFILE .psql_history-:DBNAME scratch=# \set HISTFILE .psql_history- :DBNAME scratch=# \echo :HISTFILE .psql_history-scratch scratch=# --8<---------------cut here---------------end--------------->8--- > You had the idea of not saving the history on exit if HISTFILE is not > set. I don't think we have community agreement on that change, and I > bet we wouldn't get it. (I have removed your documentation mention of > this.) I think setting HISTSIZE to zero has that effect already if > people want it. I went for bash's behaviour back then, since we copied bash's semantics with the other history options too. Thanks! Andreas
Andreas Seltenreich wrote:
> Bruce Momjian schrob:
>
> > I noticed your documentation example had a space before :DBNAME --- I
> > removed the space.
>
> This space is necessary for proper expansion of the parameter. The
> \set-Command concatenates all its arguments after expansion:
>
> --8<---------------cut here---------------start------------->8---
> scratch=# \set HISTFILE .psql_history-:DBNAME
> scratch=# \echo :HISTFILE
> .psql_history-:DBNAME
> scratch=# \set HISTFILE .psql_history- :DBNAME
> scratch=# \echo :HISTFILE
> .psql_history-scratch
> scratch=#
> --8<---------------cut here---------------end--------------->8---
>
> > You had the idea of not saving the history on exit if HISTFILE is not
> > set. I don't think we have community agreement on that change, and I
> > bet we wouldn't get it. (I have removed your documentation mention of
> > this.) I think setting HISTSIZE to zero has that effect already if
> > people want it.
>
> I went for bash's behaviour back then, since we copied bash's
> semantics with the other history options too.
Ah, I see. I tested ':' expansion in queries and found the space wasn't
needed, but I see now that with \set it is needed:
test=> \set x a
test=> \echo :x
a
test=> \set y b:x
test=> \echo :y
b:x
test=> \set y b :x
test=> \echo :y
ba
I will update the documentation to add the space. Thanks.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073