Fossil

Check-in [f266ebdd]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Minor timeline output cleanups. Added /json/branch/list.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: f266ebdd3f942b08132ca486d5aca8364fe44c2a
User & Date: stephan 2011-09-21 18:10:52
Context
2011-09-21
18:20
Refactored prepareBranchStatement() to simplify its usage, get rid of ambiguous arg handling, and allow the caller to specify the priority of the all-vs-closed-vs-opened decision. Made it non-static and renamed to branch_prepare_statement() for re-use in /json/branch/list. check-in: 5a81a5ea user: stephan tags: json
18:10
Minor timeline output cleanups. Added /json/branch/list. check-in: f266ebdd user: stephan tags: json
17:38
More work on the warnings infrastructure. json_warn() now (experimentally) disallows (elides) duplicate warning codes to simplify downstream loops. Still undecided on that behaviour, though. check-in: 576425e8 user: stephan tags: json
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/branch.c.

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  /* Do an autosync push, if requested */
  if( !isPrivate ) autosync(AUTOSYNC_PUSH);
}

/*
** Prepare a query that will list all branches.
*/
static void prepareBranchQuery(Stmt *pQuery, int showAll, int showClosed){
  if( showClosed ){
    db_prepare(pQuery,
      "SELECT value FROM tagxref"
      " WHERE tagid=%d AND value NOT NULL "
      "EXCEPT "
      "SELECT value FROM tagxref"
      " WHERE tagid=%d"







|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  /* Do an autosync push, if requested */
  if( !isPrivate ) autosync(AUTOSYNC_PUSH);
}

/*
** Prepare a query that will list all branches.
*/
void prepareBranchQuery(Stmt *pQuery, int showAll, int showClosed){
  if( showClosed ){
    db_prepare(pQuery,
      "SELECT value FROM tagxref"
      " WHERE tagid=%d AND value NOT NULL "
      "EXCEPT "
      "SELECT value FROM tagxref"
      " WHERE tagid=%d"

Changes to src/json.c.

310
311
312
313
314
315
316

























317
318
319
320
321
322
323
....
1509
1510
1511
1512
1513
1514
1515

















































1516
1517
1518
1519
1520
1521
1522
....
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
....
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
....
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
        return rc;
      }
    }
  }
  return NULL;
}



























/*
** Returns the string form of a json_getenv() value, but ONLY If that
** value is-a String. Non-strings are not converted to strings for
** this purpose. Returned memory is owned by g.json or fossil and is
** valid until end-of-app or the given key is replaced in fossil's
** internals via cgi_replace_parameter() and friends or json_setenv().
................................................................................
  listV = NULL;
  end:
  db_finalize(&q);
  return listV;
}



















































static cson_value * json_timeline_ci(unsigned int depth);
/*
** Mapping of /json/timeline/XXX commands/paths to callbacks.
*/
static const JsonPageDef JsonPageDefs_Timeline[] = {
{"ci", json_timeline_ci, 0},
/* Last entry MUST have a NULL name. */
................................................................................
** complete.
**
*/
static cson_value * json_page_timeline(unsigned int depth){
  return json_page_dispatch_helper(depth,&JsonPageDefs_Timeline[0]);
}

static int json_getenv_int(char const * pKey, int dflt ){
  cson_value const * v = json_getenv(pKey);
  if(!v){
    return dflt;
  }else if( cson_value_is_number(v) ){
    return (int)cson_value_get_integer(v);
  }else if( cson_value_is_string(v) ){
    char const * sv = cson_string_cstr(cson_value_get_string(v));
    assert( (NULL!=sv) && "This is quite unexpected." );
    return sv ? atoi(sv) : dflt;
  }else if( cson_value_is_bool(v) ){
    return cson_value_get_bool(v) ? 1 : 0;
  }else{
    /* we should arguably treat JSON null as 0. */
    return dflt;
  }
}

/*
** Create a temporary table suitable for storing timeline data.
*/
static void json_timeline_temp_table(void){
  /* Field order MUST match that from json_timeline_query_XXX()!!! */
  static const char zSql[] = 
    @ CREATE TEMP TABLE IF NOT EXISTS json_timeline(
................................................................................
/*
** Mapping of names to JSON pages/commands.  Each name is a subpath of
** /json (in CGI mode) or a subcommand of the json command in CLI mode
*/
static const JsonPageDef JsonPageDefs[] = {
/* please keep alphabetically sorted (case-insensitive) for maintenance reasons. */
{"anonymousPassword",json_page_anon_password, 1},
{"branch", json_page_nyi,0},
{"cap", json_page_cap, 0},
{"dir", json_page_nyi, 0},
{"HAI",json_page_version,0},
{"login",json_page_login,1},
{"logout",json_page_logout,1},
{"stat",json_page_stat,0},
{"tag", json_page_nyi,0},
................................................................................

/*
** Mapping of /json/artifact/XXX commands/paths to callbacks.
*/
static const JsonPageDef JsonPageDefs_Artifact[] = {
{"vinfo", json_page_nyi, 0},
{"finfo", json_page_nyi, 0},
/* Last entry MUST have a NULL name. */
{NULL,NULL,0}
};

/*
** Mapping of /json/branch/XXX commands/paths to callbacks.
*/
static const JsonPageDef JsonPageDefs_Branch[] = {
{"list", json_page_nyi, 0},
{"create", json_page_nyi, 1},
/* Last entry MUST have a NULL name. */
{NULL,NULL,0}
};

/*
** Mapping of /json/tag/XXX commands/paths to callbacks.
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







<
<
<
<
<
<
<
<
<
<







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
....
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
....
1602
1603
1604
1605
1606
1607
1608


















1609
1610
1611
1612
1613
1614
1615
....
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
....
1816
1817
1818
1819
1820
1821
1822










1823
1824
1825
1826
1827
1828
1829
        return rc;
      }
    }
  }
  return NULL;
}

/*
** Wrapper around json_getenv() which...
**
** If it finds a value and that value is-a JSON number or is a string
** which looks like an integer or is-a JSON bool then it is converted
** to an int. If none of those apply then dflt is returned.
*/
static int json_getenv_int(char const * pKey, int dflt ){
  cson_value const * v = json_getenv(pKey);
  if(!v){
    return dflt;
  }else if( cson_value_is_number(v) ){
    return (int)cson_value_get_integer(v);
  }else if( cson_value_is_string(v) ){
    char const * sv = cson_string_cstr(cson_value_get_string(v));
    assert( (NULL!=sv) && "This is quite unexpected." );
    return sv ? atoi(sv) : dflt;
  }else if( cson_value_is_bool(v) ){
    return cson_value_get_bool(v) ? 1 : 0;
  }else{
    /* we should arguably treat JSON null as 0. */
    return dflt;
  }
}


/*
** Returns the string form of a json_getenv() value, but ONLY If that
** value is-a String. Non-strings are not converted to strings for
** this purpose. Returned memory is owned by g.json or fossil and is
** valid until end-of-app or the given key is replaced in fossil's
** internals via cgi_replace_parameter() and friends or json_setenv().
................................................................................
  listV = NULL;
  end:
  db_finalize(&q);
  return listV;
}



static cson_value * json_branch_list(unsigned int depth);
/*
** Mapping of /json/branch/XXX commands/paths to callbacks.
*/
static const JsonPageDef JsonPageDefs_Branch[] = {
{"list", json_branch_list, 0},
{"create", json_page_nyi, 1},
/* Last entry MUST have a NULL name. */
{NULL,NULL,0}
};

/*
** Implements the /json/branch family of pages/commands. Far from
** complete.
**
*/
static cson_value * json_page_branch(unsigned int depth){
  return json_page_dispatch_helper(depth,&JsonPageDefs_Branch[0]);
}

/*
** Impl for /json/branch/list
*/
static cson_value * json_branch_list(unsigned int depth){
  cson_value * payV = cson_value_new_object();
  cson_object * pay = cson_value_get_object(payV);
  cson_value * listV = cson_value_new_array();
  cson_array * list = cson_value_get_array(listV);
  int showAll = json_getenv_int("showAll",0);
  int showClosed = showAll ? 0 : json_getenv_int("showClosed",0);
  Stmt q;
  char const * range = showAll
    ? "all"
    : (showClosed?"closed":"open");
  cson_object_set(pay,"range",cson_value_new_string(range,strlen(range)));
  prepareBranchQuery(&q, showAll, showClosed);
  cson_object_set(pay,"branches",listV);
  while((SQLITE_ROW==db_step(&q))){
    cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
    if(v){
      cson_array_append(list,v);
    }else{
      json_warn(FSL_JSON_W_COL_TO_JSON_FAILED,NULL);
    }
  }
  return payV;
}

static cson_value * json_timeline_ci(unsigned int depth);
/*
** Mapping of /json/timeline/XXX commands/paths to callbacks.
*/
static const JsonPageDef JsonPageDefs_Timeline[] = {
{"ci", json_timeline_ci, 0},
/* Last entry MUST have a NULL name. */
................................................................................
** complete.
**
*/
static cson_value * json_page_timeline(unsigned int depth){
  return json_page_dispatch_helper(depth,&JsonPageDefs_Timeline[0]);
}



















/*
** Create a temporary table suitable for storing timeline data.
*/
static void json_timeline_temp_table(void){
  /* Field order MUST match that from json_timeline_query_XXX()!!! */
  static const char zSql[] = 
    @ CREATE TEMP TABLE IF NOT EXISTS json_timeline(
................................................................................
/*
** Mapping of names to JSON pages/commands.  Each name is a subpath of
** /json (in CGI mode) or a subcommand of the json command in CLI mode
*/
static const JsonPageDef JsonPageDefs[] = {
/* please keep alphabetically sorted (case-insensitive) for maintenance reasons. */
{"anonymousPassword",json_page_anon_password, 1},
{"branch", json_page_branch,0},
{"cap", json_page_cap, 0},
{"dir", json_page_nyi, 0},
{"HAI",json_page_version,0},
{"login",json_page_login,1},
{"logout",json_page_logout,1},
{"stat",json_page_stat,0},
{"tag", json_page_nyi,0},
................................................................................

/*
** Mapping of /json/artifact/XXX commands/paths to callbacks.
*/
static const JsonPageDef JsonPageDefs_Artifact[] = {
{"vinfo", json_page_nyi, 0},
{"finfo", json_page_nyi, 0},










/* Last entry MUST have a NULL name. */
{NULL,NULL,0}
};

/*
** Mapping of /json/tag/XXX commands/paths to callbacks.
*/

Changes to src/json_detail.h.

15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
** for a given category have their high bits set to the category
** value.
**
*/
enum FossilJsonCodes {
FSL_JSON_W_START = 0,
FSL_JSON_W_ROW_TO_JSON_FAILED = FSL_JSON_W_START + 1,

FSL_JSON_W_STRING_TO_ARRAY_FAILED = FSL_JSON_W_START + 2,

FSL_JSON_W_END = 1000,
FSL_JSON_E_GENERIC = 1000,
FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC_SUB1 + 1,
FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC_SUB1 + 2,
FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC_SUB1 + 3,







>
|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** for a given category have their high bits set to the category
** value.
**
*/
enum FossilJsonCodes {
FSL_JSON_W_START = 0,
FSL_JSON_W_ROW_TO_JSON_FAILED = FSL_JSON_W_START + 1,
FSL_JSON_W_COL_TO_JSON_FAILED = FSL_JSON_W_START + 2,
FSL_JSON_W_STRING_TO_ARRAY_FAILED = FSL_JSON_W_START + 3,

FSL_JSON_W_END = 1000,
FSL_JSON_E_GENERIC = 1000,
FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC_SUB1 + 1,
FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC_SUB1 + 2,
FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC_SUB1 + 3,