Fossil SCM
Enhance the --sqltrace logic. Using those enhancements, locate and fix and unclosed transaction in the email alert sender logic.
Commit
f3de8b663256229dc5f02bec62160160d521a5622ee063869aeb08c46cf0ab21
Parent
0398e41aa6f72c0…
2 files changed
+10
-2
+9
-2
M
src/db.c
+10
-2
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -159,17 +159,21 @@ | ||
| 159 | 159 | void db_begin_transaction(void){ |
| 160 | 160 | if( db.nBegin==0 ){ |
| 161 | 161 | db_multi_exec("BEGIN"); |
| 162 | 162 | sqlite3_commit_hook(g.db, db_verify_at_commit, 0); |
| 163 | 163 | db.nPriorChanges = sqlite3_total_changes(g.db); |
| 164 | + db.doRollback = 0; | |
| 164 | 165 | } |
| 165 | 166 | db.nBegin++; |
| 166 | 167 | } |
| 167 | 168 | void db_end_transaction(int rollbackFlag){ |
| 168 | 169 | if( g.db==0 ) return; |
| 169 | 170 | if( db.nBegin<=0 ) return; |
| 170 | - if( rollbackFlag ) db.doRollback = 1; | |
| 171 | + if( rollbackFlag ){ | |
| 172 | + db.doRollback = 1; | |
| 173 | + if( g.fSqlTrace ) fossil_trace("-- ROLLBACK by request\n"); | |
| 174 | + } | |
| 171 | 175 | db.nBegin--; |
| 172 | 176 | if( db.nBegin==0 ){ |
| 173 | 177 | int i; |
| 174 | 178 | if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){ |
| 175 | 179 | i = 0; |
| @@ -180,11 +184,15 @@ | ||
| 180 | 184 | i++; |
| 181 | 185 | } |
| 182 | 186 | leaf_do_pending_checks(); |
| 183 | 187 | } |
| 184 | 188 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 185 | - db.doRollback |= db.aHook[i].xHook(); | |
| 189 | + int rc = db.aHook[i].xHook(); | |
| 190 | + if( rc ){ | |
| 191 | + db.doRollback = 1; | |
| 192 | + if( g.fSqlTrace ) fossil_trace("-- ROLLBACK due to aHook[%d]\n", i); | |
| 193 | + } | |
| 186 | 194 | } |
| 187 | 195 | while( db.pAllStmt ){ |
| 188 | 196 | db_finalize(db.pAllStmt); |
| 189 | 197 | } |
| 190 | 198 | db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 191 | 199 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -159,17 +159,21 @@ | |
| 159 | void db_begin_transaction(void){ |
| 160 | if( db.nBegin==0 ){ |
| 161 | db_multi_exec("BEGIN"); |
| 162 | sqlite3_commit_hook(g.db, db_verify_at_commit, 0); |
| 163 | db.nPriorChanges = sqlite3_total_changes(g.db); |
| 164 | } |
| 165 | db.nBegin++; |
| 166 | } |
| 167 | void db_end_transaction(int rollbackFlag){ |
| 168 | if( g.db==0 ) return; |
| 169 | if( db.nBegin<=0 ) return; |
| 170 | if( rollbackFlag ) db.doRollback = 1; |
| 171 | db.nBegin--; |
| 172 | if( db.nBegin==0 ){ |
| 173 | int i; |
| 174 | if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){ |
| 175 | i = 0; |
| @@ -180,11 +184,15 @@ | |
| 180 | i++; |
| 181 | } |
| 182 | leaf_do_pending_checks(); |
| 183 | } |
| 184 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 185 | db.doRollback |= db.aHook[i].xHook(); |
| 186 | } |
| 187 | while( db.pAllStmt ){ |
| 188 | db_finalize(db.pAllStmt); |
| 189 | } |
| 190 | db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 191 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -159,17 +159,21 @@ | |
| 159 | void db_begin_transaction(void){ |
| 160 | if( db.nBegin==0 ){ |
| 161 | db_multi_exec("BEGIN"); |
| 162 | sqlite3_commit_hook(g.db, db_verify_at_commit, 0); |
| 163 | db.nPriorChanges = sqlite3_total_changes(g.db); |
| 164 | db.doRollback = 0; |
| 165 | } |
| 166 | db.nBegin++; |
| 167 | } |
| 168 | void db_end_transaction(int rollbackFlag){ |
| 169 | if( g.db==0 ) return; |
| 170 | if( db.nBegin<=0 ) return; |
| 171 | if( rollbackFlag ){ |
| 172 | db.doRollback = 1; |
| 173 | if( g.fSqlTrace ) fossil_trace("-- ROLLBACK by request\n"); |
| 174 | } |
| 175 | db.nBegin--; |
| 176 | if( db.nBegin==0 ){ |
| 177 | int i; |
| 178 | if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){ |
| 179 | i = 0; |
| @@ -180,11 +184,15 @@ | |
| 184 | i++; |
| 185 | } |
| 186 | leaf_do_pending_checks(); |
| 187 | } |
| 188 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 189 | int rc = db.aHook[i].xHook(); |
| 190 | if( rc ){ |
| 191 | db.doRollback = 1; |
| 192 | if( g.fSqlTrace ) fossil_trace("-- ROLLBACK due to aHook[%d]\n", i); |
| 193 | } |
| 194 | } |
| 195 | while( db.pAllStmt ){ |
| 196 | db_finalize(db.pAllStmt); |
| 197 | } |
| 198 | db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT"); |
| 199 |
+9
-2
| --- src/email.c | ||
| +++ src/email.c | ||
| @@ -1677,10 +1677,11 @@ | ||
| 1677 | 1677 | const char *zRepoName; |
| 1678 | 1678 | const char *zFrom; |
| 1679 | 1679 | const char *zDest = (flags & SENDALERT_STDOUT) ? "stdout" : 0; |
| 1680 | 1680 | EmailSender *pSender = 0; |
| 1681 | 1681 | |
| 1682 | + if( g.fSqlTrace ) fossil_trace("-- BEGIN email_send_alerts(%u)\n", flags); | |
| 1682 | 1683 | db_begin_transaction(); |
| 1683 | 1684 | if( !email_enabled() ) goto send_alerts_done; |
| 1684 | 1685 | zUrl = db_get("email-url",0); |
| 1685 | 1686 | if( zUrl==0 ) goto send_alerts_done; |
| 1686 | 1687 | zRepoName = db_get("email-subname",0); |
| @@ -1703,11 +1704,11 @@ | ||
| 1703 | 1704 | "INSERT INTO wantalert SELECT eventid FROM pending_alert" |
| 1704 | 1705 | " WHERE sentSep IS FALSE" |
| 1705 | 1706 | ); |
| 1706 | 1707 | } |
| 1707 | 1708 | pEvents = email_compute_event_text(&nEvent); |
| 1708 | - if( nEvent==0 ) return; | |
| 1709 | + if( nEvent==0 ) goto send_alerts_done; | |
| 1709 | 1710 | blob_init(&hdr, 0, 0); |
| 1710 | 1711 | blob_init(&body, 0, 0); |
| 1711 | 1712 | db_prepare(&q, |
| 1712 | 1713 | "SELECT" |
| 1713 | 1714 | " hex(subscriberCode)," /* 0 */ |
| @@ -1757,10 +1758,11 @@ | ||
| 1757 | 1758 | } |
| 1758 | 1759 | db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep"); |
| 1759 | 1760 | } |
| 1760 | 1761 | send_alerts_done: |
| 1761 | 1762 | email_sender_free(pSender); |
| 1763 | + if( g.fSqlTrace ) fossil_trace("-- END email_send_alerts(%u)\n", flags); | |
| 1762 | 1764 | db_end_transaction(0); |
| 1763 | 1765 | } |
| 1764 | 1766 | |
| 1765 | 1767 | /* |
| 1766 | 1768 | ** Check to see if any email notifications need to occur, and then |
| @@ -1776,13 +1778,18 @@ | ||
| 1776 | 1778 | if( !email_tables_exist() ) goto autoexec_done; |
| 1777 | 1779 | if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done; |
| 1778 | 1780 | if( !db_exists("SELECT 1 FROM pending_alert") ) goto autoexec_done; |
| 1779 | 1781 | email_send_alerts(0); |
| 1780 | 1782 | iJulianDay = db_int(0, "SELECT julianday('now')"); |
| 1783 | + if( g.fSqlTrace ) fossil_trace("-- iJulianDay: %d\n", iJulianDay); | |
| 1781 | 1784 | if( iJulianDay>db_get_int("email-last-digest",0) ){ |
| 1785 | + db_multi_exec( | |
| 1786 | + "REPLACE INTO repository.config(name,value,mtime)" | |
| 1787 | + " VALUES('email-last-digest',%d,now())", | |
| 1788 | + iJulianDay | |
| 1789 | + ); | |
| 1782 | 1790 | email_send_alerts(SENDALERT_DIGEST); |
| 1783 | - db_set_int("email-last-digest", iJulianDay, 0); | |
| 1784 | 1791 | } |
| 1785 | 1792 | |
| 1786 | 1793 | autoexec_done: |
| 1787 | 1794 | db_end_transaction(0); |
| 1788 | 1795 | } |
| 1789 | 1796 |
| --- src/email.c | |
| +++ src/email.c | |
| @@ -1677,10 +1677,11 @@ | |
| 1677 | const char *zRepoName; |
| 1678 | const char *zFrom; |
| 1679 | const char *zDest = (flags & SENDALERT_STDOUT) ? "stdout" : 0; |
| 1680 | EmailSender *pSender = 0; |
| 1681 | |
| 1682 | db_begin_transaction(); |
| 1683 | if( !email_enabled() ) goto send_alerts_done; |
| 1684 | zUrl = db_get("email-url",0); |
| 1685 | if( zUrl==0 ) goto send_alerts_done; |
| 1686 | zRepoName = db_get("email-subname",0); |
| @@ -1703,11 +1704,11 @@ | |
| 1703 | "INSERT INTO wantalert SELECT eventid FROM pending_alert" |
| 1704 | " WHERE sentSep IS FALSE" |
| 1705 | ); |
| 1706 | } |
| 1707 | pEvents = email_compute_event_text(&nEvent); |
| 1708 | if( nEvent==0 ) return; |
| 1709 | blob_init(&hdr, 0, 0); |
| 1710 | blob_init(&body, 0, 0); |
| 1711 | db_prepare(&q, |
| 1712 | "SELECT" |
| 1713 | " hex(subscriberCode)," /* 0 */ |
| @@ -1757,10 +1758,11 @@ | |
| 1757 | } |
| 1758 | db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep"); |
| 1759 | } |
| 1760 | send_alerts_done: |
| 1761 | email_sender_free(pSender); |
| 1762 | db_end_transaction(0); |
| 1763 | } |
| 1764 | |
| 1765 | /* |
| 1766 | ** Check to see if any email notifications need to occur, and then |
| @@ -1776,13 +1778,18 @@ | |
| 1776 | if( !email_tables_exist() ) goto autoexec_done; |
| 1777 | if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done; |
| 1778 | if( !db_exists("SELECT 1 FROM pending_alert") ) goto autoexec_done; |
| 1779 | email_send_alerts(0); |
| 1780 | iJulianDay = db_int(0, "SELECT julianday('now')"); |
| 1781 | if( iJulianDay>db_get_int("email-last-digest",0) ){ |
| 1782 | email_send_alerts(SENDALERT_DIGEST); |
| 1783 | db_set_int("email-last-digest", iJulianDay, 0); |
| 1784 | } |
| 1785 | |
| 1786 | autoexec_done: |
| 1787 | db_end_transaction(0); |
| 1788 | } |
| 1789 |
| --- src/email.c | |
| +++ src/email.c | |
| @@ -1677,10 +1677,11 @@ | |
| 1677 | const char *zRepoName; |
| 1678 | const char *zFrom; |
| 1679 | const char *zDest = (flags & SENDALERT_STDOUT) ? "stdout" : 0; |
| 1680 | EmailSender *pSender = 0; |
| 1681 | |
| 1682 | if( g.fSqlTrace ) fossil_trace("-- BEGIN email_send_alerts(%u)\n", flags); |
| 1683 | db_begin_transaction(); |
| 1684 | if( !email_enabled() ) goto send_alerts_done; |
| 1685 | zUrl = db_get("email-url",0); |
| 1686 | if( zUrl==0 ) goto send_alerts_done; |
| 1687 | zRepoName = db_get("email-subname",0); |
| @@ -1703,11 +1704,11 @@ | |
| 1704 | "INSERT INTO wantalert SELECT eventid FROM pending_alert" |
| 1705 | " WHERE sentSep IS FALSE" |
| 1706 | ); |
| 1707 | } |
| 1708 | pEvents = email_compute_event_text(&nEvent); |
| 1709 | if( nEvent==0 ) goto send_alerts_done; |
| 1710 | blob_init(&hdr, 0, 0); |
| 1711 | blob_init(&body, 0, 0); |
| 1712 | db_prepare(&q, |
| 1713 | "SELECT" |
| 1714 | " hex(subscriberCode)," /* 0 */ |
| @@ -1757,10 +1758,11 @@ | |
| 1758 | } |
| 1759 | db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep"); |
| 1760 | } |
| 1761 | send_alerts_done: |
| 1762 | email_sender_free(pSender); |
| 1763 | if( g.fSqlTrace ) fossil_trace("-- END email_send_alerts(%u)\n", flags); |
| 1764 | db_end_transaction(0); |
| 1765 | } |
| 1766 | |
| 1767 | /* |
| 1768 | ** Check to see if any email notifications need to occur, and then |
| @@ -1776,13 +1778,18 @@ | |
| 1778 | if( !email_tables_exist() ) goto autoexec_done; |
| 1779 | if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done; |
| 1780 | if( !db_exists("SELECT 1 FROM pending_alert") ) goto autoexec_done; |
| 1781 | email_send_alerts(0); |
| 1782 | iJulianDay = db_int(0, "SELECT julianday('now')"); |
| 1783 | if( g.fSqlTrace ) fossil_trace("-- iJulianDay: %d\n", iJulianDay); |
| 1784 | if( iJulianDay>db_get_int("email-last-digest",0) ){ |
| 1785 | db_multi_exec( |
| 1786 | "REPLACE INTO repository.config(name,value,mtime)" |
| 1787 | " VALUES('email-last-digest',%d,now())", |
| 1788 | iJulianDay |
| 1789 | ); |
| 1790 | email_send_alerts(SENDALERT_DIGEST); |
| 1791 | } |
| 1792 | |
| 1793 | autoexec_done: |
| 1794 | db_end_transaction(0); |
| 1795 | } |
| 1796 |