Fossil SCM
Refactor the forum status display for performance.
Commit
0dae5f8bd93620fac77773b1559f69594252cbb7d3dcce5cfec1962dc42f6602
Parent
2d23c2e9cd5fbc3…
1 file changed
+51
-34
+51
-34
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -2415,19 +2415,24 @@ | ||
| 2415 | 2415 | int iLimit = 0, iOfst, iCnt; |
| 2416 | 2416 | int srchFlags; |
| 2417 | 2417 | const int isSearch = P("s")!=0; |
| 2418 | 2418 | const char *zStatusFilter = P("status"); |
| 2419 | 2419 | char const *zLimit = 0; |
| 2420 | - const int bHasStatus = forum_statuses()->n>1; | |
| 2420 | + int eStatusTag = 0; | |
| 2421 | + int bHasStatus = 0; | |
| 2421 | 2422 | |
| 2422 | 2423 | login_check_credentials(); |
| 2423 | 2424 | srchFlags = search_restrict(SRCH_FORUM); |
| 2424 | 2425 | if( !g.perm.RdForum ){ |
| 2425 | 2426 | login_needed(g.anon.RdForum); |
| 2426 | 2427 | return; |
| 2427 | 2428 | } |
| 2428 | 2429 | cgi_check_for_malice(); |
| 2430 | + eStatusTag = db_int(0, "SELECT tagid FROM tag WHERE tagname='status'"); | |
| 2431 | + if( eStatusTag && forum_statuses()->n>1 ){ | |
| 2432 | + bHasStatus = 1; | |
| 2433 | + } | |
| 2429 | 2434 | style_set_current_feature("forum"); |
| 2430 | 2435 | style_header("%s%s", db_get("forum-title","Forum"), |
| 2431 | 2436 | isSearch ? " Search Results" : ""); |
| 2432 | 2437 | style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx"); |
| 2433 | 2438 | if( g.perm.WrForum ){ |
| @@ -2465,64 +2470,72 @@ | ||
| 2465 | 2470 | if( zStatusFilter && |
| 2466 | 2471 | (!*zStatusFilter || 0==fossil_strcmp("*",zStatusFilter)) ){ |
| 2467 | 2472 | zStatusFilter = 0; |
| 2468 | 2473 | } |
| 2469 | 2474 | if( db_table_exists("repository","forumpost") ){ |
| 2475 | + Stmt qStat; | |
| 2476 | + if( bHasStatus ){ | |
| 2477 | + db_prepare(&qStat, | |
| 2478 | + "SELECT tagxref.value, forumstatus.label\n" | |
| 2479 | + " FROM forumstatus, tagxref\n" | |
| 2480 | + " WHERE tagid=%d AND tagtype>=1\n" | |
| 2481 | + " AND forumstatus.value=tagxref.value\n" | |
| 2482 | + " AND rid=:rid\n" | |
| 2483 | + " ORDER BY mtime DESC", | |
| 2484 | + db_int(0,"SELECT tagid FROM tag WHERE tagname='status'") | |
| 2485 | + ); | |
| 2486 | + } | |
| 2470 | 2487 | db_prepare(&q, |
| 2471 | - "WITH " | |
| 2472 | - "thread(age,duration,cnt,root,last) AS (\n" | |
| 2488 | + "WITH thread(root,endtime,lastrid) AS (\n" | |
| 2473 | 2489 | " SELECT\n" |
| 2474 | - " julianday('now') - max(fmtime),\n" | |
| 2475 | - " max(fmtime) - min(fmtime),\n" | |
| 2476 | - " sum(fprev IS NULL),\n" | |
| 2477 | 2490 | " froot,\n" |
| 2478 | - " (SELECT fpid FROM forumpost AS y\n" | |
| 2479 | - " WHERE y.froot=x.froot %s\n" | |
| 2480 | - " ORDER BY y.fmtime DESC LIMIT 1)\n" | |
| 2481 | - " FROM forumpost AS x\n" | |
| 2491 | + " max(fmtime),\n" | |
| 2492 | + " fpid\n" | |
| 2493 | + " FROM forumpost\n" | |
| 2482 | 2494 | " WHERE firt IS NULL AND %s/*ModForum*/\n" |
| 2483 | 2495 | " GROUP BY froot\n" |
| 2484 | - " ORDER BY 1\n" | |
| 2496 | + " ORDER BY 2 DESC\n" | |
| 2485 | 2497 | " LIMIT %d OFFSET %d\n" |
| 2486 | 2498 | ")\n" |
| 2487 | 2499 | "SELECT\n" |
| 2488 | - " thread.age,\n" /* 0 */ | |
| 2489 | - " thread.duration,\n" /* 1 */ | |
| 2490 | - " thread.cnt,\n" /* 2 */ | |
| 2500 | + " julianday('now') - thread.endtime,\n" /* 0 */ | |
| 2501 | + " (SELECT fmtime FROM forumpost WHERE fpid=root),\n" /* 1 */ | |
| 2502 | + " (SELECT sum(fprev IS NULL) FROM forumpost" | |
| 2503 | + " WHERE froot=root),\n" /* 2 */ | |
| 2491 | 2504 | " blob.uuid,\n" /* 3 */ |
| 2492 | 2505 | " substr(event.comment,instr(event.comment,':')+1),\n" /* 4 */ |
| 2493 | - " thread.last,\n" /* 5 */ | |
| 2494 | - " (SELECT coalesce(fs.value,dfs.value)\n" | |
| 2495 | - " FROM tag, tagxref, forumstatus fs\n" | |
| 2496 | - " WHERE tag.tagname='status'\n" | |
| 2497 | - " AND tagxref.tagid=tag.tagid\n" | |
| 2498 | - " AND tagxref.tagtype>=1\n" | |
| 2499 | - " AND fs.value=tagxref.value)," /* 6 */ | |
| 2500 | - " (SELECT coalesce(fs.label,dfs.label)\n" | |
| 2501 | - " FROM tag, tagxref, forumstatus fs\n" | |
| 2502 | - " WHERE tag.tagname='status'\n" | |
| 2503 | - " AND tagxref.tagid=tag.tagid\n" | |
| 2504 | - " AND tagxref.tagtype>=1\n" | |
| 2505 | - " AND fs.value=tagxref.value)" /* 7 */ | |
| 2506 | + " thread.lastrid,\n" /* 5 */ | |
| 2507 | + " thread.root\n" /* 6 */ | |
| 2506 | 2508 | " FROM thread, blob, event\n" |
| 2507 | - " LEFT JOIN forumstatus AS dfs ON (dfs.ord=1)\n" | |
| 2508 | - " WHERE blob.rid=thread.last\n" | |
| 2509 | - " AND event.objid=thread.last\n" | |
| 2509 | + " WHERE blob.rid=thread.lastrid\n" | |
| 2510 | + " AND event.objid=thread.lastrid\n" | |
| 2510 | 2511 | " ORDER BY 1;", |
| 2511 | - g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/, | |
| 2512 | 2512 | g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/, |
| 2513 | 2513 | iLimit+1, iOfst |
| 2514 | 2514 | ); |
| 2515 | 2515 | while( db_step(&q)==SQLITE_ROW ){ |
| 2516 | 2516 | char *zAge = human_readable_age(db_column_double(&q,0)); |
| 2517 | 2517 | int nMsg = db_column_int(&q, 2); |
| 2518 | 2518 | const char *zUuid = db_column_text(&q, 3); |
| 2519 | 2519 | const char *zTitle = db_column_text(&q, 4); |
| 2520 | - const char *zStatus = bHasStatus ? db_column_text(&q, 6) : NULL; | |
| 2521 | - const char *zStatusLbl = bHasStatus ? db_column_text(&q, 7) : NULL; | |
| 2520 | + const char *zStatus; | |
| 2521 | + const char *zStatusLbl; | |
| 2522 | 2522 | const int bShowStatus = bHasStatus && !zStatusFilter; |
| 2523 | 2523 | const int nCols = bShowStatus ? 4 : 3; |
| 2524 | + if( bHasStatus ){ | |
| 2525 | + db_reset(&qStat); | |
| 2526 | + db_bind_int(&qStat, ":rid", db_column_int(&q,6)); | |
| 2527 | + if( db_step(&qStat)==SQLITE_ROW ){ | |
| 2528 | + zStatus = db_column_text(&qStat, 0); | |
| 2529 | + zStatusLbl = db_column_text(&qStat, 1); | |
| 2530 | + }else{ | |
| 2531 | + zStatus = forum_statuses()->aStatus[0].zValue; | |
| 2532 | + zStatusLbl = forum_statuses()->aStatus[0].zLabel; | |
| 2533 | + } | |
| 2534 | + }else{ | |
| 2535 | + zStatus = zStatusLbl = NULL; | |
| 2536 | + } | |
| 2524 | 2537 | if( iCnt==0 ){ |
| 2525 | 2538 | char * zTail = zStatusFilter |
| 2526 | 2539 | ? mprintf(" with status=%Q", zStatusFilter) |
| 2527 | 2540 | : 0; |
| 2528 | 2541 | if( iOfst>0 ){ |
| @@ -2573,25 +2586,29 @@ | ||
| 2573 | 2586 | @ Awaiting Moderator Approval</span><br> |
| 2574 | 2587 | } |
| 2575 | 2588 | if( nMsg<2 ){ |
| 2576 | 2589 | @ no replies\ |
| 2577 | 2590 | }else{ |
| 2578 | - char *zDuration = human_readable_age(db_column_double(&q,1)); | |
| 2591 | + char *zDuration = human_readable_age(db_column_double(&q,0)); | |
| 2579 | 2592 | @ %d(nMsg) posts spanning %h(zDuration)\ |
| 2580 | 2593 | fossil_free(zDuration); |
| 2581 | 2594 | } |
| 2582 | 2595 | @ </td>\ |
| 2583 | 2596 | if( bShowStatus ){ |
| 2584 | 2597 | @ <td class='status'>%h(zStatusLbl)</td>\ |
| 2585 | 2598 | } |
| 2599 | + if( bHasStatus ){ | |
| 2600 | + db_reset(&qStat); | |
| 2601 | + } | |
| 2586 | 2602 | @</tr> |
| 2587 | 2603 | fossil_free(zAge); |
| 2588 | 2604 | } |
| 2589 | 2605 | db_finalize(&q); |
| 2606 | + if( bHasStatus ) db_finalize(&qStat); | |
| 2590 | 2607 | } |
| 2591 | 2608 | if( iCnt>0 ){ |
| 2592 | 2609 | @ </table></div> |
| 2593 | 2610 | }else{ |
| 2594 | 2611 | @ <h1>No forum posts found</h1> |
| 2595 | 2612 | } |
| 2596 | 2613 | style_finish_page(); |
| 2597 | 2614 | } |
| 2598 | 2615 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -2415,19 +2415,24 @@ | |
| 2415 | int iLimit = 0, iOfst, iCnt; |
| 2416 | int srchFlags; |
| 2417 | const int isSearch = P("s")!=0; |
| 2418 | const char *zStatusFilter = P("status"); |
| 2419 | char const *zLimit = 0; |
| 2420 | const int bHasStatus = forum_statuses()->n>1; |
| 2421 | |
| 2422 | login_check_credentials(); |
| 2423 | srchFlags = search_restrict(SRCH_FORUM); |
| 2424 | if( !g.perm.RdForum ){ |
| 2425 | login_needed(g.anon.RdForum); |
| 2426 | return; |
| 2427 | } |
| 2428 | cgi_check_for_malice(); |
| 2429 | style_set_current_feature("forum"); |
| 2430 | style_header("%s%s", db_get("forum-title","Forum"), |
| 2431 | isSearch ? " Search Results" : ""); |
| 2432 | style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx"); |
| 2433 | if( g.perm.WrForum ){ |
| @@ -2465,64 +2470,72 @@ | |
| 2465 | if( zStatusFilter && |
| 2466 | (!*zStatusFilter || 0==fossil_strcmp("*",zStatusFilter)) ){ |
| 2467 | zStatusFilter = 0; |
| 2468 | } |
| 2469 | if( db_table_exists("repository","forumpost") ){ |
| 2470 | db_prepare(&q, |
| 2471 | "WITH " |
| 2472 | "thread(age,duration,cnt,root,last) AS (\n" |
| 2473 | " SELECT\n" |
| 2474 | " julianday('now') - max(fmtime),\n" |
| 2475 | " max(fmtime) - min(fmtime),\n" |
| 2476 | " sum(fprev IS NULL),\n" |
| 2477 | " froot,\n" |
| 2478 | " (SELECT fpid FROM forumpost AS y\n" |
| 2479 | " WHERE y.froot=x.froot %s\n" |
| 2480 | " ORDER BY y.fmtime DESC LIMIT 1)\n" |
| 2481 | " FROM forumpost AS x\n" |
| 2482 | " WHERE firt IS NULL AND %s/*ModForum*/\n" |
| 2483 | " GROUP BY froot\n" |
| 2484 | " ORDER BY 1\n" |
| 2485 | " LIMIT %d OFFSET %d\n" |
| 2486 | ")\n" |
| 2487 | "SELECT\n" |
| 2488 | " thread.age,\n" /* 0 */ |
| 2489 | " thread.duration,\n" /* 1 */ |
| 2490 | " thread.cnt,\n" /* 2 */ |
| 2491 | " blob.uuid,\n" /* 3 */ |
| 2492 | " substr(event.comment,instr(event.comment,':')+1),\n" /* 4 */ |
| 2493 | " thread.last,\n" /* 5 */ |
| 2494 | " (SELECT coalesce(fs.value,dfs.value)\n" |
| 2495 | " FROM tag, tagxref, forumstatus fs\n" |
| 2496 | " WHERE tag.tagname='status'\n" |
| 2497 | " AND tagxref.tagid=tag.tagid\n" |
| 2498 | " AND tagxref.tagtype>=1\n" |
| 2499 | " AND fs.value=tagxref.value)," /* 6 */ |
| 2500 | " (SELECT coalesce(fs.label,dfs.label)\n" |
| 2501 | " FROM tag, tagxref, forumstatus fs\n" |
| 2502 | " WHERE tag.tagname='status'\n" |
| 2503 | " AND tagxref.tagid=tag.tagid\n" |
| 2504 | " AND tagxref.tagtype>=1\n" |
| 2505 | " AND fs.value=tagxref.value)" /* 7 */ |
| 2506 | " FROM thread, blob, event\n" |
| 2507 | " LEFT JOIN forumstatus AS dfs ON (dfs.ord=1)\n" |
| 2508 | " WHERE blob.rid=thread.last\n" |
| 2509 | " AND event.objid=thread.last\n" |
| 2510 | " ORDER BY 1;", |
| 2511 | g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/, |
| 2512 | g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/, |
| 2513 | iLimit+1, iOfst |
| 2514 | ); |
| 2515 | while( db_step(&q)==SQLITE_ROW ){ |
| 2516 | char *zAge = human_readable_age(db_column_double(&q,0)); |
| 2517 | int nMsg = db_column_int(&q, 2); |
| 2518 | const char *zUuid = db_column_text(&q, 3); |
| 2519 | const char *zTitle = db_column_text(&q, 4); |
| 2520 | const char *zStatus = bHasStatus ? db_column_text(&q, 6) : NULL; |
| 2521 | const char *zStatusLbl = bHasStatus ? db_column_text(&q, 7) : NULL; |
| 2522 | const int bShowStatus = bHasStatus && !zStatusFilter; |
| 2523 | const int nCols = bShowStatus ? 4 : 3; |
| 2524 | if( iCnt==0 ){ |
| 2525 | char * zTail = zStatusFilter |
| 2526 | ? mprintf(" with status=%Q", zStatusFilter) |
| 2527 | : 0; |
| 2528 | if( iOfst>0 ){ |
| @@ -2573,25 +2586,29 @@ | |
| 2573 | @ Awaiting Moderator Approval</span><br> |
| 2574 | } |
| 2575 | if( nMsg<2 ){ |
| 2576 | @ no replies\ |
| 2577 | }else{ |
| 2578 | char *zDuration = human_readable_age(db_column_double(&q,1)); |
| 2579 | @ %d(nMsg) posts spanning %h(zDuration)\ |
| 2580 | fossil_free(zDuration); |
| 2581 | } |
| 2582 | @ </td>\ |
| 2583 | if( bShowStatus ){ |
| 2584 | @ <td class='status'>%h(zStatusLbl)</td>\ |
| 2585 | } |
| 2586 | @</tr> |
| 2587 | fossil_free(zAge); |
| 2588 | } |
| 2589 | db_finalize(&q); |
| 2590 | } |
| 2591 | if( iCnt>0 ){ |
| 2592 | @ </table></div> |
| 2593 | }else{ |
| 2594 | @ <h1>No forum posts found</h1> |
| 2595 | } |
| 2596 | style_finish_page(); |
| 2597 | } |
| 2598 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -2415,19 +2415,24 @@ | |
| 2415 | int iLimit = 0, iOfst, iCnt; |
| 2416 | int srchFlags; |
| 2417 | const int isSearch = P("s")!=0; |
| 2418 | const char *zStatusFilter = P("status"); |
| 2419 | char const *zLimit = 0; |
| 2420 | int eStatusTag = 0; |
| 2421 | int bHasStatus = 0; |
| 2422 | |
| 2423 | login_check_credentials(); |
| 2424 | srchFlags = search_restrict(SRCH_FORUM); |
| 2425 | if( !g.perm.RdForum ){ |
| 2426 | login_needed(g.anon.RdForum); |
| 2427 | return; |
| 2428 | } |
| 2429 | cgi_check_for_malice(); |
| 2430 | eStatusTag = db_int(0, "SELECT tagid FROM tag WHERE tagname='status'"); |
| 2431 | if( eStatusTag && forum_statuses()->n>1 ){ |
| 2432 | bHasStatus = 1; |
| 2433 | } |
| 2434 | style_set_current_feature("forum"); |
| 2435 | style_header("%s%s", db_get("forum-title","Forum"), |
| 2436 | isSearch ? " Search Results" : ""); |
| 2437 | style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx"); |
| 2438 | if( g.perm.WrForum ){ |
| @@ -2465,64 +2470,72 @@ | |
| 2470 | if( zStatusFilter && |
| 2471 | (!*zStatusFilter || 0==fossil_strcmp("*",zStatusFilter)) ){ |
| 2472 | zStatusFilter = 0; |
| 2473 | } |
| 2474 | if( db_table_exists("repository","forumpost") ){ |
| 2475 | Stmt qStat; |
| 2476 | if( bHasStatus ){ |
| 2477 | db_prepare(&qStat, |
| 2478 | "SELECT tagxref.value, forumstatus.label\n" |
| 2479 | " FROM forumstatus, tagxref\n" |
| 2480 | " WHERE tagid=%d AND tagtype>=1\n" |
| 2481 | " AND forumstatus.value=tagxref.value\n" |
| 2482 | " AND rid=:rid\n" |
| 2483 | " ORDER BY mtime DESC", |
| 2484 | db_int(0,"SELECT tagid FROM tag WHERE tagname='status'") |
| 2485 | ); |
| 2486 | } |
| 2487 | db_prepare(&q, |
| 2488 | "WITH thread(root,endtime,lastrid) AS (\n" |
| 2489 | " SELECT\n" |
| 2490 | " froot,\n" |
| 2491 | " max(fmtime),\n" |
| 2492 | " fpid\n" |
| 2493 | " FROM forumpost\n" |
| 2494 | " WHERE firt IS NULL AND %s/*ModForum*/\n" |
| 2495 | " GROUP BY froot\n" |
| 2496 | " ORDER BY 2 DESC\n" |
| 2497 | " LIMIT %d OFFSET %d\n" |
| 2498 | ")\n" |
| 2499 | "SELECT\n" |
| 2500 | " julianday('now') - thread.endtime,\n" /* 0 */ |
| 2501 | " (SELECT fmtime FROM forumpost WHERE fpid=root),\n" /* 1 */ |
| 2502 | " (SELECT sum(fprev IS NULL) FROM forumpost" |
| 2503 | " WHERE froot=root),\n" /* 2 */ |
| 2504 | " blob.uuid,\n" /* 3 */ |
| 2505 | " substr(event.comment,instr(event.comment,':')+1),\n" /* 4 */ |
| 2506 | " thread.lastrid,\n" /* 5 */ |
| 2507 | " thread.root\n" /* 6 */ |
| 2508 | " FROM thread, blob, event\n" |
| 2509 | " WHERE blob.rid=thread.lastrid\n" |
| 2510 | " AND event.objid=thread.lastrid\n" |
| 2511 | " ORDER BY 1;", |
| 2512 | g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/, |
| 2513 | iLimit+1, iOfst |
| 2514 | ); |
| 2515 | while( db_step(&q)==SQLITE_ROW ){ |
| 2516 | char *zAge = human_readable_age(db_column_double(&q,0)); |
| 2517 | int nMsg = db_column_int(&q, 2); |
| 2518 | const char *zUuid = db_column_text(&q, 3); |
| 2519 | const char *zTitle = db_column_text(&q, 4); |
| 2520 | const char *zStatus; |
| 2521 | const char *zStatusLbl; |
| 2522 | const int bShowStatus = bHasStatus && !zStatusFilter; |
| 2523 | const int nCols = bShowStatus ? 4 : 3; |
| 2524 | if( bHasStatus ){ |
| 2525 | db_reset(&qStat); |
| 2526 | db_bind_int(&qStat, ":rid", db_column_int(&q,6)); |
| 2527 | if( db_step(&qStat)==SQLITE_ROW ){ |
| 2528 | zStatus = db_column_text(&qStat, 0); |
| 2529 | zStatusLbl = db_column_text(&qStat, 1); |
| 2530 | }else{ |
| 2531 | zStatus = forum_statuses()->aStatus[0].zValue; |
| 2532 | zStatusLbl = forum_statuses()->aStatus[0].zLabel; |
| 2533 | } |
| 2534 | }else{ |
| 2535 | zStatus = zStatusLbl = NULL; |
| 2536 | } |
| 2537 | if( iCnt==0 ){ |
| 2538 | char * zTail = zStatusFilter |
| 2539 | ? mprintf(" with status=%Q", zStatusFilter) |
| 2540 | : 0; |
| 2541 | if( iOfst>0 ){ |
| @@ -2573,25 +2586,29 @@ | |
| 2586 | @ Awaiting Moderator Approval</span><br> |
| 2587 | } |
| 2588 | if( nMsg<2 ){ |
| 2589 | @ no replies\ |
| 2590 | }else{ |
| 2591 | char *zDuration = human_readable_age(db_column_double(&q,0)); |
| 2592 | @ %d(nMsg) posts spanning %h(zDuration)\ |
| 2593 | fossil_free(zDuration); |
| 2594 | } |
| 2595 | @ </td>\ |
| 2596 | if( bShowStatus ){ |
| 2597 | @ <td class='status'>%h(zStatusLbl)</td>\ |
| 2598 | } |
| 2599 | if( bHasStatus ){ |
| 2600 | db_reset(&qStat); |
| 2601 | } |
| 2602 | @</tr> |
| 2603 | fossil_free(zAge); |
| 2604 | } |
| 2605 | db_finalize(&q); |
| 2606 | if( bHasStatus ) db_finalize(&qStat); |
| 2607 | } |
| 2608 | if( iCnt>0 ){ |
| 2609 | @ </table></div> |
| 2610 | }else{ |
| 2611 | @ <h1>No forum posts found</h1> |
| 2612 | } |
| 2613 | style_finish_page(); |
| 2614 | } |
| 2615 |