Fossil SCM

When logging transaction errors on the error log, try to include information about where the transaction started.

drh 2018-07-13 16:26 trunk
Commit 43336f67c37beb7d1b4cad0804d1bd79da046cf69a77cb1626416dc539d4ba1e
2 files changed +24 -3 +2 -1
+24 -3
--- src/db.c
+++ src/db.c
@@ -124,10 +124,12 @@
124124
} aHook[5];
125125
char *azDeleteOnFail[3]; /* Files to delete on a failure */
126126
char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
127127
int nBeforeCommit; /* Number of entries in azBeforeCommit */
128128
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
129
+ const char *zStartFile; /* File in which transaction was started */
130
+ int iStartLine; /* Line of zStartFile where transaction started */
129131
} db = {0, 0, 0, 0, 0, 0, };
130132
131133
/*
132134
** Arrange for the given file to be deleted on a failure.
133135
*/
@@ -141,10 +143,18 @@
141143
** not in a transaction.
142144
*/
143145
int db_transaction_nesting_depth(void){
144146
return db.nBegin;
145147
}
148
+
149
+/*
150
+** Return a pointer to a string that is the code point where the
151
+** current transaction was started.
152
+*/
153
+char *db_transaction_start_point(void){
154
+ return mprintf("%s:%d", db.zStartFile, db.iStartLine);
155
+}
146156
147157
/*
148158
** This routine is called by the SQLite commit-hook mechanism
149159
** just prior to each commit. All this routine does is verify
150160
** that nBegin really is zero. That insures that transactions
@@ -159,19 +169,29 @@
159169
return 1;
160170
}
161171
return 0;
162172
}
163173
174
+/*
175
+** Silently add the filename and line number as parameter to each
176
+** db_begin_transaction call.
177
+*/
178
+#if INTERFACE
179
+#define db_begin_transaction() db_begin_transaction_real(__FILE__,__LINE__)
180
+#endif
181
+
164182
/*
165183
** Begin and end a nested transaction
166184
*/
167
-void db_begin_transaction(void){
185
+void db_begin_transaction_real(const char *zStartFile, int iStartLine){
168186
if( db.nBegin==0 ){
169187
db_multi_exec("BEGIN");
170188
sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
171189
db.nPriorChanges = sqlite3_total_changes(g.db);
172190
db.doRollback = 0;
191
+ db.zStartFile = zStartFile;
192
+ db.iStartLine = iStartLine;
173193
}
174194
db.nBegin++;
175195
}
176196
void db_end_transaction(int rollbackFlag){
177197
if( g.db==0 ) return;
@@ -522,11 +542,11 @@
522542
blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
523543
sqlite3_column_bytes(pStmt->pStmt, N));
524544
}
525545
Blob db_column_text_as_blob(Stmt *pStmt, int N){
526546
Blob x;
527
- blob_init(&x, sqlite3_column_text(pStmt->pStmt,N),
547
+ blob_init(&x, (char*)sqlite3_column_text(pStmt->pStmt,N),
528548
sqlite3_column_bytes(pStmt->pStmt,N));
529549
return x;
530550
}
531551
532552
/*
@@ -1783,11 +1803,12 @@
17831803
}
17841804
while( db.pAllStmt ){
17851805
db_finalize(db.pAllStmt);
17861806
}
17871807
if( db.nBegin && reportErrors ){
1788
- fossil_warning("Missed call to db_end_transaction(). Rolling back.");
1808
+ fossil_warning("Transaction started at %s:%d never commits",
1809
+ db.zStartFile, db.iStartLine);
17891810
db_end_transaction(1);
17901811
}
17911812
pStmt = 0;
17921813
g.dbIgnoreErrors++; /* Stop "database locked" warnings from PRAGMA optimize */
17931814
sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
17941815
--- src/db.c
+++ src/db.c
@@ -124,10 +124,12 @@
124 } aHook[5];
125 char *azDeleteOnFail[3]; /* Files to delete on a failure */
126 char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
127 int nBeforeCommit; /* Number of entries in azBeforeCommit */
128 int nPriorChanges; /* sqlite3_total_changes() at transaction start */
 
 
129 } db = {0, 0, 0, 0, 0, 0, };
130
131 /*
132 ** Arrange for the given file to be deleted on a failure.
133 */
@@ -141,10 +143,18 @@
141 ** not in a transaction.
142 */
143 int db_transaction_nesting_depth(void){
144 return db.nBegin;
145 }
 
 
 
 
 
 
 
 
146
147 /*
148 ** This routine is called by the SQLite commit-hook mechanism
149 ** just prior to each commit. All this routine does is verify
150 ** that nBegin really is zero. That insures that transactions
@@ -159,19 +169,29 @@
159 return 1;
160 }
161 return 0;
162 }
163
 
 
 
 
 
 
 
 
164 /*
165 ** Begin and end a nested transaction
166 */
167 void db_begin_transaction(void){
168 if( db.nBegin==0 ){
169 db_multi_exec("BEGIN");
170 sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
171 db.nPriorChanges = sqlite3_total_changes(g.db);
172 db.doRollback = 0;
 
 
173 }
174 db.nBegin++;
175 }
176 void db_end_transaction(int rollbackFlag){
177 if( g.db==0 ) return;
@@ -522,11 +542,11 @@
522 blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
523 sqlite3_column_bytes(pStmt->pStmt, N));
524 }
525 Blob db_column_text_as_blob(Stmt *pStmt, int N){
526 Blob x;
527 blob_init(&x, sqlite3_column_text(pStmt->pStmt,N),
528 sqlite3_column_bytes(pStmt->pStmt,N));
529 return x;
530 }
531
532 /*
@@ -1783,11 +1803,12 @@
1783 }
1784 while( db.pAllStmt ){
1785 db_finalize(db.pAllStmt);
1786 }
1787 if( db.nBegin && reportErrors ){
1788 fossil_warning("Missed call to db_end_transaction(). Rolling back.");
 
1789 db_end_transaction(1);
1790 }
1791 pStmt = 0;
1792 g.dbIgnoreErrors++; /* Stop "database locked" warnings from PRAGMA optimize */
1793 sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
1794
--- src/db.c
+++ src/db.c
@@ -124,10 +124,12 @@
124 } aHook[5];
125 char *azDeleteOnFail[3]; /* Files to delete on a failure */
126 char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
127 int nBeforeCommit; /* Number of entries in azBeforeCommit */
128 int nPriorChanges; /* sqlite3_total_changes() at transaction start */
129 const char *zStartFile; /* File in which transaction was started */
130 int iStartLine; /* Line of zStartFile where transaction started */
131 } db = {0, 0, 0, 0, 0, 0, };
132
133 /*
134 ** Arrange for the given file to be deleted on a failure.
135 */
@@ -141,10 +143,18 @@
143 ** not in a transaction.
144 */
145 int db_transaction_nesting_depth(void){
146 return db.nBegin;
147 }
148
149 /*
150 ** Return a pointer to a string that is the code point where the
151 ** current transaction was started.
152 */
153 char *db_transaction_start_point(void){
154 return mprintf("%s:%d", db.zStartFile, db.iStartLine);
155 }
156
157 /*
158 ** This routine is called by the SQLite commit-hook mechanism
159 ** just prior to each commit. All this routine does is verify
160 ** that nBegin really is zero. That insures that transactions
@@ -159,19 +169,29 @@
169 return 1;
170 }
171 return 0;
172 }
173
174 /*
175 ** Silently add the filename and line number as parameter to each
176 ** db_begin_transaction call.
177 */
178 #if INTERFACE
179 #define db_begin_transaction() db_begin_transaction_real(__FILE__,__LINE__)
180 #endif
181
182 /*
183 ** Begin and end a nested transaction
184 */
185 void db_begin_transaction_real(const char *zStartFile, int iStartLine){
186 if( db.nBegin==0 ){
187 db_multi_exec("BEGIN");
188 sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
189 db.nPriorChanges = sqlite3_total_changes(g.db);
190 db.doRollback = 0;
191 db.zStartFile = zStartFile;
192 db.iStartLine = iStartLine;
193 }
194 db.nBegin++;
195 }
196 void db_end_transaction(int rollbackFlag){
197 if( g.db==0 ) return;
@@ -522,11 +542,11 @@
542 blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N),
543 sqlite3_column_bytes(pStmt->pStmt, N));
544 }
545 Blob db_column_text_as_blob(Stmt *pStmt, int N){
546 Blob x;
547 blob_init(&x, (char*)sqlite3_column_text(pStmt->pStmt,N),
548 sqlite3_column_bytes(pStmt->pStmt,N));
549 return x;
550 }
551
552 /*
@@ -1783,11 +1803,12 @@
1803 }
1804 while( db.pAllStmt ){
1805 db_finalize(db.pAllStmt);
1806 }
1807 if( db.nBegin && reportErrors ){
1808 fossil_warning("Transaction started at %s:%d never commits",
1809 db.zStartFile, db.iStartLine);
1810 db_end_transaction(1);
1811 }
1812 pStmt = 0;
1813 g.dbIgnoreErrors++; /* Stop "database locked" warnings from PRAGMA optimize */
1814 sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
1815
+2 -1
--- src/email.c
+++ src/email.c
@@ -2064,11 +2064,12 @@
20642064
*/
20652065
void email_auto_exec(void){
20662066
int iJulianDay;
20672067
if( g.db==0 ) return;
20682068
if( db_transaction_nesting_depth()!=0 ){
2069
- fossil_warning("Called email_auto_exec() from within a transaction");
2069
+ fossil_warning("Called email_auto_exec() from within transaction "
2070
+ "started at %z", db_transaction_start_point());
20702071
return;
20712072
}
20722073
db_begin_transaction();
20732074
if( !email_tables_exist() ) goto autoexec_done;
20742075
if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done;
20752076
--- src/email.c
+++ src/email.c
@@ -2064,11 +2064,12 @@
2064 */
2065 void email_auto_exec(void){
2066 int iJulianDay;
2067 if( g.db==0 ) return;
2068 if( db_transaction_nesting_depth()!=0 ){
2069 fossil_warning("Called email_auto_exec() from within a transaction");
 
2070 return;
2071 }
2072 db_begin_transaction();
2073 if( !email_tables_exist() ) goto autoexec_done;
2074 if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done;
2075
--- src/email.c
+++ src/email.c
@@ -2064,11 +2064,12 @@
2064 */
2065 void email_auto_exec(void){
2066 int iJulianDay;
2067 if( g.db==0 ) return;
2068 if( db_transaction_nesting_depth()!=0 ){
2069 fossil_warning("Called email_auto_exec() from within transaction "
2070 "started at %z", db_transaction_start_point());
2071 return;
2072 }
2073 db_begin_transaction();
2074 if( !email_tables_exist() ) goto autoexec_done;
2075 if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done;
2076

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button