Fossil SCM

fossil-scm / src / json_status.c
Source Blame History 198 lines
d1e4d10… stephan 1 #ifdef FOSSIL_ENABLE_JSON
d1e4d10… stephan 2 /*
d1e4d10… stephan 3 ** Copyright (c) 2013 D. Richard Hipp
d1e4d10… stephan 4 **
d1e4d10… stephan 5 ** This program is free software; you can redistribute it and/or
d1e4d10… stephan 6 ** modify it under the terms of the Simplified BSD License (also
d1e4d10… stephan 7 ** known as the "2-Clause License" or "FreeBSD License".)
d1e4d10… stephan 8 **
d1e4d10… stephan 9 ** This program is distributed in the hope that it will be useful,
d1e4d10… stephan 10 ** but without any warranty; without even the implied warranty of
d1e4d10… stephan 11 ** merchantability or fitness for a particular purpose.
d1e4d10… stephan 12 **
d1e4d10… stephan 13 ** Author contact information:
d1e4d10… stephan 14 ** [email protected]
d1e4d10… stephan 15 ** http://www.hwaci.com/drh/
d1e4d10… stephan 16 **
d1e4d10… stephan 17 */
d1e4d10… stephan 18
d1e4d10… stephan 19 #include "config.h"
d1e4d10… stephan 20 #include "json_status.h"
d1e4d10… stephan 21
d1e4d10… stephan 22 #if INTERFACE
d1e4d10… stephan 23 #include "json_detail.h"
d1e4d10… stephan 24 #endif
d1e4d10… stephan 25
d1e4d10… stephan 26 /*
d1e4d10… stephan 27 Reminder to check if a column exists:
d1e4d10… stephan 28
d1e4d10… stephan 29 PRAGMA table_info(table_name)
d1e4d10… stephan 30
d1e4d10… stephan 31 and search for a row where the 'name' field matches.
d1e4d10… stephan 32
d1e4d10… stephan 33 That assumes, of course, that table_info()'s output format
d1e4d10… stephan 34 is stable.
d1e4d10… stephan 35 */
d1e4d10… stephan 36
d1e4d10… stephan 37 /*
d1e4d10… stephan 38 ** Implementation of the /json/status page.
d1e4d10… stephan 39 **
d1e4d10… stephan 40 */
d1e4d10… stephan 41 cson_value * json_page_status(){
d1e4d10… stephan 42 Stmt q = empty_Stmt;
d1e4d10… stephan 43 cson_object * oPay;
d1e4d10… stephan 44 /*cson_object * files;*/
d1e4d10… stephan 45 int vid, nErr = 0;
d1e4d10… stephan 46 cson_object * tmpO;
d1e4d10… stephan 47 char * zTmp;
d1e4d10… stephan 48 i64 iMtime;
d1e4d10… stephan 49 cson_array * aFiles;
d1e4d10… stephan 50
e590547… jan.nijtmans 51 if(!db_open_local(0)){
d1e4d10… stephan 52 json_set_err(FSL_JSON_E_DB_NEEDS_CHECKOUT, NULL);
d1e4d10… stephan 53 return NULL;
d1e4d10… stephan 54 }
d1e4d10… stephan 55 oPay = cson_new_object();
d1e4d10… stephan 56 cson_object_set(oPay, "repository",
d1e4d10… stephan 57 json_new_string(db_repository_filename()));
d1e4d10… stephan 58 cson_object_set(oPay, "localRoot",
d1e4d10… stephan 59 json_new_string(g.zLocalRoot));
d1e4d10… stephan 60 vid = db_lget_int("checkout", 0);
d1e4d10… stephan 61 if(!vid){
d1e4d10… stephan 62 json_set_err( FSL_JSON_E_UNKNOWN, "Can this even happen?" );
d1e4d10… stephan 63 return 0;
d1e4d10… stephan 64 }
771e592… mark 65 vfile_check_signature(vid, 0);
d1e4d10… stephan 66 /* TODO: dupe show_common_info() state */
d1e4d10… stephan 67 tmpO = cson_new_object();
d1e4d10… stephan 68 cson_object_set(oPay, "checkout", cson_object_value(tmpO));
d1e4d10… stephan 69
d1e4d10… stephan 70 zTmp = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
d1e4d10… stephan 71 cson_object_set(tmpO, "uuid", json_new_string(zTmp) );
d1e4d10… stephan 72 free(zTmp);
d1e4d10… stephan 73
d1e4d10… stephan 74 cson_object_set( tmpO, "tags", json_tags_for_checkin_rid(vid, 0) );
9df71fe… jan.nijtmans 75
d1e4d10… stephan 76 /* FIXME: optimize the datetime/timestamp queries into 1 query. */
d1e4d10… stephan 77 zTmp = db_text(0, "SELECT datetime(mtime) || "
d1e4d10… stephan 78 "' UTC' FROM event WHERE objid=%d",
d1e4d10… stephan 79 vid);
d1e4d10… stephan 80 cson_object_set(tmpO, "datetime", json_new_string(zTmp));
d1e4d10… stephan 81 free(zTmp);
d1e4d10… stephan 82 iMtime = db_int64(0, "SELECT CAST(strftime('%%s',mtime) AS INTEGER) "
d1e4d10… stephan 83 "FROM event WHERE objid=%d", vid);
d1e4d10… stephan 84 cson_object_set(tmpO, "timestamp",
d1e4d10… stephan 85 cson_value_new_integer((cson_int_t)iMtime));
d1e4d10… stephan 86 #if 0
d1e4d10… stephan 87 /* TODO: add parent artifact info */
d1e4d10… stephan 88 tmpO = cson_new_object();
d1e4d10… stephan 89 cson_object_set( oPay, "parent", cson_object_value(tmpO) );
d1e4d10… stephan 90 cson_object_set( tmpO, "uuid", TODO );
d1e4d10… stephan 91 cson_object_set( tmpO, "timestamp", TODO );
d1e4d10… stephan 92 #endif
d1e4d10… stephan 93
d1e4d10… stephan 94 /* Now get the list of non-pristine files... */
d1e4d10… stephan 95 aFiles = cson_new_array();
d1e4d10… stephan 96 cson_object_set( oPay, "files", cson_array_value( aFiles ) );
d1e4d10… stephan 97
d1e4d10… stephan 98 db_prepare(&q,
771e592… mark 99 "SELECT pathname, deleted, chnged, rid, "
6112d90… stephan 100 " coalesce(origname!=pathname,0) AS renamed,"
6112d90… stephan 101 " origname"
d1e4d10… stephan 102 " FROM vfile "
d1e4d10… stephan 103 " WHERE is_selected(id)"
d1e4d10… stephan 104 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
d1e4d10… stephan 105 );
d1e4d10… stephan 106 while( db_step(&q)==SQLITE_ROW ){
771e592… mark 107 cson_array *aStatuses = NULL;
d1e4d10… stephan 108 const char *zPathname = db_column_text(&q,0);
d1e4d10… stephan 109 int isDeleted = db_column_int(&q, 1);
d1e4d10… stephan 110 int isChnged = db_column_int(&q,2);
d1e4d10… stephan 111 int isNew = db_column_int(&q,3)==0;
d1e4d10… stephan 112 int isRenamed = db_column_int(&q,4);
d1e4d10… stephan 113 cson_object * oFile;
6112d90… stephan 114 char const * zStatus = "unmodified";
d1e4d10… stephan 115 char * zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
d1e4d10… stephan 116 if( isDeleted ){
d1e4d10… stephan 117 zStatus = "deleted";
d1e4d10… stephan 118 }else if( isNew ){
d1e4d10… stephan 119 zStatus = "new" /* maintenance reminder: MUST come
d1e4d10… stephan 120 BEFORE the isChnged checks. */;
1772357… drh 121 }else if( !file_isfile_or_link(zFullName) ){
9df71fe… jan.nijtmans 122 if( file_access(zFullName, F_OK)==0 ){
d1e4d10… stephan 123 zStatus = "notAFile";
d1e4d10… stephan 124 ++nErr;
d1e4d10… stephan 125 }else{
d1e4d10… stephan 126 zStatus = "missing";
d1e4d10… stephan 127 ++nErr;
d1e4d10… stephan 128 }
6112d90… stephan 129 }else if( isChnged ){
6112d90… stephan 130 switch( isChnged ){
33d3bf3… km 131 /* These numbers from checkin.c: status_report() */
6112d90… stephan 132 case 1:
6112d90… stephan 133 if( file_contains_merge_marker(zFullName) ){
6112d90… stephan 134 zStatus = "conflict";
6112d90… stephan 135 }else{
6112d90… stephan 136 zStatus = "edited";
6112d90… stephan 137 }
6112d90… stephan 138 break;
6112d90… stephan 139 case 2: zStatus = "updatedByMerge"; break;
6112d90… stephan 140 case 3: zStatus = "addedByMerge"; break;
6112d90… stephan 141 case 4: zStatus = "updatedByIntegrate"; break;
6112d90… stephan 142 case 5: zStatus = "addedByIntegrate"; break;
6112d90… stephan 143 case 6: zStatus = "+exec"; break;
6112d90… stephan 144 case 7: zStatus = "+symlink"; break;
6112d90… stephan 145 case 8: zStatus = "-exec"; break;
6112d90… stephan 146 case 9: zStatus = "unlink"; break;
771e592… mark 147 }
771e592… mark 148 }
771e592… mark 149 oFile = cson_new_object();
771e592… mark 150 cson_array_append( aFiles, cson_object_value(oFile) );
771e592… mark 151 if( isRenamed ){
771e592… mark 152 if( *zStatus!='?' ){
771e592… mark 153 aStatuses = cson_new_array();
771e592… mark 154 cson_object_set( oFile, "status", cson_array_value( aStatuses ) );
771e592… mark 155 cson_array_append(aStatuses,
771e592… mark 156 cson_value_new_string(zStatus, strlen(zStatus)));
771e592… mark 157 cson_array_append(aStatuses, cson_value_new_string("renamed", 7));
771e592… mark 158 }else{
771e592… mark 159 zStatus = "renamed";
771e592… mark 160 }
771e592… mark 161 cson_object_set( oFile, "priorName",
771e592… mark 162 cson_sqlite3_column_to_value(q.pStmt,5));
771e592… mark 163 }
d1e4d10… stephan 164 /* optimization potential: move these keys into cson_strings
d1e4d10… stephan 165 to take advantage of refcounting. */
d1e4d10… stephan 166 cson_object_set( oFile, "name", json_new_string( zPathname ) );
771e592… mark 167 cson_object_set( oFile, "status", aStatuses!=NULL ?
771e592… mark 168 cson_array_value(aStatuses) : json_new_string( zStatus ) );
d1e4d10… stephan 169
d1e4d10… stephan 170 free(zFullName);
d1e4d10… stephan 171 }
d1e4d10… stephan 172 cson_object_set( oPay, "errorCount", json_new_int( nErr ) );
d1e4d10… stephan 173 db_finalize(&q);
d1e4d10… stephan 174
d1e4d10… stephan 175 #if 0
d1e4d10… stephan 176 /* TODO: add "merged with" status. First need (A) to decide on a
d1e4d10… stephan 177 structure and (B) to set up some tests for the multi-merge
d1e4d10… stephan 178 case.*/
fff37e6… drh 179 db_prepare(&q, "SELECT mhash, id FROM vmerge WHERE id<=0");
d1e4d10… stephan 180 while( db_step(&q)==SQLITE_ROW ){
d1e4d10… stephan 181 const char *zLabel = "MERGED_WITH";
d1e4d10… stephan 182 switch( db_column_int(&q, 1) ){
d1e4d10… stephan 183 case -1: zLabel = "CHERRYPICK "; break;
d1e4d10… stephan 184 case -2: zLabel = "BACKOUT "; break;
69dd259… jan.nijtmans 185 case -4: zLabel = "INTEGRATE "; break;
d1e4d10… stephan 186 }
d1e4d10… stephan 187 blob_append(report, zPrefix, nPrefix);
d1e4d10… stephan 188 blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
d1e4d10… stephan 189 }
d1e4d10… stephan 190 db_finalize(&q);
d1e4d10… stephan 191 if( nErr ){
31c7bdb… larrybr 192 fossil_fatal("aborting due to prior errors");
d1e4d10… stephan 193 }
d1e4d10… stephan 194 #endif
d1e4d10… stephan 195 return cson_object_value( oPay );
d1e4d10… stephan 196 }
d1e4d10… stephan 197
d1e4d10… stephan 198 #endif /* FOSSIL_ENABLE_JSON */

Keyboard Shortcuts

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