mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Teach the sqlite3 CLI shell to look in XDG_STATE_HOME for the CLI history file before falling back to its historical location in the user's home directory.
FossilOrigin-Name: 1e663374c3fcc20ab0b3250aa1ff9d5e5ac391c89808ad589aa30c8882d4b61e
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Avoid\sevaluating\sspecial\svtab\soperators\s(e.g.\sMATCH)\sthat\sare\spart\sof\sON\sclauses\sattached\sto\sleft\sjoins\sfrom\sbeing\sevaluated\stoo\searly.\sFix\sfor\s[forum:/forumpost/428ef7c468\s|\sforum\spost\s428ef7c468].
|
C Teach\sthe\ssqlite3\sCLI\sshell\sto\slook\sin\sXDG_STATE_HOME\sfor\sthe\sCLI\shistory\sfile\sbefore\sfalling\sback\sto\sits\shistorical\slocation\sin\sthe\suser's\shome\sdirectory.
|
||||||
D 2025-07-15T19:00:01.118
|
D 2025-07-16T09:27:55.137
|
||||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
@@ -718,7 +718,7 @@ F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
|
|||||||
F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0
|
F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0
|
||||||
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
|
||||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||||
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
|
F sqlite3.1 9e426a150af072be26b0661bcd54567692d979e99bc7daf55b22b952ff8e41a6
|
||||||
F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398
|
F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398
|
||||||
F src/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da
|
F src/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da
|
||||||
F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
|
F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
|
||||||
@@ -787,7 +787,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
|||||||
F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0
|
F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0
|
||||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||||
F src/select.c fc003cad96a105765261f7b6c5f4596e505894262bb5593cb29e10b682800d12
|
F src/select.c fc003cad96a105765261f7b6c5f4596e505894262bb5593cb29e10b682800d12
|
||||||
F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf
|
F src/shell.c.in 2be7d0b2ba7221bd991f96d0c72728c06cead09bec3965e230ad703c9daf0c8a
|
||||||
F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693
|
F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693
|
||||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||||
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
|
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
|
||||||
@@ -2213,9 +2213,9 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
|
|||||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||||
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
|
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 0fcc3cbdfa21adf97aed01fa76991cccf9380e2755b0182a9e2c94e3c8fb38d7 ffebbb7ae977adc6c729d30b51f2ff29d416e018d82e450d87ccd973472819c8
|
P 9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839 73539fe0932494234b8f2293b0dbc1f0aac60a7d00fdaf4a59c2da654ce26f5b
|
||||||
R 0ec55818aae25b06d1ba2943b74e8035
|
R 301553834aa3054a0cc5a0c4c21b9798
|
||||||
T +closed ffebbb7ae977adc6c729d30b51f2ff29d416e018d82e450d87ccd973472819c8
|
T +closed 73539fe0932494234b8f2293b0dbc1f0aac60a7d00fdaf4a59c2da654ce26f5b Closed\sby\sintegrate-merge.
|
||||||
U dan
|
U stephan
|
||||||
Z 39542e12671ba6b0f9f551dd25869359
|
Z f8c26aad77c21d4fab9a1de2f2326205
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839
|
1e663374c3fcc20ab0b3250aa1ff9d5e5ac391c89808ad589aa30c8882d4b61e
|
||||||
|
28
sqlite3.1
28
sqlite3.1
@@ -137,17 +137,37 @@ continue prompt = " ...> "
|
|||||||
.sp
|
.sp
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
o If the file
|
o If the environment variable XDG_CONFIG_HOME is set then
|
||||||
.B ${XDG_CONFIG_HOME}/sqlite3/sqliterc
|
.B ${XDG_CONFIG_HOME}/sqlite3/sqliterc
|
||||||
or
|
is checked, else
|
||||||
|
.B ~/.local/config/sqlite3/sqliterc
|
||||||
|
is checked. If the selected file does not exist then the fallback of
|
||||||
.B ~/.sqliterc
|
.B ~/.sqliterc
|
||||||
exists, the first of those to be found is processed during startup.
|
is used. It should generally only contain meta-commands.
|
||||||
It should generally only contain meta-commands.
|
|
||||||
|
|
||||||
o If the -init option is present, the specified file is processed.
|
o If the -init option is present, the specified file is processed.
|
||||||
|
|
||||||
o All other command line options are processed.
|
o All other command line options are processed.
|
||||||
|
|
||||||
|
.SH HISTORY FILE
|
||||||
|
.B sqlite3
|
||||||
|
may be configured to use a history file to save SQL statements and
|
||||||
|
meta-commands entered interactively. These statements and commands can be
|
||||||
|
retrieved, edited and, reused at the main and continue prompts. If the
|
||||||
|
environment variable
|
||||||
|
.B SQLITE_HISTORY
|
||||||
|
is set, it will be used as the name of the history file, whether it
|
||||||
|
already exists or not. If it is not set but the XDG_STATE_HOME
|
||||||
|
environment variable is then
|
||||||
|
.B ${XDG_STATE_HOME}/sqlite_history
|
||||||
|
is used. If XDG_STATE_HOME is not set then
|
||||||
|
.B ~/.local/state/sqlite_history
|
||||||
|
is used. If the selected file does not exist then
|
||||||
|
.B ~/.sqlite_history
|
||||||
|
will be used as the history file. If any history file is found, it
|
||||||
|
will be written if the shell exits interactive mode normally,
|
||||||
|
regardless of whether it existed previously, though saving will
|
||||||
|
silently fail if the history file's directory does not exist.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
https://sqlite.org/cli.html
|
https://sqlite.org/cli.html
|
||||||
.br
|
.br
|
||||||
|
104
src/shell.c.in
104
src/shell.c.in
@@ -12760,59 +12760,79 @@ static char *find_home_dir(int clearFlag){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** On non-Windows platforms, look for $XDG_CONFIG_HOME.
|
** On non-Windows platforms, look for:
|
||||||
** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return
|
|
||||||
** the path to it. If there is no $(XDG_CONFIG_HOME) then
|
|
||||||
** look for $(HOME)/.config/sqlite3/sqliterc and if found
|
|
||||||
** return that. If none of these are found, return 0.
|
|
||||||
**
|
**
|
||||||
** The string returned is obtained from sqlite3_malloc() and
|
** - ${zEnvVar}/${zBaseName}
|
||||||
** should be freed by the caller.
|
** - ${HOME}/${zSubdir}/${zBaseName}
|
||||||
|
**
|
||||||
|
** $zEnvVar is intended to be the name of an XDG_... environment
|
||||||
|
** variable, e.g. XDG_CONFIG_HOME or XDG_STATE_HOME. If zEnvVar is
|
||||||
|
** NULL or getenv(zEnvVar) is NULL then fall back to the second
|
||||||
|
** option. If the selected option is not found in the filesystem,
|
||||||
|
** return 0.
|
||||||
|
**
|
||||||
|
** zSubdir may be NULL or empty, in which case ${HOME}/${zBaseName}
|
||||||
|
** becomes the fallback.
|
||||||
|
**
|
||||||
|
** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir
|
||||||
|
** will conventionally be ".config" or ".local/state", which, not
|
||||||
|
** coincidentally, is the typical subdir of the corresponding XDG_...
|
||||||
|
** var with the XDG var's $HOME prefix.
|
||||||
|
**
|
||||||
|
** The returned string is obtained from sqlite3_malloc() and should be
|
||||||
|
** sqlite3_free()'d by the caller.
|
||||||
*/
|
*/
|
||||||
static char *find_xdg_config(void){
|
static char *find_xdg_file(const char *zEnvVar, const char *zSubdir,
|
||||||
|
const char *zBaseName){
|
||||||
#if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \
|
#if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \
|
||||||
|| defined(__RTP__) || defined(_WRS_KERNEL)
|
|| defined(__RTP__) || defined(_WRS_KERNEL)
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
char *zConfig = 0;
|
char *zConfigFile = 0;
|
||||||
const char *zXdgHome;
|
const char *zXdgDir;
|
||||||
|
|
||||||
zXdgHome = getenv("XDG_CONFIG_HOME");
|
zXdgDir = zEnvVar ? getenv(zEnvVar) : 0;
|
||||||
if( zXdgHome==0 ){
|
if( zXdgDir ){
|
||||||
const char *zHome = getenv("HOME");
|
zConfigFile = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName);
|
||||||
if( zHome==0 ) return 0;
|
|
||||||
zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome);
|
|
||||||
}else{
|
}else{
|
||||||
zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome);
|
const char * zHome = find_home_dir(0);
|
||||||
|
if( zHome==0 ) return 0;
|
||||||
|
zConfigFile = (zSubdir && *zSubdir)
|
||||||
|
? sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName)
|
||||||
|
: sqlite3_mprintf("%s/%s", zHome, zBaseName);
|
||||||
}
|
}
|
||||||
shell_check_oom(zConfig);
|
shell_check_oom(zConfigFile);
|
||||||
if( access(zConfig,0)!=0 ){
|
if( access(zConfigFile,0)!=0 ){
|
||||||
sqlite3_free(zConfig);
|
sqlite3_free(zConfigFile);
|
||||||
zConfig = 0;
|
zConfigFile = 0;
|
||||||
}
|
}
|
||||||
return zConfig;
|
return zConfigFile;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Read input from the file given by sqliterc_override. Or if that
|
** Read input from the file sqliterc_override. If that parameter is
|
||||||
** parameter is NULL, take input from the first of find_xdg_config()
|
** NULL, take it from find_xdg_file(), if found, or fall back to
|
||||||
** or ~/.sqliterc which is found.
|
** ~/.sqliterc.
|
||||||
**
|
**
|
||||||
** Returns the number of errors.
|
** Failure to read the config is only considered a failure if
|
||||||
|
** sqliterc_override is not NULL, in which case this function may emit
|
||||||
|
** a warning or, if ::bail_on_error is true, fail fatally if the file
|
||||||
|
** named by sqliterc_override is not found.
|
||||||
*/
|
*/
|
||||||
static void process_sqliterc(
|
static void process_sqliterc(
|
||||||
ShellState *p, /* Configuration data */
|
ShellState *p, /* Configuration data */
|
||||||
const char *sqliterc_override /* Name of config file. NULL to use default */
|
const char *sqliterc_override /* Name of config file. NULL to use default */
|
||||||
){
|
){
|
||||||
char *home_dir = NULL;
|
char *home_dir = NULL;
|
||||||
const char *sqliterc = sqliterc_override;
|
char *sqliterc = (char*)sqliterc_override;
|
||||||
char *zBuf = 0;
|
|
||||||
FILE *inSaved = p->in;
|
FILE *inSaved = p->in;
|
||||||
int savedLineno = p->lineno;
|
int savedLineno = p->lineno;
|
||||||
|
|
||||||
if( sqliterc == NULL ){
|
if( sqliterc == NULL ){
|
||||||
sqliterc = zBuf = find_xdg_config();
|
sqliterc = find_xdg_file("XDG_CONFIG_HOME",
|
||||||
|
".config",
|
||||||
|
"sqlite3/sqliterc");
|
||||||
}
|
}
|
||||||
if( sqliterc == NULL ){
|
if( sqliterc == NULL ){
|
||||||
home_dir = find_home_dir(0);
|
home_dir = find_home_dir(0);
|
||||||
@@ -12821,11 +12841,10 @@ static void process_sqliterc(
|
|||||||
" cannot read ~/.sqliterc\n");
|
" cannot read ~/.sqliterc\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
|
sqliterc = sqlite3_mprintf("%s/.sqliterc",home_dir);
|
||||||
shell_check_oom(zBuf);
|
shell_check_oom(sqliterc);
|
||||||
sqliterc = zBuf;
|
|
||||||
}
|
}
|
||||||
p->in = sqlite3_fopen(sqliterc,"rb");
|
p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0;
|
||||||
if( p->in ){
|
if( p->in ){
|
||||||
if( stdin_is_interactive ){
|
if( stdin_is_interactive ){
|
||||||
sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
|
sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc);
|
||||||
@@ -12838,7 +12857,9 @@ static void process_sqliterc(
|
|||||||
}
|
}
|
||||||
p->in = inSaved;
|
p->in = inSaved;
|
||||||
p->lineno = savedLineno;
|
p->lineno = savedLineno;
|
||||||
sqlite3_free(zBuf);
|
if( sqliterc != sqliterc_override ){
|
||||||
|
sqlite3_free(sqliterc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -13606,7 +13627,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
|||||||
if( stdin_is_interactive ){
|
if( stdin_is_interactive ){
|
||||||
char *zHome;
|
char *zHome;
|
||||||
char *zHistory;
|
char *zHistory;
|
||||||
int nHistory;
|
|
||||||
sqlite3_fprintf(stdout,
|
sqlite3_fprintf(stdout,
|
||||||
"SQLite version %s %.19s\n" /*extra-version-info*/
|
"SQLite version %s %.19s\n" /*extra-version-info*/
|
||||||
"Enter \".help\" for usage hints.\n",
|
"Enter \".help\" for usage hints.\n",
|
||||||
@@ -13619,11 +13639,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
|||||||
}
|
}
|
||||||
zHistory = getenv("SQLITE_HISTORY");
|
zHistory = getenv("SQLITE_HISTORY");
|
||||||
if( zHistory ){
|
if( zHistory ){
|
||||||
zHistory = strdup(zHistory);
|
zHistory = sqlite3_mprintf("%s", zHistory);
|
||||||
}else if( (zHome = find_home_dir(0))!=0 ){
|
shell_check_oom(zHistory);
|
||||||
nHistory = strlen30(zHome) + 20;
|
}else{
|
||||||
if( (zHistory = malloc(nHistory))!=0 ){
|
zHistory = find_xdg_file("XDG_STATE_HOME",
|
||||||
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
|
".local/state",
|
||||||
|
"sqlite_history");
|
||||||
|
if( 0==zHistory && (zHome = find_home_dir(0))!=0 ){
|
||||||
|
zHistory = sqlite3_mprintf("%s/.sqlite_history", zHome);
|
||||||
|
shell_check_oom(zHistory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( zHistory ){ shell_read_history(zHistory); }
|
if( zHistory ){ shell_read_history(zHistory); }
|
||||||
@@ -13639,7 +13663,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
|||||||
if( zHistory ){
|
if( zHistory ){
|
||||||
shell_stifle_history(2000);
|
shell_stifle_history(2000);
|
||||||
shell_write_history(zHistory);
|
shell_write_history(zHistory);
|
||||||
free(zHistory);
|
sqlite3_free(zHistory);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
data.in = stdin;
|
data.in = stdin;
|
||||||
|
Reference in New Issue
Block a user