| | @@ -312,10 +312,35 @@ |
| 312 | 312 | } |
| 313 | 313 | } |
| 314 | 314 | return NULL; |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | +/* |
| 318 | +** Wrapper around json_getenv() which... |
| 319 | +** |
| 320 | +** If it finds a value and that value is-a JSON number or is a string |
| 321 | +** which looks like an integer or is-a JSON bool then it is converted |
| 322 | +** to an int. If none of those apply then dflt is returned. |
| 323 | +*/ |
| 324 | +static int json_getenv_int(char const * pKey, int dflt ){ |
| 325 | + cson_value const * v = json_getenv(pKey); |
| 326 | + if(!v){ |
| 327 | + return dflt; |
| 328 | + }else if( cson_value_is_number(v) ){ |
| 329 | + return (int)cson_value_get_integer(v); |
| 330 | + }else if( cson_value_is_string(v) ){ |
| 331 | + char const * sv = cson_string_cstr(cson_value_get_string(v)); |
| 332 | + assert( (NULL!=sv) && "This is quite unexpected." ); |
| 333 | + return sv ? atoi(sv) : dflt; |
| 334 | + }else if( cson_value_is_bool(v) ){ |
| 335 | + return cson_value_get_bool(v) ? 1 : 0; |
| 336 | + }else{ |
| 337 | + /* we should arguably treat JSON null as 0. */ |
| 338 | + return dflt; |
| 339 | + } |
| 340 | +} |
| 341 | + |
| 317 | 342 | |
| 318 | 343 | /* |
| 319 | 344 | ** Returns the string form of a json_getenv() value, but ONLY If that |
| 320 | 345 | ** value is-a String. Non-strings are not converted to strings for |
| 321 | 346 | ** this purpose. Returned memory is owned by g.json or fossil and is |
| | @@ -1511,10 +1536,59 @@ |
| 1511 | 1536 | db_finalize(&q); |
| 1512 | 1537 | return listV; |
| 1513 | 1538 | } |
| 1514 | 1539 | |
| 1515 | 1540 | |
| 1541 | + |
| 1542 | +static cson_value * json_branch_list(unsigned int depth); |
| 1543 | +/* |
| 1544 | +** Mapping of /json/branch/XXX commands/paths to callbacks. |
| 1545 | +*/ |
| 1546 | +static const JsonPageDef JsonPageDefs_Branch[] = { |
| 1547 | +{"list", json_branch_list, 0}, |
| 1548 | +{"create", json_page_nyi, 1}, |
| 1549 | +/* Last entry MUST have a NULL name. */ |
| 1550 | +{NULL,NULL,0} |
| 1551 | +}; |
| 1552 | + |
| 1553 | +/* |
| 1554 | +** Implements the /json/branch family of pages/commands. Far from |
| 1555 | +** complete. |
| 1556 | +** |
| 1557 | +*/ |
| 1558 | +static cson_value * json_page_branch(unsigned int depth){ |
| 1559 | + return json_page_dispatch_helper(depth,&JsonPageDefs_Branch[0]); |
| 1560 | +} |
| 1561 | + |
| 1562 | +/* |
| 1563 | +** Impl for /json/branch/list |
| 1564 | +*/ |
| 1565 | +static cson_value * json_branch_list(unsigned int depth){ |
| 1566 | + cson_value * payV = cson_value_new_object(); |
| 1567 | + cson_object * pay = cson_value_get_object(payV); |
| 1568 | + cson_value * listV = cson_value_new_array(); |
| 1569 | + cson_array * list = cson_value_get_array(listV); |
| 1570 | + int showAll = json_getenv_int("showAll",0); |
| 1571 | + int showClosed = showAll ? 0 : json_getenv_int("showClosed",0); |
| 1572 | + Stmt q; |
| 1573 | + char const * range = showAll |
| 1574 | + ? "all" |
| 1575 | + : (showClosed?"closed":"open"); |
| 1576 | + cson_object_set(pay,"range",cson_value_new_string(range,strlen(range))); |
| 1577 | + prepareBranchQuery(&q, showAll, showClosed); |
| 1578 | + cson_object_set(pay,"branches",listV); |
| 1579 | + while((SQLITE_ROW==db_step(&q))){ |
| 1580 | + cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0); |
| 1581 | + if(v){ |
| 1582 | + cson_array_append(list,v); |
| 1583 | + }else{ |
| 1584 | + json_warn(FSL_JSON_W_COL_TO_JSON_FAILED,NULL); |
| 1585 | + } |
| 1586 | + } |
| 1587 | + return payV; |
| 1588 | +} |
| 1589 | + |
| 1516 | 1590 | static cson_value * json_timeline_ci(unsigned int depth); |
| 1517 | 1591 | /* |
| 1518 | 1592 | ** Mapping of /json/timeline/XXX commands/paths to callbacks. |
| 1519 | 1593 | */ |
| 1520 | 1594 | static const JsonPageDef JsonPageDefs_Timeline[] = { |
| | @@ -1530,28 +1604,10 @@ |
| 1530 | 1604 | */ |
| 1531 | 1605 | static cson_value * json_page_timeline(unsigned int depth){ |
| 1532 | 1606 | return json_page_dispatch_helper(depth,&JsonPageDefs_Timeline[0]); |
| 1533 | 1607 | } |
| 1534 | 1608 | |
| 1535 | | -static int json_getenv_int(char const * pKey, int dflt ){ |
| 1536 | | - cson_value const * v = json_getenv(pKey); |
| 1537 | | - if(!v){ |
| 1538 | | - return dflt; |
| 1539 | | - }else if( cson_value_is_number(v) ){ |
| 1540 | | - return (int)cson_value_get_integer(v); |
| 1541 | | - }else if( cson_value_is_string(v) ){ |
| 1542 | | - char const * sv = cson_string_cstr(cson_value_get_string(v)); |
| 1543 | | - assert( (NULL!=sv) && "This is quite unexpected." ); |
| 1544 | | - return sv ? atoi(sv) : dflt; |
| 1545 | | - }else if( cson_value_is_bool(v) ){ |
| 1546 | | - return cson_value_get_bool(v) ? 1 : 0; |
| 1547 | | - }else{ |
| 1548 | | - /* we should arguably treat JSON null as 0. */ |
| 1549 | | - return dflt; |
| 1550 | | - } |
| 1551 | | -} |
| 1552 | | - |
| 1553 | 1609 | /* |
| 1554 | 1610 | ** Create a temporary table suitable for storing timeline data. |
| 1555 | 1611 | */ |
| 1556 | 1612 | static void json_timeline_temp_table(void){ |
| 1557 | 1613 | /* Field order MUST match that from json_timeline_query_XXX()!!! */ |
| | @@ -1726,11 +1782,11 @@ |
| 1726 | 1782 | ** /json (in CGI mode) or a subcommand of the json command in CLI mode |
| 1727 | 1783 | */ |
| 1728 | 1784 | static const JsonPageDef JsonPageDefs[] = { |
| 1729 | 1785 | /* please keep alphabetically sorted (case-insensitive) for maintenance reasons. */ |
| 1730 | 1786 | {"anonymousPassword",json_page_anon_password, 1}, |
| 1731 | | -{"branch", json_page_nyi,0}, |
| 1787 | +{"branch", json_page_branch,0}, |
| 1732 | 1788 | {"cap", json_page_cap, 0}, |
| 1733 | 1789 | {"dir", json_page_nyi, 0}, |
| 1734 | 1790 | {"HAI",json_page_version,0}, |
| 1735 | 1791 | {"login",json_page_login,1}, |
| 1736 | 1792 | {"logout",json_page_logout,1}, |
| | @@ -1762,20 +1818,10 @@ |
| 1762 | 1818 | ** Mapping of /json/artifact/XXX commands/paths to callbacks. |
| 1763 | 1819 | */ |
| 1764 | 1820 | static const JsonPageDef JsonPageDefs_Artifact[] = { |
| 1765 | 1821 | {"vinfo", json_page_nyi, 0}, |
| 1766 | 1822 | {"finfo", json_page_nyi, 0}, |
| 1767 | | -/* Last entry MUST have a NULL name. */ |
| 1768 | | -{NULL,NULL,0} |
| 1769 | | -}; |
| 1770 | | - |
| 1771 | | -/* |
| 1772 | | -** Mapping of /json/branch/XXX commands/paths to callbacks. |
| 1773 | | -*/ |
| 1774 | | -static const JsonPageDef JsonPageDefs_Branch[] = { |
| 1775 | | -{"list", json_page_nyi, 0}, |
| 1776 | | -{"create", json_page_nyi, 1}, |
| 1777 | 1823 | /* Last entry MUST have a NULL name. */ |
| 1778 | 1824 | {NULL,NULL,0} |
| 1779 | 1825 | }; |
| 1780 | 1826 | |
| 1781 | 1827 | /* |
| 1782 | 1828 | |