Fossil SCM

Cleanup of the code used to resolve tag names in contexts where an artifact ID can be entered.

drh 2010-01-19 17:34 trunk
Commit bf56b2ddf4082e7ba0654574f7cd60f6246c54b3
2 files changed +8 -22 +43 -69
+8 -22
--- src/info.c
+++ src/info.c
@@ -1056,38 +1056,24 @@
10561056
** Figure out what the artifact ID is and jump to it.
10571057
*/
10581058
void info_page(void){
10591059
const char *zName;
10601060
Blob uuid;
1061
- int rid, nName;
1061
+ int rid;
10621062
10631063
zName = P("name");
10641064
if( zName==0 ) fossil_redirect_home();
1065
- nName = strlen(zName);
1066
- if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
1067
- switch( sym_tag_to_uuid(zName, &uuid) ){
1068
- case 1: {
1069
- /* got one UUID, use it */
1070
- zName = blob_str(&uuid);
1071
- break;
1072
- }
1073
- case 2: {
1074
- /* go somewhere to show the multiple UUIDs */
1075
- return;
1076
- break;
1077
- }
1078
- default: {
1079
- fossil_redirect_home();
1080
- break;
1081
- }
1082
- }
1083
- }
1084
- if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%s*'", zName) ){
1065
+ blob_set(&uuid, zName);
1066
+ if( name_to_uuid(&uuid, 1) ){
1067
+ fossil_redirect_home();
1068
+ }
1069
+ zName = blob_str(&uuid);
1070
+ if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zName) ){
10851071
tktview_page();
10861072
return;
10871073
}
1088
- rid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zName);
1074
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
10891075
if( rid==0 ){
10901076
style_header("Broken Link");
10911077
@ <p>No such object: %h(zName)</p>
10921078
style_footer();
10931079
return;
10941080
--- src/info.c
+++ src/info.c
@@ -1056,38 +1056,24 @@
1056 ** Figure out what the artifact ID is and jump to it.
1057 */
1058 void info_page(void){
1059 const char *zName;
1060 Blob uuid;
1061 int rid, nName;
1062
1063 zName = P("name");
1064 if( zName==0 ) fossil_redirect_home();
1065 nName = strlen(zName);
1066 if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
1067 switch( sym_tag_to_uuid(zName, &uuid) ){
1068 case 1: {
1069 /* got one UUID, use it */
1070 zName = blob_str(&uuid);
1071 break;
1072 }
1073 case 2: {
1074 /* go somewhere to show the multiple UUIDs */
1075 return;
1076 break;
1077 }
1078 default: {
1079 fossil_redirect_home();
1080 break;
1081 }
1082 }
1083 }
1084 if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%s*'", zName) ){
1085 tktview_page();
1086 return;
1087 }
1088 rid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%s*'", zName);
1089 if( rid==0 ){
1090 style_header("Broken Link");
1091 @ <p>No such object: %h(zName)</p>
1092 style_footer();
1093 return;
1094
--- src/info.c
+++ src/info.c
@@ -1056,38 +1056,24 @@
1056 ** Figure out what the artifact ID is and jump to it.
1057 */
1058 void info_page(void){
1059 const char *zName;
1060 Blob uuid;
1061 int rid;
1062
1063 zName = P("name");
1064 if( zName==0 ) fossil_redirect_home();
1065 blob_set(&uuid, zName);
1066 if( name_to_uuid(&uuid, 1) ){
1067 fossil_redirect_home();
1068 }
1069 zName = blob_str(&uuid);
1070 if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid='%s'", zName) ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1071 tktview_page();
1072 return;
1073 }
1074 rid = db_int(0, "SELECT rid FROM blob WHERE uuid='%s'", zName);
1075 if( rid==0 ){
1076 style_header("Broken Link");
1077 @ <p>No such object: %h(zName)</p>
1078 style_footer();
1079 return;
1080
+43 -69
--- src/name.c
+++ src/name.c
@@ -35,38 +35,33 @@
3535
** This routine takes a user-entered UUID which might be in mixed
3636
** case and might only be a prefix of the full UUID and converts it
3737
** into the full-length UUID in canonical form.
3838
**
3939
** If the input is not a UUID or a UUID prefix, then try to resolve
40
-** the name as a tag.
40
+** the name as a tag. If multiple tags match, pick the latest.
4141
**
4242
** Return the number of errors.
4343
*/
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
- Blob uuid;
50
- static const char prefix[] = "tag:";
51
- static const int preflen = sizeof(prefix)-1;
49
+ char *zUuid;
5250
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{
51
+ if( memcmp(zName, "tag:", 4)==0 ){
52
+ zName += 4;
53
+ }
54
+ zUuid = tag_to_uuid(zName);
55
+ if( zUuid ){
6456
blob_reset(pName);
65
- *pName = uuid;
57
+ blob_append(pName, zUuid, -1);
58
+ free(zUuid);
6659
return 0;
6760
}
61
+ fossil_error(iErrPriority, "not a valid object name: %s", zName);
62
+ return 1;
6863
}
6964
blob_materialize(pName);
7065
canonical16(blob_buffer(pName), sz);
7166
if( sz==UUID_SIZE ){
7267
rc = db_int(1, "SELECT 0 FROM blob WHERE uuid=%B", pName);
@@ -74,28 +69,29 @@
7469
fossil_error(iErrPriority, "no such artifact: %b", pName);
7570
blob_reset(pName);
7671
}
7772
}else if( sz<UUID_SIZE && sz>=4 ){
7873
Stmt q;
79
- char zOrig[UUID_SIZE+1];
80
- memcpy(zOrig, blob_buffer(pName), sz);
81
- zOrig[sz] = 0;
82
- blob_reset(pName);
83
- db_prepare(&q, "SELECT uuid FROM blob"
84
- " WHERE uuid>='%s'"
85
- " AND substr(uuid,1,%d)='%s'",
86
- zOrig, sz, zOrig);
74
+ db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName);
8775
if( db_step(&q)!=SQLITE_ROW ){
76
+ char *zUuid;
8877
db_finalize(&q);
89
- fossil_error(iErrPriority, "no artifacts match the prefix \"%s\"", zOrig);
78
+ zUuid = tag_to_uuid(blob_str(pName));
79
+ if( zUuid ){
80
+ blob_reset(pName);
81
+ blob_append(pName, zUuid, -1);
82
+ free(zUuid);
83
+ return 0;
84
+ }
85
+ fossil_error(iErrPriority, "no artifacts match the prefix \"%b\"", pName);
9086
return 1;
9187
}
88
+ blob_reset(pName);
9289
blob_append(pName, db_column_text(&q, 0), db_column_bytes(&q, 0));
9390
if( db_step(&q)==SQLITE_ROW ){
9491
fossil_error(iErrPriority,
95
- "multiple artifacts match the prefix \"%s\"",
96
- zOrig
92
+ "multiple artifacts match"
9793
);
9894
blob_reset(pName);
9995
db_finalize(&q);
10096
return 1;
10197
}
@@ -106,52 +102,30 @@
106102
}
107103
return rc;
108104
}
109105
110106
/*
111
-** This routine takes a name which might be a tag and attempts to
112
-** produce a UUID. The UUID (if any) is returned in the blob pointed
113
-** to by the second argument.
114
-**
115
-** Return as follows:
116
-** 0 Name is not a tag
117
-** 1 A single UUID was found
118
-** 2 More than one UUID was found, so this is presumably a
119
-** propagating tag. The return UUID is the most recent,
120
-** which is most likely to be the one wanted.
121
-*/
122
-int tag_to_uuid(const char *pName, Blob *pUuid,const char *pPrefix){
123
- Stmt q;
124
- int count = 0;
125
- db_prepare(&q,
126
- "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
127
- " FROM tagxref JOIN event ON rid=objid"
128
- " WHERE tagxref.tagid=(SELECT tagid FROM tag WHERE tagname=%Q||%Q)"
129
- " AND tagtype>0"
130
- " AND value IS NULL"
131
- " ORDER BY event.mtime DESC",
132
- pPrefix,
133
- pName
134
- );
135
- blob_zero(pUuid);
136
- while( db_step(&q)==SQLITE_ROW ){
137
- count++;
138
- if(count>1){
139
- break;
140
- }
141
- db_column_blob(&q, 0, pUuid);
142
- }
143
- db_finalize(&q);
144
- return count;
145
-}
146
-
147
-/*
148
-** This routine takes a name which might be a symbolic tag and
149
-** attempts to produce a UUID. See tag_to_uuid.
150
-*/
151
-int sym_tag_to_uuid(const char *pName, Blob *pUuid){
152
- return tag_to_uuid(pName,pUuid,"sym-");
107
+** Convert a symbolic tag name into the UUID of a check-in that contains
108
+** that tag. If the tag appears on multiple check-ins, return the UUID
109
+** of the most recent check-in with the tag.
110
+**
111
+** Memory to hold the returned string comes from malloc() and needs to
112
+** be freed by the caller.
113
+*/
114
+char *tag_to_uuid(const char *zTag){
115
+ char *zUuid =
116
+ db_text(0,
117
+ "SELECT blob.uuid"
118
+ " FROM tag, tagxref, event, blob"
119
+ " WHERE tag.tagname='sym-'||%Q "
120
+ " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
121
+ " AND event.objid=tagxref.rid "
122
+ " AND blob.rid=event.objid "
123
+ " ORDER BY event.mtime DESC ",
124
+ zTag
125
+ );
126
+ return zUuid;
153127
}
154128
155129
/*
156130
** COMMAND: test-name-to-id
157131
**
158132
--- src/name.c
+++ src/name.c
@@ -35,38 +35,33 @@
35 ** This routine takes a user-entered UUID which might be in mixed
36 ** case and might only be a prefix of the full UUID and converts it
37 ** into the full-length UUID in canonical form.
38 **
39 ** If the input is not a UUID or a UUID prefix, then try to resolve
40 ** the name as a tag.
41 **
42 ** Return the number of errors.
43 */
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{
64 blob_reset(pName);
65 *pName = uuid;
 
66 return 0;
67 }
 
 
68 }
69 blob_materialize(pName);
70 canonical16(blob_buffer(pName), sz);
71 if( sz==UUID_SIZE ){
72 rc = db_int(1, "SELECT 0 FROM blob WHERE uuid=%B", pName);
@@ -74,28 +69,29 @@
74 fossil_error(iErrPriority, "no such artifact: %b", pName);
75 blob_reset(pName);
76 }
77 }else if( sz<UUID_SIZE && sz>=4 ){
78 Stmt q;
79 char zOrig[UUID_SIZE+1];
80 memcpy(zOrig, blob_buffer(pName), sz);
81 zOrig[sz] = 0;
82 blob_reset(pName);
83 db_prepare(&q, "SELECT uuid FROM blob"
84 " WHERE uuid>='%s'"
85 " AND substr(uuid,1,%d)='%s'",
86 zOrig, sz, zOrig);
87 if( db_step(&q)!=SQLITE_ROW ){
 
88 db_finalize(&q);
89 fossil_error(iErrPriority, "no artifacts match the prefix \"%s\"", zOrig);
 
 
 
 
 
 
 
90 return 1;
91 }
 
92 blob_append(pName, db_column_text(&q, 0), db_column_bytes(&q, 0));
93 if( db_step(&q)==SQLITE_ROW ){
94 fossil_error(iErrPriority,
95 "multiple artifacts match the prefix \"%s\"",
96 zOrig
97 );
98 blob_reset(pName);
99 db_finalize(&q);
100 return 1;
101 }
@@ -106,52 +102,30 @@
106 }
107 return rc;
108 }
109
110 /*
111 ** This routine takes a name which might be a tag and attempts to
112 ** produce a UUID. The UUID (if any) is returned in the blob pointed
113 ** to by the second argument.
114 **
115 ** Return as follows:
116 ** 0 Name is not a tag
117 ** 1 A single UUID was found
118 ** 2 More than one UUID was found, so this is presumably a
119 ** propagating tag. The return UUID is the most recent,
120 ** which is most likely to be the one wanted.
121 */
122 int tag_to_uuid(const char *pName, Blob *pUuid,const char *pPrefix){
123 Stmt q;
124 int count = 0;
125 db_prepare(&q,
126 "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
127 " FROM tagxref JOIN event ON rid=objid"
128 " WHERE tagxref.tagid=(SELECT tagid FROM tag WHERE tagname=%Q||%Q)"
129 " AND tagtype>0"
130 " AND value IS NULL"
131 " ORDER BY event.mtime DESC",
132 pPrefix,
133 pName
134 );
135 blob_zero(pUuid);
136 while( db_step(&q)==SQLITE_ROW ){
137 count++;
138 if(count>1){
139 break;
140 }
141 db_column_blob(&q, 0, pUuid);
142 }
143 db_finalize(&q);
144 return count;
145 }
146
147 /*
148 ** This routine takes a name which might be a symbolic tag and
149 ** attempts to produce a UUID. See tag_to_uuid.
150 */
151 int sym_tag_to_uuid(const char *pName, Blob *pUuid){
152 return tag_to_uuid(pName,pUuid,"sym-");
153 }
154
155 /*
156 ** COMMAND: test-name-to-id
157 **
158
--- src/name.c
+++ src/name.c
@@ -35,38 +35,33 @@
35 ** This routine takes a user-entered UUID which might be in mixed
36 ** case and might only be a prefix of the full UUID and converts it
37 ** into the full-length UUID in canonical form.
38 **
39 ** If the input is not a UUID or a UUID prefix, then try to resolve
40 ** the name as a tag. If multiple tags match, pick the latest.
41 **
42 ** Return the number of errors.
43 */
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 char *zUuid;
 
 
50 const char *zName = blob_str(pName);
51 if( memcmp(zName, "tag:", 4)==0 ){
52 zName += 4;
53 }
54 zUuid = tag_to_uuid(zName);
55 if( zUuid ){
 
 
 
 
 
 
56 blob_reset(pName);
57 blob_append(pName, zUuid, -1);
58 free(zUuid);
59 return 0;
60 }
61 fossil_error(iErrPriority, "not a valid object name: %s", zName);
62 return 1;
63 }
64 blob_materialize(pName);
65 canonical16(blob_buffer(pName), sz);
66 if( sz==UUID_SIZE ){
67 rc = db_int(1, "SELECT 0 FROM blob WHERE uuid=%B", pName);
@@ -74,28 +69,29 @@
69 fossil_error(iErrPriority, "no such artifact: %b", pName);
70 blob_reset(pName);
71 }
72 }else if( sz<UUID_SIZE && sz>=4 ){
73 Stmt q;
74 db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName);
 
 
 
 
 
 
 
75 if( db_step(&q)!=SQLITE_ROW ){
76 char *zUuid;
77 db_finalize(&q);
78 zUuid = tag_to_uuid(blob_str(pName));
79 if( zUuid ){
80 blob_reset(pName);
81 blob_append(pName, zUuid, -1);
82 free(zUuid);
83 return 0;
84 }
85 fossil_error(iErrPriority, "no artifacts match the prefix \"%b\"", pName);
86 return 1;
87 }
88 blob_reset(pName);
89 blob_append(pName, db_column_text(&q, 0), db_column_bytes(&q, 0));
90 if( db_step(&q)==SQLITE_ROW ){
91 fossil_error(iErrPriority,
92 "multiple artifacts match"
 
93 );
94 blob_reset(pName);
95 db_finalize(&q);
96 return 1;
97 }
@@ -106,52 +102,30 @@
102 }
103 return rc;
104 }
105
106 /*
107 ** Convert a symbolic tag name into the UUID of a check-in that contains
108 ** that tag. If the tag appears on multiple check-ins, return the UUID
109 ** of the most recent check-in with the tag.
110 **
111 ** Memory to hold the returned string comes from malloc() and needs to
112 ** be freed by the caller.
113 */
114 char *tag_to_uuid(const char *zTag){
115 char *zUuid =
116 db_text(0,
117 "SELECT blob.uuid"
118 " FROM tag, tagxref, event, blob"
119 " WHERE tag.tagname='sym-'||%Q "
120 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
121 " AND event.objid=tagxref.rid "
122 " AND blob.rid=event.objid "
123 " ORDER BY event.mtime DESC ",
124 zTag
125 );
126 return zUuid;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127 }
128
129 /*
130 ** COMMAND: test-name-to-id
131 **
132

Keyboard Shortcuts

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