Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When logging transaction errors on the error log, try to include information about where the transaction started. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
43336f67c37beb7d1b4cad0804d1bd79 |
User & Date: | drh 2018-07-13 16:26:12.587 |
Context
2018-07-13
| ||
18:20 | Improved code to discover the IP address of the peer. Record the IP address of the peer in a Received: header line of all input emails. ... (check-in: 9979edbd user: drh tags: trunk) | |
16:26 | When logging transaction errors on the error log, try to include information about where the transaction started. ... (check-in: 43336f67 user: drh tags: trunk) | |
16:06 | When rendering SQLite log messages to the error log, include the SQL for all busy SQL statements in the log message. ... (check-in: c6ecf21f user: drh tags: trunk) | |
Changes
Changes to src/db.c.
︙ | ︙ | |||
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | int (*xHook)(void); /* Functions to call at db_end_transaction() */ int sequence; /* Call functions in sequence order */ } aHook[5]; char *azDeleteOnFail[3]; /* Files to delete on a failure */ char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */ int nBeforeCommit; /* Number of entries in azBeforeCommit */ int nPriorChanges; /* sqlite3_total_changes() at transaction start */ } db = {0, 0, 0, 0, 0, 0, }; /* ** Arrange for the given file to be deleted on a failure. */ void db_delete_on_failure(const char *zFilename){ assert( db.nDeleteOnFail<count(db.azDeleteOnFail) ); db.azDeleteOnFail[db.nDeleteOnFail++] = fossil_strdup(zFilename); } /* ** Return the transaction nesting depth. 0 means we are currently ** not in a transaction. */ int db_transaction_nesting_depth(void){ return db.nBegin; } /* ** This routine is called by the SQLite commit-hook mechanism ** just prior to each commit. All this routine does is verify ** that nBegin really is zero. That insures that transactions ** cannot commit by any means other than by calling db_end_transaction() ** below. ** ** This is just a safety and sanity check. */ static int db_verify_at_commit(void *notUsed){ if( db.nBegin ){ fossil_panic("illegal commit attempt"); return 1; } return 0; } /* ** Begin and end a nested transaction */ | > > > > > > > > > > > > > > > > > > | > > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | int (*xHook)(void); /* Functions to call at db_end_transaction() */ int sequence; /* Call functions in sequence order */ } aHook[5]; char *azDeleteOnFail[3]; /* Files to delete on a failure */ char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */ int nBeforeCommit; /* Number of entries in azBeforeCommit */ int nPriorChanges; /* sqlite3_total_changes() at transaction start */ const char *zStartFile; /* File in which transaction was started */ int iStartLine; /* Line of zStartFile where transaction started */ } db = {0, 0, 0, 0, 0, 0, }; /* ** Arrange for the given file to be deleted on a failure. */ void db_delete_on_failure(const char *zFilename){ assert( db.nDeleteOnFail<count(db.azDeleteOnFail) ); db.azDeleteOnFail[db.nDeleteOnFail++] = fossil_strdup(zFilename); } /* ** Return the transaction nesting depth. 0 means we are currently ** not in a transaction. */ int db_transaction_nesting_depth(void){ return db.nBegin; } /* ** Return a pointer to a string that is the code point where the ** current transaction was started. */ char *db_transaction_start_point(void){ return mprintf("%s:%d", db.zStartFile, db.iStartLine); } /* ** This routine is called by the SQLite commit-hook mechanism ** just prior to each commit. All this routine does is verify ** that nBegin really is zero. That insures that transactions ** cannot commit by any means other than by calling db_end_transaction() ** below. ** ** This is just a safety and sanity check. */ static int db_verify_at_commit(void *notUsed){ if( db.nBegin ){ fossil_panic("illegal commit attempt"); return 1; } return 0; } /* ** Silently add the filename and line number as parameter to each ** db_begin_transaction call. */ #if INTERFACE #define db_begin_transaction() db_begin_transaction_real(__FILE__,__LINE__) #endif /* ** Begin and end a nested transaction */ void db_begin_transaction_real(const char *zStartFile, int iStartLine){ if( db.nBegin==0 ){ db_multi_exec("BEGIN"); sqlite3_commit_hook(g.db, db_verify_at_commit, 0); db.nPriorChanges = sqlite3_total_changes(g.db); db.doRollback = 0; db.zStartFile = zStartFile; db.iStartLine = iStartLine; } db.nBegin++; } void db_end_transaction(int rollbackFlag){ if( g.db==0 ) return; if( db.nBegin<=0 ){ fossil_warning("Extra call to db_end_transaction"); |
︙ | ︙ | |||
520 521 522 523 524 525 526 | } void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){ blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N), sqlite3_column_bytes(pStmt->pStmt, N)); } Blob db_column_text_as_blob(Stmt *pStmt, int N){ Blob x; | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | } void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){ blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N), sqlite3_column_bytes(pStmt->pStmt, N)); } Blob db_column_text_as_blob(Stmt *pStmt, int N){ Blob x; blob_init(&x, (char*)sqlite3_column_text(pStmt->pStmt,N), sqlite3_column_bytes(pStmt->pStmt,N)); return x; } /* ** Initialize a blob to an ephemeral copy of the content of a ** column in the current row. The data in the blob will become |
︙ | ︙ | |||
1781 1782 1783 1784 1785 1786 1787 | fprintf(stderr, "-- PCACHE_OVFLOW %10d %10d\n", cur, hiwtr); fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare); } while( db.pAllStmt ){ db_finalize(db.pAllStmt); } if( db.nBegin && reportErrors ){ | | > | 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 | fprintf(stderr, "-- PCACHE_OVFLOW %10d %10d\n", cur, hiwtr); fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare); } while( db.pAllStmt ){ db_finalize(db.pAllStmt); } if( db.nBegin && reportErrors ){ fossil_warning("Transaction started at %s:%d never commits", db.zStartFile, db.iStartLine); db_end_transaction(1); } pStmt = 0; g.dbIgnoreErrors++; /* Stop "database locked" warnings from PRAGMA optimize */ sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0); g.dbIgnoreErrors--; db_close_config(); |
︙ | ︙ |
Changes to src/email.c.
︙ | ︙ | |||
2062 2063 2064 2065 2066 2067 2068 | ** This routine is called after certain webpages have been run and ** have already responded. */ void email_auto_exec(void){ int iJulianDay; if( g.db==0 ) return; if( db_transaction_nesting_depth()!=0 ){ | | > | 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 | ** This routine is called after certain webpages have been run and ** have already responded. */ void email_auto_exec(void){ int iJulianDay; if( g.db==0 ) return; if( db_transaction_nesting_depth()!=0 ){ fossil_warning("Called email_auto_exec() from within transaction " "started at %z", db_transaction_start_point()); return; } db_begin_transaction(); if( !email_tables_exist() ) goto autoexec_done; if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done; email_send_alerts(0); iJulianDay = db_int(0, "SELECT julianday('now')"); |
︙ | ︙ |