Fossil SCM

lots of minor cleanups in JSON error handling (mostly cosmetic). Added some new FOSSIL-xxxx codes.

stephan 2011-10-05 00:53 UTC json-multitag-test
Commit 2e41514fb754131bc1206b7f42338da5a286846e
+34 -23
--- src/json.c
+++ src/json.c
@@ -206,29 +206,35 @@
206206
207207
C(GENERIC,"Generic error");
208208
C(INVALID_REQUEST,"Invalid request");
209209
C(UNKNOWN_COMMAND,"Unknown Command");
210210
C(UNKNOWN,"Unknown error");
211
- C(RESOURCE_NOT_FOUND,"Resource not found");
212211
C(TIMEOUT,"Timeout reached");
213212
C(ASSERT,"Assertion failed");
214213
C(ALLOC,"Resource allocation failed");
215214
C(NYI,"Not yet implemented");
215
+ C(PANIC,"x");
216
+ C(MANIFEST_READ_FAILED,"Reading artifact manifest failed.");
217
+ C(FILE_OPEN_FAILED,"Opening file failed.");
218
+
216219
C(AUTH,"Authentication error");
220
+ C(MISSING_AUTH,"Authentication info missing from request");
221
+ C(DENIED,"Access denied");
222
+ C(WRONG_MODE,"Request not allowed (wrong operation mode)");
217223
C(LOGIN_FAILED,"Login failed");
218224
C(LOGIN_FAILED_NOSEED,"Anonymous login attempt was missing password seed");
219225
C(LOGIN_FAILED_NONAME,"Login failed - name not supplied");
220226
C(LOGIN_FAILED_NOPW,"Login failed - password not supplied");
221227
C(LOGIN_FAILED_NOTFOUND,"Login failed - no match found");
222
- C(MISSING_AUTH,"Authentication info missing from request");
223
- C(DENIED,"Access denied");
224
- C(WRONG_MODE,"Request not allowed (wrong operation mode)");
225228
226229
C(USAGE,"Usage error");
227
- C(INVALID_ARGS,"Invalid arguments");
228
- C(MISSING_ARGS,"Missing arguments");
229
- C(AMBIGUOUS_UUID,"Argument is ambiguous");
230
+ C(INVALID_ARGS,"Invalid argument(s)");
231
+ C(MISSING_ARGS,"Missing argument(s)");
232
+ C(AMBIGUOUS_UUID,"Resource identifier is ambiguous");
233
+ C(UNRESOLVED_UUID,"Provided uuid/tag/branch could not be resolved");
234
+ C(RESOURCE_ALREADY_EXISTS,"Resource already exists");
235
+ C(RESOURCE_NOT_FOUND,"Resource not found");
230236
231237
C(DB,"Database error");
232238
C(STMT_PREP,"Statement preparation failed");
233239
C(STMT_BIND,"Statement parameter binding failed");
234240
C(STMT_EXEC,"Statement execution/stepping failed");
@@ -882,18 +888,18 @@
882888
if( once ){
883889
return;
884890
}else{
885891
once = 1;
886892
}
893
+ g.json.isJsonMode = 1;
894
+ g.json.resultCode = 0;
895
+ g.json.cmd.offset = -1;
887896
g.json.jsonp = PD("jsonp",NULL)
888897
/* FIXME: do some sanity checking on g.json.jsonp and ignore it
889898
if it is not halfway reasonable.
890899
*/
891900
;
892
- g.json.isJsonMode = 1;
893
- g.json.resultCode = 0;
894
- g.json.cmd.offset = -1;
895901
if( !g.isHTTP && g.fullHttpReply ){
896902
/* workaround for server mode, so we see it as CGI mode. */
897903
g.isHTTP = 1;
898904
}
899905
@@ -961,11 +967,11 @@
961967
}
962968
inFile = (0==strcmp("-",jfile))
963969
? stdin
964970
: fopen(jfile,"rb");
965971
if(!inFile){
966
- g.json.resultCode = FSL_JSON_E_UNKNOWN;
972
+ g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
967973
fossil_fatal("Could not open JSON file [%s].",jfile)
968974
/* Does not return. */
969975
;
970976
}
971977
cgi_parse_POST_JSON(inFile, 0);
@@ -1555,11 +1561,12 @@
15551561
cson_value * jv = NULL;
15561562
cson_object * jo = NULL;
15571563
cson_value * jv2 = NULL;
15581564
cson_object * jo2 = NULL;
15591565
if( !g.perm.Read ){
1560
- g.json.resultCode = FSL_JSON_E_DENIED;
1566
+ json_set_err(FSL_JSON_E_DENIED,
1567
+ "Requires 'o' permissions.");
15611568
return NULL;
15621569
}
15631570
if( g.isHTTP ){
15641571
full = json_getenv_bool("full",0);
15651572
}else{
@@ -1672,11 +1679,11 @@
16721679
cson_value * json_page_dispatch_helper(JsonPageDef const * pages){
16731680
JsonPageDef const * def;
16741681
char const * cmd = json_command_arg(1+g.json.dispatchDepth);
16751682
assert( NULL != pages );
16761683
if( ! cmd ){
1677
- g.json.resultCode = FSL_JSON_E_MISSING_ARGS;
1684
+ json_set_err(FSL_JSON_E_MISSING_ARGS, "No subcommand specified.");
16781685
return NULL;
16791686
}
16801687
def = json_handler_for_name( cmd, pages );
16811688
if(!def){
16821689
g.json.resultCode = FSL_JSON_E_UNKNOWN_COMMAND;
@@ -1700,18 +1707,21 @@
17001707
/*
17011708
** Impl of /json/rebuild. Requires admin previleges.
17021709
*/
17031710
static cson_value * json_page_rebuild(){
17041711
if( !g.perm.Admin ){
1705
- g.json.resultCode = FSL_JSON_E_DENIED;
1712
+ json_set_err(FSL_JSON_E_DENIED,"Requires 'a' privileges.");
17061713
return NULL;
17071714
}else{
1708
- /* Reminder: the db_xxx() ops "should" fail via
1709
- the fossil core error handlers, which will cause
1710
- a JSON error and exit(). i.e. we don't handle
1711
- the errors here. TODO: confirm that all these
1712
- db routine fail gracefully in JSON mode.
1715
+ /* Reminder: the db_xxx() ops "should" fail via the fossil core
1716
+ error handlers, which will cause a JSON error and exit(). i.e. we
1717
+ don't handle the errors here. TODO: confirm that all these db
1718
+ routine fail gracefully in JSON mode.
1719
+
1720
+ On large repos (e.g. fossil's) this operation is likely to take
1721
+ longer than the client timeout, which will cause it to fail (but
1722
+ it's sqlite3, so it'll fail gracefully).
17131723
*/
17141724
db_close(1);
17151725
db_open_repository(g.zRepositoryName);
17161726
db_begin_transaction();
17171727
rebuild_db(0, 0, 0);
@@ -1737,11 +1747,12 @@
17371747
" mtime AS mtime"
17381748
" FROM user ORDER BY login");
17391749
payV = json_stmt_to_array_of_obj(&q, NULL);
17401750
db_finalize(&q);
17411751
if(NULL == payV){
1742
- g.json.resultCode = FSL_JSON_E_UNKNOWN;
1752
+ json_set_err(FSL_JSON_E_UNKNOWN,
1753
+ "Could not convert user list to JSON.");
17431754
}
17441755
return payV;
17451756
}
17461757
17471758
/*
@@ -1762,11 +1773,11 @@
17621773
if we pass the name as part of the path, so we check the path
17631774
_before_ checking for name=XYZ.
17641775
*/;
17651776
}
17661777
if(!pUser || !*pUser){
1767
- g.json.resultCode = FSL_JSON_E_MISSING_ARGS;
1778
+ json_set_err(FSL_JSON_E_MISSING_ARGS,"Missing 'name' property.");
17681779
return NULL;
17691780
}
17701781
db_prepare(&q,"SELECT uid AS uid,"
17711782
" login AS name,"
17721783
" cap AS capabilities,"
@@ -1776,14 +1787,14 @@
17761787
" WHERE login=%Q",
17771788
pUser);
17781789
if( (SQLITE_ROW == db_step(&q)) ){
17791790
payV = cson_sqlite3_row_to_object(q.pStmt);
17801791
if(!payV){
1781
- g.json.resultCode = FSL_JSON_E_UNKNOWN;
1792
+ json_set_err(FSL_JSON_E_UNKNOWN,"Could not convert user row to JSON.");
17821793
}
17831794
}else{
1784
- g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
1795
+ json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,"User not found.");
17851796
}
17861797
db_finalize(&q);
17871798
return payV;
17881799
}
17891800
17901801
--- src/json.c
+++ src/json.c
@@ -206,29 +206,35 @@
206
207 C(GENERIC,"Generic error");
208 C(INVALID_REQUEST,"Invalid request");
209 C(UNKNOWN_COMMAND,"Unknown Command");
210 C(UNKNOWN,"Unknown error");
211 C(RESOURCE_NOT_FOUND,"Resource not found");
212 C(TIMEOUT,"Timeout reached");
213 C(ASSERT,"Assertion failed");
214 C(ALLOC,"Resource allocation failed");
215 C(NYI,"Not yet implemented");
 
 
 
 
216 C(AUTH,"Authentication error");
 
 
 
217 C(LOGIN_FAILED,"Login failed");
218 C(LOGIN_FAILED_NOSEED,"Anonymous login attempt was missing password seed");
219 C(LOGIN_FAILED_NONAME,"Login failed - name not supplied");
220 C(LOGIN_FAILED_NOPW,"Login failed - password not supplied");
221 C(LOGIN_FAILED_NOTFOUND,"Login failed - no match found");
222 C(MISSING_AUTH,"Authentication info missing from request");
223 C(DENIED,"Access denied");
224 C(WRONG_MODE,"Request not allowed (wrong operation mode)");
225
226 C(USAGE,"Usage error");
227 C(INVALID_ARGS,"Invalid arguments");
228 C(MISSING_ARGS,"Missing arguments");
229 C(AMBIGUOUS_UUID,"Argument is ambiguous");
 
 
 
230
231 C(DB,"Database error");
232 C(STMT_PREP,"Statement preparation failed");
233 C(STMT_BIND,"Statement parameter binding failed");
234 C(STMT_EXEC,"Statement execution/stepping failed");
@@ -882,18 +888,18 @@
882 if( once ){
883 return;
884 }else{
885 once = 1;
886 }
 
 
 
887 g.json.jsonp = PD("jsonp",NULL)
888 /* FIXME: do some sanity checking on g.json.jsonp and ignore it
889 if it is not halfway reasonable.
890 */
891 ;
892 g.json.isJsonMode = 1;
893 g.json.resultCode = 0;
894 g.json.cmd.offset = -1;
895 if( !g.isHTTP && g.fullHttpReply ){
896 /* workaround for server mode, so we see it as CGI mode. */
897 g.isHTTP = 1;
898 }
899
@@ -961,11 +967,11 @@
961 }
962 inFile = (0==strcmp("-",jfile))
963 ? stdin
964 : fopen(jfile,"rb");
965 if(!inFile){
966 g.json.resultCode = FSL_JSON_E_UNKNOWN;
967 fossil_fatal("Could not open JSON file [%s].",jfile)
968 /* Does not return. */
969 ;
970 }
971 cgi_parse_POST_JSON(inFile, 0);
@@ -1555,11 +1561,12 @@
1555 cson_value * jv = NULL;
1556 cson_object * jo = NULL;
1557 cson_value * jv2 = NULL;
1558 cson_object * jo2 = NULL;
1559 if( !g.perm.Read ){
1560 g.json.resultCode = FSL_JSON_E_DENIED;
 
1561 return NULL;
1562 }
1563 if( g.isHTTP ){
1564 full = json_getenv_bool("full",0);
1565 }else{
@@ -1672,11 +1679,11 @@
1672 cson_value * json_page_dispatch_helper(JsonPageDef const * pages){
1673 JsonPageDef const * def;
1674 char const * cmd = json_command_arg(1+g.json.dispatchDepth);
1675 assert( NULL != pages );
1676 if( ! cmd ){
1677 g.json.resultCode = FSL_JSON_E_MISSING_ARGS;
1678 return NULL;
1679 }
1680 def = json_handler_for_name( cmd, pages );
1681 if(!def){
1682 g.json.resultCode = FSL_JSON_E_UNKNOWN_COMMAND;
@@ -1700,18 +1707,21 @@
1700 /*
1701 ** Impl of /json/rebuild. Requires admin previleges.
1702 */
1703 static cson_value * json_page_rebuild(){
1704 if( !g.perm.Admin ){
1705 g.json.resultCode = FSL_JSON_E_DENIED;
1706 return NULL;
1707 }else{
1708 /* Reminder: the db_xxx() ops "should" fail via
1709 the fossil core error handlers, which will cause
1710 a JSON error and exit(). i.e. we don't handle
1711 the errors here. TODO: confirm that all these
1712 db routine fail gracefully in JSON mode.
 
 
 
1713 */
1714 db_close(1);
1715 db_open_repository(g.zRepositoryName);
1716 db_begin_transaction();
1717 rebuild_db(0, 0, 0);
@@ -1737,11 +1747,12 @@
1737 " mtime AS mtime"
1738 " FROM user ORDER BY login");
1739 payV = json_stmt_to_array_of_obj(&q, NULL);
1740 db_finalize(&q);
1741 if(NULL == payV){
1742 g.json.resultCode = FSL_JSON_E_UNKNOWN;
 
1743 }
1744 return payV;
1745 }
1746
1747 /*
@@ -1762,11 +1773,11 @@
1762 if we pass the name as part of the path, so we check the path
1763 _before_ checking for name=XYZ.
1764 */;
1765 }
1766 if(!pUser || !*pUser){
1767 g.json.resultCode = FSL_JSON_E_MISSING_ARGS;
1768 return NULL;
1769 }
1770 db_prepare(&q,"SELECT uid AS uid,"
1771 " login AS name,"
1772 " cap AS capabilities,"
@@ -1776,14 +1787,14 @@
1776 " WHERE login=%Q",
1777 pUser);
1778 if( (SQLITE_ROW == db_step(&q)) ){
1779 payV = cson_sqlite3_row_to_object(q.pStmt);
1780 if(!payV){
1781 g.json.resultCode = FSL_JSON_E_UNKNOWN;
1782 }
1783 }else{
1784 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
1785 }
1786 db_finalize(&q);
1787 return payV;
1788 }
1789
1790
--- src/json.c
+++ src/json.c
@@ -206,29 +206,35 @@
206
207 C(GENERIC,"Generic error");
208 C(INVALID_REQUEST,"Invalid request");
209 C(UNKNOWN_COMMAND,"Unknown Command");
210 C(UNKNOWN,"Unknown error");
 
211 C(TIMEOUT,"Timeout reached");
212 C(ASSERT,"Assertion failed");
213 C(ALLOC,"Resource allocation failed");
214 C(NYI,"Not yet implemented");
215 C(PANIC,"x");
216 C(MANIFEST_READ_FAILED,"Reading artifact manifest failed.");
217 C(FILE_OPEN_FAILED,"Opening file failed.");
218
219 C(AUTH,"Authentication error");
220 C(MISSING_AUTH,"Authentication info missing from request");
221 C(DENIED,"Access denied");
222 C(WRONG_MODE,"Request not allowed (wrong operation mode)");
223 C(LOGIN_FAILED,"Login failed");
224 C(LOGIN_FAILED_NOSEED,"Anonymous login attempt was missing password seed");
225 C(LOGIN_FAILED_NONAME,"Login failed - name not supplied");
226 C(LOGIN_FAILED_NOPW,"Login failed - password not supplied");
227 C(LOGIN_FAILED_NOTFOUND,"Login failed - no match found");
 
 
 
228
229 C(USAGE,"Usage error");
230 C(INVALID_ARGS,"Invalid argument(s)");
231 C(MISSING_ARGS,"Missing argument(s)");
232 C(AMBIGUOUS_UUID,"Resource identifier is ambiguous");
233 C(UNRESOLVED_UUID,"Provided uuid/tag/branch could not be resolved");
234 C(RESOURCE_ALREADY_EXISTS,"Resource already exists");
235 C(RESOURCE_NOT_FOUND,"Resource not found");
236
237 C(DB,"Database error");
238 C(STMT_PREP,"Statement preparation failed");
239 C(STMT_BIND,"Statement parameter binding failed");
240 C(STMT_EXEC,"Statement execution/stepping failed");
@@ -882,18 +888,18 @@
888 if( once ){
889 return;
890 }else{
891 once = 1;
892 }
893 g.json.isJsonMode = 1;
894 g.json.resultCode = 0;
895 g.json.cmd.offset = -1;
896 g.json.jsonp = PD("jsonp",NULL)
897 /* FIXME: do some sanity checking on g.json.jsonp and ignore it
898 if it is not halfway reasonable.
899 */
900 ;
 
 
 
901 if( !g.isHTTP && g.fullHttpReply ){
902 /* workaround for server mode, so we see it as CGI mode. */
903 g.isHTTP = 1;
904 }
905
@@ -961,11 +967,11 @@
967 }
968 inFile = (0==strcmp("-",jfile))
969 ? stdin
970 : fopen(jfile,"rb");
971 if(!inFile){
972 g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
973 fossil_fatal("Could not open JSON file [%s].",jfile)
974 /* Does not return. */
975 ;
976 }
977 cgi_parse_POST_JSON(inFile, 0);
@@ -1555,11 +1561,12 @@
1561 cson_value * jv = NULL;
1562 cson_object * jo = NULL;
1563 cson_value * jv2 = NULL;
1564 cson_object * jo2 = NULL;
1565 if( !g.perm.Read ){
1566 json_set_err(FSL_JSON_E_DENIED,
1567 "Requires 'o' permissions.");
1568 return NULL;
1569 }
1570 if( g.isHTTP ){
1571 full = json_getenv_bool("full",0);
1572 }else{
@@ -1672,11 +1679,11 @@
1679 cson_value * json_page_dispatch_helper(JsonPageDef const * pages){
1680 JsonPageDef const * def;
1681 char const * cmd = json_command_arg(1+g.json.dispatchDepth);
1682 assert( NULL != pages );
1683 if( ! cmd ){
1684 json_set_err(FSL_JSON_E_MISSING_ARGS, "No subcommand specified.");
1685 return NULL;
1686 }
1687 def = json_handler_for_name( cmd, pages );
1688 if(!def){
1689 g.json.resultCode = FSL_JSON_E_UNKNOWN_COMMAND;
@@ -1700,18 +1707,21 @@
1707 /*
1708 ** Impl of /json/rebuild. Requires admin previleges.
1709 */
1710 static cson_value * json_page_rebuild(){
1711 if( !g.perm.Admin ){
1712 json_set_err(FSL_JSON_E_DENIED,"Requires 'a' privileges.");
1713 return NULL;
1714 }else{
1715 /* Reminder: the db_xxx() ops "should" fail via the fossil core
1716 error handlers, which will cause a JSON error and exit(). i.e. we
1717 don't handle the errors here. TODO: confirm that all these db
1718 routine fail gracefully in JSON mode.
1719
1720 On large repos (e.g. fossil's) this operation is likely to take
1721 longer than the client timeout, which will cause it to fail (but
1722 it's sqlite3, so it'll fail gracefully).
1723 */
1724 db_close(1);
1725 db_open_repository(g.zRepositoryName);
1726 db_begin_transaction();
1727 rebuild_db(0, 0, 0);
@@ -1737,11 +1747,12 @@
1747 " mtime AS mtime"
1748 " FROM user ORDER BY login");
1749 payV = json_stmt_to_array_of_obj(&q, NULL);
1750 db_finalize(&q);
1751 if(NULL == payV){
1752 json_set_err(FSL_JSON_E_UNKNOWN,
1753 "Could not convert user list to JSON.");
1754 }
1755 return payV;
1756 }
1757
1758 /*
@@ -1762,11 +1773,11 @@
1773 if we pass the name as part of the path, so we check the path
1774 _before_ checking for name=XYZ.
1775 */;
1776 }
1777 if(!pUser || !*pUser){
1778 json_set_err(FSL_JSON_E_MISSING_ARGS,"Missing 'name' property.");
1779 return NULL;
1780 }
1781 db_prepare(&q,"SELECT uid AS uid,"
1782 " login AS name,"
1783 " cap AS capabilities,"
@@ -1776,14 +1787,14 @@
1787 " WHERE login=%Q",
1788 pUser);
1789 if( (SQLITE_ROW == db_step(&q)) ){
1790 payV = cson_sqlite3_row_to_object(q.pStmt);
1791 if(!payV){
1792 json_set_err(FSL_JSON_E_UNKNOWN,"Could not convert user row to JSON.");
1793 }
1794 }else{
1795 json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,"User not found.");
1796 }
1797 db_finalize(&q);
1798 return payV;
1799 }
1800
1801
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -169,11 +169,11 @@
169169
json_gc_add("$EVENT_TYPE_LABEL(ticket)", eventTypeLabel, 1);
170170
}
171171
172172
pTktChng = manifest_get(rid, CFTYPE_TICKET);
173173
if( pTktChng==0 ){
174
- g.json.resultCode = FSL_JSON_E_UNKNOWN;
174
+ g.json.resultCode = FSL_JSON_E_MANIFEST_READ_FAILED;
175175
return NULL;
176176
}
177177
payV = cson_value_new_object();
178178
pay = cson_value_get_object(payV);
179179
cson_object_set(pay, "eventType", eventTypeLabel );
180180
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -169,11 +169,11 @@
169 json_gc_add("$EVENT_TYPE_LABEL(ticket)", eventTypeLabel, 1);
170 }
171
172 pTktChng = manifest_get(rid, CFTYPE_TICKET);
173 if( pTktChng==0 ){
174 g.json.resultCode = FSL_JSON_E_UNKNOWN;
175 return NULL;
176 }
177 payV = cson_value_new_object();
178 pay = cson_value_get_object(payV);
179 cson_object_set(pay, "eventType", eventTypeLabel );
180
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -169,11 +169,11 @@
169 json_gc_add("$EVENT_TYPE_LABEL(ticket)", eventTypeLabel, 1);
170 }
171
172 pTktChng = manifest_get(rid, CFTYPE_TICKET);
173 if( pTktChng==0 ){
174 g.json.resultCode = FSL_JSON_E_MANIFEST_READ_FAILED;
175 return NULL;
176 }
177 payV = cson_value_new_object();
178 pay = cson_value_get_object(payV);
179 cson_object_set(pay, "eventType", eventTypeLabel );
180
+34 -31
--- src/json_detail.h
+++ src/json_detail.h
@@ -36,51 +36,54 @@
3636
** value.
3737
**
3838
*/
3939
enum FossilJsonCodes {
4040
FSL_JSON_W_START = 0,
41
-FSL_JSON_W_UNKNOWN = FSL_JSON_W_START + 1,
42
-FSL_JSON_W_ROW_TO_JSON_FAILED = FSL_JSON_W_START + 2,
43
-FSL_JSON_W_COL_TO_JSON_FAILED = FSL_JSON_W_START + 3,
44
-FSL_JSON_W_STRING_TO_ARRAY_FAILED = FSL_JSON_W_START + 4,
41
+FSL_JSON_W_UNKNOWN /*+1*/,
42
+FSL_JSON_W_ROW_TO_JSON_FAILED /*+2*/,
43
+FSL_JSON_W_COL_TO_JSON_FAILED /*+3*/,
44
+FSL_JSON_W_STRING_TO_ARRAY_FAILED /*+4*/,
4545
4646
FSL_JSON_W_END = 1000,
4747
FSL_JSON_E_GENERIC = 1000,
4848
FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
49
-FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC_SUB1 + 1,
50
-FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC_SUB1 + 2,
51
-FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC_SUB1 + 3,
52
-FSL_JSON_E_RESOURCE_NOT_FOUND = FSL_JSON_E_GENERIC_SUB1 + 4,
53
-FSL_JSON_E_TIMEOUT = FSL_JSON_E_GENERIC_SUB1 + 5,
54
-FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC_SUB1 + 6,
55
-FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC_SUB1 + 7,
56
-FSL_JSON_E_NYI = FSL_JSON_E_GENERIC_SUB1 + 8,
57
-FSL_JSON_E_PANIC = FSL_JSON_E_GENERIC_SUB1 + 9,
49
+FSL_JSON_E_INVALID_REQUEST /*+1*/,
50
+FSL_JSON_E_UNKNOWN_COMMAND /*+2*/,
51
+FSL_JSON_E_UNKNOWN /*+3*/,
52
+/*REUSE: +4*/
53
+FSL_JSON_E_TIMEOUT /*+5*/,
54
+FSL_JSON_E_ASSERT /*+6*/,
55
+FSL_JSON_E_ALLOC /*+7*/,
56
+FSL_JSON_E_NYI /*+8*/,
57
+FSL_JSON_E_PANIC /*+9*/,
58
+FSL_JSON_E_MANIFEST_READ_FAILED /*+10*/,
59
+FSL_JSON_E_FILE_OPEN_FAILED /*+11*/,
5860
5961
FSL_JSON_E_AUTH = 2000,
60
-FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 1,
61
-FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 2,
62
-FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 3,
63
-FSL_JSON_E_RESOURCE_ALREADY_EXISTS = FSL_JSON_E_AUTH + 4,
64
-
65
-FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,
66
-FSL_JSON_E_LOGIN_FAILED_NOSEED = FSL_JSON_E_LOGIN_FAILED + 1,
67
-FSL_JSON_E_LOGIN_FAILED_NONAME = FSL_JSON_E_LOGIN_FAILED + 2,
68
-FSL_JSON_E_LOGIN_FAILED_NOPW = FSL_JSON_E_LOGIN_FAILED + 3,
69
-FSL_JSON_E_LOGIN_FAILED_NOTFOUND = FSL_JSON_E_LOGIN_FAILED + 4,
62
+FSL_JSON_E_MISSING_AUTH /*+1*/,
63
+FSL_JSON_E_DENIED /*+2*/,
64
+FSL_JSON_E_WRONG_MODE /*+3*/,
65
+
66
+FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH +100,
67
+FSL_JSON_E_LOGIN_FAILED_NOSEED /*+1*/,
68
+FSL_JSON_E_LOGIN_FAILED_NONAME /*+2*/,
69
+FSL_JSON_E_LOGIN_FAILED_NOPW /*+3*/,
70
+FSL_JSON_E_LOGIN_FAILED_NOTFOUND /*+4*/,
7071
7172
FSL_JSON_E_USAGE = 3000,
72
-FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
73
-FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,
74
-FSL_JSON_E_AMBIGUOUS_UUID = FSL_JSON_E_USAGE + 3,
75
-
73
+FSL_JSON_E_INVALID_ARGS /*+1*/,
74
+FSL_JSON_E_MISSING_ARGS /*+2*/,
75
+FSL_JSON_E_AMBIGUOUS_UUID /*+3*/,
76
+FSL_JSON_E_UNRESOLVED_UUID /*+4*/,
77
+FSL_JSON_E_RESOURCE_ALREADY_EXISTS /*+5*/,
78
+FSL_JSON_E_RESOURCE_NOT_FOUND /*+6*/,
7679
7780
FSL_JSON_E_DB = 4000,
78
-FSL_JSON_E_STMT_PREP = FSL_JSON_E_DB + 1,
79
-FSL_JSON_E_STMT_BIND = FSL_JSON_E_DB + 2,
80
-FSL_JSON_E_STMT_EXEC = FSL_JSON_E_DB + 3,
81
-FSL_JSON_E_DB_LOCKED = FSL_JSON_E_DB + 4,
81
+FSL_JSON_E_STMT_PREP /*+1*/,
82
+FSL_JSON_E_STMT_BIND /*+2*/,
83
+FSL_JSON_E_STMT_EXEC /*+3*/,
84
+FSL_JSON_E_DB_LOCKED /*+4*/,
8285
8386
FSL_JSON_E_DB_NEEDS_REBUILD = FSL_JSON_E_DB + 101
8487
8588
};
8689
8790
--- src/json_detail.h
+++ src/json_detail.h
@@ -36,51 +36,54 @@
36 ** value.
37 **
38 */
39 enum FossilJsonCodes {
40 FSL_JSON_W_START = 0,
41 FSL_JSON_W_UNKNOWN = FSL_JSON_W_START + 1,
42 FSL_JSON_W_ROW_TO_JSON_FAILED = FSL_JSON_W_START + 2,
43 FSL_JSON_W_COL_TO_JSON_FAILED = FSL_JSON_W_START + 3,
44 FSL_JSON_W_STRING_TO_ARRAY_FAILED = FSL_JSON_W_START + 4,
45
46 FSL_JSON_W_END = 1000,
47 FSL_JSON_E_GENERIC = 1000,
48 FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
49 FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC_SUB1 + 1,
50 FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC_SUB1 + 2,
51 FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC_SUB1 + 3,
52 FSL_JSON_E_RESOURCE_NOT_FOUND = FSL_JSON_E_GENERIC_SUB1 + 4,
53 FSL_JSON_E_TIMEOUT = FSL_JSON_E_GENERIC_SUB1 + 5,
54 FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC_SUB1 + 6,
55 FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC_SUB1 + 7,
56 FSL_JSON_E_NYI = FSL_JSON_E_GENERIC_SUB1 + 8,
57 FSL_JSON_E_PANIC = FSL_JSON_E_GENERIC_SUB1 + 9,
 
 
58
59 FSL_JSON_E_AUTH = 2000,
60 FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 1,
61 FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 2,
62 FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 3,
63 FSL_JSON_E_RESOURCE_ALREADY_EXISTS = FSL_JSON_E_AUTH + 4,
64
65 FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,
66 FSL_JSON_E_LOGIN_FAILED_NOSEED = FSL_JSON_E_LOGIN_FAILED + 1,
67 FSL_JSON_E_LOGIN_FAILED_NONAME = FSL_JSON_E_LOGIN_FAILED + 2,
68 FSL_JSON_E_LOGIN_FAILED_NOPW = FSL_JSON_E_LOGIN_FAILED + 3,
69 FSL_JSON_E_LOGIN_FAILED_NOTFOUND = FSL_JSON_E_LOGIN_FAILED + 4,
70
71 FSL_JSON_E_USAGE = 3000,
72 FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
73 FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,
74 FSL_JSON_E_AMBIGUOUS_UUID = FSL_JSON_E_USAGE + 3,
75
 
 
76
77 FSL_JSON_E_DB = 4000,
78 FSL_JSON_E_STMT_PREP = FSL_JSON_E_DB + 1,
79 FSL_JSON_E_STMT_BIND = FSL_JSON_E_DB + 2,
80 FSL_JSON_E_STMT_EXEC = FSL_JSON_E_DB + 3,
81 FSL_JSON_E_DB_LOCKED = FSL_JSON_E_DB + 4,
82
83 FSL_JSON_E_DB_NEEDS_REBUILD = FSL_JSON_E_DB + 101
84
85 };
86
87
--- src/json_detail.h
+++ src/json_detail.h
@@ -36,51 +36,54 @@
36 ** value.
37 **
38 */
39 enum FossilJsonCodes {
40 FSL_JSON_W_START = 0,
41 FSL_JSON_W_UNKNOWN /*+1*/,
42 FSL_JSON_W_ROW_TO_JSON_FAILED /*+2*/,
43 FSL_JSON_W_COL_TO_JSON_FAILED /*+3*/,
44 FSL_JSON_W_STRING_TO_ARRAY_FAILED /*+4*/,
45
46 FSL_JSON_W_END = 1000,
47 FSL_JSON_E_GENERIC = 1000,
48 FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
49 FSL_JSON_E_INVALID_REQUEST /*+1*/,
50 FSL_JSON_E_UNKNOWN_COMMAND /*+2*/,
51 FSL_JSON_E_UNKNOWN /*+3*/,
52 /*REUSE: +4*/
53 FSL_JSON_E_TIMEOUT /*+5*/,
54 FSL_JSON_E_ASSERT /*+6*/,
55 FSL_JSON_E_ALLOC /*+7*/,
56 FSL_JSON_E_NYI /*+8*/,
57 FSL_JSON_E_PANIC /*+9*/,
58 FSL_JSON_E_MANIFEST_READ_FAILED /*+10*/,
59 FSL_JSON_E_FILE_OPEN_FAILED /*+11*/,
60
61 FSL_JSON_E_AUTH = 2000,
62 FSL_JSON_E_MISSING_AUTH /*+1*/,
63 FSL_JSON_E_DENIED /*+2*/,
64 FSL_JSON_E_WRONG_MODE /*+3*/,
65
66 FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH +100,
67 FSL_JSON_E_LOGIN_FAILED_NOSEED /*+1*/,
68 FSL_JSON_E_LOGIN_FAILED_NONAME /*+2*/,
69 FSL_JSON_E_LOGIN_FAILED_NOPW /*+3*/,
70 FSL_JSON_E_LOGIN_FAILED_NOTFOUND /*+4*/,
 
71
72 FSL_JSON_E_USAGE = 3000,
73 FSL_JSON_E_INVALID_ARGS /*+1*/,
74 FSL_JSON_E_MISSING_ARGS /*+2*/,
75 FSL_JSON_E_AMBIGUOUS_UUID /*+3*/,
76 FSL_JSON_E_UNRESOLVED_UUID /*+4*/,
77 FSL_JSON_E_RESOURCE_ALREADY_EXISTS /*+5*/,
78 FSL_JSON_E_RESOURCE_NOT_FOUND /*+6*/,
79
80 FSL_JSON_E_DB = 4000,
81 FSL_JSON_E_STMT_PREP /*+1*/,
82 FSL_JSON_E_STMT_BIND /*+2*/,
83 FSL_JSON_E_STMT_EXEC /*+3*/,
84 FSL_JSON_E_DB_LOCKED /*+4*/,
85
86 FSL_JSON_E_DB_NEEDS_REBUILD = FSL_JSON_E_DB + 101
87
88 };
89
90
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -401,18 +401,20 @@
401401
}
402402
payV = cson_value_new_object();
403403
pay = cson_value_get_object(payV);
404404
check = json_timeline_setup_sql( "ci", &sql, pay );
405405
if(check){
406
- g.json.resultCode = check;
406
+ json_set_err(check, "Query initialization failed.");
407407
goto error;
408408
}
409409
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
410
- g.json.resultCode = (cson_rc.AllocError==check) \
411
- ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN; \
410
+ json_set_err((cson_rc.AllocError==check) \
411
+ ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN,\
412
+ "Object property insertion failed"); \
412413
goto error;\
413
- }
414
+ } (void)0
415
+
414416
#if 0
415417
/* only for testing! */
416418
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
417419
SET("timelineSql");
418420
#endif
@@ -489,19 +491,20 @@
489491
}
490492
payV = cson_value_new_object();
491493
pay = cson_value_get_object(payV);
492494
check = json_timeline_setup_sql( "w", &sql, pay );
493495
if(check){
494
- g.json.resultCode = check;
496
+ json_set_err(check, "Query initialization failed.");
495497
goto error;
496498
}
497499
498500
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
499
- g.json.resultCode = (cson_rc.AllocError==check) \
500
- ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN; \
501
+ json_set_err((cson_rc.AllocError==check) \
502
+ ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
503
+ "Object property insertion failed."); \
501504
goto error;\
502
- }
505
+ } (void)0
503506
#if 0
504507
/* only for testing! */
505508
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
506509
SET("timelineSql");
507510
#endif
@@ -562,28 +565,34 @@
562565
}
563566
payV = cson_value_new_object();
564567
pay = cson_value_get_object(payV);
565568
check = json_timeline_setup_sql( "t", &sql, pay );
566569
if(check){
567
- g.json.resultCode = check;
570
+ json_set_err(check, "Query initialization failed.");
568571
goto error;
569572
}
570573
571574
db_multi_exec(blob_buffer(&sql));
572575
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
573
- g.json.resultCode = (cson_rc.AllocError==check) \
574
- ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN; \
576
+ json_set_err((cson_rc.AllocError==check) \
577
+ ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
578
+ "Object property insertion failed."); \
575579
goto error;\
576
- }
580
+ } (void)0
577581
578582
#if 0
579583
/* only for testing! */
580584
tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
581585
SET("timelineSql");
582586
#endif
583587
584588
blob_reset(&sql);
589
+ /*
590
+ REMINDER/FIXME(?): we have both uuid (the change uuid?) and
591
+ ticketUuid (the actual ticket). This is different from the wiki
592
+ timeline, where we only have the wiki page uuid.
593
+ */
585594
db_prepare(&q, "SELECT rid AS rid,"
586595
" uuid AS uuid,"
587596
" mtime AS timestamp,"
588597
#if 0
589598
" timestampString AS timestampString,"
590599
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -401,18 +401,20 @@
401 }
402 payV = cson_value_new_object();
403 pay = cson_value_get_object(payV);
404 check = json_timeline_setup_sql( "ci", &sql, pay );
405 if(check){
406 g.json.resultCode = check;
407 goto error;
408 }
409 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
410 g.json.resultCode = (cson_rc.AllocError==check) \
411 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN; \
 
412 goto error;\
413 }
 
414 #if 0
415 /* only for testing! */
416 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
417 SET("timelineSql");
418 #endif
@@ -489,19 +491,20 @@
489 }
490 payV = cson_value_new_object();
491 pay = cson_value_get_object(payV);
492 check = json_timeline_setup_sql( "w", &sql, pay );
493 if(check){
494 g.json.resultCode = check;
495 goto error;
496 }
497
498 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
499 g.json.resultCode = (cson_rc.AllocError==check) \
500 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN; \
 
501 goto error;\
502 }
503 #if 0
504 /* only for testing! */
505 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
506 SET("timelineSql");
507 #endif
@@ -562,28 +565,34 @@
562 }
563 payV = cson_value_new_object();
564 pay = cson_value_get_object(payV);
565 check = json_timeline_setup_sql( "t", &sql, pay );
566 if(check){
567 g.json.resultCode = check;
568 goto error;
569 }
570
571 db_multi_exec(blob_buffer(&sql));
572 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
573 g.json.resultCode = (cson_rc.AllocError==check) \
574 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN; \
 
575 goto error;\
576 }
577
578 #if 0
579 /* only for testing! */
580 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
581 SET("timelineSql");
582 #endif
583
584 blob_reset(&sql);
 
 
 
 
 
585 db_prepare(&q, "SELECT rid AS rid,"
586 " uuid AS uuid,"
587 " mtime AS timestamp,"
588 #if 0
589 " timestampString AS timestampString,"
590
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -401,18 +401,20 @@
401 }
402 payV = cson_value_new_object();
403 pay = cson_value_get_object(payV);
404 check = json_timeline_setup_sql( "ci", &sql, pay );
405 if(check){
406 json_set_err(check, "Query initialization failed.");
407 goto error;
408 }
409 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
410 json_set_err((cson_rc.AllocError==check) \
411 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN,\
412 "Object property insertion failed"); \
413 goto error;\
414 } (void)0
415
416 #if 0
417 /* only for testing! */
418 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
419 SET("timelineSql");
420 #endif
@@ -489,19 +491,20 @@
491 }
492 payV = cson_value_new_object();
493 pay = cson_value_get_object(payV);
494 check = json_timeline_setup_sql( "w", &sql, pay );
495 if(check){
496 json_set_err(check, "Query initialization failed.");
497 goto error;
498 }
499
500 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
501 json_set_err((cson_rc.AllocError==check) \
502 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
503 "Object property insertion failed."); \
504 goto error;\
505 } (void)0
506 #if 0
507 /* only for testing! */
508 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
509 SET("timelineSql");
510 #endif
@@ -562,28 +565,34 @@
565 }
566 payV = cson_value_new_object();
567 pay = cson_value_get_object(payV);
568 check = json_timeline_setup_sql( "t", &sql, pay );
569 if(check){
570 json_set_err(check, "Query initialization failed.");
571 goto error;
572 }
573
574 db_multi_exec(blob_buffer(&sql));
575 #define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
576 json_set_err((cson_rc.AllocError==check) \
577 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN, \
578 "Object property insertion failed."); \
579 goto error;\
580 } (void)0
581
582 #if 0
583 /* only for testing! */
584 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
585 SET("timelineSql");
586 #endif
587
588 blob_reset(&sql);
589 /*
590 REMINDER/FIXME(?): we have both uuid (the change uuid?) and
591 ticketUuid (the actual ticket). This is different from the wiki
592 timeline, where we only have the wiki page uuid.
593 */
594 db_prepare(&q, "SELECT rid AS rid,"
595 " uuid AS uuid,"
596 " mtime AS timestamp,"
597 #if 0
598 " timestampString AS timestampString,"
599
+76 -62
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -47,10 +47,79 @@
4747
*/
4848
cson_value * json_page_wiki(){
4949
return json_page_dispatch_helper(&JsonPageDefs_Wiki[0]);
5050
}
5151
52
+
53
+/*
54
+** Loads the given wiki page and creates a JSON object representation
55
+** of it. If the page is not found then NULL is returned. If doParse
56
+** is true then the page content is HTML-ized using fossil's
57
+** conventional wiki format, else it is not parsed.
58
+**
59
+** The returned value, if not NULL, is-a JSON Object owned by the
60
+** caller.
61
+*/
62
+cson_value * json_get_wiki_page(char const * zPageName, char doParse){
63
+ int rid;
64
+ Manifest *pWiki = 0;
65
+ char const * zBody = NULL;
66
+ char const * zFormat = NULL;
67
+ char * zUuid = NULL;
68
+ Stmt q;
69
+ db_prepare(&q,
70
+ "SELECT x.rid, b.uuid FROM tag t, tagxref x, blob b"
71
+ " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' "
72
+ " AND b.rid=x.rid"
73
+ " ORDER BY x.mtime DESC LIMIT 1",
74
+ zPageName
75
+ );
76
+ if( (SQLITE_ROW != db_step(&q)) ){
77
+ return NULL;
78
+ }
79
+ rid = db_column_int(&q,0);
80
+ zUuid = db_column_malloc(&q,1);
81
+ db_finalize(&q);
82
+ if( (pWiki = manifest_get(rid, CFTYPE_WIKI))!=0 ){
83
+ zBody = pWiki->zWiki;
84
+ }
85
+
86
+ {
87
+ unsigned int len;
88
+ cson_value * payV = cson_value_new_object();
89
+ cson_object * pay = cson_value_get_object(payV);
90
+ cson_object_set(pay,"name",json_new_string(zPageName));
91
+ cson_object_set(pay,"uuid",json_new_string(zUuid));
92
+ free(zUuid);
93
+ zUuid = NULL;
94
+ cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));
95
+ cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
96
+ cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
97
+ cson_object_set(pay,"contentFormat",json_new_string(zFormat));
98
+ if( doParse ){
99
+ Blob content = empty_blob;
100
+ Blob raw = empty_blob;
101
+ blob_append(&raw,zBody,-1);
102
+ wiki_convert(&raw,&content,0);
103
+ len = strlen(zBody);
104
+ len = (unsigned int)blob_size(&content);
105
+ cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
106
+ cson_object_set(pay,"content",
107
+ cson_value_new_string(blob_buffer(&content),len));
108
+ blob_reset(&content);
109
+ blob_reset(&raw);
110
+ }else{
111
+ len = zBody ? strlen(zBody) : 0;
112
+ cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
113
+ cson_object_set(pay,"content",cson_value_new_string(zBody,len));
114
+ }
115
+ /*TODO: add 'T' (tag) fields*/
116
+ /*TODO: add the 'A' card (file attachment) entries?*/
117
+ manifest_destroy(pWiki);
118
+ return payV;
119
+ }
120
+}
52121
53122
/*
54123
** Implementation of /json/wiki/get.
55124
**
56125
*/
@@ -89,72 +158,11 @@
89158
zFormat = "raw";
90159
}
91160
if( 'r' != *zFormat ){
92161
zFormat = "html";
93162
}
94
- db_prepare(&q,
95
- "SELECT x.rid, b.uuid FROM tag t, tagxref x, blob b"
96
- " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' "
97
- " AND b.rid=x.rid"
98
- " ORDER BY x.mtime DESC LIMIT 1",
99
- zPageName
100
- );
101
- if( (SQLITE_ROW != db_step(&q)) ){
102
- manifest_destroy(pWiki);
103
- json_set_err(FSL_JSON_E_UNKNOWN,
104
- "Error reading wiki page manifest.");
105
- return NULL;
106
- }
107
- rid = db_column_int(&q,0);
108
- zUuid = db_column_malloc(&q,1);
109
- db_finalize(&q);
110
-
111
- if( (pWiki = manifest_get(rid, CFTYPE_WIKI))!=0 ){
112
- zBody = pWiki->zWiki;
113
- }
114
- if( zBody==0 ){
115
- manifest_destroy(pWiki);
116
- free(zUuid);
117
- json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,
118
- "Wiki body is empty (is that possible?)");
119
- return NULL;
120
- }
121
-
122
- {
123
- unsigned int len;
124
- cson_value * payV = cson_value_new_object();
125
- cson_object * pay = cson_value_get_object(payV);
126
- cson_object_set(pay,"name",json_new_string(zPageName));
127
- cson_object_set(pay,"uuid",json_new_string(zUuid));
128
- free(zUuid);
129
- zUuid = NULL;
130
- cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));
131
- cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
132
- cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
133
- cson_object_set(pay,"contentFormat",json_new_string(zFormat));
134
- if( ('h'==*zFormat) ){
135
- Blob content = empty_blob;
136
- Blob raw = empty_blob;
137
- blob_append(&raw,zBody,-1);
138
- wiki_convert(&raw,&content,0);
139
- len = strlen(zBody);
140
- len = (unsigned int)blob_size(&content);
141
- cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
142
- cson_object_set(pay,"content",
143
- cson_value_new_string(blob_buffer(&content),len));
144
- blob_reset(&content);
145
- blob_reset(&raw);
146
- }else{
147
- len = strlen(zBody);
148
- cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
149
- cson_object_set(pay,"content",cson_value_new_string(zBody,len));
150
- }
151
- /*TODO: add 'T' (tag) fields*/
152
- /*TODO: add the 'A' card (file attachment) entries?*/
153
- manifest_destroy(pWiki);
154
- return payV;
155
- }
163
+ return json_get_wiki_page(zPageName, 'h'==*zFormat);
156164
}
157165
158166
/*
159167
** Internal impl of /wiki/save and /wiki/create. If createMode is 0
160168
** and the page already exists then a
@@ -306,21 +314,27 @@
306314
listV = cson_value_new_array();
307315
list = cson_value_get_array(listV);
308316
while( SQLITE_ROW == db_step(&q) ){
309317
cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
310318
if(!v){
319
+ json_set_err(FSL_JSON_E_UNKNOWN,
320
+ "Could not convert wiki name column to JSON.");
311321
goto error;
312322
}else if( 0 != cson_array_append( list, v ) ){
313323
cson_value_free(v);
324
+ json_set_err(FSL_JSON_E_ALLOC,"Could not append wiki page name to array.")
325
+ /* OOM (or maybe numeric overflow) are the only realistic
326
+ error codes for that particular failure.*/;
314327
goto error;
315328
}
316329
}
317330
goto end;
318331
error:
332
+ assert(0 != g.json.resultCode);
319333
cson_value_free(listV);
320334
listV = NULL;
321335
json_set_err(FSL_JSON_E_UNKNOWN,
322336
"Error creating wiki page list.");
323337
end:
324338
db_finalize(&q);
325339
return listV;
326340
}
327341
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -47,10 +47,79 @@
47 */
48 cson_value * json_page_wiki(){
49 return json_page_dispatch_helper(&JsonPageDefs_Wiki[0]);
50 }
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
53 /*
54 ** Implementation of /json/wiki/get.
55 **
56 */
@@ -89,72 +158,11 @@
89 zFormat = "raw";
90 }
91 if( 'r' != *zFormat ){
92 zFormat = "html";
93 }
94 db_prepare(&q,
95 "SELECT x.rid, b.uuid FROM tag t, tagxref x, blob b"
96 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' "
97 " AND b.rid=x.rid"
98 " ORDER BY x.mtime DESC LIMIT 1",
99 zPageName
100 );
101 if( (SQLITE_ROW != db_step(&q)) ){
102 manifest_destroy(pWiki);
103 json_set_err(FSL_JSON_E_UNKNOWN,
104 "Error reading wiki page manifest.");
105 return NULL;
106 }
107 rid = db_column_int(&q,0);
108 zUuid = db_column_malloc(&q,1);
109 db_finalize(&q);
110
111 if( (pWiki = manifest_get(rid, CFTYPE_WIKI))!=0 ){
112 zBody = pWiki->zWiki;
113 }
114 if( zBody==0 ){
115 manifest_destroy(pWiki);
116 free(zUuid);
117 json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND,
118 "Wiki body is empty (is that possible?)");
119 return NULL;
120 }
121
122 {
123 unsigned int len;
124 cson_value * payV = cson_value_new_object();
125 cson_object * pay = cson_value_get_object(payV);
126 cson_object_set(pay,"name",json_new_string(zPageName));
127 cson_object_set(pay,"uuid",json_new_string(zUuid));
128 free(zUuid);
129 zUuid = NULL;
130 cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));
131 cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
132 cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
133 cson_object_set(pay,"contentFormat",json_new_string(zFormat));
134 if( ('h'==*zFormat) ){
135 Blob content = empty_blob;
136 Blob raw = empty_blob;
137 blob_append(&raw,zBody,-1);
138 wiki_convert(&raw,&content,0);
139 len = strlen(zBody);
140 len = (unsigned int)blob_size(&content);
141 cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
142 cson_object_set(pay,"content",
143 cson_value_new_string(blob_buffer(&content),len));
144 blob_reset(&content);
145 blob_reset(&raw);
146 }else{
147 len = strlen(zBody);
148 cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
149 cson_object_set(pay,"content",cson_value_new_string(zBody,len));
150 }
151 /*TODO: add 'T' (tag) fields*/
152 /*TODO: add the 'A' card (file attachment) entries?*/
153 manifest_destroy(pWiki);
154 return payV;
155 }
156 }
157
158 /*
159 ** Internal impl of /wiki/save and /wiki/create. If createMode is 0
160 ** and the page already exists then a
@@ -306,21 +314,27 @@
306 listV = cson_value_new_array();
307 list = cson_value_get_array(listV);
308 while( SQLITE_ROW == db_step(&q) ){
309 cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
310 if(!v){
 
 
311 goto error;
312 }else if( 0 != cson_array_append( list, v ) ){
313 cson_value_free(v);
 
 
 
314 goto error;
315 }
316 }
317 goto end;
318 error:
 
319 cson_value_free(listV);
320 listV = NULL;
321 json_set_err(FSL_JSON_E_UNKNOWN,
322 "Error creating wiki page list.");
323 end:
324 db_finalize(&q);
325 return listV;
326 }
327
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -47,10 +47,79 @@
47 */
48 cson_value * json_page_wiki(){
49 return json_page_dispatch_helper(&JsonPageDefs_Wiki[0]);
50 }
51
52
53 /*
54 ** Loads the given wiki page and creates a JSON object representation
55 ** of it. If the page is not found then NULL is returned. If doParse
56 ** is true then the page content is HTML-ized using fossil's
57 ** conventional wiki format, else it is not parsed.
58 **
59 ** The returned value, if not NULL, is-a JSON Object owned by the
60 ** caller.
61 */
62 cson_value * json_get_wiki_page(char const * zPageName, char doParse){
63 int rid;
64 Manifest *pWiki = 0;
65 char const * zBody = NULL;
66 char const * zFormat = NULL;
67 char * zUuid = NULL;
68 Stmt q;
69 db_prepare(&q,
70 "SELECT x.rid, b.uuid FROM tag t, tagxref x, blob b"
71 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' "
72 " AND b.rid=x.rid"
73 " ORDER BY x.mtime DESC LIMIT 1",
74 zPageName
75 );
76 if( (SQLITE_ROW != db_step(&q)) ){
77 return NULL;
78 }
79 rid = db_column_int(&q,0);
80 zUuid = db_column_malloc(&q,1);
81 db_finalize(&q);
82 if( (pWiki = manifest_get(rid, CFTYPE_WIKI))!=0 ){
83 zBody = pWiki->zWiki;
84 }
85
86 {
87 unsigned int len;
88 cson_value * payV = cson_value_new_object();
89 cson_object * pay = cson_value_get_object(payV);
90 cson_object_set(pay,"name",json_new_string(zPageName));
91 cson_object_set(pay,"uuid",json_new_string(zUuid));
92 free(zUuid);
93 zUuid = NULL;
94 cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));
95 cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
96 cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
97 cson_object_set(pay,"contentFormat",json_new_string(zFormat));
98 if( doParse ){
99 Blob content = empty_blob;
100 Blob raw = empty_blob;
101 blob_append(&raw,zBody,-1);
102 wiki_convert(&raw,&content,0);
103 len = strlen(zBody);
104 len = (unsigned int)blob_size(&content);
105 cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
106 cson_object_set(pay,"content",
107 cson_value_new_string(blob_buffer(&content),len));
108 blob_reset(&content);
109 blob_reset(&raw);
110 }else{
111 len = zBody ? strlen(zBody) : 0;
112 cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len));
113 cson_object_set(pay,"content",cson_value_new_string(zBody,len));
114 }
115 /*TODO: add 'T' (tag) fields*/
116 /*TODO: add the 'A' card (file attachment) entries?*/
117 manifest_destroy(pWiki);
118 return payV;
119 }
120 }
121
122 /*
123 ** Implementation of /json/wiki/get.
124 **
125 */
@@ -89,72 +158,11 @@
158 zFormat = "raw";
159 }
160 if( 'r' != *zFormat ){
161 zFormat = "html";
162 }
163 return json_get_wiki_page(zPageName, 'h'==*zFormat);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164 }
165
166 /*
167 ** Internal impl of /wiki/save and /wiki/create. If createMode is 0
168 ** and the page already exists then a
@@ -306,21 +314,27 @@
314 listV = cson_value_new_array();
315 list = cson_value_get_array(listV);
316 while( SQLITE_ROW == db_step(&q) ){
317 cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
318 if(!v){
319 json_set_err(FSL_JSON_E_UNKNOWN,
320 "Could not convert wiki name column to JSON.");
321 goto error;
322 }else if( 0 != cson_array_append( list, v ) ){
323 cson_value_free(v);
324 json_set_err(FSL_JSON_E_ALLOC,"Could not append wiki page name to array.")
325 /* OOM (or maybe numeric overflow) are the only realistic
326 error codes for that particular failure.*/;
327 goto error;
328 }
329 }
330 goto end;
331 error:
332 assert(0 != g.json.resultCode);
333 cson_value_free(listV);
334 listV = NULL;
335 json_set_err(FSL_JSON_E_UNKNOWN,
336 "Error creating wiki page list.");
337 end:
338 db_finalize(&q);
339 return listV;
340 }
341

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button