Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add the internal checkin_mtime() function. Use it to implement the --age and -t options to the "fossil ls" command. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
9ba8a393fcc569b2a652984a374adf08 |
| User & Date: | drh 2012-10-10 20:03:49.821 |
References
|
2012-10-11
| ||
| 19:45 | Cherrypick changes [0c37874941c8972], [9ba8a393fcc569b], and [ae092ec605eed11] in order to backport the --setmtime option of "fossil update" and the --age and -t options of "fossil ls" to version 1.19. ... (check-in: 773c6c5f2c user: drh tags: branch-1.19) | |
Context
|
2012-10-11
| ||
| 14:21 | Add the "fileage" webpage. ... (check-in: 368347d660 user: drh tags: trunk) | |
|
2012-10-10
| ||
| 20:03 | Add the internal checkin_mtime() function. Use it to implement the --age and -t options to the "fossil ls" command. ... (check-in: 9ba8a393fc user: drh tags: trunk) | |
| 16:06 | The "fossil undo" and "fossil redo" commands remember file mtimes and restore them appropriately. When upgrading through this version, you may need to run "fossil undo --reset" to clear your old undo stack. ... (check-in: 0c37874941 user: drh tags: trunk) | |
Changes
Changes to src/checkin.c.
| ︙ | ︙ | |||
203 204 205 206 207 208 209 210 211 212 213 |
vid = db_lget_int("checkout", 0);
if( vid ){
show_common_info(vid, "checkout:", 1, 1);
}
db_record_repository_filename(0);
changes_cmd();
}
/*
** COMMAND: ls
**
| > > > > > | | > > > > > > > > > > > > > | > > > > > > > | | | | > > > | | 203 204 205 206 207 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 |
vid = db_lget_int("checkout", 0);
if( vid ){
show_common_info(vid, "checkout:", 1, 1);
}
db_record_repository_filename(0);
changes_cmd();
}
/*
** Implementation of the checkin_mtime SQL function
*/
/*
** COMMAND: ls
**
** Usage: %fossil ls ?OPTIONS? ?VERSION?
**
** Show the names of all files in the current checkout. The -l provides
** extra information about each file.
**
** Options:
** -l Provide extra information about each file.
** --age Show when each file was committed
**
** See also: changes, extra, status
*/
void ls_cmd(void){
int vid;
Stmt q;
int isBrief;
int showAge;
char *zOrderBy = "pathname";
isBrief = find_option("l","l", 0)==0;
showAge = find_option("age",0,0)!=0;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
if( find_option("t","t",0)!=0 ){
if( showAge ){
zOrderBy = mprintf("checkin_mtime(%d,rid) DESC", vid);
}else{
zOrderBy = "mtime DESC";
}
}
verify_all_options();
vfile_check_signature(vid, 0, 0);
if( showAge ){
db_prepare(&q,
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0),"
" datetime(checkin_mtime(%d,rid),'unixepoch','localtime')"
" FROM vfile"
" ORDER BY %s", vid, zOrderBy
);
}else{
db_prepare(&q,
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
" FROM vfile"
" ORDER BY %s", zOrderBy
);
}
while( db_step(&q)==SQLITE_ROW ){
const char *zPathname = db_column_text(&q,0);
int isDeleted = db_column_int(&q, 1);
int isNew = db_column_int(&q,2)==0;
int chnged = db_column_int(&q,3);
int renamed = db_column_int(&q,4);
char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
if( showAge ){
fossil_print("%s %s\n", db_column_text(&q, 5), zPathname);
}else if( isBrief ){
fossil_print("%s\n", zPathname);
}else if( isNew ){
fossil_print("ADDED %s\n", zPathname);
}else if( isDeleted ){
fossil_print("DELETED %s\n", zPathname);
}else if( !file_wd_isfile_or_link(zFullName) ){
if( file_access(zFullName, 0)==0 ){
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
674 675 676 677 678 679 680 681 682 683 684 685 686 687 |
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_int64(context, time(0));
}
/*
** Open a database file. Return a pointer to the new database
** connection. An error results in process abort.
*/
static sqlite3 *openDatabase(const char *zDbName){
int rc;
| > > > > > > > > > > > > > > > > | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_int64(context, time(0));
}
/*
** Function to return the check-in time for a file.
*/
void db_checkin_mtime_function(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
i64 mtime;
int rc = mtime_of_manifest_file(sqlite3_value_int(argv[0]),
sqlite3_value_int(argv[1]), &mtime);
if( rc==0 ){
sqlite3_result_int64(context, mtime);
}
}
/*
** Open a database file. Return a pointer to the new database
** connection. An error results in process abort.
*/
static sqlite3 *openDatabase(const char *zDbName){
int rc;
|
| ︙ | ︙ | |||
696 697 698 699 700 701 702 703 704 705 706 707 708 709 |
);
if( rc!=SQLITE_OK ){
db_err(sqlite3_errmsg(db));
}
sqlite3_busy_timeout(db, 5000);
sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0);
return db;
}
/*
** Detaches the zLabel database.
*/
| > > | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
);
if( rc!=SQLITE_OK ){
db_err(sqlite3_errmsg(db));
}
sqlite3_busy_timeout(db, 5000);
sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0);
sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_ANY, 0,
db_checkin_mtime_function, 0, 0);
return db;
}
/*
** Detaches the zLabel database.
*/
|
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
154 155 156 157 158 159 160 | } } /* ** Load the record ID rid and up to N-1 closest ancestors into ** the "ok" table. */ | | | > | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
}
}
/*
** Load the record ID rid and up to N-1 closest ancestors into
** the "ok" table.
*/
void compute_ancestors(int rid, int N, int directOnly){
Bag seen;
PQueue queue;
Stmt ins;
Stmt q;
bag_init(&seen);
pqueuex_init(&queue);
bag_insert(&seen, rid);
pqueuex_insert(&queue, rid, 0.0, 0);
db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
db_prepare(&q,
"SELECT a.pid, b.mtime FROM plink a LEFT JOIN plink b ON b.cid=a.pid"
" WHERE a.cid=:rid %s",
directOnly ? " AND a.isprim" : ""
);
while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
db_bind_int(&ins, ":rid", rid);
db_step(&ins);
db_reset(&ins);
db_bind_int(&q, ":rid", rid);
while( db_step(&q)==SQLITE_ROW ){
|
| ︙ | ︙ | |||
200 201 202 203 204 205 206 |
** direct ancestor as the largest generation number.
*/
void compute_direct_ancestors(int rid, int N){
Stmt ins;
Stmt q;
int gen = 0;
db_multi_exec(
| | > | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
** direct ancestor as the largest generation number.
*/
void compute_direct_ancestors(int rid, int N){
Stmt ins;
Stmt q;
int gen = 0;
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ancestor(rid INTEGER,"
" generation INTEGER PRIMARY KEY);"
"DELETE FROM ancestor;"
"INSERT INTO ancestor VALUES(%d, 0);", rid
);
db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)");
db_prepare(&q,
"SELECT pid FROM plink"
" WHERE cid=:rid AND isprim"
|
| ︙ | ︙ | |||
223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
db_bind_int(&ins, ":gen", gen);
db_step(&ins);
db_reset(&ins);
}
db_finalize(&ins);
db_finalize(&q);
}
/*
** Load the record ID rid and up to N-1 closest descendants into
** the "ok" table.
*/
void compute_descendants(int rid, int N){
Bag seen;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
db_bind_int(&ins, ":gen", gen);
db_step(&ins);
db_reset(&ins);
}
db_finalize(&ins);
db_finalize(&q);
}
/*
** Compute the "mtime" of the file given whose blob.rid is "fid" that
** is part of check-in "vid". The mtime will be the mtime on vid or
** some ancestor of vid where fid first appears.
*/
int mtime_of_manifest_file(
int vid, /* The check-in that contains fid */
int fid, /* The id of the file whose check-in time is sought */
i64 *pMTime /* Write result here */
){
static int prevVid = -1;
static Stmt q;
if( prevVid!=vid ){
prevVid = vid;
db_multi_exec("DROP TABLE IF EXISTS temp.ok;"
"CREATE TEMP TABLE ok(x INTEGER PRIMARY KEY);");
compute_ancestors(vid, 100000000, 1);
}
db_static_prepare(&q,
"SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
" WHERE mlink.mid=event.objid"
" AND +mlink.mid IN ok"
" AND mlink.fid=:fid");
db_bind_int(&q, ":fid", fid);
if( db_step(&q)!=SQLITE_ROW ){
db_reset(&q);
return 1;
}
*pMTime = db_column_int64(&q, 0);
db_reset(&q);
return 0;
}
/*
** Load the record ID rid and up to N-1 closest descendants into
** the "ok" table.
*/
void compute_descendants(int rid, int N){
Bag seen;
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
1021 1022 1023 1024 1025 1026 1027 |
nd = db_int(0, "SELECT count(*)-1 FROM ok");
if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
if( useDividers ) timeline_add_dividers(0, d_rid);
db_multi_exec("DELETE FROM ok");
}
if( p_rid ){
| | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 |
nd = db_int(0, "SELECT count(*)-1 FROM ok");
if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
if( useDividers ) timeline_add_dividers(0, d_rid);
db_multi_exec("DELETE FROM ok");
}
if( p_rid ){
compute_ancestors(p_rid, nEntry+1, 0);
np = db_int(0, "SELECT count(*)-1 FROM ok");
if( np>0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestors", np);
db_multi_exec("%s", blob_str(&sql));
}
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
|
| ︙ | ︙ | |||
1536 1537 1538 1539 1540 1541 1542 |
);
if( mode==3 || mode==4 ){
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
if( mode==3 ){
compute_descendants(objid, n);
}else{
| | | 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 |
);
if( mode==3 || mode==4 ){
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
if( mode==3 ){
compute_descendants(objid, n);
}else{
compute_ancestors(objid, n, 0);
}
blob_appendf(&sql, " AND blob.rid IN ok");
}
if( zType && (zType[0]!='a') ){
blob_appendf(&sql, " AND event.type=%Q ", zType);
}
blob_appendf(&sql, " ORDER BY event.mtime DESC");
|
| ︙ | ︙ |