Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add initial infrastructure for being able to resolve 'ckout' uniformly in certain contexts, per /chat discussion. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
4d8c30265b3dc76d9fe559cb1c91aea0 |
| User & Date: | stephan 2023-01-24 19:01:11.326 |
References
|
2024-12-26
| ||
| 09:27 | Correct some as-yet-unused semantics in symbolic_name_to_rid() which were inadvertently broken in [1ef6499a9a], which was reverting some new breakage from [4d8c30265b3dc76d]. Problem seen only by accident when comparison impls between fossil and libfossil. The value of the feature being repaired is, in hindsight, questionable. check-in: 15df204706 user: stephan tags: trunk | |
|
2023-09-09
| ||
| 15:05 | Correct inability to use certain commands after doing (open --empty), as reported in [forum:04f86a038c|forum post 04f86a038c] and caused by [4d8c30265b]. check-in: 1ef6499a9a user: stephan tags: trunk | |
Context
|
2023-01-24
| ||
| 21:25 | Upgrade FTS search from v4 to v5. check-in: c3c4ef167e user: stephan tags: trunk | |
| 19:01 | Add initial infrastructure for being able to resolve 'ckout' uniformly in certain contexts, per /chat discussion. check-in: 4d8c30265b user: stephan tags: trunk | |
| 03:18 | Replaced a standalone "diffFlags" variable in the /fdiff handler with use of the new DiffConfig.diffFlags member. No functional change, just a code cleanup found while working on another branch. Making it on trunk to keep that branch's diffs minimal. check-in: 65d97f23f6 user: wyoung tags: trunk | |
Changes
Changes to src/db.c.
| ︙ | ︙ | |||
2202 2203 2204 2205 2206 2207 2208 |
g.zLocalDbName = mprintf("%s", zPwd);
zPwd[n] = 0;
while( n>0 && zPwd[n-1]=='/' ){
n--;
zPwd[n] = 0;
}
g.zLocalRoot = mprintf("%s/", zPwd);
| | | 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 |
g.zLocalDbName = mprintf("%s", zPwd);
zPwd[n] = 0;
while( n>0 && zPwd[n-1]=='/' ){
n--;
zPwd[n] = 0;
}
g.zLocalRoot = mprintf("%s/", zPwd);
g.localOpen = db_lget_int("checkout", -1);
db_open_repository(zDbName);
return 1;
}
}
if( bRootOnly ) break;
n--;
while( n>1 && zPwd[n]!='/' ){ n--; }
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
**
** This file contains code used to resolved user-supplied object names.
*/
#include "config.h"
#include "name.h"
#include <assert.h>
/*
** Return TRUE if the string begins with something that looks roughly
** like an ISO date/time string. The SQLite date/time functions will
** have the final say-so about whether or not the date/time string is
** well-formed.
*/
int fossil_isdate(const char *z){
| > > > > > > > > > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
**
** This file contains code used to resolved user-supplied object names.
*/
#include "config.h"
#include "name.h"
#include <assert.h>
#if INTERFACE
/*
** An upper boundary on RIDs, provided in order to be able to
** distinguish real RID values from RID_CKOUT and any future
** RID_... values.
*/
#define RID_MAX 0x7ffffff0
/*
** A "magic" RID representing the current checkout in some contexts.
*/
#define RID_CKOUT (RID_MAX+1)
#endif
/*
** Return TRUE if the string begins with something that looks roughly
** like an ISO date/time string. The SQLite date/time functions will
** have the final say-so about whether or not the date/time string is
** well-formed.
*/
int fossil_isdate(const char *z){
|
| ︙ | ︙ | |||
163 164 165 166 167 168 169 |
" par(pid, ex, cnt) as ("
" SELECT pid, EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0"
" AND value=%Q AND rid=plink.pid), 1"
" FROM plink WHERE cid=%d AND isprim"
" UNION ALL "
" SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
| | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
" par(pid, ex, cnt) as ("
" SELECT pid, EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0"
" AND value=%Q AND rid=plink.pid), 1"
" FROM plink WHERE cid=%d AND isprim"
" UNION ALL "
" SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
" WHERE tagid=%d AND tagtype>0"
" AND value=%Q AND rid=plink.pid),"
" 1+par.cnt"
" FROM plink, par"
" WHERE cid=par.pid AND isprim AND par.ex "
" LIMIT 100000 "
" )"
" SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
);
fossil_free(zBr);
rc = db_step(&q);
if( rc==SQLITE_ROW ){
ans = db_column_int(&q, 0);
}
db_finalize(&q);
if( eType==2 && ans>0 ){
zBr = branch_of_rid(ans);
ans = compute_youngest_ancestor_in_branch(rid, zBr);
fossil_free(zBr);
}
return ans;
}
/*
** Find the RID of the most recent object with symbolic tag zTag
** and having a type that matches zType.
**
** Return 0 if there are no matches.
**
** This is a tricky query to do efficiently.
** If the tag is very common (ex: "trunk") then
** we want to use the query identified below as Q1 - which searching
** the most recent EVENT table entries for the most recent with the tag.
** But if the tag is relatively scarce (anything other than "trunk", basically)
** then we want to do the indexed search show below as Q2.
*/
static int most_recent_event_with_tag(const char *zTag, const char *zType){
|
| ︙ | ︙ | |||
276 277 278 279 280 281 282 | ** ** The zType parameter specifies the type of artifact: ci, t, w, e, g, f. ** If zType is NULL or "" or "*" then any type of artifact will serve. ** If zType is "br" then find the first check-in of the named branch ** rather than the last. ** ** zType is "ci" in most use cases since we are usually searching for | | > > > > > < > > > > > > > | > > | | > > | > > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
**
** The zType parameter specifies the type of artifact: ci, t, w, e, g, f.
** If zType is NULL or "" or "*" then any type of artifact will serve.
** If zType is "br" then find the first check-in of the named branch
** rather than the last.
**
** zType is "ci" in most use cases since we are usually searching for
** a check-in. A value of "ci+" works like "ci" but adds these
** semantics: if zTag is "ckout" and a checkout is open, "ci+" causes
** RID_CKOUT to be returned, in which case g.localOpen will hold the
** RID of the checkout. Conversely, passing in the hash, or another
** symbolic name of the local checkout version, will always result in
** its RID being returned.
**
** Note that the input zTag for types "t" and "e" is the artifact hash of
** the ticket-change or technote-change artifact, not the randomly generated
** hexadecimal identifier assigned to tickets and events. Those identifiers
** live in a separate namespace.
*/
int symbolic_name_to_rid(const char *zTag, const char *zType){
int rid = 0;
int nTag;
int i;
int startOfBranch = 0;
const char *zXTag; /* zTag with optional [...] removed */
int nXTag; /* Size of zXTag */
const char *zDate; /* Expanded date-time string */
int isCheckin = 0; /* zType==ci = 1, zType==ci+ = 2 */
if( zType==0 || zType[0]==0 ){
zType = "*";
}else if( zType[0]=='b' ){
zType = "ci";
startOfBranch = 1;
}
if( zTag==0 || zTag[0]==0 ) return 0;
else if( 'c'==zType[0] ){
if( fossil_strcmp(zType,"ci")==0 ){
isCheckin = 1;
}else if( fossil_strcmp(zType,"ci+")==0 ){
isCheckin = 2;
zType = "ci";
}
}
/* special keyword: "tip" */
if( fossil_strcmp(zTag, "tip")==0 && (zType[0]=='*' || isCheckin!=0) ){
rid = db_int(0,
"SELECT objid"
" FROM event"
" WHERE type='ci'"
" ORDER BY event.mtime DESC"
);
if( rid ) return rid;
}
/* special keywords: "prev", "previous", "current", "ckout", and
** "next" */
if( g.localOpen>0 && (zType[0]=='*' || isCheckin!=0) ){
const int vid = g.localOpen;
if( fossil_strcmp(zTag, "current")==0 ){
rid = vid;
}else if( fossil_strcmp(zTag, "prev")==0
|| fossil_strcmp(zTag, "previous")==0 ){
rid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", vid);
}else if( fossil_strcmp(zTag, "next")==0 ){
rid = db_int(0, "SELECT cid FROM plink WHERE pid=%d"
" ORDER BY isprim DESC, mtime DESC", vid);
}else if( isCheckin>1 && fossil_strcmp(zTag, "ckout")==0 ){
rid = RID_CKOUT;
}
if( rid ) return rid;
}
/* Date and times */
if( memcmp(zTag, "date:", 5)==0 ){
zDate = fossil_expand_datetime(&zTag[5],0);
|
| ︙ | ︙ | |||
521 522 523 524 525 526 527 |
if( nTag>4
&& is_trailing_punct(zTag[nTag-1])
&& !is_trailing_punct(zTag[nTag-2])
){
char *zNew = fossil_strndup(zTag, nTag-1);
rid = symbolic_name_to_rid(zNew,zType);
fossil_free(zNew);
| | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
if( nTag>4
&& is_trailing_punct(zTag[nTag-1])
&& !is_trailing_punct(zTag[nTag-2])
){
char *zNew = fossil_strndup(zTag, nTag-1);
rid = symbolic_name_to_rid(zNew,zType);
fossil_free(zNew);
}else
if( nTag>5
&& is_trailing_punct(zTag[nTag-1])
&& is_trailing_punct(zTag[nTag-2])
&& !is_trailing_punct(zTag[nTag-3])
){
char *zNew = fossil_strndup(zTag, nTag-2);
rid = symbolic_name_to_rid(zNew,zType);
|
| ︙ | ︙ | |||
586 587 588 589 590 591 592 |
** negative value is returned. On success the rid is returned and
** pUuid (if it is not NULL) is set to a newly-allocated string,
** the full hash, which must eventually be free()d by the caller.
*/
int name_to_uuid2(const char *zName, const char *zType, char **pUuid){
int rid = symbolic_name_to_rid(zName, zType);
if((rid>0) && pUuid){
| > | > | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
** negative value is returned. On success the rid is returned and
** pUuid (if it is not NULL) is set to a newly-allocated string,
** the full hash, which must eventually be free()d by the caller.
*/
int name_to_uuid2(const char *zName, const char *zType, char **pUuid){
int rid = symbolic_name_to_rid(zName, zType);
if((rid>0) && pUuid){
*pUuid = (rid<RID_MAX)
? db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid)
: NULL;
}
return rid;
}
/*
** name_collisions searches through events, blobs, and tickets for
|
| ︙ | ︙ | |||
621 622 623 624 625 626 627 | } return c; } /* ** COMMAND: test-name-to-id ** | | > > > > > | | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
}
return c;
}
/*
** COMMAND: test-name-to-id
**
** Usage: %fossil test-name-to-id [--count N] [--type ARTIFACT_TYPE] NAME
**
** Convert a NAME to a full artifact ID. Repeat the conversion N
** times (for timing purposes) if the --count option is given.
*/
void test_name_to_id(void){
int i;
int n = 0;
Blob name;
const char *zType;
db_must_be_within_tree();
if( (zType = find_option("type","t",1))==0 ){
zType = "*";
}
for(i=2; i<g.argc; i++){
if( strcmp(g.argv[i],"--count")==0 && i+1<g.argc ){
i++;
n = atoi(g.argv[i]);
continue;
}
do{
blob_init(&name, g.argv[i], -1);
fossil_print("%s -> ", g.argv[i]);
if( name_to_uuid(&name, 1, zType) ){
fossil_print("ERROR: %s\n", g.zErrMsg);
fossil_error_reset();
}else{
fossil_print("%s\n", blob_buffer(&name));
}
blob_reset(&name);
}while( n-- > 0 );
|
| ︙ | ︙ |