Fossil SCM

Allow specifying tags using TAG:DATE. The result is the newest check-in with TAG that occurs or before DATE.

drh 2010-03-06 16:41 trunk
Commit 337a1aca06cd6d75827acfa4f78cfdbc73b62e08
1 file changed +54 -1
+54 -1
--- src/name.c
+++ src/name.c
@@ -111,15 +111,39 @@
111111
}else{
112112
rc = 0;
113113
}
114114
return rc;
115115
}
116
+
117
+/*
118
+** Return TRUE if the string begins with an ISO8601 date: YYYY-MM-DD.
119
+*/
120
+static int is_date(const char *z){
121
+ if( !isdigit(z[0]) ) return 0;
122
+ if( !isdigit(z[1]) ) return 0;
123
+ if( !isdigit(z[2]) ) return 0;
124
+ if( !isdigit(z[3]) ) return 0;
125
+ if( z[4]!='-') return 0;
126
+ if( !isdigit(z[5]) ) return 0;
127
+ if( !isdigit(z[6]) ) return 0;
128
+ if( z[7]!='-') return 0;
129
+ if( !isdigit(z[8]) ) return 0;
130
+ if( !isdigit(z[9]) ) return 0;
131
+ return 1;
132
+}
116133
117134
/*
118135
** Convert a symbolic tag name into the UUID of a check-in that contains
119136
** that tag. If the tag appears on multiple check-ins, return the UUID
120137
** of the most recent check-in with the tag.
138
+**
139
+** If the input string is of the form:
140
+**
141
+** tag:date
142
+**
143
+** Then return the UUID of the oldest check-in with that tag that is
144
+** not older than 'date'.
121145
**
122146
** Memory to hold the returned string comes from malloc() and needs to
123147
** be freed by the caller.
124148
*/
125149
char *tag_to_uuid(const char *zTag){
@@ -132,10 +156,39 @@
132156
" AND event.objid=tagxref.rid "
133157
" AND blob.rid=event.objid "
134158
" ORDER BY event.mtime DESC ",
135159
zTag
136160
);
161
+ if( zUuid==0 ){
162
+ int nTag = strlen(zTag);
163
+ int i;
164
+ for(i=0; i<nTag-10; i++){
165
+ if( zTag[i]==':' && is_date(&zTag[i+1]) ){
166
+ char *zDate = mprintf("%s", &zTag[i+1]);
167
+ char *zTagBase = mprintf("%.*s", i, zTag);
168
+ int nDate = strlen(zDate);
169
+ int useUtc = 0;
170
+ if( sqlite3_strnicmp(&zDate[nDate-3],"utc",3)==0 ){
171
+ nDate -= 3;
172
+ zDate[nDate] = 0;
173
+ useUtc = 1;
174
+ }
175
+ zUuid = db_text(0,
176
+ "SELECT blob.uuid"
177
+ " FROM tag, tagxref, event, blob"
178
+ " WHERE tag.tagname='sym-'||%Q "
179
+ " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
180
+ " AND event.objid=tagxref.rid "
181
+ " AND blob.rid=event.objid "
182
+ " AND event.mtime<=julianday(%Q %s)"
183
+ " ORDER BY event.mtime DESC ",
184
+ zTagBase, zDate, (useUtc ? "" : ",'utc'")
185
+ );
186
+ break;
187
+ }
188
+ }
189
+ }
137190
return zUuid;
138191
}
139192
140193
/*
141194
** Convert a date/time string into a UUID.
@@ -162,11 +215,11 @@
162215
}else if( memcmp(zDate, "utc:", 4)==0 ){
163216
zDate += 4;
164217
useUtc = 1;
165218
}
166219
n = strlen(zDate);
167
- if( n<10 || zDate[4]!='-' || zDate[7]!='-' ) return 0;
220
+ if( n<10 || !is_date(zDate) ) return 0;
168221
if( n>4 && sqlite3_strnicmp(&zDate[n-3], "utc", 3)==0 ){
169222
zCopy = mprintf("%s", zDate);
170223
zCopy[n-3] = 0;
171224
zDate = zCopy;
172225
n -= 3;
173226
--- src/name.c
+++ src/name.c
@@ -111,15 +111,39 @@
111 }else{
112 rc = 0;
113 }
114 return rc;
115 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
117 /*
118 ** Convert a symbolic tag name into the UUID of a check-in that contains
119 ** that tag. If the tag appears on multiple check-ins, return the UUID
120 ** of the most recent check-in with the tag.
 
 
 
 
 
 
 
121 **
122 ** Memory to hold the returned string comes from malloc() and needs to
123 ** be freed by the caller.
124 */
125 char *tag_to_uuid(const char *zTag){
@@ -132,10 +156,39 @@
132 " AND event.objid=tagxref.rid "
133 " AND blob.rid=event.objid "
134 " ORDER BY event.mtime DESC ",
135 zTag
136 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137 return zUuid;
138 }
139
140 /*
141 ** Convert a date/time string into a UUID.
@@ -162,11 +215,11 @@
162 }else if( memcmp(zDate, "utc:", 4)==0 ){
163 zDate += 4;
164 useUtc = 1;
165 }
166 n = strlen(zDate);
167 if( n<10 || zDate[4]!='-' || zDate[7]!='-' ) return 0;
168 if( n>4 && sqlite3_strnicmp(&zDate[n-3], "utc", 3)==0 ){
169 zCopy = mprintf("%s", zDate);
170 zCopy[n-3] = 0;
171 zDate = zCopy;
172 n -= 3;
173
--- src/name.c
+++ src/name.c
@@ -111,15 +111,39 @@
111 }else{
112 rc = 0;
113 }
114 return rc;
115 }
116
117 /*
118 ** Return TRUE if the string begins with an ISO8601 date: YYYY-MM-DD.
119 */
120 static int is_date(const char *z){
121 if( !isdigit(z[0]) ) return 0;
122 if( !isdigit(z[1]) ) return 0;
123 if( !isdigit(z[2]) ) return 0;
124 if( !isdigit(z[3]) ) return 0;
125 if( z[4]!='-') return 0;
126 if( !isdigit(z[5]) ) return 0;
127 if( !isdigit(z[6]) ) return 0;
128 if( z[7]!='-') return 0;
129 if( !isdigit(z[8]) ) return 0;
130 if( !isdigit(z[9]) ) return 0;
131 return 1;
132 }
133
134 /*
135 ** Convert a symbolic tag name into the UUID of a check-in that contains
136 ** that tag. If the tag appears on multiple check-ins, return the UUID
137 ** of the most recent check-in with the tag.
138 **
139 ** If the input string is of the form:
140 **
141 ** tag:date
142 **
143 ** Then return the UUID of the oldest check-in with that tag that is
144 ** not older than 'date'.
145 **
146 ** Memory to hold the returned string comes from malloc() and needs to
147 ** be freed by the caller.
148 */
149 char *tag_to_uuid(const char *zTag){
@@ -132,10 +156,39 @@
156 " AND event.objid=tagxref.rid "
157 " AND blob.rid=event.objid "
158 " ORDER BY event.mtime DESC ",
159 zTag
160 );
161 if( zUuid==0 ){
162 int nTag = strlen(zTag);
163 int i;
164 for(i=0; i<nTag-10; i++){
165 if( zTag[i]==':' && is_date(&zTag[i+1]) ){
166 char *zDate = mprintf("%s", &zTag[i+1]);
167 char *zTagBase = mprintf("%.*s", i, zTag);
168 int nDate = strlen(zDate);
169 int useUtc = 0;
170 if( sqlite3_strnicmp(&zDate[nDate-3],"utc",3)==0 ){
171 nDate -= 3;
172 zDate[nDate] = 0;
173 useUtc = 1;
174 }
175 zUuid = db_text(0,
176 "SELECT blob.uuid"
177 " FROM tag, tagxref, event, blob"
178 " WHERE tag.tagname='sym-'||%Q "
179 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
180 " AND event.objid=tagxref.rid "
181 " AND blob.rid=event.objid "
182 " AND event.mtime<=julianday(%Q %s)"
183 " ORDER BY event.mtime DESC ",
184 zTagBase, zDate, (useUtc ? "" : ",'utc'")
185 );
186 break;
187 }
188 }
189 }
190 return zUuid;
191 }
192
193 /*
194 ** Convert a date/time string into a UUID.
@@ -162,11 +215,11 @@
215 }else if( memcmp(zDate, "utc:", 4)==0 ){
216 zDate += 4;
217 useUtc = 1;
218 }
219 n = strlen(zDate);
220 if( n<10 || !is_date(zDate) ) return 0;
221 if( n>4 && sqlite3_strnicmp(&zDate[n-3], "utc", 3)==0 ){
222 zCopy = mprintf("%s", zDate);
223 zCopy[n-3] = 0;
224 zDate = zCopy;
225 n -= 3;
226

Keyboard Shortcuts

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