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 | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:f3de8b663256229dc5f02bec62160160d521a5622ee063869aeb08c46cf0ab21
User & Date: drh 2018-06-24 16:38:11
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
Hide Diffs Unified Diffs 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
....
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
....
1755
1756
1757
1758
1759
1760
1761

1762
1763
1764
1765
1766
1767
1768
....
1774
1775
1776
1777
1778
1779
1780

1781





1782
1783
1784
1785
1786
1787
1788
1789
1790
  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);
................................................................................
  }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 */
................................................................................
    }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.
**
................................................................................
  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);
}

/*







>







 







|







 







>







 







>

>
>
>
>
>

<







1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
....
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
....
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
....
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790

1791
1792
1793
1794
1795
1796
1797
  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);
................................................................................
  }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 */
................................................................................
    }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.
**
................................................................................
  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);
}

/*