Fossil SCM
Replace firt with pIrt
Commit
ed56faad2a10ef19591a26f4463f131f67109f33cc332f8711144b4392e5659b
Parent
b932e49c7ffef84…
1 file changed
+32
-39
+32
-39
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -26,21 +26,21 @@ | ||
| 26 | 26 | */ |
| 27 | 27 | #define DEFAULT_FORUM_MIMETYPE "text/x-markdown" |
| 28 | 28 | |
| 29 | 29 | #if INTERFACE |
| 30 | 30 | /* |
| 31 | -** Each instance of the following object represents a single message - | |
| 31 | +** Each instance of the following object represents a single message - | |
| 32 | 32 | ** either the initial post, an edit to a post, a reply, or an edit to |
| 33 | 33 | ** a reply. |
| 34 | 34 | */ |
| 35 | 35 | struct ForumEntry { |
| 36 | 36 | int fpid; /* rid for this entry */ |
| 37 | 37 | int fprev; /* zero if initial entry. non-zero if an edit */ |
| 38 | - int firt; /* This entry replies to firt */ | |
| 39 | 38 | int mfirt; /* Root in-reply-to */ |
| 40 | 39 | int sid; /* Serial ID number */ |
| 41 | 40 | char *zUuid; /* Artifact hash */ |
| 41 | + ForumEntry *pIrt; /* This entry replies to pIrt */ | |
| 42 | 42 | ForumEntry *pEditHead; /* Original, unedited entry */ |
| 43 | 43 | ForumEntry *pEditTail; /* Most recent edit for this entry */ |
| 44 | 44 | ForumEntry *pEditNext; /* This entry is edited by pEditNext */ |
| 45 | 45 | ForumEntry *pEditPrev; /* This entry is an edit of pEditPrev */ |
| 46 | 46 | ForumEntry *pNext; /* Next in chronological order */ |
| @@ -154,13 +154,14 @@ | ||
| 154 | 154 | ** Construct a ForumThread object given the root record id. |
| 155 | 155 | */ |
| 156 | 156 | static ForumThread *forumthread_create(int froot, int computeHierarchy){ |
| 157 | 157 | ForumThread *pThread; |
| 158 | 158 | ForumEntry *pEntry; |
| 159 | + ForumEntry *p; | |
| 159 | 160 | Stmt q; |
| 160 | 161 | int sid = 1; |
| 161 | - Bag seen = Bag_INIT; | |
| 162 | + int firt; | |
| 162 | 163 | pThread = fossil_malloc( sizeof(*pThread) ); |
| 163 | 164 | memset(pThread, 0, sizeof(*pThread)); |
| 164 | 165 | db_prepare(&q, |
| 165 | 166 | "SELECT fpid, firt, fprev, (SELECT uuid FROM blob WHERE rid=fpid)" |
| 166 | 167 | " FROM forumpost" |
| @@ -169,39 +170,42 @@ | ||
| 169 | 170 | ); |
| 170 | 171 | while( db_step(&q)==SQLITE_ROW ){ |
| 171 | 172 | pEntry = fossil_malloc( sizeof(*pEntry) ); |
| 172 | 173 | memset(pEntry, 0, sizeof(*pEntry)); |
| 173 | 174 | pEntry->fpid = db_column_int(&q, 0); |
| 174 | - pEntry->firt = db_column_int(&q, 1); | |
| 175 | + firt = db_column_int(&q, 1); | |
| 175 | 176 | pEntry->fprev = db_column_int(&q, 2); |
| 176 | 177 | pEntry->zUuid = fossil_strdup(db_column_text(&q,3)); |
| 177 | - pEntry->mfirt = pEntry->firt; | |
| 178 | + pEntry->mfirt = firt; | |
| 178 | 179 | pEntry->sid = sid++; |
| 179 | 180 | pEntry->pPrev = pThread->pLast; |
| 180 | 181 | pEntry->pNext = 0; |
| 181 | - bag_insert(&seen, pEntry->fpid); | |
| 182 | 182 | if( pThread->pLast==0 ){ |
| 183 | 183 | pThread->pFirst = pEntry; |
| 184 | 184 | }else{ |
| 185 | 185 | pThread->pLast->pNext = pEntry; |
| 186 | 186 | } |
| 187 | - if( pEntry->firt && !bag_find(&seen,pEntry->firt) ){ | |
| 188 | - pEntry->firt = froot; | |
| 189 | - pEntry->mfirt = froot; | |
| 187 | + if( firt ){ | |
| 188 | + pEntry->pIrt = pThread->pFirst; | |
| 189 | + for(p=pThread->pFirst; p; p=p->pNext){ | |
| 190 | + if( p->fpid==firt ){ | |
| 191 | + pEntry->pIrt = p; | |
| 192 | + break; | |
| 193 | + } | |
| 194 | + } | |
| 190 | 195 | } |
| 191 | 196 | pThread->pLast = pEntry; |
| 192 | 197 | } |
| 193 | 198 | db_finalize(&q); |
| 194 | - bag_clear(&seen); | |
| 195 | 199 | |
| 196 | 200 | /* Establish which entries are the latest edit. After this loop |
| 197 | 201 | ** completes, entries that have non-NULL pEditTail should not be |
| 198 | 202 | ** displayed. |
| 199 | 203 | */ |
| 200 | 204 | for(pEntry=pThread->pFirst; pEntry; pEntry=pEntry->pNext){ |
| 201 | 205 | if( pEntry->fprev ){ |
| 202 | - ForumEntry *pBase = 0, *p; | |
| 206 | + ForumEntry *pBase = 0; | |
| 203 | 207 | p = forumentry_backward(pEntry->pPrev, pEntry->fprev); |
| 204 | 208 | p->pEditNext = pEntry; |
| 205 | 209 | pEntry->pEditPrev = p; |
| 206 | 210 | pEntry->pEditHead = p->pEditHead ? p->pEditHead : p; |
| 207 | 211 | while( p ){ |
| @@ -295,14 +299,14 @@ | ||
| 295 | 299 | pThread = forumthread_create(froot, 1); |
| 296 | 300 | fossil_print("Chronological:\n"); |
| 297 | 301 | fossil_print( |
| 298 | 302 | /* 0 1 2 3 4 5 6 7 */ |
| 299 | 303 | /* 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123 */ |
| 300 | - " sid fpid firt fprev mfirt pEditTail hash\n"); | |
| 304 | + " sid fpid pIrt fprev mfirt pEditTail hash\n"); | |
| 301 | 305 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 302 | 306 | fossil_print("%4d %9d %9d %9d %9d %9d %8.8s\n", p->sid, |
| 303 | - p->fpid, p->firt, p->fprev, p->mfirt, | |
| 307 | + p->fpid, p->pIrt ? p->pIrt->fpid : 0, p->fprev, p->mfirt, | |
| 304 | 308 | p->pEditTail ? p->pEditTail->fpid : 0, p->zUuid); |
| 305 | 309 | } |
| 306 | 310 | fossil_print("\nDisplay\n"); |
| 307 | 311 | for(p=pThread->pDisplay; p; p=p->pDisplay){ |
| 308 | 312 | fossil_print("%*s", (p->nIndent-1)*3, ""); |
| @@ -447,17 +451,13 @@ | ||
| 447 | 451 | } |
| 448 | 452 | if( g.perm.Debug ){ |
| 449 | 453 | @ <span class="debug">\ |
| 450 | 454 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 451 | 455 | } |
| 452 | - if( p->firt ){ | |
| 453 | - ForumEntry *pIrt = p->pPrev; | |
| 454 | - while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; | |
| 455 | - if( pIrt ){ | |
| 456 | - @ in reply to %z(href("%R/forumpost/%S?t=%c",pIrt->zUuid,cMode))\ | |
| 457 | - @ %d(pIrt->sid)</a> | |
| 458 | - } | |
| 456 | + if( p->pIrt ){ | |
| 457 | + @ in reply to %z(href("%R/forumpost/%S?t=%c",p->pIrt->zUuid,cMode))\ | |
| 458 | + @ %d(p->pIrt->sid)</a> | |
| 459 | 459 | } |
| 460 | 460 | zUuid = p->zUuid; |
| 461 | 461 | if( p->pEditTail ){ |
| 462 | 462 | @ updated by %z(href("%R/forumpost/%S?t=%c",p->pEditTail->zUuid,cMode))\ |
| 463 | 463 | @ %d(p->pEditTail->sid)</a> |
| @@ -519,15 +519,16 @@ | ||
| 519 | 519 | ** to be displayed for debugging purposes. |
| 520 | 520 | */ |
| 521 | 521 | if( PB("threadtable") ){ |
| 522 | 522 | @ <hr> |
| 523 | 523 | @ <table border="1" cellpadding="3" cellspacing="0"> |
| 524 | - @ <tr><th>sid<th>fpid<th>firt<th>fprev<th>mfirt<th>pEditHead<th>pEditTail\ | |
| 524 | + @ <tr><th>sid<th>fpid<th>pIrt<th>fprev<th>mfirt<th>pEditHead<th>pEditTail\ | |
| 525 | 525 | @ <th>pEditNext<th>pEditPrev<th>hash |
| 526 | 526 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 527 | - @ <tr><td>%d(p->sid)<td>%d(p->fpid)<td>%d(p->firt)\ | |
| 528 | - @ <td>%d(p->fprev)<td>%d(p->mfirt)\ | |
| 527 | + @ <tr><td>%d(p->sid)<td>%d(p->fpid)\ | |
| 528 | + @ <td>%d(p->pIrt?p->pIrt->fpid:0)\ | |
| 529 | + @ <td>%d(p->fprev)\ | |
| 529 | 530 | @ <td>%d(p->pEditHead?p->pEditHead->fpid:0)\ |
| 530 | 531 | @ <td>%d(p->pEditTail?p->pEditTail->fpid:0)\ |
| 531 | 532 | @ <td>%d(p->pEditNext?p->pEditNext->fpid:0)\ |
| 532 | 533 | @ <td>%d(p->pEditPrev?p->pEditPrev->fpid:0)\ |
| 533 | 534 | @ <td>%S(p->zUuid)</tr> |
| @@ -573,17 +574,13 @@ | ||
| 573 | 574 | fossil_free(zDate); |
| 574 | 575 | if( g.perm.Debug ){ |
| 575 | 576 | @ <span class="debug">\ |
| 576 | 577 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 577 | 578 | } |
| 578 | - if( p->firt && cnt==1 ){ | |
| 579 | - ForumEntry *pIrt = p->pPrev; | |
| 580 | - while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; | |
| 581 | - if( pIrt ){ | |
| 582 | - @ in reply to %z(href("%R/forumpost/%S?t=%c",pIrt->zUuid,cMode))\ | |
| 583 | - @ %d(pIrt->sid)</a> | |
| 584 | - } | |
| 579 | + if( p->pIrt && cnt==1 ){ | |
| 580 | + @ in reply to %z(href("%R/forumpost/%S?t=%c",p->pIrt->zUuid,cMode))\ | |
| 581 | + @ %d(p->pIrt->sid)</a> | |
| 585 | 582 | } |
| 586 | 583 | zUuid = p->zUuid; |
| 587 | 584 | @ %z(href("%R/forumpost/%S?t=c",zUuid))[link]</a> |
| 588 | 585 | if( !bRawMode ){ |
| 589 | 586 | @ %z(href("%R/forumpost/%S?raw",zUuid))[source]</a> |
| @@ -707,17 +704,13 @@ | ||
| 707 | 704 | } |
| 708 | 705 | if( fpid!=target ){ |
| 709 | 706 | @ %z(href("%R/forumpost/%S",zUuid))[link]</a> |
| 710 | 707 | } |
| 711 | 708 | @ %z(href("%R/forumpost/%S?raw",zUuid))[source]</a> |
| 712 | - if( p->firt ){ | |
| 713 | - ForumEntry *pIrt = p->pPrev; | |
| 714 | - while( pIrt && pIrt->fpid!=p->mfirt ) pIrt = pIrt->pPrev; | |
| 715 | - if( pIrt ){ | |
| 716 | - @ in reply to %z(href("%R/forumpost/%S?t=h",pIrt->zUuid))\ | |
| 717 | - @ %d(pIrt->sid)</a> | |
| 718 | - } | |
| 709 | + if( p->pIrt ){ | |
| 710 | + @ in reply to %z(href("%R/forumpost/%S?t=h",p->pIrt->zUuid))\ | |
| 711 | + @ %d(p->pIrt->sid)</a> | |
| 719 | 712 | } |
| 720 | 713 | @ </h3> |
| 721 | 714 | isPrivate = content_is_private(fpid); |
| 722 | 715 | sameUser = notAnon && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 723 | 716 | if( isPrivate && !g.perm.ModForum && !sameUser ){ |
| @@ -955,11 +948,11 @@ | ||
| 955 | 948 | webpage_assert( (zTitle==0)+(iInReplyTo==0)==1 ); |
| 956 | 949 | blob_init(&x, 0, 0); |
| 957 | 950 | zDate = date_in_standard_format("now"); |
| 958 | 951 | blob_appendf(&x, "D %s\n", zDate); |
| 959 | 952 | fossil_free(zDate); |
| 960 | - zG = db_text(0, | |
| 953 | + zG = db_text(0, | |
| 961 | 954 | "SELECT uuid FROM blob, forumpost" |
| 962 | 955 | " WHERE blob.rid==forumpost.froot" |
| 963 | 956 | " AND forumpost.fpid=%d", iBasis); |
| 964 | 957 | if( zG ){ |
| 965 | 958 | blob_appendf(&x, "G %s\n", zG); |
| @@ -1209,11 +1202,11 @@ | ||
| 1209 | 1202 | } |
| 1210 | 1203 | cgi_redirectf("%R/forumpost/%S",P("fpid")); |
| 1211 | 1204 | return; |
| 1212 | 1205 | } |
| 1213 | 1206 | if( P("reject") ){ |
| 1214 | - char *zParent = | |
| 1207 | + char *zParent = | |
| 1215 | 1208 | db_text(0, |
| 1216 | 1209 | "SELECT uuid FROM forumpost, blob" |
| 1217 | 1210 | " WHERE forumpost.fpid=%d AND blob.rid=forumpost.firt", |
| 1218 | 1211 | fpid |
| 1219 | 1212 | ); |
| 1220 | 1213 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -26,21 +26,21 @@ | |
| 26 | */ |
| 27 | #define DEFAULT_FORUM_MIMETYPE "text/x-markdown" |
| 28 | |
| 29 | #if INTERFACE |
| 30 | /* |
| 31 | ** Each instance of the following object represents a single message - |
| 32 | ** either the initial post, an edit to a post, a reply, or an edit to |
| 33 | ** a reply. |
| 34 | */ |
| 35 | struct ForumEntry { |
| 36 | int fpid; /* rid for this entry */ |
| 37 | int fprev; /* zero if initial entry. non-zero if an edit */ |
| 38 | int firt; /* This entry replies to firt */ |
| 39 | int mfirt; /* Root in-reply-to */ |
| 40 | int sid; /* Serial ID number */ |
| 41 | char *zUuid; /* Artifact hash */ |
| 42 | ForumEntry *pEditHead; /* Original, unedited entry */ |
| 43 | ForumEntry *pEditTail; /* Most recent edit for this entry */ |
| 44 | ForumEntry *pEditNext; /* This entry is edited by pEditNext */ |
| 45 | ForumEntry *pEditPrev; /* This entry is an edit of pEditPrev */ |
| 46 | ForumEntry *pNext; /* Next in chronological order */ |
| @@ -154,13 +154,14 @@ | |
| 154 | ** Construct a ForumThread object given the root record id. |
| 155 | */ |
| 156 | static ForumThread *forumthread_create(int froot, int computeHierarchy){ |
| 157 | ForumThread *pThread; |
| 158 | ForumEntry *pEntry; |
| 159 | Stmt q; |
| 160 | int sid = 1; |
| 161 | Bag seen = Bag_INIT; |
| 162 | pThread = fossil_malloc( sizeof(*pThread) ); |
| 163 | memset(pThread, 0, sizeof(*pThread)); |
| 164 | db_prepare(&q, |
| 165 | "SELECT fpid, firt, fprev, (SELECT uuid FROM blob WHERE rid=fpid)" |
| 166 | " FROM forumpost" |
| @@ -169,39 +170,42 @@ | |
| 169 | ); |
| 170 | while( db_step(&q)==SQLITE_ROW ){ |
| 171 | pEntry = fossil_malloc( sizeof(*pEntry) ); |
| 172 | memset(pEntry, 0, sizeof(*pEntry)); |
| 173 | pEntry->fpid = db_column_int(&q, 0); |
| 174 | pEntry->firt = db_column_int(&q, 1); |
| 175 | pEntry->fprev = db_column_int(&q, 2); |
| 176 | pEntry->zUuid = fossil_strdup(db_column_text(&q,3)); |
| 177 | pEntry->mfirt = pEntry->firt; |
| 178 | pEntry->sid = sid++; |
| 179 | pEntry->pPrev = pThread->pLast; |
| 180 | pEntry->pNext = 0; |
| 181 | bag_insert(&seen, pEntry->fpid); |
| 182 | if( pThread->pLast==0 ){ |
| 183 | pThread->pFirst = pEntry; |
| 184 | }else{ |
| 185 | pThread->pLast->pNext = pEntry; |
| 186 | } |
| 187 | if( pEntry->firt && !bag_find(&seen,pEntry->firt) ){ |
| 188 | pEntry->firt = froot; |
| 189 | pEntry->mfirt = froot; |
| 190 | } |
| 191 | pThread->pLast = pEntry; |
| 192 | } |
| 193 | db_finalize(&q); |
| 194 | bag_clear(&seen); |
| 195 | |
| 196 | /* Establish which entries are the latest edit. After this loop |
| 197 | ** completes, entries that have non-NULL pEditTail should not be |
| 198 | ** displayed. |
| 199 | */ |
| 200 | for(pEntry=pThread->pFirst; pEntry; pEntry=pEntry->pNext){ |
| 201 | if( pEntry->fprev ){ |
| 202 | ForumEntry *pBase = 0, *p; |
| 203 | p = forumentry_backward(pEntry->pPrev, pEntry->fprev); |
| 204 | p->pEditNext = pEntry; |
| 205 | pEntry->pEditPrev = p; |
| 206 | pEntry->pEditHead = p->pEditHead ? p->pEditHead : p; |
| 207 | while( p ){ |
| @@ -295,14 +299,14 @@ | |
| 295 | pThread = forumthread_create(froot, 1); |
| 296 | fossil_print("Chronological:\n"); |
| 297 | fossil_print( |
| 298 | /* 0 1 2 3 4 5 6 7 */ |
| 299 | /* 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123 */ |
| 300 | " sid fpid firt fprev mfirt pEditTail hash\n"); |
| 301 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 302 | fossil_print("%4d %9d %9d %9d %9d %9d %8.8s\n", p->sid, |
| 303 | p->fpid, p->firt, p->fprev, p->mfirt, |
| 304 | p->pEditTail ? p->pEditTail->fpid : 0, p->zUuid); |
| 305 | } |
| 306 | fossil_print("\nDisplay\n"); |
| 307 | for(p=pThread->pDisplay; p; p=p->pDisplay){ |
| 308 | fossil_print("%*s", (p->nIndent-1)*3, ""); |
| @@ -447,17 +451,13 @@ | |
| 447 | } |
| 448 | if( g.perm.Debug ){ |
| 449 | @ <span class="debug">\ |
| 450 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 451 | } |
| 452 | if( p->firt ){ |
| 453 | ForumEntry *pIrt = p->pPrev; |
| 454 | while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; |
| 455 | if( pIrt ){ |
| 456 | @ in reply to %z(href("%R/forumpost/%S?t=%c",pIrt->zUuid,cMode))\ |
| 457 | @ %d(pIrt->sid)</a> |
| 458 | } |
| 459 | } |
| 460 | zUuid = p->zUuid; |
| 461 | if( p->pEditTail ){ |
| 462 | @ updated by %z(href("%R/forumpost/%S?t=%c",p->pEditTail->zUuid,cMode))\ |
| 463 | @ %d(p->pEditTail->sid)</a> |
| @@ -519,15 +519,16 @@ | |
| 519 | ** to be displayed for debugging purposes. |
| 520 | */ |
| 521 | if( PB("threadtable") ){ |
| 522 | @ <hr> |
| 523 | @ <table border="1" cellpadding="3" cellspacing="0"> |
| 524 | @ <tr><th>sid<th>fpid<th>firt<th>fprev<th>mfirt<th>pEditHead<th>pEditTail\ |
| 525 | @ <th>pEditNext<th>pEditPrev<th>hash |
| 526 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 527 | @ <tr><td>%d(p->sid)<td>%d(p->fpid)<td>%d(p->firt)\ |
| 528 | @ <td>%d(p->fprev)<td>%d(p->mfirt)\ |
| 529 | @ <td>%d(p->pEditHead?p->pEditHead->fpid:0)\ |
| 530 | @ <td>%d(p->pEditTail?p->pEditTail->fpid:0)\ |
| 531 | @ <td>%d(p->pEditNext?p->pEditNext->fpid:0)\ |
| 532 | @ <td>%d(p->pEditPrev?p->pEditPrev->fpid:0)\ |
| 533 | @ <td>%S(p->zUuid)</tr> |
| @@ -573,17 +574,13 @@ | |
| 573 | fossil_free(zDate); |
| 574 | if( g.perm.Debug ){ |
| 575 | @ <span class="debug">\ |
| 576 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 577 | } |
| 578 | if( p->firt && cnt==1 ){ |
| 579 | ForumEntry *pIrt = p->pPrev; |
| 580 | while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; |
| 581 | if( pIrt ){ |
| 582 | @ in reply to %z(href("%R/forumpost/%S?t=%c",pIrt->zUuid,cMode))\ |
| 583 | @ %d(pIrt->sid)</a> |
| 584 | } |
| 585 | } |
| 586 | zUuid = p->zUuid; |
| 587 | @ %z(href("%R/forumpost/%S?t=c",zUuid))[link]</a> |
| 588 | if( !bRawMode ){ |
| 589 | @ %z(href("%R/forumpost/%S?raw",zUuid))[source]</a> |
| @@ -707,17 +704,13 @@ | |
| 707 | } |
| 708 | if( fpid!=target ){ |
| 709 | @ %z(href("%R/forumpost/%S",zUuid))[link]</a> |
| 710 | } |
| 711 | @ %z(href("%R/forumpost/%S?raw",zUuid))[source]</a> |
| 712 | if( p->firt ){ |
| 713 | ForumEntry *pIrt = p->pPrev; |
| 714 | while( pIrt && pIrt->fpid!=p->mfirt ) pIrt = pIrt->pPrev; |
| 715 | if( pIrt ){ |
| 716 | @ in reply to %z(href("%R/forumpost/%S?t=h",pIrt->zUuid))\ |
| 717 | @ %d(pIrt->sid)</a> |
| 718 | } |
| 719 | } |
| 720 | @ </h3> |
| 721 | isPrivate = content_is_private(fpid); |
| 722 | sameUser = notAnon && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 723 | if( isPrivate && !g.perm.ModForum && !sameUser ){ |
| @@ -955,11 +948,11 @@ | |
| 955 | webpage_assert( (zTitle==0)+(iInReplyTo==0)==1 ); |
| 956 | blob_init(&x, 0, 0); |
| 957 | zDate = date_in_standard_format("now"); |
| 958 | blob_appendf(&x, "D %s\n", zDate); |
| 959 | fossil_free(zDate); |
| 960 | zG = db_text(0, |
| 961 | "SELECT uuid FROM blob, forumpost" |
| 962 | " WHERE blob.rid==forumpost.froot" |
| 963 | " AND forumpost.fpid=%d", iBasis); |
| 964 | if( zG ){ |
| 965 | blob_appendf(&x, "G %s\n", zG); |
| @@ -1209,11 +1202,11 @@ | |
| 1209 | } |
| 1210 | cgi_redirectf("%R/forumpost/%S",P("fpid")); |
| 1211 | return; |
| 1212 | } |
| 1213 | if( P("reject") ){ |
| 1214 | char *zParent = |
| 1215 | db_text(0, |
| 1216 | "SELECT uuid FROM forumpost, blob" |
| 1217 | " WHERE forumpost.fpid=%d AND blob.rid=forumpost.firt", |
| 1218 | fpid |
| 1219 | ); |
| 1220 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -26,21 +26,21 @@ | |
| 26 | */ |
| 27 | #define DEFAULT_FORUM_MIMETYPE "text/x-markdown" |
| 28 | |
| 29 | #if INTERFACE |
| 30 | /* |
| 31 | ** Each instance of the following object represents a single message - |
| 32 | ** either the initial post, an edit to a post, a reply, or an edit to |
| 33 | ** a reply. |
| 34 | */ |
| 35 | struct ForumEntry { |
| 36 | int fpid; /* rid for this entry */ |
| 37 | int fprev; /* zero if initial entry. non-zero if an edit */ |
| 38 | int mfirt; /* Root in-reply-to */ |
| 39 | int sid; /* Serial ID number */ |
| 40 | char *zUuid; /* Artifact hash */ |
| 41 | ForumEntry *pIrt; /* This entry replies to pIrt */ |
| 42 | ForumEntry *pEditHead; /* Original, unedited entry */ |
| 43 | ForumEntry *pEditTail; /* Most recent edit for this entry */ |
| 44 | ForumEntry *pEditNext; /* This entry is edited by pEditNext */ |
| 45 | ForumEntry *pEditPrev; /* This entry is an edit of pEditPrev */ |
| 46 | ForumEntry *pNext; /* Next in chronological order */ |
| @@ -154,13 +154,14 @@ | |
| 154 | ** Construct a ForumThread object given the root record id. |
| 155 | */ |
| 156 | static ForumThread *forumthread_create(int froot, int computeHierarchy){ |
| 157 | ForumThread *pThread; |
| 158 | ForumEntry *pEntry; |
| 159 | ForumEntry *p; |
| 160 | Stmt q; |
| 161 | int sid = 1; |
| 162 | int firt; |
| 163 | pThread = fossil_malloc( sizeof(*pThread) ); |
| 164 | memset(pThread, 0, sizeof(*pThread)); |
| 165 | db_prepare(&q, |
| 166 | "SELECT fpid, firt, fprev, (SELECT uuid FROM blob WHERE rid=fpid)" |
| 167 | " FROM forumpost" |
| @@ -169,39 +170,42 @@ | |
| 170 | ); |
| 171 | while( db_step(&q)==SQLITE_ROW ){ |
| 172 | pEntry = fossil_malloc( sizeof(*pEntry) ); |
| 173 | memset(pEntry, 0, sizeof(*pEntry)); |
| 174 | pEntry->fpid = db_column_int(&q, 0); |
| 175 | firt = db_column_int(&q, 1); |
| 176 | pEntry->fprev = db_column_int(&q, 2); |
| 177 | pEntry->zUuid = fossil_strdup(db_column_text(&q,3)); |
| 178 | pEntry->mfirt = firt; |
| 179 | pEntry->sid = sid++; |
| 180 | pEntry->pPrev = pThread->pLast; |
| 181 | pEntry->pNext = 0; |
| 182 | if( pThread->pLast==0 ){ |
| 183 | pThread->pFirst = pEntry; |
| 184 | }else{ |
| 185 | pThread->pLast->pNext = pEntry; |
| 186 | } |
| 187 | if( firt ){ |
| 188 | pEntry->pIrt = pThread->pFirst; |
| 189 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 190 | if( p->fpid==firt ){ |
| 191 | pEntry->pIrt = p; |
| 192 | break; |
| 193 | } |
| 194 | } |
| 195 | } |
| 196 | pThread->pLast = pEntry; |
| 197 | } |
| 198 | db_finalize(&q); |
| 199 | |
| 200 | /* Establish which entries are the latest edit. After this loop |
| 201 | ** completes, entries that have non-NULL pEditTail should not be |
| 202 | ** displayed. |
| 203 | */ |
| 204 | for(pEntry=pThread->pFirst; pEntry; pEntry=pEntry->pNext){ |
| 205 | if( pEntry->fprev ){ |
| 206 | ForumEntry *pBase = 0; |
| 207 | p = forumentry_backward(pEntry->pPrev, pEntry->fprev); |
| 208 | p->pEditNext = pEntry; |
| 209 | pEntry->pEditPrev = p; |
| 210 | pEntry->pEditHead = p->pEditHead ? p->pEditHead : p; |
| 211 | while( p ){ |
| @@ -295,14 +299,14 @@ | |
| 299 | pThread = forumthread_create(froot, 1); |
| 300 | fossil_print("Chronological:\n"); |
| 301 | fossil_print( |
| 302 | /* 0 1 2 3 4 5 6 7 */ |
| 303 | /* 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123 */ |
| 304 | " sid fpid pIrt fprev mfirt pEditTail hash\n"); |
| 305 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 306 | fossil_print("%4d %9d %9d %9d %9d %9d %8.8s\n", p->sid, |
| 307 | p->fpid, p->pIrt ? p->pIrt->fpid : 0, p->fprev, p->mfirt, |
| 308 | p->pEditTail ? p->pEditTail->fpid : 0, p->zUuid); |
| 309 | } |
| 310 | fossil_print("\nDisplay\n"); |
| 311 | for(p=pThread->pDisplay; p; p=p->pDisplay){ |
| 312 | fossil_print("%*s", (p->nIndent-1)*3, ""); |
| @@ -447,17 +451,13 @@ | |
| 451 | } |
| 452 | if( g.perm.Debug ){ |
| 453 | @ <span class="debug">\ |
| 454 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 455 | } |
| 456 | if( p->pIrt ){ |
| 457 | @ in reply to %z(href("%R/forumpost/%S?t=%c",p->pIrt->zUuid,cMode))\ |
| 458 | @ %d(p->pIrt->sid)</a> |
| 459 | } |
| 460 | zUuid = p->zUuid; |
| 461 | if( p->pEditTail ){ |
| 462 | @ updated by %z(href("%R/forumpost/%S?t=%c",p->pEditTail->zUuid,cMode))\ |
| 463 | @ %d(p->pEditTail->sid)</a> |
| @@ -519,15 +519,16 @@ | |
| 519 | ** to be displayed for debugging purposes. |
| 520 | */ |
| 521 | if( PB("threadtable") ){ |
| 522 | @ <hr> |
| 523 | @ <table border="1" cellpadding="3" cellspacing="0"> |
| 524 | @ <tr><th>sid<th>fpid<th>pIrt<th>fprev<th>mfirt<th>pEditHead<th>pEditTail\ |
| 525 | @ <th>pEditNext<th>pEditPrev<th>hash |
| 526 | for(p=pThread->pFirst; p; p=p->pNext){ |
| 527 | @ <tr><td>%d(p->sid)<td>%d(p->fpid)\ |
| 528 | @ <td>%d(p->pIrt?p->pIrt->fpid:0)\ |
| 529 | @ <td>%d(p->fprev)\ |
| 530 | @ <td>%d(p->pEditHead?p->pEditHead->fpid:0)\ |
| 531 | @ <td>%d(p->pEditTail?p->pEditTail->fpid:0)\ |
| 532 | @ <td>%d(p->pEditNext?p->pEditNext->fpid:0)\ |
| 533 | @ <td>%d(p->pEditPrev?p->pEditPrev->fpid:0)\ |
| 534 | @ <td>%S(p->zUuid)</tr> |
| @@ -573,17 +574,13 @@ | |
| 574 | fossil_free(zDate); |
| 575 | if( g.perm.Debug ){ |
| 576 | @ <span class="debug">\ |
| 577 | @ <a href="%R/artifact/%h(p->zUuid)">(artifact-%d(p->fpid))</a></span> |
| 578 | } |
| 579 | if( p->pIrt && cnt==1 ){ |
| 580 | @ in reply to %z(href("%R/forumpost/%S?t=%c",p->pIrt->zUuid,cMode))\ |
| 581 | @ %d(p->pIrt->sid)</a> |
| 582 | } |
| 583 | zUuid = p->zUuid; |
| 584 | @ %z(href("%R/forumpost/%S?t=c",zUuid))[link]</a> |
| 585 | if( !bRawMode ){ |
| 586 | @ %z(href("%R/forumpost/%S?raw",zUuid))[source]</a> |
| @@ -707,17 +704,13 @@ | |
| 704 | } |
| 705 | if( fpid!=target ){ |
| 706 | @ %z(href("%R/forumpost/%S",zUuid))[link]</a> |
| 707 | } |
| 708 | @ %z(href("%R/forumpost/%S?raw",zUuid))[source]</a> |
| 709 | if( p->pIrt ){ |
| 710 | @ in reply to %z(href("%R/forumpost/%S?t=h",p->pIrt->zUuid))\ |
| 711 | @ %d(p->pIrt->sid)</a> |
| 712 | } |
| 713 | @ </h3> |
| 714 | isPrivate = content_is_private(fpid); |
| 715 | sameUser = notAnon && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| 716 | if( isPrivate && !g.perm.ModForum && !sameUser ){ |
| @@ -955,11 +948,11 @@ | |
| 948 | webpage_assert( (zTitle==0)+(iInReplyTo==0)==1 ); |
| 949 | blob_init(&x, 0, 0); |
| 950 | zDate = date_in_standard_format("now"); |
| 951 | blob_appendf(&x, "D %s\n", zDate); |
| 952 | fossil_free(zDate); |
| 953 | zG = db_text(0, |
| 954 | "SELECT uuid FROM blob, forumpost" |
| 955 | " WHERE blob.rid==forumpost.froot" |
| 956 | " AND forumpost.fpid=%d", iBasis); |
| 957 | if( zG ){ |
| 958 | blob_appendf(&x, "G %s\n", zG); |
| @@ -1209,11 +1202,11 @@ | |
| 1202 | } |
| 1203 | cgi_redirectf("%R/forumpost/%S",P("fpid")); |
| 1204 | return; |
| 1205 | } |
| 1206 | if( P("reject") ){ |
| 1207 | char *zParent = |
| 1208 | db_text(0, |
| 1209 | "SELECT uuid FROM forumpost, blob" |
| 1210 | " WHERE forumpost.fpid=%d AND blob.rid=forumpost.firt", |
| 1211 | fpid |
| 1212 | ); |
| 1213 |