Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Improved rounding behavior for timestamp identifiers on object where the timestamp has less then millisecond precision. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
633ea7343f68c90745f7a6f2a44da325 |
| User & Date: | drh 2025-03-18 11:04:45.762 |
Context
|
2025-03-18
| ||
| 11:16 | Remove obsolete code - unused and commented out since 2019. No functional changes. check-in: 7517845c7c user: drh tags: trunk | |
| 11:04 | Improved rounding behavior for timestamp identifiers on object where the timestamp has less then millisecond precision. check-in: 633ea7343f user: drh tags: trunk | |
| 05:27 | Use existing HTTP AUTH information if available when using Fossil configuration synchronization commands. Addresses [forum:d8cb1918f9|forum post d8cb1918f9]. check-in: 5a942d1219 user: andybradford tags: trunk | |
Changes
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
125 126 127 128 129 130 131 |
void diff_print_versions(const char *zFrom, const char *zTo, DiffConfig *pCfg){
if( (pCfg->diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT|
DIFF_HTML|DIFF_WEBPAGE|DIFF_BROWSER|DIFF_JSON|DIFF_TCL))==0 ){
fossil_print("Fossil-Diff-From: %s\n",
zFrom[0]=='(' ? zFrom : mprintf("%S %s",
rid_to_uuid(symbolic_name_to_rid(zFrom, "ci")),
db_text("","SELECT datetime(%f)||' UTC'",
| | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
void diff_print_versions(const char *zFrom, const char *zTo, DiffConfig *pCfg){
if( (pCfg->diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF|DIFF_NUMSTAT|
DIFF_HTML|DIFF_WEBPAGE|DIFF_BROWSER|DIFF_JSON|DIFF_TCL))==0 ){
fossil_print("Fossil-Diff-From: %s\n",
zFrom[0]=='(' ? zFrom : mprintf("%S %s",
rid_to_uuid(symbolic_name_to_rid(zFrom, "ci")),
db_text("","SELECT datetime(%f)||' UTC'",
symbolic_name_to_mtime(zFrom, 0, 0))));
fossil_print("Fossil-Diff-To: %s\n",
zTo[0]=='(' ? zTo : mprintf("%S %s",
rid_to_uuid(symbolic_name_to_rid(zTo, "ci")),
db_text("","SELECT datetime(%f)||' UTC'",
symbolic_name_to_mtime(zTo, 0, 1))));
fossil_print("%.66c\n", '-');
}
}
/*
** Print the "Index:" message that patches wants to see at the top of a diff.
*/
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
496 497 498 499 500 501 502 |
" LEFT JOIN filename ON filename.fnid=clade.fnid\n"
"WHERE mlink.fnid=clade.fnid AND mlink.fid=clade.fid\n"
" AND event.objid=mlink.mid\n",
TAG_BRANCH
);
if( (zA = P("a"))!=0 ){
blob_append_sql(&sql, " AND event.mtime>=%.16g\n",
| | | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
" LEFT JOIN filename ON filename.fnid=clade.fnid\n"
"WHERE mlink.fnid=clade.fnid AND mlink.fid=clade.fid\n"
" AND event.objid=mlink.mid\n",
TAG_BRANCH
);
if( (zA = P("a"))!=0 ){
blob_append_sql(&sql, " AND event.mtime>=%.16g\n",
symbolic_name_to_mtime(zA,0,0));
url_add_parameter(&url, "a", zA);
}
if( (zB = P("b"))!=0 ){
blob_append_sql(&sql, " AND event.mtime<=%.16g\n",
symbolic_name_to_mtime(zB,0,1));
url_add_parameter(&url, "b", zB);
}
if( ridFrom ){
blob_append_sql(&sql,
" AND mlink.mid IN (SELECT rid FROM ancestor)\n"
"GROUP BY mlink.fid\n"
);
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
57 58 59 60 61 62 63 | /* ** Check to see if the string might be a compact date/time that omits ** the punctuation. Example: "20190327084549" instead of ** "2019-03-27 08:45:49". If the string is of the appropriate form, ** then return an alternative string (in static space) that is the same ** string with punctuation inserted. ** | > > > | > > > > | | | | | | | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
/*
** Check to see if the string might be a compact date/time that omits
** the punctuation. Example: "20190327084549" instead of
** "2019-03-27 08:45:49". If the string is of the appropriate form,
** then return an alternative string (in static space) that is the same
** string with punctuation inserted.
**
** If the bRoundUp parameter is true, then round the resulting date-time
** up to the largest date/time that is consistent with the input value.
** This is because the result will be used for an mtime<=julianday($DATE)
** comparison. In other words:
**
** 20250317123421 -> 2025-03-17 12:34:21.999
** ^^^^--- Added
**
** 202503171234 -> 2025-03-17 12:34:59.999
** ^^^^^^^--- Added
** 20250317 -> 2025-03-17 23:59:59.999
** ^^^^^^^^^^^^--- Added
**
** If the bVerifyNotAHash flag is true, then a check is made to see if
** the input string is a hash prefix and NULL is returned if it is. If the
** bVerifyNotAHash flag is false, then the result is determined by syntax
** of the input string only, without reference to the artifact table.
*/
char *fossil_expand_datetime(const char *zIn,int bVerifyNotAHash,int bRoundUp){
static char zEDate[24];
static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
int n = (int)strlen(zIn);
int i, j;
int addZulu = 0;
/* These forms are allowed:
**
** 123456789 1234 123456789 123456789 1234
** (1) YYYYMMDD => YYYY-MM-DD 23:59:59.999
** (2) YYYYMMDDHHMM => YYYY-MM-DD HH:MM:59.999
** (3) YYYYMMDDHHMMSS => YYYY-MM-DD HH:MM:SS.999
**
** An optional "Z" zulu timezone designator is allowed at the end.
*/
if( n>0 && (zIn[n-1]=='Z' || zIn[n-1]=='z') ){
n--;
addZulu = 1;
}
|
| ︙ | ︙ | |||
103 104 105 106 107 108 109 |
/* Expand the date */
for(i=j=0; i<n; i++){
if( i>=4 && (i%2)==0 ){
zEDate[j++] = aPunct[i/2];
}
zEDate[j++] = zIn[i];
}
| > | | | | | | > > > > | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
/* Expand the date */
for(i=j=0; i<n; i++){
if( i>=4 && (i%2)==0 ){
zEDate[j++] = aPunct[i/2];
}
zEDate[j++] = zIn[i];
}
if( bRoundUp ){
if( j==10 ){
memcpy(&zEDate[10], " 23:59:59.999", 13);
j += 13;
}else if( j==16 ){
memcpy(&zEDate[16], ":59.999",7);
j += 7;
}else if( j==19 ){
memcpy(&zEDate[19], ".999", 4);
j += 4;
}
}
if( addZulu ){
zEDate[j++] = 'Z';
}
zEDate[j] = 0;
/* Check for reasonable date values.
|
| ︙ | ︙ | |||
486 487 488 489 490 491 492 |
g.localOpen = ridCkout;
}
if( rid ) return rid;
}
/* Date and times */
if( memcmp(zTag, "date:", 5)==0 ){
| | | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
g.localOpen = ridCkout;
}
if( rid ) return rid;
}
/* Date and times */
if( memcmp(zTag, "date:", 5)==0 ){
zDate = fossil_expand_datetime(&zTag[5],0,1);
if( zDate==0 ) zDate = &zTag[5];
rid = db_int(0,
"SELECT objid FROM event"
" WHERE mtime<=julianday(%Q,fromLocal()) AND type GLOB '%q'"
" ORDER BY mtime DESC LIMIT 1",
fossil_roundup_date(zDate), zType);
return rid;
|
| ︙ | ︙ | |||
552 553 554 555 556 557 558 |
return start_of_branch(rid, 2);
}
/* symbolic-name ":" date-time */
nTag = strlen(zTag);
for(i=0; i<nTag-8 && zTag[i]!=':'; i++){}
if( zTag[i]==':'
| | | | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
return start_of_branch(rid, 2);
}
/* symbolic-name ":" date-time */
nTag = strlen(zTag);
for(i=0; i<nTag-8 && zTag[i]!=':'; i++){}
if( zTag[i]==':'
&& (fossil_isdate(&zTag[i+1]) || fossil_expand_datetime(&zTag[i+1],0,0)!=0)
){
char *zDate = mprintf("%s", &zTag[i+1]);
char *zTagBase = mprintf("%.*s", i, zTag);
char *zXDate;
int nDate = strlen(zDate);
if( sqlite3_strnicmp(&zDate[nDate-3],"utc",3)==0 ){
zDate[nDate-3] = 'z';
zDate[nDate-2] = 0;
}
zXDate = fossil_expand_datetime(zDate,0,1);
if( zXDate==0 ) zXDate = zDate;
rid = db_int(0,
"SELECT event.objid, max(event.mtime)"
" FROM tag, tagxref, event"
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
|
| ︙ | ︙ | |||
638 639 640 641 642 643 644 |
if( rid>0 ){
if( startOfBranch ) rid = start_of_branch(rid,1);
return rid;
}
/* Pure numeric date/time */
| | | 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
if( rid>0 ){
if( startOfBranch ) rid = start_of_branch(rid,1);
return rid;
}
/* Pure numeric date/time */
zDate = fossil_expand_datetime(zTag, 0,1);
if( zDate ){
rid = db_int(0,
"SELECT objid FROM event"
" WHERE mtime<=julianday(%Q,fromLocal()) AND type GLOB '%q'"
" ORDER BY mtime DESC LIMIT 1",
fossil_roundup_date(zDate), zType);
if( rid) return rid;
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 1097 | ; return zBase; } /* ** Convert a symbolic name used as an argument to the a=, b=, or c= ** query parameters of timeline into a julianday mtime value. */ | > > > > > > > > > > > | > > > > | | | 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 |
;
return zBase;
}
/*
** Convert a symbolic name used as an argument to the a=, b=, or c=
** query parameters of timeline into a julianday mtime value.
**
** If pzDisplay is not null, then display text for the symbolic name might
** be written into *pzDisplay. But that is not guaranteed.
**
** If bRoundUp is true and the symbolic name is a timestamp with less
** than millisecond resolution, then the timestamp is rounding up to the
** largest millisecond consistent with that timestamp. If bRoundUp is
** false, then the resulting time is obtained by extending the timestamp
** with zeros (hence rounding down). Use bRoundUp==1 if the result
** will be used in mtime<=$RESULT and use bRoundUp==0 if the result
** will be used in mtime>=$RESULT.
*/
double symbolic_name_to_mtime(
const char *z, /* Input symbolic name */
const char **pzDisplay, /* Perhaps write display text here, if not NULL */
int bRoundUp /* Round up if true */
){
double mtime;
int rid;
const char *zDate;
if( z==0 ) return -1.0;
if( fossil_isdate(z) ){
mtime = db_double(0.0, "SELECT julianday(%Q,fromLocal())", z);
if( mtime>0.0 ) return mtime;
}
zDate = fossil_expand_datetime(z, 1, bRoundUp);
if( zDate!=0 ){
mtime = db_double(0.0, "SELECT julianday(%Q,fromLocal())",
bRoundUp ? fossil_roundup_date(zDate) : zDate);
if( mtime>0.0 ){
if( pzDisplay ) *pzDisplay = fossil_strdup(zDate);
return mtime;
}
}
rid = symbolic_name_to_rid(z, "*");
if( rid ){
|
| ︙ | ︙ | |||
2865 2866 2867 2868 2869 2870 2871 |
zSearch, zSearch, zSearch);
}else{
blob_append_sql(&cond,
" AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
zSearch, zSearch);
}
}
| | | | | 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 |
zSearch, zSearch, zSearch);
}else{
blob_append_sql(&cond,
" AND (event.comment LIKE '%%%q%%' OR event.brief LIKE '%%%q%%')",
zSearch, zSearch);
}
}
rBefore = symbolic_name_to_mtime(zBefore, &zBefore, 1);
rAfter = symbolic_name_to_mtime(zAfter, &zAfter, 0);
rCirca = symbolic_name_to_mtime(zCirca, &zCirca, 0);
blob_append_sql(&sql, "%s", blob_sql_text(&cond));
if( rAfter>0.0 ){
if( rBefore>0.0 ){
blob_append_sql(&sql,
" AND event.mtime>=%.17g AND event.mtime<=%.17g\n"
" ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
nEntry = -1;
|
| ︙ | ︙ | |||
3008 3009 3010 3011 3012 3013 3014 |
};
double rDate;
zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){
zDate = mprintf("%s", (zAfter ? zAfter : zBefore));
}
if( zDate ){
| | | | 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 |
};
double rDate;
zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){
zDate = mprintf("%s", (zAfter ? zAfter : zBefore));
}
if( zDate ){
rDate = symbolic_name_to_mtime(zDate, 0, 0);
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid AND mtime<=%.17g%s)",
rDate-ONE_SECOND, blob_sql_text(&cond))
){
zOlderButton = fossil_strdup(url_render(&url, "b", zDate, "a", 0));
zOlderButtonLabel = "More";
}
free(zDate);
}
zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
if( (!zDate || !zDate[0]) && ( zAfter || zBefore ) ){
zDate = mprintf("%s", (zBefore ? zBefore : zAfter));
}
if( zDate ){
rDate = symbolic_name_to_mtime(zDate, 0, 0);
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid AND mtime>=%.17g%s)",
rDate+ONE_SECOND, blob_sql_text(&cond))
){
zNewerButton = fossil_strdup(url_render(&url, "a", zDate, "b", 0));
zNewerButtonLabel = "More";
|
| ︙ | ︙ | |||
3067 3068 3069 3070 3071 3072 3073 |
url_render(&url, "advm", "0", "udc", "1"));
}else{
style_submenu_element("Advanced", "%s",
url_render(&url, "advm", "1", "udc", "1"));
}
if( PB("showid") ) tmFlags |= TIMELINE_SHOWRID;
if( useDividers && zMark && zMark[0] ){
| | | 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 |
url_render(&url, "advm", "0", "udc", "1"));
}else{
style_submenu_element("Advanced", "%s",
url_render(&url, "advm", "1", "udc", "1"));
}
if( PB("showid") ) tmFlags |= TIMELINE_SHOWRID;
if( useDividers && zMark && zMark[0] ){
double r = symbolic_name_to_mtime(zMark, 0, 0);
if( r>0.0 && !selectedRid ) selectedRid = timeline_add_divider(r);
}
blob_zero(&sql);
if( PB("oldestfirst") ){
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby ASC /*scan*/");
}else{
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
|
| ︙ | ︙ |