Fossil SCM
Enhance the "x" (mnemonic: eXtra) query parameter to /timeline so that it works with d=, p=, and from= queries.
Commit
1e8451b55f3f38a6cc0bdcb62d579afbf5f7830be681807b2fe95fc92636e0fd
Parent
dff73bdc71c24b3…
1 file changed
+44
-17
+44
-17
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1663,10 +1663,51 @@ | ||
| 1663 | 1663 | } |
| 1664 | 1664 | db_finalize(&q); |
| 1665 | 1665 | db_unpause_dml_log(); |
| 1666 | 1666 | return ans; |
| 1667 | 1667 | } |
| 1668 | + | |
| 1669 | +/* | |
| 1670 | +** Add to the (temp) table zTab, RID values for every check-in | |
| 1671 | +** identifier found on the zExtra string. Check-in names can be separated | |
| 1672 | +** by commas or by whitespace. | |
| 1673 | +*/ | |
| 1674 | +static void add_extra_rids(const char *zTab, const char *zExtra){ | |
| 1675 | + int ii; | |
| 1676 | + int rid; | |
| 1677 | + int cnt; | |
| 1678 | + Blob sql; | |
| 1679 | + char *zX; | |
| 1680 | + char *zToDel; | |
| 1681 | + if( zExtra==0 ) return; | |
| 1682 | + cnt = 0; | |
| 1683 | + blob_init(&sql, 0, 0); | |
| 1684 | + zX = zToDel = fossil_strdup(zExtra); | |
| 1685 | + blob_append_sql(&sql, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab); | |
| 1686 | + while( zX[0] ){ | |
| 1687 | + char c; | |
| 1688 | + if( zX[0]==',' || zX[0]==' ' ){ zX++; continue; } | |
| 1689 | + for(ii=1; zX[ii] && zX[ii]!=',' && zX[ii]!=' '; ii++){} | |
| 1690 | + c = zX[ii]; | |
| 1691 | + zX[ii] = 0; | |
| 1692 | + rid = name_to_rid(zX); | |
| 1693 | + if( rid>0 ){ | |
| 1694 | + if( (cnt%10)==4 ){ | |
| 1695 | + blob_append_sql(&sql,",\n "); | |
| 1696 | + }else if( cnt>0 ){ | |
| 1697 | + blob_append_sql(&sql,","); | |
| 1698 | + } | |
| 1699 | + blob_append_sql(&sql, "(%d)", rid); | |
| 1700 | + cnt++; | |
| 1701 | + } | |
| 1702 | + zX[ii] = c; | |
| 1703 | + zX += ii; | |
| 1704 | + } | |
| 1705 | + if( cnt ) db_exec_sql(blob_sql_text(&sql)); | |
| 1706 | + blob_reset(&sql); | |
| 1707 | + fossil_free(zToDel); | |
| 1708 | +} | |
| 1668 | 1709 | |
| 1669 | 1710 | /* |
| 1670 | 1711 | ** COMMAND: test-endpoint |
| 1671 | 1712 | ** |
| 1672 | 1713 | ** Usage: fossil test-endpoint BASE TAG ?OPTIONS? |
| @@ -2312,10 +2353,11 @@ | ||
| 2312 | 2353 | "DELETE FROM related WHERE x NOT IN ok;" |
| 2313 | 2354 | ); |
| 2314 | 2355 | } |
| 2315 | 2356 | db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related"); |
| 2316 | 2357 | } |
| 2358 | + add_extra_rids("pathnode",P("x")); | |
| 2317 | 2359 | blob_append_sql(&sql, " AND event.objid IN pathnode"); |
| 2318 | 2360 | if( zChng && zChng[0] ){ |
| 2319 | 2361 | db_multi_exec( |
| 2320 | 2362 | "DELETE FROM pathnode\n" |
| 2321 | 2363 | " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n" |
| @@ -2377,10 +2419,11 @@ | ||
| 2377 | 2419 | if( !haveParameterN ) nEntry = 10; |
| 2378 | 2420 | } |
| 2379 | 2421 | db_multi_exec( |
| 2380 | 2422 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 2381 | 2423 | ); |
| 2424 | + add_extra_rids("ok", P("x")); | |
| 2382 | 2425 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", |
| 2383 | 2426 | p_rid ? p_rid : d_rid); |
| 2384 | 2427 | zCiName = zDPName; |
| 2385 | 2428 | if( zCiName==0 ) zCiName = zUuid; |
| 2386 | 2429 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| @@ -2718,27 +2761,11 @@ | ||
| 2718 | 2761 | ** include the UUID check-in in the display list */ |
| 2719 | 2762 | int ridMark = name_to_rid(zMark); |
| 2720 | 2763 | db_multi_exec( |
| 2721 | 2764 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark); |
| 2722 | 2765 | } |
| 2723 | - if( P("x")!=0 ){ | |
| 2724 | - char *zX = fossil_strdup(P("x")); | |
| 2725 | - int ii; | |
| 2726 | - int ridX; | |
| 2727 | - while( zX[0] ){ | |
| 2728 | - char c; | |
| 2729 | - if( zX[0]==',' || zX[0]==' ' ){ zX++; continue; } | |
| 2730 | - for(ii=1; zX[ii] && zX[ii]!=',' && zX[ii]!=' '; ii++){} | |
| 2731 | - c = zX[ii]; | |
| 2732 | - zX[ii] = 0; | |
| 2733 | - ridX = name_to_rid(zX); | |
| 2734 | - db_multi_exec( | |
| 2735 | - "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridX); | |
| 2736 | - zX[ii] = c; | |
| 2737 | - zX += ii; | |
| 2738 | - } | |
| 2739 | - } | |
| 2766 | + add_extra_rids("selected_nodes",P("x")); | |
| 2740 | 2767 | if( !related ){ |
| 2741 | 2768 | blob_append_sql(&cond, " AND blob.rid IN selected_nodes"); |
| 2742 | 2769 | }else{ |
| 2743 | 2770 | db_multi_exec( |
| 2744 | 2771 | "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);" |
| 2745 | 2772 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1663,10 +1663,51 @@ | |
| 1663 | } |
| 1664 | db_finalize(&q); |
| 1665 | db_unpause_dml_log(); |
| 1666 | return ans; |
| 1667 | } |
| 1668 | |
| 1669 | /* |
| 1670 | ** COMMAND: test-endpoint |
| 1671 | ** |
| 1672 | ** Usage: fossil test-endpoint BASE TAG ?OPTIONS? |
| @@ -2312,10 +2353,11 @@ | |
| 2312 | "DELETE FROM related WHERE x NOT IN ok;" |
| 2313 | ); |
| 2314 | } |
| 2315 | db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related"); |
| 2316 | } |
| 2317 | blob_append_sql(&sql, " AND event.objid IN pathnode"); |
| 2318 | if( zChng && zChng[0] ){ |
| 2319 | db_multi_exec( |
| 2320 | "DELETE FROM pathnode\n" |
| 2321 | " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n" |
| @@ -2377,10 +2419,11 @@ | |
| 2377 | if( !haveParameterN ) nEntry = 10; |
| 2378 | } |
| 2379 | db_multi_exec( |
| 2380 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 2381 | ); |
| 2382 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", |
| 2383 | p_rid ? p_rid : d_rid); |
| 2384 | zCiName = zDPName; |
| 2385 | if( zCiName==0 ) zCiName = zUuid; |
| 2386 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| @@ -2718,27 +2761,11 @@ | |
| 2718 | ** include the UUID check-in in the display list */ |
| 2719 | int ridMark = name_to_rid(zMark); |
| 2720 | db_multi_exec( |
| 2721 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark); |
| 2722 | } |
| 2723 | if( P("x")!=0 ){ |
| 2724 | char *zX = fossil_strdup(P("x")); |
| 2725 | int ii; |
| 2726 | int ridX; |
| 2727 | while( zX[0] ){ |
| 2728 | char c; |
| 2729 | if( zX[0]==',' || zX[0]==' ' ){ zX++; continue; } |
| 2730 | for(ii=1; zX[ii] && zX[ii]!=',' && zX[ii]!=' '; ii++){} |
| 2731 | c = zX[ii]; |
| 2732 | zX[ii] = 0; |
| 2733 | ridX = name_to_rid(zX); |
| 2734 | db_multi_exec( |
| 2735 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridX); |
| 2736 | zX[ii] = c; |
| 2737 | zX += ii; |
| 2738 | } |
| 2739 | } |
| 2740 | if( !related ){ |
| 2741 | blob_append_sql(&cond, " AND blob.rid IN selected_nodes"); |
| 2742 | }else{ |
| 2743 | db_multi_exec( |
| 2744 | "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);" |
| 2745 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1663,10 +1663,51 @@ | |
| 1663 | } |
| 1664 | db_finalize(&q); |
| 1665 | db_unpause_dml_log(); |
| 1666 | return ans; |
| 1667 | } |
| 1668 | |
| 1669 | /* |
| 1670 | ** Add to the (temp) table zTab, RID values for every check-in |
| 1671 | ** identifier found on the zExtra string. Check-in names can be separated |
| 1672 | ** by commas or by whitespace. |
| 1673 | */ |
| 1674 | static void add_extra_rids(const char *zTab, const char *zExtra){ |
| 1675 | int ii; |
| 1676 | int rid; |
| 1677 | int cnt; |
| 1678 | Blob sql; |
| 1679 | char *zX; |
| 1680 | char *zToDel; |
| 1681 | if( zExtra==0 ) return; |
| 1682 | cnt = 0; |
| 1683 | blob_init(&sql, 0, 0); |
| 1684 | zX = zToDel = fossil_strdup(zExtra); |
| 1685 | blob_append_sql(&sql, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab); |
| 1686 | while( zX[0] ){ |
| 1687 | char c; |
| 1688 | if( zX[0]==',' || zX[0]==' ' ){ zX++; continue; } |
| 1689 | for(ii=1; zX[ii] && zX[ii]!=',' && zX[ii]!=' '; ii++){} |
| 1690 | c = zX[ii]; |
| 1691 | zX[ii] = 0; |
| 1692 | rid = name_to_rid(zX); |
| 1693 | if( rid>0 ){ |
| 1694 | if( (cnt%10)==4 ){ |
| 1695 | blob_append_sql(&sql,",\n "); |
| 1696 | }else if( cnt>0 ){ |
| 1697 | blob_append_sql(&sql,","); |
| 1698 | } |
| 1699 | blob_append_sql(&sql, "(%d)", rid); |
| 1700 | cnt++; |
| 1701 | } |
| 1702 | zX[ii] = c; |
| 1703 | zX += ii; |
| 1704 | } |
| 1705 | if( cnt ) db_exec_sql(blob_sql_text(&sql)); |
| 1706 | blob_reset(&sql); |
| 1707 | fossil_free(zToDel); |
| 1708 | } |
| 1709 | |
| 1710 | /* |
| 1711 | ** COMMAND: test-endpoint |
| 1712 | ** |
| 1713 | ** Usage: fossil test-endpoint BASE TAG ?OPTIONS? |
| @@ -2312,10 +2353,11 @@ | |
| 2353 | "DELETE FROM related WHERE x NOT IN ok;" |
| 2354 | ); |
| 2355 | } |
| 2356 | db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related"); |
| 2357 | } |
| 2358 | add_extra_rids("pathnode",P("x")); |
| 2359 | blob_append_sql(&sql, " AND event.objid IN pathnode"); |
| 2360 | if( zChng && zChng[0] ){ |
| 2361 | db_multi_exec( |
| 2362 | "DELETE FROM pathnode\n" |
| 2363 | " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n" |
| @@ -2377,10 +2419,11 @@ | |
| 2419 | if( !haveParameterN ) nEntry = 10; |
| 2420 | } |
| 2421 | db_multi_exec( |
| 2422 | "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)" |
| 2423 | ); |
| 2424 | add_extra_rids("ok", P("x")); |
| 2425 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", |
| 2426 | p_rid ? p_rid : d_rid); |
| 2427 | zCiName = zDPName; |
| 2428 | if( zCiName==0 ) zCiName = zUuid; |
| 2429 | blob_append_sql(&sql, " AND event.objid IN ok"); |
| @@ -2718,27 +2761,11 @@ | |
| 2761 | ** include the UUID check-in in the display list */ |
| 2762 | int ridMark = name_to_rid(zMark); |
| 2763 | db_multi_exec( |
| 2764 | "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark); |
| 2765 | } |
| 2766 | add_extra_rids("selected_nodes",P("x")); |
| 2767 | if( !related ){ |
| 2768 | blob_append_sql(&cond, " AND blob.rid IN selected_nodes"); |
| 2769 | }else{ |
| 2770 | db_multi_exec( |
| 2771 | "CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);" |
| 2772 |