Fossil SCM
/json/wiki/get now supports uuid=string option to specify a specific version of the page. Response now includes the parent version's uuid.
Commit
6f2a51602e19356ff8c997cc44d1a97b332c07aa
Parent
7830e2cc0f175cf…
2 files changed
+31
-3
+1
-1
+31
-3
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -86,10 +86,15 @@ | ||
| 86 | 86 | ); |
| 87 | 87 | cson_object_set(pay,"name",json_new_string(pWiki->zWikiTitle)); |
| 88 | 88 | cson_object_set(pay,"uuid",json_new_string(zUuid)); |
| 89 | 89 | free(zUuid); |
| 90 | 90 | zUuid = NULL; |
| 91 | + if( pWiki->nParent > 0 ){ | |
| 92 | + cson_object_set( pay, "parent", json_new_string(pWiki->azParent[0]) ) | |
| 93 | + /* Reminder: wiki pages do not branch and have only one parent | |
| 94 | + (except for the initial version, which has no parents). */; | |
| 95 | + } | |
| 91 | 96 | /*cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));*/ |
| 92 | 97 | cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser)); |
| 93 | 98 | cson_object_set(pay,FossilJsonKeys.timestamp, |
| 94 | 99 | json_julian_to_timestamp(pWiki->rDate)); |
| 95 | 100 | if(0 == contentFormat){ |
| @@ -184,10 +189,11 @@ | ||
| 184 | 189 | ** |
| 185 | 190 | */ |
| 186 | 191 | static cson_value * json_wiki_get(){ |
| 187 | 192 | char const * zPageName; |
| 188 | 193 | char const * zFormat = NULL; |
| 194 | + char const * zSymName = NULL; | |
| 189 | 195 | char contentFormat = -1; |
| 190 | 196 | if( !g.perm.RdWiki && !g.perm.Read ){ |
| 191 | 197 | json_set_err(FSL_JSON_E_DENIED, |
| 192 | 198 | "Requires 'o' or 'j' access."); |
| 193 | 199 | return NULL; |
| @@ -205,18 +211,40 @@ | ||
| 205 | 211 | zPageName = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v)); |
| 206 | 212 | } |
| 207 | 213 | if(!zPageName){ |
| 208 | 214 | zPageName = json_command_arg(g.json.dispatchDepth+1); |
| 209 | 215 | } |
| 210 | - if(!zPageName||!*zPageName){ | |
| 216 | + | |
| 217 | + zSymName = json_find_option_cstr("uuid",NULL,"u"); | |
| 218 | + | |
| 219 | + if((!zPageName||!*zPageName) && (!zSymName || !*zSymName)){ | |
| 211 | 220 | json_set_err(FSL_JSON_E_MISSING_ARGS, |
| 212 | - "'name' argument is missing."); | |
| 221 | + "At least one of the 'name' or 'uuid' arguments must be provided."); | |
| 213 | 222 | return NULL; |
| 214 | 223 | } |
| 215 | 224 | |
| 225 | + /* TODO: see if we have a page named zPageName. If not, try to resolve | |
| 226 | + zPageName as a UUID. | |
| 227 | + */ | |
| 228 | + | |
| 216 | 229 | contentFormat = json_wiki_get_content_format_flag(contentFormat); |
| 217 | - return json_get_wiki_page_by_name(zPageName, contentFormat); | |
| 230 | + if(!zSymName || !*zSymName){ | |
| 231 | + return json_get_wiki_page_by_name(zPageName, contentFormat); | |
| 232 | + }else{ | |
| 233 | + int rid = symbolic_name_to_rid( zSymName ? zSymName : zPageName, "w" ); | |
| 234 | + if(rid<0){ | |
| 235 | + json_set_err(FSL_JSON_E_AMBIGUOUS_UUID, | |
| 236 | + "UUID [%s] is ambiguious.", zSymName); | |
| 237 | + return NULL; | |
| 238 | + }else if(rid==0){ | |
| 239 | + json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, | |
| 240 | + "UUID [%s] does not resolve to a wiki page.", zSymName); | |
| 241 | + return NULL; | |
| 242 | + }else{ | |
| 243 | + return json_get_wiki_page_by_rid(rid, contentFormat); | |
| 244 | + } | |
| 245 | + } | |
| 218 | 246 | } |
| 219 | 247 | |
| 220 | 248 | /* |
| 221 | 249 | ** Internal impl of /wiki/save and /wiki/create. If createMode is 0 |
| 222 | 250 | ** and the page already exists then a |
| 223 | 251 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -86,10 +86,15 @@ | |
| 86 | ); |
| 87 | cson_object_set(pay,"name",json_new_string(pWiki->zWikiTitle)); |
| 88 | cson_object_set(pay,"uuid",json_new_string(zUuid)); |
| 89 | free(zUuid); |
| 90 | zUuid = NULL; |
| 91 | /*cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));*/ |
| 92 | cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser)); |
| 93 | cson_object_set(pay,FossilJsonKeys.timestamp, |
| 94 | json_julian_to_timestamp(pWiki->rDate)); |
| 95 | if(0 == contentFormat){ |
| @@ -184,10 +189,11 @@ | |
| 184 | ** |
| 185 | */ |
| 186 | static cson_value * json_wiki_get(){ |
| 187 | char const * zPageName; |
| 188 | char const * zFormat = NULL; |
| 189 | char contentFormat = -1; |
| 190 | if( !g.perm.RdWiki && !g.perm.Read ){ |
| 191 | json_set_err(FSL_JSON_E_DENIED, |
| 192 | "Requires 'o' or 'j' access."); |
| 193 | return NULL; |
| @@ -205,18 +211,40 @@ | |
| 205 | zPageName = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v)); |
| 206 | } |
| 207 | if(!zPageName){ |
| 208 | zPageName = json_command_arg(g.json.dispatchDepth+1); |
| 209 | } |
| 210 | if(!zPageName||!*zPageName){ |
| 211 | json_set_err(FSL_JSON_E_MISSING_ARGS, |
| 212 | "'name' argument is missing."); |
| 213 | return NULL; |
| 214 | } |
| 215 | |
| 216 | contentFormat = json_wiki_get_content_format_flag(contentFormat); |
| 217 | return json_get_wiki_page_by_name(zPageName, contentFormat); |
| 218 | } |
| 219 | |
| 220 | /* |
| 221 | ** Internal impl of /wiki/save and /wiki/create. If createMode is 0 |
| 222 | ** and the page already exists then a |
| 223 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -86,10 +86,15 @@ | |
| 86 | ); |
| 87 | cson_object_set(pay,"name",json_new_string(pWiki->zWikiTitle)); |
| 88 | cson_object_set(pay,"uuid",json_new_string(zUuid)); |
| 89 | free(zUuid); |
| 90 | zUuid = NULL; |
| 91 | if( pWiki->nParent > 0 ){ |
| 92 | cson_object_set( pay, "parent", json_new_string(pWiki->azParent[0]) ) |
| 93 | /* Reminder: wiki pages do not branch and have only one parent |
| 94 | (except for the initial version, which has no parents). */; |
| 95 | } |
| 96 | /*cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));*/ |
| 97 | cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser)); |
| 98 | cson_object_set(pay,FossilJsonKeys.timestamp, |
| 99 | json_julian_to_timestamp(pWiki->rDate)); |
| 100 | if(0 == contentFormat){ |
| @@ -184,10 +189,11 @@ | |
| 189 | ** |
| 190 | */ |
| 191 | static cson_value * json_wiki_get(){ |
| 192 | char const * zPageName; |
| 193 | char const * zFormat = NULL; |
| 194 | char const * zSymName = NULL; |
| 195 | char contentFormat = -1; |
| 196 | if( !g.perm.RdWiki && !g.perm.Read ){ |
| 197 | json_set_err(FSL_JSON_E_DENIED, |
| 198 | "Requires 'o' or 'j' access."); |
| 199 | return NULL; |
| @@ -205,18 +211,40 @@ | |
| 211 | zPageName = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v)); |
| 212 | } |
| 213 | if(!zPageName){ |
| 214 | zPageName = json_command_arg(g.json.dispatchDepth+1); |
| 215 | } |
| 216 | |
| 217 | zSymName = json_find_option_cstr("uuid",NULL,"u"); |
| 218 | |
| 219 | if((!zPageName||!*zPageName) && (!zSymName || !*zSymName)){ |
| 220 | json_set_err(FSL_JSON_E_MISSING_ARGS, |
| 221 | "At least one of the 'name' or 'uuid' arguments must be provided."); |
| 222 | return NULL; |
| 223 | } |
| 224 | |
| 225 | /* TODO: see if we have a page named zPageName. If not, try to resolve |
| 226 | zPageName as a UUID. |
| 227 | */ |
| 228 | |
| 229 | contentFormat = json_wiki_get_content_format_flag(contentFormat); |
| 230 | if(!zSymName || !*zSymName){ |
| 231 | return json_get_wiki_page_by_name(zPageName, contentFormat); |
| 232 | }else{ |
| 233 | int rid = symbolic_name_to_rid( zSymName ? zSymName : zPageName, "w" ); |
| 234 | if(rid<0){ |
| 235 | json_set_err(FSL_JSON_E_AMBIGUOUS_UUID, |
| 236 | "UUID [%s] is ambiguious.", zSymName); |
| 237 | return NULL; |
| 238 | }else if(rid==0){ |
| 239 | json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 240 | "UUID [%s] does not resolve to a wiki page.", zSymName); |
| 241 | return NULL; |
| 242 | }else{ |
| 243 | return json_get_wiki_page_by_rid(rid, contentFormat); |
| 244 | } |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | /* |
| 249 | ** Internal impl of /wiki/save and /wiki/create. If createMode is 0 |
| 250 | ** and the page already exists then a |
| 251 |
+1
-1
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -69,11 +69,11 @@ | ||
| 69 | 69 | ** The zType parameter specifies the type of artifact: ci, t, w, e, g. |
| 70 | 70 | ** If zType is NULL or "" or "*" then any type of artifact will serve. |
| 71 | 71 | ** zType is "ci" in most use cases since we are usually searching for |
| 72 | 72 | ** a check-in. |
| 73 | 73 | */ |
| 74 | -static int symbolic_name_to_rid(const char *zTag, const char *zType){ | |
| 74 | +int symbolic_name_to_rid(const char *zTag, const char *zType){ | |
| 75 | 75 | int vid; |
| 76 | 76 | int rid = 0; |
| 77 | 77 | int nTag; |
| 78 | 78 | int i; |
| 79 | 79 | |
| 80 | 80 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -69,11 +69,11 @@ | |
| 69 | ** The zType parameter specifies the type of artifact: ci, t, w, e, g. |
| 70 | ** If zType is NULL or "" or "*" then any type of artifact will serve. |
| 71 | ** zType is "ci" in most use cases since we are usually searching for |
| 72 | ** a check-in. |
| 73 | */ |
| 74 | static int symbolic_name_to_rid(const char *zTag, const char *zType){ |
| 75 | int vid; |
| 76 | int rid = 0; |
| 77 | int nTag; |
| 78 | int i; |
| 79 | |
| 80 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -69,11 +69,11 @@ | |
| 69 | ** The zType parameter specifies the type of artifact: ci, t, w, e, g. |
| 70 | ** If zType is NULL or "" or "*" then any type of artifact will serve. |
| 71 | ** zType is "ci" in most use cases since we are usually searching for |
| 72 | ** a check-in. |
| 73 | */ |
| 74 | int symbolic_name_to_rid(const char *zTag, const char *zType){ |
| 75 | int vid; |
| 76 | int rid = 0; |
| 77 | int nTag; |
| 78 | int i; |
| 79 | |
| 80 |