Overview
SHA1 Hash: | 95f5520a09efb7698179f5123fbca8e3f33fbb39 |
---|---|
Date: | 2009-09-14 14:08:35 |
User: | drh |
Comment: | Construct event records for tickets correctly even when the ticket change artifacts arrive out of order. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/manifest.c from [9476d92cd1] to [3ac47cd0a7].
@@ -883,10 +883,109 @@ } manifest_clear(&other); } /* +** True if manifest_crosslink_begin() has been called but +** manifest_crosslink_end() is still pending. +*/ +static int manifest_crosslink_busy = 0; + +/* +** Setup to do multiple manifest_crosslink() calls. +** This is only required if processing ticket changes. +*/ +void manifest_crosslink_begin(void){ + assert( manifest_crosslink_busy==0 ); + manifest_crosslink_busy = 1; + db_begin_transaction(); + db_multi_exec("CREATE TEMP TABLE pending_tkt(uuid TEXT UNIQUE)"); +} + +/* +** Finish up a sequence of manifest_crosslink calls. +*/ +void manifest_crosslink_end(void){ + Stmt q; + assert( manifest_crosslink_busy==1 ); + db_prepare(&q, "SELECT uuid FROM pending_tkt"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zUuid = db_column_text(&q, 0); + ticket_rebuild_entry(zUuid); + } + db_finalize(&q); + db_end_transaction(0); + manifest_crosslink_busy = 0; +} + +/* +** Make an entry in the event table for a ticket change artifact. +*/ +void manifest_ticket_event( + int rid, /* Artifact ID of the change ticket artifact */ + const Manifest *pManifest, /* Parsed content of the artifact */ + int isNew /* True if this is the first event */ +){ + int i; + char *zTitle; + Blob comment; + char *zNewStatus = 0; + static char *zTitleExpr = 0; + static char *zStatusColumn = 0; + static int once = 1; + + blob_zero(&comment); + if( once ){ + once = 0; + zTitleExpr = db_get("ticket-title-expr", "title"); + zStatusColumn = db_get("ticket-status-column", "status"); + } + zTitle = db_text("unknown", + "SELECT %s FROM ticket WHERE tkt_uuid='%s'", + zTitleExpr, pManifest->zTicketUuid + ); + if( !isNew ){ + for(i=0; i<pManifest->nField; i++){ + if( strcmp(pManifest->aField[i].zName, zStatusColumn)==0 ){ + zNewStatus = pManifest->aField[i].zValue; + } + } + if( zNewStatus ){ + blob_appendf(&comment, "%h ticket [%.10s]: <i>%h</i>", + zNewStatus, pManifest->zTicketUuid, zTitle + ); + if( pManifest->nField>1 ){ + blob_appendf(&comment, " plus %d other change%s", + pManifest->nField-1, pManifest->nField==2 ? "" : "s"); + } + }else{ + zNewStatus = db_text("unknown", + "SELECT %s FROM ticket WHERE tkt_uuid='%s'", + zStatusColumn, pManifest->zTicketUuid + ); + blob_appendf(&comment, "Ticket [%.10s] <i>%h</i> status still %h with " + "%d other change%s", + pManifest->zTicketUuid, zTitle, zNewStatus, pManifest->nField, + pManifest->nField==1 ? "" : "s" + ); + free(zNewStatus); + } + }else{ + blob_appendf(&comment, "New ticket [%.10s] <i>%h</i>.", + pManifest->zTicketUuid, zTitle + ); + } + free(zTitle); + db_multi_exec( + "REPLACE INTO event(type,mtime,objid,user,comment)" + "VALUES('t',%.17g,%d,%Q,%Q)", + pManifest->rDate, rid, pManifest->zUser, blob_str(&comment) + ); + blob_reset(&comment); +} + +/* ** Scan artifact rid/pContent to see if it is a control artifact of ** any key: ** ** * Manifest ** * Control @@ -1024,72 +1123,18 @@ TAG_COMMENT, rid ); free(zComment); } if( m.type==CFTYPE_TICKET ){ - int i; - char *zTitle; char *zTag; - Blob comment; - char *zNewStatus = 0; - static char *zTitleExpr = 0; - static char *zStatusColumn = 0; - static int once = 1; - int isNew; - isNew = ticket_insert(&m, 1, 1); + assert( manifest_crosslink_busy==1 ); zTag = mprintf("tkt-%s", m.zTicketUuid); tag_insert(zTag, 1, 0, rid, m.rDate, rid); free(zTag); - blob_zero(&comment); - if( once ){ - once = 0; - zTitleExpr = db_get("ticket-title-expr", "title"); - zStatusColumn = db_get("ticket-status-column", "status"); - } - zTitle = db_text("unknown", - "SELECT %s FROM ticket WHERE tkt_uuid='%s'", - zTitleExpr, m.zTicketUuid - ); - if( !isNew ){ - for(i=0; i<m.nField; i++){ - if( strcmp(m.aField[i].zName, zStatusColumn)==0 ){ - zNewStatus = m.aField[i].zValue; - } - } - if( zNewStatus ){ - blob_appendf(&comment, "%h ticket [%.10s]: <i>%h</i>", - zNewStatus, m.zTicketUuid, zTitle - ); - if( m.nField>1 ){ - blob_appendf(&comment, " plus %d other change%s", - m.nField-1, m.nField==2 ? "" : "s"); - } - }else{ - zNewStatus = db_text("unknown", - "SELECT %s FROM ticket WHERE tkt_uuid='%s'", - zStatusColumn, m.zTicketUuid - ); - blob_appendf(&comment, "Ticket [%.10s] <i>%h</i> status still %h with " - "%d other change%s", - m.zTicketUuid, zTitle, zNewStatus, m.nField, - m.nField==1 ? "" : "s" - ); - free(zNewStatus); - } - }else{ - blob_appendf(&comment, "New ticket [%.10s] <i>%h</i>.", - m.zTicketUuid, zTitle - ); - } - free(zTitle); - db_multi_exec( - "REPLACE INTO event(type,mtime,objid,user,comment)" - "VALUES('t',%.17g,%d,%Q,%Q)", - m.rDate, rid, m.zUser, blob_str(&comment) - ); - blob_reset(&comment); + db_multi_exec("INSERT OR IGNORE INTO pending_tkt VALUES(%Q)", + m.zTicketUuid); } db_end_transaction(0); manifest_clear(&m); return 1; }
Modified src/rebuild.c from [fd43a695c4] to [cd57d5ccbc].
@@ -241,10 +241,11 @@ db_prepare(&s, "SELECT rid, size FROM blob" " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)" " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)" ); + manifest_crosslink_begin(); while( db_step(&s)==SQLITE_ROW ){ int rid = db_column_int(&s, 0); int size = db_column_int(&s, 1); if( size>=0 ){ Blob content; @@ -270,10 +271,11 @@ db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid); rebuild_step_done(rid); } } db_finalize(&s); + manifest_crosslink_end(); rebuild_tag_trunk(); if( ttyOutput ){ printf("\n"); } return errCnt;
Modified src/tag.c from [11a50e87e6] to [bc765b3a20].
@@ -142,11 +142,11 @@ } /* ** Insert a tag into the database. */ -void tag_insert( +int tag_insert( const char *zTag, /* Name of the tag (w/o the "+" or "-" prefix */ int tagtype, /* 0:cancel 1:singleton 2:propagated */ const char *zValue, /* Value if the tag is really a property */ int srcId, /* Artifact that contains this tag */ double mtime, /* Timestamp. Use default if <=0.0 */ @@ -170,11 +170,11 @@ db_bind_double(&s, ":mtime", mtime); rc = db_step(&s); db_finalize(&s); if( rc==SQLITE_ROW ){ /* Another entry that is more recent already exists. Do nothing */ - return; + return tagid; } db_prepare(&s, "REPLACE INTO tagxref(tagid,tagtype,srcId,origid,value,mtime,rid)" " VALUES(%d,%d,%d,%d,%Q,:mtime,%d)", tagid, tagtype, srcId, rid, zValue, rid @@ -208,10 +208,11 @@ zValue, rid); } if( tagtype==0 || tagtype==2 ){ tag_propagate(rid, tagid, tagtype, rid, zValue, mtime); } + return tagid; } /* ** COMMAND: test-tag
Modified src/tkt.c from [53e4b94cc8] to [bc233f791c].
@@ -197,11 +197,11 @@ ** work of trying to create it. ** ** Return TRUE if a new TICKET entry was created and FALSE if an ** existing entry was revised. */ -int ticket_insert(Manifest *p, int createFlag, int checkTime){ +int ticket_insert(const Manifest *p, int createFlag, int checkTime){ Blob sql; Stmt q; int i; const char *zSep; int rc = 0; @@ -264,10 +264,11 @@ while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); content_get(rid, &content); manifest_parse(&manifest, &content); ticket_insert(&manifest, createFlag, 0); + manifest_ticket_event(rid, &manifest, createFlag); manifest_clear(&manifest); createFlag = 0; } db_finalize(&q); } @@ -456,11 +457,13 @@ }else{ rid = content_put(&tktchng, 0, 0); if( rid==0 ){ fossil_panic("trouble committing ticket: %s", g.zErrMsg); } + manifest_crosslink_begin(); manifest_crosslink(rid, &tktchng); + manifest_crosslink_end(); } return TH_RETURN; } @@ -690,11 +693,12 @@ char zUuid[12]; memcpy(zUuid, zChngUuid, 10); zUuid[10] = 0; @ @ Ticket change - @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zUuid)</a>]</a> by + @ [<a href="%s(g.zTop)/artifact/%T(zChngUuid)">%s(zUuid)</a>]</a> + @ (rid %d(rid)) by hyperlink_to_user(m.zUser,zDate," on"); hyperlink_to_date(zDate, ":"); free(zDate); ticket_output_change_artifact(&m); }
Modified src/xfer.c from [5dff3de1ae] to [5bb8ce2dae].
@@ -580,10 +580,11 @@ db_begin_transaction(); db_multi_exec( "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" ); + manifest_crosslink_begin(); while( blob_line(xfer.pIn, &xfer.line) ){ if( blob_buffer(&xfer.line)[0]=='#' ) continue; xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); /* file UUID SIZE \n CONTENT @@ -831,10 +832,11 @@ send_unclustered(&xfer); } if( recvConfig ){ configure_finalize_receive(); } + manifest_crosslink_end(); db_end_transaction(0); } /* ** COMMAND: test-xfer @@ -946,10 +948,11 @@ } if( pushFlag ){ blob_appendf(&send, "push %s %s\n", zSCode, zPCode); nCard++; } + manifest_crosslink_begin(); printf(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); while( go ){ int newPhantom = 0; char *zRandomness; @@ -1228,7 +1231,8 @@ printf("Total network traffic: %d bytes sent, %d bytes received\n", nSent, nRcvd); transport_close(); socket_global_shutdown(); db_multi_exec("DROP TABLE onremote"); + manifest_crosslink_end(); db_end_transaction(0); }