Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessions_from_cli |
Files: | files | file ages | folders |
SHA1: |
c2fcf0b9f4bdc48dfc6530bda4f531b9 |
User & Date: | drh 2014-08-18 15:08:26.073 |
Context
2014-08-18
| ||
17:56 | Add the "changeset" command-line utility for getting an ASCII dump of change sets. (check-in: 55bb3544a6 user: drh tags: sessions_from_cli) | |
15:08 | 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. (check-in: c2fcf0b9f4 user: drh tags: sessions_from_cli) | |
13:48 | Merge the latest trunk changes, and in particular the refactoring of the object names in the command-line shell. (check-in: 419d286a2f user: drh tags: sessions) | |
Changes
Changes to main.mk.
︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 | pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ random.o resolve.o rowset.o rtree.o select.o status.o \ table.o tokenize.o trigger.o \ update.o util.o vacuum.o \ vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \ vdbetrace.o wal.o walker.o where.o utf.o vtab.o # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ $(TOP)/src/analyze.c \ | > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \ random.o resolve.o rowset.o rtree.o select.o status.o \ table.o tokenize.o trigger.o \ update.o util.o vacuum.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. # SRC = \ $(TOP)/src/alter.c \ $(TOP)/src/analyze.c \ |
︙ | ︙ | |||
558 559 560 561 562 563 564 565 566 567 568 569 570 571 | $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c # Rules for building test programs and for running tests # tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) | > > > | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c 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 # tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
428 429 430 431 432 433 434 435 436 437 438 439 440 441 | fflush(stdout); zResult = local_getline(zPrior, stdin); #endif } return zResult; } /* ** Shell output mode information from before ".explain on", ** saved so that it can be restored by ".explain off" */ typedef struct SavedModeInfo SavedModeInfo; struct SavedModeInfo { int valid; /* Is there legit data in here? */ | > > > > > > > > > > > > > | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | fflush(stdout); zResult = local_getline(zPrior, stdin); #endif } 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" */ typedef struct SavedModeInfo SavedModeInfo; struct SavedModeInfo { int valid; /* Is there legit data in here? */ |
︙ | ︙ | |||
475 476 477 478 479 480 481 482 483 484 485 486 487 488 | char *zFreeOnClose; /* Filename to free when closing */ const char *zVfs; /* Name of VFS to use */ sqlite3_stmt *pStmt; /* Current statement if any. */ FILE *pLog; /* Write log output here */ int *aiIndent; /* Array of indents used in MODE_Explain */ int nIndent; /* Size of array aiIndent[] */ int iIndent; /* Index of current op in aiIndent[] */ }; /* ** These are the allowed modes. */ #define MODE_Line 0 /* One column per line. Blank line between records */ #define MODE_Column 1 /* One record per line in neat columns */ | > > > > | 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | char *zFreeOnClose; /* Filename to free when closing */ const char *zVfs; /* Name of VFS to use */ sqlite3_stmt *pStmt; /* Current statement if any. */ FILE *pLog; /* Write log output here */ 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 }; /* ** These are the allowed modes. */ #define MODE_Line 0 /* One column per line. Blank line between records */ #define MODE_Column 1 /* One record per line in neat columns */ |
︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".save FILE Write in-memory database into FILE\n" ".schema ?TABLE? Show the CREATE statements\n" " If TABLE specified, only show tables matching\n" " 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" ".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" ".system CMD ARGS... Run CMD ARGS... in a system shell\n" ".tables ?TABLE? List names of tables\n" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" ".timeout MS Try opening locked tables for MS milliseconds\n" ".timer on|off Turn SQL timer on or off\n" ".trace FILE|off Output each SQL statement as it is run\n" ".vfsname ?AUX? Print the name of the VFS stack\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" " Negative values right-justify\n" ; /* Forward reference */ static int process_input(ShellState *p, FILE *in); /* ** Implementation of the "readfile(X)" SQL function. The entire content ** of the file named X is read and returned as a BLOB. NULL is returned ** if the file does not exist or is unreadable. | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 | ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".save FILE Write in-memory database into FILE\n" ".schema ?TABLE? Show the CREATE statements\n" " If TABLE specified, only show tables matching\n" " 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" ".system CMD ARGS... Run CMD ARGS... in a system shell\n" ".tables ?TABLE? List names of tables\n" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" ".timeout MS Try opening locked tables for MS milliseconds\n" ".timer on|off Turn SQL timer on or off\n" ".trace FILE|off Output each SQL statement as it is run\n" ".vfsname ?AUX? Print the name of the VFS stack\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" " 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); /* ** Implementation of the "readfile(X)" SQL function. The entire content ** of the file named X is read and returned as a BLOB. NULL is returned ** if the file does not exist or is unreadable. |
︙ | ︙ | |||
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 | rc = 0; }else{ rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); } fclose(out); sqlite3_result_int64(context, rc); } /* ** 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. */ static void open_db(ShellState *p, int keepAlive){ if( p->db==0 ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 | rc = 0; }else{ rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); } fclose(out); 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. */ static void open_db(ShellState *p, int keepAlive){ if( p->db==0 ){ |
︙ | ︙ | |||
2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 | char *zNewFilename = 0; p->db = 0; if( nArg>=2 ){ p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]); } open_db(p, 1); if( p->db!=0 ){ sqlite3_close(savedDb); sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = zNewFilename; }else{ sqlite3_free(zNewFilename); p->db = savedDb; p->zDbFilename = zSavedFilename; | > | 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 | char *zNewFilename = 0; p->db = 0; if( nArg>=2 ){ p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]); } open_db(p, 1); if( p->db!=0 ){ session_close_all(p); sqlite3_close(savedDb); sqlite3_free(p->zFreeOnClose); p->zFreeOnClose = zNewFilename; }else{ sqlite3_free(zNewFilename); p->db = savedDb; p->zDbFilename = zSavedFilename; |
︙ | ︙ | |||
3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 | }else if( rc != SQLITE_OK ){ fprintf(stderr,"Error: querying schema information\n"); rc = 1; }else{ rc = 0; } }else #ifdef SQLITE_DEBUG /* Undocumented commands for internal testing. Subject to change ** without notice. */ if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ int i, v; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 | }else if( rc != SQLITE_OK ){ fprintf(stderr,"Error: querying schema information\n"); rc = 1; }else{ rc = 0; } }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. */ if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ int i, v; |
︙ | ︙ | |||
4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 | } }else{ rc = process_input(&data, stdin); } } set_table_name(&data, 0); if( data.db ){ sqlite3_close(data.db); } sqlite3_free(data.zFreeOnClose); return rc; } | > | 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 | } }else{ rc = process_input(&data, stdin); } } set_table_name(&data, 0); if( data.db ){ session_close_all(&data); sqlite3_close(data.db); } sqlite3_free(data.zFreeOnClose); return rc; } |