diff options
| author | cashmere <cashmere@autistici.org> | 2026-09-04 09:05:24 +0200 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-09-04 09:05:24 +0200 |
| commit | 4f49b16079b27d7ce633619e4cddfdf2bffbc952 (patch) | |
| tree | c296c1e7f3c3e2f6859c6d3a1b1b208779b89679 /src/json_status.c | |
| download | relic-master.tar.gz | |
Diffstat (limited to 'src/json_status.c')
| -rw-r--r-- | src/json_status.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/json_status.c b/src/json_status.c new file mode 100644 index 0000000..85d1b01 --- /dev/null +++ b/src/json_status.c @@ -0,0 +1,198 @@ +#ifdef FOSSIL_ENABLE_JSON +/* +** Copyright (c) 2013 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the Simplified BSD License (also +** known as the "2-Clause License" or "FreeBSD License".) +** +** This program is distributed in the hope that it will be useful, +** but without any warranty; without even the implied warranty of +** merchantability or fitness for a particular purpose. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +*/ + +#include "config.h" +#include "json_status.h" + +#if INTERFACE +#include "json_detail.h" +#endif + +/* +Reminder to check if a column exists: + +PRAGMA table_info(table_name) + +and search for a row where the 'name' field matches. + +That assumes, of course, that table_info()'s output format +is stable. +*/ + +/* +** Implementation of the /json/status page. +** +*/ +cson_value * json_page_status(){ + Stmt q = empty_Stmt; + cson_object * oPay; + /*cson_object * files;*/ + int vid, nErr = 0; + cson_object * tmpO; + char * zTmp; + i64 iMtime; + cson_array * aFiles; + + if(!db_open_local(0)){ + json_set_err(FSL_JSON_E_DB_NEEDS_CHECKOUT, NULL); + return NULL; + } + oPay = cson_new_object(); + cson_object_set(oPay, "repository", + json_new_string(db_repository_filename())); + cson_object_set(oPay, "localRoot", + json_new_string(g.zLocalRoot)); + vid = db_lget_int("checkout", 0); + if(!vid){ + json_set_err( FSL_JSON_E_UNKNOWN, "Can this even happen?" ); + return 0; + } + vfile_check_signature(vid, 0); + /* TODO: dupe show_common_info() state */ + tmpO = cson_new_object(); + cson_object_set(oPay, "checkout", cson_object_value(tmpO)); + + zTmp = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); + cson_object_set(tmpO, "uuid", json_new_string(zTmp) ); + free(zTmp); + + cson_object_set( tmpO, "tags", json_tags_for_checkin_rid(vid, 0) ); + + /* FIXME: optimize the datetime/timestamp queries into 1 query. */ + zTmp = db_text(0, "SELECT datetime(mtime) || " + "' UTC' FROM event WHERE objid=%d", + vid); + cson_object_set(tmpO, "datetime", json_new_string(zTmp)); + free(zTmp); + iMtime = db_int64(0, "SELECT CAST(strftime('%%s',mtime) AS INTEGER) " + "FROM event WHERE objid=%d", vid); + cson_object_set(tmpO, "timestamp", + cson_value_new_integer((cson_int_t)iMtime)); +#if 0 + /* TODO: add parent artifact info */ + tmpO = cson_new_object(); + cson_object_set( oPay, "parent", cson_object_value(tmpO) ); + cson_object_set( tmpO, "uuid", TODO ); + cson_object_set( tmpO, "timestamp", TODO ); +#endif + + /* Now get the list of non-pristine files... */ + aFiles = cson_new_array(); + cson_object_set( oPay, "files", cson_array_value( aFiles ) ); + + db_prepare(&q, + "SELECT pathname, deleted, chnged, rid, " + " coalesce(origname!=pathname,0) AS renamed," + " origname" + " FROM vfile " + " WHERE is_selected(id)" + " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1" + ); + while( db_step(&q)==SQLITE_ROW ){ + cson_array *aStatuses = NULL; + const char *zPathname = db_column_text(&q,0); + int isDeleted = db_column_int(&q, 1); + int isChnged = db_column_int(&q,2); + int isNew = db_column_int(&q,3)==0; + int isRenamed = db_column_int(&q,4); + cson_object * oFile; + char const * zStatus = "unmodified"; + char * zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); + if( isDeleted ){ + zStatus = "deleted"; + }else if( isNew ){ + zStatus = "new" /* maintenance reminder: MUST come + BEFORE the isChnged checks. */; + }else if( !file_isfile_or_link(zFullName) ){ + if( file_access(zFullName, F_OK)==0 ){ + zStatus = "notAFile"; + ++nErr; + }else{ + zStatus = "missing"; + ++nErr; + } + }else if( isChnged ){ + switch( isChnged ){ + /* These numbers from checkin.c: status_report() */ + case 1: + if( file_contains_merge_marker(zFullName) ){ + zStatus = "conflict"; + }else{ + zStatus = "edited"; + } + break; + case 2: zStatus = "updatedByMerge"; break; + case 3: zStatus = "addedByMerge"; break; + case 4: zStatus = "updatedByIntegrate"; break; + case 5: zStatus = "addedByIntegrate"; break; + case 6: zStatus = "+exec"; break; + case 7: zStatus = "+symlink"; break; + case 8: zStatus = "-exec"; break; + case 9: zStatus = "unlink"; break; + } + } + oFile = cson_new_object(); + cson_array_append( aFiles, cson_object_value(oFile) ); + if( isRenamed ){ + if( *zStatus!='?' ){ + aStatuses = cson_new_array(); + cson_object_set( oFile, "status", cson_array_value( aStatuses ) ); + cson_array_append(aStatuses, + cson_value_new_string(zStatus, strlen(zStatus))); + cson_array_append(aStatuses, cson_value_new_string("renamed", 7)); + }else{ + zStatus = "renamed"; + } + cson_object_set( oFile, "priorName", + cson_sqlite3_column_to_value(q.pStmt,5)); + } + /* optimization potential: move these keys into cson_strings + to take advantage of refcounting. */ + cson_object_set( oFile, "name", json_new_string( zPathname ) ); + cson_object_set( oFile, "status", aStatuses!=NULL ? + cson_array_value(aStatuses) : json_new_string( zStatus ) ); + + free(zFullName); + } + cson_object_set( oPay, "errorCount", json_new_int( nErr ) ); + db_finalize(&q); + +#if 0 + /* TODO: add "merged with" status. First need (A) to decide on a + structure and (B) to set up some tests for the multi-merge + case.*/ + db_prepare(&q, "SELECT mhash, id FROM vmerge WHERE id<=0"); + while( db_step(&q)==SQLITE_ROW ){ + const char *zLabel = "MERGED_WITH"; + switch( db_column_int(&q, 1) ){ + case -1: zLabel = "CHERRYPICK "; break; + case -2: zLabel = "BACKOUT "; break; + case -4: zLabel = "INTEGRATE "; break; + } + blob_append(report, zPrefix, nPrefix); + blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0)); + } + db_finalize(&q); + if( nErr ){ + fossil_fatal("aborting due to prior errors"); + } +#endif + return cson_object_value( oPay ); +} + +#endif /* FOSSIL_ENABLE_JSON */ |
