From: dan Date: Tue, 27 Nov 2012 10:56:39 +0000 (+0000) Subject: Fix problems in test_sqllog.c. Clarify the experimental SQLITE_CONFIG_SQLLOG interfac... X-Git-Tag: version-3.7.15~34^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71ba10d3c9e8f8c8137d0efaaa549f38f9a8233c;p=thirdparty%2Fsqlite.git Fix problems in test_sqllog.c. Clarify the experimental SQLITE_CONFIG_SQLLOG interface. Handle at least the more likely error conditions in test_sqllog.c. FossilOrigin-Name: 429c5b2056d7b7c644ca53bc97b8e0b9cb89ab04 --- diff --git a/manifest b/manifest index 56f3032e28..3de91a4d81 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\soption\sto\sregister\sglobal\shooks\sused\sfor\slogging\sall\sSQL\sexecuted\sby\san\sapplication. -D 2012-11-26T19:50:41.133 +C Fix\sproblems\sin\stest_sqllog.c.\sClarify\sthe\sexperimental\sSQLITE_CONFIG_SQLLOG\sinterface.\sHandle\sat\sleast\sthe\smore\slikely\serror\sconditions\sin\stest_sqllog.c. +D 2012-11-27T10:56:39.734 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 82c41c0ed4cc94dd3cc7d498575b84c57c2c2384 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d -F src/main.c c0b8cfbe397801dfae1f63b56b6dd30b8726b199 +F src/main.c 448564ee3795b13c373bbc5c8590df8fbfe1d64c F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa @@ -176,7 +176,7 @@ F src/resolve.c 7b986a715ac281643309c29257bb58cfae7aa810 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 3a8baf4719f9723b4e0b43f2baa60692d0d921f8 F src/shell.c 24cd0aa74aff73ea08594629faead564c4c2a286 -F src/sqlite.h.in c0ab54580c16be8618fd9af48041dfc56cf071b2 +F src/sqlite.h.in 4e71a210f383b6d060bd3fdf81d850f0f8c4eca3 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h 68f23dcfc3fb6559c07b327ab6d8d2e63e4bb69e @@ -221,7 +221,7 @@ F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f F src/test_spellfix.c 76dd8d3111d2f5354c374f71fa23b752bd0b029c -F src/test_sqllog.c 5e8e25829947eee74ebb68a484d22a71c54b9c2f +F src/test_sqllog.c 426eb95f41d06f9a45af6cb58f80f516434edc9d F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae @@ -1025,10 +1025,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P d4c36d4991b048133efb21b251ab57fa66764d9d -R a9a22eaa36217a482e6b6184420d709e -T *branch * sqllog -T *sym-sqllog * -T -sym-trunk * +P cd501bbccf3e62b002317592cc331770b32c129a +R ad919a174cc92f00b19fd1b031dd4d29 U dan -Z 0aa6ee962f53d4f3c0dddb8a9d2ec33e +Z 5c76c382e687bb7efe7c77eaf9918880 diff --git a/manifest.uuid b/manifest.uuid index 25b4f98be5..ae47c04099 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd501bbccf3e62b002317592cc331770b32c129a \ No newline at end of file +429c5b2056d7b7c644ca53bc97b8e0b9cb89ab04 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7ef10605b5..b52d474443 100644 --- a/src/main.c +++ b/src/main.c @@ -134,7 +134,7 @@ int sqlite3_initialize(void){ #ifdef SQLITE_ENABLE_SQLLOG { - extern sqlite3_init_sqllog(void); + extern void sqlite3_init_sqllog(void); sqlite3_init_sqllog(); } #endif @@ -837,7 +837,8 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ - sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 0); + /* Closing the handle. Fourth parameter is passed the value 2. */ + sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); } #endif @@ -2475,9 +2476,9 @@ opendb_out: *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ - sqlite3GlobalConfig.xSqllog( - sqlite3GlobalConfig.pSqllogArg, db, zFilename, -1 - ); + /* Opening a db handle. Fourth parameter is passed 0. */ + void *pArg = sqlite3GlobalConfig.pSqllogArg; + sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); } #endif return sqlite3ApiExit(0, rc); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9770a7fc03..ba97cd7d4e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1599,7 +1599,15 @@ struct sqlite3_mem_methods { **
This option is only available if sqlite is compiled with the ** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should ** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). -** The second should be of type (void*). +** The second should be of type (void*). The callback is invoked by the library +** in three separate circumstances, identified by the value passed as the +** fourth parameter. If the fourth parameter is 0, then the database connection +** passed as the second argument has just been opened. The third argument +** points to a buffer containing the name of the main database file. If the +** fourth parameter is 1, then the SQL statement that the third parameter +** points to has just been executed. Or, if the fourth parameter is 2, then +** the connection being passed as the second parameter is being closed. The +** third parameter is passed NULL In this case. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ diff --git a/src/test_sqllog.c b/src/test_sqllog.c index ba0367039c..52aa3a6326 100644 --- a/src/test_sqllog.c +++ b/src/test_sqllog.c @@ -48,6 +48,13 @@ ** sqllog.idx - An index mapping from integer N to a database ** file name - indicating the full path of the ** database from which sqllog_N.db was copied. +** +** ERROR HANDLING: +** +** This module attempts to make a best effort to continue logging if an +** IO or other error is encountered. For example, if a log file cannot +** be opened logs are not collected for that connection, but other +** logging proceeds as expected. Errors are logged by calling sqlite3_log(). */ #include "sqlite3.h" @@ -56,6 +63,13 @@ #include "string.h" #include "assert.h" +#include "sys/types.h" +#include "unistd.h" +static int getProcessId(void){ + return (int)getpid(); +} + + #define ENVIRONMENT_VARIABLE1_NAME "SQLITE_SQLLOG_DIR" #define ENVIRONMENT_VARIABLE2_NAME "SQLITE_SQLLOG_REUSE_FILES" @@ -82,7 +96,7 @@ struct SLGlobal { /* Protected by SLGlobal.mutex */ int bReuse; /* True to avoid extra copies of db files */ - char zDir[SQLLOG_NAMESZ]; /* Directory to create files in */ + char zPrefix[SQLLOG_NAMESZ]; /* Prefix for all created files */ char zIdx[SQLLOG_NAMESZ]; /* Full path to *.idx file */ int iNextLog; /* Used to allocate file names */ int iNextDb; /* Used to allocate database file names */ @@ -135,36 +149,51 @@ static char *sqllogFindFile(const char *zFile){ /* Open the index file for reading */ fd = fopen(sqllogglobal.zIdx, "r"); + if( fd==0 ){ + sqlite3_log(SQLITE_IOERR, "sqllogFindFile(): error in fopen()"); + return 0; + } + /* Loop through each entry in the index file. If zFile is not NULL and the + ** entry is a match, then set zRet to point to the filename of the existing + ** copy and break out of the loop. */ while( feof(fd)==0 ){ - char *z; - int n; char zLine[SQLLOG_NAMESZ*2+5]; + if( fgets(zLine, sizeof(zLine), fd) ){ + int n; + char *z; - fgets(zLine, sizeof(zLine), fd); - z = zLine; - while( *z>='0' && *z<='9' ) z++; - while( *z==' ' ) z++; - - n = strlen(z); - while( n>0 && sqllog_isspace(z[n-1]) ) n--; - if( n==strlen(zFile) && 0==memcmp(zFile, z, n) ){ - char zBuf[16]; + zLine[sizeof(zLine)-1] = '\0'; z = zLine; - while( *z>='0' && *z<='9' ){ - zBuf[z-zLine] = *z; - z++; + while( *z>='0' && *z<='9' ) z++; + while( *z==' ' ) z++; + + n = strlen(z); + while( n>0 && sqllog_isspace(z[n-1]) ) n--; + + if( n==strlen(zFile) && 0==memcmp(zFile, z, n) ){ + char zBuf[16]; + memset(zBuf, 0, sizeof(zBuf)); + z = zLine; + while( *z>='0' && *z<='9' ){ + zBuf[z-zLine] = *z; + z++; + } + zRet = sqlite3_mprintf("%s_%s.db", sqllogglobal.zPrefix, zBuf); + break; } - zRet = sqlite3_mprintf("%s/sqllog_%s.db", sqllogglobal.zDir, zBuf); - break; } } + if( ferror(fd) ){ + sqlite3_log(SQLITE_IOERR, "sqllogFindFile(): error reading index file"); + } + fclose(fd); return zRet; } -static void sqllogFindAttached( +static int sqllogFindAttached( struct SLConn *p, /* Database connection */ const char *zSearch, /* Name to search for (or NULL) */ char *zName, /* OUT: Name of attached database */ @@ -201,6 +230,11 @@ static void sqllogFindAttached( rc = sqlite3_finalize(pStmt); } sqllogglobal.bRec = 0; + + if( rc!=SQLITE_OK ){ + sqlite3_log(rc, "sqllogFindAttached(): error in \"PRAGMA database_list\""); + } + return rc; } @@ -228,8 +262,11 @@ static void sqllogCopydb(struct SLConn *p, const char *zSearch, int bLog){ char zFile[SQLLOG_NAMESZ]; /* Database file name */ char *zFree; char *zInit = 0; + int rc; + + rc = sqllogFindAttached(p, zSearch, zName, zFile); + if( rc!=SQLITE_OK ) return; - sqllogFindAttached(p, zSearch, zName, zFile); if( zFile[0]=='\0' ){ zInit = sqlite3_mprintf(""); }else{ @@ -241,12 +278,11 @@ static void sqllogCopydb(struct SLConn *p, const char *zSearch, int bLog){ if( zInit==0 ){ int rc; sqlite3 *copy = 0; - FILE *fd; int iDb; /* Generate a file-name to use for the copy of this database */ iDb = sqllogglobal.iNextDb++; - zInit = sqlite3_mprintf("%s/sqllog_%d.db", sqllogglobal.zDir, iDb); + zInit = sqlite3_mprintf("%s_%d.db", sqllogglobal.zPrefix, iDb); /* Create the backup */ assert( sqllogglobal.bRec==0 ); @@ -258,21 +294,29 @@ static void sqllogCopydb(struct SLConn *p, const char *zSearch, int bLog){ pBak = sqlite3_backup_init(copy, "main", p->db, zName); if( pBak ){ sqlite3_backup_step(pBak, -1); - sqlite3_backup_finish(pBak); + rc = sqlite3_backup_finish(pBak); + }else{ + rc = sqlite3_errcode(copy); } sqlite3_close(copy); } sqllogglobal.bRec = 0; - /* Write an entry into the database index file */ - fd = fopen(sqllogglobal.zIdx, "a"); - fprintf(fd, "%d %s\n", iDb, zFile); - fclose(fd); + if( rc==SQLITE_OK ){ + /* Write an entry into the database index file */ + FILE *fd = fopen(sqllogglobal.zIdx, "a"); + if( fd ){ + fprintf(fd, "%d %s\n", iDb, zFile); + fclose(fd); + } + }else{ + sqlite3_log(rc, "sqllogCopydb(): error backing up database"); + } } } if( bLog ){ - zFree = sqlite3_mprintf("ATTACH '%q' AS '%q'; -- clock=%d steps=1\n", + zFree = sqlite3_mprintf("ATTACH '%q' AS '%q'; -- clock=%d\n", zInit, zName, sqllogglobal.iClock++ ); }else{ @@ -294,47 +338,44 @@ static void sqllogOpenlog(struct SLConn *p){ if( p->fd==0 ){ char *zLog; - /* If it is still NULL, have global.zDir point to a copy of environment - ** variable $ENVIRONMENT_VARIABLE1_NAME. */ - if( sqllogglobal.zDir[0]==0 ){ + /* If it is still NULL, have global.zPrefix point to a copy of + ** environment variable $ENVIRONMENT_VARIABLE1_NAME. */ + if( sqllogglobal.zPrefix[0]==0 ){ FILE *fd; char *zVar = getenv(ENVIRONMENT_VARIABLE1_NAME); - if( zVar==0 || strlen(zVar)>=(sizeof(sqllogglobal.zDir)) ) return; - memcpy(sqllogglobal.zDir, zVar, strlen(zVar)+1); - sprintf(sqllogglobal.zIdx, "%s/sqllog.idx", sqllogglobal.zDir); + if( zVar==0 || strlen(zVar)+10>=(sizeof(sqllogglobal.zPrefix)) ) return; + sprintf(sqllogglobal.zPrefix, "%s/sqllog_%d", zVar, getProcessId()); + sprintf(sqllogglobal.zIdx, "%s.idx", sqllogglobal.zPrefix); if( getenv(ENVIRONMENT_VARIABLE2_NAME) ){ sqllogglobal.bReuse = atoi(getenv(ENVIRONMENT_VARIABLE2_NAME)); } fd = fopen(sqllogglobal.zIdx, "w"); - close(fd); + if( fd ) fclose(fd); } /* Open the log file */ - zLog = sqlite3_mprintf("%s/sqllog_%d.sql", sqllogglobal.zDir, p->iLog); + zLog = sqlite3_mprintf("%s_%d.sql", sqllogglobal.zPrefix, p->iLog); p->fd = fopen(zLog, "w"); - assert( p->fd ); sqlite3_free(zLog); + if( p->fd==0 ){ + sqlite3_log(SQLITE_IOERR, "sqllogOpenlog(): Failed to open log file"); + } } } /* ** This function is called if the SQLLOG callback is invoked to report ** execution of an SQL statement. Parameter p is the connection the statement -** was executed by, parameter zSql is the text of the statement itself and -** parameter nStep is the number of times sqlite3_step() was called. +** was executed by and parameter zSql is the text of the statement itself. */ -static void testSqllogStmt(struct SLConn *p, const char *zSql, int nStep){ +static void testSqllogStmt(struct SLConn *p, const char *zSql){ const char *zFirst; /* Pointer to first token in zSql */ int nFirst; /* Size of token zFirst in bytes */ - assert( nStep>0 ); - sqllogTokenize(zSql, &zFirst, &nFirst); if( nFirst!=6 || 0!=sqlite3_strnicmp("ATTACH", zFirst, 6) ){ /* Not an ATTACH statement. Write this directly to the log. */ - fprintf(p->fd, "%s; -- clock=%d steps=%d\n", - zSql, sqllogglobal.iClock++, nStep - ); + fprintf(p->fd, "%s; -- clock=%d\n", zSql, sqllogglobal.iClock++); }else{ /* This is an ATTACH statement. Copy the database. */ sqllogCopydb(p, 0, 1); @@ -344,20 +385,15 @@ static void testSqllogStmt(struct SLConn *p, const char *zSql, int nStep){ /* ** The SQLITE_CONFIG_SQLLOG callback registered by sqlite3_init_sqllog(). */ -static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int nStep){ +static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int eType){ struct SLConn *p; sqlite3_mutex *master = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); -#if 0 - if( sqllogglobal.isErr && zSql ){ - /* If an error has already occurred, ignore all callbacks except - ** those reporting calls to sqlite3_close(). */ - return; - } -#endif + assert( eType==0 || eType==1 || eType==2 ); + assert( (eType==2)==(zSql==0) ); /* This is a database open command. */ - if( zSql && nStep<0 ){ + if( eType==0 ){ sqlite3_mutex_enter(master); if( sqllogglobal.mutex==0 ){ sqllogglobal.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); @@ -372,7 +408,7 @@ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int nStep){ sqlite3_mutex_enter(sqllogglobal.mutex); if( sqllogglobal.bRec==0 ){ sqllogOpenlog(p); - sqllogCopydb(p, "main", 0); + if( p->fd ) sqllogCopydb(p, "main", 0); } sqlite3_mutex_leave(sqllogglobal.mutex); } @@ -387,7 +423,7 @@ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int nStep){ if( i==sqllogglobal.nConn ) return; /* A database handle close command */ - if( zSql==0 ){ + if( eType==2 ){ sqlite3_mutex_enter(master); if( p->fd ) fclose(p->fd); p->db = 0; @@ -406,10 +442,10 @@ static void testSqllog(void *pCtx, sqlite3 *db, const char *zSql, int nStep){ sqlite3_mutex_leave(master); /* An ordinary SQL command. */ - }else{ + }else if( p->fd ){ sqlite3_mutex_enter(sqllogglobal.mutex); if( sqllogglobal.bRec==0 ){ - testSqllogStmt(p, zSql, nStep); + testSqllogStmt(p, zSql); } sqlite3_mutex_leave(sqllogglobal.mutex); }