Fossil

Check-in [f3de8b66]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance the --sqltrace logic. Using those enhancements, locate and fix and unclosed transaction in the email alert sender logic.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f3de8b663256229dc5f02bec62160160d521a5622ee063869aeb08c46cf0ab21
User & Date: drh 2018-06-24 16:38:11.959
Context
2018-06-24
17:44
Extra defenses against running the digest alert generator in a context where the transaction will rollback, thus failing to record the new digest time. Change the "fossil server" and "fossil ui" commands to always log errors to the console if no other error logging is defined. ... (check-in: f87fb027 user: drh tags: trunk)
16:38
Enhance the --sqltrace logic. Using those enhancements, locate and fix and unclosed transaction in the email alert sender logic. ... (check-in: f3de8b66 user: drh tags: trunk)
10:07
Fix an SQL syntax error. ... (check-in: 0398e41a user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
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
** Begin and end a nested transaction
*/
void db_begin_transaction(void){
  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.nBegin++;
}
void db_end_transaction(int rollbackFlag){
  if( g.db==0 ) return;
  if( db.nBegin<=0 ) return;
  if( rollbackFlag ) db.doRollback = 1;



  db.nBegin--;
  if( db.nBegin==0 ){
    int i;
    if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){
      i = 0;
      while( db.nBeforeCommit ){
        db.nBeforeCommit--;
        sqlite3_exec(g.db, db.azBeforeCommit[i], 0, 0, 0);
        sqlite3_free(db.azBeforeCommit[i]);
        i++;
      }
      leaf_do_pending_checks();
    }
    for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){


      db.doRollback |= db.aHook[i].xHook();


    }
    while( db.pAllStmt ){
      db_finalize(db.pAllStmt);
    }
    db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
    db.doRollback = 0;
  }







>






|
>
>
>














>
>
|
>
>







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
200
** Begin and end a nested transaction
*/
void db_begin_transaction(void){
  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.nBegin++;
}
void db_end_transaction(int rollbackFlag){
  if( g.db==0 ) return;
  if( db.nBegin<=0 ) return;
  if( rollbackFlag ){
    db.doRollback = 1;
    if( g.fSqlTrace ) fossil_trace("-- ROLLBACK by request\n");
  }
  db.nBegin--;
  if( db.nBegin==0 ){
    int i;
    if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){
      i = 0;
      while( db.nBeforeCommit ){
        db.nBeforeCommit--;
        sqlite3_exec(g.db, db.azBeforeCommit[i], 0, 0, 0);
        sqlite3_free(db.azBeforeCommit[i]);
        i++;
      }
      leaf_do_pending_checks();
    }
    for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){
      int rc = db.aHook[i].xHook();
      if( rc ){
        db.doRollback = 1;
        if( g.fSqlTrace ) fossil_trace("-- ROLLBACK due to aHook[%d]\n", i);
      }
    }
    while( db.pAllStmt ){
      db_finalize(db.pAllStmt);
    }
    db_multi_exec("%s", db.doRollback ? "ROLLBACK" : "COMMIT");
    db.doRollback = 0;
  }
Changes to src/email.c.
1675
1676
1677
1678
1679
1680
1681

1682
1683
1684
1685
1686
1687
1688
  Blob hdr, body;
  const char *zUrl;
  const char *zRepoName;
  const char *zFrom;
  const char *zDest = (flags & SENDALERT_STDOUT) ? "stdout" : 0;
  EmailSender *pSender = 0;


  db_begin_transaction();
  if( !email_enabled() ) goto send_alerts_done;
  zUrl = db_get("email-url",0);
  if( zUrl==0 ) goto send_alerts_done;
  zRepoName = db_get("email-subname",0);
  if( zRepoName==0 ) goto send_alerts_done;
  zFrom = db_get("email-self",0);







>







1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
  Blob hdr, body;
  const char *zUrl;
  const char *zRepoName;
  const char *zFrom;
  const char *zDest = (flags & SENDALERT_STDOUT) ? "stdout" : 0;
  EmailSender *pSender = 0;

  if( g.fSqlTrace ) fossil_trace("-- BEGIN email_send_alerts(%u)\n", flags);
  db_begin_transaction();
  if( !email_enabled() ) goto send_alerts_done;
  zUrl = db_get("email-url",0);
  if( zUrl==0 ) goto send_alerts_done;
  zRepoName = db_get("email-subname",0);
  if( zRepoName==0 ) goto send_alerts_done;
  zFrom = db_get("email-self",0);
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
  }else{
    db_multi_exec(
      "INSERT INTO wantalert SELECT eventid FROM pending_alert"
      "  WHERE sentSep IS FALSE"
    );
  }
  pEvents = email_compute_event_text(&nEvent);
  if( nEvent==0 ) return;
  blob_init(&hdr, 0, 0);
  blob_init(&body, 0, 0);
  db_prepare(&q,
     "SELECT"
     " hex(subscriberCode),"  /* 0 */
     " semail,"               /* 1 */
     " ssub"                  /* 2 */







|







1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
  }else{
    db_multi_exec(
      "INSERT INTO wantalert SELECT eventid FROM pending_alert"
      "  WHERE sentSep IS FALSE"
    );
  }
  pEvents = email_compute_event_text(&nEvent);
  if( nEvent==0 ) goto send_alerts_done;
  blob_init(&hdr, 0, 0);
  blob_init(&body, 0, 0);
  db_prepare(&q,
     "SELECT"
     " hex(subscriberCode),"  /* 0 */
     " semail,"               /* 1 */
     " ssub"                  /* 2 */
1755
1756
1757
1758
1759
1760
1761

1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780

1781





1782
1783
1784
1785
1786
1787
1788
1789
1790
    }else{
      db_multi_exec("UPDATE pending_alert SET sentSep=true");
    }
    db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep");
  }
send_alerts_done:
  email_sender_free(pSender);

  db_end_transaction(0);
}

/*
** Check to see if any email notifications need to occur, and then
** do them.
**
** 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;
  db_begin_transaction();
  if( !email_tables_exist() ) goto autoexec_done;
  if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done;
  if( !db_exists("SELECT 1 FROM pending_alert") ) goto autoexec_done;
  email_send_alerts(0);
  iJulianDay = db_int(0, "SELECT julianday('now')");

  if( iJulianDay>db_get_int("email-last-digest",0) ){





    email_send_alerts(SENDALERT_DIGEST);
    db_set_int("email-last-digest", iJulianDay, 0);
  }

autoexec_done:
  db_end_transaction(0);
}

/*







>



















>

>
>
>
>
>

<







1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790

1791
1792
1793
1794
1795
1796
1797
    }else{
      db_multi_exec("UPDATE pending_alert SET sentSep=true");
    }
    db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep");
  }
send_alerts_done:
  email_sender_free(pSender);
  if( g.fSqlTrace ) fossil_trace("-- END email_send_alerts(%u)\n", flags);
  db_end_transaction(0);
}

/*
** Check to see if any email notifications need to occur, and then
** do them.
**
** 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;
  db_begin_transaction();
  if( !email_tables_exist() ) goto autoexec_done;
  if( !db_get_boolean("email-autoexec",0) ) goto autoexec_done;
  if( !db_exists("SELECT 1 FROM pending_alert") ) goto autoexec_done;
  email_send_alerts(0);
  iJulianDay = db_int(0, "SELECT julianday('now')");
  if( g.fSqlTrace ) fossil_trace("-- iJulianDay: %d\n", iJulianDay);
  if( iJulianDay>db_get_int("email-last-digest",0) ){
    db_multi_exec(
      "REPLACE INTO repository.config(name,value,mtime)"
      " VALUES('email-last-digest',%d,now())",
      iJulianDay
    );
    email_send_alerts(SENDALERT_DIGEST);

  }

autoexec_done:
  db_end_transaction(0);
}

/*