Fossil SCM
Added uuid=... option to the as-yet-undocumented /json/finfo.
Commit
64721991671aec654e5bf0e10e6ba18528d15b7c
Parent
c685a35eb08a1c4…
1 file changed
+40
-8
+40
-8
| --- src/json_finfo.c | ||
| +++ src/json_finfo.c | ||
| @@ -35,25 +35,32 @@ | ||
| 35 | 35 | Stmt q = empty_Stmt; |
| 36 | 36 | char const * zAfter = NULL; |
| 37 | 37 | char const * zBefore = NULL; |
| 38 | 38 | int limit = -1; |
| 39 | 39 | int currentRow = 0; |
| 40 | + char const * zCheckin = NULL; | |
| 40 | 41 | if(!g.perm.Read){ |
| 41 | 42 | json_set_err(FSL_JSON_E_DENIED,"Requires 'o' privileges."); |
| 42 | 43 | return NULL; |
| 43 | 44 | } |
| 44 | 45 | json_warn( FSL_JSON_W_UNKNOWN, "Achtung: the output of the finfo command is up for change."); |
| 45 | - zFilename = json_find_option_cstr2("name",NULL,NULL, | |
| 46 | - g.json.dispatchDepth+1); | |
| 47 | 46 | |
| 47 | + /* For the "name" argument we have to jump through some hoops to make sure that we don't | |
| 48 | + get the fossil-internally-assigned "name" option. | |
| 49 | + */ | |
| 50 | + zFilename = json_find_option_cstr("name",NULL,NULL); | |
| 51 | + if(!zFilename && !g.isHTTP){ | |
| 52 | + zFilename = json_command_arg(g.json.dispatchDepth+1); | |
| 53 | + } | |
| 48 | 54 | if(!zFilename){ |
| 49 | 55 | json_set_err(FSL_JSON_E_MISSING_ARGS, "Missing 'name' parameter."); |
| 50 | 56 | return NULL; |
| 51 | 57 | } |
| 52 | 58 | zBefore = json_find_option_cstr("before",NULL,"b"); |
| 53 | 59 | zAfter = json_find_option_cstr("after",NULL,"a"); |
| 54 | 60 | limit = json_find_option_int("limit",NULL,"n", -1); |
| 61 | + zCheckin = json_find_option_cstr("checkin",NULL,"ci"); | |
| 55 | 62 | |
| 56 | 63 | blob_appendf(&sql, |
| 57 | 64 | "SELECT b.uuid," |
| 58 | 65 | " ci.uuid," |
| 59 | 66 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| @@ -71,16 +78,32 @@ | ||
| 71 | 78 | " AND b.rid=mlink.fid" |
| 72 | 79 | " AND event.objid=mlink.mid" |
| 73 | 80 | " AND event.objid=ci.rid", |
| 74 | 81 | zFilename, filename_collation() |
| 75 | 82 | ); |
| 76 | - if( zAfter ){ | |
| 77 | - blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter); | |
| 78 | - }else if( zBefore ){ | |
| 79 | - blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore); | |
| 83 | + | |
| 84 | + if( zCheckin && *zCheckin ){ | |
| 85 | + char * zU = NULL; | |
| 86 | + int rc = name_to_uuid2( zCheckin, "ci", &zU ); | |
| 87 | + printf("zCheckin=[%s], zU=[%s]", zCheckin, zU); | |
| 88 | + if(rc<=0){ | |
| 89 | + json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND, | |
| 90 | + "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found"); | |
| 91 | + blob_reset(&sql); | |
| 92 | + return NULL; | |
| 93 | + } | |
| 94 | + blob_appendf(&sql, " AND ci.uuid='%q'", zU); | |
| 95 | + free(zU); | |
| 96 | + }else{ | |
| 97 | + if( zAfter ){ | |
| 98 | + blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter); | |
| 99 | + }else if( zBefore ){ | |
| 100 | + blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore); | |
| 101 | + } | |
| 80 | 102 | } |
| 81 | 103 | blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); |
| 104 | + /*printf("SQL=\n%s\n",blob_str(&sql));*/ | |
| 82 | 105 | db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding |
| 83 | 106 | SQL escapes*/); |
| 84 | 107 | blob_reset(&sql); |
| 85 | 108 | |
| 86 | 109 | pay = cson_new_object(); |
| @@ -92,11 +115,11 @@ | ||
| 92 | 115 | cson_object_set(pay, "checkins", cson_array_value(checkins)); |
| 93 | 116 | while( db_step(&q)==SQLITE_ROW ){ |
| 94 | 117 | cson_object * row = cson_new_object(); |
| 95 | 118 | cson_array_append( checkins, cson_object_value(row) ); |
| 96 | 119 | cson_object_set(row, "checkin", json_new_string( db_column_text(&q,1) )); |
| 97 | - cson_object_set(row, "artifact", json_new_string( db_column_text(&q,2) )); | |
| 120 | + cson_object_set(row, "uuid", json_new_string( db_column_text(&q,2) )); | |
| 98 | 121 | /*cson_object_set(row, "parentArtifact", json_new_string( db_column_text(&q,6) ));*/ |
| 99 | 122 | cson_object_set(row, "mtime", json_new_int( db_column_int(&q,3) )); |
| 100 | 123 | cson_object_set(row, "user", json_new_string( db_column_text(&q,4) )); |
| 101 | 124 | cson_object_set(row, "comment", json_new_string( db_column_text(&q,5) )); |
| 102 | 125 | /*cson_object_set(row, "bgColor", json_new_string( db_column_text(&q,7) ));*/ |
| @@ -104,11 +127,20 @@ | ||
| 104 | 127 | break; |
| 105 | 128 | } |
| 106 | 129 | } |
| 107 | 130 | db_finalize(&q); |
| 108 | 131 | |
| 109 | - return cson_object_value(pay); | |
| 132 | + if( !cson_array_length_get(checkins) ){ | |
| 133 | + json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, | |
| 134 | + zCheckin | |
| 135 | + ? "File not part of the given checkin." | |
| 136 | + : "File not found." ); | |
| 137 | + cson_free_object(pay); | |
| 138 | + pay = NULL; | |
| 139 | + } | |
| 140 | + | |
| 141 | + return pay ? cson_object_value(pay) : NULL; | |
| 110 | 142 | } |
| 111 | 143 | |
| 112 | 144 | |
| 113 | 145 | |
| 114 | 146 | #endif /* FOSSIL_ENABLE_JSON */ |
| 115 | 147 |
| --- src/json_finfo.c | |
| +++ src/json_finfo.c | |
| @@ -35,25 +35,32 @@ | |
| 35 | Stmt q = empty_Stmt; |
| 36 | char const * zAfter = NULL; |
| 37 | char const * zBefore = NULL; |
| 38 | int limit = -1; |
| 39 | int currentRow = 0; |
| 40 | if(!g.perm.Read){ |
| 41 | json_set_err(FSL_JSON_E_DENIED,"Requires 'o' privileges."); |
| 42 | return NULL; |
| 43 | } |
| 44 | json_warn( FSL_JSON_W_UNKNOWN, "Achtung: the output of the finfo command is up for change."); |
| 45 | zFilename = json_find_option_cstr2("name",NULL,NULL, |
| 46 | g.json.dispatchDepth+1); |
| 47 | |
| 48 | if(!zFilename){ |
| 49 | json_set_err(FSL_JSON_E_MISSING_ARGS, "Missing 'name' parameter."); |
| 50 | return NULL; |
| 51 | } |
| 52 | zBefore = json_find_option_cstr("before",NULL,"b"); |
| 53 | zAfter = json_find_option_cstr("after",NULL,"a"); |
| 54 | limit = json_find_option_int("limit",NULL,"n", -1); |
| 55 | |
| 56 | blob_appendf(&sql, |
| 57 | "SELECT b.uuid," |
| 58 | " ci.uuid," |
| 59 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| @@ -71,16 +78,32 @@ | |
| 71 | " AND b.rid=mlink.fid" |
| 72 | " AND event.objid=mlink.mid" |
| 73 | " AND event.objid=ci.rid", |
| 74 | zFilename, filename_collation() |
| 75 | ); |
| 76 | if( zAfter ){ |
| 77 | blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter); |
| 78 | }else if( zBefore ){ |
| 79 | blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore); |
| 80 | } |
| 81 | blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); |
| 82 | db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding |
| 83 | SQL escapes*/); |
| 84 | blob_reset(&sql); |
| 85 | |
| 86 | pay = cson_new_object(); |
| @@ -92,11 +115,11 @@ | |
| 92 | cson_object_set(pay, "checkins", cson_array_value(checkins)); |
| 93 | while( db_step(&q)==SQLITE_ROW ){ |
| 94 | cson_object * row = cson_new_object(); |
| 95 | cson_array_append( checkins, cson_object_value(row) ); |
| 96 | cson_object_set(row, "checkin", json_new_string( db_column_text(&q,1) )); |
| 97 | cson_object_set(row, "artifact", json_new_string( db_column_text(&q,2) )); |
| 98 | /*cson_object_set(row, "parentArtifact", json_new_string( db_column_text(&q,6) ));*/ |
| 99 | cson_object_set(row, "mtime", json_new_int( db_column_int(&q,3) )); |
| 100 | cson_object_set(row, "user", json_new_string( db_column_text(&q,4) )); |
| 101 | cson_object_set(row, "comment", json_new_string( db_column_text(&q,5) )); |
| 102 | /*cson_object_set(row, "bgColor", json_new_string( db_column_text(&q,7) ));*/ |
| @@ -104,11 +127,20 @@ | |
| 104 | break; |
| 105 | } |
| 106 | } |
| 107 | db_finalize(&q); |
| 108 | |
| 109 | return cson_object_value(pay); |
| 110 | } |
| 111 | |
| 112 | |
| 113 | |
| 114 | #endif /* FOSSIL_ENABLE_JSON */ |
| 115 |
| --- src/json_finfo.c | |
| +++ src/json_finfo.c | |
| @@ -35,25 +35,32 @@ | |
| 35 | Stmt q = empty_Stmt; |
| 36 | char const * zAfter = NULL; |
| 37 | char const * zBefore = NULL; |
| 38 | int limit = -1; |
| 39 | int currentRow = 0; |
| 40 | char const * zCheckin = NULL; |
| 41 | if(!g.perm.Read){ |
| 42 | json_set_err(FSL_JSON_E_DENIED,"Requires 'o' privileges."); |
| 43 | return NULL; |
| 44 | } |
| 45 | json_warn( FSL_JSON_W_UNKNOWN, "Achtung: the output of the finfo command is up for change."); |
| 46 | |
| 47 | /* For the "name" argument we have to jump through some hoops to make sure that we don't |
| 48 | get the fossil-internally-assigned "name" option. |
| 49 | */ |
| 50 | zFilename = json_find_option_cstr("name",NULL,NULL); |
| 51 | if(!zFilename && !g.isHTTP){ |
| 52 | zFilename = json_command_arg(g.json.dispatchDepth+1); |
| 53 | } |
| 54 | if(!zFilename){ |
| 55 | json_set_err(FSL_JSON_E_MISSING_ARGS, "Missing 'name' parameter."); |
| 56 | return NULL; |
| 57 | } |
| 58 | zBefore = json_find_option_cstr("before",NULL,"b"); |
| 59 | zAfter = json_find_option_cstr("after",NULL,"a"); |
| 60 | limit = json_find_option_int("limit",NULL,"n", -1); |
| 61 | zCheckin = json_find_option_cstr("checkin",NULL,"ci"); |
| 62 | |
| 63 | blob_appendf(&sql, |
| 64 | "SELECT b.uuid," |
| 65 | " ci.uuid," |
| 66 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| @@ -71,16 +78,32 @@ | |
| 78 | " AND b.rid=mlink.fid" |
| 79 | " AND event.objid=mlink.mid" |
| 80 | " AND event.objid=ci.rid", |
| 81 | zFilename, filename_collation() |
| 82 | ); |
| 83 | |
| 84 | if( zCheckin && *zCheckin ){ |
| 85 | char * zU = NULL; |
| 86 | int rc = name_to_uuid2( zCheckin, "ci", &zU ); |
| 87 | printf("zCheckin=[%s], zU=[%s]", zCheckin, zU); |
| 88 | if(rc<=0){ |
| 89 | json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 90 | "Checkin UUID %s.", (rc<0) ? "is ambiguous" : "not found"); |
| 91 | blob_reset(&sql); |
| 92 | return NULL; |
| 93 | } |
| 94 | blob_appendf(&sql, " AND ci.uuid='%q'", zU); |
| 95 | free(zU); |
| 96 | }else{ |
| 97 | if( zAfter ){ |
| 98 | blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zAfter); |
| 99 | }else if( zBefore ){ |
| 100 | blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zBefore); |
| 101 | } |
| 102 | } |
| 103 | blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); |
| 104 | /*printf("SQL=\n%s\n",blob_str(&sql));*/ |
| 105 | db_prepare(&q, "%s", blob_str(&sql)/*extra %s to avoid double-expanding |
| 106 | SQL escapes*/); |
| 107 | blob_reset(&sql); |
| 108 | |
| 109 | pay = cson_new_object(); |
| @@ -92,11 +115,11 @@ | |
| 115 | cson_object_set(pay, "checkins", cson_array_value(checkins)); |
| 116 | while( db_step(&q)==SQLITE_ROW ){ |
| 117 | cson_object * row = cson_new_object(); |
| 118 | cson_array_append( checkins, cson_object_value(row) ); |
| 119 | cson_object_set(row, "checkin", json_new_string( db_column_text(&q,1) )); |
| 120 | cson_object_set(row, "uuid", json_new_string( db_column_text(&q,2) )); |
| 121 | /*cson_object_set(row, "parentArtifact", json_new_string( db_column_text(&q,6) ));*/ |
| 122 | cson_object_set(row, "mtime", json_new_int( db_column_int(&q,3) )); |
| 123 | cson_object_set(row, "user", json_new_string( db_column_text(&q,4) )); |
| 124 | cson_object_set(row, "comment", json_new_string( db_column_text(&q,5) )); |
| 125 | /*cson_object_set(row, "bgColor", json_new_string( db_column_text(&q,7) ));*/ |
| @@ -104,11 +127,20 @@ | |
| 127 | break; |
| 128 | } |
| 129 | } |
| 130 | db_finalize(&q); |
| 131 | |
| 132 | if( !cson_array_length_get(checkins) ){ |
| 133 | json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 134 | zCheckin |
| 135 | ? "File not part of the given checkin." |
| 136 | : "File not found." ); |
| 137 | cson_free_object(pay); |
| 138 | pay = NULL; |
| 139 | } |
| 140 | |
| 141 | return pay ? cson_object_value(pay) : NULL; |
| 142 | } |
| 143 | |
| 144 | |
| 145 | |
| 146 | #endif /* FOSSIL_ENABLE_JSON */ |
| 147 |