Fossil SCM
refactored the prototype timeline code, split off completely from www version (different requirements).
Commit
1ecf337404e04409302f1432fa8d92f7f6a43df5
Parent
e78578453878bd6…
2 files changed
+66
-19
+1
-1
+66
-19
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -1399,10 +1399,62 @@ | ||
| 1399 | 1399 | }else{ |
| 1400 | 1400 | /* we should arguably treat JSON null as 0. */ |
| 1401 | 1401 | return dflt; |
| 1402 | 1402 | } |
| 1403 | 1403 | } |
| 1404 | + | |
| 1405 | +/* | |
| 1406 | +** Create a temporary table suitable for storing timeline data. | |
| 1407 | +*/ | |
| 1408 | +static void json_timeline_temp_table(void){ | |
| 1409 | + static const char zSql[] = | |
| 1410 | + @ CREATE TEMP TABLE IF NOT EXISTS json_timeline( | |
| 1411 | + @ rid INTEGER PRIMARY KEY, | |
| 1412 | + @ uuid TEXT, | |
| 1413 | + @ mtime INTEGER, | |
| 1414 | + @ timestampString TEXT, | |
| 1415 | + @ comment TEXT, | |
| 1416 | + @ user TEXT, | |
| 1417 | + @ isLeaf BOOLEAN, | |
| 1418 | + @ bgColor TEXT, | |
| 1419 | + @ eventType TEXT, | |
| 1420 | + @ tags TEXT, | |
| 1421 | + @ tagId INTEGER, | |
| 1422 | + @ brief TEXT | |
| 1423 | + @ ) | |
| 1424 | + ; | |
| 1425 | + db_multi_exec(zSql); | |
| 1426 | +} | |
| 1427 | + | |
| 1428 | +/* | |
| 1429 | +** Return a pointer to a constant string that forms the basis | |
| 1430 | +** for a timeline query for the JSON "checkin" interface. | |
| 1431 | +*/ | |
| 1432 | +const char const * json_timeline_query_ci(void){ | |
| 1433 | + /* Field order MUST match that from json_timeline_temp_table()!!! */ | |
| 1434 | + static const char zBaseSql[] = | |
| 1435 | + @ SELECT | |
| 1436 | + @ blob.rid, | |
| 1437 | + @ uuid, | |
| 1438 | + @ strftime('%%s',event.mtime), | |
| 1439 | + @ datetime(event.mtime,'utc'), | |
| 1440 | + @ coalesce(ecomment, comment), | |
| 1441 | + @ coalesce(euser, user), | |
| 1442 | + @ blob.rid IN leaf, | |
| 1443 | + @ bgcolor, | |
| 1444 | + @ event.type, | |
| 1445 | + @ (SELECT group_concat(substr(tagname,5), ' ') FROM tag, tagxref | |
| 1446 | + @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid | |
| 1447 | + @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0), | |
| 1448 | + @ tagid, | |
| 1449 | + @ brief | |
| 1450 | + @ FROM event JOIN blob | |
| 1451 | + @ WHERE blob.rid=event.objid | |
| 1452 | + ; | |
| 1453 | + return zBaseSql; | |
| 1454 | +} | |
| 1455 | + | |
| 1404 | 1456 | |
| 1405 | 1457 | /* |
| 1406 | 1458 | ** /json/timeline/ci |
| 1407 | 1459 | ** |
| 1408 | 1460 | ** Far from complete. |
| @@ -1417,19 +1469,14 @@ | ||
| 1417 | 1469 | if( !g.perm.Read/* && !g.perm.RdTkt && !g.perm.RdWiki*/ ){ |
| 1418 | 1470 | g.json.resultCode = FSL_JSON_E_DENIED; |
| 1419 | 1471 | return NULL; |
| 1420 | 1472 | } |
| 1421 | 1473 | if( limit < 0 ) limit = 10; |
| 1422 | - timeline_temp_table() /* FIXME: we need a JSON-specific one or some | |
| 1423 | - workarounds for timestamp and int-vs-bool | |
| 1424 | - values in the HTML version. i'd prefer the | |
| 1425 | - former, to avoid risking breaking HTML | |
| 1426 | - mode. | |
| 1427 | - */; | |
| 1428 | - | |
| 1429 | - blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1); | |
| 1430 | - blob_append(&sql, timeline_query_for_www(), -1); | |
| 1474 | + json_timeline_temp_table(); | |
| 1475 | + | |
| 1476 | + blob_append(&sql, "INSERT OR IGNORE INTO json_timeline ", -1); | |
| 1477 | + blob_append(&sql, json_timeline_query_ci(), -1 ); | |
| 1431 | 1478 | blob_append(&sql, "AND event.type IN('ci') ", -1); |
| 1432 | 1479 | blob_append(&sql, "ORDER BY mtime DESC ", -1); |
| 1433 | 1480 | if(limit){ |
| 1434 | 1481 | blob_appendf(&sql,"LIMIT %d ",limit); |
| 1435 | 1482 | } |
| @@ -1445,22 +1492,22 @@ | ||
| 1445 | 1492 | #endif |
| 1446 | 1493 | |
| 1447 | 1494 | blob_reset(&sql); |
| 1448 | 1495 | blob_append(&sql, "SELECT rid AS rid," |
| 1449 | 1496 | " uuid AS uuid," |
| 1450 | - " timestamp AS timestamp," /*FIXME: as epoch time*/ | |
| 1497 | + " mtime AS timestamp," | |
| 1498 | + " timestampString AS timestampString," | |
| 1451 | 1499 | " comment AS comment, " |
| 1452 | 1500 | " user AS user," |
| 1453 | - " isleaf AS isLeaf," | |
| 1454 | - " bgcolor AS bgColor," | |
| 1455 | - " etype AS eventType," | |
| 1456 | - " taglist AS tagList," /*FIXME: split this into | |
| 1457 | - a JSON array*/ | |
| 1458 | - " tagid AS tagId," | |
| 1459 | - " short AS shortText" | |
| 1460 | - /* ignoring sortby field */ | |
| 1461 | - " FROM timeline",-1); | |
| 1501 | + " isLeaf AS isLeaf," /*FIXME: convert to JSON bool */ | |
| 1502 | + " bgColor AS bgColor," | |
| 1503 | + " eventType AS eventType," | |
| 1504 | + " tags AS tags," /*FIXME: split this into | |
| 1505 | + a JSON array*/ | |
| 1506 | + " tagId AS tagId," | |
| 1507 | + " brief AS briefText" | |
| 1508 | + " FROM json_timeline",-1); | |
| 1462 | 1509 | db_prepare(&q,blob_buffer(&sql)); |
| 1463 | 1510 | tmp = NULL; |
| 1464 | 1511 | cson_sqlite3_stmt_to_json(q.pStmt, &tmp, 1); |
| 1465 | 1512 | db_finalize(&q); |
| 1466 | 1513 | if(tmp){ |
| 1467 | 1514 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1399,10 +1399,62 @@ | |
| 1399 | }else{ |
| 1400 | /* we should arguably treat JSON null as 0. */ |
| 1401 | return dflt; |
| 1402 | } |
| 1403 | } |
| 1404 | |
| 1405 | /* |
| 1406 | ** /json/timeline/ci |
| 1407 | ** |
| 1408 | ** Far from complete. |
| @@ -1417,19 +1469,14 @@ | |
| 1417 | if( !g.perm.Read/* && !g.perm.RdTkt && !g.perm.RdWiki*/ ){ |
| 1418 | g.json.resultCode = FSL_JSON_E_DENIED; |
| 1419 | return NULL; |
| 1420 | } |
| 1421 | if( limit < 0 ) limit = 10; |
| 1422 | timeline_temp_table() /* FIXME: we need a JSON-specific one or some |
| 1423 | workarounds for timestamp and int-vs-bool |
| 1424 | values in the HTML version. i'd prefer the |
| 1425 | former, to avoid risking breaking HTML |
| 1426 | mode. |
| 1427 | */; |
| 1428 | |
| 1429 | blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1); |
| 1430 | blob_append(&sql, timeline_query_for_www(), -1); |
| 1431 | blob_append(&sql, "AND event.type IN('ci') ", -1); |
| 1432 | blob_append(&sql, "ORDER BY mtime DESC ", -1); |
| 1433 | if(limit){ |
| 1434 | blob_appendf(&sql,"LIMIT %d ",limit); |
| 1435 | } |
| @@ -1445,22 +1492,22 @@ | |
| 1445 | #endif |
| 1446 | |
| 1447 | blob_reset(&sql); |
| 1448 | blob_append(&sql, "SELECT rid AS rid," |
| 1449 | " uuid AS uuid," |
| 1450 | " timestamp AS timestamp," /*FIXME: as epoch time*/ |
| 1451 | " comment AS comment, " |
| 1452 | " user AS user," |
| 1453 | " isleaf AS isLeaf," |
| 1454 | " bgcolor AS bgColor," |
| 1455 | " etype AS eventType," |
| 1456 | " taglist AS tagList," /*FIXME: split this into |
| 1457 | a JSON array*/ |
| 1458 | " tagid AS tagId," |
| 1459 | " short AS shortText" |
| 1460 | /* ignoring sortby field */ |
| 1461 | " FROM timeline",-1); |
| 1462 | db_prepare(&q,blob_buffer(&sql)); |
| 1463 | tmp = NULL; |
| 1464 | cson_sqlite3_stmt_to_json(q.pStmt, &tmp, 1); |
| 1465 | db_finalize(&q); |
| 1466 | if(tmp){ |
| 1467 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -1399,10 +1399,62 @@ | |
| 1399 | }else{ |
| 1400 | /* we should arguably treat JSON null as 0. */ |
| 1401 | return dflt; |
| 1402 | } |
| 1403 | } |
| 1404 | |
| 1405 | /* |
| 1406 | ** Create a temporary table suitable for storing timeline data. |
| 1407 | */ |
| 1408 | static void json_timeline_temp_table(void){ |
| 1409 | static const char zSql[] = |
| 1410 | @ CREATE TEMP TABLE IF NOT EXISTS json_timeline( |
| 1411 | @ rid INTEGER PRIMARY KEY, |
| 1412 | @ uuid TEXT, |
| 1413 | @ mtime INTEGER, |
| 1414 | @ timestampString TEXT, |
| 1415 | @ comment TEXT, |
| 1416 | @ user TEXT, |
| 1417 | @ isLeaf BOOLEAN, |
| 1418 | @ bgColor TEXT, |
| 1419 | @ eventType TEXT, |
| 1420 | @ tags TEXT, |
| 1421 | @ tagId INTEGER, |
| 1422 | @ brief TEXT |
| 1423 | @ ) |
| 1424 | ; |
| 1425 | db_multi_exec(zSql); |
| 1426 | } |
| 1427 | |
| 1428 | /* |
| 1429 | ** Return a pointer to a constant string that forms the basis |
| 1430 | ** for a timeline query for the JSON "checkin" interface. |
| 1431 | */ |
| 1432 | const char const * json_timeline_query_ci(void){ |
| 1433 | /* Field order MUST match that from json_timeline_temp_table()!!! */ |
| 1434 | static const char zBaseSql[] = |
| 1435 | @ SELECT |
| 1436 | @ blob.rid, |
| 1437 | @ uuid, |
| 1438 | @ strftime('%%s',event.mtime), |
| 1439 | @ datetime(event.mtime,'utc'), |
| 1440 | @ coalesce(ecomment, comment), |
| 1441 | @ coalesce(euser, user), |
| 1442 | @ blob.rid IN leaf, |
| 1443 | @ bgcolor, |
| 1444 | @ event.type, |
| 1445 | @ (SELECT group_concat(substr(tagname,5), ' ') FROM tag, tagxref |
| 1446 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 1447 | @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0), |
| 1448 | @ tagid, |
| 1449 | @ brief |
| 1450 | @ FROM event JOIN blob |
| 1451 | @ WHERE blob.rid=event.objid |
| 1452 | ; |
| 1453 | return zBaseSql; |
| 1454 | } |
| 1455 | |
| 1456 | |
| 1457 | /* |
| 1458 | ** /json/timeline/ci |
| 1459 | ** |
| 1460 | ** Far from complete. |
| @@ -1417,19 +1469,14 @@ | |
| 1469 | if( !g.perm.Read/* && !g.perm.RdTkt && !g.perm.RdWiki*/ ){ |
| 1470 | g.json.resultCode = FSL_JSON_E_DENIED; |
| 1471 | return NULL; |
| 1472 | } |
| 1473 | if( limit < 0 ) limit = 10; |
| 1474 | json_timeline_temp_table(); |
| 1475 | |
| 1476 | blob_append(&sql, "INSERT OR IGNORE INTO json_timeline ", -1); |
| 1477 | blob_append(&sql, json_timeline_query_ci(), -1 ); |
| 1478 | blob_append(&sql, "AND event.type IN('ci') ", -1); |
| 1479 | blob_append(&sql, "ORDER BY mtime DESC ", -1); |
| 1480 | if(limit){ |
| 1481 | blob_appendf(&sql,"LIMIT %d ",limit); |
| 1482 | } |
| @@ -1445,22 +1492,22 @@ | |
| 1492 | #endif |
| 1493 | |
| 1494 | blob_reset(&sql); |
| 1495 | blob_append(&sql, "SELECT rid AS rid," |
| 1496 | " uuid AS uuid," |
| 1497 | " mtime AS timestamp," |
| 1498 | " timestampString AS timestampString," |
| 1499 | " comment AS comment, " |
| 1500 | " user AS user," |
| 1501 | " isLeaf AS isLeaf," /*FIXME: convert to JSON bool */ |
| 1502 | " bgColor AS bgColor," |
| 1503 | " eventType AS eventType," |
| 1504 | " tags AS tags," /*FIXME: split this into |
| 1505 | a JSON array*/ |
| 1506 | " tagId AS tagId," |
| 1507 | " brief AS briefText" |
| 1508 | " FROM json_timeline",-1); |
| 1509 | db_prepare(&q,blob_buffer(&sql)); |
| 1510 | tmp = NULL; |
| 1511 | cson_sqlite3_stmt_to_json(q.pStmt, &tmp, 1); |
| 1512 | db_finalize(&q); |
| 1513 | if(tmp){ |
| 1514 |
+1
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -738,11 +738,11 @@ | ||
| 738 | 738 | } |
| 739 | 739 | |
| 740 | 740 | /* |
| 741 | 741 | ** Create a temporary table suitable for storing timeline data. |
| 742 | 742 | */ |
| 743 | -void timeline_temp_table(void){ | |
| 743 | +static void timeline_temp_table(void){ | |
| 744 | 744 | static const char zSql[] = |
| 745 | 745 | @ CREATE TEMP TABLE IF NOT EXISTS timeline( |
| 746 | 746 | @ rid INTEGER PRIMARY KEY, |
| 747 | 747 | @ uuid TEXT, |
| 748 | 748 | @ timestamp TEXT, |
| 749 | 749 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -738,11 +738,11 @@ | |
| 738 | } |
| 739 | |
| 740 | /* |
| 741 | ** Create a temporary table suitable for storing timeline data. |
| 742 | */ |
| 743 | void timeline_temp_table(void){ |
| 744 | static const char zSql[] = |
| 745 | @ CREATE TEMP TABLE IF NOT EXISTS timeline( |
| 746 | @ rid INTEGER PRIMARY KEY, |
| 747 | @ uuid TEXT, |
| 748 | @ timestamp TEXT, |
| 749 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -738,11 +738,11 @@ | |
| 738 | } |
| 739 | |
| 740 | /* |
| 741 | ** Create a temporary table suitable for storing timeline data. |
| 742 | */ |
| 743 | static void timeline_temp_table(void){ |
| 744 | static const char zSql[] = |
| 745 | @ CREATE TEMP TABLE IF NOT EXISTS timeline( |
| 746 | @ rid INTEGER PRIMARY KEY, |
| 747 | @ uuid TEXT, |
| 748 | @ timestamp TEXT, |
| 749 |