Fossil SCM

Make the info web page handle symbolic tags as well as UUIDs. Start trying to make the currently-disabled tagview page more useful.

eric 2008-08-04 20:46 eric-tagview-rework
Commit 3984b1b2c117b7b3ea4ab2b844e1b607d03dbf8a
4 files changed +18 -1 +1 -1 +37 -15 +82 -3
+18 -1
--- src/info.c
+++ src/info.c
@@ -911,17 +911,34 @@
911911
**
912912
** Figure out what the UUID is and jump to it.
913913
*/
914914
void info_page(void){
915915
const char *zName;
916
+ Blob uuid;
916917
int rid, nName;
917918
918919
zName = P("name");
919920
if( zName==0 ) fossil_redirect_home();
920921
nName = strlen(zName);
921922
if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
922
- fossil_redirect_home();
923
+ switch( sym_tag_to_uuid(zName, &uuid) ){
924
+ case 1: {
925
+ /* got one UUID, use it */
926
+ zName = blob_str(&uuid);
927
+ break;
928
+ }
929
+ case 2: {
930
+ /* go somewhere to show the multiple UUIDs */
931
+ tagview_page();
932
+ return;
933
+ break;
934
+ }
935
+ default: {
936
+ fossil_redirect_home();
937
+ break;
938
+ }
939
+ }
923940
}
924941
if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%s*'", zName) ){
925942
tktview_page();
926943
return;
927944
}
928945
--- src/info.c
+++ src/info.c
@@ -911,17 +911,34 @@
911 **
912 ** Figure out what the UUID is and jump to it.
913 */
914 void info_page(void){
915 const char *zName;
 
916 int rid, nName;
917
918 zName = P("name");
919 if( zName==0 ) fossil_redirect_home();
920 nName = strlen(zName);
921 if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
922 fossil_redirect_home();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
923 }
924 if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%s*'", zName) ){
925 tktview_page();
926 return;
927 }
928
--- src/info.c
+++ src/info.c
@@ -911,17 +911,34 @@
911 **
912 ** Figure out what the UUID is and jump to it.
913 */
914 void info_page(void){
915 const char *zName;
916 Blob uuid;
917 int rid, nName;
918
919 zName = P("name");
920 if( zName==0 ) fossil_redirect_home();
921 nName = strlen(zName);
922 if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
923 switch( sym_tag_to_uuid(zName, &uuid) ){
924 case 1: {
925 /* got one UUID, use it */
926 zName = blob_str(&uuid);
927 break;
928 }
929 case 2: {
930 /* go somewhere to show the multiple UUIDs */
931 tagview_page();
932 return;
933 break;
934 }
935 default: {
936 fossil_redirect_home();
937 break;
938 }
939 }
940 }
941 if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%s*'", zName) ){
942 tktview_page();
943 return;
944 }
945
+1 -1
--- src/login.c
+++ src/login.c
@@ -299,11 +299,11 @@
299299
}
300300
g.userUid = uid;
301301
if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
302302
g.zLogin = 0;
303303
}
304
- if( uid>0 ){
304
+ if( uid && g.zLogin ){
305305
zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
306306
login_set_capabilities(zNcap);
307307
if( db_get_int("inherit-anon",0) ){
308308
zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
309309
login_set_capabilities(zAcap);
310310
--- src/login.c
+++ src/login.c
@@ -299,11 +299,11 @@
299 }
300 g.userUid = uid;
301 if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
302 g.zLogin = 0;
303 }
304 if( uid>0 ){
305 zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
306 login_set_capabilities(zNcap);
307 if( db_get_int("inherit-anon",0) ){
308 zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
309 login_set_capabilities(zAcap);
310
--- src/login.c
+++ src/login.c
@@ -299,11 +299,11 @@
299 }
300 g.userUid = uid;
301 if( g.zLogin && strcmp(g.zLogin,"nobody")==0 ){
302 g.zLogin = 0;
303 }
304 if( uid && g.zLogin ){
305 zNcap = db_text("", "SELECT cap FROM user WHERE login = 'nobody'");
306 login_set_capabilities(zNcap);
307 if( db_get_int("inherit-anon",0) ){
308 zAcap = db_text("", "SELECT cap FROM user WHERE login = 'anonymous'");
309 login_set_capabilities(zAcap);
310
+37 -15
--- src/name.c
+++ src/name.c
@@ -44,34 +44,20 @@
4444
int name_to_uuid(Blob *pName, int iErrPriority){
4545
int rc;
4646
int sz;
4747
sz = blob_size(pName);
4848
if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){
49
- Stmt q;
5049
Blob uuid;
5150
static const char prefix[] = "tag:";
5251
static const int preflen = sizeof(prefix)-1;
5352
const char *zName = blob_str(pName);
5453
5554
if( strncmp(zName, prefix, preflen)==0 ){
5655
zName += preflen;
5756
}
5857
59
- db_prepare(&q,
60
- "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
61
- " FROM tagxref JOIN event ON rid=objid"
62
- " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)"
63
- " AND tagtype>0"
64
- " AND value IS NULL"
65
- " ORDER BY event.mtime DESC",
66
- zName
67
- );
68
- blob_zero(&uuid);
69
- if( db_step(&q)==SQLITE_ROW ){
70
- db_column_blob(&q, 0, &uuid);
71
- }
72
- db_finalize(&q);
58
+ sym_tag_to_uuid(zName, &uuid);
7359
if( blob_size(&uuid)==0 ){
7460
fossil_error(iErrPriority, "not a valid object name: %s", zName);
7561
blob_reset(&uuid);
7662
return 1;
7763
}else{
@@ -111,10 +97,46 @@
11197
}else{
11298
rc = 0;
11399
}
114100
return rc;
115101
}
102
+
103
+/*
104
+** This routine takes a name which might be a symbolic tag and
105
+** attempts to produce a UUID. The UUID (if any) is returned in the
106
+** blob pointed to by the second argument.
107
+**
108
+** Return as follows:
109
+** 0 Name is not a tag
110
+** 1 A single UUID was found
111
+** 2 More than one UUID was found, so this is presumably a
112
+** propagating tag. The return UUID is the most recent,
113
+** which is most likely to be the one wanted.
114
+*/
115
+int sym_tag_to_uuid(const char *pName, Blob *pUuid){
116
+ Stmt q;
117
+ int count = 0;
118
+ db_prepare(&q,
119
+ "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
120
+ " FROM tagxref JOIN event ON rid=objid"
121
+ " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)"
122
+ " AND tagtype>0"
123
+ " AND value IS NULL"
124
+ " ORDER BY event.mtime DESC",
125
+ pName
126
+ );
127
+ blob_zero(pUuid);
128
+ while( db_step(&q)==SQLITE_ROW ){
129
+ count++;
130
+ if(count>1){
131
+ break;
132
+ }
133
+ db_column_blob(&q, 0, pUuid);
134
+ }
135
+ db_finalize(&q);
136
+ return count;
137
+}
116138
117139
/*
118140
** COMMAND: test-name-to-uuid
119141
**
120142
** Convert a name to a full UUID.
121143
--- src/name.c
+++ src/name.c
@@ -44,34 +44,20 @@
44 int name_to_uuid(Blob *pName, int iErrPriority){
45 int rc;
46 int sz;
47 sz = blob_size(pName);
48 if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){
49 Stmt q;
50 Blob uuid;
51 static const char prefix[] = "tag:";
52 static const int preflen = sizeof(prefix)-1;
53 const char *zName = blob_str(pName);
54
55 if( strncmp(zName, prefix, preflen)==0 ){
56 zName += preflen;
57 }
58
59 db_prepare(&q,
60 "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
61 " FROM tagxref JOIN event ON rid=objid"
62 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)"
63 " AND tagtype>0"
64 " AND value IS NULL"
65 " ORDER BY event.mtime DESC",
66 zName
67 );
68 blob_zero(&uuid);
69 if( db_step(&q)==SQLITE_ROW ){
70 db_column_blob(&q, 0, &uuid);
71 }
72 db_finalize(&q);
73 if( blob_size(&uuid)==0 ){
74 fossil_error(iErrPriority, "not a valid object name: %s", zName);
75 blob_reset(&uuid);
76 return 1;
77 }else{
@@ -111,10 +97,46 @@
111 }else{
112 rc = 0;
113 }
114 return rc;
115 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
117 /*
118 ** COMMAND: test-name-to-uuid
119 **
120 ** Convert a name to a full UUID.
121
--- src/name.c
+++ src/name.c
@@ -44,34 +44,20 @@
44 int name_to_uuid(Blob *pName, int iErrPriority){
45 int rc;
46 int sz;
47 sz = blob_size(pName);
48 if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){
 
49 Blob uuid;
50 static const char prefix[] = "tag:";
51 static const int preflen = sizeof(prefix)-1;
52 const char *zName = blob_str(pName);
53
54 if( strncmp(zName, prefix, preflen)==0 ){
55 zName += preflen;
56 }
57
58 sym_tag_to_uuid(zName, &uuid);
 
 
 
 
 
 
 
 
 
 
 
 
 
59 if( blob_size(&uuid)==0 ){
60 fossil_error(iErrPriority, "not a valid object name: %s", zName);
61 blob_reset(&uuid);
62 return 1;
63 }else{
@@ -111,10 +97,46 @@
97 }else{
98 rc = 0;
99 }
100 return rc;
101 }
102
103 /*
104 ** This routine takes a name which might be a symbolic tag and
105 ** attempts to produce a UUID. The UUID (if any) is returned in the
106 ** blob pointed to by the second argument.
107 **
108 ** Return as follows:
109 ** 0 Name is not a tag
110 ** 1 A single UUID was found
111 ** 2 More than one UUID was found, so this is presumably a
112 ** propagating tag. The return UUID is the most recent,
113 ** which is most likely to be the one wanted.
114 */
115 int sym_tag_to_uuid(const char *pName, Blob *pUuid){
116 Stmt q;
117 int count = 0;
118 db_prepare(&q,
119 "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
120 " FROM tagxref JOIN event ON rid=objid"
121 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname='sym-'||%Q)"
122 " AND tagtype>0"
123 " AND value IS NULL"
124 " ORDER BY event.mtime DESC",
125 pName
126 );
127 blob_zero(pUuid);
128 while( db_step(&q)==SQLITE_ROW ){
129 count++;
130 if(count>1){
131 break;
132 }
133 db_column_blob(&q, 0, pUuid);
134 }
135 db_finalize(&q);
136 return count;
137 }
138
139 /*
140 ** COMMAND: test-name-to-uuid
141 **
142 ** Convert a name to a full UUID.
143
+82 -3
--- src/tagview.c
+++ src/tagview.c
@@ -78,11 +78,11 @@
7878
** A small search form which forwards to ?like=SEARCH_STRING
7979
*/
8080
static void tagview_page_search_miniform(void){
8181
char const * like = P("like");
8282
@ <div style='font-size:smaller'>
83
- @ <form action='/tagview' method='post'>
83
+ @ <form action='tagview' method='post'>
8484
@ Search for tags:
8585
@ <input type='text' name='like' value='%h((like?like:""))' size='10'/>
8686
@ <input type='submit'/>
8787
@ </form>
8888
@ </div>
@@ -134,15 +134,40 @@
134134
tagname);
135135
db_generic_query_view(zSql, 1);
136136
free(zSql);
137137
}
138138
139
+/*
140
+** Get the UUIDs for a tag
141
+*/
142
+char *tag_query_for_www(const char *pName){
143
+ static const char zBaseSql[] =
144
+ @ SELECT
145
+ @ blob.rid,
146
+ @ uuid,
147
+ @ datetime(event.mtime,'localtime') AS timestamp,
148
+ @ coalesce(ecomment, comment),
149
+ @ coalesce(euser, user),
150
+ @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),
151
+ @ (SELECT count(*) FROM plink WHERE cid=blob.rid),
152
+ @ NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),
153
+ @ coalesce(bgcolor, brbgcolor),
154
+ @ event.type
155
+ @ FROM event JOIN blob JOIN tagxref
156
+ @ WHERE blob.rid=event.objid
157
+ @ AND tagxref.rid = event.objid
158
+ @ AND tagxref.tagid = (SELECT tagid FROM tag
159
+ @ WHERE tagname = 'sym-'||%Q)
160
+ @ ORDER BY 3 desc
161
+ ;
162
+ return mprintf(zBaseSql,pName);
163
+}
139164
140165
/*
141
-** WEBPAGE: /tagview
166
+** WEBP AGE: /tagview
142167
*/
143
-void tagview_page(void){
168
+void old_tagview_page(void){
144169
char const * check = 0;
145170
login_check_credentials();
146171
if( !g.okRdWiki ){
147172
login_needed();
148173
}
@@ -159,7 +184,61 @@
159184
}else{
160185
tagview_page_default();
161186
}
162187
style_footer();
163188
}
189
+
190
+/*
191
+** WEBPAGE: /tagview
192
+*/
193
+void tagview_page(void){
194
+ char const *zName = 0;
195
+ login_check_credentials();
196
+ if( !g.okRead ){
197
+ login_needed();
198
+ }
199
+ login_anonymous_available();
200
+ if( 0 != (zName = P("name")) ){
201
+ Blob uuid;
202
+ char *zSql;
203
+ Stmt q;
204
+ if( sym_tag_to_uuid(zName, &uuid) > 0){
205
+ style_header("Tagged Baselines");
206
+ @ <h2>%s(zName):</h2>
207
+ zSql = tag_query_for_www(zName);
208
+ db_prepare(&q, zSql);
209
+ free(zSql);
210
+ www_print_timeline(&q);
211
+ db_finalize(&q);
212
+ }else{
213
+ style_header("TaggedBaselines");
214
+ @ <h2>%s(zName):</h2>
215
+ @ There is no artifact with this tag.
216
+ }
217
+ }else{
218
+ Stmt q;
219
+ const char *prefix = "sym-";
220
+ int preflen = strlen(prefix);
221
+ style_header("Tags");
222
+ db_prepare(&q,
223
+ "SELECT tagname"
224
+ " FROM tag"
225
+ " WHERE EXISTS(SELECT 1 FROM tagxref"
226
+ " WHERE tagid=tag.tagid"
227
+ " AND tagtype>0)"
228
+ " ORDER BY tagname"
229
+ );
230
+ @ <ul>
231
+ while( db_step(&q)==SQLITE_ROW ){
232
+ const char *name = db_column_text(&q, 0);
233
+ if( strncmp(name, prefix, preflen)==0 ){
234
+ @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name+preflen)>
235
+ @ %s(name+preflen)</a></li>
236
+ }
237
+ }
238
+ @ </ul>
239
+ db_finalize(&q);
240
+ }
241
+ style_footer();
242
+}
164243
165244
#undef TAGVIEW_DEFAULT_FILTER
166245
--- src/tagview.c
+++ src/tagview.c
@@ -78,11 +78,11 @@
78 ** A small search form which forwards to ?like=SEARCH_STRING
79 */
80 static void tagview_page_search_miniform(void){
81 char const * like = P("like");
82 @ <div style='font-size:smaller'>
83 @ <form action='/tagview' method='post'>
84 @ Search for tags:
85 @ <input type='text' name='like' value='%h((like?like:""))' size='10'/>
86 @ <input type='submit'/>
87 @ </form>
88 @ </div>
@@ -134,15 +134,40 @@
134 tagname);
135 db_generic_query_view(zSql, 1);
136 free(zSql);
137 }
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
140 /*
141 ** WEBPAGE: /tagview
142 */
143 void tagview_page(void){
144 char const * check = 0;
145 login_check_credentials();
146 if( !g.okRdWiki ){
147 login_needed();
148 }
@@ -159,7 +184,61 @@
159 }else{
160 tagview_page_default();
161 }
162 style_footer();
163 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
165 #undef TAGVIEW_DEFAULT_FILTER
166
--- src/tagview.c
+++ src/tagview.c
@@ -78,11 +78,11 @@
78 ** A small search form which forwards to ?like=SEARCH_STRING
79 */
80 static void tagview_page_search_miniform(void){
81 char const * like = P("like");
82 @ <div style='font-size:smaller'>
83 @ <form action='tagview' method='post'>
84 @ Search for tags:
85 @ <input type='text' name='like' value='%h((like?like:""))' size='10'/>
86 @ <input type='submit'/>
87 @ </form>
88 @ </div>
@@ -134,15 +134,40 @@
134 tagname);
135 db_generic_query_view(zSql, 1);
136 free(zSql);
137 }
138
139 /*
140 ** Get the UUIDs for a tag
141 */
142 char *tag_query_for_www(const char *pName){
143 static const char zBaseSql[] =
144 @ SELECT
145 @ blob.rid,
146 @ uuid,
147 @ datetime(event.mtime,'localtime') AS timestamp,
148 @ coalesce(ecomment, comment),
149 @ coalesce(euser, user),
150 @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim=1),
151 @ (SELECT count(*) FROM plink WHERE cid=blob.rid),
152 @ NOT EXISTS (SELECT 1 FROM plink WHERE pid=blob.rid),
153 @ coalesce(bgcolor, brbgcolor),
154 @ event.type
155 @ FROM event JOIN blob JOIN tagxref
156 @ WHERE blob.rid=event.objid
157 @ AND tagxref.rid = event.objid
158 @ AND tagxref.tagid = (SELECT tagid FROM tag
159 @ WHERE tagname = 'sym-'||%Q)
160 @ ORDER BY 3 desc
161 ;
162 return mprintf(zBaseSql,pName);
163 }
164
165 /*
166 ** WEBP AGE: /tagview
167 */
168 void old_tagview_page(void){
169 char const * check = 0;
170 login_check_credentials();
171 if( !g.okRdWiki ){
172 login_needed();
173 }
@@ -159,7 +184,61 @@
184 }else{
185 tagview_page_default();
186 }
187 style_footer();
188 }
189
190 /*
191 ** WEBPAGE: /tagview
192 */
193 void tagview_page(void){
194 char const *zName = 0;
195 login_check_credentials();
196 if( !g.okRead ){
197 login_needed();
198 }
199 login_anonymous_available();
200 if( 0 != (zName = P("name")) ){
201 Blob uuid;
202 char *zSql;
203 Stmt q;
204 if( sym_tag_to_uuid(zName, &uuid) > 0){
205 style_header("Tagged Baselines");
206 @ <h2>%s(zName):</h2>
207 zSql = tag_query_for_www(zName);
208 db_prepare(&q, zSql);
209 free(zSql);
210 www_print_timeline(&q);
211 db_finalize(&q);
212 }else{
213 style_header("TaggedBaselines");
214 @ <h2>%s(zName):</h2>
215 @ There is no artifact with this tag.
216 }
217 }else{
218 Stmt q;
219 const char *prefix = "sym-";
220 int preflen = strlen(prefix);
221 style_header("Tags");
222 db_prepare(&q,
223 "SELECT tagname"
224 " FROM tag"
225 " WHERE EXISTS(SELECT 1 FROM tagxref"
226 " WHERE tagid=tag.tagid"
227 " AND tagtype>0)"
228 " ORDER BY tagname"
229 );
230 @ <ul>
231 while( db_step(&q)==SQLITE_ROW ){
232 const char *name = db_column_text(&q, 0);
233 if( strncmp(name, prefix, preflen)==0 ){
234 @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name+preflen)>
235 @ %s(name+preflen)</a></li>
236 }
237 }
238 @ </ul>
239 db_finalize(&q);
240 }
241 style_footer();
242 }
243
244 #undef TAGVIEW_DEFAULT_FILTER
245

Keyboard Shortcuts

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