Fossil SCM

Enhanced /json/artifact/FILE_UUID a bit. Now only includes full content if explicitly told to, but returns more metadata even for binary files.

stephan 2011-10-19 23:56 json-multitag-test
Commit 2165e77c856872a270c5d02a9a2092335d487e72
2 files changed +2 -1 +54 -47
+2 -1
--- src/json.c
+++ src/json.c
@@ -1736,11 +1736,12 @@
17361736
}
17371737
17381738
/*
17391739
** Works just like json_stmt_to_array_of_obj(), but each row in the
17401740
** result set is represented as an Array of values instead of an
1741
-** Object (key/value pairs).
1741
+** Object (key/value pairs). If pTgt is NULL and the statement
1742
+** has no results then NULL is returned, not an empty array.
17421743
*/
17431744
cson_value * json_stmt_to_array_of_array(Stmt *pStmt,
17441745
cson_value * pTgt){
17451746
cson_value * v = pTgt;
17461747
cson_array * a = NULL;
17471748
--- src/json.c
+++ src/json.c
@@ -1736,11 +1736,12 @@
1736 }
1737
1738 /*
1739 ** Works just like json_stmt_to_array_of_obj(), but each row in the
1740 ** result set is represented as an Array of values instead of an
1741 ** Object (key/value pairs).
 
1742 */
1743 cson_value * json_stmt_to_array_of_array(Stmt *pStmt,
1744 cson_value * pTgt){
1745 cson_value * v = pTgt;
1746 cson_array * a = NULL;
1747
--- src/json.c
+++ src/json.c
@@ -1736,11 +1736,12 @@
1736 }
1737
1738 /*
1739 ** Works just like json_stmt_to_array_of_obj(), but each row in the
1740 ** result set is represented as an Array of values instead of an
1741 ** Object (key/value pairs). If pTgt is NULL and the statement
1742 ** has no results then NULL is returned, not an empty array.
1743 */
1744 cson_value * json_stmt_to_array_of_array(Stmt *pStmt,
1745 cson_value * pTgt){
1746 cson_value * v = pTgt;
1747 cson_array * a = NULL;
1748
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -210,10 +210,18 @@
210210
{"ticket", json_artifact_ticket},
211211
{"wiki", json_artifact_wiki},
212212
/* Final entry MUST have a NULL name. */
213213
{NULL,NULL}
214214
};
215
+
216
+/*
217
+** Internal helper which returns true (non-0) if the includeContent
218
+** (HTTP) or -content|-c flags (CLI) are set.
219
+*/
220
+static char json_artifact_include_content_flag(){
221
+ return json_find_option_bool("includeContent","content","c",0);
222
+}
215223
216224
cson_value * json_artifact_wiki(int rid){
217225
if( ! g.perm.RdWiki ){
218226
json_set_err(FSL_JSON_E_DENIED,
219227
"Requires 'j' privileges.");
@@ -225,13 +233,13 @@
225233
226234
cson_value * json_artifact_file(int rid){
227235
cson_value * payV = NULL;
228236
cson_object * pay = NULL;
229237
const char *zMime;
230
- const char *zRaw;
231
- Blob content;
232
- Stmt q;
238
+ Blob content = empty_blob;
239
+ Stmt q = empty_Stmt;
240
+ cson_array * checkin_arr = NULL;
233241
234242
if( ! g.perm.Read ){
235243
json_set_err(FSL_JSON_E_DENIED,
236244
"Requires 'o' privileges.");
237245
return NULL;
@@ -239,33 +247,31 @@
239247
240248
payV = cson_value_new_object();
241249
pay = cson_value_get_object(payV);
242250
243251
content_get(rid, &content);
252
+ cson_object_set(pay, "contentLength",
253
+ json_new_int( blob_size(&content) )
254
+ /* achtung: overflow potential on 32-bit builds! */);
244255
zMime = mimetype_from_content(&content);
245256
246
- if (!zMime){
247
- cson_array * checkin_arr = NULL;
248
- cson_value * checkin_list = NULL;
249
- /*cson_string * tagKey = NULL;*/
250
- cson_value * checkinV = NULL;
251
- cson_object * checkin = NULL;
252
-
253
- cson_int_t const rawLen = blob_size(&content);
254
- zRaw = blob_str(&content);
255
- checkin_list = cson_value_new_array();
256
-
257
- cson_object_set(pay, "contentLength",
258
- json_new_int( rawLen
259
- /* achtung: overflow potential on 32-bit builds! */));
260
- cson_object_set(pay, "content",
261
- cson_value_new_string(zRaw,(unsigned int)rawLen));
262
- cson_object_set(pay, "checkins", checkin_list);
263
-
264
- checkin_arr = cson_value_get_array(checkin_list);
265
-
266
- db_prepare(&q,
257
+ cson_object_set(pay, "contentType",
258
+ json_new_string(zMime ? zMime : "text/plain"));
259
+ if( json_artifact_include_content_flag() && !zMime ){
260
+#if 0
261
+ /*see next #if block below*/
262
+ cson_string * tagKey = NULL;
263
+ cson_value * checkinV = NULL;
264
+ cson_object * checkin = NULL;
265
+#endif
266
+ cson_object_set(pay, "content",
267
+ cson_value_new_string(blob_str(&content),
268
+ (unsigned int)blob_size(&content)));
269
+ }
270
+ blob_reset(&content);
271
+
272
+ db_prepare(&q,
267273
"SELECT filename.name AS name, "
268274
" cast(strftime('%%s',event.mtime) as int) AS mtime,"
269275
" coalesce(event.ecomment,event.comment) as comment,"
270276
" coalesce(event.euser,event.user) as user,"
271277
" b.uuid as uuid, mlink.mperm as mperm,"/* WTF is mperm?*/
@@ -278,36 +284,37 @@
278284
" AND b.rid=mlink.mid"
279285
" AND mlink.fid=%d"
280286
" ORDER BY filename.name, event.mtime",
281287
TAG_BRANCH, rid
282288
);
289
+ checkin_arr = cson_new_array();
290
+ cson_object_set(pay, "checkins", cson_array_value(checkin_arr));
283291
#if 0
284
- /* Damn: json_tags_for_rid() only works for commits.
285
-
286
- FIXME: extend json_tags_for_rid() to accept file rids and then
287
- implement this loop to add the tags to each object.
288
- */
289
-
290
- while( SQLITE_ROW == db_step(&q) ){
291
- checkinV = cson_sqlite3_row_to_object( q.pStmt );
292
- if(!checkinV){
293
- continue;
294
- }
295
- if(!tagKey) {
296
- tagKey = cson_new_string("tags",4);
297
- json_gc_add("artifact/file/tags", cson_string_value(tagKey))
298
- /*avoids a potential lifetime issue*/;
299
- }
300
- checkin = cson_value_get_object(checkinV);
301
- cson_object_set_s(checkin, tagKey, json_tags_for_rid(rid,0));
302
- cson_array_append( checkin_arr, checkinV );
303
- }
292
+ /* Damn: json_tags_for_rid() only works for commits.
293
+
294
+ FIXME: extend json_tags_for_rid() to accept file rids and then
295
+ implement this loop to add the tags to each object.
296
+ */
297
+
298
+ while( SQLITE_ROW == db_step(&q) ){
299
+ checkinV = cson_sqlite3_row_to_object( q.pStmt );
300
+ if(!checkinV){
301
+ continue;
302
+ }
303
+ if(!tagKey) {
304
+ tagKey = cson_new_string("tags",4);
305
+ json_gc_add("artifact/file/tags", cson_string_value(tagKey))
306
+ /*avoids a potential lifetime issue*/;
307
+ }
308
+ checkin = cson_value_get_object(checkinV);
309
+ cson_object_set_s(checkin, tagKey, json_tags_for_rid(rid,0));
310
+ cson_array_append( checkin_arr, checkinV );
311
+ }
304312
#else
305
- json_stmt_to_array_of_obj( &q, checkin_list );
313
+ json_stmt_to_array_of_obj( &q, cson_array_value(checkin_arr) );
306314
#endif
307
- db_finalize(&q);
308
- }
315
+ db_finalize(&q);
309316
return payV;
310317
}
311318
312319
/*
313320
** Impl of /json/artifact. This basically just determines the type of
314321
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -210,10 +210,18 @@
210 {"ticket", json_artifact_ticket},
211 {"wiki", json_artifact_wiki},
212 /* Final entry MUST have a NULL name. */
213 {NULL,NULL}
214 };
 
 
 
 
 
 
 
 
215
216 cson_value * json_artifact_wiki(int rid){
217 if( ! g.perm.RdWiki ){
218 json_set_err(FSL_JSON_E_DENIED,
219 "Requires 'j' privileges.");
@@ -225,13 +233,13 @@
225
226 cson_value * json_artifact_file(int rid){
227 cson_value * payV = NULL;
228 cson_object * pay = NULL;
229 const char *zMime;
230 const char *zRaw;
231 Blob content;
232 Stmt q;
233
234 if( ! g.perm.Read ){
235 json_set_err(FSL_JSON_E_DENIED,
236 "Requires 'o' privileges.");
237 return NULL;
@@ -239,33 +247,31 @@
239
240 payV = cson_value_new_object();
241 pay = cson_value_get_object(payV);
242
243 content_get(rid, &content);
 
 
 
244 zMime = mimetype_from_content(&content);
245
246 if (!zMime){
247 cson_array * checkin_arr = NULL;
248 cson_value * checkin_list = NULL;
249 /*cson_string * tagKey = NULL;*/
250 cson_value * checkinV = NULL;
251 cson_object * checkin = NULL;
252
253 cson_int_t const rawLen = blob_size(&content);
254 zRaw = blob_str(&content);
255 checkin_list = cson_value_new_array();
256
257 cson_object_set(pay, "contentLength",
258 json_new_int( rawLen
259 /* achtung: overflow potential on 32-bit builds! */));
260 cson_object_set(pay, "content",
261 cson_value_new_string(zRaw,(unsigned int)rawLen));
262 cson_object_set(pay, "checkins", checkin_list);
263
264 checkin_arr = cson_value_get_array(checkin_list);
265
266 db_prepare(&q,
267 "SELECT filename.name AS name, "
268 " cast(strftime('%%s',event.mtime) as int) AS mtime,"
269 " coalesce(event.ecomment,event.comment) as comment,"
270 " coalesce(event.euser,event.user) as user,"
271 " b.uuid as uuid, mlink.mperm as mperm,"/* WTF is mperm?*/
@@ -278,36 +284,37 @@
278 " AND b.rid=mlink.mid"
279 " AND mlink.fid=%d"
280 " ORDER BY filename.name, event.mtime",
281 TAG_BRANCH, rid
282 );
 
 
283 #if 0
284 /* Damn: json_tags_for_rid() only works for commits.
285
286 FIXME: extend json_tags_for_rid() to accept file rids and then
287 implement this loop to add the tags to each object.
288 */
289
290 while( SQLITE_ROW == db_step(&q) ){
291 checkinV = cson_sqlite3_row_to_object( q.pStmt );
292 if(!checkinV){
293 continue;
294 }
295 if(!tagKey) {
296 tagKey = cson_new_string("tags",4);
297 json_gc_add("artifact/file/tags", cson_string_value(tagKey))
298 /*avoids a potential lifetime issue*/;
299 }
300 checkin = cson_value_get_object(checkinV);
301 cson_object_set_s(checkin, tagKey, json_tags_for_rid(rid,0));
302 cson_array_append( checkin_arr, checkinV );
303 }
304 #else
305 json_stmt_to_array_of_obj( &q, checkin_list );
306 #endif
307 db_finalize(&q);
308 }
309 return payV;
310 }
311
312 /*
313 ** Impl of /json/artifact. This basically just determines the type of
314
--- src/json_artifact.c
+++ src/json_artifact.c
@@ -210,10 +210,18 @@
210 {"ticket", json_artifact_ticket},
211 {"wiki", json_artifact_wiki},
212 /* Final entry MUST have a NULL name. */
213 {NULL,NULL}
214 };
215
216 /*
217 ** Internal helper which returns true (non-0) if the includeContent
218 ** (HTTP) or -content|-c flags (CLI) are set.
219 */
220 static char json_artifact_include_content_flag(){
221 return json_find_option_bool("includeContent","content","c",0);
222 }
223
224 cson_value * json_artifact_wiki(int rid){
225 if( ! g.perm.RdWiki ){
226 json_set_err(FSL_JSON_E_DENIED,
227 "Requires 'j' privileges.");
@@ -225,13 +233,13 @@
233
234 cson_value * json_artifact_file(int rid){
235 cson_value * payV = NULL;
236 cson_object * pay = NULL;
237 const char *zMime;
238 Blob content = empty_blob;
239 Stmt q = empty_Stmt;
240 cson_array * checkin_arr = NULL;
241
242 if( ! g.perm.Read ){
243 json_set_err(FSL_JSON_E_DENIED,
244 "Requires 'o' privileges.");
245 return NULL;
@@ -239,33 +247,31 @@
247
248 payV = cson_value_new_object();
249 pay = cson_value_get_object(payV);
250
251 content_get(rid, &content);
252 cson_object_set(pay, "contentLength",
253 json_new_int( blob_size(&content) )
254 /* achtung: overflow potential on 32-bit builds! */);
255 zMime = mimetype_from_content(&content);
256
257 cson_object_set(pay, "contentType",
258 json_new_string(zMime ? zMime : "text/plain"));
259 if( json_artifact_include_content_flag() && !zMime ){
260 #if 0
261 /*see next #if block below*/
262 cson_string * tagKey = NULL;
263 cson_value * checkinV = NULL;
264 cson_object * checkin = NULL;
265 #endif
266 cson_object_set(pay, "content",
267 cson_value_new_string(blob_str(&content),
268 (unsigned int)blob_size(&content)));
269 }
270 blob_reset(&content);
271
272 db_prepare(&q,
 
 
 
 
 
273 "SELECT filename.name AS name, "
274 " cast(strftime('%%s',event.mtime) as int) AS mtime,"
275 " coalesce(event.ecomment,event.comment) as comment,"
276 " coalesce(event.euser,event.user) as user,"
277 " b.uuid as uuid, mlink.mperm as mperm,"/* WTF is mperm?*/
@@ -278,36 +284,37 @@
284 " AND b.rid=mlink.mid"
285 " AND mlink.fid=%d"
286 " ORDER BY filename.name, event.mtime",
287 TAG_BRANCH, rid
288 );
289 checkin_arr = cson_new_array();
290 cson_object_set(pay, "checkins", cson_array_value(checkin_arr));
291 #if 0
292 /* Damn: json_tags_for_rid() only works for commits.
293
294 FIXME: extend json_tags_for_rid() to accept file rids and then
295 implement this loop to add the tags to each object.
296 */
297
298 while( SQLITE_ROW == db_step(&q) ){
299 checkinV = cson_sqlite3_row_to_object( q.pStmt );
300 if(!checkinV){
301 continue;
302 }
303 if(!tagKey) {
304 tagKey = cson_new_string("tags",4);
305 json_gc_add("artifact/file/tags", cson_string_value(tagKey))
306 /*avoids a potential lifetime issue*/;
307 }
308 checkin = cson_value_get_object(checkinV);
309 cson_object_set_s(checkin, tagKey, json_tags_for_rid(rid,0));
310 cson_array_append( checkin_arr, checkinV );
311 }
312 #else
313 json_stmt_to_array_of_obj( &q, cson_array_value(checkin_arr) );
314 #endif
315 db_finalize(&q);
 
316 return payV;
317 }
318
319 /*
320 ** Impl of /json/artifact. This basically just determines the type of
321

Keyboard Shortcuts

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