int iData; /* Bytes of data already read by sessions */
};
+/*
+** Extract an sqlite3* db handle from the object passed as the second
+** argument. If successful, set *pDb to point to the db handle and return
+** TCL_OK. Otherwise, return TCL_ERROR.
+*/
+static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
+ Tcl_CmdInfo info;
+ if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){
+ Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0);
+ return TCL_ERROR;
+ }
+
+ *pDb = *(sqlite3 **)info.objClientData;
+ return TCL_OK;
+}
+
+/*************************************************************************
+** The following code is copied byte-for-byte from the sessions module
+** documentation. It is used by some of the sessions modules tests to
+** ensure that the example in the documentation does actually work.
+*/
+/*
+** Argument zSql points to a buffer containing an SQL script to execute
+** against the database handle passed as the first argument. As well as
+** executing the SQL script, this function collects a changeset recording
+** all changes made to the "main" database file. Assuming no error occurs,
+** output variables (*ppChangeset) and (*pnChangeset) are set to point
+** to a buffer containing the changeset and the size of the changeset in
+** bytes before returning SQLITE_OK. In this case it is the responsibility
+** of the caller to eventually free the changeset blob by passing it to
+** the sqlite3_free function.
+**
+** Or, if an error does occur, return an SQLite error code. The final
+** value of (*pChangeset) and (*pnChangeset) are undefined in this case.
+*/
+int sql_exec_changeset(
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL script to execute */
+ int *pnChangeset, /* OUT: Size of changeset blob in bytes */
+ void **ppChangeset /* OUT: Pointer to changeset blob */
+){
+ sqlite3_session *pSession = 0;
+ int rc;
+
+ /* Create a new session object */
+ rc = sqlite3session_create(db, "main", &pSession);
+
+ /* Configure the session object to record changes to all tables */
+ if( rc==SQLITE_OK ) rc = sqlite3session_attach(pSession, NULL);
+
+ /* Execute the SQL script */
+ if( rc==SQLITE_OK ) rc = sqlite3_exec(db, zSql, 0, 0, 0);
+
+ /* Collect the changeset */
+ if( rc==SQLITE_OK ){
+ rc = sqlite3session_changeset(pSession, pnChangeset, ppChangeset);
+ }
+
+ /* Delete the session object */
+ sqlite3session_delete(pSession);
+
+ return rc;
+}
+/************************************************************************/
+
+/*
+** Tclcmd: sql_exec_changeset DB SQL
+*/
+static int SQLITE_TCLAPI test_sql_exec_changeset(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ const char *zSql;
+ sqlite3 *db;
+ void *pChangeset;
+ int nChangeset;
+ int rc;
+
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB SQL");
+ return TCL_ERROR;
+ }
+ if( dbHandleFromObj(interp, objv[1], &db) ) return TCL_ERROR;
+ zSql = (const char*)Tcl_GetString(objv[2]);
+
+ rc = sql_exec_changeset(db, zSql, &nChangeset, &pChangeset);
+ if( rc!=SQLITE_OK ){
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "error in sql_exec_changeset()", 0);
+ return TCL_ERROR;
+ }
+
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pChangeset, nChangeset));
+ sqlite3_free(pChangeset);
+ return TCL_OK;
+}
+
+
+
#define SESSION_STREAM_TCL_VAR "sqlite3session_streams"
/*
}
int TestSession_Init(Tcl_Interp *interp){
- Tcl_CreateObjCommand(interp, "sqlite3session", test_sqlite3session, 0, 0);
- Tcl_CreateObjCommand(
- interp, "sqlite3session_foreach", test_sqlite3session_foreach, 0, 0
- );
- Tcl_CreateObjCommand(
- interp, "sqlite3changeset_invert", test_sqlite3changeset_invert, 0, 0
- );
- Tcl_CreateObjCommand(
- interp, "sqlite3changeset_concat", test_sqlite3changeset_concat, 0, 0
- );
- Tcl_CreateObjCommand(
- interp, "sqlite3changeset_apply", test_sqlite3changeset_apply, 0, 0
- );
- Tcl_CreateObjCommand(
- interp, "sqlite3changeset_apply_replace_all",
- test_sqlite3changeset_apply_replace_all, 0, 0
- );
+ struct Cmd {
+ const char *zCmd;
+ Tcl_ObjCmdProc *xProc;
+ } aCmd[] = {
+ { "sqlite3session", test_sqlite3session },
+ { "sqlite3session_foreach", test_sqlite3session_foreach },
+ { "sqlite3changeset_invert", test_sqlite3changeset_invert },
+ { "sqlite3changeset_concat", test_sqlite3changeset_concat },
+ { "sqlite3changeset_apply", test_sqlite3changeset_apply },
+ { "sqlite3changeset_apply_replace_all",
+ test_sqlite3changeset_apply_replace_all },
+ { "sql_exec_changeset", test_sql_exec_changeset },
+ };
+ int i;
+
+ for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){
+ struct Cmd *p = &aCmd[i];
+ Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, 0, 0);
+ }
+
return TCL_OK;
}
-C Fix\stypos\sin\scomments.\s\sNo\schanges\sto\srunning\scode.
-D 2016-08-27T20:21:51.309
+C Use\ssome\sof\sthe\sexample\scode\sfrom\sthe\ssessions\sdocumenatation\sin\sthe\ssessions\stest\scases.
+D 2016-08-29T14:18:18.207
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 5017381e4853b1472e01d5bb926be1268eba429c
F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
-F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596
+F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32
F ext/session/sqlite3session.h 7b9037818ee61f7429ca83e9866885ca6de5f764
-F ext/session/test_session.c 2caed9a659586428c63ca46e4900347b374487d4
+F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 78cd64e202fcbe9ce69070b0f48ccd0c6b48538d
-R 3fe3d686aa6a61df97c243454c02cd64
-U drh
-Z 90feb3c09ae2ca31e13afbfbff662667
+P a07269f2a0f87e0b736127f528f6caf3b63f9052
+R e338ebda27cef4eaa61a39e0a172ba0c
+U dan
+Z 11041cb022515aa05751c4e3c90843c8