Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merged in UUID-renaming changes from trunk. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | ui-local-diff |
| Files: | files | file ages | folders |
| SHA3-256: |
1fd9acb97c6dc73a56cda356b5bb5e5a |
| User & Date: | graham 2020-05-30 19:32:34.926 |
Context
|
2020-05-30
| ||
| 22:22 | Distinguish local-changes from changes from a merge. check-in: db758a3454 user: graham tags: ui-local-diff | |
| 19:32 | Merged in UUID-renaming changes from trunk. check-in: 1fd9acb97c user: graham tags: ui-local-diff | |
| 16:51 | Added "& server" to the "native" row in the characterization table at the top of fossil-v-git.wiki. check-in: 6c04e42f76 user: wyoung tags: trunk | |
| 16:15 | Make two passes through list of local changes so all "one-line" entries are listed first. check-in: bc56945ea4 user: graham tags: ui-local-diff | |
Changes
Changes to skins/blitz/ticket.txt.
1 2 | <h4>$<title></h4> <table class="tktDsp"> | | | 1 2 3 4 5 6 7 8 9 10 |
<h4>$<title></h4>
<table class="tktDsp">
<tr><td class="tktDspLabel">Ticket Hash</td>
<th1>
if {[info exists tkt_uuid]} {
if {[hascap s]} {
html "<td class='tktDspValue' colspan='3'>$tkt_uuid "
html "($tkt_id)</td></tr>\n"
} else {
html "<td class='tktDspValue' colspan='3'>$tkt_uuid</td></tr>\n"
|
| ︙ | ︙ |
Changes to skins/blitz_no_logo/ticket.txt.
1 2 | <h4>$<title></h4> <table class="tktDsp"> | | | 1 2 3 4 5 6 7 8 9 10 |
<h4>$<title></h4>
<table class="tktDsp">
<tr><td class="tktDspLabel">Ticket Hash</td>
<th1>
if {[info exists tkt_uuid]} {
if {[hascap s]} {
html "<td class='tktDspValue' colspan='3'>$tkt_uuid "
html "($tkt_id)</td></tr>\n"
} else {
html "<td class='tktDspValue' colspan='3'>$tkt_uuid</td></tr>\n"
|
| ︙ | ︙ |
Changes to src/attach.c.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 | #include "attach.h" #include <assert.h> /* ** WEBPAGE: attachlist ** List attachments. ** | | > | > | | > | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include "attach.h"
#include <assert.h>
/*
** WEBPAGE: attachlist
** List attachments.
**
** tkt=HASH
** page=WIKIPAGE
** technote=HASH
**
** At most one of technote=, tkt= or page= may be supplied.
**
** If none are given, all attachments are listed. If one is given, only
** attachments for the designated technote, ticket or wiki page are shown.
**
** HASH may be just a prefix of the relevant technical note or ticket
** artifact hash, in which case all attachments of all technical notes or
** tickets with the prefix will be listed.
*/
void attachlist_page(void){
const char *zPage = P("page");
const char *zTkt = P("tkt");
const char *zTechNote = P("technote");
Blob sql;
Stmt q;
|
| ︙ | ︙ | |||
150 151 152 153 154 155 156 157 158 | /* ** WEBPAGE: attachdownload ** WEBPAGE: attachimage ** WEBPAGE: attachview ** ** Download or display an attachment. ** Query parameters: ** | > | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
/*
** WEBPAGE: attachdownload
** WEBPAGE: attachimage
** WEBPAGE: attachview
**
** Download or display an attachment.
**
** Query parameters:
**
** tkt=HASH
** page=WIKIPAGE
** technote=HASH
** file=FILENAME
** attachid=ID
**
*/
void attachview_page(void){
const char *zPage = P("page");
const char *zTkt = P("tkt");
|
| ︙ | ︙ | |||
248 249 250 251 252 253 254 | /* ** Commit a new attachment into the repository */ void attach_commit( const char *zName, /* The filename of the attachment */ | | | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
/*
** Commit a new attachment into the repository
*/
void attach_commit(
const char *zName, /* The filename of the attachment */
const char *zTarget, /* The artifact hash to attach to */
const char *aContent, /* The content of the attachment */
int szContent, /* The length of the attachment */
int needModerator, /* Moderate the attachment? */
const char *zComment /* The comment for the attachment */
){
Blob content;
Blob manifest;
|
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
db_end_transaction(0);
}
/*
** WEBPAGE: attachadd
** Add a new attachment.
**
| | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
db_end_transaction(0);
}
/*
** WEBPAGE: attachadd
** Add a new attachment.
**
** tkt=HASH
** page=WIKIPAGE
** technote=HASH
** from=URL
**
*/
void attachadd_page(void){
const char *zPage = P("page");
const char *zTkt = P("tkt");
const char *zTechNote = P("technote");
|
| ︙ | ︙ | |||
418 419 420 421 422 423 424 |
**
** Show the details of an attachment artifact.
*/
void ainfo_page(void){
int rid; /* RID for the control artifact */
int ridSrc; /* RID for the attached file */
char *zDate; /* Date attached */
| | | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 |
**
** Show the details of an attachment artifact.
*/
void ainfo_page(void){
int rid; /* RID for the control artifact */
int ridSrc; /* RID for the attached file */
char *zDate; /* Date attached */
const char *zUuid; /* Hash of the control artifact */
Manifest *pAttach; /* Parse of the control artifact */
const char *zTarget; /* Wiki, ticket or tech note attached to */
const char *zSrc; /* Hash of the attached file */
const char *zName; /* Name of the attached file */
const char *zDesc; /* Description of the attached file */
const char *zWikiName = 0; /* Wiki page name when attached to Wiki */
const char *zTNUuid = 0; /* Tech Note ID when attached to tech note */
const char *zTktUuid = 0; /* Ticket ID when attached to a ticket */
int modPending; /* True if awaiting moderation */
const char *zModAction; /* Moderation action or NULL */
|
| ︙ | ︙ | |||
761 762 763 764 765 766 767 |
);
zFile = g.argv[3];
}
blob_read_from_file(&content, zFile, ExtFILE);
user_select();
attach_commit(
zFile, /* The filename of the attachment */
| | | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 |
);
zFile = g.argv[3];
}
blob_read_from_file(&content, zFile, ExtFILE);
user_select();
attach_commit(
zFile, /* The filename of the attachment */
zTarget, /* The artifact hash to attach to */
blob_buffer(&content), /* The content of the attachment */
blob_size(&content), /* The length of the attachment */
0, /* No need to moderate the attachment */
"" /* Empty attachment comment */
);
if( !zETime ){
fossil_print("Attached %s to wiki page %s.\n", zFile, zPageName);
|
| ︙ | ︙ |
Changes to src/blob.c.
| ︙ | ︙ | |||
480 481 482 483 484 485 486 487 488 |
pBlob->aData[newSize] = 0;
}
/*
** Ensures that the given blob has at least the given amount of memory
** allocated to it. Does not modify pBlob->nUsed nor will it reduce
** the currently-allocated amount of memory.
*/
void blob_reserve(Blob *pBlob, unsigned int newSize){
| > > > > > > > | | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
pBlob->aData[newSize] = 0;
}
/*
** Ensures that the given blob has at least the given amount of memory
** allocated to it. Does not modify pBlob->nUsed nor will it reduce
** the currently-allocated amount of memory.
**
** For semantic compatibility with blob_append_full(), if newSize is
** >=0x7fff000 (~2GB) then this function will trigger blob_panic(). If
** it didn't, it would be possible to bypass that hard-coded limit via
** this function.
*/
void blob_reserve(Blob *pBlob, unsigned int newSize){
if(newSize>=0x7fff0000 ){
blob_panic();
}else if(newSize>pBlob->nUsed){
pBlob->xRealloc(pBlob, newSize);
pBlob->aData[newSize] = 0;
}
}
/*
** Make sure a blob is nul-terminated and is not a pointer to unmanaged
|
| ︙ | ︙ |
Changes to src/bundle.c.
| ︙ | ︙ | |||
528 529 530 531 532 533 534 |
fossil_fatal("incorrect hash for artifact %b", &h1);
}
blob_reset(&h1);
bag_remove(&busy, blobid);
db_finalize(&q);
}
| | | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
fossil_fatal("incorrect hash for artifact %b", &h1);
}
blob_reset(&h1);
bag_remove(&busy, blobid);
db_finalize(&q);
}
/* fossil bundle cat BUNDLE HASH...
**
** Write elements of a bundle on standard output
*/
static void bundle_cat_cmd(void){
int i;
Blob x;
verify_all_options();
if( g.argc<5 ) usage("cat BUNDLE HASH...");
bundle_attach_file(g.argv[3], "b1", 1);
blob_zero(&x);
for(i=4; i<g.argc; i++){
int blobid = db_int(0,"SELECT blobid FROM bblob WHERE uuid LIKE '%q%%'",
g.argv[i]);
if( blobid==0 ){
fossil_fatal("no such artifact in bundle: %s", g.argv[i]);
|
| ︙ | ︙ | |||
723 724 725 726 727 728 729 | ** Usage: %fossil bundle SUBCOMMAND ARGS... ** ** fossil bundle append BUNDLE FILE... ** ** Add files named on the command line to BUNDLE. This subcommand has ** little practical use and is mostly intended for testing. ** | | | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | ** Usage: %fossil bundle SUBCOMMAND ARGS... ** ** fossil bundle append BUNDLE FILE... ** ** Add files named on the command line to BUNDLE. This subcommand has ** little practical use and is mostly intended for testing. ** ** fossil bundle cat BUNDLE HASH... ** ** Extract one or more artifacts from the bundle and write them ** consecutively on standard output. This subcommand was designed ** for testing and introspection of bundles and is not something ** commonly used. ** ** fossil bundle export BUNDLE ?OPTIONS? |
| ︙ | ︙ | |||
768 769 770 771 772 773 774 | ** ** Remove from the repository all files that are used exclusively ** by check-ins in BUNDLE. This has the effect of undoing a ** "fossil bundle import". ** ** SUMMARY: ** fossil bundle append BUNDLE FILE... Add files to BUNDLE | | | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | ** ** Remove from the repository all files that are used exclusively ** by check-ins in BUNDLE. This has the effect of undoing a ** "fossil bundle import". ** ** SUMMARY: ** fossil bundle append BUNDLE FILE... Add files to BUNDLE ** fossil bundle cat BUNDLE HASH... Extract file from BUNDLE ** fossil bundle export BUNDLE ?OPTIONS? Create a new BUNDLE ** --branch BRANCH --from TAG1 --to TAG2 Check-ins to include ** --checkin TAG Use only check-in TAG ** --standalone Omit dependencies ** fossil bundle extend BUNDLE Update with newer content ** fossil bundle import BUNDLE ?OPTIONS? Import a bundle ** --publish Publish the import |
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | /* ** Make sure the current check-in with timestamp zDate is younger than its ** ancestor identified rid and zUuid. Throw a fatal error if not. */ static void checkin_verify_younger( int rid, /* The record ID of the ancestor */ | | | 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 |
/*
** Make sure the current check-in with timestamp zDate is younger than its
** ancestor identified rid and zUuid. Throw a fatal error if not.
*/
static void checkin_verify_younger(
int rid, /* The record ID of the ancestor */
const char *zUuid, /* The artifact hash of the ancestor */
const char *zDate /* Date & time of the current check-in */
){
#ifndef FOSSIL_ALLOW_OUT_OF_ORDER_DATES
if(checkin_is_younger(rid,zDate)==0){
fossil_fatal("ancestor check-in [%S] (%s) is not older (clock skew?)"
" Use --allow-older to override.", zUuid, zDate);
}
|
| ︙ | ︙ | |||
1498 1499 1500 1501 1502 1503 1504 | #endif /* INTERFACE */ /* ** Create a manifest. */ static void create_manifest( Blob *pOut, /* Write the manifest here */ | | | | 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 |
#endif /* INTERFACE */
/*
** Create a manifest.
*/
static void create_manifest(
Blob *pOut, /* Write the manifest here */
const char *zBaselineUuid, /* Hash of baseline, or zero */
Manifest *pBaseline, /* Make it a delta manifest if not zero */
int vid, /* BLOB.id for the parent check-in */
CheckinInfo *p, /* Information about the check-in */
int *pnFBcard /* OUT: Number of generated B- and F-cards */
){
char *zDate; /* Date of the check-in */
char *zParentUuid = 0; /* Hash of parent check-in */
Blob filename; /* A single filename */
int nBasename; /* Size of base filename */
Stmt q; /* Various queries */
Blob mcksum; /* Manifest checksum */
ManifestFile *pFile; /* File from the baseline */
int nFBcard = 0; /* Number of B-cards and F-cards */
int i; /* Loop counter */
|
| ︙ | ︙ | |||
2056 2057 2058 2059 2060 2061 2062 | int hasChanges; /* True if unsaved changes exist */ int vid; /* blob-id of parent version */ int nrid; /* blob-id of a modified file */ int nvid; /* Blob-id of the new check-in */ Blob comment; /* Check-in comment */ const char *zComment; /* Check-in comment */ Stmt q; /* Various queries */ | | | 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 | int hasChanges; /* True if unsaved changes exist */ int vid; /* blob-id of parent version */ int nrid; /* blob-id of a modified file */ int nvid; /* Blob-id of the new check-in */ Blob comment; /* Check-in comment */ const char *zComment; /* Check-in comment */ Stmt q; /* Various queries */ char *zUuid; /* Hash of the new check-in */ int useHash = 0; /* True to verify file status using hashing */ int noSign = 0; /* True to omit signing the manifest using GPG */ int privateFlag = 0; /* True if the --private option is present */ int privateParent = 0; /* True if the parent check-in is private */ int isAMerge = 0; /* True if checking in a merge */ int noWarningFlag = 0; /* True if skipping all warnings */ int noPrompt = 0; /* True if skipping all prompts */ |
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
85 86 87 88 89 90 91 |
);
fossil_free(zPwd);
db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);
}
/*
| | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
);
fossil_free(zPwd);
db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);
}
/*
** Given the abbreviated hash of a version, load the content of that
** version in the VFILE table. Return the VID for the version.
**
** If anything goes wrong, panic.
*/
int load_vfile(const char *zName, int forceMissingFlag){
Blob uuid;
int vid;
|
| ︙ | ︙ |
Changes to src/codecheck1.c.
| ︙ | ︙ | |||
341 342 343 344 345 346 347 | if( strncmp(z,"cgi_param",9)==0 ) return 1; return 0; } /* ** Processing flags */ | | | | | | | > > | > > | | | | > > | | | | > > > | | > > > > > > > > > | 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 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
if( strncmp(z,"cgi_param",9)==0 ) return 1;
return 0;
}
/*
** Processing flags
*/
#define FMT_SQL 0x00001 /* Generator for SQL text */
#define FMT_HTML 0x00002 /* Generator for HTML text */
#define FMT_URL 0x00004 /* Generator for URLs */
#define FMT_SAFE 0x00008 /* Generator for human-readable text */
/*
** A list of internal Fossil interfaces that take a printf-style format
** string.
*/
struct FmtFunc {
const char *zFName; /* Name of the function */
int iFmtArg; /* Index of format argument. Leftmost is 1. */
unsigned fmtFlags; /* Processing flags */
} aFmtFunc[] = {
{ "admin_log", 1, FMT_SAFE },
{ "audit_append", 3, FMT_SAFE },
{ "backofficeTrace", 1, FMT_SAFE },
{ "blob_append_sql", 2, FMT_SQL },
{ "blob_appendf", 2, FMT_SAFE },
{ "cgi_debug", 1, FMT_SAFE },
{ "cgi_panic", 1, FMT_SAFE },
{ "cgi_printf", 1, FMT_HTML },
{ "cgi_printf_header", 1, FMT_HTML },
{ "cgi_redirectf", 1, FMT_URL },
{ "chref", 2, FMT_URL },
{ "CX", 1, FMT_HTML },
{ "db_blob", 2, FMT_SQL },
{ "db_debug", 1, FMT_SQL },
{ "db_double", 2, FMT_SQL },
{ "db_err", 1, FMT_SAFE },
{ "db_exists", 1, FMT_SQL },
{ "db_get_mprintf", 2, FMT_SAFE },
{ "db_int", 2, FMT_SQL },
{ "db_int64", 2, FMT_SQL },
{ "db_multi_exec", 1, FMT_SQL },
{ "db_optional_sql", 2, FMT_SQL },
{ "db_prepare", 2, FMT_SQL },
{ "db_prepare_ignore_error", 2, FMT_SQL },
{ "db_set_mprintf", 3, FMT_SAFE },
{ "db_static_prepare", 2, FMT_SQL },
{ "db_text", 2, FMT_SQL },
{ "db_unset_mprintf", 2, FMT_SAFE },
{ "emailerError", 2, FMT_SAFE },
{ "fileedit_ajax_error", 2, FMT_SAFE },
{ "form_begin", 2, FMT_URL },
{ "fossil_error", 2, FMT_SAFE },
{ "fossil_errorlog", 1, FMT_SAFE },
{ "fossil_fatal", 1, FMT_SAFE },
{ "fossil_fatal_recursive", 1, FMT_SAFE },
{ "fossil_panic", 1, FMT_SAFE },
{ "fossil_print", 1, FMT_SAFE },
{ "fossil_trace", 1, FMT_SAFE },
{ "fossil_warning", 1, FMT_SAFE },
{ "href", 1, FMT_URL },
{ "json_new_string_f", 1, FMT_SAFE },
{ "json_set_err", 2, FMT_SAFE },
{ "json_warn", 2, FMT_SAFE },
{ "mprintf", 1, FMT_SAFE },
{ "pop3_print", 2, FMT_SAFE },
{ "smtp_send_line", 2, FMT_SAFE },
{ "smtp_server_send", 2, FMT_SAFE },
{ "socket_set_errmsg", 1, FMT_SAFE },
{ "ssl_set_errmsg", 1, FMT_SAFE },
{ "style_header", 1, FMT_HTML },
{ "style_js_onload", 1, FMT_HTML },
{ "style_set_current_page", 1, FMT_URL },
{ "style_submenu_element", 2, FMT_URL },
{ "style_submenu_sql", 3, FMT_SQL },
{ "webpage_error", 1, FMT_SAFE },
{ "xhref", 2, FMT_URL },
};
/*
** Comparison function for two FmtFunc entries
*/
static int fmtfunc_cmp(const void *pAA, const void *pBB){
const struct FmtFunc *pA = (const struct FmtFunc*)pAA;
const struct FmtFunc *pB = (const struct FmtFunc*)pBB;
return strcmp(pA->zFName, pB->zFName);
}
/*
** Determine if the indentifier zIdent of length nIndent is a Fossil
** internal interface that uses a printf-style argument. Return zero if not.
** Return the index of the format string if true with the left-most
** argument having an index of 1.
*/
|
| ︙ | ︙ | |||
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 |
** on the command-line.
**
** The eVerbose global variable is incremented with each "-v" argument.
*/
int main(int argc, char **argv){
int i;
int nErr = 0;
for(i=1; i<argc; i++){
char *zFile;
if( strcmp(argv[i],"-v")==0 ){
eVerbose++;
continue;
}
if( eVerbose>0 ) printf("Processing %s...\n", argv[i]);
zFile = read_file(argv[i]);
nErr += scan_file(argv[i], zFile);
free(zFile);
}
return nErr;
}
| > > | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
** on the command-line.
**
** The eVerbose global variable is incremented with each "-v" argument.
*/
int main(int argc, char **argv){
int i;
int nErr = 0;
qsort(aFmtFunc, sizeof(aFmtFunc)/sizeof(aFmtFunc[0]),
sizeof(aFmtFunc[0]), fmtfunc_cmp);
for(i=1; i<argc; i++){
char *zFile;
if( strcmp(argv[i],"-v")==0 ){
eVerbose++;
continue;
}
if( eVerbose>0 ) printf("Processing %s...\n", argv[i]);
zFile = read_file(argv[i]);
nErr += scan_file(argv[i], zFile);
free(zFile);
}
return nErr;
}
|
Changes to src/configure.c.
| ︙ | ︙ | |||
146 147 148 149 150 151 152 |
{ "dotfiles", CONFIGSET_PROJ },
{ "parent-project-code", CONFIGSET_PROJ },
{ "parent-project-name", CONFIGSET_PROJ },
{ "hash-policy", CONFIGSET_PROJ },
{ "comment-format", CONFIGSET_PROJ },
{ "mimetypes", CONFIGSET_PROJ },
{ "forbid-delta-manifests", CONFIGSET_PROJ },
| < | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
{ "dotfiles", CONFIGSET_PROJ },
{ "parent-project-code", CONFIGSET_PROJ },
{ "parent-project-name", CONFIGSET_PROJ },
{ "hash-policy", CONFIGSET_PROJ },
{ "comment-format", CONFIGSET_PROJ },
{ "mimetypes", CONFIGSET_PROJ },
{ "forbid-delta-manifests", CONFIGSET_PROJ },
#ifdef FOSSIL_ENABLE_LEGACY_MV_RM
{ "mv-rm-files", CONFIGSET_PROJ },
#endif
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
|
| ︙ | ︙ |
Changes to src/content.c.
| ︙ | ︙ | |||
562 563 564 565 566 567 568 |
** have no data with which to dephantomize it. In either case,
** there is nothing for us to do other than return the RID. */
db_finalize(&s1);
db_end_transaction(0);
return rid;
}
}else{
| | | 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
** have no data with which to dephantomize it. In either case,
** there is nothing for us to do other than return the RID. */
db_finalize(&s1);
db_end_transaction(0);
return rid;
}
}else{
rid = 0; /* No entry with the same hash currently exists */
markAsUnclustered = 1;
}
db_finalize(&s1);
/* Construct a received-from ID if we do not already have one */
content_rcvid_init(0);
|
| ︙ | ︙ | |||
657 658 659 660 661 662 663 |
*/
int content_put(Blob *pBlob){
return content_put_ex(pBlob, 0, 0, 0, 0);
}
/*
| | | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
*/
int content_put(Blob *pBlob){
return content_put_ex(pBlob, 0, 0, 0, 0);
}
/*
** Create a new phantom with the given hash and return its artifact ID.
*/
int content_new(const char *zUuid, int isPrivate){
int rid;
static Stmt s1, s2, s3;
assert( g.repositoryOpen );
db_begin_transaction();
|
| ︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 | } /* Allowed flags for check_exists */ #define MISSING_SHUNNED 0x0001 /* Do not report shunned artifacts */ /* This is a helper routine for test-artifacts. ** | | | > | | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 |
}
/* Allowed flags for check_exists */
#define MISSING_SHUNNED 0x0001 /* Do not report shunned artifacts */
/* This is a helper routine for test-artifacts.
**
** Check to see that the artifact hash referenced by zUuid exists in the
** repository. If it does, return 0. If it does not, generate an error
** message and return 1.
*/
static int check_exists(
const char *zUuid, /* Hash of the artifact we are checking for */
unsigned flags, /* Flags */
Manifest *p, /* The control artifact that references zUuid */
const char *zRole, /* Role of zUuid in p */
const char *zDetail /* Additional information, such as a filename */
){
static Stmt q;
int rc = 0;
|
| ︙ | ︙ |
Changes to src/event.c.
| ︙ | ︙ | |||
61 62 63 64 65 66 67 |
** v=BOOLEAN Show details if TRUE. Default is FALSE. Optional.
**
** Display an existing tech-note identified by its ID, optionally at a
** specific version, and optionally with additional details.
*/
void event_page(void){
int rid = 0; /* rid of the event artifact */
| | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
** v=BOOLEAN Show details if TRUE. Default is FALSE. Optional.
**
** Display an existing tech-note identified by its ID, optionally at a
** specific version, and optionally with additional details.
*/
void event_page(void){
int rid = 0; /* rid of the event artifact */
char *zUuid; /* artifact hash corresponding to rid */
const char *zId; /* Event identifier */
const char *zVerbose; /* Value of verbose option */
char *zETime; /* Time of the tech-note */
char *zATime; /* Time the artifact was created */
int specRid; /* rid specified by aid= parameter */
int prevRid, nextRid; /* Previous or next edits of this tech-note */
Manifest *pTNote; /* Parsed technote artifact */
|
| ︙ | ︙ |
Changes to src/fileedit.c.
| ︙ | ︙ | |||
886 887 888 889 890 891 892 | CheckinMiniInfo_cleanup(&cimi); } /* ** If the fileedit-glob setting has a value, this returns its Glob ** object (in memory owned by this function), else it returns NULL. */ | | | 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 |
CheckinMiniInfo_cleanup(&cimi);
}
/*
** If the fileedit-glob setting has a value, this returns its Glob
** object (in memory owned by this function), else it returns NULL.
*/
Glob *fileedit_glob(void){
static Glob * pGlobs = 0;
static int once = 0;
if(0==pGlobs && once==0){
char * zGlobs = db_get("fileedit-glob",0);
once = 1;
if(0!=zGlobs && 0!=*zGlobs){
pGlobs = glob_create(zGlobs);
|
| ︙ | ︙ | |||
985 986 987 988 989 990 991 |
const char *zContent = blob_str(pContent);
if(FE_PREVIEW_LINE_NUMBERS & flags){
output_text_with_line_numbers(zContent, "on");
}else if(zExt && zExt[1]){
CX("<pre><code class='language-%s'>%h</code></pre>",
zExt+1, zContent);
}else{
| | | 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 |
const char *zContent = blob_str(pContent);
if(FE_PREVIEW_LINE_NUMBERS & flags){
output_text_with_line_numbers(zContent, "on");
}else if(zExt && zExt[1]){
CX("<pre><code class='language-%s'>%h</code></pre>",
zExt+1, zContent);
}else{
CX("<pre>%h</pre>", zContent);
}
break;
}
}
}
/*
|
| ︙ | ︙ | |||
1711 1712 1713 1714 1715 1716 1717 1718 1719 |
}
CX("\"dryRun\": %s",
(CIMINI_DRY_RUN & cimi.flags) ? "true" : "false");
if(blob_size(&manifest)>0){
CX(",\"manifest\": %!j", blob_str(&manifest));
}
CX("}");
db_end_transaction(0/*noting that dry-run mode will have already
** set this to rollback mode. */);
| > < | 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 |
}
CX("\"dryRun\": %s",
(CIMINI_DRY_RUN & cimi.flags) ? "true" : "false");
if(blob_size(&manifest)>0){
CX(",\"manifest\": %!j", blob_str(&manifest));
}
CX("}");
end_cleanup:
db_end_transaction(0/*noting that dry-run mode will have already
** set this to rollback mode. */);
fossil_free(zNewUuid);
blob_reset(&err);
blob_reset(&manifest);
CheckinMiniInfo_cleanup(&cimi);
}
/*
|
| ︙ | ︙ | |||
1763 1764 1765 1766 1767 1768 1769 |
Blob err = empty_blob; /* Error report */
Blob endScript = empty_blob; /* Script code to run at the
end. This content will be
combined into a single JS
function call, thus each
entry must end with a
semicolon. */
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < | > | | | 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 |
Blob err = empty_blob; /* Error report */
Blob endScript = empty_blob; /* Script code to run at the
end. This content will be
combined into a single JS
function call, thus each
entry must end with a
semicolon. */
const char *zAjax = P("name"); /* Name of AJAX route for
sub-dispatching. */
/* Allow no access to this page without check-in privilege */
login_check_credentials();
if( !g.perm.Write ){
if(zAjax!=0){
fileedit_ajax_error(403, "Write permissions required.");
}else{
login_needed(g.anon.Write);
}
return;
}
/* No access to anything on this page if the fileedit-glob is empty */
if( fileedit_glob()==0 ){
if(zAjax!=0){
fileedit_ajax_error(403, "Online editing is disabled for this "
"repository.");
return;
}
style_header("File Editor (disabled)");
CX("<h1>Online File Editing Is Disabled</h1>\n");
if( g.perm.Admin ){
CX("<p>To enable online editing, the "
"<a href='%R/setup_settings'>"
"<code>fileedit-glob</code> repository setting</a>\n"
"must be set to a comma- and/or newine-delimited list of glob\n"
"values matching files which may be edited online."
"</p>\n");
}else{
CX("<p>Online editing is disabled for this repository.</p>\n");
}
style_footer();
return;
}
/* Dispatch AJAX methods based tail of the request URI.
** The AJAX parts do their own permissions/CSRF check and
** fail with a JSON-format response if needed.
*/
if( 0!=zAjax ){
if(0==strcmp("content",zAjax)){
fileedit_ajax_content();
}else if(0==strcmp("preview",zAjax)){
fileedit_ajax_preview();
}else if(0==strcmp("filelist",zAjax)){
fileedit_ajax_filelist();
}else if(0==strcmp("diff",zAjax)){
fileedit_ajax_diff();
}else if(0==strcmp("commit",zAjax)){
fileedit_ajax_commit();
}else{
fileedit_ajax_error(500, "Unhandled ajax route name.");
}
return;
}
db_begin_transaction();
CheckinMiniInfo_init(&cimi);
style_header("File Editor");
/* As of this point, don't use return or fossil_fatal(). Write any
** error in (&err) and goto end_footer instead so that we can be
** sure to emit the error message, do any cleanup, and end the
** transaction cleanly.
*/
{
int isMissingArg = 0;
if(fileedit_setup_cimi_from_p(&cimi, &err, &isMissingArg)==0){
zFilename = cimi.zFilename;
zRev = cimi.zParentUuid;
assert(zRev);
assert(zFilename);
zFileMime = mimetype_from_name(cimi.zFilename);
}else if(isMissingArg!=0){
/* Squelch these startup warnings - they're non-fatal now but
** used to be fatal. */
blob_reset(&err);
}
}
/********************************************************************
** All errors which "could" have happened up to this point are of a
** degree which keep us from rendering the rest of the page, and
|
| ︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 |
** selectors, but we do have the BODY, which we can decorate with
** whatever CSS we wish...
*/
style_emit_script_tag(0,0);
CX("document.body.classList.add('fileedit');\n");
style_emit_script_tag(1,0);
}
| < < < < < < < < | 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 |
** selectors, but we do have the BODY, which we can decorate with
** whatever CSS we wish...
*/
style_emit_script_tag(0,0);
CX("document.body.classList.add('fileedit');\n");
style_emit_script_tag(1,0);
}
/* Status bar */
CX("<div id='fossil-status-bar' "
"title='Status message area. Double-click to clear them.'>"
"Status messages will go here.</div>\n"
/* will be moved into the tab container via JS */);
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
282 283 284 285 286 287 288 | ** ** a=DATETIME Only show changes after DATETIME ** b=DATETIME Only show changes before DATETIME ** m=HASH Mark this particular file version ** n=NUM Show the first NUM changes only ** brbg Background color by branch name ** ubg Background color by user name | | | | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | ** ** a=DATETIME Only show changes after DATETIME ** b=DATETIME Only show changes before DATETIME ** m=HASH Mark this particular file version ** n=NUM Show the first NUM changes only ** brbg Background color by branch name ** ubg Background color by user name ** ci=HASH Ancestors of a particular check-in ** orig=HASH If both ci and orig are supplied, only show those ** changes on a direct path from orig to ci. ** showid Show RID values for debugging ** ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in ** year-month-day form, it may be truncated, and it may also name a ** timezone offset from UTC as "-HH:MM" (westward) or "+HH:MM" ** (eastward). Either no timezone suffix or "Z" means UTC. |
| ︙ | ︙ | |||
369 370 371 372 373 374 375 |
blob_append_sql(&sql,
"SELECT"
" datetime(min(event.mtime),toLocal())," /* Date of change */
" coalesce(event.ecomment, event.comment)," /* Check-in comment */
" coalesce(event.euser, event.user)," /* User who made chng */
" mlink.pid," /* Parent file rid */
" mlink.fid," /* File rid */
| | | | | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
blob_append_sql(&sql,
"SELECT"
" datetime(min(event.mtime),toLocal())," /* Date of change */
" coalesce(event.ecomment, event.comment)," /* Check-in comment */
" coalesce(event.euser, event.user)," /* User who made chng */
" mlink.pid," /* Parent file rid */
" mlink.fid," /* File rid */
" (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file hash */
" blob.uuid," /* Current file hash */
" (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in hash */
" event.bgcolor," /* Background color */
" (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
" AND tagxref.rid=mlink.mid)," /* Branchname */
" mlink.mid," /* check-in ID */
" mlink.pfnid," /* Previous filename */
" blob.size" /* File size */
" FROM mlink, event, blob"
|
| ︙ | ︙ | |||
539 540 541 542 543 544 545 |
@ <td class="timeline%s(zStyle)Cell">
}
if( tmFlags & TIMELINE_COMPACT ){
@ <span class='timelineCompactComment' data-id='%d(frid)'>
}else{
@ <span class='timeline%s(zStyle)Comment'>
if( (tmFlags & TIMELINE_VERBOSE)!=0 && zUuid ){
| | | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
@ <td class="timeline%s(zStyle)Cell">
}
if( tmFlags & TIMELINE_COMPACT ){
@ <span class='timelineCompactComment' data-id='%d(frid)'>
}else{
@ <span class='timeline%s(zStyle)Comment'>
if( (tmFlags & TIMELINE_VERBOSE)!=0 && zUuid ){
hyperlink_to_version(zUuid);
@ part of check-in \
hyperlink_to_version(zCkin);
}
}
@ %W(zCom)</span>
if( (tmFlags & TIMELINE_COMPACT)!=0 ){
@ <span class='timelineEllipsis' data-id='%d(frid)' \
@ id='ellipsis-%d(frid)'>...</span>
@ <span class='clutter timelineCompactDetail'
|
| ︙ | ︙ | |||
574 575 576 577 578 579 580 |
@ id: %d(frid)←%d(srcId)
}else{
@ id: %d(frid)
}
}
}
@ check-in: \
| | | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
@ id: %d(frid)←%d(srcId)
}else{
@ id: %d(frid)
}
}
}
@ check-in: \
hyperlink_to_version(zCkin);
if( fShowId ){
@ (%d(fmid))
}
@ user: \
hyperlink_to_user(zUser, zDate, ",");
@ branch: %z(href("%R/timeline?t=%T",zBr))%h(zBr)</a>,
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ){
|
| ︙ | ︙ |
Changes to src/fossil.fetch.js.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 | of these properties: - onload: callback(responseData) (default = output response to the console). In the context of the callback, the options object is "this", noting that this call may have amended the options object with state other than what the caller provided. | | | | > | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | of these properties: - onload: callback(responseData) (default = output response to the console). In the context of the callback, the options object is "this", noting that this call may have amended the options object with state other than what the caller provided. - onerror: callback(Error object) (default = output error message to console.error() and fossil.error()). Triggered if the request generates any response other than HTTP 200 or suffers a connection error or timeout while awaiting a response. In the context of the callback, the options object is "this". - method: 'POST' | 'GET' (default = 'GET'). CASE SENSITIVE! - payload: anything acceptable by XHR2.send(ARG) (DOMString, Document, FormData, Blob, File, ArrayBuffer), or a plain object or array, either of which gets JSON.stringify()'d. If payload is set then the method is automatically set to 'POST'. By default XHR2 |
| ︙ | ︙ | |||
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
immediately after it is received, regardless of success or
error. In the context of the callback, the options object is the
"this". These can be used to, e.g., keep track of in-flight
requests and update the UI accordingly, e.g. disabling/enabling DOM
elements. Any exceptions triggered by beforesend/aftersend are
caught and silently ignored.
When an options object does not provide
onload/onerror/beforesend/aftersend handlers of its own, this
function falls to defaults which are member properties of this
function with the same name, e.g. fossil.fetch.onload(). The
default onload/onerror implementations route the data through the
dev console and (for onerror()) through fossil.error(). The default
beforesend/aftersend are no-ops. Individual pages may overwrite
those members to provide default implementations suitable for the
page's use, e.g. keeping track of how many in-flight
Returns this object, noting that the XHR request is asynchronous,
and still in transit (or has yet to be sent) when that happens.
*/
window.fossil.fetch = function f(uri,opt){
const F = fossil;
if(!f.onload){
| > > > > > > | | | | < < < < < < < < < < < < < | < < | 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 |
immediately after it is received, regardless of success or
error. In the context of the callback, the options object is the
"this". These can be used to, e.g., keep track of in-flight
requests and update the UI accordingly, e.g. disabling/enabling DOM
elements. Any exceptions triggered by beforesend/aftersend are
caught and silently ignored.
- timeout: integer in milliseconds specifying the XHR timeout
duration. Default = fossil.fetch.timeout.
When an options object does not provide
onload/onerror/beforesend/aftersend handlers of its own, this
function falls to defaults which are member properties of this
function with the same name, e.g. fossil.fetch.onload(). The
default onload/onerror implementations route the data through the
dev console and (for onerror()) through fossil.error(). The default
beforesend/aftersend are no-ops. Individual pages may overwrite
those members to provide default implementations suitable for the
page's use, e.g. keeping track of how many in-flight
Note that this routine may add properties to the 2nd argument, so
that instance should not be kept around for later use.
Returns this object, noting that the XHR request is asynchronous,
and still in transit (or has yet to be sent) when that happens.
*/
window.fossil.fetch = function f(uri,opt){
const F = fossil;
if(!f.onload){
f.onload = (r)=>console.debug('fossil.fetch() XHR response:',r);
}
if(!f.onerror){
f.onerror = function(e/*exception*/){
console.error("fossil.fetch() XHR error:",e);
if(e instanceof Error) F.error('Exception:',e);
else F.error("Unknown error in handling of XHR request.");
};
}/*f.onerror()*/
if(!f.parseResponseHeaders){
f.parseResponseHeaders = function(h){
const rc = {};
if(!h) return rc;
const ar = h.trim().split(/[\r\n]+/);
|
| ︙ | ︙ | |||
153 154 155 156 157 158 159 |
}
}
const url=[F.repoUrl(uri,opt.urlParams)],
x=new XMLHttpRequest();
if('POST'===opt.method && 'string'===typeof opt.contentType){
x.setRequestHeader('Content-Type',opt.contentType);
}
| < | > > > > > | > > > > > | | | | | > > > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 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 |
}
}
const url=[F.repoUrl(uri,opt.urlParams)],
x=new XMLHttpRequest();
if('POST'===opt.method && 'string'===typeof opt.contentType){
x.setRequestHeader('Content-Type',opt.contentType);
}
if('json'===opt.responseType){
/* 'json' is an extension to the supported XHR.responseType
list. We use it as a flag to tell us to JSON.parse()
the response. */
jsonResponse = true;
x.responseType = 'text';
}else{
x.responseType = opt.responseType||'text';
}
x.ontimeout = function(){
try{opt.aftersend()}catch(e){/*ignore*/}
opt.onerror(new Error("XHR timeout of "+x.timeout+"ms expired."));
};
x.onreadystatechange = function(){
if(XMLHttpRequest.DONE !== x.readyState) return;
try{opt.aftersend()}catch(e){/*ignore*/}
if(200!==x.status){
let err;
try{
const j = JSON.parse(x.response);
if(j.error) err = new Error(j.error);
}catch(ex){/*ignore*/}
opt.onerror(err || new Error("HTTP response status "+x.status+"."));
return;
}
const orh = opt.responseHeaders;
let head;
if(true===orh){
head = f.parseResponseHeaders(x.getAllResponseHeaders());
}else if('string'===typeof orh){
head = x.getResponseHeader(orh);
}else if(orh instanceof Array){
head = {};
orh.forEach((s)=>{
if('string' === typeof s) head[s.toLowerCase()] = x.getResponseHeader(s);
});
}
try{
const args = [(jsonResponse && x.response)
? JSON.parse(x.response) : x.response];
if(head) args.push(head);
opt.onload.apply(opt, args);
}catch(e){
opt.onerror(e);
}
};
try{opt.beforesend()}catch(e){/*ignore*/}
x.open(opt.method||'GET', url.join(''), true);
x.timeout = +opt.timeout || f.timeout;
if(undefined!==payload) x.send(payload);
else x.send();
return this;
};
window.fossil.fetch.beforesend = function(){};
window.fossil.fetch.aftersend = function(){};
window.fossil.fetch.timeout = 15000/* Default timeout, in ms. */;
|
Changes to src/import.c.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 |
#if INTERFACE
/*
** A single file change record.
*/
struct ImportFile {
char *zName; /* Name of a file */
| | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#if INTERFACE
/*
** A single file change record.
*/
struct ImportFile {
char *zName; /* Name of a file */
char *zUuid; /* Hash of the file */
char *zPrior; /* Prior name if the name was changed */
char isFrom; /* True if obtained from the parent */
char isExe; /* True if executable */
char isLink; /* True if symlink */
};
#endif
|
| ︙ | ︙ | |||
57 58 59 60 61 62 63 | char *zBranch; /* Name of a branch for a commit */ char *zPrevBranch; /* The branch of the previous check-in */ char *aData; /* Data content */ char *zMark; /* The current mark */ char *zDate; /* Date/time stamp */ char *zUser; /* User name */ char *zComment; /* Comment of a commit */ | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | char *zBranch; /* Name of a branch for a commit */ char *zPrevBranch; /* The branch of the previous check-in */ char *aData; /* Data content */ char *zMark; /* The current mark */ char *zDate; /* Date/time stamp */ char *zUser; /* User name */ char *zComment; /* Comment of a commit */ char *zFrom; /* from value as a hash */ char *zPrevCheckin; /* Name of the previous check-in */ char *zFromMark; /* The mark of the "from" field */ int nMerge; /* Number of merge values */ int nMergeAlloc; /* Number of slots in azMerge[] */ char **azMerge; /* Merge values */ int nFile; /* Number of aFile values */ int nFileAlloc; /* Number of slots in aFile[] */ |
| ︙ | ︙ | |||
141 142 143 144 145 146 147 | } /* ** Insert an artifact into the BLOB table if it isn't there already. ** If zMark is not zero, create a cross-reference from that mark back ** to the newly inserted artifact. ** | | | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
}
/*
** Insert an artifact into the BLOB table if it isn't there already.
** If zMark is not zero, create a cross-reference from that mark back
** to the newly inserted artifact.
**
** If saveHash is true, then pContent is a commit record. Record its
** artifact hash in gg.zPrevCheckin.
*/
static int fast_insert_content(
Blob *pContent, /* Content to insert */
const char *zMark, /* Label using this mark, if not NULL */
int saveHash, /* Save artifact hash in gg.zPrevCheckin */
int doParse /* Invoke manifest_crosslink() */
){
Blob hash;
Blob cmpr;
int rid;
hname_hash(pContent, 0, &hash);
|
| ︙ | ︙ | |||
185 186 187 188 189 190 191 |
);
db_multi_exec(
"INSERT OR IGNORE INTO xmark(tname, trid, tuuid)"
"VALUES(%B,%d,%B)",
&hash, rid, &hash
);
}
| | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
);
db_multi_exec(
"INSERT OR IGNORE INTO xmark(tname, trid, tuuid)"
"VALUES(%B,%d,%B)",
&hash, rid, &hash
);
}
if( saveHash ){
fossil_free(gg.zPrevCheckin);
gg.zPrevCheckin = fossil_strdup(blob_str(&hash));
}
blob_reset(&hash);
return rid;
}
|
| ︙ | ︙ | |||
409 410 411 412 413 414 415 |
}else{
*pzIn = &z[i];
}
return z;
}
/*
| | | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
}else{
*pzIn = &z[i];
}
return z;
}
/*
** Convert a "mark" or "committish" into the artifact hash.
*/
static char *resolve_committish(const char *zCommittish){
char *zRes;
zRes = db_text(0, "SELECT tuuid FROM xmark WHERE tname=%Q", zCommittish);
return zRes;
}
|
| ︙ | ︙ | |||
1826 1827 1828 1829 1830 1831 1832 |
Bag blobs, vers;
bag_init(&blobs);
bag_init(&vers);
/* The following temp-tables are used to hold information needed for
** the import.
**
** The XMARK table provides a mapping from fast-import "marks" and symbols
| | > | | 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 |
Bag blobs, vers;
bag_init(&blobs);
bag_init(&vers);
/* The following temp-tables are used to hold information needed for
** the import.
**
** The XMARK table provides a mapping from fast-import "marks" and symbols
** into artifact hashes.
**
** Given any valid fast-import symbol, the corresponding fossil rid and
** hash can found by searching against the xmark.tname field.
**
** The XBRANCH table maps commit marks and symbols into the branch those
** commits belong to. If xbranch.tname is a fast-import symbol for a
** check-in then xbranch.brnm is the branch that check-in is part of.
**
** The XTAG table records information about tags that need to be applied
** to various branches after the import finishes. The xtag.tcontent field
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
52 53 54 55 56 57 58 | return zTags; } /* ** Print common information about a particular record. ** | | | | | 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 |
return zTags;
}
/*
** Print common information about a particular record.
**
** * The artifact hash
** * The record ID
** * mtime and ctime
** * who signed it
**
*/
void show_common_info(
int rid, /* The rid for the check-in to display info for */
const char *zRecDesc, /* Brief record description; e.g. "checkout:" */
int showComment, /* True to show the check-in comment */
int showFamily /* True to show parents and children */
){
Stmt q;
char *zComment = 0;
char *zTags;
char *zDate;
char *zUuid;
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid ){
zDate = db_text(0,
"SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
rid
);
/* 01234567890123 */
fossil_print("%-13s %.40s %s\n", zRecDesc, zUuid, zDate ? zDate : "");
free(zDate);
if( showComment ){
zComment = db_text(0,
"SELECT coalesce(ecomment,comment) || "
" ' (user: ' || coalesce(euser,user,'?') || ')' "
" FROM event WHERE objid=%d",
rid
|
| ︙ | ︙ | |||
272 273 274 275 276 277 278 |
}
}else{
int rid;
rid = name_to_rid(g.argv[2]);
if( rid==0 ){
fossil_fatal("no such object: %s", g.argv[2]);
}
| | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
}
}else{
int rid;
rid = name_to_rid(g.argv[2]);
if( rid==0 ){
fossil_fatal("no such object: %s", g.argv[2]);
}
show_common_info(rid, "hash:", 1, 1);
}
}
/*
** Show the context graph (immediate parents and children) for
** check-in rid.
*/
|
| ︙ | ︙ | |||
745 746 747 748 749 750 751 |
@ <span class="infoTag">%h(zTagname)=%h(zValue)</span>
}else {
@ <span class="infoTag">%h(zTagname)</span>
}
if( tagtype==2 ){
if( zOrigUuid && zOrigUuid[0] ){
@ inherited from
| | | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 |
@ <span class="infoTag">%h(zTagname)=%h(zValue)</span>
}else {
@ <span class="infoTag">%h(zTagname)</span>
}
if( tagtype==2 ){
if( zOrigUuid && zOrigUuid[0] ){
@ inherited from
hyperlink_to_version(zOrigUuid);
}else{
@ propagates to descendants
}
}
if( zSrcUuid && zSrcUuid[0] ){
if( tagtype==0 ){
@ by
}else{
@ added by
}
hyperlink_to_version(zSrcUuid);
@ on
hyperlink_to_date(zDate,0);
}
@ </li>
}
db_finalize(&q);
if( cnt ){
|
| ︙ | ︙ | |||
827 828 829 830 831 832 833 |
void ci_page(void){
Stmt q1, q2, q3;
int rid;
int isLeaf;
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
u64 diffFlags; /* Flag parameter for text_diff() */
const char *zName; /* Name of the check-in to be displayed */
| | | | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 |
void ci_page(void){
Stmt q1, q2, q3;
int rid;
int isLeaf;
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
u64 diffFlags; /* Flag parameter for text_diff() */
const char *zName; /* Name of the check-in to be displayed */
const char *zUuid; /* Hash of zName, found via blob.uuid */
const char *zParent; /* Hash of the parent check-in (if any) */
const char *zRe; /* regex parameter */
ReCompiled *pRe = 0; /* regex */
const char *zW; /* URL param for ignoring whitespace */
const char *zPage = "vinfo"; /* Page that shows diffs */
const char *zPageHide = "ci"; /* Page that hides diffs */
const char *zBrName; /* Branch name */
int bLocalMode; /* TRUE for /local; FALSE otherwise */
|
| ︙ | ︙ | |||
1322 1323 1324 1325 1326 1327 1328 | } db_finalize(&q3); db_end_transaction(1); /* ROLLBACK */ } /* ** WEBPAGE: winfo | | | 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 |
}
db_finalize(&q3);
db_end_transaction(1); /* ROLLBACK */
}
/*
** WEBPAGE: winfo
** URL: /winfo?name=HASH
**
** Display information about a wiki page.
*/
void winfo_page(void){
int rid;
Manifest *pWiki;
char *zUuid;
|
| ︙ | ︙ | |||
1483 1484 1485 1486 1487 1488 1489 |
const char *zUuid = db_column_text(&q, 3);
const char *zTagList = db_column_text(&q, 4);
Blob comment;
int wikiFlags = WIKI_INLINE|WIKI_NOBADLINKS;
if( db_get_boolean("timeline-block-markup", 0)==0 ){
wikiFlags |= WIKI_NOBLOCK;
}
| | | 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 |
const char *zUuid = db_column_text(&q, 3);
const char *zTagList = db_column_text(&q, 4);
Blob comment;
int wikiFlags = WIKI_INLINE|WIKI_NOBADLINKS;
if( db_get_boolean("timeline-block-markup", 0)==0 ){
wikiFlags |= WIKI_NOBLOCK;
}
hyperlink_to_version(zUuid);
blob_zero(&comment);
db_column_blob(&q, 2, &comment);
wiki_convert(&comment, 0, wikiFlags);
blob_reset(&comment);
@ (user:
hyperlink_to_user(zUser,zDate,",");
if( zTagList && zTagList[0] && g.perm.Hyperlink ){
|
| ︙ | ︙ | |||
1811 1812 1813 1814 1815 1816 1817 |
}
prevName = fossil_strdup(zName);
}
if( showDetail ){
@ <li>
hyperlink_to_date(zDate,"");
@ — part of check-in
| | | | 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 |
}
prevName = fossil_strdup(zName);
}
if( showDetail ){
@ <li>
hyperlink_to_date(zDate,"");
@ — part of check-in
hyperlink_to_version(zVers);
}else{
@ — part of check-in
hyperlink_to_version(zVers);
@ at
hyperlink_to_date(zDate,"");
}
if( zBr && zBr[0] ){
@ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
}
@ — %!W(zCom) (user:
|
| ︙ | ︙ | |||
1917 1918 1919 1920 1921 1922 1923 |
}else if( zType[0]=='f' ){
objType |= OBJTYPE_FORUM;
@ Forum post
}else{
@ Tag referencing
}
if( zType[0]!='e' || eventTagId == 0){
| | | 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 |
}else if( zType[0]=='f' ){
objType |= OBJTYPE_FORUM;
@ Forum post
}else{
@ Tag referencing
}
if( zType[0]!='e' || eventTagId == 0){
hyperlink_to_version(zUuid);
}
@ - %!W(zCom) by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate, ".");
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_appendf(pDownloadName, "%S.txt", zUuid);
}
|
| ︙ | ︙ | |||
1949 1950 1951 1952 1953 1954 1955 |
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
objType |= OBJTYPE_ATTACHMENT;
| | | 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 |
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
objType |= OBJTYPE_ATTACHMENT;
if( fossil_is_artifact_hash(zTarget) ){
if( db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'",
zTarget)
){
if( g.perm.Hyperlink && g.anon.RdTkt ){
@ ticket [%z(href("%R/tktview?name=%!S",zTarget))%S(zTarget)</a>]
}else{
@ ticket [%S(zTarget)]
|
| ︙ | ︙ | |||
2009 2010 2011 2012 2013 2014 2015 | return objType; } /* ** WEBPAGE: fdiff ** WEBPAGE: localdiff | | | 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 | return objType; } /* ** WEBPAGE: fdiff ** WEBPAGE: localdiff ** URL: fdiff?v1=HASH&v2=HASH ** URL: localdiff?name=filename ** ** Two arguments, v1 and v2, identify the artifacts to be diffed. ** Show diff side by side unless sbs is 0. Generate plain text if ** "patch" is present, otherwise generate "pretty" HTML. ** ** Alternative URL: fdiff?from=filename1&to=filename2&ci=checkin |
| ︙ | ︙ | |||
2225 2226 2227 2228 2229 2230 2231 |
** Return the uninterpreted content of an artifact. This is similar
** to /raw except in this case the only way to specify the artifact
** is by the full-length SHA1 or SHA3 hash. Abbreviations are not
** accepted.
*/
void secure_rawartifact_page(void){
int rid = 0;
| | | | | 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 |
** Return the uninterpreted content of an artifact. This is similar
** to /raw except in this case the only way to specify the artifact
** is by the full-length SHA1 or SHA3 hash. Abbreviations are not
** accepted.
*/
void secure_rawartifact_page(void){
int rid = 0;
const char *zName = PD("name", "");
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
if( rid==0 ){
cgi_set_status(404, "Not Found");
@ Unknown artifact: "%h(zName)"
return;
}
g.isConst = 1;
deliver_artifact(rid, P("m"));
}
|
| ︙ | ︙ | |||
3023 3024 3025 3026 3027 3028 3029 | manifest_destroy(pTktChng); style_footer(); } /* ** WEBPAGE: info | | | | > > | | 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 |
manifest_destroy(pTktChng);
style_footer();
}
/*
** WEBPAGE: info
** URL: info/NAME
**
** The NAME argument is any valid artifact name: an artifact hash,
** a timestamp, a tag name, etc.
**
** Because NAME can match so many different things (commit artifacts,
** wiki pages, ticket comments, forum posts...) the format of the output
** page depends on the type of artifact that NAME matches.
*/
void info_page(void){
const char *zName;
Blob uuid;
int rid;
int rc;
int nLen;
|
| ︙ | ︙ | |||
3642 3643 3644 3645 3646 3647 3648 |
blob_append(&prompt, zUuid, -1);
}
blob_append(&prompt, ".\n# Lines beginning with a # are ignored.\n", -1);
prompt_for_user_comment(pComment, &prompt);
blob_reset(&prompt);
}
| | | | | 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 |
blob_append(&prompt, zUuid, -1);
}
blob_append(&prompt, ".\n# Lines beginning with a # are ignored.\n", -1);
prompt_for_user_comment(pComment, &prompt);
blob_reset(&prompt);
}
#define AMEND_USAGE_STMT "HASH OPTION ?OPTION ...?"
/*
** COMMAND: amend
**
** Usage: %fossil amend HASH OPTION ?OPTION ...?
**
** Amend the tags on check-in HASH to change how it displays in the timeline.
**
** Options:
**
** --author USER Make USER the author for check-in
** -m|--comment COMMENT Make COMMENT the check-in comment
** -M|--message-file FILE Read the amended comment from FILE
** -e|--edit-comment Launch editor to revise comment
|
| ︙ | ︙ | |||
3736 3737 3738 3739 3740 3741 3742 |
db_find_and_open_repository(0,0);
user_select();
verify_all_options();
if( g.argc<3 || g.argc>=4 ) usage(AMEND_USAGE_STMT);
rid = name_to_typed_rid(g.argv[2], "ci");
if( rid==0 && !is_a_version(rid) ) fossil_fatal("no such check-in");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
| | | 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 |
db_find_and_open_repository(0,0);
user_select();
verify_all_options();
if( g.argc<3 || g.argc>=4 ) usage(AMEND_USAGE_STMT);
rid = name_to_typed_rid(g.argv[2], "ci");
if( rid==0 && !is_a_version(rid) ) fossil_fatal("no such check-in");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid==0 ) fossil_fatal("Unable to find artifact hash");
zComment = db_text(0, "SELECT coalesce(ecomment,comment)"
" FROM event WHERE objid=%d", rid);
zUser = db_text(0, "SELECT coalesce(euser,user)"
" FROM event WHERE objid=%d", rid);
zDate = db_text(0, "SELECT datetime(mtime)"
" FROM event WHERE objid=%d", rid);
zColor = db_text("", "SELECT bgcolor"
|
| ︙ | ︙ | |||
3826 3827 3828 3829 3830 3831 3832 |
fossil_free((void *)pzCancelTags);
}
if( fHide && !fHasHidden ) hide_branch();
if( fClose && !fHasClosed ) close_leaf(rid);
if( zNewBranch && zNewBranch[0] ) change_branch(rid,zNewBranch);
apply_newtags(&ctrl, rid, zUuid, zUserOvrd, fDryRun);
if( fDryRun==0 ){
| | | 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 |
fossil_free((void *)pzCancelTags);
}
if( fHide && !fHasHidden ) hide_branch();
if( fClose && !fHasClosed ) close_leaf(rid);
if( zNewBranch && zNewBranch[0] ) change_branch(rid,zNewBranch);
apply_newtags(&ctrl, rid, zUuid, zUserOvrd, fDryRun);
if( fDryRun==0 ){
show_common_info(rid, "hash:", 1, 0);
}
if( g.localOpen ){
manifest_to_disk(rid);
}
}
|
Changes to src/json_finfo.c.
| ︙ | ︙ | |||
87 88 89 90 91 92 93 |
if( zCheckin && *zCheckin ){
char * zU = NULL;
int rc = name_to_uuid2( zCheckin, "ci", &zU );
/*printf("zCheckin=[%s], zU=[%s]", zCheckin, zU);*/
if(rc<=0){
json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
| | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
if( zCheckin && *zCheckin ){
char * zU = NULL;
int rc = name_to_uuid2( zCheckin, "ci", &zU );
/*printf("zCheckin=[%s], zU=[%s]", zCheckin, zU);*/
if(rc<=0){
json_set_err((rc<0) ? FSL_JSON_E_AMBIGUOUS_UUID : FSL_JSON_E_RESOURCE_NOT_FOUND,
"Check-in hash %s.", (rc<0) ? "is ambiguous" : "not found");
blob_reset(&sql);
return NULL;
}
blob_append_sql(&sql, " AND ci.uuid='%q'", zU);
free(zU);
}else{
if( zAfter && *zAfter ){
|
| ︙ | ︙ |
Changes to src/json_tag.c.
| ︙ | ︙ | |||
115 116 117 118 119 120 121 |
cson_object_set(pay, "raw", cson_value_new_bool(fRaw));
{
Blob uu = empty_blob;
int rc;
blob_append(&uu, zName, -1);
rc = name_to_uuid(&uu, 9, "*");
if(0!=rc){
| | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
cson_object_set(pay, "raw", cson_value_new_bool(fRaw));
{
Blob uu = empty_blob;
int rc;
blob_append(&uu, zName, -1);
rc = name_to_uuid(&uu, 9, "*");
if(0!=rc){
json_set_err(FSL_JSON_E_UNKNOWN,"Could not convert name back to artifact hash!");
blob_reset(&uu);
goto error;
}
cson_object_set(pay, "appliedTo", json_new_string(blob_buffer(&uu)));
blob_reset(&uu);
}
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
157 158 159 160 161 162 163 | char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ const char *zCmdName; /* Name of the Fossil command currently running */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ const char *zCmdName; /* Name of the Fossil command currently running */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct hash */ int eHashPolicy; /* Current hash policy. One of HPOLICY_* */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if --sqlprint flag is present */ int fCgiTrace; /* True if --cgitrace is enabled */ int fQuiet; /* True if -quiet flag is present */ int fJail; /* True if running with a chroot jail */ |
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
606 607 608 609 610 611 612 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
| < | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_USE_ALLOCA \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
|
| ︙ | ︙ | |||
634 635 636 637 638 639 640 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
| < | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_USE_ALLOCA \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
|
| ︙ | ︙ |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
190 191 192 193 194 195 196 | -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED | < | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 |
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
2432 2433 2434 2435 2436 2437 2438 |
char *zComment = 0;
const char isAdd = (p->zAttachSrc && p->zAttachSrc[0]) ? 1 : 0;
/* We assume that we're attaching to a wiki page until we
** prove otherwise (which could on a later artifact if we
** process the attachment artifact before the artifact to
** which it is attached!) */
char attachToType = 'w';
| | | 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 |
char *zComment = 0;
const char isAdd = (p->zAttachSrc && p->zAttachSrc[0]) ? 1 : 0;
/* We assume that we're attaching to a wiki page until we
** prove otherwise (which could on a later artifact if we
** process the attachment artifact before the artifact to
** which it is attached!) */
char attachToType = 'w';
if( fossil_is_artifact_hash(p->zAttachTarget) ){
if( db_exists("SELECT 1 FROM tag WHERE tagname='tkt-%q'",
p->zAttachTarget)
){
attachToType = 't'; /* Attaching to known ticket */
}else if( db_exists("SELECT 1 FROM tag WHERE tagname='event-%q'",
p->zAttachTarget)
){
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
444 445 446 447 448 449 450 |
}
}
}
return rid;
}
/*
| | > > > | > | | < > > > | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
}
}
}
return rid;
}
/*
** This routine takes a user-entered string and tries to convert it to
** an artifact hash.
**
** We first try to treat the string as an artifact hash, or at least a
** unique prefix of an artifact hash. The input may be in mixed case.
** If we are passed such a string, this routine has the effect of
** converting the hash [prefix] to canonical form.
**
** If the input is not a hash or a hash prefix, then try to resolve
** the name as a tag. If multiple tags match, pick the latest.
** A caller can force this routine to skip the hash case above by
** prefixing the string with "tag:", a useful property when the tag
** may be misinterpreted as a hex ASCII string. (e.g. "decade" or "facade")
**
** If the input is not a tag, then try to match it as an ISO-8601 date
** string YYYY-MM-DD HH:MM:SS and pick the nearest check-in to that date.
** If the input is of the form "date:*" then always resolve the name as
** a date. The forms "utc:*" and "local:" are deprecated.
**
** Return 0 on success. Return 1 if the name cannot be resolved.
|
| ︙ | ︙ | |||
479 480 481 482 483 484 485 |
return 0;
}
}
/*
** This routine is similar to name_to_uuid() except in the form it
** takes its parameters and returns its value, and in that it does not
| | | | | > | | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 |
return 0;
}
}
/*
** This routine is similar to name_to_uuid() except in the form it
** takes its parameters and returns its value, and in that it does not
** treat errors as fatal. zName must be an artifact hash or prefix of
** a hash. zType is also as described for name_to_uuid(). If
** zName does not resolve, 0 is returned. If it is ambiguous, a
** 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 = db_text(NULL, "SELECT uuid FROM blob WHERE rid=%d", rid);
}
return rid;
}
/*
** name_collisions searches through events, blobs, and tickets for
** collisions of a given hash based on its length, counting only
** hashes greater than or equal to 4 hex ASCII characters (16 bits)
** in length.
*/
int name_collisions(const char *zName){
int c = 0; /* count of collisions for zName */
int nLen; /* length of zName */
nLen = strlen(zName);
if( nLen>=4 && nLen<=HNAME_MAX && validate16(zName, nLen) ){
c = db_int(0,
|
| ︙ | ︙ | |||
631 632 633 634 635 636 637 |
int rid = db_column_int(&q, 0);
const char *zUuid = db_column_text(&q, 1);
const char *zTitle = db_column_text(&q, 2);
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
@ <ul></ul>
@ Ticket
| | | 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 |
int rid = db_column_int(&q, 0);
const char *zUuid = db_column_text(&q, 1);
const char *zTitle = db_column_text(&q, 2);
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
@ <ul></ul>
@ Ticket
hyperlink_to_version(zUuid);
@ - %h(zTitle).
@ <ul><li>
object_description(rid, 0, 0, 0);
@ </li></ul>
@ </p></li>
}
db_finalize(&q);
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
95 96 97 98 99 100 101 | #define etPOINTER 16 /* The %p conversion */ #define etHTMLIZE 17 /* Make text safe for HTML */ #define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 20 /* The fossil header encoding format. */ #define etPATH 21 /* Path type */ #define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */ | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#define etPOINTER 16 /* The %p conversion */
#define etHTMLIZE 17 /* Make text safe for HTML */
#define etHTTPIZE 18 /* Make text safe for HTTP. "/" encoded as %2f */
#define etURLIZE 19 /* Make text safe for HTTP. "/" not encoded */
#define etFOSSILIZE 20 /* The fossil header encoding format. */
#define etPATH 21 /* Path type */
#define etWIKISTR 22 /* Timeline comment text rendered from a char*: %W */
#define etSTRINGID 23 /* String with length limit for a hash prefix: %S */
#define etROOT 24 /* String value of g.zTop: %R */
#define etJSONSTR 25 /* String encoded as a JSON string literal: %j
Use %!j to include double-quotes around it. */
/*
** An "etByte" is an 8-bit unsigned value.
|
| ︙ | ︙ |
Changes to src/purge.c.
| ︙ | ︙ | |||
454 455 456 457 458 459 460 | ** ==== WARNING: This command can potentially destroy historical data and ==== ** ==== leave your repository in a goofy state. Know what you are doing! ==== ** ==== Make a backup of your repository before using this command! ==== ** ** ==== FURTHER WARNING: This command is a work-in-progress and may yet ==== ** ==== contain bugs. ==== ** | | | | | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | ** ==== WARNING: This command can potentially destroy historical data and ==== ** ==== leave your repository in a goofy state. Know what you are doing! ==== ** ==== Make a backup of your repository before using this command! ==== ** ** ==== FURTHER WARNING: This command is a work-in-progress and may yet ==== ** ==== contain bugs. ==== ** ** fossil purge artifacts HASH... ?OPTIONS? ** ** Move arbitrary artifacts identified by the HASH list into the ** graveyard. ** ** fossil purge cat HASH... ** ** Write the content of one or more artifacts in the graveyard onto ** standard output. ** ** fossil purge checkins TAGS... ?OPTIONS? ** ** Move the check-ins or branches identified by TAGS and all of |
| ︙ | ︙ | |||
507 508 509 510 511 512 513 | ** ** COMMON OPTIONS: ** ** --explain Make no changes, but show what would happen. ** --dry-run An alias for --explain ** ** SUMMARY: | | | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | ** ** COMMON OPTIONS: ** ** --explain Make no changes, but show what would happen. ** --dry-run An alias for --explain ** ** SUMMARY: ** fossil purge artifacts HASH.. [OPTIONS] ** fossil purge cat HASH... ** fossil purge checkins TAGS... [OPTIONS] ** fossil purge files FILENAME... [OPTIONS] ** fossil purge list ** fossil purge obliterate ID... ** fossil purge tickets NAME... [OPTIONS] ** fossil purge undo ID ** fossil purge wiki NAME... [OPTIONS] |
| ︙ | ︙ | |||
545 546 547 548 549 550 551 |
}
describe_artifacts_to_stdout("IN ok", 0);
purge_artifact_list("ok", "", purgeFlags);
db_end_transaction(0);
}else if( strncmp(zSubcmd, "cat", n)==0 ){
int i, piid;
Blob content;
| | | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
}
describe_artifacts_to_stdout("IN ok", 0);
purge_artifact_list("ok", "", purgeFlags);
db_end_transaction(0);
}else if( strncmp(zSubcmd, "cat", n)==0 ){
int i, piid;
Blob content;
if( g.argc<4 ) usage("cat HASH...");
for(i=3; i<g.argc; i++){
piid = db_int(0, "SELECT piid FROM purgeitem WHERE uuid LIKE '%q%%'",
g.argv[i]);
if( piid==0 ) fossil_fatal("no such item: %s", g.argv[3]);
purge_extract_item(piid, &content);
blob_write_to_file(&content, "-");
blob_reset(&content);
|
| ︙ | ︙ |
Changes to src/rebuild.c.
| ︙ | ︙ | |||
1147 1148 1149 1150 1151 1152 1153 |
** Helper functions used by the `deconstruct' and `reconstruct' commands to
** save and restore the contents of the PRIVATE table.
*/
void private_export(char *zFileName)
{
Stmt q;
Blob fctx = empty_blob;
| | | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 |
** Helper functions used by the `deconstruct' and `reconstruct' commands to
** save and restore the contents of the PRIVATE table.
*/
void private_export(char *zFileName)
{
Stmt q;
Blob fctx = empty_blob;
blob_append(&fctx, "# The hashes of private artifacts\n", -1);
db_prepare(&q,
"SELECT uuid FROM blob WHERE rid IN ( SELECT rid FROM private );");
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
blob_append(&fctx, zUuid, -1);
blob_append(&fctx, "\n", -1);
}
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
668 669 670 671 672 673 674 |
void *pUser, /* Pointer to output state */
int nArg, /* Number of columns in this result row */
const char **azArg, /* Text of data in all columns */
const char **azName /* Names of the columns */
){
struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
int i;
| | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 |
void *pUser, /* Pointer to output state */
int nArg, /* Number of columns in this result row */
const char **azArg, /* Text of data in all columns */
const char **azName /* Names of the columns */
){
struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
int i;
const char *zTid; /* Ticket hash. (value of column named '#') */
const char *zBg = 0; /* Use this background color */
/* Do initialization
*/
if( pState->nCount==0 ){
/* Turn off the authorizer. It is no longer doing anything since the
** query has already been prepared.
|
| ︙ | ︙ |
Changes to src/rss.c.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 | #include "config.h" #include <time.h> #include "rss.h" #include <assert.h> /* ** WEBPAGE: timeline.rss | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include "config.h" #include <time.h> #include "rss.h" #include <assert.h> /* ** WEBPAGE: timeline.rss ** URL: /timeline.rss?y=TYPE&n=LIMIT&tkt=HASH&tag=TAG&wiki=NAME&name=FILENAME ** ** Produce an RSS feed of the timeline. ** ** TYPE may be: all, ci (show check-ins only), t (show ticket changes only), ** w (show wiki only), e (show tech notes only), f (show forum posts only), ** g (show tag/branch changes only). ** ** LIMIT is the number of items to show. ** ** tkt=HASH filters for only those events for the specified ticket. tag=TAG ** filters for a tag, and wiki=NAME for a wiki page. Only one may be used. ** ** In addition, name=FILENAME filters for a specific file. This may be ** combined with one of the other filters (useful for looking at a specific ** branch). */ |
| ︙ | ︙ | |||
229 230 231 232 233 234 235 | ** -type|y FLAG ** may be: all (default), ci (show check-ins only), t (show tickets only), ** w (show wiki only). ** ** -limit|n LIMIT ** The maximum number of items to show. ** | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | ** -type|y FLAG ** may be: all (default), ci (show check-ins only), t (show tickets only), ** w (show wiki only). ** ** -limit|n LIMIT ** The maximum number of items to show. ** ** -tkt HASH ** Filters for only those events for the specified ticket. ** ** -tag TAG ** filters for a tag ** ** -wiki NAME ** Filters on a specific wiki page. |
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
264 265 266 267 268 269 270 | @ -- @ CREATE TABLE mlink( @ mid INTEGER, -- Check-in that contains fid @ fid INTEGER, -- New file content. 0 if deleted @ pmid INTEGER, -- Check-in that contains pid @ pid INTEGER, -- Prev file content. 0 if new. -1 merge @ fnid INTEGER REFERENCES filename, -- Name of the file | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | @ -- @ CREATE TABLE mlink( @ mid INTEGER, -- Check-in that contains fid @ fid INTEGER, -- New file content. 0 if deleted @ pmid INTEGER, -- Check-in that contains pid @ pid INTEGER, -- Prev file content. 0 if new. -1 merge @ fnid INTEGER REFERENCES filename, -- Name of the file @ pfnid INTEGER, -- Previous name. 0 if unchanged @ mperm INTEGER, -- File permissions. 1==exec @ isaux BOOLEAN DEFAULT 0 -- TRUE if pmid is the primary @ ); @ CREATE INDEX mlink_i1 ON mlink(mid); @ CREATE INDEX mlink_i2 ON mlink(fnid); @ CREATE INDEX mlink_i3 ON mlink(fid); @ CREATE INDEX mlink_i4 ON mlink(pid); |
| ︙ | ︙ | |||
319 320 321 322 323 324 325 | @ comment TEXT, -- Comment describing the event @ brief TEXT, -- Short comment when tagid already seen @ omtime DATETIME -- Original unchanged date+time, or NULL @ ); @ CREATE INDEX event_i1 ON event(mtime); @ @ -- A record of phantoms. A phantom is a record for which we know the | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | @ comment TEXT, -- Comment describing the event @ brief TEXT, -- Short comment when tagid already seen @ omtime DATETIME -- Original unchanged date+time, or NULL @ ); @ CREATE INDEX event_i1 ON event(mtime); @ @ -- A record of phantoms. A phantom is a record for which we know the @ -- file hash but we do not (yet) know the file content. @ -- @ CREATE TABLE phantom( @ rid INTEGER PRIMARY KEY -- Record ID of the phantom @ ); @ @ -- A record of orphaned delta-manifests. An orphan is a delta-manifest @ -- for which we have content, but its baseline-manifest is a phantom. |
| ︙ | ︙ | |||
360 361 362 363 364 365 366 | @ rid INTEGER PRIMARY KEY -- Record ID of the phantom @ ); @ @ -- Each artifact can have one or more tags. A tag @ -- is defined by a row in the next table. @ -- @ -- Wiki pages are tagged with "wiki-NAME" where NAME is the name of | | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | @ rid INTEGER PRIMARY KEY -- Record ID of the phantom @ ); @ @ -- Each artifact can have one or more tags. A tag @ -- is defined by a row in the next table. @ -- @ -- Wiki pages are tagged with "wiki-NAME" where NAME is the name of @ -- the wiki page. Tickets changes are tagged with "ticket-HASH" where @ -- HASH is the indentifier of the ticket. Tags used to assign symbolic @ -- names to baselines are branches are of the form "sym-NAME" where @ -- NAME is the symbolic name. @ -- @ CREATE TABLE tag( @ tagid INTEGER PRIMARY KEY, -- Numeric tag ID @ tagname TEXT UNIQUE -- Tag name. @ ); |
| ︙ | ︙ | |||
419 420 421 422 423 424 425 | @ -- Each attachment is an entry in the following table. Only @ -- the most recent attachment (identified by the D card) is saved. @ -- @ CREATE TABLE attachment( @ attachid INTEGER PRIMARY KEY, -- Local id for this attachment @ isLatest BOOLEAN DEFAULT 0, -- True if this is the one to use @ mtime TIMESTAMP, -- Last changed. Julian day. | | | | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | @ -- Each attachment is an entry in the following table. Only @ -- the most recent attachment (identified by the D card) is saved. @ -- @ CREATE TABLE attachment( @ attachid INTEGER PRIMARY KEY, -- Local id for this attachment @ isLatest BOOLEAN DEFAULT 0, -- True if this is the one to use @ mtime TIMESTAMP, -- Last changed. Julian day. @ src TEXT, -- Hash of the attachment. NULL to delete @ target TEXT, -- Object attached to. Wikiname or Tkt hash @ filename TEXT, -- Filename for the attachment @ comment TEXT, -- Comment associated with this attachment @ user TEXT -- Name of user adding attachment @ ); @ CREATE INDEX attachment_idx1 ON attachment(target, filename, mtime); @ CREATE INDEX attachment_idx2 ON attachment(src); @ |
| ︙ | ︙ |
Changes to src/security_audit.c.
| ︙ | ︙ | |||
519 520 521 522 523 524 525 526 527 528 529 530 531 532 |
ext_files();
nFile = db_int(0, "SELECT count(*) FROM sfile");
nCgi = nFile==0 ? 0 : db_int(0,"SELECT count(*) FROM sfile WHERE isexe");
@ <li><p> CGI Extensions are enabled with a document root
@ at <a href='%R/extfilelist'>%h(g.zExtRoot)</a> holding
@ %d(nCgi) CGIs and %d(nFile-nCgi) static content and data files.
}
@ <li><p> User capability summary:
capability_summary();
azCSP = parse_content_security_policy();
if( azCSP==0 ){
| > > > > > > > | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
ext_files();
nFile = db_int(0, "SELECT count(*) FROM sfile");
nCgi = nFile==0 ? 0 : db_int(0,"SELECT count(*) FROM sfile WHERE isexe");
@ <li><p> CGI Extensions are enabled with a document root
@ at <a href='%R/extfilelist'>%h(g.zExtRoot)</a> holding
@ %d(nCgi) CGIs and %d(nFile-nCgi) static content and data files.
}
if( fileedit_glob()!=0 ){
@ <li><p><a href='%R/fileedit'>Online File Editing</a> is enabled
@ for this repository. Clear the
@ <a href='%R/setup_settings'>"fileedit-glob" setting</a> to
@ disable online editing.</p>
}
@ <li><p> User capability summary:
capability_summary();
azCSP = parse_content_security_policy();
if( azCSP==0 ){
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
9698 9699 9700 9701 9702 9703 9704 | char *zName; /* Symbolic name for this session */ int nFilter; /* Number of xFilter rejection GLOB patterns */ char **azFilter; /* Array of xFilter rejection GLOB patterns */ sqlite3_session *p; /* The open session */ }; #endif | < < < < < < < < < < < < | 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 |
char *zName; /* Symbolic name for this session */
int nFilter; /* Number of xFilter rejection GLOB patterns */
char **azFilter; /* Array of xFilter rejection GLOB patterns */
sqlite3_session *p; /* The open session */
};
#endif
typedef struct ExpertInfo ExpertInfo;
struct ExpertInfo {
sqlite3expert *pExpert;
int bVerbose;
};
/* A single line in the EQP output */
|
| ︙ | ︙ | |||
9779 9780 9781 9782 9783 9784 9785 | char *zDestTable; /* Name of destination table when MODE_Insert */ char *zTempFile; /* Temporary file that might need deleting */ char zTestcase[30]; /* Name of current test case */ char colSeparator[20]; /* Column separator character for several modes */ char rowSeparator[20]; /* Row separator character for MODE_Ascii */ char colSepPrior[20]; /* Saved column separator */ char rowSepPrior[20]; /* Saved row separator */ | | | > | 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 |
char *zDestTable; /* Name of destination table when MODE_Insert */
char *zTempFile; /* Temporary file that might need deleting */
char zTestcase[30]; /* Name of current test case */
char colSeparator[20]; /* Column separator character for several modes */
char rowSeparator[20]; /* Row separator character for MODE_Ascii */
char colSepPrior[20]; /* Saved column separator */
char rowSepPrior[20]; /* Saved row separator */
int *colWidth; /* Requested width of each column in columnar modes */
int *actualWidth; /* Actual width of each column */
int nWidth; /* Number of slots in colWidth[] and actualWidth[] */
char nullValue[20]; /* The text to print when a NULL comes back from
** the database */
char outfile[FILENAME_MAX]; /* Filename for *out */
const char *zDbFilename; /* name of the database file */
char *zFreeOnClose; /* Filename to free when closing */
const char *zVfs; /* Name of VFS to use */
sqlite3_stmt *pStmt; /* Current statement if any. */
|
| ︙ | ︙ | |||
9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 |
#define MODE_Quote 6 /* Quote values as for SQL */
#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
#define MODE_Csv 8 /* Quote strings, numbers are plain */
#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
#define MODE_Pretty 11 /* Pretty-print schemas */
#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
static const char *modeDescr[] = {
"line",
"column",
"list",
"semi",
"html",
"insert",
"quote",
"tcl",
"csv",
"explain",
"ascii",
"prettyprint",
| > > > | > > > | 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 |
#define MODE_Quote 6 /* Quote values as for SQL */
#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
#define MODE_Csv 8 /* Quote strings, numbers are plain */
#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
#define MODE_Pretty 11 /* Pretty-print schemas */
#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
#define MODE_Json 13 /* Output JSON */
#define MODE_Markdown 14 /* Markdown formatting */
#define MODE_Table 15 /* MySQL-style table formatting */
static const char *modeDescr[] = {
"line",
"column",
"list",
"semi",
"html",
"insert",
"quote",
"tcl",
"csv",
"explain",
"ascii",
"prettyprint",
"eqp",
"json",
"markdown",
"table"
};
/*
** These are the column/row/line separators used by the various
** import/export modes.
*/
#define SEP_Column "|"
|
| ︙ | ︙ | |||
10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 |
raw_printf(out, "\\%03o", c&0xff);
}else{
fputc(c, out);
}
}
fputc('"', out);
}
/*
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(FILE *out, const char *z){
int i;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 |
raw_printf(out, "\\%03o", c&0xff);
}else{
fputc(c, out);
}
}
fputc('"', out);
}
/*
** Output the given string as a quoted according to JSON quoting rules.
*/
static void output_json_string(FILE *out, const char *z, int n){
unsigned int c;
if( n<0 ) n = (int)strlen(z);
fputc('"', out);
while( n-- ){
c = *(z++);
if( c=='\\' || c=='"' ){
fputc('\\', out);
fputc(c, out);
}else if( c<=0x1f ){
fputc('\\', out);
if( c=='\b' ){
fputc('b', out);
}else if( c=='\f' ){
fputc('f', out);
}else if( c=='\n' ){
fputc('n', out);
}else if( c=='\r' ){
fputc('r', out);
}else if( c=='\t' ){
fputc('t', out);
}else{
raw_printf(out, "u%04x",c);
}
}else{
fputc(c, out);
}
}
fputc('"', out);
}
/*
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(FILE *out, const char *z){
int i;
|
| ︙ | ︙ | |||
10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 |
}
if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
raw_printf(p->out, "Progress %u\n", p->nProgress);
}
return 0;
}
#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
void *pArg,
int nArg, /* Number of result columns */
char **azArg, /* Text of each result column */
char **azCol, /* Column names */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < | < < < < < < < < < < | | < < < < | < < < < < < < < < < < < < | < < < < < < < < < < < < < < < | | | < < < | < < < | | | 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 |
}
if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
raw_printf(p->out, "Progress %u\n", p->nProgress);
}
return 0;
}
#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
/*
** Print N dashes
*/
static void print_dashes(FILE *out, int N){
const char zDash[] = "--------------------------------------------------";
const int nDash = sizeof(zDash) - 1;
while( N>nDash ){
fputs(zDash, out);
N -= nDash;
}
raw_printf(out, "%.*s", N, zDash);
}
/*
** Print a markdown or table-style row separator
*/
static void print_row_separator(
ShellState *p,
int nArg,
const char *zSep
){
int i;
for(i=0; i<nArg; i++){
fputs(zSep, p->out);
print_dashes(p->out, p->actualWidth[i]+2);
}
fputs(zSep, p->out);
fputs("\n", p->out);
}
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
void *pArg,
int nArg, /* Number of result columns */
char **azArg, /* Text of each result column */
char **azCol, /* Column names */
int *aiType /* Column types. Might be NULL */
){
int i;
ShellState *p = (ShellState*)pArg;
if( azArg==0 ) return 0;
switch( p->cMode ){
case MODE_Line: {
int w = 5;
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
int len = strlen30(azCol[i] ? azCol[i] : "");
if( len>w ) w = len;
}
if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
for(i=0; i<nArg; i++){
utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
}
break;
}
case MODE_Explain: {
static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
if( nArg>ArraySize(aExplainWidth) ){
nArg = ArraySize(aExplainWidth);
}
if( p->cnt++==0 ){
for(i=0; i<nArg; i++){
int w = aExplainWidth[i];
utf8_width_print(p->out, w, azCol[i]);
fputs(i==nArg-1 ? "\n" : " ", p->out);
}
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
int w = aExplainWidth[i];
if( azArg[i] && strlenChar(azArg[i])>w ){
w = strlenChar(azArg[i]);
}
if( i==1 && p->aiIndent && p->pStmt ){
if( p->iIndent<p->nIndent ){
utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
}
p->iIndent++;
}
utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
fputs(i==nArg-1 ? "\n" : " ", p->out);
}
break;
}
case MODE_Semi: { /* .schema and .fullschema output */
printSchemaLine(p->out, azArg[0], ";\n");
break;
}
|
| ︙ | ︙ | |||
10863 10864 10865 10866 10867 10868 10869 10870 |
output_quoted_string(p->out, azArg[i]);
}else{
output_quoted_escaped_string(p->out, azArg[i]);
}
}
raw_printf(p->out,");\n");
break;
}
| | | > > > > > | > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 |
output_quoted_string(p->out, azArg[i]);
}else{
output_quoted_escaped_string(p->out, azArg[i]);
}
}
raw_printf(p->out,");\n");
break;
}
case MODE_Json: {
if( azArg==0 ) break;
if( p->cnt==0 ){
fputs("[{", p->out);
}else{
fputs(",\n{", p->out);
}
p->cnt++;
for(i=0; i<nArg; i++){
output_json_string(p->out, azCol[i], -1);
putc(':', p->out);
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
fputs("null",p->out);
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
char z[50];
double r = sqlite3_column_double(p->pStmt, i);
sqlite3_uint64 ur;
memcpy(&ur,&r,sizeof(r));
if( ur==0x7ff0000000000000LL ){
raw_printf(p->out, "1e999");
}else if( ur==0xfff0000000000000LL ){
raw_printf(p->out, "-1e999");
}else{
sqlite3_snprintf(50,z,"%!.20g", r);
raw_printf(p->out, "%s", z);
}
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
output_json_string(p->out, pBlob, nBlob);
}else if( aiType && aiType[i]==SQLITE_TEXT ){
output_json_string(p->out, azArg[i], -1);
}else{
utf8_printf(p->out,"%s", azArg[i]);
}
if( i<nArg-1 ){
putc(',', p->out);
}
}
putc('}', p->out);
break;
}
case MODE_Quote: {
if( azArg==0 ) break;
if( p->cnt==0 && p->showHeader ){
for(i=0; i<nArg; i++){
if( i>0 ) fputs(p->colSeparator, p->out);
output_quoted_string(p->out, azCol[i]);
}
fputs(p->rowSeparator, p->out);
}
p->cnt++;
for(i=0; i<nArg; i++){
if( i>0 ) fputs(p->colSeparator, p->out);
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
utf8_printf(p->out,"NULL");
}else if( aiType && aiType[i]==SQLITE_TEXT ){
output_quoted_string(p->out, azArg[i]);
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
utf8_printf(p->out,"%s", azArg[i]);
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
|
| ︙ | ︙ | |||
10897 10898 10899 10900 10901 10902 10903 |
output_hex_blob(p->out, pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
utf8_printf(p->out,"%s", azArg[i]);
}else{
output_quoted_string(p->out, azArg[i]);
}
}
| | | 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 |
output_hex_blob(p->out, pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
utf8_printf(p->out,"%s", azArg[i]);
}else{
output_quoted_string(p->out, azArg[i]);
}
}
fputs(p->rowSeparator, p->out);
break;
}
case MODE_Ascii: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
|
| ︙ | ︙ | |||
11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 11571 11572 11573 11574 |
}else{
sqlite3_bind_null(pStmt, i);
}
sqlite3_reset(pQ);
}
sqlite3_finalize(pQ);
}
/*
** Run a prepared statement
*/
static void exec_prepared_stmt(
ShellState *pArg, /* Pointer to ShellState */
sqlite3_stmt *pStmt /* Statment to run */
){
int rc;
/* perform the first step. this will tell us if we
** have a result set or not and how wide it is.
*/
rc = sqlite3_step(pStmt);
/* if we have a result set... */
if( SQLITE_ROW == rc ){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723 11724 11725 11726 11727 11728 11729 11730 11731 11732 11733 11734 |
}else{
sqlite3_bind_null(pStmt, i);
}
sqlite3_reset(pQ);
}
sqlite3_finalize(pQ);
}
/*
** Run a prepared statement and output the result in one of the
** table-oriented formats: MODE_Column, MODE_Markdown, or MODE_Table.
**
** This is different from ordinary exec_prepared_stmt() in that
** it has to run the entire query and gather the results into memory
** first, in order to determine column widths, before providing
** any output.
*/
static void exec_prepared_stmt_columnar(
ShellState *p, /* Pointer to ShellState */
sqlite3_stmt *pStmt /* Statment to run */
){
int nRow = 0;
int nColumn = 0;
char **azData = 0;
char *zMsg = 0;
const char *z;
int rc;
int i, j, nTotal, w, n;
const char *colSep;
const char *rowSep;
rc = sqlite3_get_table(p->db, sqlite3_sql(pStmt),
&azData, &nRow, &nColumn, &zMsg);
if( rc ){
utf8_printf(p->out, "ERROR: %s\n", zMsg);
sqlite3_free(zMsg);
sqlite3_free_table(azData);
return;
}
if( nColumn>p->nWidth ){
p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int));
if( p->colWidth==0 ) shell_out_of_memory();
for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
p->nWidth = nColumn;
p->actualWidth = &p->colWidth[nColumn];
}
memset(p->actualWidth, 0, nColumn*sizeof(int));
for(i=0; i<nColumn; i++){
w = p->colWidth[i];
if( w<0 ) w = -w;
p->actualWidth[i] = w;
}
nTotal = nColumn*(nRow+1);
for(i=0; i<nTotal; i++){
z = azData[i];
if( z==0 ) z = p->nullValue;
n = strlenChar(z);
j = i%nColumn;
if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
}
if( p->cMode==MODE_Column ){
colSep = " ";
rowSep = "\n";
if( p->showHeader ){
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
if( p->colWidth[i]<0 ) w = -w;
utf8_width_print(p->out, w, azData[i]);
fputs(i==nColumn-1?"\n":" ", p->out);
}
for(i=0; i<nColumn; i++){
print_dashes(p->out, p->actualWidth[i]);
fputs(i==nColumn-1?"\n":" ", p->out);
}
}
}else{
colSep = " | ";
rowSep = " |\n";
if( p->cMode==MODE_Table ) print_row_separator(p, nColumn, "+");
fputs("| ", p->out);
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
n = strlenChar(azData[i]);
utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
fputs(i==nColumn-1?" |\n":" | ", p->out);
}
print_row_separator(p, nColumn, p->cMode==MODE_Table ? "+" : "|");
}
for(i=nColumn, j=0; i<nTotal; i++, j++){
if( j==0 && p->cMode!=MODE_Column ) fputs("| ", p->out);
z = azData[i];
if( z==0 ) z = p->nullValue;
w = p->actualWidth[j];
if( p->colWidth[j]<0 ) w = -w;
utf8_width_print(p->out, w, z);
if( j==nColumn-1 ){
fputs(rowSep, p->out);
j = -1;
}else{
fputs(colSep, p->out);
}
}
if( p->cMode==MODE_Table ){
print_row_separator(p, nColumn, "+");
}
sqlite3_free_table(azData);
}
/*
** Run a prepared statement
*/
static void exec_prepared_stmt(
ShellState *pArg, /* Pointer to ShellState */
sqlite3_stmt *pStmt /* Statment to run */
){
int rc;
if( pArg->cMode==MODE_Column
|| pArg->cMode==MODE_Table
|| pArg->cMode==MODE_Markdown
){
exec_prepared_stmt_columnar(pArg, pStmt);
return;
}
/* perform the first step. this will tell us if we
** have a result set or not and how wide it is.
*/
rc = sqlite3_step(pStmt);
/* if we have a result set... */
if( SQLITE_ROW == rc ){
|
| ︙ | ︙ | |||
11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 |
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
}
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** This function is called to process SQL if the previous shell command
| > > > > > | 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 |
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
if( pArg->cMode==MODE_Table ){
print_row_separator(pArg, nCol, "+");
}else if( pArg->cMode==MODE_Json ){
fputs("]\n", pArg->out);
}
}
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** This function is called to process SQL if the previous shell command
|
| ︙ | ︙ | |||
16881 16882 16883 16884 16885 16886 16887 16888 16889 16890 16891 16892 16893 16894 16895 |
p->mode = MODE_List;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
}else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
p->mode = MODE_Insert;
set_table_name(p, nArg>=3 ? azArg[2] : "table");
}else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
p->mode = MODE_Quote;
}else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
p->mode = MODE_Ascii;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
}else if( nArg==1 ){
raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
}else{
raw_printf(stderr, "Error: mode should be one of: "
| > > > > > > > > | > | 17046 17047 17048 17049 17050 17051 17052 17053 17054 17055 17056 17057 17058 17059 17060 17061 17062 17063 17064 17065 17066 17067 17068 17069 17070 17071 17072 17073 17074 17075 17076 17077 |
p->mode = MODE_List;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
}else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
p->mode = MODE_Insert;
set_table_name(p, nArg>=3 ? azArg[2] : "table");
}else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
p->mode = MODE_Quote;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
}else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
p->mode = MODE_Ascii;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
}else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
p->mode = MODE_Markdown;
}else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
p->mode = MODE_Table;
}else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
p->mode = MODE_Json;
}else if( nArg==1 ){
raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
}else{
raw_printf(stderr, "Error: mode should be one of: "
"ascii column csv html insert json line list markdown "
"quote table tabs tcl\n");
rc = 1;
}
p->cMode = p->mode;
}else
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
if( nArg==2 ){
|
| ︙ | ︙ | |||
17990 17991 17992 17993 17994 17995 17996 |
output_c_string(p->out, p->colSeparator);
raw_printf(p->out, "\n");
utf8_printf(p->out,"%12.12s: ", "rowseparator");
output_c_string(p->out, p->rowSeparator);
raw_printf(p->out, "\n");
utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
utf8_printf(p->out, "%12.12s: ", "width");
| | | 18164 18165 18166 18167 18168 18169 18170 18171 18172 18173 18174 18175 18176 18177 18178 |
output_c_string(p->out, p->colSeparator);
raw_printf(p->out, "\n");
utf8_printf(p->out,"%12.12s: ", "rowseparator");
output_c_string(p->out, p->rowSeparator);
raw_printf(p->out, "\n");
utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
utf8_printf(p->out, "%12.12s: ", "width");
for (i=0;i<p->nWidth;i++) {
raw_printf(p->out, "%d ", p->colWidth[i]);
}
raw_printf(p->out, "\n");
utf8_printf(p->out, "%12.12s: %s\n", "filename",
p->zDbFilename ? p->zDbFilename : "");
}else
|
| ︙ | ︙ | |||
18539 18540 18541 18542 18543 18544 18545 |
sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
}else
#endif
if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
int j;
assert( nArg<=ArraySize(azArg) );
| > > > > | | 18713 18714 18715 18716 18717 18718 18719 18720 18721 18722 18723 18724 18725 18726 18727 18728 18729 18730 18731 |
sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
}else
#endif
if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
int j;
assert( nArg<=ArraySize(azArg) );
p->nWidth = nArg-1;
p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
for(j=1; j<nArg; j++){
p->colWidth[j-1] = (int)integerValue(azArg[j]);
}
}else
{
utf8_printf(stderr, "Error: unknown command or invalid arguments: "
" \"%s\". Enter \".help\" for help\n", azArg[0]);
|
| ︙ | ︙ | |||
18899 18900 18901 18902 18903 18904 18905 18906 18907 18908 18909 18910 18911 18912 18913 18914 18915 18916 18917 18918 18919 18920 18921 18922 18923 18924 18925 18926 18927 18928 18929 18930 18931 18932 18933 18934 | " -[no]header turn headers on or off\n" #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) " -heap SIZE Size of heap for memsys3 or memsys5\n" #endif " -help show this message\n" " -html set output mode to HTML\n" " -interactive force interactive I/O\n" " -line set output mode to 'line'\n" " -list set output mode to 'list'\n" " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" #if defined(SQLITE_ENABLE_DESERIALIZE) " -maxsize N maximum size for a --deserialize database\n" #endif " -memtrace trace all memory allocations and deallocations\n" " -mmap N default mmap size set to N\n" #ifdef SQLITE_ENABLE_MULTIPLEX " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" " -nofollow refuse to open symbolic links to database files\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" " -readonly open the database read-only\n" " -separator SEP set output column separator. Default: '|'\n" #ifdef SQLITE_ENABLE_SORTER_REFERENCES " -sorterref SIZE sorter references threshold size\n" #endif " -stats print memory stats before each finalize\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" #ifdef SQLITE_ENABLE_VFSTRACE " -vfstrace enable tracing of all VFS calls\n" #endif #ifdef SQLITE_HAVE_ZLIB " -zip open the file as a ZIP Archive\n" | > > > | 19077 19078 19079 19080 19081 19082 19083 19084 19085 19086 19087 19088 19089 19090 19091 19092 19093 19094 19095 19096 19097 19098 19099 19100 19101 19102 19103 19104 19105 19106 19107 19108 19109 19110 19111 19112 19113 19114 19115 | " -[no]header turn headers on or off\n" #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) " -heap SIZE Size of heap for memsys3 or memsys5\n" #endif " -help show this message\n" " -html set output mode to HTML\n" " -interactive force interactive I/O\n" " -json set output mode to 'json'\n" " -line set output mode to 'line'\n" " -list set output mode to 'list'\n" " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" " -markdown set output mode to 'markdown'\n" #if defined(SQLITE_ENABLE_DESERIALIZE) " -maxsize N maximum size for a --deserialize database\n" #endif " -memtrace trace all memory allocations and deallocations\n" " -mmap N default mmap size set to N\n" #ifdef SQLITE_ENABLE_MULTIPLEX " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" " -nofollow refuse to open symbolic links to database files\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" " -readonly open the database read-only\n" " -separator SEP set output column separator. Default: '|'\n" #ifdef SQLITE_ENABLE_SORTER_REFERENCES " -sorterref SIZE sorter references threshold size\n" #endif " -stats print memory stats before each finalize\n" " -table set output mode to 'table'\n" " -version show SQLite version\n" " -vfs NAME use NAME as the default VFS\n" #ifdef SQLITE_ENABLE_VFSTRACE " -vfstrace enable tracing of all VFS calls\n" #endif #ifdef SQLITE_HAVE_ZLIB " -zip open the file as a ZIP Archive\n" |
| ︙ | ︙ | |||
19322 19323 19324 19325 19326 19327 19328 19329 19330 19331 19332 19333 19334 19335 |
data.mode = MODE_List;
}else if( strcmp(z,"-quote")==0 ){
data.mode = MODE_Quote;
}else if( strcmp(z,"-line")==0 ){
data.mode = MODE_Line;
}else if( strcmp(z,"-column")==0 ){
data.mode = MODE_Column;
}else if( strcmp(z,"-csv")==0 ){
data.mode = MODE_Csv;
memcpy(data.colSeparator,",",2);
#ifdef SQLITE_HAVE_ZLIB
}else if( strcmp(z,"-zip")==0 ){
data.openMode = SHELL_OPEN_ZIPFILE;
#endif
| > > > > > > | 19503 19504 19505 19506 19507 19508 19509 19510 19511 19512 19513 19514 19515 19516 19517 19518 19519 19520 19521 19522 |
data.mode = MODE_List;
}else if( strcmp(z,"-quote")==0 ){
data.mode = MODE_Quote;
}else if( strcmp(z,"-line")==0 ){
data.mode = MODE_Line;
}else if( strcmp(z,"-column")==0 ){
data.mode = MODE_Column;
}else if( strcmp(z,"-json")==0 ){
data.mode = MODE_Json;
}else if( strcmp(z,"-markdown")==0 ){
data.mode = MODE_Markdown;
}else if( strcmp(z,"-table")==0 ){
data.mode = MODE_Table;
}else if( strcmp(z,"-csv")==0 ){
data.mode = MODE_Csv;
memcpy(data.colSeparator,",",2);
#ifdef SQLITE_HAVE_ZLIB
}else if( strcmp(z,"-zip")==0 ){
data.openMode = SHELL_OPEN_ZIPFILE;
#endif
|
| ︙ | ︙ | |||
19539 19540 19541 19542 19543 19544 19545 19546 19547 19548 19549 19550 | output_reset(&data); data.doXdgOpen = 0; clearTempFile(&data); #if !SQLITE_SHELL_IS_UTF8 for(i=0; i<argcToFree; i++) free(argvToFree[i]); free(argvToFree); #endif /* Clear the global data structure so that valgrind will detect memory ** leaks */ memset(&data, 0, sizeof(data)); return rc; } | > | 19726 19727 19728 19729 19730 19731 19732 19733 19734 19735 19736 19737 19738 | output_reset(&data); data.doXdgOpen = 0; clearTempFile(&data); #if !SQLITE_SHELL_IS_UTF8 for(i=0; i<argcToFree; i++) free(argvToFree[i]); free(argvToFree); #endif free(data.colWidth); /* Clear the global data structure so that valgrind will detect memory ** leaks */ memset(&data, 0, sizeof(data)); return rc; } |
Changes to src/smtp.c.
| ︙ | ︙ | |||
1526 1527 1528 1529 1530 1531 1532 |
if( strcmp(zCmd,"capa")==0 ){
static const char *const azCap[] = {
"TOP", "USER", "UIDL",
};
int i;
pop3_print(pLog, "+OK");
for(i=0; i<sizeof(azCap)/sizeof(azCap[0]); i++){
| | | 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 |
if( strcmp(zCmd,"capa")==0 ){
static const char *const azCap[] = {
"TOP", "USER", "UIDL",
};
int i;
pop3_print(pLog, "+OK");
for(i=0; i<sizeof(azCap)/sizeof(azCap[0]); i++){
pop3_print(pLog, "%s", azCap[i]);
}
pop3_print(pLog, ".");
continue;
}
if( inAuth ){
if( strcmp(zCmd,"user")==0 ){
if( zA1==0 || zA2!=0 ) goto cmd_error;
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | 1 2 3 4 5 6 7 8 9 10 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.33.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other |
| ︙ | ︙ | |||
1158 1159 1160 1161 1162 1163 1164 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.33.0" #define SQLITE_VERSION_NUMBER 3033000 #define SQLITE_SOURCE_ID "2020-05-29 16:15:58 4e1db8e9a9ee370a398f13fd8546a520111b8cfb84460389535b5bc5bd9f4f82" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
38283 38284 38285 38286 38287 38288 38289 | ** ** 1. Checkpointer lock (ofst==1). ** 2. Write lock (ofst==0). ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). ** ** In other words, if this is a blocking lock, none of the locks that ** occur later in the above list than the lock being obtained may be | | > > > | 38283 38284 38285 38286 38287 38288 38289 38290 38291 38292 38293 38294 38295 38296 38297 38298 38299 38300 |
**
** 1. Checkpointer lock (ofst==1).
** 2. Write lock (ofst==0).
** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
**
** In other words, if this is a blocking lock, none of the locks that
** occur later in the above list than the lock being obtained may be
** held.
**
** It is not permitted to block on the RECOVER lock.
*/
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
(ofst!=2) /* not RECOVER */
&& (ofst!=1 || (p->exclMask|p->sharedMask)==0)
&& (ofst!=0 || (p->exclMask|p->sharedMask)<3)
&& (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
));
|
| ︙ | ︙ | |||
80833 80834 80835 80836 80837 80838 80839 |
/* If the VDBE has been run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
** if the VDBE has just been set to run but has not actually executed any
** instructions yet, leave the main database error information unchanged.
*/
if( p->pc>=0 ){
vdbeInvokeSqllog(p);
| > | > > > > | | > | 80836 80837 80838 80839 80840 80841 80842 80843 80844 80845 80846 80847 80848 80849 80850 80851 80852 80853 80854 80855 80856 80857 80858 80859 80860 80861 80862 80863 80864 80865 80866 80867 80868 80869 80870 80871 80872 80873 80874 80875 80876 80877 |
/* If the VDBE has been run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
** if the VDBE has just been set to run but has not actually executed any
** instructions yet, leave the main database error information unchanged.
*/
if( p->pc>=0 ){
vdbeInvokeSqllog(p);
if( db->pErr || p->zErrMsg ){
sqlite3VdbeTransferError(p);
}else{
db->errCode = p->rc;
}
if( p->runOnlyOnce ) p->expired = 1;
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
** to sqlite3_step(). For consistency (since sqlite3_step() was
** called), set the database error in this case as well.
*/
sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
}
/* Reset register contents and reclaim error message memory.
*/
#ifdef SQLITE_DEBUG
/* Execute assert() statements to ensure that the Vdbe.apCsr[] and
** Vdbe.aMem[] arrays have already been cleaned up. */
if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
if( p->aMem ){
for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
}
#endif
if( p->zErrMsg ){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
p->pResultSet = 0;
#ifdef SQLITE_DEBUG
p->nWrite = 0;
#endif
/* Save profiling information from this VDBE run.
*/
|
| ︙ | ︙ | |||
102030 102031 102032 102033 102034 102035 102036 |
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
** ephemeral table. */
if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
| | > | 102039 102040 102041 102042 102043 102044 102045 102046 102047 102048 102049 102050 102051 102052 102053 102054 102055 102056 102057 102058 102059 102060 102061 102062 102063 102064 |
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
** ephemeral table. */
if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
int iDb; /* Database idx for pTab */
ExprList *pEList = p->pEList;
int nExpr = pEList->nExpr;
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
/* Code an OP_Transaction and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<SQLITE_MAX_ATTACHED );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
assert(v); /* sqlite3GetVdbe() has always been previously called */
if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
/* The "x IN (SELECT rowid FROM table)" case */
int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
|
| ︙ | ︙ | |||
103274 103275 103276 103277 103278 103279 103280 | int regFree1 = 0; /* If non-zero free this temporary register */ int regFree2 = 0; /* If non-zero free this temporary register */ int r1, r2; /* Various register numbers */ Expr tempX; /* Temporary expression node */ int p5 = 0; assert( target>0 && target<=pParse->nMem ); | < | < < | 103284 103285 103286 103287 103288 103289 103290 103291 103292 103293 103294 103295 103296 103297 103298 |
int regFree1 = 0; /* If non-zero free this temporary register */
int regFree2 = 0; /* If non-zero free this temporary register */
int r1, r2; /* Various register numbers */
Expr tempX; /* Temporary expression node */
int p5 = 0;
assert( target>0 && target<=pParse->nMem );
assert( v!=0 );
expr_code_doover:
if( pExpr==0 ){
op = TK_NULL;
}else{
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
op = pExpr->op;
|
| ︙ | ︙ | |||
104107 104108 104109 104110 104111 104112 104113 |
** in register target.
*/
SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
assert( target>0 && target<=pParse->nMem );
| < > > | | 104114 104115 104116 104117 104118 104119 104120 104121 104122 104123 104124 104125 104126 104127 104128 104129 104130 104131 |
** in register target.
*/
SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
assert( target>0 && target<=pParse->nMem );
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
if( pParse->pVdbe==0 ) return;
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
if( inReg!=target ){
u8 op;
if( ExprHasProperty(pExpr,EP_Subquery) ){
op = OP_Copy;
}else{
op = OP_SCopy;
}
sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
|
| ︙ | ︙ | |||
114089 114090 114091 114092 114093 114094 114095 |
** aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized. The numbers generated here
** are based on typical values found in actual indices.
*/
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
| | | > | > > > > > > > | > > > > | | | 114097 114098 114099 114100 114101 114102 114103 114104 114105 114106 114107 114108 114109 114110 114111 114112 114113 114114 114115 114116 114117 114118 114119 114120 114121 114122 114123 114124 114125 114126 114127 114128 114129 114130 114131 114132 114133 114134 114135 114136 114137 |
** aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized. The numbers generated here
** are based on typical values found in actual indices.
*/
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
/* 10, 9, 8, 7, 6 */
static const LogEst aVal[] = { 33, 32, 30, 28, 26 };
LogEst *a = pIdx->aiRowLogEst;
LogEst x;
int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
int i;
/* Indexes with default row estimates should not have stat1 data */
assert( !pIdx->hasStat1 );
/* Set the first entry (number of rows in the index) to the estimated
** number of rows in the table, or half the number of rows in the table
** for a partial index.
**
** 2020-05-27: If some of the stat data is coming from the sqlite_stat1
** table but other parts we are having to guess at, then do not let the
** estimated number of rows in the table be less than 1000 (LogEst 99).
** Failure to do this can cause the indexes for which we do not have
** stat1 data to be ignored by the query planner. tag-20200527-1
*/
x = pIdx->pTable->nRowLogEst;
assert( 99==sqlite3LogEst(1000) );
if( x<99 ){
pIdx->pTable->nRowLogEst = x = 99;
}
if( pIdx->pPartIdxWhere!=0 ) x -= 10; assert( 10==sqlite3LogEst(2) );
a[0] = x;
/* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
** 6 and each subsequent value (if any) is 5. */
memcpy(&a[1], aVal, nCopy*sizeof(LogEst));
for(i=nCopy+1; i<=pIdx->nKeyCol; i++){
a[i] = 23; assert( 23==sqlite3LogEst(5) );
}
|
| ︙ | ︙ | |||
128403 128404 128405 128406 128407 128408 128409 |
** Convert a schema pointer into the iDb index that indicates
** which database file in db->aDb[] the schema refers to.
**
** If the same database is attached more than once, the first
** attached database is returned.
*/
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
| | | | | | > | 128423 128424 128425 128426 128427 128428 128429 128430 128431 128432 128433 128434 128435 128436 128437 128438 128439 128440 128441 128442 128443 128444 128445 128446 128447 128448 |
** Convert a schema pointer into the iDb index that indicates
** which database file in db->aDb[] the schema refers to.
**
** If the same database is attached more than once, the first
** attached database is returned.
*/
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
int i = -32768;
/* If pSchema is NULL, then return -32768. This happens when code in
** expr.c is trying to resolve a reference to a transient table (i.e. one
** created by a sub-select). In this case the return value of this
** function should never be used.
**
** We return -32768 instead of the more usual -1 simply because using
** -32768 as the incorrect index into db->aDb[] is much
** more likely to cause a segfault than -1 (of course there are assert()
** statements too, but it never hurts to play the odds) and
** -32768 will still fit into a 16-bit signed integer.
*/
assert( sqlite3_mutex_held(db->mutex) );
if( pSchema ){
for(i=0; 1; i++){
assert( i<db->nDb );
if( db->aDb[i].pSchema==pSchema ){
break;
|
| ︙ | ︙ | |||
128968 128969 128970 128971 128972 128973 128974 |
Expr *pWhere, /* the WHERE clause */
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
u32 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit /* LIMIT value. NULL means not used */
){
| | | | 128989 128990 128991 128992 128993 128994 128995 128996 128997 128998 128999 129000 129001 129002 129003 129004 129005 |
Expr *pWhere, /* the WHERE clause */
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
u32 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit /* LIMIT value. NULL means not used */
){
Select *pNew, *pAllocated;
Select standin;
pAllocated = pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
if( pNew==0 ){
assert( pParse->db->mallocFailed );
pNew = &standin;
}
if( pEList==0 ){
pEList = sqlite3ExprListAppend(pParse, 0,
sqlite3Expr(pParse->db,TK_ASTERISK,0));
|
| ︙ | ︙ | |||
129004 129005 129006 129007 129008 129009 129010 |
pNew->pWith = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = 0;
#endif
if( pParse->db->mallocFailed ) {
clearSelect(pParse->db, pNew, pNew!=&standin);
| | < | | 129025 129026 129027 129028 129029 129030 129031 129032 129033 129034 129035 129036 129037 129038 129039 129040 129041 129042 129043 |
pNew->pWith = 0;
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = 0;
#endif
if( pParse->db->mallocFailed ) {
clearSelect(pParse->db, pNew, pNew!=&standin);
pAllocated = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
}
return pAllocated;
}
/*
** Delete the given Select structure and all of its substructures.
*/
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
|
| ︙ | ︙ | |||
224818 224819 224820 224821 224822 224823 224824 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 224838 224839 224840 224841 224842 224843 224844 224845 224846 224847 224848 224849 224850 224851 224852 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2020-05-29 16:15:58 4e1db8e9a9ee370a398f13fd8546a520111b8cfb84460389535b5bc5bd9f4f82", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
| ︙ | ︙ | |||
229601 229602 229603 229604 229605 229606 229607 | #endif return rc; } #endif /* SQLITE_CORE */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ | | | | 229621 229622 229623 229624 229625 229626 229627 229628 229629 229630 229631 229632 229633 229634 |
#endif
return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
#if __LINE__!=229628
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID "2020-05-29 16:15:58 4e1db8e9a9ee370a398f13fd8546a520111b8cfb84460389535b5bc5bd9falt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/
|
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
119 120 121 122 123 124 125 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.33.0" #define SQLITE_VERSION_NUMBER 3033000 #define SQLITE_SOURCE_ID "2020-05-29 16:15:58 4e1db8e9a9ee370a398f13fd8546a520111b8cfb84460389535b5bc5bd9f4f82" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ |
Changes to src/tar.c.
| ︙ | ︙ | |||
464 465 466 467 468 469 470 | ** If the RID object does not exist in the repository, then ** pTar is zeroed. ** ** zDir is a "synthetic" subdirectory which all files get ** added to as part of the tarball. It may be 0 or an empty string, in ** which case it is ignored. The intention is to create a tarball which ** politely expands into a subdir instead of filling your current dir | | | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | ** If the RID object does not exist in the repository, then ** pTar is zeroed. ** ** zDir is a "synthetic" subdirectory which all files get ** added to as part of the tarball. It may be 0 or an empty string, in ** which case it is ignored. The intention is to create a tarball which ** politely expands into a subdir instead of filling your current dir ** with source files. For example, pass an artifact hash or "ProjectName". ** */ void tarball_of_checkin( int rid, /* The RID of the checkin from which to form a tarball */ Blob *pTar, /* Write the tarball into this blob */ const char *zDir, /* Directory prefix for all file added to tarball */ Glob *pInclude, /* Only add files matching this pattern */ |
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
cgi_printf(" %s", UNPUB_TAG);
}
}
/*
** Generate a hyperlink to a version.
*/
| | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
cgi_printf(" %s", UNPUB_TAG);
}
}
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_version(const char *zVerHash){
if( g.perm.Hyperlink ){
@ %z(chref("timelineHistLink","%R/info/%!S",zVerHash))[%S(zVerHash)]</a>
}else{
@ <span class="timelineHistDsp">[%S(zVerHash)]</span>
}
}
/*
** Generate a hyperlink to a date & time.
*/
void hyperlink_to_date(const char *zDate, const char *zSuffix){
|
| ︙ | ︙ | |||
99 100 101 102 103 104 105 | #define TIMELINE_GRAPH 0x0000008 /* Compute a graph */ #define TIMELINE_DISJOINT 0x0000010 /* Elements are not contiguous */ #define TIMELINE_FCHANGES 0x0000020 /* Detail file changes */ #define TIMELINE_BRCOLOR 0x0000040 /* Background color by branch name */ #define TIMELINE_UCOLOR 0x0000080 /* Background color by user */ #define TIMELINE_FRENAMES 0x0000100 /* Detail only file name changes */ #define TIMELINE_UNHIDE 0x0000200 /* Unhide check-ins with "hidden" tag */ | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #define TIMELINE_GRAPH 0x0000008 /* Compute a graph */ #define TIMELINE_DISJOINT 0x0000010 /* Elements are not contiguous */ #define TIMELINE_FCHANGES 0x0000020 /* Detail file changes */ #define TIMELINE_BRCOLOR 0x0000040 /* Background color by branch name */ #define TIMELINE_UCOLOR 0x0000080 /* Background color by user */ #define TIMELINE_FRENAMES 0x0000100 /* Detail only file name changes */ #define TIMELINE_UNHIDE 0x0000200 /* Unhide check-ins with "hidden" tag */ #define TIMELINE_SHOWRID 0x0000400 /* Show RID values in addition to hashes */ #define TIMELINE_BISECT 0x0000800 /* Show supplimental bisect information */ #define TIMELINE_COMPACT 0x0001000 /* Use the "compact" view style */ #define TIMELINE_VERBOSE 0x0002000 /* Use the "detailed" view style */ #define TIMELINE_MODERN 0x0004000 /* Use the "modern" view style */ #define TIMELINE_COLUMNAR 0x0008000 /* Use the "columns" view style */ #define TIMELINE_CLASSIC 0x0010000 /* Use the "classic" view style */ #define TIMELINE_VIEWS 0x001f000 /* Mask for all of the view styles */ |
| ︙ | ︙ | |||
227 228 229 230 231 232 233 | } /* ** Output a timeline in the web format given a query. The query ** should return these columns: ** ** 0. rid | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
}
/*
** Output a timeline in the web format given a query. The query
** should return these columns:
**
** 0. rid
** 1. artifact hash
** 2. Date/Time
** 3. Comment string
** 4. User
** 5. True if is a leaf
** 6. background color
** 7. type ("ci", "w", "t", "e", "g", "f", "div")
** 8. list of symbolic tags.
|
| ︙ | ︙ | |||
531 532 533 534 535 536 537 |
if( tmFlags & TIMELINE_COMPACT ){
@ <span class='timelineCompactComment' data-id='%d(rid)'>
}else{
@ <span class='timeline%s(zStyle)Comment'>
}
if( (tmFlags & TIMELINE_CLASSIC)!=0 ){
if( zType[0]=='c' ){
| | | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
if( tmFlags & TIMELINE_COMPACT ){
@ <span class='timelineCompactComment' data-id='%d(rid)'>
}else{
@ <span class='timeline%s(zStyle)Comment'>
}
if( (tmFlags & TIMELINE_CLASSIC)!=0 ){
if( zType[0]=='c' ){
hyperlink_to_version(zUuid);
if( isLeaf ){
if( db_exists("SELECT 1 FROM tagxref"
" WHERE rid=%d AND tagid=%d AND tagtype>0",
rid, TAG_CLOSED) ){
@ <span class="timelineLeaf">Closed-Leaf:</span>
}else{
@ <span class="timelineLeaf">Leaf:</span>
}
}
}else if( zType[0]=='e' && tagid ){
hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
}else if( (tmFlags & TIMELINE_ARTID)!=0 ){
hyperlink_to_version(zUuid);
}
if( tmFlags & TIMELINE_SHOWRID ){
int srcId = delta_source_rid(rid);
if( srcId ){
@ (%d(rid)←%d(srcId))
}else{
@ (%d(rid))
|
| ︙ | ︙ | |||
3022 3023 3024 3025 3026 3027 3028 |
}
@ <h1>This Day In History For %h(zToday)</h1>
z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);
style_submenu_element("Yesterday", "%R/thisdayinhistory?today=%t", z);
z = db_text(0, "SELECT date(%Q,'+1 day')", zToday);
style_submenu_element("Tomorrow", "%R/thisdayinhistory?today=%t", z);
zStartOfProject = db_text(0,
| | | 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 |
}
@ <h1>This Day In History For %h(zToday)</h1>
z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);
style_submenu_element("Yesterday", "%R/thisdayinhistory?today=%t", z);
z = db_text(0, "SELECT date(%Q,'+1 day')", zToday);
style_submenu_element("Tomorrow", "%R/thisdayinhistory?today=%t", z);
zStartOfProject = db_text(0,
"SELECT datetime(min(mtime),toLocal(),'startofday') FROM event;"
);
timeline_temp_table();
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
for(i=0; i<sizeof(aYearsAgo)/sizeof(aYearsAgo[0]); i++){
int iAgo = aYearsAgo[i];
char *zThis = db_text(0, "SELECT date(%Q,'-%d years')", zToday, iAgo);
Blob sql;
|
| ︙ | ︙ |
Changes to src/tktsetup.c.
| ︙ | ︙ | |||
446 447 448 449 450 451 452 |
0,
40
);
}
static const char zDefaultView[] =
@ <table cellpadding="5">
| | | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
0,
40
);
}
static const char zDefaultView[] =
@ <table cellpadding="5">
@ <tr><td class="tktDspLabel">Ticket Hash:</td>
@ <th1>
@ if {[info exists tkt_uuid]} {
@ html "<td class='tktDspValue' colspan='3'>"
@ copybtn hash-tk 0 $tkt_uuid 2
@ if {[hascap s]} {
@ html " ($tkt_id)"
@ }
|
| ︙ | ︙ |
Changes to src/util.c.
| ︙ | ︙ | |||
414 415 416 417 418 419 420 | #endif } /* ** Returns TRUE if zSym is exactly HNAME_LEN_SHA1 or HNAME_LEN_K256 ** bytes long and contains only lower-case ASCII hexadecimal values. */ | | | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 |
#endif
}
/*
** Returns TRUE if zSym is exactly HNAME_LEN_SHA1 or HNAME_LEN_K256
** bytes long and contains only lower-case ASCII hexadecimal values.
*/
int fossil_is_artifact_hash(const char *zSym){
int sz = zSym ? (int)strlen(zSym) : 0;
return (HNAME_LEN_SHA1==sz || HNAME_LEN_K256==sz) && validate16(zSym, sz);
}
/*
** Return true if the input string is NULL or all whitespace.
** Return false if the input string contains text.
|
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
612 613 614 615 616 617 618 | ** If the RID object does not exist in the repository, then ** pZip is zeroed. ** ** zDir is a "synthetic" subdirectory which all zipped files get ** added to as part of the zip file. It may be 0 or an empty string, ** in which case it is ignored. The intention is to create a zip which ** politely expands into a subdir instead of filling your current dir | | | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | ** If the RID object does not exist in the repository, then ** pZip is zeroed. ** ** zDir is a "synthetic" subdirectory which all zipped files get ** added to as part of the zip file. It may be 0 or an empty string, ** in which case it is ignored. The intention is to create a zip which ** politely expands into a subdir instead of filling your current dir ** with source files. For example, pass a commit hash or "ProjectName". ** */ static void zip_of_checkin( int eType, /* Type of archive (ZIP or SQLAR) */ int rid, /* The RID of the checkin to build the archive from */ Blob *pZip, /* Write the archive content into this blob */ const char *zDir, /* Top-level directory of the archive */ |
| ︙ | ︙ |
Changes to test/amend.test.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 |
}
proc manifest_comment {comment} {
string map [list { } {\\s} \n {\\n} \r {\\r}] $comment
}
proc uuid_from_commit {res var} {
| | | | | | | | | | | | | | 24 25 26 27 28 29 30 31 32 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 |
}
proc manifest_comment {comment} {
string map [list { } {\\s} \n {\\n} \r {\\r}] $comment
}
proc uuid_from_commit {res var} {
upvar $var HASH
regexp {^New_Version: ([0-9a-f]{40})[0-9a-f]*$} $res m HASH
}
proc uuid_from_branch {res var} {
upvar $var HASH
regexp {^New branch: ([0-9a-f]{40})[0-9a-f]*$} $res m HASH
}
proc uuid_from_checkout {var} {
global RESULT
upvar $var HASH
fossil status
regexp {checkout:\s+([0-9a-f]{40})[0-9a-f]*} $RESULT m HASH
}
# Make sure we are not in an open repository and initialize new repository
test_setup
########################################
# Setup: Add file and commit #
########################################
if {![uuid_from_checkout HASHINIT]} {
test amend-checkout-failure false
test_cleanup_then_return
}
write_file datafile "data"
fossil add datafile
fossil commit -m "c1"
if {![uuid_from_commit $RESULT HASH]} {
test amend-setup-failure false
test_cleanup_then_return
}
########################################
# Test: -branch #
########################################
set HASHB HASHB
write_file datafile "data.file"
fossil commit -m "c2"
if {![uuid_from_commit $RESULT HASHB]} {
test amend-branch.setup false
}
fossil amend $HASHB -branch amended-branch
test amend-branch-1.1 {[regexp {tags:\s+amended-branch} $RESULT]}
fossil branch ls
test amend-branch-1.2 {[string first "* amended-branch" $RESULT] != -1}
fossil tag list
test amend-branch-1.3 {[string first amended-branch $RESULT] != -1}
fossil tag list --raw $HASHB
test amend-branch-1.4 {[string first "branch=amended-branch" $RESULT] != -1}
test amend-branch-1.5 {[string first "sym-amended-branch" $RESULT] != -1}
fossil timeline -n 1
test amend-branch-1.6 {[string match {*Move*to*branch*amended-branch*} $RESULT]}
########################################
# Test: -bgcolor #
|
| ︙ | ︙ | |||
100 101 102 103 104 105 106 |
acf #acf
123 #123
#1234 #1234
1234 1234
123456 #123456
} {
incr tc
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 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 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
acf #acf
123 #123
#1234 #1234
1234 1234
123456 #123456
} {
incr tc
fossil amend $HASH -bgcolor $color
test amend-bgcolor-1.$tc.a {[string match "*uuid:*$HASH*" $RESULT]}
fossil tag list --raw $HASH
test amend-bgcolor-1.$tc.b {[string first "bgcolor=$result" $RESULT] != -1}
fossil timeline -n 1
test amend-bgcolor-1.$tc.c {
[string match "*Change*background*color*to*\"$result\"*" $RESULT]
}
if {[artifact_from_timeline $RESULT artid]} {
fossil artifact $artid
test amend-bgcolor-1.$tc.d {
[string match "*T +bgcolor $HASH* $result*" $RESULT]
}
} else {
if {$VERBOSE} { protOut "No artifact found in timeline output" }
test amend-bgcolor-1.$tc.d false
}
}
fossil amend $HASH -bgcolor {}
test amend-bgcolor-2.1 {[string match "*uuid:*$HASH*" $RESULT]}
fossil tag list --raw $HASH
test amend-bgcolor-2.2 {
[string first "bgcolor=" $RESULT] == -1 &&
[string first "bgcolor" $RESULT] != -1
}
fossil timeline -n 1
test amend-bgcolor-2.3 {[string match "*Cancel*background*color.*" $RESULT]}
if {[artifact_from_timeline $RESULT artid]} {
fossil artifact $artid
test amend-bgcolor-2.4 {[string match "*T -bgcolor $HASH*" $RESULT]}
} else {
if {$VERBOSE} { protOut "No artifact found in timeline output" }
test amend-bgcolor-2.4 false
}
########################################
# Test: -branchcolor #
########################################
set HASH2 HASH2
fossil branch new brclr $HASH
if {![uuid_from_branch $RESULT HASH2]} {
test amend-branchcolor.setup false
}
fossil update $HASH2
fossil amend $HASH2 -branchcolor yellow
test amend-branchcolor-1.1 {[string match "*uuid:*$HASH2*" $RESULT]}
fossil tag ls --raw $HASH2
test amend-branchcolor-1.2 {[string first "bgcolor=yellow" $RESULT] != -1}
fossil timeline -n 1
test amend-branchcolor-1.3 {
[string match {*Change*branch*background*color*to*"yellow".*} $RESULT]
}
if {[regexp {(?x)[0-9]{2}(?::[0-9]{2}){2}\s+\[([0-9a-f]+)]} $RESULT m artid]} {
fossil artifact $artid
test amend-branchcolor-1.4 {
[string match "*T \*bgcolor $HASH2* yellow*" $RESULT]
}
} else {
if {$VERBOSE} { protOut "No artifact found in timeline output" }
test amend-branchcolor-1.4 false
}
set HASHN HASHN
write_file datafile "brclr"
fossil commit -m "brclr"
if {![uuid_from_commit $RESULT HASHN]} {
test amend-branchcolor-propagating.setup false
}
write_file datafile "bc1"
fossil commit -m "mc1"
write_file datafile "bc2"
fossil commit -m "mc2"
fossil amend $HASHN -branchcolor deadbe
test amend-branchcolor-2.1 {[string match "*uuid:*$HASHN*" $RESULT]}
fossil tag ls --raw current
test amend-branchcolor-2.2 {[string first "bgcolor=#deadbe" $RESULT] != -1}
fossil timeline -n 1
test amend-branchcolor-2.3 {
[string match {*Change*branch*background*color*to*"#deadbe".*} $RESULT]
}
########################################
# Test: -author #
########################################
fossil amend $HASH -author author-test
test amend-author-1.1 {[string match {*comment:*(user:*author-test)*} $RESULT]}
fossil tag ls --raw $HASH
test amend-author-1.2 {[string first "user=author-test" $RESULT] != -1}
fossil timeline -n 1
test amend-author-1.3 {[string match {*Change*user*to*"author-test".*} $RESULT]}
########################################
# Test: -date #
########################################
set timestamp [clock scan yesterday]
set date [clock format $timestamp -format "%Y-%m-%d" -gmt 1]
set time [clock format $timestamp -format "%H:%M:%S" -gmt 1]
set datetime "$date $time"
fossil amend $HASHINIT -date $datetime
test amend-date-1.1 {[string match "*uuid:*$HASHINIT*$datetime*" $RESULT]}
fossil tag ls --raw $HASHINIT
test amend-date-1.2 {[string first "date=$datetime" $RESULT] != -1}
fossil timeline -n 1
test amend-date-1.3 {[string match "*Timestamp*$date*$time*" $RESULT]}
set badformats {
"%+"
"%Y-%m-%d %H:%M%:%S %Z"
"%d/%m/%Y %H:%M%:%S %Z"
"%d/%m/%Y %H:%M%:%S"
"%d/%m/%Y"
}
set sc 0
foreach badformat $badformats {
incr sc
set datetime [clock format $timestamp -format $badformat -gmt 1]
fossil amend $HASHINIT -date $datetime -expectError
test amend-date-2.$sc {[string first "YYYY-MM-DD HH:MM:SS" $RESULT] != -1}
}
########################################
# Test: -hide #
########################################
set HASHH HASHH
fossil revert
fossil update trunk
fossil branch new tohide current
if {![uuid_from_branch $RESULT HASHH]} {
test amend-hide-setup false
}
fossil amend $HASHH -hide
test amend-hide-1.1 {[string match "*uuid:*$HASHH*" $RESULT]}
fossil tag ls --raw $HASHH
test amend-hide-1.2 {[string first "hidden" $RESULT] != -1}
fossil timeline -n 1
test amend-hide-1.3 {[string match {*Add*propagating*"hidden".*} $RESULT]}
########################################
# Test: -close #
########################################
set HASHC HASHC
fossil branch new cllf $HASH
if {![uuid_from_branch $RESULT HASHC]} {
test amend-close.setup false
}
fossil update $HASHC
fossil amend $HASHC -close
test amend-close-1.1.a {[string match "*uuid:*$HASHC*" $RESULT]}
test amend-close-1.1.b {
[string match "*comment:*Create*new*branch*named*\"cllf\"*" $RESULT]
}
fossil tag ls --raw $HASHC
test amend-close-1.2 {[string first "closed" $RESULT] != -1}
fossil timeline -n 1
test amend-close-1.3 {[string match {*Mark*"Closed".*} $RESULT]}
write_file datafile "cllf"
fossil commit -m "should fail" -expectError
test amend-close-2 {[string first "closed leaf" $RESULT] != -1}
set HASH3 HASH3
fossil revert
fossil update trunk
write_file datafile "cb"
fossil commit -m "closed-branch" --branch "closebranch"
if {![uuid_from_commit $RESULT HASH3]} {
test amend-close-3.setup false
}
write_file datafile "b1"
fossil commit -m "m1"
write_file datafile "b2"
fossil commit -m "m2"
fossil amend $HASH3 --close
test amend-close-3.1 {[string match "*uuid:*$HASH3*" $RESULT]}
fossil tag ls --raw current
test amend-close-3.2 {[string first "closed" $RESULT] != -1}
fossil timeline -n 1
test amend-close-3.3 {
[string match "*Add*propagating*\"closed\".*" $RESULT]
}
write_file datafile "changed"
|
| ︙ | ︙ | |||
308 309 310 311 312 313 314 |
}
foreach res $result {
append t1exp ", $res"
append t2exp "sym-$res*"
append t3exp "Add*tag*\"$res\".*"
append t5exp "Cancel*tag*\"$res\".*"
}
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
}
foreach res $result {
append t1exp ", $res"
append t2exp "sym-$res*"
append t3exp "Add*tag*\"$res\".*"
append t5exp "Cancel*tag*\"$res\".*"
}
eval fossil amend $HASH $tags
test amend-tag-$tc.1 {[string match "*uuid:*$HASH*tags:*$t1exp*" $RESULT]}
fossil tag ls --raw $HASH
test amend-tag-$tc.2 {[string match $t2exp $RESULT]}
fossil timeline -n 1
test amend-tag-$tc.3 {[string match $t3exp $RESULT]}
eval fossil amend $HASH $cancels
test amend-tag-$tc.4 {![string match "*tags:*$t1exp*" $RESULT]}
fossil timeline -n 1
test amend-tag-$tc.5 {[string match $t5exp $RESULT]}
}
########################################
# Test: -comment #
########################################
proc prep-test {comment content} {
global HASH RESULT
fossil revert
fossil update trunk
write_file datafile $comment
fossil commit -m $content
if {![uuid_from_commit $RESULT HASH]} {
set HASH ""
}
}
proc test-comment {name HASH comment} {
global VERBOSE RESULT
test amend-comment-$name.1 {
[string match "*uuid:*$HASH*comment:*$comment*" $RESULT]
}
fossil timeline -n 1
if {[artifact_from_timeline $RESULT artid]} {
fossil artifact $artid
test amend-comment-$name.2 {
[string match "*T +comment $HASH* *[manifest_comment $comment]*" $RESULT]
}
} else {
if {$VERBOSE} { protOut "No artifact found in timeline output: $RESULT" }
test amend-comment-$name.2 false
}
fossil timeline -n 1
test amend-comment-$name.3 {
[string match "*[short_uuid $HASH]*Edit*check-in*comment.*" $RESULT]
}
fossil info $HASH
test amend-comment-$name.4 {
[string match "*uuid:*$HASH*comment:*$comment*" $RESULT]
}
}
prep-test "revision 1" "revision 1"
fossil amend $HASH -comment "revised revision 1"
test-comment 1 $HASH "revised revision 1"
prep-test "revision 2" "revision 2"
fossil amend $HASH -m "revised revision 2 with -m"
test-comment 2 $HASH "revised revision 2 with -m"
prep-test "revision 3" "revision 3"
write_file commitmsg "revision 3 revised"
fossil amend $HASH -message-file commitmsg
test-comment 3 $HASH "revision 3 revised"
prep-test "revision 4" "revision 4"
write_file commitmsg "revision 4 revised with -M"
fossil amend $HASH -M commitmsg
test-comment 4 $HASH "revision 4 revised with -M"
prep-test "final comment" "final content"
if {[catch {exec which ed} result]} {
if {$VERBOSE} { protOut "Install ed for interactive comment test: $result" }
test-comment 5 $HASH "ed required for interactive edit"
} else {
fossil settings editor "ed -s"
set comment "interactive edited comment"
fossil_maybe_answer "a\n$comment\n.\nw\nq\n" amend $HASH --edit-comment
test-comment 5 $HASH $comment
}
########################################
# Test: NULL hash #
########################################
fossil amend {} -close -expectError
test amend-null-uuid {$CODE && [string first "no such check-in" $RESULT] != -1}
###############################################################################
test_cleanup
|
Changes to tools/email-sender.tcl.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 |
msg TXT
);
}
while {1} {
db transaction immediate {
set n 0
db eval {SELECT msg FROM email} {
| > > > > | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
msg TXT
);
}
while {1} {
db transaction immediate {
set n 0
db eval {SELECT msg FROM email} {
set pipe $PIPE
if {[regexp {\nFrom:[^\n]*<([^>]+)>} $msg all addr]} {
append pipe " -f $addr"
}
set out [open |$pipe w]
puts -nonewline $out $msg
flush $out
close $out
incr n
}
if {$n>0} {
db eval {DELETE FROM email}
|
| ︙ | ︙ |
Changes to win/Makefile.PellesCGMake.
| ︙ | ︙ | |||
81 82 83 84 85 86 87 | UTILS_OBJ=$(UTILS:.exe=.obj) UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) # define the SQLite files, which need special flags on compile SQLITESRC=sqlite3.c ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | UTILS_OBJ=$(UTILS:.exe=.obj) UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) # define the SQLite files, which need special flags on compile SQLITESRC=sqlite3.c ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DSQLITE_WIN32_NO_ANSI # define the SQLite shell files, which need special flags on compile SQLITESHELLSRC=shell.c ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf)) SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj)) SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen # define the th scripting files, which need special flags on compile THSRC=th.c th_lang.c ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf)) THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj)) # define the zlib files, needed by this compile |
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen SRC = add_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O RC=$(DMDIR)\bin\rcc |
| ︙ | ︙ |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
2483 2484 2485 2486 2487 2488 2489 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
| < | 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_USE_ALLOCA \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
|
| ︙ | ︙ | |||
2514 2515 2516 2517 2518 2519 2520 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
| < | 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 |
-DSQLITE_DQS=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_MEMSTATUS=0 \
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
-DSQLITE_OMIT_DECLTYPE \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_USE_ALLOCA \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
|
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
281 282 283 284 285 286 287 |
/DSQLITE_DQS=0 \
/DSQLITE_THREADSAFE=0 \
/DSQLITE_DEFAULT_MEMSTATUS=0 \
/DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
/DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
/DSQLITE_OMIT_DECLTYPE \
/DSQLITE_OMIT_DEPRECATED \
| < | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
/DSQLITE_DQS=0 \
/DSQLITE_THREADSAFE=0 \
/DSQLITE_DEFAULT_MEMSTATUS=0 \
/DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
/DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
/DSQLITE_OMIT_DECLTYPE \
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_USE_ALLOCA \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
|
| ︙ | ︙ | |||
309 310 311 312 313 314 315 |
/DSQLITE_DQS=0 \
/DSQLITE_THREADSAFE=0 \
/DSQLITE_DEFAULT_MEMSTATUS=0 \
/DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
/DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
/DSQLITE_OMIT_DECLTYPE \
/DSQLITE_OMIT_DEPRECATED \
| < | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
/DSQLITE_DQS=0 \
/DSQLITE_THREADSAFE=0 \
/DSQLITE_DEFAULT_MEMSTATUS=0 \
/DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
/DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
/DSQLITE_OMIT_DECLTYPE \
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_USE_ALLOCA \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
|
| ︙ | ︙ |
Changes to www/concepts.wiki.
| ︙ | ︙ | |||
78 79 80 81 82 83 84 | is a duplicate of a remote repository. Communication between repositories is via HTTP. Remote repositories are identified by URL. You can also point a web browser at a repository and get human-readable status, history, and tracking information about the project. | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | is a duplicate of a remote repository. Communication between repositories is via HTTP. Remote repositories are identified by URL. You can also point a web browser at a repository and get human-readable status, history, and tracking information about the project. <h3><a id="artifacts"></a>2.1 Identification Of Artifacts</h3> A particular version of a particular file is called an "artifact". Each artifact has a universally unique name which is the <a href="http://en.wikipedia.org/wiki/SHA1">SHA1</a> or <a href="http://en.wikipedia.org/wiki/SHA3">SHA3-256</a> hash of the content of that file expressed as either 40 or 64 characters of lower-case hexadecimal. (See the [./hashpolicy.wiki|hash policy |
| ︙ | ︙ |
Changes to www/fiveminutes.wiki.
| ︙ | ︙ | |||
56 57 58 59 60 61 62 | otherwise just the listed file(s) will be checked in. <h2>Compare two revisions of a file</h2> <p>If you wish to compare the last revision of a file and its checked out version in your work directory:</p> <p>fossil gdiff myfile.c</p> <p>If you wish to compare two different revisions of a file in the repository:</p> | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | otherwise just the listed file(s) will be checked in. <h2>Compare two revisions of a file</h2> <p>If you wish to compare the last revision of a file and its checked out version in your work directory:</p> <p>fossil gdiff myfile.c</p> <p>If you wish to compare two different revisions of a file in the repository:</p> <p>fossil finfo myfile: Note the first hash, which is the hash of the commit when the file was committed</p> <p>fossil gdiff --from HASH#1 --to HASH#2 myfile.c</p> <h2>Cancel changes and go back to previous revision</h2> <p>fossil revert myfile.c</p> <p>Fossil does not prompt when reverting a file. It simply reminds the user about the "undo" command, just in case the revert was a mistake.</p> |
Changes to www/fossil-v-git.wiki.
| ︙ | ︙ | |||
38 39 40 41 42 43 44 |
<tr>
<td>File versioning only</td>
<td>VCS, tickets, wiki, docs, notes, forum, UI,
[https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]</td>
<td><a href="#features">2.1 ↓</a></td>
</tr>
<tr>
| | | | | | 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 |
<tr>
<td>File versioning only</td>
<td>VCS, tickets, wiki, docs, notes, forum, UI,
[https://en.wikipedia.org/wiki/Role-based_access_control|RBAC]</td>
<td><a href="#features">2.1 ↓</a></td>
</tr>
<tr>
<td>Sprawling and inefficient</td>
<td>Self-contained and efficient</td>
<td><a href="#efficient">2.2 ↓</a></td>
</tr>
<tr>
<td>One-off custom pile-of-files data store</td>
<td>[https://sqlite.org/famous.html|The most popular database in the world]</td>
<td><a href="#durable">2.3 ↓</a></td>
</tr>
<tr>
<td>Runs natively on POSIX systems only</td>
<td>Native on common desktop & server platforms</td>
<td><a href="#portable">2.4 ↓</a></td>
</tr>
<tr>
<td>Bazaar-style development</td>
<td>Cathedral-style development</td>
<td><a href="#devorg">2.5.1 ↓</a></td>
</tr>
|
| ︙ | ︙ |
Changes to www/hashes.md.
1 2 3 4 | # Hashes: Fossil Artifact Identification All artifacts in Fossil are identified by a unique hash, currently using [the SHA3 algorithm by default][hpol], but historically using the SHA1 | | < > | < | | > | < < | > > | | | | < < < > > > | | | | > < | > > | < < > | > > > > | > > > > > | > > > > | > > | > | | | < < < < < < < | | > | < > > > | < | | | < | < < < < | > | | > | < < > | < > > | | | | | < < > | > > > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 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 | # Hashes: Fossil Artifact Identification All artifacts in Fossil are identified by a unique hash, currently using [the SHA3 algorithm by default][hpol], but historically using the SHA1 algorithm: <table border="1" cellspacing="0" cellpadding="10"> <tr><th>Algorithm<</th><th>Raw Bits</th> <th>Hexadecimal digits</th></tr> <tr><td>SHA3-256</td> <td>256</td> <td>64</td></tr> <tr><td>SHA1</td> <td>160</td> <td>40</td></tr> </table> There are many types of artifacts in Fossil: commits (a.k.a. check-ins), tickets, ticket comments, wiki articles, forum postings, file data belonging to check-ins, etc. ([More info...](./concepts.wiki#artifacts)). There is a loose hierarchy of terms used instead of “hash” in various parts of the Fossil UI, which we cover in the sections below. ## Names Several Fossil interfaces accept [a wide variety of check-in names][cin]: commit artifact hashes, ISO8601 date strings, branch names, etc. Fossil interfaces that accept any of these options usually document the parameter as “NAME”, so we will use that form to refer to this specialized use. Artifact hashes are only one of many different types of NAME. We use the broad term “NAME” to refer to the whole class of options. We use more specific terms when we mean one particular type of NAME. ## Versions When an artifact hash refers to a specific commit, Fossil sometimes calls it a “VERSION,” a “commit ID,” or a “check-in ID.” We may eventually settle on one of these terms, but all three are currently in common use within Fossil’s docs, UI, and programming interfaces. A VERSION is a specific type of artifact hash, distinct from, let us say, a wiki article artifact hash. A unique prefix of a VERSION hash is itself a VERSION. That is, if your repository has exactly one commit artifact with a hash prefix of “abc123”, then that is a valid version string as long as it remains unambiguous. ## <a id="uvh"></a>UUIDs Fossil uses the term “UUID” as a short alias for “artifact hash” in its internals. There are a few places where this leaks out into external interfaces, which we cover in the sections below. Going forward, we prefer one of the terms above in public interfaces instead. Whether this short alias is correct is debateable. One argument is that since "UUID" is an acronym for “Univerially Unique Identifier,” and both SHA1 and SHA3-256 are larger and stronger than the 128-bit algorithms used by “proper” UUIDs, Fossil artifact hashes are *more universally unique*. It is therefore quibbling to say that Fossil UUIDs are not actually UUIDs. One wag suggested that Fossil artifact hashes be called MUIDs: multiversally unique IDs. The common counterargument is that the acronym “UUID” was created for [a particular type of universally-unique ID][uuid], with particular ASCII and bitfield formats, and with particular meaning given to certain of its bits. In that sense, no Fossil “UUID” can be used as a proper UUID. Be warned: attempting to advance the second position on the Fossil discussion forum will get you nowhere at this late date. We’ve had the debates, we’ve done the engineering, and we’ve made our evaluation. It’s a settled matter: internally within Fossil, “UUID” is defined as in this section’s leading paragraph. To those who remain unconvinced, “fixing” this would require touching almost every source code file in Fossil in a total of about a thousand separate locations. (Not exaggeration, actual data.) This would be a massive undertaking simply to deal with a small matter of terminology, with a high risk of creating bugs and downstream incompatibilities. Therefore, we are highly unlikely to change this ourselves, and we are also unlikely to accept a patch that attempts to fix it. ### Repository DB Schema The primary place where you find "UUID" in Fossil is in the `blob.uuid` table column, in code dealing with that column, and in code manipulating *other* data that *refers* to that column. This is a key lookup column in the most important Fossil DB table, so it influences broad swaths of the Fossil internals. For example, C code that refers to SQL result data on `blob.uuid` usually calls the variable `zUuid`. That value may then be inserted into a table like `ticket.tkt_uuid`, creating a reference back to `blob.uuid`, and then be passed to a function like `uuid_to_rid()`. There is no point renaming a single one of these in isolation: it would create needless terminology conflicts, making the code hard to read and understand, risking the creation of new bugs. You may have local SQL code that digs into the repository DB using these column names. While you may rest easy, assured now that we are highly unlikely to ever rename these columns, the Fossil repository DB schema is not considered an external user interface, and internal interfaces are subject to change at any time. We suggest switching to a more stable API: [the JSON API][japi], [`timeline.rss`][trss], [TH1][th1], etc. ### TH1 Scripting Interfaces Some [TH1][th1] interfaces expose Fossil internals flowing from `blob.uuid`, so “UUID” is a short alias for “artifact hash” in TH1. For example, the `$tkt_uuid` variable — available when [customizing the ticket system][ctkt] — is a ticket artifact hash, exposing the `ticket.tkt_uuid` column, which has a SQL relation to `blob.uuid`. TH1 is a longstanding public programming interface. We cannot rename its interfaces without breaking existing TH1 Fossil customizations. We are also unlikely to provide a parallel set of variables with “better” names, since that would create a mismatch with respect to the internals they expose, creating a different sort of developer confusion in its place. ### JSON API Parameters and Outputs [The JSON API][japi] frequently uses the term “UUID” in the same sort of way, most commonly in [artifact][jart] and [timeline][jtim] APIs. As with TH1, we can’t change this without breaking code that uses the JSON API as originally designed, so we take the same stance. ### `manifest.uuid` If you have [the `manifest` setting][mset] enabled, Fossil writes a file called `manifest.uuid` at the root of the check-out tree containing the commit hash for the current checked-out version. Because this is a public interface that existing code depends on, we are unwilling to rename the file. [cin]: ./checkin_names.wiki [ctkt]: ./custom_ticket.wiki [hpol]: ./hashpolicy.wiki [japi]: ./json-api/ [jart]: ./json-api/api-artifact.md [jtim]: ./json-api/api-timeline.md [mset]: /help?cmd=manifest [th1]: ./th1.md [trss]: /help?cmd=/timeline.rss [tvb]: ./branching.wiki [uuid]: https://en.wikipedia.org/wiki/Universally_unique_identifier |
Changes to www/json-api/api-artifact.md.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 | <a id="checkin"></a> # Checkin Artifacts (Commits) Returns information about checkin artifacts (commits). **Status:** implemented 201110xx | | | | | | | | | | > | | | | | > | 12 13 14 15 16 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 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 |
<a id="checkin"></a>
# Checkin Artifacts (Commits)
Returns information about checkin artifacts (commits).
**Status:** implemented 201110xx
**Request:** `/json/artifact/COMMIT_HASH`
**Required permissions:** "o" (was "h" prior to 20120408)
**Response payload example: (CHANGED SIGNIFICANTLY ON 20120713)**
```json
{
"type":"checkin",
"name":"18dd383e5e7684e", // as given on CLI
"uuid":"18dd383e5e7684ecee327d3de7d3ff846069d1b2",
"isLeaf":false,
"user":"drh",
"comment":"Merge wideAnnotateUser and jsonWarnings into trunk.",
"timestamp":1330090810,
"parents":[
// 1st entry is primary parent hash:
"3a44f95f40a193739aaafc2409f155df43e74a6f",
// Remaining entries are merged-in branch hashes:
"86f6e675eb3f8761d70d8b82b052ce2b297fffd2",\
"dbf4ecf414881c9aad6f4f125dab9762589ef3d7"\
],
"tags":["trunk"],
"files":[{
"name":"src/diff.c",
// BLOB hashes, NOT commit hashes:
"uuid":"78c74c3b37e266f8f7e570d5cf476854b7af9d76",
"parent":"b1fa7e636cf4e7b6ed20bba2d2680397f80c096a",
"state":"modified",
"downloadPath":"/raw/src/diff.c?name=78c74c3b37e266f8f7e570d5cf476854b7af9d76"
},
...]
}
```
The "parents" property lists the parent hashes of the checkin. The
"parent" property of file entries refers to the parent hash of that
file. In the case of a merge there may be essentially an arbitrary
number. The first entry in the list is the "primary" parent. The primary
parent is the parent which was not pulled in via a merge operation. The
ordering of remaining entries is unspecified and may even change between
calls. For example: if, from branch C, we merge in A and B and then
commit, then in the artifact response for that commit the hash of branch
C will be in the first (primary) position, with the hashes for branches A
and B in the following entries (in an unspecified, and possibly
unstable, order).
Note that the "uuid" and "parent" properties of the "files" entries
refer to raw blob hashes, not commit (a.k.a. check-in) hashes. See also
[the UUID vs. Hash discussion][uvh].
<a id="file"></a>
# File Artifacts
Fetches information about file artifacts.
**FIXME:** the content type guessing is currently very primitive, and
may (but i haven't seen this) mis-diagnose some non-binary files as
binary. Fossil doesn't yet have a mechanism for mime-type mappings.
**Status:** implemented 20111020
**Required permissions:** "o"
**Request:** `/json/artifact/FILE_HASH`
**Request options:**
- `format=(raw|html|none)` (default=none). If set, the contents of the
artifact are included if they are text, else they are not (JSON does
not do binary). The "html" flag runs it through the wiki parser. The
results of doing so are unspecified for non-embedded-doc files. The
"raw" format means to return the content as-is. "none" is the same
as not specifying this flag, and elides the content from the
response.
- DEPRECATED (use format instead): `includeContent=bool` (=false) (CLI:
`--content|-c`). If true, the full content of the artifact is returned
for text-only artifacts (but not for non-text artifacts). As of
20120713 this option is only inspected if "format" is not specified.
**Response payload example: (CHANGED SIGNIFICANTLY ON 20120713)**
```json
{
"type":"file",
"name":"same name specified as FILE_HASH argument",
"size": 12345, // in bytes, independent of format=...
"parent": "hash of parent file blob. Not set for first generation.",
"checkins":[{
"name":"src/json_detail.h",
"timestamp":1319058803,
"comment":"...",
"user":"stephan",
"checkin":"d2c1ae23a90b24f6ca1d7637193a59d5ecf3e680",
"branch":"json",
"state":"added|modified|removed"
},
...],
/* The following "content" properties are only set if format=raw|html */
"content": "file contents",
"contentSize": "size of content field, in bytes. Affected by the format option!",
"contentType": "text/plain", /* currently always text/plain */
"contentFormat": "html|raw"
}
```
The "checkins" array lists all checkins which include this file, and a
file might have different names across different branches. The size and
hash, however, are the same across all checkins for a given blob.
<a id="wiki"></a>
# Wiki Artifacts
Returns information about wiki artifacts.
**Status:** implemented 20111020, fixed to return the requested version
(instead of the latest) on 20120302.
**Request:** `/json/artifact/WIKI_HASH`
**Required permissions:** "j"
**Options:**
- DEPRECATED (use format instead): `bool includeContent` (=false). If
true then the raw content is returned with the wiki page, else no
content is returned.\
CLI: `--includeContent|-c`
- The `--format` option works as for
[`/json/wiki/get`](api-wiki.md#get), and if set then it
implies the `includeContent` option.
**Response payload example:**
Currently the same as [`/json/wiki/get`](api-wiki.md#get).
[uvh]: ../hashes.md#uvh
|
Changes to www/json-api/api-diff.md.
| ︙ | ︙ | |||
31 32 33 34 35 36 37 | "to":"96920e7c04746c55ceed6e24fc82879886cb8197", "diff":"@@ -1,7 +1,7 @@\\n-C factored\\\\sout..." } ``` TODOs: | | | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
"to":"96920e7c04746c55ceed6e24fc82879886cb8197",
"diff":"@@ -1,7 +1,7 @@\\n-C factored\\\\sout..."
}
```
TODOs:
- Unlike the standard diff command, which apparently requires a commit
hash, this one diffs individual file versions. If a commit hash is
provided, a diff of the manifests is returned. (That should be
considered a bug - we should return a combined diff in that case.)
- If hashes from two different types of artifacts are given, results
are unspecified. Garbage in, garbage out, and all that.
- For file diffs, add the file name(s) to the response payload.
|
Changes to www/json-api/api-tag.md.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | "value":"abc", "propagate":true, "raw":false, "appliedTo":"626ab2f3743543122cc11bc082a0603d2b5b2b1b" } ``` | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | "value":"abc", "propagate":true, "raw":false, "appliedTo":"626ab2f3743543122cc11bc082a0603d2b5b2b1b" } ``` The `appliedTo` property is the hash of the check-in to which the tag was applied. This is the "resolved" version of the check-in name provided by the client. <a id="cancel"></a> # Cancel Tag **Status:** implemented 20111006 |
| ︙ | ︙ | |||
97 98 99 100 101 102 103 |
- `name=string` The tag name to search for. Can optionally be the 3rd
path element.
- `limit=int` (defalt=0) Limits the number of results (0=no limit).
Since they are ordered from oldest to newest, the newest N results
will be returned.
- `type=string` (default=`*`) Searches only for the given type of
artifact (using fossil's conventional type naming: ci, e, t, w.
| | > | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
- `name=string` The tag name to search for. Can optionally be the 3rd
path element.
- `limit=int` (defalt=0) Limits the number of results (0=no limit).
Since they are ordered from oldest to newest, the newest N results
will be returned.
- `type=string` (default=`*`) Searches only for the given type of
artifact (using fossil's conventional type naming: ci, e, t, w.
- `raw=bool` (=false) If enabled, the response is an array of hashes
of the requested artifact type; otherwise,
it is an array of higher-level objects. If this is
true, the "name" property is interpretted as-is. If it is false, the
name is automatically prepended with "sym-" (meaning a branch).
(FIXME: the current semantics are confusing and hard to remember.
Re-do them.)
**Response payload example, in RAW mode: (expect this format to change
at some point!)**
|
| ︙ | ︙ |
Changes to www/json-api/api-timeline.md.
| ︙ | ︙ | |||
77 78 79 80 81 82 83 | "uuid":"be700e84336941ef1bcd08d676310b75b9070f43", "timestamp":1317094090, "comment":"Added /json/timeline/ci showFiles to ajax test page.", "user":"stephan", "isLeaf":true, "bgColor":null, /* not quite sure why this is null? */ "type":"ci", | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
"uuid":"be700e84336941ef1bcd08d676310b75b9070f43",
"timestamp":1317094090,
"comment":"Added /json/timeline/ci showFiles to ajax test page.",
"user":"stephan",
"isLeaf":true,
"bgColor":null, /* not quite sure why this is null? */
"type":"ci",
"parents": ["primary parent hash", "...other parent hashes"],
"tags":["json"],
"files":[{
"name":"ajax/index.html",
"uuid":"9f00773a94cea6191dc3289aa24c0811b6d0d8fe",
"parent":"50e337c33c27529e08a7037a8679fb84b976ad0b",
"state":"modified"
}]
|
| ︙ | ︙ | |||
99 100 101 102 103 104 105 |
commit. The first entry in the array is the "primary parent" - the one
which was not involved in a merge with the child.
**Request options:**
- `files=bool` toggles the addition of a "files" array property which
contains objects describing the files changed by the commit,
| | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
commit. The first entry in the array is the "primary parent" - the one
which was not involved in a merge with the child.
**Request options:**
- `files=bool` toggles the addition of a "files" array property which
contains objects describing the files changed by the commit,
including their hash, previous hash, and state change type
(modified, added, or removed). ([“uuid” here means hash][uvh])\
CLI mode: `--show-files|-f`
- `tag|branch=string` selects only entries with the given tag or "close
to" the given branch. Only one of these may be specified and if both
are specified, which one takes precedence is unspecified. If the
given tag/branch does not exist, an error response is generated. The
difference between the two is subtle - tag filters only on the given
tag (analog to the HTML interface's "r" option) whereas branch can
|
| ︙ | ︙ | |||
170 171 172 173 174 175 176 |
"comment":"Ticket [b64435dba9] <i>How to...</i>",
"briefComment":"Ticket [b64435dba9]: 2 changes",
"ticketUuid":"b64435dba9cceb709bd54fbc5883884d73f93491"
},...]
}
```
| | | | | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
"comment":"Ticket [b64435dba9] <i>How to...</i>",
"briefComment":"Ticket [b64435dba9]: 2 changes",
"ticketUuid":"b64435dba9cceb709bd54fbc5883884d73f93491"
},...]
}
```
**Notice that there are two [hashes][uvh] for tickets** - `uuid` is the change
hash and `ticketUuid` is the actual ticket’s hash. This is an unfortunate
discrepancy vis-a-vis the other timeline entries, which only have one
hash. We may want to swap `uuid` to mean the ticket hash and change `uuid`
to `commitHash`.
<a id="wiki"></a>
# Wiki Timeline
**Status:** implemented 201109xx
**Required privileges:** "j" or "o"
|
| ︙ | ︙ | |||
204 205 206 207 208 209 210 | "user":"stephan", "eventType":"w" },...] } ``` The `uuid` of each entry can be passed to `/json/artifact` or | | > | 204 205 206 207 208 209 210 211 212 213 214 | "user":"stephan", "eventType":"w" },...] } ``` The `uuid` of each entry can be passed to `/json/artifact` or `/json/wiki/get?uuid=...` to fetch the raw page and the hash of the parent version. [uvh]: ../hashes.md#uvh |
Changes to www/json-api/conventions.md.
| ︙ | ︙ | |||
582 583 584 585 586 587 588 | **`FOSSIL-3000`: Usage Error Category** - `FOSSIL-3001`: Invalid argument/parameter type(s) or value(s) in request - `FOSSIL-3002`: Required argument(s)/parameter(s) missing from request - `FOSSIL-3003`: Requested resource identifier is ambiguous (e.g. a | | > | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | **`FOSSIL-3000`: Usage Error Category** - `FOSSIL-3001`: Invalid argument/parameter type(s) or value(s) in request - `FOSSIL-3002`: Required argument(s)/parameter(s) missing from request - `FOSSIL-3003`: Requested resource identifier is ambiguous (e.g. a shortened hash that matches multiple artifacts, an abbreviated date that matches multiple commits, etc.) - `FOSSIL-3004`: Unresolved resource identifier. A branch/tag/uuid provided by client code could not be resolved. This is a special case of #3006. - `FOSSIL-3005`: Resource already exists and overwriting/replacing is not allowed. e.g. trying to create a wiki page or user which already exists. FIXME? Consolidate this and resource-not-found into a separate category for dumb-down purposes? |
| ︙ | ︙ |