Diff
Not logged in

Differences From Artifact [1511a64c2c]:

To Artifact [9c3bb93aa7]:


33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49

50
51
52
53

54
55

56
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
102
103
104
105
106
107
108
109
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


135
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48

49


50

51


52
53



54
55


56




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
102
103
104
105
106



107
108
109
110


111
112




113


114
115








116
117
118
119
120
121
122
123



124
125










126








127
128
129
130
131
132
133







-
+








-
+
-
-

-
+
-
-
+

-
-
-
+
+
-
-
+
-
-
-
-
+
+


+
+











-
-
-
-
-
+
-
-
-

+

+
+
+
+
+
+
+
-
+


+



-
+
-














-
-
-
+
+
+

-
-
+
+
-
-
-
-

-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-








/*
** This routine takes a user-entered UUID which might be in mixed
** case and might only be a prefix of the full UUID and converts it
** into the full-length UUID in canonical form.
**
** If the input is not a UUID or a UUID prefix, then try to resolve
** the name as a tag.
** the name as a tag.  If multiple tags match, pick the latest.
**
** Return the number of errors.
*/
int name_to_uuid(Blob *pName, int iErrPriority){
  int rc;
  int sz;
  sz = blob_size(pName);
  if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){
    Blob uuid;
    char *zUuid;
    static const char prefix[] = "tag:";
    static const int preflen = sizeof(prefix)-1;
    const char *zName = blob_str(pName);

    if( memcmp(zName, "tag:", 4)==0 ){
    if( strncmp(zName, prefix, preflen)==0 ){
      zName += preflen;
      zName += 4;
    }

    sym_tag_to_uuid(zName, &uuid);
    if( blob_size(&uuid)==0 ){
    zUuid = tag_to_uuid(zName);
    if( zUuid ){
      fossil_error(iErrPriority, "not a valid object name: %s", zName);
      blob_reset(&uuid);
      blob_reset(pName);
      return 1;
    }else{
      blob_reset(pName);
      *pName = uuid;
      blob_append(pName, zUuid, -1);
      free(zUuid);
      return 0;
    }
    fossil_error(iErrPriority, "not a valid object name: %s", zName);
    return 1;
  }
  blob_materialize(pName);
  canonical16(blob_buffer(pName), sz);
  if( sz==UUID_SIZE ){
    rc = db_int(1, "SELECT 0 FROM blob WHERE uuid=%B", pName);
    if( rc ){
      fossil_error(iErrPriority, "no such artifact: %b", pName);
      blob_reset(pName);
    }
  }else if( sz<UUID_SIZE && sz>=4 ){
    Stmt q;
    char zOrig[UUID_SIZE+1];
    memcpy(zOrig, blob_buffer(pName), sz);
    zOrig[sz] = 0;
    blob_reset(pName);
    db_prepare(&q, "SELECT uuid FROM blob"
    db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName);
                   " WHERE uuid>='%s'"
                   "   AND substr(uuid,1,%d)='%s'",
                   zOrig, sz, zOrig);
    if( db_step(&q)!=SQLITE_ROW ){
      char *zUuid;
      db_finalize(&q);
      zUuid = tag_to_uuid(blob_str(pName));
      if( zUuid ){
        blob_reset(pName);
        blob_append(pName, zUuid, -1);
        free(zUuid);
        return 0;
      }
      fossil_error(iErrPriority, "no artifacts match the prefix \"%s\"", zOrig);
      fossil_error(iErrPriority, "no artifacts match the prefix \"%b\"", pName);
      return 1;
    }
    blob_reset(pName);
    blob_append(pName, db_column_text(&q, 0), db_column_bytes(&q, 0));
    if( db_step(&q)==SQLITE_ROW ){
      fossil_error(iErrPriority, 
         "multiple artifacts match the prefix \"%s\"",
         "multiple artifacts match"
         zOrig
      );
      blob_reset(pName);
      db_finalize(&q);
      return 1;
    }
    db_finalize(&q);
    rc = 0;
  }else{
    rc = 0;
  }
  return rc;
}

/*
** This routine takes a name which might be a tag and attempts to
** produce a UUID. The UUID (if any) is returned in the blob pointed
** to by the second argument.
** Convert a symbolic tag name into the UUID of a check-in that contains
** that tag.  If the tag appears on multiple check-ins, return the UUID
** of the most recent check-in with the tag.
**
** Return as follows:
**      0   Name is not a tag
** Memory to hold the returned string comes from malloc() and needs to
** be freed by the caller.
**      1   A single UUID was found
**      2   More than one UUID was found, so this is presumably a
**          propagating tag. The return UUID is the most recent,
**          which is most likely to be the one wanted.
*/
int tag_to_uuid(const char *pName, Blob *pUuid,const char *pPrefix){
  Stmt q;
char *tag_to_uuid(const char *zTag){
  char *zUuid = 
  int count = 0;
  db_prepare(&q,
    "SELECT (SELECT uuid FROM blob WHERE rid=objid)"
    "  FROM tagxref JOIN event ON rid=objid"
    " WHERE tagxref.tagid=(SELECT tagid FROM tag WHERE tagname=%Q||%Q)"
    "   AND tagtype>0"
    "   AND value IS NULL"
    " ORDER BY event.mtime DESC",
    db_text(0,
       "SELECT blob.uuid"
       "  FROM tag, tagxref, event, blob"
       " WHERE tag.tagname='sym-'||%Q "
       "   AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
       "   AND event.objid=tagxref.rid "
       "   AND blob.rid=event.objid "
       " ORDER BY event.mtime DESC ",
    pPrefix,
    pName
  );
       zTag
    );
  blob_zero(pUuid);
  while( db_step(&q)==SQLITE_ROW ){
    count++;
    if(count>1){
      break;
    }
    db_column_blob(&q, 0, pUuid);
  }
  db_finalize(&q);
  return count;
  return zUuid;
}

/*
** This routine takes a name which might be a symbolic tag and
** attempts to produce a UUID. See tag_to_uuid.
*/
int sym_tag_to_uuid(const char *pName, Blob *pUuid){
    return tag_to_uuid(pName,pUuid,"sym-");
}

/*
** COMMAND:  test-name-to-id
**
** Convert a name to a full artifact ID.
*/