Fossil SCM
more consolidation of timeline/artifact code.
Commit
cc444a02cd9cc4b3fb9aa7d4848e9386f250fd15
Parent
22fc0ab81bf965c…
2 files changed
+34
-18
+7
-27
+34
-18
| --- src/json_artifact.c | ||
| +++ src/json_artifact.c | ||
| @@ -5,15 +5,15 @@ | ||
| 5 | 5 | #if INTERFACE |
| 6 | 6 | #include "json_detail.h" |
| 7 | 7 | #endif |
| 8 | 8 | |
| 9 | 9 | /* |
| 10 | -** Internal callback for /json/artifact handlers. rid and uid refer to | |
| 11 | -** the rid/uid of a given type of artifact, and each callback is | |
| 10 | +** Internal callback for /json/artifact handlers. rid refers to | |
| 11 | +** the rid of a given type of artifact, and each callback is | |
| 12 | 12 | ** specialized to return a JSON form of one type of artifact. |
| 13 | 13 | */ |
| 14 | -typedef cson_value * (*artifact_f)( int rid, char const * uid ); | |
| 14 | +typedef cson_value * (*artifact_f)( int rid ); | |
| 15 | 15 | |
| 16 | 16 | typedef struct ArtifactDispatchEntry { |
| 17 | 17 | /** |
| 18 | 18 | Artifact type name, e.g. "checkin". |
| 19 | 19 | */ |
| @@ -35,68 +35,84 @@ | ||
| 35 | 35 | ** Generates an artifact Object for the given rid/zUuid. rid |
| 36 | 36 | ** must refer to a Checkin. |
| 37 | 37 | ** |
| 38 | 38 | ** Returned value is NULL or an Object owned by the caller. |
| 39 | 39 | */ |
| 40 | -cson_value * json_artifact_for_ci( int rid, char const * zUuid, char showFiles ){ | |
| 40 | +cson_value * json_artifact_for_ci( int rid, char showFiles ){ | |
| 41 | 41 | char const * zParent = NULL; |
| 42 | 42 | cson_value * v = NULL; |
| 43 | 43 | Stmt q; |
| 44 | - assert( NULL != zUuid ); | |
| 44 | + static cson_value * eventTypeLabel = NULL; | |
| 45 | + if(!eventTypeLabel){ | |
| 46 | + eventTypeLabel = json_new_string("commit"); | |
| 47 | + json_gc_add("$EVENT_TYPE_LABEL(commit)", eventTypeLabel, 1); | |
| 48 | + } | |
| 45 | 49 | zParent = db_text(0, |
| 46 | 50 | "SELECT uuid FROM plink, blob" |
| 47 | 51 | " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim", |
| 48 | 52 | rid |
| 49 | 53 | ); |
| 50 | 54 | |
| 51 | 55 | db_prepare(&q, |
| 52 | - "SELECT uuid, mtime, user, comment," | |
| 53 | - " omtime" | |
| 54 | - " FROM blob, event" | |
| 56 | + "SELECT uuid, " | |
| 57 | + " strftime('%%s',mtime), " | |
| 58 | + " user, " | |
| 59 | + " comment," | |
| 60 | + " strftime('%%s',omtime)" | |
| 61 | + " FROM blob, event" | |
| 55 | 62 | " WHERE blob.rid=%d" |
| 56 | 63 | " AND event.objid=%d", |
| 57 | 64 | rid, rid |
| 58 | 65 | ); |
| 59 | 66 | if( db_step(&q)==SQLITE_ROW ){ |
| 60 | 67 | cson_object * o; |
| 61 | 68 | cson_value * tmpV = NULL; |
| 62 | 69 | v = cson_value_new_object(); |
| 63 | 70 | o = cson_value_get_object(v); |
| 64 | - /*const char *zUuid = db_column_text(&q, 0);*/ | |
| 71 | + const char *zUuid = db_column_text(&q, 0); | |
| 65 | 72 | char * zTmp; |
| 66 | 73 | const char *zUser; |
| 67 | 74 | const char *zComment; |
| 68 | 75 | char * zEUser, * zEComment; |
| 69 | 76 | int mtime, omtime; |
| 70 | 77 | #define SET(K,V) cson_object_set(o,(K), (V)) |
| 71 | - SET("isLeaf", cson_value_new_bool(is_a_leaf(rid))); | |
| 78 | + SET("artifactType", eventTypeLabel ); | |
| 72 | 79 | SET("uuid",json_new_string(zUuid)); |
| 80 | + SET("isLeaf", cson_value_new_bool(is_a_leaf(rid))); | |
| 73 | 81 | zUser = db_column_text(&q,2); |
| 74 | - SET("user",json_new_string(zUser)); | |
| 75 | 82 | zEUser = db_text(0, |
| 76 | 83 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 77 | 84 | TAG_USER, rid); |
| 78 | 85 | if(zEUser){ |
| 79 | - SET("editedBy", json_new_string(zEUser)); | |
| 86 | + SET("user", json_new_string(zEUser)); | |
| 87 | + if(0!=strcmp(zEUser,zUser)){ | |
| 88 | + SET("originUser",json_new_string(zUser)); | |
| 89 | + } | |
| 80 | 90 | free(zEUser); |
| 91 | + }else{ | |
| 92 | + SET("user",json_new_string(zUser)); | |
| 81 | 93 | } |
| 82 | 94 | |
| 83 | 95 | zComment = db_column_text(&q,3); |
| 84 | - SET("comment",json_new_string(zComment)); | |
| 85 | 96 | zEComment = db_text(0, |
| 86 | 97 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 87 | 98 | TAG_COMMENT, rid); |
| 88 | 99 | if(zEComment){ |
| 89 | - SET("editedComment", json_new_string(zEComment)); | |
| 100 | + SET("comment",json_new_string(zEComment)); | |
| 101 | + if(0 != strcmp(zEComment,zComment)){ | |
| 102 | + SET("originComment", json_new_string(zComment)); | |
| 103 | + } | |
| 90 | 104 | free(zEComment); |
| 105 | + }else{ | |
| 106 | + SET("comment",json_new_string(zComment)); | |
| 91 | 107 | } |
| 92 | 108 | |
| 93 | 109 | mtime = db_column_int(&q,1); |
| 94 | 110 | SET("mtime",json_new_int(mtime)); |
| 95 | 111 | omtime = db_column_int(&q,4); |
| 96 | 112 | if(omtime && (omtime!=mtime)){ |
| 97 | - SET("omtime",json_new_int(omtime)); | |
| 113 | + SET("originTime",json_new_int(omtime)); | |
| 98 | 114 | } |
| 99 | 115 | |
| 100 | 116 | if(zParent){ |
| 101 | 117 | SET("parentUuid", json_new_string(zParent)); |
| 102 | 118 | } |
| @@ -121,12 +137,12 @@ | ||
| 121 | 137 | } |
| 122 | 138 | |
| 123 | 139 | /* |
| 124 | 140 | ** Sub-impl of /json/artifact for checkins. |
| 125 | 141 | */ |
| 126 | -static cson_value * json_artifact_ci( int rid, char const * zUuid ){ | |
| 127 | - return json_artifact_for_ci(rid, zUuid, 1); | |
| 142 | +static cson_value * json_artifact_ci( int rid ){ | |
| 143 | + return json_artifact_for_ci(rid, 1); | |
| 128 | 144 | } |
| 129 | 145 | |
| 130 | 146 | static char perms_can_read(){ |
| 131 | 147 | return g.perm.Read ? 1 : 0; |
| 132 | 148 | } |
| @@ -224,11 +240,11 @@ | ||
| 224 | 240 | }else{ |
| 225 | 241 | cson_value * entry; |
| 226 | 242 | if( ! (*disp->permCheck)() ){ |
| 227 | 243 | break; |
| 228 | 244 | } |
| 229 | - entry = (*disp->func)(rid, zUuid); | |
| 245 | + entry = (*disp->func)(rid); | |
| 230 | 246 | if(entry){ |
| 231 | 247 | cson_object_set(pay, "artifact", entry); |
| 232 | 248 | } |
| 233 | 249 | break; |
| 234 | 250 | } |
| 235 | 251 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -5,15 +5,15 @@ | |
| 5 | #if INTERFACE |
| 6 | #include "json_detail.h" |
| 7 | #endif |
| 8 | |
| 9 | /* |
| 10 | ** Internal callback for /json/artifact handlers. rid and uid refer to |
| 11 | ** the rid/uid of a given type of artifact, and each callback is |
| 12 | ** specialized to return a JSON form of one type of artifact. |
| 13 | */ |
| 14 | typedef cson_value * (*artifact_f)( int rid, char const * uid ); |
| 15 | |
| 16 | typedef struct ArtifactDispatchEntry { |
| 17 | /** |
| 18 | Artifact type name, e.g. "checkin". |
| 19 | */ |
| @@ -35,68 +35,84 @@ | |
| 35 | ** Generates an artifact Object for the given rid/zUuid. rid |
| 36 | ** must refer to a Checkin. |
| 37 | ** |
| 38 | ** Returned value is NULL or an Object owned by the caller. |
| 39 | */ |
| 40 | cson_value * json_artifact_for_ci( int rid, char const * zUuid, char showFiles ){ |
| 41 | char const * zParent = NULL; |
| 42 | cson_value * v = NULL; |
| 43 | Stmt q; |
| 44 | assert( NULL != zUuid ); |
| 45 | zParent = db_text(0, |
| 46 | "SELECT uuid FROM plink, blob" |
| 47 | " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim", |
| 48 | rid |
| 49 | ); |
| 50 | |
| 51 | db_prepare(&q, |
| 52 | "SELECT uuid, mtime, user, comment," |
| 53 | " omtime" |
| 54 | " FROM blob, event" |
| 55 | " WHERE blob.rid=%d" |
| 56 | " AND event.objid=%d", |
| 57 | rid, rid |
| 58 | ); |
| 59 | if( db_step(&q)==SQLITE_ROW ){ |
| 60 | cson_object * o; |
| 61 | cson_value * tmpV = NULL; |
| 62 | v = cson_value_new_object(); |
| 63 | o = cson_value_get_object(v); |
| 64 | /*const char *zUuid = db_column_text(&q, 0);*/ |
| 65 | char * zTmp; |
| 66 | const char *zUser; |
| 67 | const char *zComment; |
| 68 | char * zEUser, * zEComment; |
| 69 | int mtime, omtime; |
| 70 | #define SET(K,V) cson_object_set(o,(K), (V)) |
| 71 | SET("isLeaf", cson_value_new_bool(is_a_leaf(rid))); |
| 72 | SET("uuid",json_new_string(zUuid)); |
| 73 | zUser = db_column_text(&q,2); |
| 74 | SET("user",json_new_string(zUser)); |
| 75 | zEUser = db_text(0, |
| 76 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 77 | TAG_USER, rid); |
| 78 | if(zEUser){ |
| 79 | SET("editedBy", json_new_string(zEUser)); |
| 80 | free(zEUser); |
| 81 | } |
| 82 | |
| 83 | zComment = db_column_text(&q,3); |
| 84 | SET("comment",json_new_string(zComment)); |
| 85 | zEComment = db_text(0, |
| 86 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 87 | TAG_COMMENT, rid); |
| 88 | if(zEComment){ |
| 89 | SET("editedComment", json_new_string(zEComment)); |
| 90 | free(zEComment); |
| 91 | } |
| 92 | |
| 93 | mtime = db_column_int(&q,1); |
| 94 | SET("mtime",json_new_int(mtime)); |
| 95 | omtime = db_column_int(&q,4); |
| 96 | if(omtime && (omtime!=mtime)){ |
| 97 | SET("omtime",json_new_int(omtime)); |
| 98 | } |
| 99 | |
| 100 | if(zParent){ |
| 101 | SET("parentUuid", json_new_string(zParent)); |
| 102 | } |
| @@ -121,12 +137,12 @@ | |
| 121 | } |
| 122 | |
| 123 | /* |
| 124 | ** Sub-impl of /json/artifact for checkins. |
| 125 | */ |
| 126 | static cson_value * json_artifact_ci( int rid, char const * zUuid ){ |
| 127 | return json_artifact_for_ci(rid, zUuid, 1); |
| 128 | } |
| 129 | |
| 130 | static char perms_can_read(){ |
| 131 | return g.perm.Read ? 1 : 0; |
| 132 | } |
| @@ -224,11 +240,11 @@ | |
| 224 | }else{ |
| 225 | cson_value * entry; |
| 226 | if( ! (*disp->permCheck)() ){ |
| 227 | break; |
| 228 | } |
| 229 | entry = (*disp->func)(rid, zUuid); |
| 230 | if(entry){ |
| 231 | cson_object_set(pay, "artifact", entry); |
| 232 | } |
| 233 | break; |
| 234 | } |
| 235 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -5,15 +5,15 @@ | |
| 5 | #if INTERFACE |
| 6 | #include "json_detail.h" |
| 7 | #endif |
| 8 | |
| 9 | /* |
| 10 | ** Internal callback for /json/artifact handlers. rid refers to |
| 11 | ** the rid of a given type of artifact, and each callback is |
| 12 | ** specialized to return a JSON form of one type of artifact. |
| 13 | */ |
| 14 | typedef cson_value * (*artifact_f)( int rid ); |
| 15 | |
| 16 | typedef struct ArtifactDispatchEntry { |
| 17 | /** |
| 18 | Artifact type name, e.g. "checkin". |
| 19 | */ |
| @@ -35,68 +35,84 @@ | |
| 35 | ** Generates an artifact Object for the given rid/zUuid. rid |
| 36 | ** must refer to a Checkin. |
| 37 | ** |
| 38 | ** Returned value is NULL or an Object owned by the caller. |
| 39 | */ |
| 40 | cson_value * json_artifact_for_ci( int rid, char showFiles ){ |
| 41 | char const * zParent = NULL; |
| 42 | cson_value * v = NULL; |
| 43 | Stmt q; |
| 44 | static cson_value * eventTypeLabel = NULL; |
| 45 | if(!eventTypeLabel){ |
| 46 | eventTypeLabel = json_new_string("commit"); |
| 47 | json_gc_add("$EVENT_TYPE_LABEL(commit)", eventTypeLabel, 1); |
| 48 | } |
| 49 | zParent = db_text(0, |
| 50 | "SELECT uuid FROM plink, blob" |
| 51 | " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim", |
| 52 | rid |
| 53 | ); |
| 54 | |
| 55 | db_prepare(&q, |
| 56 | "SELECT uuid, " |
| 57 | " strftime('%%s',mtime), " |
| 58 | " user, " |
| 59 | " comment," |
| 60 | " strftime('%%s',omtime)" |
| 61 | " FROM blob, event" |
| 62 | " WHERE blob.rid=%d" |
| 63 | " AND event.objid=%d", |
| 64 | rid, rid |
| 65 | ); |
| 66 | if( db_step(&q)==SQLITE_ROW ){ |
| 67 | cson_object * o; |
| 68 | cson_value * tmpV = NULL; |
| 69 | v = cson_value_new_object(); |
| 70 | o = cson_value_get_object(v); |
| 71 | const char *zUuid = db_column_text(&q, 0); |
| 72 | char * zTmp; |
| 73 | const char *zUser; |
| 74 | const char *zComment; |
| 75 | char * zEUser, * zEComment; |
| 76 | int mtime, omtime; |
| 77 | #define SET(K,V) cson_object_set(o,(K), (V)) |
| 78 | SET("artifactType", eventTypeLabel ); |
| 79 | SET("uuid",json_new_string(zUuid)); |
| 80 | SET("isLeaf", cson_value_new_bool(is_a_leaf(rid))); |
| 81 | zUser = db_column_text(&q,2); |
| 82 | zEUser = db_text(0, |
| 83 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 84 | TAG_USER, rid); |
| 85 | if(zEUser){ |
| 86 | SET("user", json_new_string(zEUser)); |
| 87 | if(0!=strcmp(zEUser,zUser)){ |
| 88 | SET("originUser",json_new_string(zUser)); |
| 89 | } |
| 90 | free(zEUser); |
| 91 | }else{ |
| 92 | SET("user",json_new_string(zUser)); |
| 93 | } |
| 94 | |
| 95 | zComment = db_column_text(&q,3); |
| 96 | zEComment = db_text(0, |
| 97 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 98 | TAG_COMMENT, rid); |
| 99 | if(zEComment){ |
| 100 | SET("comment",json_new_string(zEComment)); |
| 101 | if(0 != strcmp(zEComment,zComment)){ |
| 102 | SET("originComment", json_new_string(zComment)); |
| 103 | } |
| 104 | free(zEComment); |
| 105 | }else{ |
| 106 | SET("comment",json_new_string(zComment)); |
| 107 | } |
| 108 | |
| 109 | mtime = db_column_int(&q,1); |
| 110 | SET("mtime",json_new_int(mtime)); |
| 111 | omtime = db_column_int(&q,4); |
| 112 | if(omtime && (omtime!=mtime)){ |
| 113 | SET("originTime",json_new_int(omtime)); |
| 114 | } |
| 115 | |
| 116 | if(zParent){ |
| 117 | SET("parentUuid", json_new_string(zParent)); |
| 118 | } |
| @@ -121,12 +137,12 @@ | |
| 137 | } |
| 138 | |
| 139 | /* |
| 140 | ** Sub-impl of /json/artifact for checkins. |
| 141 | */ |
| 142 | static cson_value * json_artifact_ci( int rid ){ |
| 143 | return json_artifact_for_ci(rid, 1); |
| 144 | } |
| 145 | |
| 146 | static char perms_can_read(){ |
| 147 | return g.perm.Read ? 1 : 0; |
| 148 | } |
| @@ -224,11 +240,11 @@ | |
| 240 | }else{ |
| 241 | cson_value * entry; |
| 242 | if( ! (*disp->permCheck)() ){ |
| 243 | break; |
| 244 | } |
| 245 | entry = (*disp->func)(rid); |
| 246 | if(entry){ |
| 247 | cson_object_set(pay, "artifact", entry); |
| 248 | } |
| 249 | break; |
| 250 | } |
| 251 |
+7
-27
| --- src/json_timeline.c | ||
| +++ src/json_timeline.c | ||
| @@ -317,41 +317,21 @@ | ||
| 317 | 317 | tmp = listV; |
| 318 | 318 | SET("timeline"); |
| 319 | 319 | while( (SQLITE_ROW == db_step(&q) )){ |
| 320 | 320 | /* convert each row into a JSON object...*/ |
| 321 | 321 | int const rid = db_column_int(&q,0); |
| 322 | - cson_value * rowV = cson_sqlite3_row_to_object(q.pStmt); | |
| 322 | + cson_value * rowV = json_artifact_for_ci(rid, showFiles); | |
| 323 | 323 | cson_object * row = cson_value_get_object(rowV); |
| 324 | - cson_value * tagList = NULL; | |
| 325 | - if(!row && !warnRowToJsonFailed){ | |
| 326 | - warnRowToJsonFailed = 1; | |
| 327 | - json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, | |
| 328 | - "Could not convert at least one timeline result row to JSON." ); | |
| 324 | + if(!row){ | |
| 325 | + if( !warnRowToJsonFailed ){ | |
| 326 | + warnRowToJsonFailed = 1; | |
| 327 | + json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, | |
| 328 | + "Could not convert at least one timeline result row to JSON." ); | |
| 329 | + } | |
| 329 | 330 | continue; |
| 330 | 331 | } |
| 331 | - /* Split tags string field into JSON Array... */ | |
| 332 | 332 | cson_array_append(list, rowV); |
| 333 | - tmp = json_tags_for_rid(rid); | |
| 334 | - if(tmp){ | |
| 335 | - cson_object_set(row,"tags",tmp); | |
| 336 | - } | |
| 337 | - | |
| 338 | - /* replace isLeaf int w/ JSON bool */ | |
| 339 | - tmp = cson_object_get(row,"isLeaf"); | |
| 340 | - if(tmp && cson_value_is_integer(tmp)){ | |
| 341 | - cson_object_set(row,"isLeaf", | |
| 342 | - cson_value_get_integer(tmp) | |
| 343 | - ? cson_value_true() | |
| 344 | - : cson_value_false()); | |
| 345 | - tmp = NULL; | |
| 346 | - } | |
| 347 | - if( showFiles ){ | |
| 348 | - cson_value * flist = json_get_changed_files(rid); | |
| 349 | - if(flist){ | |
| 350 | - cson_object_set(row,"files",flist); | |
| 351 | - } | |
| 352 | - } | |
| 353 | 333 | } |
| 354 | 334 | #undef SET |
| 355 | 335 | goto ok; |
| 356 | 336 | error: |
| 357 | 337 | assert( 0 != g.json.resultCode ); |
| 358 | 338 |
| --- src/json_timeline.c | |
| +++ src/json_timeline.c | |
| @@ -317,41 +317,21 @@ | |
| 317 | tmp = listV; |
| 318 | SET("timeline"); |
| 319 | while( (SQLITE_ROW == db_step(&q) )){ |
| 320 | /* convert each row into a JSON object...*/ |
| 321 | int const rid = db_column_int(&q,0); |
| 322 | cson_value * rowV = cson_sqlite3_row_to_object(q.pStmt); |
| 323 | cson_object * row = cson_value_get_object(rowV); |
| 324 | cson_value * tagList = NULL; |
| 325 | if(!row && !warnRowToJsonFailed){ |
| 326 | warnRowToJsonFailed = 1; |
| 327 | json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, |
| 328 | "Could not convert at least one timeline result row to JSON." ); |
| 329 | continue; |
| 330 | } |
| 331 | /* Split tags string field into JSON Array... */ |
| 332 | cson_array_append(list, rowV); |
| 333 | tmp = json_tags_for_rid(rid); |
| 334 | if(tmp){ |
| 335 | cson_object_set(row,"tags",tmp); |
| 336 | } |
| 337 | |
| 338 | /* replace isLeaf int w/ JSON bool */ |
| 339 | tmp = cson_object_get(row,"isLeaf"); |
| 340 | if(tmp && cson_value_is_integer(tmp)){ |
| 341 | cson_object_set(row,"isLeaf", |
| 342 | cson_value_get_integer(tmp) |
| 343 | ? cson_value_true() |
| 344 | : cson_value_false()); |
| 345 | tmp = NULL; |
| 346 | } |
| 347 | if( showFiles ){ |
| 348 | cson_value * flist = json_get_changed_files(rid); |
| 349 | if(flist){ |
| 350 | cson_object_set(row,"files",flist); |
| 351 | } |
| 352 | } |
| 353 | } |
| 354 | #undef SET |
| 355 | goto ok; |
| 356 | error: |
| 357 | assert( 0 != g.json.resultCode ); |
| 358 |
| --- src/json_timeline.c | |
| +++ src/json_timeline.c | |
| @@ -317,41 +317,21 @@ | |
| 317 | tmp = listV; |
| 318 | SET("timeline"); |
| 319 | while( (SQLITE_ROW == db_step(&q) )){ |
| 320 | /* convert each row into a JSON object...*/ |
| 321 | int const rid = db_column_int(&q,0); |
| 322 | cson_value * rowV = json_artifact_for_ci(rid, showFiles); |
| 323 | cson_object * row = cson_value_get_object(rowV); |
| 324 | if(!row){ |
| 325 | if( !warnRowToJsonFailed ){ |
| 326 | warnRowToJsonFailed = 1; |
| 327 | json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED, |
| 328 | "Could not convert at least one timeline result row to JSON." ); |
| 329 | } |
| 330 | continue; |
| 331 | } |
| 332 | cson_array_append(list, rowV); |
| 333 | } |
| 334 | #undef SET |
| 335 | goto ok; |
| 336 | error: |
| 337 | assert( 0 != g.json.resultCode ); |
| 338 |