Fossil SCM
/json/artifact/WIKI_UUID now returns the requested wiki page version instead of the most recent one.
Commit
accd6f3df6918f13502d9a683f3083daae42ddfd
Parent
f825f8c85db3441…
2 files changed
+3
-1
+51
-61
+3
-1
| --- src/json_artifact.c | ||
| +++ src/json_artifact.c | ||
| @@ -241,11 +241,13 @@ | ||
| 241 | 241 | if( ! g.perm.RdWiki ){ |
| 242 | 242 | json_set_err(FSL_JSON_E_DENIED, |
| 243 | 243 | "Requires 'j' privileges."); |
| 244 | 244 | return NULL; |
| 245 | 245 | }else{ |
| 246 | - return json_get_wiki_page_by_rid(rid, 0); | |
| 246 | + char addContent = json_artifact_include_content_flag(); | |
| 247 | + /* todo: support format=(raw|html|none) like /wiki/get does. */ | |
| 248 | + return json_get_wiki_page_by_rid(rid, addContent ? -1 : 0); | |
| 247 | 249 | } |
| 248 | 250 | } |
| 249 | 251 | |
| 250 | 252 | cson_value * json_artifact_file(int rid){ |
| 251 | 253 | cson_object * pay = NULL; |
| 252 | 254 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -241,11 +241,13 @@ | |
| 241 | if( ! g.perm.RdWiki ){ |
| 242 | json_set_err(FSL_JSON_E_DENIED, |
| 243 | "Requires 'j' privileges."); |
| 244 | return NULL; |
| 245 | }else{ |
| 246 | return json_get_wiki_page_by_rid(rid, 0); |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | cson_value * json_artifact_file(int rid){ |
| 251 | cson_object * pay = NULL; |
| 252 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -241,11 +241,13 @@ | |
| 241 | if( ! g.perm.RdWiki ){ |
| 242 | json_set_err(FSL_JSON_E_DENIED, |
| 243 | "Requires 'j' privileges."); |
| 244 | return NULL; |
| 245 | }else{ |
| 246 | char addContent = json_artifact_include_content_flag(); |
| 247 | /* todo: support format=(raw|html|none) like /wiki/get does. */ |
| 248 | return json_get_wiki_page_by_rid(rid, addContent ? -1 : 0); |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | cson_value * json_artifact_file(int rid){ |
| 253 | cson_object * pay = NULL; |
| 254 |
+51
-61
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -50,69 +50,56 @@ | ||
| 50 | 50 | return json_page_dispatch_helper(&JsonPageDefs_Wiki[0]); |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | |
| 54 | 54 | /* |
| 55 | -** Loads the given wiki page and creates a JSON object representation | |
| 56 | -** of it. If the page is not found then NULL is returned. If | |
| 57 | -** contentFormat is positive true then the page content is HTML-ized | |
| 58 | -** using fossil's conventional wiki format, if it is negative then no | |
| 59 | -** parsing is performed, if it is 0 then the content is not returned | |
| 60 | -** in the response. If contentFormat is 0 then the contentSize reflects | |
| 61 | -** the number of bytes, not characters, stored in the page. | |
| 55 | +** Tries to load a wiki page from the given rid creates a JSON object | |
| 56 | +** representation of it. If the page is not found then NULL is | |
| 57 | +** returned. If contentFormat is positive then the page content | |
| 58 | +** is HTML-ized using fossil's conventional wiki format, if it is | |
| 59 | +** negative then no parsing is performed, if it is 0 then the content | |
| 60 | +** is not returned in the response. If contentFormat is 0 then the | |
| 61 | +** contentSize reflects the number of bytes, not characters, stored in | |
| 62 | +** the page. | |
| 62 | 63 | ** |
| 63 | 64 | ** The returned value, if not NULL, is-a JSON Object owned by the |
| 64 | 65 | ** caller. If it returns NULL then it may set g.json's error state. |
| 65 | 66 | */ |
| 66 | -cson_value * json_get_wiki_page_by_name(char const * zPageName, char contentFormat){ | |
| 67 | - int rid; | |
| 68 | - Manifest *pWiki = 0; | |
| 69 | - char * zUuid = NULL; | |
| 70 | - Stmt q; | |
| 71 | - db_prepare(&q, | |
| 72 | - "SELECT x.rid, b.uuid FROM tag t, tagxref x, blob b" | |
| 73 | - " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' " | |
| 74 | - " AND b.rid=x.rid" | |
| 75 | - " ORDER BY x.mtime DESC LIMIT 1", | |
| 76 | - zPageName | |
| 77 | - ); | |
| 78 | - if( (SQLITE_ROW != db_step(&q)) ){ | |
| 79 | - db_finalize(&q); | |
| 80 | - json_set_err( FSL_JSON_E_RESOURCE_NOT_FOUND, "Wiki page not found: %s", | |
| 81 | - zPageName ); | |
| 82 | - return NULL; | |
| 83 | - } | |
| 84 | - rid = db_column_int(&q,0); | |
| 85 | - zUuid = db_column_malloc(&q,1); | |
| 86 | - db_finalize(&q); | |
| 67 | +cson_value * json_get_wiki_page_by_rid(int rid, char contentFormat){ | |
| 68 | + Manifest * pWiki = NULL; | |
| 87 | 69 | if( NULL == (pWiki = manifest_get(rid, CFTYPE_WIKI)) ){ |
| 88 | - free(zUuid); | |
| 89 | 70 | json_set_err( FSL_JSON_E_UNKNOWN, |
| 90 | - "Error reading wiki page from manifest (rid=%d, uuid=%s).", | |
| 91 | - rid, zUuid ); | |
| 71 | + "Error reading wiki page from manifest (rid=%d).", | |
| 72 | + rid ); | |
| 92 | 73 | return NULL; |
| 93 | 74 | }else{ |
| 94 | - char const * zFormat = NULL; | |
| 75 | + /*char const * zFormat = NULL;*/ | |
| 95 | 76 | unsigned int len = 0; |
| 96 | 77 | cson_object * pay = cson_new_object(); |
| 97 | 78 | char const * zBody = pWiki->zWiki; |
| 98 | - cson_object_set(pay,"name",json_new_string(zPageName)); | |
| 79 | + char const * zFormat = NULL; | |
| 80 | + char * zUuid = db_text(NULL, | |
| 81 | + "SELECT b.uuid FROM tag t, tagxref x, blob b" | |
| 82 | + " WHERE x.tagid=t.tagid AND t.tagname GLOB 'wiki-*' " | |
| 83 | + " AND b.rid=x.rid AND b.rid=%d" | |
| 84 | + " ORDER BY x.mtime DESC LIMIT 1", | |
| 85 | + rid | |
| 86 | + ); | |
| 87 | + cson_object_set(pay,"name",json_new_string(pWiki->zWikiTitle)); | |
| 99 | 88 | cson_object_set(pay,"uuid",json_new_string(zUuid)); |
| 100 | 89 | free(zUuid); |
| 101 | 90 | zUuid = NULL; |
| 102 | 91 | /*cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));*/ |
| 103 | 92 | cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser)); |
| 104 | 93 | cson_object_set(pay,FossilJsonKeys.timestamp, |
| 105 | 94 | json_julian_to_timestamp(pWiki->rDate)); |
| 106 | - | |
| 107 | - | |
| 108 | 95 | if(0 == contentFormat){ |
| 109 | 96 | cson_object_set(pay,"contentLength", |
| 110 | 97 | json_new_int((cson_int_t)(zBody?strlen(zBody):0))); |
| 111 | 98 | }else{ |
| 112 | - cson_object_set(pay,"contentFormat",json_new_string(zFormat)); | |
| 113 | 99 | if( contentFormat>0 ){/*HTML-ize it*/ |
| 100 | + zFormat = "html"; | |
| 114 | 101 | Blob content = empty_blob; |
| 115 | 102 | Blob raw = empty_blob; |
| 116 | 103 | if(zBody && *zBody){ |
| 117 | 104 | blob_append(&raw,zBody,-1); |
| 118 | 105 | wiki_convert(&raw,&content,0); |
| @@ -122,45 +109,48 @@ | ||
| 122 | 109 | cson_object_set(pay,"content", |
| 123 | 110 | cson_value_new_string(blob_buffer(&content),len)); |
| 124 | 111 | blob_reset(&content); |
| 125 | 112 | blob_reset(&raw); |
| 126 | 113 | }else{/*raw format*/ |
| 114 | + zFormat = "raw"; | |
| 127 | 115 | len = zBody ? strlen(zBody) : 0; |
| 128 | 116 | cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len)); |
| 129 | 117 | cson_object_set(pay,"content",cson_value_new_string(zBody,len)); |
| 130 | 118 | } |
| 119 | + cson_object_set(pay,"contentFormat",json_new_string(zFormat)); | |
| 120 | + | |
| 131 | 121 | } |
| 132 | 122 | /*TODO: add 'T' (tag) fields*/ |
| 133 | 123 | /*TODO: add the 'A' card (file attachment) entries?*/ |
| 134 | 124 | manifest_destroy(pWiki); |
| 135 | 125 | return cson_object_value(pay); |
| 136 | 126 | } |
| 137 | - | |
| 138 | -} | |
| 139 | - | |
| 140 | - | |
| 141 | -/* | |
| 142 | -** Searches for a wiki page with the given rid. If found it behaves | |
| 143 | -** like json_get_wiki_page_by_name(pageName, contentFormat), else it returns | |
| 144 | -** NULL. | |
| 145 | -*/ | |
| 146 | -cson_value * json_get_wiki_page_by_rid(int rid, char contentFormat){ | |
| 147 | - char * zPageName = NULL; | |
| 148 | - cson_value * rc = NULL; | |
| 149 | - zPageName = db_text(NULL, | |
| 150 | - "SELECT substr(t.tagname,6) AS name " | |
| 151 | - " FROM tag t, tagxref x, blob b " | |
| 152 | - " WHERE b.rid=%d " | |
| 153 | - " AND t.tagname GLOB 'wiki-*'" | |
| 154 | - " AND x.tagid=t.tagid AND b.rid=x.rid ", | |
| 155 | - rid); | |
| 156 | - if( zPageName ){ | |
| 157 | - rc = json_get_wiki_page_by_name(zPageName, contentFormat); | |
| 158 | - free(zPageName); | |
| 159 | - } | |
| 160 | - return rc; | |
| 161 | -} | |
| 127 | +} | |
| 128 | + | |
| 129 | +/* | |
| 130 | +** Searches for the latest version of a wiki page with the given | |
| 131 | +** name. If found it behaves like json_get_wiki_page_by_rid(theRid, | |
| 132 | +** contentFormat), else it returns NULL. | |
| 133 | +*/ | |
| 134 | +cson_value * json_get_wiki_page_by_name(char const * zPageName, char contentFormat){ | |
| 135 | + int rid; | |
| 136 | + rid = db_int(0, | |
| 137 | + "SELECT x.rid FROM tag t, tagxref x, blob b" | |
| 138 | + " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' " | |
| 139 | + " AND b.rid=x.rid" | |
| 140 | + " ORDER BY x.mtime DESC LIMIT 1", | |
| 141 | + zPageName | |
| 142 | + ); | |
| 143 | + if( 0==rid ){ | |
| 144 | + json_set_err( FSL_JSON_E_RESOURCE_NOT_FOUND, "Wiki page not found: %s", | |
| 145 | + zPageName ); | |
| 146 | + return NULL; | |
| 147 | + } | |
| 148 | + return json_get_wiki_page_by_rid(rid, contentFormat); | |
| 149 | +} | |
| 150 | + | |
| 151 | + | |
| 162 | 152 | |
| 163 | 153 | /* |
| 164 | 154 | ** Implementation of /json/wiki/get. |
| 165 | 155 | ** |
| 166 | 156 | */ |
| 167 | 157 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -50,69 +50,56 @@ | |
| 50 | return json_page_dispatch_helper(&JsonPageDefs_Wiki[0]); |
| 51 | } |
| 52 | |
| 53 | |
| 54 | /* |
| 55 | ** Loads the given wiki page and creates a JSON object representation |
| 56 | ** of it. If the page is not found then NULL is returned. If |
| 57 | ** contentFormat is positive true then the page content is HTML-ized |
| 58 | ** using fossil's conventional wiki format, if it is negative then no |
| 59 | ** parsing is performed, if it is 0 then the content is not returned |
| 60 | ** in the response. If contentFormat is 0 then the contentSize reflects |
| 61 | ** the number of bytes, not characters, stored in the page. |
| 62 | ** |
| 63 | ** The returned value, if not NULL, is-a JSON Object owned by the |
| 64 | ** caller. If it returns NULL then it may set g.json's error state. |
| 65 | */ |
| 66 | cson_value * json_get_wiki_page_by_name(char const * zPageName, char contentFormat){ |
| 67 | int rid; |
| 68 | Manifest *pWiki = 0; |
| 69 | char * zUuid = NULL; |
| 70 | Stmt q; |
| 71 | db_prepare(&q, |
| 72 | "SELECT x.rid, b.uuid FROM tag t, tagxref x, blob b" |
| 73 | " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' " |
| 74 | " AND b.rid=x.rid" |
| 75 | " ORDER BY x.mtime DESC LIMIT 1", |
| 76 | zPageName |
| 77 | ); |
| 78 | if( (SQLITE_ROW != db_step(&q)) ){ |
| 79 | db_finalize(&q); |
| 80 | json_set_err( FSL_JSON_E_RESOURCE_NOT_FOUND, "Wiki page not found: %s", |
| 81 | zPageName ); |
| 82 | return NULL; |
| 83 | } |
| 84 | rid = db_column_int(&q,0); |
| 85 | zUuid = db_column_malloc(&q,1); |
| 86 | db_finalize(&q); |
| 87 | if( NULL == (pWiki = manifest_get(rid, CFTYPE_WIKI)) ){ |
| 88 | free(zUuid); |
| 89 | json_set_err( FSL_JSON_E_UNKNOWN, |
| 90 | "Error reading wiki page from manifest (rid=%d, uuid=%s).", |
| 91 | rid, zUuid ); |
| 92 | return NULL; |
| 93 | }else{ |
| 94 | char const * zFormat = NULL; |
| 95 | unsigned int len = 0; |
| 96 | cson_object * pay = cson_new_object(); |
| 97 | char const * zBody = pWiki->zWiki; |
| 98 | cson_object_set(pay,"name",json_new_string(zPageName)); |
| 99 | cson_object_set(pay,"uuid",json_new_string(zUuid)); |
| 100 | free(zUuid); |
| 101 | zUuid = NULL; |
| 102 | /*cson_object_set(pay,"rid",json_new_int((cson_int_t)rid));*/ |
| 103 | cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser)); |
| 104 | cson_object_set(pay,FossilJsonKeys.timestamp, |
| 105 | json_julian_to_timestamp(pWiki->rDate)); |
| 106 | |
| 107 | |
| 108 | if(0 == contentFormat){ |
| 109 | cson_object_set(pay,"contentLength", |
| 110 | json_new_int((cson_int_t)(zBody?strlen(zBody):0))); |
| 111 | }else{ |
| 112 | cson_object_set(pay,"contentFormat",json_new_string(zFormat)); |
| 113 | if( contentFormat>0 ){/*HTML-ize it*/ |
| 114 | Blob content = empty_blob; |
| 115 | Blob raw = empty_blob; |
| 116 | if(zBody && *zBody){ |
| 117 | blob_append(&raw,zBody,-1); |
| 118 | wiki_convert(&raw,&content,0); |
| @@ -122,45 +109,48 @@ | |
| 122 | cson_object_set(pay,"content", |
| 123 | cson_value_new_string(blob_buffer(&content),len)); |
| 124 | blob_reset(&content); |
| 125 | blob_reset(&raw); |
| 126 | }else{/*raw format*/ |
| 127 | len = zBody ? strlen(zBody) : 0; |
| 128 | cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len)); |
| 129 | cson_object_set(pay,"content",cson_value_new_string(zBody,len)); |
| 130 | } |
| 131 | } |
| 132 | /*TODO: add 'T' (tag) fields*/ |
| 133 | /*TODO: add the 'A' card (file attachment) entries?*/ |
| 134 | manifest_destroy(pWiki); |
| 135 | return cson_object_value(pay); |
| 136 | } |
| 137 | |
| 138 | } |
| 139 | |
| 140 | |
| 141 | /* |
| 142 | ** Searches for a wiki page with the given rid. If found it behaves |
| 143 | ** like json_get_wiki_page_by_name(pageName, contentFormat), else it returns |
| 144 | ** NULL. |
| 145 | */ |
| 146 | cson_value * json_get_wiki_page_by_rid(int rid, char contentFormat){ |
| 147 | char * zPageName = NULL; |
| 148 | cson_value * rc = NULL; |
| 149 | zPageName = db_text(NULL, |
| 150 | "SELECT substr(t.tagname,6) AS name " |
| 151 | " FROM tag t, tagxref x, blob b " |
| 152 | " WHERE b.rid=%d " |
| 153 | " AND t.tagname GLOB 'wiki-*'" |
| 154 | " AND x.tagid=t.tagid AND b.rid=x.rid ", |
| 155 | rid); |
| 156 | if( zPageName ){ |
| 157 | rc = json_get_wiki_page_by_name(zPageName, contentFormat); |
| 158 | free(zPageName); |
| 159 | } |
| 160 | return rc; |
| 161 | } |
| 162 | |
| 163 | /* |
| 164 | ** Implementation of /json/wiki/get. |
| 165 | ** |
| 166 | */ |
| 167 |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -50,69 +50,56 @@ | |
| 50 | return json_page_dispatch_helper(&JsonPageDefs_Wiki[0]); |
| 51 | } |
| 52 | |
| 53 | |
| 54 | /* |
| 55 | ** Tries to load a wiki page from the given rid creates a JSON object |
| 56 | ** representation of it. If the page is not found then NULL is |
| 57 | ** returned. If contentFormat is positive then the page content |
| 58 | ** is HTML-ized using fossil's conventional wiki format, if it is |
| 59 | ** negative then no parsing is performed, if it is 0 then the content |
| 60 | ** is not returned in the response. If contentFormat is 0 then the |
| 61 | ** contentSize reflects the number of bytes, not characters, stored in |
| 62 | ** the page. |
| 63 | ** |
| 64 | ** The returned value, if not NULL, is-a JSON Object owned by the |
| 65 | ** caller. If it returns NULL then it may set g.json's error state. |
| 66 | */ |
| 67 | cson_value * json_get_wiki_page_by_rid(int rid, char contentFormat){ |
| 68 | Manifest * pWiki = NULL; |
| 69 | if( NULL == (pWiki = manifest_get(rid, CFTYPE_WIKI)) ){ |
| 70 | json_set_err( FSL_JSON_E_UNKNOWN, |
| 71 | "Error reading wiki page from manifest (rid=%d).", |
| 72 | rid ); |
| 73 | return NULL; |
| 74 | }else{ |
| 75 | /*char const * zFormat = NULL;*/ |
| 76 | unsigned int len = 0; |
| 77 | cson_object * pay = cson_new_object(); |
| 78 | char const * zBody = pWiki->zWiki; |
| 79 | char const * zFormat = NULL; |
| 80 | char * zUuid = db_text(NULL, |
| 81 | "SELECT b.uuid FROM tag t, tagxref x, blob b" |
| 82 | " WHERE x.tagid=t.tagid AND t.tagname GLOB 'wiki-*' " |
| 83 | " AND b.rid=x.rid AND b.rid=%d" |
| 84 | " ORDER BY x.mtime DESC LIMIT 1", |
| 85 | rid |
| 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){ |
| 96 | cson_object_set(pay,"contentLength", |
| 97 | json_new_int((cson_int_t)(zBody?strlen(zBody):0))); |
| 98 | }else{ |
| 99 | if( contentFormat>0 ){/*HTML-ize it*/ |
| 100 | zFormat = "html"; |
| 101 | Blob content = empty_blob; |
| 102 | Blob raw = empty_blob; |
| 103 | if(zBody && *zBody){ |
| 104 | blob_append(&raw,zBody,-1); |
| 105 | wiki_convert(&raw,&content,0); |
| @@ -122,45 +109,48 @@ | |
| 109 | cson_object_set(pay,"content", |
| 110 | cson_value_new_string(blob_buffer(&content),len)); |
| 111 | blob_reset(&content); |
| 112 | blob_reset(&raw); |
| 113 | }else{/*raw format*/ |
| 114 | zFormat = "raw"; |
| 115 | len = zBody ? strlen(zBody) : 0; |
| 116 | cson_object_set(pay,"contentLength",json_new_int((cson_int_t)len)); |
| 117 | cson_object_set(pay,"content",cson_value_new_string(zBody,len)); |
| 118 | } |
| 119 | cson_object_set(pay,"contentFormat",json_new_string(zFormat)); |
| 120 | |
| 121 | } |
| 122 | /*TODO: add 'T' (tag) fields*/ |
| 123 | /*TODO: add the 'A' card (file attachment) entries?*/ |
| 124 | manifest_destroy(pWiki); |
| 125 | return cson_object_value(pay); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | /* |
| 130 | ** Searches for the latest version of a wiki page with the given |
| 131 | ** name. If found it behaves like json_get_wiki_page_by_rid(theRid, |
| 132 | ** contentFormat), else it returns NULL. |
| 133 | */ |
| 134 | cson_value * json_get_wiki_page_by_name(char const * zPageName, char contentFormat){ |
| 135 | int rid; |
| 136 | rid = db_int(0, |
| 137 | "SELECT x.rid FROM tag t, tagxref x, blob b" |
| 138 | " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q' " |
| 139 | " AND b.rid=x.rid" |
| 140 | " ORDER BY x.mtime DESC LIMIT 1", |
| 141 | zPageName |
| 142 | ); |
| 143 | if( 0==rid ){ |
| 144 | json_set_err( FSL_JSON_E_RESOURCE_NOT_FOUND, "Wiki page not found: %s", |
| 145 | zPageName ); |
| 146 | return NULL; |
| 147 | } |
| 148 | return json_get_wiki_page_by_rid(rid, contentFormat); |
| 149 | } |
| 150 | |
| 151 | |
| 152 | |
| 153 | /* |
| 154 | ** Implementation of /json/wiki/get. |
| 155 | ** |
| 156 | */ |
| 157 |