1
0
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:
stephan
2025-07-16 09:27:55 +00:00
4 changed files with 98 additions and 54 deletions

View File

@@ -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.

View File

@@ -1 +1 @@
9f184f8dfa5ef6d57e10376adc30e0060ceda07d283c23dfdfe3dbdd6608f839 1e663374c3fcc20ab0b3250aa1ff9d5e5ac391c89808ad589aa30c8882d4b61e

View File

@@ -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

View File

@@ -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;