208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
+
-
+
+
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
|
{"file", json_artifact_file},
{"tag", NULL},
{"ticket", json_artifact_ticket},
{"wiki", json_artifact_wiki},
/* Final entry MUST have a NULL name. */
{NULL,NULL}
};
/*
** Internal helper which returns true (non-0) if the includeContent
** (HTTP) or -content|-c flags (CLI) are set.
*/
static char json_artifact_include_content_flag(){
return json_find_option_bool("includeContent","content","c",0);
}
cson_value * json_artifact_wiki(int rid){
if( ! g.perm.RdWiki ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'j' privileges.");
return NULL;
}else{
return json_get_wiki_page_by_rid(rid, 0);
}
}
cson_value * json_artifact_file(int rid){
cson_value * payV = NULL;
cson_object * pay = NULL;
const char *zMime;
const char *zRaw;
Blob content;
Stmt q;
Blob content = empty_blob;
Stmt q = empty_Stmt;
cson_array * checkin_arr = NULL;
if( ! g.perm.Read ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'o' privileges.");
return NULL;
}
payV = cson_value_new_object();
pay = cson_value_get_object(payV);
content_get(rid, &content);
cson_object_set(pay, "contentLength",
json_new_int( blob_size(&content) )
/* achtung: overflow potential on 32-bit builds! */);
zMime = mimetype_from_content(&content);
cson_object_set(pay, "contentType",
json_new_string(zMime ? zMime : "text/plain"));
if( json_artifact_include_content_flag() && !zMime ){
if (!zMime){
#if 0
cson_array * checkin_arr = NULL;
cson_value * checkin_list = NULL;
/*cson_string * tagKey = NULL;*/
cson_value * checkinV = NULL;
cson_object * checkin = NULL;
/*see next #if block below*/
cson_string * tagKey = NULL;
cson_value * checkinV = NULL;
cson_object * checkin = NULL;
#endif
cson_int_t const rawLen = blob_size(&content);
zRaw = blob_str(&content);
checkin_list = cson_value_new_array();
cson_object_set(pay, "contentLength",
json_new_int( rawLen
/* achtung: overflow potential on 32-bit builds! */));
cson_object_set(pay, "content",
cson_value_new_string(zRaw,(unsigned int)rawLen));
cson_object_set(pay, "content",
cson_value_new_string(blob_str(&content),
cson_object_set(pay, "checkins", checkin_list);
(unsigned int)blob_size(&content)));
}
checkin_arr = cson_value_get_array(checkin_list);
blob_reset(&content);
db_prepare(&q,
db_prepare(&q,
"SELECT filename.name AS name, "
" cast(strftime('%%s',event.mtime) as int) AS mtime,"
" coalesce(event.ecomment,event.comment) as comment,"
" coalesce(event.euser,event.user) as user,"
" b.uuid as uuid, mlink.mperm as mperm,"/* WTF is mperm?*/
" coalesce((SELECT value FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND rid=mlink.mid),'trunk') as branch"
" FROM mlink, filename, event, blob a, blob b"
" WHERE filename.fnid=mlink.fnid"
" AND event.objid=mlink.mid"
" AND a.rid=mlink.fid"
" AND b.rid=mlink.mid"
" AND mlink.fid=%d"
" ORDER BY filename.name, event.mtime",
TAG_BRANCH, rid
);
checkin_arr = cson_new_array();
cson_object_set(pay, "checkins", cson_array_value(checkin_arr));
#if 0
/* Damn: json_tags_for_rid() only works for commits.
/* Damn: json_tags_for_rid() only works for commits.
FIXME: extend json_tags_for_rid() to accept file rids and then
implement this loop to add the tags to each object.
*/
FIXME: extend json_tags_for_rid() to accept file rids and then
implement this loop to add the tags to each object.
*/
while( SQLITE_ROW == db_step(&q) ){
checkinV = cson_sqlite3_row_to_object( q.pStmt );
if(!checkinV){
continue;
}
if(!tagKey) {
tagKey = cson_new_string("tags",4);
json_gc_add("artifact/file/tags", cson_string_value(tagKey))
/*avoids a potential lifetime issue*/;
}
checkin = cson_value_get_object(checkinV);
cson_object_set_s(checkin, tagKey, json_tags_for_rid(rid,0));
cson_array_append( checkin_arr, checkinV );
}
while( SQLITE_ROW == db_step(&q) ){
checkinV = cson_sqlite3_row_to_object( q.pStmt );
if(!checkinV){
continue;
}
if(!tagKey) {
tagKey = cson_new_string("tags",4);
json_gc_add("artifact/file/tags", cson_string_value(tagKey))
/*avoids a potential lifetime issue*/;
}
checkin = cson_value_get_object(checkinV);
cson_object_set_s(checkin, tagKey, json_tags_for_rid(rid,0));
cson_array_append( checkin_arr, checkinV );
}
#else
json_stmt_to_array_of_obj( &q, checkin_list );
json_stmt_to_array_of_obj( &q, cson_array_value(checkin_arr) );
#endif
db_finalize(&q);
db_finalize(&q);
}
return payV;
}
/*
** Impl of /json/artifact. This basically just determines the type of
** an artifact and forwards the real work to another function.
*/
|