Begin adding commands to the command-line interface for interacting with

the sessions extension.  This is the first check-in of a work-in-progress.

FossilOrigin-Name: c2fcf0b9f4bdc48dfc6530bda4f531b94a833207
This commit is contained in:
drh 2014-08-18 15:08:26 +00:00
parent 8b7a2e3a1e
commit e62296100f
4 changed files with 167 additions and 8 deletions

View File

@ -72,6 +72,8 @@ LIBOBJ+= vdbe.o parse.o \
vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
vdbetrace.o wal.o walker.o where.o utf.o vtab.o
LIBOBJ += sqlite3session.o
# All of the source code files.
@ -563,6 +565,9 @@ fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
sqlite3session.o: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c
# Rules for building test programs and for running tests
#

View File

@ -1,5 +1,5 @@
C Merge\sthe\slatest\strunk\schanges,\sand\sin\sparticular\sthe\srefactoring\sof\sthe\nobject\snames\sin\sthe\scommand-line\sshell.
D 2014-08-18T13:48:41.625
C Begin\sadding\scommands\sto\sthe\scommand-line\sinterface\sfor\sinteracting\swith\nthe\ssessions\sextension.\s\sThis\sis\sthe\sfirst\scheck-in\sof\sa\swork-in-progress.
D 2014-08-18T15:08:26.073
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -161,7 +161,7 @@ F ext/session/test_session.c 920ccb6d6e1df263cd9099563328094c230b2925
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 152593de5d19eeab0fdaacfdedd5eafdfdd83d5a
F main.mk eb6742eba7ebb8dc18401220e7ce21788d41aaef
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@ -238,7 +238,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c ea48e891406ccdf748f3eb02893e056d134a0fea
F src/shell.c 41df1103617331e023301d943977f8c06bd1486f
F src/shell.c 6378fc281ab6c2c5ee46cf13f2657e8a187c3ce7
F src/sqlite.h.in 021a1f5c50e83060675d994a6014fd409e611d9e
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
@ -1202,7 +1202,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 82fdb1975f5b29a751089a8582713372999ae56e 11a70e1ae7f05d06e4e09c9d20db0444b8881584
R 9eb07c2c47c345635567e1ec3d8ef22d
P 419d286a2fc465f6e0f9662909d0cc52a18eefa4
R 23a3bfb6cd8e3a34baca1f6d98151d23
T *branch * sessions_from_cli
T *sym-sessions_from_cli *
T -sym-sessions *
U drh
Z 44d5fceffc6c6ae323a3b362c9fccbd4
Z dbfbe7f80e47f8918e41f67c20d63911

View File

@ -1 +1 @@
419d286a2fc465f6e0f9662909d0cc52a18eefa4
c2fcf0b9f4bdc48dfc6530bda4f531b94a833207

View File

@ -432,6 +432,19 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
return zResult;
}
#if defined(SQLITE_ENABLE_SESSION)
/*
** State information for a single open session
*/
typedef struct OpenSession OpenSession;
struct OpenSession {
char *zName; /* Symbolic name for this session */
int nFilter; /* Number of xFilter rejection GLOB patterns */
char **azFilter; /* Array of xFilter rejection GLOB patterns */
sqlite3_session *p; /* The open session */
};
#endif
/*
** Shell output mode information from before ".explain on",
** saved so that it can be restored by ".explain off"
@ -479,6 +492,10 @@ struct ShellState {
int *aiIndent; /* Array of indents used in MODE_Explain */
int nIndent; /* Size of array aiIndent[] */
int iIndent; /* Index of current op in aiIndent[] */
#if defined(SQLITE_ENABLE_SESSION)
int nSession; /* Number of active sessions */
OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
#endif
};
/*
@ -1636,6 +1653,9 @@ static char zHelp[] =
" LIKE pattern TABLE.\n"
".separator STRING ?NL? Change separator used by output mode and .import\n"
" NL is the end-of-line mark for CSV\n"
#if defined(SQLITE_ENABLE_SESSION)
".session CMD ... Create or control sessions\n"
#endif
".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
".show Show the current values for various settings\n"
".stats on|off Turn stats on or off\n"
@ -1651,6 +1671,30 @@ static char zHelp[] =
" Negative values right-justify\n"
;
#if defined(SQLITE_ENABLE_SESSION)
/*
** Print help information for the ".sessions" command
*/
void session_help(ShellState *p){
fprintf(p->out,
".session ?NAME? SUBCOMMAND ?ARGS...?\n"
"If ?NAME? is omitted, the first defined session is used.\n"
"Subcommands:\n"
" attach TABLE Attach TABLE\n"
" changeset FILE Write a changeset into FILE\n"
" close Close one session\n"
" enable ?BOOLEAN? Set or query the enable bit\n"
" filter GLOB... Reject tables matching GLOBs\n"
" indirect ?BOOLEAN? Mark or query the indirect status\n"
" isempty Query whether the session is empty\n"
" list List currently open session names\n"
" open DB NAME Open a new session on DB\n"
" patchset FILE Write a patchset into FILE\n"
);
}
#endif
/* Forward reference */
static int process_input(ShellState *p, FILE *in);
/*
@ -1714,6 +1758,36 @@ static void writefileFunc(
sqlite3_result_int64(context, rc);
}
#if defined(SQLITE_ENABLE_SESSION)
/*
** Close a single OpenSession object and release all of its associated
** resources.
*/
static void session_close(OpenSession *pSession){
int i;
sqlite3session_delete(pSession->p);
sqlite3_free(pSession->zName);
for(i=0; i<pSession->nFilter; i++){
sqlite3_free(pSession->azFilter[i]);
}
sqlite3_free(pSession->azFilter);
memset(pSession, 0, sizeof(OpenSession));
}
#endif
/*
** Close all OpenSession objects and release all assocaited resources.
*/
static void session_close_all(ShellState *p){
#if defined(SQLITE_ENABLE_SESSION)
int i;
for(i=0; i<p->nSession; i++){
session_close(&p->aSession[i]);
}
p->nSession = 0;
#endif
}
/*
** Make sure the database is open. If it is not, then open it. If
** the database fails to open, print an error message and exit.
@ -2865,6 +2939,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}
open_db(p, 1);
if( p->db!=0 ){
session_close_all(p);
sqlite3_close(savedDb);
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = zNewFilename;
@ -3086,6 +3161,81 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}else
#if defined(SQLITE_ENABLE_SESSION)
if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
OpenSession *pSession = &p->aSession[0];
char **azCmd = &azArg[1];
int iSes = 0;
int nCmd = nArg - 1;
int i;
if( nArg<=1 ) goto session_syntax_error;
if( nArg>=3 ){
for(iSes=0; iSes<p->nSession; iSes++){
if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
}
if( iSes<p->nSession ){
pSession = &p->aSession[iSes];
azCmd++;
nCmd--;
}else{
pSession = &p->aSession[0];
iSes = 0;
}
}
/* .session close
** Close the identified session
*/
if( strcmp(azCmd[0], "close")==0 ){
if( p->nSession ){
session_close(pSession);
p->aSession[iSes] = p->aSession[--p->nSession];
}
}else
/* .session list
** List all currently open sessions
*/
if( strcmp(azCmd[0],"list")==0 ){
for(i=0; i<p->nSession; i++){
fprintf(p->out, "%d %s\n", i, p->aSession[i].zName);
}
}else
/* .session open DB NAME
** Open a new session called NAME on the attached database DB.
** DB is normally "main".
*/
if( strcmp(azCmd[0],"open")==0 ){
char *zName;
if( nCmd!=3 ) goto session_syntax_error;
zName = azCmd[2];
if( zName[0]==0 ) goto session_syntax_error;
for(i=0; i<p->nSession; i++){
if( strcmp(p->aSession[i].zName,zName)==0 ){
fprintf(stderr, "Session \"%s\" already exists\n", zName);
goto meta_command_exit;
}
}
if( p->nSession>=ArraySize(p->aSession) ){
fprintf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
goto meta_command_exit;
}
pSession = &p->aSession[p->nSession];
rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
if( rc ){
fprintf(stderr, "Cannot open session: error code=%d\n", rc);
goto meta_command_exit;
}
p->nSession++;
pSession->zName = sqlite3_mprintf("%s", zName);
}else
/* If no command name matches, show a syntax error */
session_syntax_error:
session_help(p);
}else
#endif
#ifdef SQLITE_DEBUG
/* Undocumented commands for internal testing. Subject to change
** without notice. */
@ -4134,6 +4284,7 @@ int main(int argc, char **argv){
}
set_table_name(&data, 0);
if( data.db ){
session_close_all(&data);
sqlite3_close(data.db);
}
sqlite3_free(data.zFreeOnClose);