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

/*
** 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.
**
** 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;
    static const char prefix[] = "tag:";
    static const int preflen = sizeof(prefix)-1;
    const char *zName = blob_str(pName);

    if( strncmp(zName, prefix, preflen)==0 ){
      zName += preflen;
    }

    sym_tag_to_uuid(zName, &uuid);
    if( blob_size(&uuid)==0 ){
      fossil_error(iErrPriority, "not a valid object name: %s", zName);
      blob_reset(&uuid);
      return 1;
    }else{
      blob_reset(pName);
      *pName = uuid;
      return 0;
    }


  }
  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"
                   " WHERE uuid>='%s'"
                   "   AND substr(uuid,1,%d)='%s'",
                   zOrig, sz, zOrig);
    if( db_step(&q)!=SQLITE_ROW ){

      db_finalize(&q);







      fossil_error(iErrPriority, "no artifacts match the prefix \"%s\"", zOrig);
      return 1;
    }

    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\"",
         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.
**
** Return as follows:
**      0   Name is not a tag
**      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;
  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",
    pPrefix,
    pName
  );
  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;
}

/*
** 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.
*/







|








|
<
<

|
<
|

<
|
|
<
|
<
<
|
|


>
>











<
<
<
<
|
<
<
<

>

>
>
>
>
>
>
>
|


>



|
<














<
|
>
|

|
|
<
<
<
<

|
|
<
|
|
|
|
|
>
|
|
<
|
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<







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.  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) ){
    char *zUuid;


    const char *zName = blob_str(pName);
    if( memcmp(zName, "tag:", 4)==0 ){

      zName += 4;
    }

    zUuid = tag_to_uuid(zName);
    if( zUuid ){

      blob_reset(pName);


      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;




    db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName);



    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 \"%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"

      );
      blob_reset(pName);
      db_finalize(&q);
      return 1;
    }
    db_finalize(&q);
    rc = 0;
  }else{
    rc = 0;
  }
  return rc;
}

/*

** 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.
**
** Memory to hold the returned string comes from malloc() and needs to
** be freed by the caller.




*/
char *tag_to_uuid(const char *zTag){
  char *zUuid = 

    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 ",

       zTag
    );









  return zUuid;








}

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