Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merged in trunk. Minor help text corrections for add/rm --reset. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | unaddremove-command |
| Files: | files | file ages | folders |
| SHA3-256: |
822f3aee48de082de0e441c300e80133 |
| User & Date: | stephan 2020-05-12 08:48:01.265 |
Context
|
2020-05-26
| ||
| 07:16 | Merged in trunk. ... (Closed-Leaf check-in: 58ee06450c user: stephan tags: unaddremove-command) | |
|
2020-05-12
| ||
| 08:48 | Merged in trunk. Minor help text corrections for add/rm --reset. ... (check-in: 822f3aee48 user: stephan tags: unaddremove-command) | |
| 00:21 | Extra comment in the code for the m=checkin with t=release feature of /timeline. ... (check-in: 461d4f41d5 user: drh tags: trunk) | |
|
2020-05-04
| ||
| 07:54 | Merged in trunk. ... (check-in: 628c39fb60 user: stephan tags: unaddremove-command) | |
Changes
Changes to src/add.c.
| ︙ | ︙ | |||
365 366 367 368 369 370 371 |
** --case-sensitive <BOOL> Override the case-sensitive setting.
** --dotfiles include files beginning with a dot (".")
** -f|--force Add files without prompting
** --ignore <CSG> Ignore unmanaged files matching patterns from
** the comma separated list of glob patterns.
** --clean <CSG> Also ignore files matching patterns from
** the comma separated list of glob patterns.
| > | | > > | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
** --case-sensitive <BOOL> Override the case-sensitive setting.
** --dotfiles include files beginning with a dot (".")
** -f|--force Add files without prompting
** --ignore <CSG> Ignore unmanaged files matching patterns from
** the comma separated list of glob patterns.
** --clean <CSG> Also ignore files matching patterns from
** the comma separated list of glob patterns.
** --reset Reset the ADDEd state of a checkout, such
** that all newly-added (but not yet committed)
** files are no longer added. No flags other
** than --verbose and --dry-run may be used
** with --reset.
**
** The following options are only valid with --reset:
** -v|--verbose Outputs information about each --reset file.
** -n|--dry-run Display instead of run actions.
**
** See also: addremove, rm
*/
|
| ︙ | ︙ | |||
550 551 552 553 554 555 556 | ** This supersedes the --hard option. ** --hard Remove files from the checkout. ** --case-sensitive <BOOL> Override the case-sensitive setting. ** -n|--dry-run If given, display instead of run actions. ** --reset Reset the DELETED state of a checkout, such ** that all newly-rm'd (but not yet committed) ** files are no longer removed. No flags other | | > | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
** This supersedes the --hard option.
** --hard Remove files from the checkout.
** --case-sensitive <BOOL> Override the case-sensitive setting.
** -n|--dry-run If given, display instead of run actions.
** --reset Reset the DELETED state of a checkout, such
** that all newly-rm'd (but not yet committed)
** files are no longer removed. No flags other
** than --verbose or --dry-run may be used with
** --reset.
** --verbose|-v Outputs information about each --reset file.
** Only usable with --reset.
**
** See also: addremove, add
*/
void delete_cmd(void){
int i;
|
| ︙ | ︙ |
Changes to src/allrepo.c.
| ︙ | ︙ | |||
126 127 128 129 130 131 132 | ** ** rebuild Rebuild on all repositories. The command line options ** supported by the rebuild command itself, if any are ** present, are passed along verbatim. The --force and ** --randomize options are not supported. ** ** sync Run a "sync" on all repositories. Only the --verbose | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | ** ** rebuild Rebuild on all repositories. The command line options ** supported by the rebuild command itself, if any are ** present, are passed along verbatim. The --force and ** --randomize options are not supported. ** ** sync Run a "sync" on all repositories. Only the --verbose ** and --unversioned options are supported. ** ** setting Run the "setting", "set", or "unset" commands on all ** set repositories. These command are particularly useful in ** unset conjunction with the "max-loadavg" setting which cannot ** otherwise be set globally. ** ** server Run the "ui" or "server" commands on all repositories. |
| ︙ | ︙ |
Changes to src/branch.c.
| ︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ******************************************************************************* ** ** This file contains code used to create new branches within a repository. */ #include "config.h" #include "branch.h" #include <assert.h> /* ** If RID refers to a check-in, return the name of the branch for that ** check-in. ** ** Space to hold the returned value is obtained from fossil_malloc() ** and should be freed by the caller. | > > > > > > > > > > > > > > | 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 |
*******************************************************************************
**
** This file contains code used to create new branches within a repository.
*/
#include "config.h"
#include "branch.h"
#include <assert.h>
/*
** Return true if zBr is the branch name associated with check-in with
** blob.uuid value of zUuid
*/
int branch_includes_uuid(const char *zBr, const char *zUuid){
return db_exists(
"SELECT 1 FROM tagxref, blob"
" WHERE blob.uuid=%Q AND tagxref.rid=blob.rid"
" AND tagxref.value=%Q AND tagxref.tagtype>0"
" AND tagxref.tagid=%d",
zUuid, zBr, TAG_BRANCH
);
}
/*
** If RID refers to a check-in, return the name of the branch for that
** check-in.
**
** Space to hold the returned value is obtained from fossil_malloc()
** and should be freed by the caller.
|
| ︙ | ︙ |
Changes to src/browse.c.
| ︙ | ︙ | |||
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
sqlite3_result_text(context, (char*)&z[n], len-n, SQLITE_TRANSIENT);
}else{
zOut = sqlite3_mprintf("/%.*s", i-n, &z[n]);
sqlite3_result_text(context, zOut, i-n+1, sqlite3_free);
}
}
/*
** Given a pathname which is a relative path from the root of
** the repository to a file or directory, compute a string which
** is an HTML rendering of that path with hyperlinks on each
** directory component of the path where the hyperlink redirects
** to the "dir" page for the directory.
**
** There is no hyperlink on the file element of the path.
**
** The computed string is appended to the pOut blob. pOut should
** have already been initialized.
*/
void hyperlinked_path(
const char *zPath, /* Path to render */
Blob *pOut, /* Write into this blob */
const char *zCI, /* check-in name, or NULL */
const char *zURI, /* "dir" or "tree" */
| > > > > > > > > | > | > > > > > > > > > | | | | | | | | < < < | 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 |
sqlite3_result_text(context, (char*)&z[n], len-n, SQLITE_TRANSIENT);
}else{
zOut = sqlite3_mprintf("/%.*s", i-n, &z[n]);
sqlite3_result_text(context, zOut, i-n+1, sqlite3_free);
}
}
/*
** Flag arguments for hyperlinked_path()
*/
#if INTERFACE
# define LINKPATH_FINFO 0x0001 /* Link final term to /finfo */
# define LINKPATH_FILE 0x0002 /* Link final term to /file */
#endif
/*
** Given a pathname which is a relative path from the root of
** the repository to a file or directory, compute a string which
** is an HTML rendering of that path with hyperlinks on each
** directory component of the path where the hyperlink redirects
** to the "dir" page for the directory.
**
** There is no hyperlink on the file element of the path.
**
** The computed string is appended to the pOut blob. pOut should
** have already been initialized.
*/
void hyperlinked_path(
const char *zPath, /* Path to render */
Blob *pOut, /* Write into this blob */
const char *zCI, /* check-in name, or NULL */
const char *zURI, /* "dir" or "tree" */
const char *zREx, /* Extra query parameters */
unsigned int mFlags /* Extra flags */
){
int i, j;
char *zSep = "";
for(i=0; zPath[i]; i=j){
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
if( zPath[j]==0 ){
if( mFlags & LINKPATH_FILE ){
zURI = "file";
}else if( mFlags & LINKPATH_FINFO ){
zURI = "finfo";
}else{
blob_appendf(pOut, "/%h", zPath+i);
break;
}
}
if( zCI ){
char *zLink = href("%R/%s?name=%#T%s&ci=%T", zURI, j, zPath, zREx,zCI);
blob_appendf(pOut, "%s%z%#h</a>",
zSep, zLink, j-i, &zPath[i]);
}else{
char *zLink = href("%R/%s?name=%#T%s", zURI, j, zPath, zREx);
blob_appendf(pOut, "%s%z%#h</a>",
zSep, zLink, j-i, &zPath[i]);
}
zSep = "/";
while( zPath[j]=='/' ){ j++; }
}
}
|
| ︙ | ︙ | |||
125 126 127 128 129 130 131 |
int nD = zD ? strlen(zD)+1 : 0;
int mxLen;
char *zPrefix;
Stmt q;
const char *zCI = P("ci");
int rid = 0;
char *zUuid = 0;
| < > > > > < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > < > | | > > | > > > > > > > > > > > > > > > > > < < < | | < < < < < < < < < < < < < < | 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 |
int nD = zD ? strlen(zD)+1 : 0;
int mxLen;
char *zPrefix;
Stmt q;
const char *zCI = P("ci");
int rid = 0;
char *zUuid = 0;
Manifest *pM = 0;
const char *zSubdirLink;
int linkTrunk = 1;
int linkTip = 1;
HQuery sURI;
int isSymbolicCI = 0; /* ci= is symbolic name, not a hash prefix */
int isBranchCI = 0; /* True if ci= refers to a branch name */
char *zHeader = 0;
if( zCI && strlen(zCI)==0 ){ zCI = 0; }
if( strcmp(PD("type","flat"),"tree")==0 ){ page_tree(); return; }
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
/* If the name= parameter is an empty string, make it a NULL pointer */
if( zD && strlen(zD)==0 ){ zD = 0; }
/* If a specific check-in is requested, fetch and parse it. If the
** specific check-in does not exist, clear zCI. zCI==0 will cause all
** files from all check-ins to be displayed.
*/
if( zCI ){
pM = manifest_get_by_name(zCI, &rid);
if( pM ){
int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
linkTrunk = trunkRid && rid != trunkRid;
linkTip = rid != symbolic_name_to_rid("tip", "ci");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
isBranchCI = branch_includes_uuid(zCI, zUuid);
}else{
zCI = 0;
}
}
assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
if( zD==0 ){
if( zCI ){
zHeader = mprintf("Top-level Files of %s", zCI);
}else{
zHeader = mprintf("All Top-level Files");
}
}else{
if( zCI ){
zHeader = mprintf("Files in %s/ of %s", zD, zCI);
}else{
zHeader = mprintf("All File in %s/", zD);
}
}
style_header("%s", zHeader);
fossil_free(zHeader);
style_adunit_config(ADUNIT_RIGHT_OK);
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "dir");
cgi_query_parameters_to_url(&sURI);
/* Compute the title of the page */
if( zD ){
Blob dirname;
blob_init(&dirname, 0, 0);
hyperlinked_path(zD, &dirname, zCI, "dir", "", 0);
@ <h2>Files in directory %s(blob_str(&dirname)) \
blob_reset(&dirname);
zPrefix = mprintf("%s/", zD);
style_submenu_element("Top-Level", "%s",
url_render(&sURI, "name", 0, 0, 0));
}else{
@ <h2>Files in the top-level directory \
zPrefix = "";
}
if( zCI ){
if( fossil_strcmp(zCI,"tip")==0 ){
@ from the %z(href("%R/info?name=%T",zCI))latest check-in</a></h2>
}else if( isBranchCI ){
@ from the %z(href("%R/info?name=%T",zCI))latest check-in</a> \
@ of branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
}else {
@ of check-in %z(href("%R/info?name=%T",zCI))%h(zCI)</a></h2>
}
zSubdirLink = mprintf("%R/dir?ci=%T&name=%T", zCI, zPrefix);
if( nD==0 ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}else{
@ in any check-in</h2>
zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
}
if( linkTrunk ){
style_submenu_element("Trunk", "%s",
url_render(&sURI, "ci", "trunk", 0, 0));
}
if( linkTip ){
style_submenu_element("Tip", "%s", url_render(&sURI, "ci", "tip", 0, 0));
}
if( zD ){
style_submenu_element("History","%R/timeline?chng=%T/*", zD);
}
style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
style_submenu_element("Tree-View", "%s",
url_render(&sURI, "type", "tree", 0, 0));
/* Compute the temporary table "localfiles" containing the names
** of all files and subdirectories in the zD[] directory.
|
| ︙ | ︙ | |||
280 281 282 283 284 285 286 |
zFN = db_column_text(&q, 0);
if( zFN[0]=='/' ){
zFN++;
@ <li class="dir">%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
}else{
const char *zLink;
if( zCI ){
| < | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
zFN = db_column_text(&q, 0);
if( zFN[0]=='/' ){
zFN++;
@ <li class="dir">%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
}else{
const char *zLink;
if( zCI ){
zLink = href("%R/file?name=%T%T&ci=%T",zPrefix,zFN,zCI);
}else{
zLink = href("%R/finfo?name=%T%T",zPrefix,zFN);
}
@ <li class="%z(fileext_class(zFN))">%z(zLink)%h(zFN)</a></li>
}
}
db_finalize(&q);
|
| ︙ | ︙ | |||
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
FileTreeNode *p; /* One line of the tree */
FileTree sTree; /* The complete tree of files */
HQuery sURI; /* Hyperlink */
int startExpanded; /* True to start out with the tree expanded */
int showDirOnly; /* Show directories only. Omit files */
int nDir = 0; /* Number of directories. Used for ID attributes */
char *zProjectName = db_get("project-name", 0);
if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; }
memset(&sTree, 0, sizeof(sTree));
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "tree");
cgi_query_parameters_to_url(&sURI);
if( PB("nofiles") ){
showDirOnly = 1;
| > > > > < < | 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 |
FileTreeNode *p; /* One line of the tree */
FileTree sTree; /* The complete tree of files */
HQuery sURI; /* Hyperlink */
int startExpanded; /* True to start out with the tree expanded */
int showDirOnly; /* Show directories only. Omit files */
int nDir = 0; /* Number of directories. Used for ID attributes */
char *zProjectName = db_get("project-name", 0);
int isSymbolicCI = 0; /* ci= is a symbolic name, not a hash prefix */
int isBranchCI = 0; /* ci= refers to a branch name */
char *zHeader = 0;
if( zCI && strlen(zCI)==0 ){ zCI = 0; }
if( strcmp(PD("type","flat"),"flat")==0 ){ page_dir(); return; }
memset(&sTree, 0, sizeof(sTree));
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "tree");
cgi_query_parameters_to_url(&sURI);
if( PB("nofiles") ){
showDirOnly = 1;
}else{
showDirOnly = 0;
}
style_adunit_config(ADUNIT_RIGHT_OK);
if( PB("expand") ){
startExpanded = 1;
}else{
startExpanded = 0;
}
|
| ︙ | ︙ | |||
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 |
int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
linkTrunk = trunkRid && rid != trunkRid;
linkTip = rid != symbolic_name_to_rid("tip", "ci");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal())"
" FROM event WHERE objid=%d", rid);
}else{
zCI = 0;
}
}
if( zCI==0 ){
rNow = db_double(0.0, "SELECT max(mtime) FROM event");
zNow = db_text("", "SELECT datetime(max(mtime),toLocal()) FROM event");
}
/* Compute the title of the page */
blob_zero(&dirname);
if( zD ){
blob_append(&dirname, "within directory ", -1);
| > > > > > > > > > > > > > > > > > > > | < | | < | | 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 |
int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
linkTrunk = trunkRid && rid != trunkRid;
linkTip = rid != symbolic_name_to_rid("tip", "ci");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal())"
" FROM event WHERE objid=%d", rid);
isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI)) != 0);
isBranchCI = branch_includes_uuid(zCI, zUuid);
}else{
zCI = 0;
}
}
if( zCI==0 ){
rNow = db_double(0.0, "SELECT max(mtime) FROM event");
zNow = db_text("", "SELECT datetime(max(mtime),toLocal()) FROM event");
}
assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
if( zD==0 ){
if( zCI ){
zHeader = mprintf("Top-level Files of %s", zCI);
}else{
zHeader = mprintf("All Top-level Files");
}
}else{
if( zCI ){
zHeader = mprintf("Files in %s/ of %s", zD, zCI);
}else{
zHeader = mprintf("All File in %s/", zD);
}
}
style_header("%s", zHeader);
fossil_free(zHeader);
/* Compute the title of the page */
blob_zero(&dirname);
if( zD ){
blob_append(&dirname, "within directory ", -1);
hyperlinked_path(zD, &dirname, zCI, "tree", zREx, 0);
if( zRE ) blob_appendf(&dirname, " matching \"%s\"", zRE);
style_submenu_element("Top-Level", "%s",
url_render(&sURI, "name", 0, 0, 0));
}else if( zRE ){
blob_appendf(&dirname, "matching \"%s\"", zRE);
}
style_submenu_binary("mtime","Sort By Time","Sort By Filename", 0);
if( zCI ){
style_submenu_element("All", "%s", url_render(&sURI, "ci", 0, 0, 0));
if( nD==0 && !showDirOnly ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}
if( linkTrunk ){
style_submenu_element("Trunk", "%s",
url_render(&sURI, "ci", "trunk", 0, 0));
}
if( linkTip ){
|
| ︙ | ︙ | |||
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
}
if( pRE && re_match(pRE, (const u8*)zName, -1)==0 ) continue;
tree_add_node(&sTree, zName, zUuid, mtime);
nFile++;
}
db_finalize(&q);
}
if( showDirOnly ){
for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
if( p->pChild!=0 && p->nFullName>nD ) nFile++;
}
zObjType = "Folders";
}else{
zObjType = "Files";
}
| > | > > > > > > | | | < | > > < | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 |
}
if( pRE && re_match(pRE, (const u8*)zName, -1)==0 ) continue;
tree_add_node(&sTree, zName, zUuid, mtime);
nFile++;
}
db_finalize(&q);
}
style_submenu_checkbox("nofiles", "Folders Only", 0, 0);
if( showDirOnly ){
for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
if( p->pChild!=0 && p->nFullName>nD ) nFile++;
}
zObjType = "Folders";
}else{
zObjType = "Files";
}
if( zCI && strcmp(zCI,"tip")==0 ){
@ <h2>%s(zObjType) in the %z(href("%R/info?name=tip"))latest check-in</a>
}else if( isBranchCI ){
@ <h2>%s(zObjType) in the %z(href("%R/info?name=%T",zCI))latest check-in\
@ </a> for branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a>
if( blob_size(&dirname) ){
@ and %s(blob_str(&dirname))</h2>
}
}else if( zCI ){
@ <h2>%s(zObjType) for check-in \
@ %z(href("%R/info?name=%T",zCI))%h(zCI)</a></h2>
if( blob_size(&dirname) ){
@ and %s(blob_str(&dirname))</h2>
}
}else{
int n = db_int(0, "SELECT count(*) FROM plink");
@ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))
}
if( useMtime ){
@ sorted by modification time</h2>
}else{
|
| ︙ | ︙ | |||
822 823 824 825 826 827 828 |
@ <ul id="dir%d(nDir)" class="collapsed">
}
nDir++;
}else if( !showDirOnly ){
const char *zFileClass = fileext_class(p->zName);
char *zLink;
if( zCI ){
| | | 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 |
@ <ul id="dir%d(nDir)" class="collapsed">
}
nDir++;
}else if( !showDirOnly ){
const char *zFileClass = fileext_class(p->zName);
char *zLink;
if( zCI ){
zLink = href("%R/file?name=%T&ci=%T",p->zFullName,zCI);
}else{
zLink = href("%R/finfo?name=%T",p->zFullName);
}
@ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
@ %z(zLink)%h(p->zName)</a>
if( p->mtime>0 ){
char *zAge = human_readable_age(rNow - p->mtime);
|
| ︙ | ︙ | |||
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 |
*/
void fileage_page(void){
int rid;
const char *zName;
const char *zGlob;
const char *zUuid;
const char *zNow; /* Time of check-in */
int showId = PB("showid");
Stmt q1, q2;
double baseTime;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
if( exclude_spiders() ) return;
zName = P("name");
if( zName==0 ) zName = "tip";
rid = symbolic_name_to_rid(zName, "ci");
if( rid==0 ){
fossil_fatal("not a valid check-in: %s", zName);
}
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
" WHERE objid=%d", rid);
style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
style_header("File Ages");
zGlob = P("glob");
compute_fileage(rid,zGlob);
db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
| > > > | > | > > > > | < | | < < | < > > | | | | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 |
*/
void fileage_page(void){
int rid;
const char *zName;
const char *zGlob;
const char *zUuid;
const char *zNow; /* Time of check-in */
int isBranchCI; /* name= is a branch name */
int showId = PB("showid");
Stmt q1, q2;
double baseTime;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
if( exclude_spiders() ) return;
zName = P("name");
if( zName==0 ) zName = "tip";
rid = symbolic_name_to_rid(zName, "ci");
if( rid==0 ){
fossil_fatal("not a valid check-in: %s", zName);
}
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
isBranchCI = branch_includes_uuid(zName,zUuid);
baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
" WHERE objid=%d", rid);
style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
style_header("File Ages");
zGlob = P("glob");
compute_fileage(rid,zGlob);
db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
if( fossil_strcmp(zName,"tip")==0 ){
@ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a>
}else if( isBranchCI ){
@ <h1>Files in the %z(href("%R/info?name=%T",zName))latest check-in</a>
@ of branch %z(href("%R/timeline?r=%T",zName))%h(zName)</a>
}else{
@ <h1>Files in check-in %z(href("%R/info?name=%T",zName))%h(zName)</a>
}
if( zGlob && zGlob[0] ){
@ that match "%h(zGlob)"
}
@ ordered by age</h1>
@
@ <p>File ages are expressed relative to the check-in time of
@ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
@
@ <div class='fileage'><table>
@ <tr><th>Age</th><th>Files</th><th>Check-in</th></tr>
db_prepare(&q1,
"SELECT event.mtime, event.objid, blob.uuid,\n"
" coalesce(event.ecomment,event.comment),\n"
" coalesce(event.euser,event.user),\n"
" coalesce((SELECT value FROM tagxref\n"
" WHERE tagtype>0 AND tagid=%d\n"
" AND rid=event.objid),'trunk')\n"
" FROM event, blob\n"
" WHERE event.objid IN (SELECT mid FROM fileage)\n"
" AND blob.rid=event.objid\n"
" ORDER BY event.mtime DESC;",
TAG_BRANCH
);
db_prepare(&q2,
"SELECT filename.name, fileage.fid\n"
" FROM fileage, filename\n"
" WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
);
while( db_step(&q1)==SQLITE_ROW ){
double age = baseTime - db_column_double(&q1, 0);
int mid = db_column_int(&q1, 1);
const char *zUuid = db_column_text(&q1, 2);
const char *zComment = db_column_text(&q1, 3);
const char *zUser = db_column_text(&q1, 4);
const char *zBranch = db_column_text(&q1, 5);
char *zAge = human_readable_age(age);
@ <tr><td>%s(zAge)</td>
@ <td>
db_bind_int(&q2, ":mid", mid);
while( db_step(&q2)==SQLITE_ROW ){
const char *zFile = db_column_text(&q2,0);
@ %z(href("%R/file?name=%T&ci=%!S",zFile,zUuid))%h(zFile)</a> \
if( showId ){
int fid = db_column_int(&q2,1);
@ (%d(fid))<br />
}else{
@ </a><br />
}
}
db_reset(&q2);
@ </td>
@ <td>
@ %W(zComment)
@ (check-in: %z(href("%R/info/%!S",zUuid))%S(zUuid)</a>,
if( showId ){
@ id: %d(mid)
}
@ user: %z(href("%R/timeline?u=%t&c=%!S&nd",zUser,zUuid))%h(zUser)</a>,
@ branch: \
@ %z(href("%R/timeline?r=%t&c=%!S&nd",zBranch,zUuid))%h(zBranch)</a>)
@ </td></tr>
|
| ︙ | ︙ |
Changes to src/builtin.c.
| ︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 |
}
const char *builtin_text(const char *zFilename){
return (char*)builtin_file(zFilename, 0);
}
/*
** COMMAND: test-builtin-list
**
** List the names and sizes of all built-in resources.
*/
void test_builtin_list(void){
| > > > | > | > > > > | 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 |
}
const char *builtin_text(const char *zFilename){
return (char*)builtin_file(zFilename, 0);
}
/*
** COMMAND: test-builtin-list
**
** If -verbose is used, it outputs a line at the end
** with the total item count and size.
**
** List the names and sizes of all built-in resources.
*/
void test_builtin_list(void){
int i, size = 0;;
for(i=0; i<count(aBuiltinFiles); i++){
const int n = aBuiltinFiles[i].nByte;
fossil_print("%-30s %6d\n", aBuiltinFiles[i].zName,n);
size += n;
}
if(find_option("verbose","v",0)!=0){
fossil_print("%d entries totaling %d bytes\n", i, size);
}
}
/*
** WEBPAGE: test-builtin-files
**
** Show all built-in text files.
|
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
172 173 174 175 176 177 178 | cgi_combine_header_and_body(); return blob_buffer(&cgiContent[0]); } /* ** Additional information used to form the HTTP reply */ | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | cgi_combine_header_and_body(); return blob_buffer(&cgiContent[0]); } /* ** Additional information used to form the HTTP reply */ static const char *zContentType = "text/html"; /* Content type of the reply */ static const char *zReplyStatus = "OK"; /* Reply status description */ static int iReplyStatus = 200; /* Reply status code */ static Blob extraHeader = BLOB_INITIALIZER; /* Extra header text */ static int rangeStart = 0; /* Start of Range: */ static int rangeEnd = 0; /* End of Range: plus 1 */ /* ** Set the reply content type |
| ︙ | ︙ | |||
291 292 293 294 295 296 297 |
assert( rangeEnd==0 );
fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
}
if( g.isConst ){
/* isConst means that the reply is guaranteed to be invariant, even
** after configuration changes and/or Fossil binary recompiles. */
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
| | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
assert( rangeEnd==0 );
fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus);
}
if( g.isConst ){
/* isConst means that the reply is guaranteed to be invariant, even
** after configuration changes and/or Fossil binary recompiles. */
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
}else if( etag_tag()[0]!=0 ){
fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
}else{
fprintf(g.httpOut, "Cache-control: no-cache\r\n");
}
if( etag_mtime()>0 ){
fprintf(g.httpOut, "Last-Modified: %s\r\n",
|
| ︙ | ︙ | |||
327 328 329 330 331 332 333 | ** These headers are probably best added by the web server hosting fossil as ** a CGI script. */ /* Content intended for logged in users should only be cached in ** the browser, not some shared location. */ | > | | | | | < | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
** These headers are probably best added by the web server hosting fossil as
** a CGI script.
*/
/* Content intended for logged in users should only be cached in
** the browser, not some shared location.
*/
if( iReplyStatus!=304 ) {
fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType);
if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){
cgi_combine_header_and_body();
blob_compress(&cgiContent[0], &cgiContent[0]);
}
if( is_gzippable() && iReplyStatus!=206 ){
int i;
gzip_begin(0);
for( i=0; i<2; i++ ){
int size = blob_size(&cgiContent[i]);
if( size>0 ) gzip_step(blob_buffer(&cgiContent[i]), size);
blob_reset(&cgiContent[i]);
|
| ︙ | ︙ | |||
357 358 359 360 361 362 363 |
total_size = rangeEnd - rangeStart;
}
fprintf(g.httpOut, "Content-Length: %d\r\n", total_size);
}else{
total_size = 0;
}
fprintf(g.httpOut, "\r\n");
| | > | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
total_size = rangeEnd - rangeStart;
}
fprintf(g.httpOut, "Content-Length: %d\r\n", total_size);
}else{
total_size = 0;
}
fprintf(g.httpOut, "\r\n");
if( total_size>0
&& iReplyStatus!=304
&& fossil_strcmp(P("REQUEST_METHOD"),"HEAD")!=0
){
int i, size;
for(i=0; i<2; i++){
size = blob_size(&cgiContent[i]);
if( size<=rangeStart ){
rangeStart -= size;
|
| ︙ | ︙ |
Changes to src/comformat.c.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 | ** ** This file contains code used to format and print comments or other ** text on a TTY. */ #include "config.h" #include "comformat.h" #include <assert.h> | < < < < < < | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** ** This file contains code used to format and print comments or other ** text on a TTY. */ #include "config.h" #include "comformat.h" #include <assert.h> #if INTERFACE #define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags = non-legacy. */ #define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */ #define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */ #define COMMENT_PRINT_TRIM_SPACE ((u32)0x00000004) /* Trim leading/trailing. */ #define COMMENT_PRINT_WORD_BREAK ((u32)0x00000008) /* Break lines on words. */ |
| ︙ | ︙ | |||
65 66 67 68 69 70 71 |
** returned to indicate the terminal line width is using the hard-coded
** legacy default value.
*/
static int comment_set_maxchars(
int indent,
int *pMaxChars
){
| | < | < < | | < < < | | < < | | | | | | | | < > | 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 |
** returned to indicate the terminal line width is using the hard-coded
** legacy default value.
*/
static int comment_set_maxchars(
int indent,
int *pMaxChars
){
struct TerminalSize ts;
if ( !terminal_get_size(&ts) ){
return 0;
}
if( ts.nColumns ){
*pMaxChars = ts.nColumns - indent;
return 1;
}else{
/*
** Fallback to using more-or-less the "legacy semantics" of hard-coding
** the maximum line length to a value reasonable for the vast majority
** of supported systems.
*/
*pMaxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
return -1;
}
}
/*
** This function checks the current line being printed against the original
** comment text. Upon matching, it updates the provided character and line
** counts, if applicable. The caller needs to emit a new line, if desired.
*/
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 |
if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
return n;
}
/*
** Extract the width of columns for side-by-side diff. Supply an
** appropriate default if no width is given.
*/
int diff_width(u64 diffFlags){
int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
| > > > > > > | > > > > > > > > > > > > > > > > > > > | 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 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 |
if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
return n;
}
/*
** Extract the width of columns for side-by-side diff. Supply an
** appropriate default if no width is given.
**
** Calculate the default automatically, based on terminal's current width:
** term-width = 2*diff-col + diff-marker + 1
** diff-col = lineno + lmargin + text-width + rmargin
**
** text-width = (term-width - diff-marker - 1)/2 - lineno - lmargin - rmargin
*/
int diff_width(u64 diffFlags){
int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
if( w==0 ){
static struct {
unsigned int lineno, lmargin, text, rmargin, marker;
} sbsW = { 5, 2, 0, 0, 3 };
const unsigned int wMin = 24, wMax = 132;
unsigned int tw = terminal_get_width(80);
unsigned int twMin =
(wMin + sbsW.lineno + sbsW.lmargin + sbsW.rmargin)*2 + sbsW.marker + 1;
unsigned int twMax =
(wMax + sbsW.lineno + sbsW.lmargin + sbsW.rmargin)*2 + sbsW.marker + 1;
if( tw<twMin ){
tw = twMin;
}else if( tw>twMax ){
tw = twMax;
}
sbsW.text =
(tw - sbsW.marker - 1)/2 - sbsW.lineno - sbsW.lmargin - sbsW.rmargin;
w = sbsW.text;
}
return w;
}
/*
** Append the error message to pOut.
*/
void diff_errmsg(Blob *pOut, const char *msg, int diffFlags){
|
| ︙ | ︙ |
Changes to src/etag.c.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** in the ETag include: ** ** (1) The mtime on the Fossil executable ** (2) The last change to the CONFIG table ** (3) The last change to the EVENT table ** (4) The value of the display cookie ** (5) A hash value supplied by the page generator ** ** Item (1) is always included in the ETag. The other elements are ** optional. Because (1) is always included as part of the ETag, all ** outstanding ETags can be invalidated by touching the fossil executable. ** ** A page generator routine invokes etag_check() exactly once, with ** arguments that indicates which of the above elements to include in the | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ** in the ETag include: ** ** (1) The mtime on the Fossil executable ** (2) The last change to the CONFIG table ** (3) The last change to the EVENT table ** (4) The value of the display cookie ** (5) A hash value supplied by the page generator ** (6) The details of the request URI ** (7) The name user as determined by the login cookie ** ** Item (1) is always included in the ETag. The other elements are ** optional. Because (1) is always included as part of the ETag, all ** outstanding ETags can be invalidated by touching the fossil executable. ** ** A page generator routine invokes etag_check() exactly once, with ** arguments that indicates which of the above elements to include in the |
| ︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
/*
** Things to monitor
*/
#define ETAG_CONFIG 0x01 /* Output depends on the CONFIG table */
#define ETAG_DATA 0x02 /* Output depends on the EVENT table */
#define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
#define ETAG_HASH 0x08 /* Output depends on a hash */
#endif
static char zETag[33]; /* The generated ETag */
static int iMaxAge = 0; /* The max-age parameter in the reply */
static sqlite3_int64 iEtagMtime = 0; /* Last-Modified time */
/*
** Generate an ETag
*/
void etag_check(unsigned eFlags, const char *zHash){
| > > > > > > > > > > > > > > > > > > > < | | | | | > > > > > > > > > > > > > > > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
/*
** Things to monitor
*/
#define ETAG_CONFIG 0x01 /* Output depends on the CONFIG table */
#define ETAG_DATA 0x02 /* Output depends on the EVENT table */
#define ETAG_COOKIE 0x04 /* Output depends on a display cookie value */
#define ETAG_HASH 0x08 /* Output depends on a hash */
#define ETAG_QUERY 0x10 /* Output depends on PATH_INFO and QUERY_STRING */
/* and the g.zLogin value */
#endif
static char zETag[33]; /* The generated ETag */
static int iMaxAge = 0; /* The max-age parameter in the reply */
static sqlite3_int64 iEtagMtime = 0; /* Last-Modified time */
/*
** Return a hash that changes every time the Fossil source code is
** rebuilt.
**
** The FOSSIL_BUILD_HASH string that is returned here gets computed by
** the mkversion utility program. The result is a hash of MANIFEST_UUID
** and the unix timestamp for when the mkversion utility program is run.
**
** During development rebuilds, if you need the source code id to change
** in order to invalidate caches, simply "touch" the "manifest" file in
** the top of the source directory prior to running "make" and a new
** FOSSIL_BUILD_HASH will be generated automatically.
*/
const char *fossil_exe_id(void){
return FOSSIL_BUILD_HASH;
}
/*
** Generate an ETag
*/
void etag_check(unsigned eFlags, const char *zHash){
const char *zIfNoneMatch;
char zBuf[50];
assert( zETag[0]==0 ); /* Only call this routine once! */
iMaxAge = 86400;
md5sum_init();
/* Always include the executable ID as part of the hash */
md5sum_step_text("exe-id: ", -1);
md5sum_step_text(fossil_exe_id(), -1);
md5sum_step_text("\n", 1);
if( (eFlags & ETAG_HASH)!=0 && zHash ){
md5sum_step_text("hash: ", -1);
md5sum_step_text(zHash, -1);
md5sum_step_text("\n", 1);
iMaxAge = 0;
}else if( eFlags & ETAG_DATA ){
int iKey = db_int(0, "SELECT max(rcvid) FROM rcvfrom");
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",iKey);
md5sum_step_text("data: ", -1);
md5sum_step_text(zBuf, -1);
md5sum_step_text("\n", 1);
iMaxAge = 60;
}else if( eFlags & ETAG_CONFIG ){
int iKey = db_int(0, "SELECT value FROM config WHERE name='cfgcnt'");
sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",iKey);
md5sum_step_text("config: ", -1);
md5sum_step_text(zBuf, -1);
md5sum_step_text("\n", 1);
iMaxAge = 3600;
}
/* Include the display cookie */
if( eFlags & ETAG_COOKIE ){
md5sum_step_text("display-cookie: ", -1);
md5sum_step_text(PD(DISPLAY_SETTINGS_COOKIE,""), -1);
md5sum_step_text("\n", 1);
iMaxAge = 0;
}
/* Output depends on PATH_INFO and QUERY_STRING */
if( eFlags & ETAG_QUERY ){
const char *zQS = P("QUERY_STRING");
md5sum_step_text("query: ", -1);
md5sum_step_text(PD("PATH_INFO",""), -1);
if( zQS ){
md5sum_step_text("?", 1);
md5sum_step_text(zQS, -1);
}
md5sum_step_text("\n",1);
if( g.zLogin ){
md5sum_step_text("login: ", -1);
md5sum_step_text(g.zLogin, -1);
md5sum_step_text("\n", 1);
}
}
/* Generate the ETag */
memcpy(zETag, md5sum_finish(0), 33);
/* Check to see if the generated ETag matches If-None-Match and
** generate a 304 reply if it does. */
zIfNoneMatch = P("HTTP_IF_NONE_MATCH");
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
197 198 199 200 201 202 203 |
" AND event.objid=ci.rid"
" ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
TAG_BRANCH, zFilename, filename_collation(),
iLimit, iOffset
);
blob_zero(&line);
if( iBrief ){
| | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
" AND event.objid=ci.rid"
" ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
TAG_BRANCH, zFilename, filename_collation(),
iLimit, iOffset
);
blob_zero(&line);
if( iBrief ){
fossil_print("History for %s\n", blob_str(&fname));
}
while( db_step(&q)==SQLITE_ROW ){
const char *zFileUuid = db_column_text(&q, 0);
const char *zCiUuid = db_column_text(&q,1);
const char *zDate = db_column_text(&q, 2);
const char *zCom = db_column_text(&q, 3);
const char *zUser = db_column_text(&q, 4);
|
| ︙ | ︙ | |||
294 295 296 297 298 299 300 |
** 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.
*/
void finfo_page(void){
Stmt q;
| | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
** 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.
*/
void finfo_page(void){
Stmt q;
const char *zFilename = PD("name","");
char zPrevDate[20];
const char *zA;
const char *zB;
int n;
int baseCheckin;
int origCheckin = 0;
int fnid;
|
| ︙ | ︙ | |||
319 320 321 322 323 324 325 |
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
const char *zMark; /* Mark this version of the file */
int selRid = 0; /* RID of the marked file version */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
| > > | > > > < < | 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 |
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
const char *zMark; /* Mark this version of the file */
int selRid = 0; /* RID of the marked file version */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
if( fnid==0 ){
style_header("No such file");
}else{
style_header("History for %s", zFilename);
}
login_anonymous_available();
tmFlags = timeline_ss_submenu();
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
}else if( tmFlags & TIMELINE_CLASSIC ){
zStyle = "Classic";
}else{
zStyle = "Modern";
}
url_initialize(&url, "finfo");
if( brBg ) url_add_parameter(&url, "brbg", 0);
if( uBg ) url_add_parameter(&url, "ubg", 0);
baseCheckin = name_to_rid_www("ci");
zPrevDate[0] = 0;
cookie_render();
if( fnid==0 ){
@ No such file: %h(zFilename)
style_footer();
return;
}
if( g.perm.Admin ){
style_submenu_element("MLink Table", "%R/mlink?name=%t", zFilename);
|
| ︙ | ︙ | |||
433 434 435 436 437 438 439 |
if( origCheckin ){
blob_appendf(&title, "Changes to file ");
}else if( n>0 ){
blob_appendf(&title, "First %d ancestors of file ", n);
}else{
blob_appendf(&title, "Ancestors of file ");
}
| | > | | | | 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
if( origCheckin ){
blob_appendf(&title, "Changes to file ");
}else if( n>0 ){
blob_appendf(&title, "First %d ancestors of file ", n);
}else{
blob_appendf(&title, "Ancestors of file ");
}
blob_appendf(&title,"%z%h</a>",
href("%R/file?name=%T&ci=%!S", zFilename, zUuid),
zFilename);
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
blob_append(&title, origCheckin ? " between " : " from ", -1);
blob_appendf(&title, "check-in %z%S</a>", zLink, zUuid);
if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin);
fossil_free(zUuid);
if( origCheckin ){
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", origCheckin);
zLink = href("%R/info/%!S", zUuid);
blob_appendf(&title, " and check-in %z%S</a>", zLink, zUuid);
fossil_free(zUuid);
}
}else{
blob_appendf(&title, "History for ");
hyperlinked_path(zFilename, &title, 0, "tree", "", LINKPATH_FILE);
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
}
if( uBg ){
blob_append(&title, " (color-coded by user)", -1);
}
@ <h2>%b(&title)</h2>
blob_reset(&title);
|
| ︙ | ︙ | |||
522 523 524 525 526 527 528 |
zTime[5] = 0;
if( frid==selRid ){
@ <tr class='timelineSelected'>
}else{
@ <tr>
}
@ <td class="timelineTime">\
| | | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
zTime[5] = 0;
if( frid==selRid ){
@ <tr class='timelineSelected'>
}else{
@ <tr>
}
@ <td class="timelineTime">\
@ %z(href("%R/file?name=%T&ci=%!S",zFilename,zCkin))%s(zTime)</a></td>
@ <td class="timelineGraph"><div id="m%d(gidx)" class="tl-nodemark"></div>
@ </td>
if( zBgClr && zBgClr[0] ){
@ <td class="timeline%s(zStyle)Cell" id='mc%d(gidx)'>
}else{
@ <td class="timeline%s(zStyle)Cell">
}
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 |
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
| | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
if( tmFlags & (TIMELINE_COMPACT|TIMELINE_VERBOSE) ) cgi_printf("(");
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
@ file: %z(href("%R/file?name=%T&ci=%!S",zFilename,zCkin))[%S(zUuid)]</a>
if( fShowId ){
int srcId = delta_source_rid(frid);
if( srcId>0 ){
@ id: %d(frid)←%d(srcId)
}else{
@ id: %d(frid)
}
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
1338 1339 1340 1341 1342 1343 1344 | #define OBJTYPE_EXE 0x0100 #define OBJTYPE_FORUM 0x0200 /* ** Possible flags for the second parameter to ** object_description() */ | | < < < < < < < < < < < < | > | | 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 |
#define OBJTYPE_EXE 0x0100
#define OBJTYPE_FORUM 0x0200
/*
** Possible flags for the second parameter to
** object_description()
*/
#define OBJDESC_DETAIL 0x0001 /* Show more detail */
#define OBJDESC_BASE 0x0002 /* Set <base> using this object */
#endif
/*
** Write a description of an object to the www reply.
*/
int object_description(
int rid, /* The artifact ID for the object to describe */
u32 objdescFlags, /* Flags to control display */
const char *zFileName, /* For file objects, use this name. Can be NULL */
Blob *pDownloadName /* Fill with a good download name. Can be NULL */
){
Stmt q;
int cnt = 0;
int nWiki = 0;
int objType = 0;
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
int showDetail = (objdescFlags & OBJDESC_DETAIL)!=0;
|
| ︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 |
const char *zCom = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
const char *zVers = db_column_text(&q, 4);
int mPerm = db_column_int(&q, 5);
const char *zBr = db_column_text(&q, 6);
int szFile = db_column_int(&q,7);
int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0;
if( sameFilename && !showDetail ){
if( cnt==1 ){
@ %z(href("%R/whatis/%!S",zUuid))[more...]</a>
}
cnt++;
continue;
}
| > | 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 |
const char *zCom = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
const char *zVers = db_column_text(&q, 4);
int mPerm = db_column_int(&q, 5);
const char *zBr = db_column_text(&q, 6);
int szFile = db_column_int(&q,7);
int sameFilename = prevName!=0 && fossil_strcmp(zName,prevName)==0;
if( zFileName && fossil_strcmp(zName,zFileName)!=0 ) continue;
if( sameFilename && !showDetail ){
if( cnt==1 ){
@ %z(href("%R/whatis/%!S",zUuid))[more...]</a>
}
cnt++;
continue;
}
|
| ︙ | ︙ | |||
1669 1670 1671 1672 1673 1674 1675 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cookie_link_parameter("diff","diff","2");
diffType = atoi(PD("diff","2"));
cookie_render();
if( P("from") && P("to") ){
| | | | 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cookie_link_parameter("diff","diff","2");
diffType = atoi(PD("diff","2"));
cookie_render();
if( P("from") && P("to") ){
v1 = artifact_from_ci_and_filename("from");
v2 = artifact_from_ci_and_filename("to");
}else{
Stmt q;
v1 = name_to_rid_www("v1");
v2 = name_to_rid_www("v2");
/* If the two file versions being compared both have the same
** filename, then offer an "Annotate" link that constructs an
|
| ︙ | ︙ | |||
1745 1746 1747 1748 1749 1750 1751 |
if( P("smhdr")!=0 ){
@ <h2>Differences From Artifact
@ %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a> To
@ %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>.</h2>
}else{
@ <h2>Differences From
@ Artifact %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a>:</h2>
| | | | 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 |
if( P("smhdr")!=0 ){
@ <h2>Differences From Artifact
@ %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a> To
@ %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>.</h2>
}else{
@ <h2>Differences From
@ Artifact %z(href("%R/artifact/%!S",zV1))[%S(zV1)]</a>:</h2>
object_description(v1, objdescFlags,0, 0);
@ <h2>To Artifact %z(href("%R/artifact/%!S",zV2))[%S(zV2)]</a>:</h2>
object_description(v2, objdescFlags,0, 0);
}
if( pRe ){
@ <b>Only differences that match regular expression "%h(zRe)"
@ are shown.</b>
}
@ <hr />
append_diff(zV1, zV2, diffFlags, pRe);
|
| ︙ | ︙ | |||
1771 1772 1773 1774 1775 1776 1777 |
** Return the uninterpreted content of an artifact. Used primarily
** to view artifacts that are images.
*/
void rawartifact_page(void){
int rid = 0;
char *zUuid;
| | | | 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 |
** Return the uninterpreted content of an artifact. Used primarily
** to view artifacts that are images.
*/
void rawartifact_page(void){
int rid = 0;
char *zUuid;
if( P("ci") ){
rid = artifact_from_ci_and_filename(0);
}
if( rid==0 ){
rid = name_to_rid_www("name");
}
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
if( rid==0 ) fossil_redirect_home();
|
| ︙ | ︙ | |||
1935 1936 1937 1938 1939 1940 1941 |
if( g.perm.Setup ){
@ (%d(rid)):</h2>
}else{
@ :</h2>
}
blob_zero(&downloadName);
if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
| | | | | | | < < | < < | > > > > | | | < < < < < < | | | 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 |
if( g.perm.Setup ){
@ (%d(rid)):</h2>
}else{
@ :</h2>
}
blob_zero(&downloadName);
if( P("verbose")!=0 ) objdescFlags |= OBJDESC_DETAIL;
object_description(rid, objdescFlags, 0, &downloadName);
style_submenu_element("Download", "%s/raw/%T?name=%s",
g.zTop, blob_str(&downloadName), zUuid);
@ <hr />
content_get(rid, &content);
@ <blockquote><pre>
hexdump(&content);
@ </pre></blockquote>
style_footer();
}
/*
** Look for "ci" and "filename" query parameters. If found, try to
** use them to extract the record ID of an artifact for the file.
**
** Also look for "fn" and "name" as an aliases for "filename". If any
** "filename" or "fn" or "name" are present but "ci" is missing, then
** use "tip" as the default value for "ci".
**
** If zNameParam is not NULL, then use that parameter as the filename
** rather than "fn" or "filename" or "name". the zNameParam is used
** for the from= and to= query parameters of /fdiff.
*/
int artifact_from_ci_and_filename(const char *zNameParam){
const char *zFilename;
const char *zCI;
int cirid;
Manifest *pManifest;
ManifestFile *pFile;
int rid = 0;
if( zNameParam ){
zFilename = P(zNameParam);
}else{
zFilename = P("filename");
if( zFilename==0 ){
zFilename = P("fn");
}
if( zFilename==0 ){
zFilename = P("name");
}
}
if( zFilename==0 ) return 0;
zCI = PD("ci", "tip");
cirid = name_to_typed_rid(zCI, "ci");
if( cirid<=0 ) return 0;
pManifest = manifest_get(cirid, CFTYPE_MANIFEST, 0);
if( pManifest==0 ) return 0;
manifest_file_rewind(pManifest);
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
if( fossil_strcmp(zFilename, pFile->zName)==0 ){
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", pFile->zUuid);
break;
}
}
manifest_destroy(pManifest);
return rid;
}
/*
** The "z" argument is a string that contains the text of a source code
** file. This routine appends that text to the HTTP reply with line numbering.
**
** zLn is the ?ln= parameter for the HTTP query. If there is an argument,
|
| ︙ | ︙ | |||
2104 2105 2106 2107 2108 2109 2110 | ** ** ln - show line numbers ** ln=N - highlight line number N ** ln=M-N - highlight lines M through N inclusive ** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive) ** verbose - show more detail in the description ** download - redirect to the download (artifact page only) | | | | | > < | > | | | > > > > > > > > > | > > > > > > > | > > | | | > > > | > > > > > > > > > | | | > | | | | | < < | > | > | > > > | > > > > > | > | > > | < | > > > | | | | | | | | | | | < < < | | < < < < < < < < < < | | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > < | < | | > > > > > > > > > > > > > > > > | < > > | | 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 |
**
** ln - show line numbers
** ln=N - highlight line number N
** ln=M-N - highlight lines M through N inclusive
** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
** verbose - show more detail in the description
** download - redirect to the download (artifact page only)
** name=NAME - filename or hash as a query parameter
** filename=NAME - alternative spelling for "name="
** fn=NAME - alternative spelling for "name="
** ci=VERSION - The specific check-in to use with "name=" to
** identify the file.
**
** The /artifact page show the complete content of a file
** identified by HASH. The /whatis page shows only a description
** of how the artifact is used. The /file page shows the most recent
** version of the file or directory called NAME, or a list of the
** top-level directory if NAME is omitted.
**
** For /artifact and /whatis, the name= query parameter can refer to
** either the name of a file, or an artifact hash. If the ci= query
** parameter is also present, then name= must refer to a file name.
** If ci= is omitted, then the hash interpretation is preferred but
** if name= cannot be understood as a hash, a default "tip" value is
** used for ci=.
**
** For /file, name= can only be interpreted as a filename. As before,
** a default value of "tip" is used for ci= if ci= is omitted.
*/
void artifact_page(void){
int rid = 0;
Blob content;
const char *zMime;
Blob downloadName;
int renderAsWiki = 0;
int renderAsHtml = 0;
int objType;
int asText;
const char *zUuid = 0;
u32 objdescFlags = OBJDESC_BASE;
int descOnly = fossil_strcmp(g.zPath,"whatis")==0;
int isFile = fossil_strcmp(g.zPath,"file")==0;
const char *zLn = P("ln");
const char *zName = P("name");
const char *zCI = P("ci");
HQuery url;
char *zCIUuid = 0;
int isSymbolicCI = 0; /* ci= exists and is a symbolic name, not a hash */
int isBranchCI = 0; /* ci= refers to a branch name */
char *zHeader = 0;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
/* Capture and normalize the name= and ci= query parameters */
if( zName==0 ){
zName = P("filename");
if( zName==0 ){
zName = P("fn");
}
}
if( zCI && strlen(zCI)==0 ){ zCI = 0; }
if( zCI
&& name_to_uuid2(zCI, "ci", &zCIUuid)
&& sqlite3_strnicmp(zCIUuid, zCI, strlen(zCI))!=0
){
isSymbolicCI = 1;
isBranchCI = branch_includes_uuid(zCI, zCIUuid);
}
/* The name= query parameter (or at least one of its alternative
** spellings) is required. Except for /file, show a top-level
** directory listing if name= is omitted.
*/
if( zName==0 ){
if( isFile ){
if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
page_tree();
return;
}
style_header("Missing name= query parameter");
@ The name= query parameter is missing
style_footer();
return;
}
url_initialize(&url, g.zPath);
url_add_parameter(&url, "name", zName);
url_add_parameter(&url, "ci", zCI);
if( zCI==0 && !isFile ){
/* If there is no ci= query parameter, then prefer to interpret
** name= as a hash for /artifact and /whatis. But for not for /file.
** For /file, a name= without a ci= while prefer to use the default
** "tip" value for ci=. */
rid = name_to_rid(zName);
}
if( rid==0 ){
rid = artifact_from_ci_and_filename(0);
}
if( rid==0 ){ /* Artifact not found */
if( isFile ){
/* For /file, also check to see if name= refers to a directory,
** and if so, do a listing for that directory */
int nName = (int)strlen(zName);
if( nName && zName[nName-1]=='/' ) nName--;
if( db_exists(
"SELECT 1 FROM filename"
" WHERE name GLOB '%.*q/*' AND substr(name,1,%d)=='%.*q/';",
nName, zName, nName+1, nName, zName
) ){
if( P("ci")==0 ) cgi_set_query_parameter("ci","tip");
page_tree();
return;
}
style_header("No such file");
@ File '%h(zName)' does not exist in this repository.
}else{
style_header("No such artifact");
@ Artifact '%h(zName)' does not exist in this repository.
}
style_footer();
return;
}
if( descOnly || P("verbose")!=0 ){
url_add_parameter(&url, "verbose", "1");
objdescFlags |= OBJDESC_DETAIL;
}
zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid);
asText = P("txt")!=0;
if( isFile ){
if( zCI==0 || fossil_strcmp(zCI,"tip")==0 ){
zCI = "tip";
@ <h2>File %z(href("%R/finfo?name=%T&m=tip",zName))%h(zName)</a>
@ from the %z(href("%R/info/tip"))latest check-in</a></h2>
}else{
const char *zPath;
Blob path;
blob_zero(&path);
hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO);
zPath = blob_str(&path);
@ <h2>File %s(zPath) \
if( isBranchCI ){
@ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
}else if( isSymbolicCI ){
@ as of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
}else{
@ as of check-in [%z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a>]</h2>
}
blob_reset(&path);
}
style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
zName, zCI);
style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
zName, zCI);
blob_init(&downloadName, zName, -1);
objType = OBJTYPE_CONTENT;
}else{
@ <h2>Artifact
style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
if( g.perm.Setup ){
@ (%d(rid)):</h2>
}else{
@ :</h2>
}
blob_zero(&downloadName);
if( asText ) objdescFlags &= ~OBJDESC_BASE;
objType = object_description(rid, objdescFlags,
(isFile?zName:0), &downloadName);
}
if( !descOnly && P("download")!=0 ){
cgi_redirectf("%R/raw/%T?name=%s", blob_str(&downloadName),
db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid));
/*NOTREACHED*/
}
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
style_submenu_element("Unshun", "%s/shun?accept=%s&sub=1#accshun",
g.zTop, zUuid);
}else{
style_submenu_element("Shun", "%s/shun?shun=%s#addshun", g.zTop, zUuid);
}
}
if( isFile ){
if( isSymbolicCI ){
zHeader = mprintf("%s at %s", file_tail(zName), zCI);
}else if( zCI ){
zHeader = mprintf("%s at [%S]", file_tail(zName), zCIUuid);
}else{
zHeader = mprintf("%s", file_tail(zName));
}
}else if( descOnly ){
zHeader = mprintf("Artifact Description [%S]", zUuid);
}else{
zHeader = mprintf("Artifact [%S]", zUuid);
}
style_header("%s", zHeader);
fossil_free(zCIUuid);
fossil_free(zHeader);
if( !isFile && g.perm.Admin ){
Stmt q;
db_prepare(&q,
"SELECT coalesce(user.login,rcvfrom.uid),"
" datetime(rcvfrom.mtime,toLocal()), rcvfrom.ipaddr"
" FROM blob, rcvfrom LEFT JOIN user ON user.uid=rcvfrom.uid"
" WHERE blob.rid=%d"
" AND rcvfrom.rcvid=blob.rcvid;", rid);
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
1734 1735 1736 1737 1738 1739 1740 |
@ <td><input type="password" name="cp" value="%h(zConfirm)" size="30"></td>
@ </tr>
if( iErrLine==5 ){
@ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr>
}
@ <tr>
@ <td class="form_label" align="right">Captcha:</td>
| | | 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 |
@ <td><input type="password" name="cp" value="%h(zConfirm)" size="30"></td>
@ </tr>
if( iErrLine==5 ){
@ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr>
}
@ <tr>
@ <td class="form_label" align="right">Captcha:</td>
@ <td><input type="text" name="captcha" \
@ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
captcha_speakit_button(uSeed, "Speak the captcha text");
@ </td>
@ </tr>
if( iErrLine==6 ){
@ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr>
}
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
129 130 131 132 133 134 135 136 137 138 139 140 141 142 | $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ $(SRCDIR)/style.c \ $(SRCDIR)/sync.c \ $(SRCDIR)/tag.c \ $(SRCDIR)/tar.c \ $(SRCDIR)/th_main.c \ $(SRCDIR)/timeline.c \ $(SRCDIR)/tkt.c \ $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/unicode.c \ $(SRCDIR)/unversioned.c \ | > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ $(SRCDIR)/style.c \ $(SRCDIR)/sync.c \ $(SRCDIR)/tag.c \ $(SRCDIR)/tar.c \ $(SRCDIR)/terminal.c \ $(SRCDIR)/th_main.c \ $(SRCDIR)/timeline.c \ $(SRCDIR)/tkt.c \ $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/unicode.c \ $(SRCDIR)/unversioned.c \ |
| ︙ | ︙ | |||
362 363 364 365 366 367 368 369 370 371 372 373 374 375 | $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ $(OBJDIR)/style_.c \ $(OBJDIR)/sync_.c \ $(OBJDIR)/tag_.c \ $(OBJDIR)/tar_.c \ $(OBJDIR)/th_main_.c \ $(OBJDIR)/timeline_.c \ $(OBJDIR)/tkt_.c \ $(OBJDIR)/tktsetup_.c \ $(OBJDIR)/undo_.c \ $(OBJDIR)/unicode_.c \ $(OBJDIR)/unversioned_.c \ | > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ $(OBJDIR)/style_.c \ $(OBJDIR)/sync_.c \ $(OBJDIR)/tag_.c \ $(OBJDIR)/tar_.c \ $(OBJDIR)/terminal_.c \ $(OBJDIR)/th_main_.c \ $(OBJDIR)/timeline_.c \ $(OBJDIR)/tkt_.c \ $(OBJDIR)/tktsetup_.c \ $(OBJDIR)/undo_.c \ $(OBJDIR)/unicode_.c \ $(OBJDIR)/unversioned_.c \ |
| ︙ | ︙ | |||
504 505 506 507 508 509 510 511 512 513 514 515 516 517 | $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ $(OBJDIR)/style.o \ $(OBJDIR)/sync.o \ $(OBJDIR)/tag.o \ $(OBJDIR)/tar.o \ $(OBJDIR)/th_main.o \ $(OBJDIR)/timeline.o \ $(OBJDIR)/tkt.o \ $(OBJDIR)/tktsetup.o \ $(OBJDIR)/undo.o \ $(OBJDIR)/unicode.o \ $(OBJDIR)/unversioned.o \ | > | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | $(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 \ |
| ︙ | ︙ | |||
841 842 843 844 845 846 847 848 849 850 851 852 853 854 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \ $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \ $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \ $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \ $(OBJDIR)/unversioned_.c:$(OBJDIR)/unversioned.h \ | > | 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \ $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \ $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \ $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \ $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \ $(OBJDIR)/unversioned_.c:$(OBJDIR)/unversioned.h \ |
| ︙ | ︙ | |||
1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 | $(OBJDIR)/tar_.c: $(SRCDIR)/tar.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/tar.c >$@ $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c $(OBJDIR)/tar.h: $(OBJDIR)/headers $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/th_main.c >$@ $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c | > > > > > > > > | 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 | $(OBJDIR)/tar_.c: $(SRCDIR)/tar.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/tar.c >$@ $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c $(OBJDIR)/tar.h: $(OBJDIR)/headers $(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/terminal.c >$@ $(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h: $(OBJDIR)/headers $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/th_main.c >$@ $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c |
| ︙ | ︙ |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 149 150 151 152 | stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned | > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned |
| ︙ | ︙ |
Changes to src/merge3.c.
| ︙ | ︙ | |||
137 138 139 140 141 142 143 |
/*
** Text of boundary markers for merge conflicts.
*/
static const char *const mergeMarker[] = {
/*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
"<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<\n",
| | | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
/*
** Text of boundary markers for merge conflicts.
*/
static const char *const mergeMarker[] = {
/*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
"<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<\n",
"||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||||||\n",
"======= MERGED IN content follows ==================================\n",
">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
};
/*
** Do a three-way merge. Initialize pOut to contain the result.
|
| ︙ | ︙ |
Changes to src/mkversion.c.
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 |
/*
** This C program generates the "VERSION.h" header file from information
** extracted out of the "manifest", "manifest.uuid", and "VERSION" files.
** Call this program with three arguments:
**
** ./a.out manifest.uuid manifest VERSION
**
** Note that the manifest.uuid and manifest files are generated by Fossil.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static FILE *open_for_reading(const char *zFilename){
FILE *f = fopen(zFilename, "r");
if( f==0 ){
fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename);
exit(1);
}
return f;
}
int main(int argc, char *argv[]){
FILE *m,*u,*v;
char *z;
#if defined(__DMC__) /* e.g. 0x857 */
int i = 0;
#endif
int j = 0, x = 0, d = 0;
int vn[3];
char b[1000];
char vx[1000];
if( argc!=4 ){
fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]);
exit(1);
}
memset(b,0,sizeof(b));
memset(vx,0,sizeof(vx));
u = open_for_reading(argv[1]);
if( fgets(b, sizeof(b)-1,u)==0 ){
fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]);
exit(1);
}
fclose(u);
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
*z = 0;
printf("#define MANIFEST_UUID \"%s\"\n",b);
printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
m = open_for_reading(argv[2]);
while(b == fgets(b, sizeof(b)-1,m)){
if(0 == strncmp("D ",b,2)){
int k, n;
char zDateNum[30];
printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13);
printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2);
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
/*
** This C program generates the "VERSION.h" header file from information
** extracted out of the "manifest", "manifest.uuid", and "VERSION" files.
** Call this program with three arguments:
**
** ./a.out manifest.uuid manifest VERSION
**
** Note that the manifest.uuid and manifest files are generated by Fossil.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
static FILE *open_for_reading(const char *zFilename){
FILE *f = fopen(zFilename, "r");
if( f==0 ){
fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename);
exit(1);
}
return f;
}
/*
** Given an arbitrary-length input string key zIn, generate
** an N-byte hexadecimal hash of that string into zOut.
*/
static void hash(const char *zIn, int N, char *zOut){
unsigned char i, j, t;
int m, n;
unsigned char s[256];
for(m=0; m<256; m++){ s[m] = m; }
for(j=0, m=n=0; m<256; m++, n++){
j += s[m] + zIn[n];
if( zIn[n]==0 ){ n = -1; }
t = s[j];
s[j] = s[m];
s[m] = t;
}
i = j = 0;
for(n=0; n<N-2; n+=2){
i++;
t = s[i];
j += t;
s[i] = s[j];
s[j] = t;
t += s[i];
zOut[n] = "0123456789abcdef"[(t>>4)&0xf];
zOut[n+1] = "0123456789abcdef"[t&0xf];
}
zOut[n] = 0;
}
int main(int argc, char *argv[]){
FILE *m,*u,*v;
char *z;
#if defined(__DMC__) /* e.g. 0x857 */
int i = 0;
#endif
int j = 0, x = 0, d = 0;
size_t n;
int vn[3];
char b[1000];
char vx[1000];
if( argc!=4 ){
fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]);
exit(1);
}
memset(b,0,sizeof(b));
memset(vx,0,sizeof(vx));
u = open_for_reading(argv[1]);
if( fgets(b, sizeof(b)-1,u)==0 ){
fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]);
exit(1);
}
fclose(u);
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
*z = 0;
printf("#define MANIFEST_UUID \"%s\"\n",b);
printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
n = strlen(b);
if( n + 50 < sizeof(b) ){
sprintf(b+n, "%d", (int)time(0));
hash(b,33,vx);
printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx);
}
m = open_for_reading(argv[2]);
while(b == fgets(b, sizeof(b)-1,m)){
if(0 == strncmp("D ",b,2)){
int k, n;
char zDateNum[30];
printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13);
printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2);
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
612 613 614 615 616 617 618 |
canonical16(z, strlen(z));
db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
int rid = db_column_int(&q, 1);
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
| | | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
canonical16(z, strlen(z));
db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
int rid = db_column_int(&q, 1);
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
object_description(rid, 0, 0, 0);
@ </p></li>
}
db_finalize(&q);
db_prepare(&q,
" SELECT tkt_rid, tkt_uuid, title"
" FROM ticket, ticketchng"
" WHERE ticket.tkt_id = ticketchng.tkt_id"
|
| ︙ | ︙ | |||
634 635 636 637 638 639 640 |
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
@ <ul></ul>
@ Ticket
hyperlink_to_uuid(zUuid);
@ - %h(zTitle).
@ <ul><li>
| | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
@ <ul></ul>
@ Ticket
hyperlink_to_uuid(zUuid);
@ - %h(zTitle).
@ <ul><li>
object_description(rid, 0, 0, 0);
@ </li></ul>
@ </p></li>
}
db_finalize(&q);
db_prepare(&q,
"SELECT rid, uuid FROM"
" (SELECT tagxref.rid AS rid, substr(tagname, 7) AS uuid"
" FROM tagxref, tag WHERE tagxref.tagid = tag.tagid"
" AND tagname GLOB 'event-%q*') GROUP BY uuid", z);
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q, 0);
const char* zUuid = db_column_text(&q, 1);
@ <li><p><a href="%R/%T(zSrc)/%!S(zUuid)">
@ %s(zUuid)</a> -
@ <ul><li>
object_description(rid, 0, 0, 0);
@ </li></ul>
@ </p></li>
}
@ </ol>
db_finalize(&q);
style_footer();
}
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
874 875 876 877 878 879 880 881 882 883 884 885 886 887 |
} else {
@ <br />
}
}
}
@ <br /><input type="submit" name="submit" value="Apply Changes" />
@ </td><td style="width:50px;"></td><td valign="top">
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
if( pSet->width>0 && !pSet->forceTextArea ){
int hasVersionableValue = pSet->versionable &&
(db_get_versioned(pSet->name, NULL)!=0);
entry_attribute("", /*pSet->width*/ 25, pSet->name,
pSet->var!=0 ? pSet->var : pSet->name,
(char*)pSet->def, hasVersionableValue);
| > > > > > > > > > < < < < | | | < > | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 |
} else {
@ <br />
}
}
}
@ <br /><input type="submit" name="submit" value="Apply Changes" />
@ </td><td style="width:50px;"></td><td valign="top">
@ <table>
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
if( pSet->width>0 && !pSet->forceTextArea ){
int hasVersionableValue = pSet->versionable &&
(db_get_versioned(pSet->name, NULL)!=0);
@ <tr><td>
@ <a href='%R/help?cmd=%s(pSet->name)'>%h(pSet->name)</a>
if( pSet->versionable ){
@ (v)
} else {
@
}
@</td><td>
entry_attribute("", /*pSet->width*/ 25, pSet->name,
pSet->var!=0 ? pSet->var : pSet->name,
(char*)pSet->def, hasVersionableValue);
@</td></tr>
}
}
@</table>
@ </td><td style="width:50px;"></td><td valign="top">
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
if( pSet->width>0 && pSet->forceTextArea ){
int hasVersionableValue = db_get_versioned(pSet->name, NULL)!=0;
@ <a href='%R/help?cmd=%s(pSet->name)'>%s(pSet->name)</a>
if( pSet->versionable ){
@ (v)<br />
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 |
void *notUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
const unsigned char *zA = (const unsigned char*)pKey1;
const unsigned char *zB = (const unsigned char*)pKey2;
int i=0, j=0, x;
while( i<nKey1 && j<nKey2 ){
x = zA[i] - zB[j];
if( isdigit(zA[i]) ){
int k;
if( !isdigit(zB[j]) ) return x;
while( i<nKey1 && zA[i]=='0' ){ i++; }
while( j<nKey2 && zB[j]=='0' ){ j++; }
| > | 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 |
void *notUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
const unsigned char *zA = (const unsigned char*)pKey1;
const unsigned char *zB = (const unsigned char*)pKey2;
int i=0, j=0, x;
(void)notUsed;
while( i<nKey1 && j<nKey2 ){
x = zA[i] - zB[j];
if( isdigit(zA[i]) ){
int k;
if( !isdigit(zB[j]) ) return x;
while( i<nKey1 && zA[i]=='0' ){ i++; }
while( j<nKey2 && zB[j]=='0' ){ j++; }
|
| ︙ | ︙ | |||
11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 |
zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc==SQLITE_OK ){
while( sqlite3_step(pExplain)==SQLITE_ROW ){
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
int iEqpId = sqlite3_column_int(pExplain, 0);
int iParentId = sqlite3_column_int(pExplain, 1);
if( zEQPLine[0]=='-' ) eqp_render(pArg);
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
}
eqp_render(pArg);
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
| > | 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 11828 11829 |
zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc==SQLITE_OK ){
while( sqlite3_step(pExplain)==SQLITE_ROW ){
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
int iEqpId = sqlite3_column_int(pExplain, 0);
int iParentId = sqlite3_column_int(pExplain, 1);
if( zEQPLine==0 ) zEQPLine = "";
if( zEQPLine[0]=='-' ) eqp_render(pArg);
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
}
eqp_render(pArg);
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
|
| ︙ | ︙ | |||
13723 13724 13725 13726 13727 13728 13729 |
unsigned char aHdr[100];
open_db(p, 0);
if( p->db==0 ) return 1;
rc = sqlite3_prepare_v2(p->db,
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
-1, &pStmt, 0);
if( rc ){
| < < < < | < | 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 |
unsigned char aHdr[100];
open_db(p, 0);
if( p->db==0 ) return 1;
rc = sqlite3_prepare_v2(p->db,
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
-1, &pStmt, 0);
if( rc ){
utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
return 1;
}
sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
if( sqlite3_step(pStmt)==SQLITE_ROW
&& sqlite3_column_bytes(pStmt,0)>100
){
|
| ︙ | ︙ | |||
17002 17003 17004 17005 17006 17007 17008 |
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
){
const char *zFile = 0;
int bTxtMode = 0;
int i;
int eMode = 0;
int bBOM = 0;
| | | 16999 17000 17001 17002 17003 17004 17005 17006 17007 17008 17009 17010 17011 17012 17013 |
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
){
const char *zFile = 0;
int bTxtMode = 0;
int i;
int eMode = 0;
int bBOM = 0;
int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
if( c=='e' ){
eMode = 'x';
bOnce = 2;
}else if( strncmp(azArg[0],"once",n)==0 ){
bOnce = 1;
}
|
| ︙ | ︙ |
Changes to src/shun.c.
| ︙ | ︙ | |||
185 186 187 188 189 190 191 | @ or artifacts that by design or accident interfere with the processing @ of the repository. Do not shun artifacts merely to remove them from @ sight - set the "hidden" tag on such artifacts instead.</p> @ @ <blockquote> @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div> login_insert_csrf_secret(); | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
@ or artifacts that by design or accident interfere with the processing
@ of the repository. Do not shun artifacts merely to remove them from
@ sight - set the "hidden" tag on such artifacts instead.</p>
@
@ <blockquote>
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
login_insert_csrf_secret();
@ <textarea class="fullsize-text" cols="70" rows="%d(numRows)" name="uuid">
if( zShun ){
if( strlen(zShun) ){
@ %h(zShun)
}else if( nRcvid ){
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
while( db_step(&q)==SQLITE_ROW ){
@ %s(db_column_text(&q, 0))
|
| ︙ | ︙ | |||
212 213 214 215 216 217 218 | @ restored because the content is unknown. The only change is that @ the formerly shunned artifacts will be accepted on subsequent sync @ operations.</p> @ @ <blockquote> @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div> login_insert_csrf_secret(); | | | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
@ restored because the content is unknown. The only change is that
@ the formerly shunned artifacts will be accepted on subsequent sync
@ operations.</p>
@
@ <blockquote>
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
login_insert_csrf_secret();
@ <textarea class="fullsize-text" cols="70" rows="%d(numRows)" name="uuid">
if( zAccept ){
if( strlen(zAccept) ){
@ %h(zAccept)
}else if( nRcvid ){
db_prepare(&q, "SELECT uuid FROM blob WHERE rcvid=%d", nRcvid);
while( db_step(&q)==SQLITE_ROW ){
@ %s(db_column_text(&q, 0))
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
214 215 216 217 218 219 220 221 222 223 224 225 226 227 | #endif #if SQLITE_ENABLE_ATOMIC_WRITE "ENABLE_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_BATCH_ATOMIC_WRITE "ENABLE_BATCH_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_CEROD "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), #endif #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif #if SQLITE_ENABLE_COLUMN_USED_MASK | > > > | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | #endif #if SQLITE_ENABLE_ATOMIC_WRITE "ENABLE_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_BATCH_ATOMIC_WRITE "ENABLE_BATCH_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_BYTECODE_VTAB "ENABLE_BYTECODE_VTAB", #endif #if SQLITE_ENABLE_CEROD "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), #endif #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif #if SQLITE_ENABLE_COLUMN_USED_MASK |
| ︙ | ︙ | |||
532 533 534 535 536 537 538 | #endif #if SQLITE_OMIT_BETWEEN_OPTIMIZATION "OMIT_BETWEEN_OPTIMIZATION", #endif #if SQLITE_OMIT_BLOB_LITERAL "OMIT_BLOB_LITERAL", #endif | < < < | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | #endif #if SQLITE_OMIT_BETWEEN_OPTIMIZATION "OMIT_BETWEEN_OPTIMIZATION", #endif #if SQLITE_OMIT_BLOB_LITERAL "OMIT_BLOB_LITERAL", #endif #if SQLITE_OMIT_CAST "OMIT_CAST", #endif #if SQLITE_OMIT_CHECK "OMIT_CHECK", #endif #if SQLITE_OMIT_COMPLETE |
| ︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.32.0" #define SQLITE_VERSION_NUMBER 3032000 | | | 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.32.0" #define SQLITE_VERSION_NUMBER 3032000 #define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff" /* ** 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 |
| ︙ | ︙ | |||
1334 1335 1336 1337 1338 1339 1340 1341 | ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** ^If the database connection is associated with unfinalized prepared | > > > > | | | | > > | | | | | < < < < < < < < < < | 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 | ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** Ideally, applications should [sqlite3_finalize | finalize] all ** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated ** with the [sqlite3] object prior to attempting to close the object. ** ^If the database connection is associated with unfinalized prepared ** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then ** sqlite3_close() will leave the database connection open and return ** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared ** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups, ** it returns [SQLITE_OK] regardless, but instead of deallocating the database ** connection immediately, it marks the database connection as an unusable ** "zombie" and makes arrangements to automatically deallocate the database ** connection after all prepared statements are finalized, all BLOB handles ** are closed, and all backups have finished. The sqlite3_close_v2() interface ** is intended for use with host languages that are garbage collected, and ** where the order in which destructors are called is arbitrary. ** ** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained |
| ︙ | ︙ | |||
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) #define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) | > > > | 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) #define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| ︙ | ︙ | |||
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 | ** omits changes made by other database connections. The ** [PRAGMA data_version] command provides a mechanism to detect changes to ** a single attached database that occur due to other database connections, ** but omits changes implemented by the database connection on which it is ** called. This file control is the only mechanism to detect changes that ** happen either internally or externally and that are associated with ** a particular attached database. ** ** <li>[[SQLITE_FCNTL_CKPT_DONE]] ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** </ul> | > > > > > | 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 | ** omits changes made by other database connections. The ** [PRAGMA data_version] command provides a mechanism to detect changes to ** a single attached database that occur due to other database connections, ** but omits changes implemented by the database connection on which it is ** called. This file control is the only mechanism to detect changes that ** happen either internally or externally and that are associated with ** a particular attached database. ** ** <li>[[SQLITE_FCNTL_CKPT_START]] ** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint ** in wal mode before the client starts to copy pages from the wal ** file to the database file. ** ** <li>[[SQLITE_FCNTL_CKPT_DONE]] ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** </ul> |
| ︙ | ︙ | |||
2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 | #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 #define SQLITE_FCNTL_SIZE_LIMIT 36 #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO | > | 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 | #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 #define SQLITE_FCNTL_SIZE_LIMIT 36 #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
| ︙ | ︙ | |||
4571 4572 4573 4574 4575 4576 4577 | /* ** CAPI3REF: Obtain Values For URI Parameters ** ** These are utility routines, useful to [VFS|custom VFS implementations], ** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** | > > > > | | > > > > > > > | 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 | /* ** CAPI3REF: Obtain Values For URI Parameters ** ** These are utility routines, useful to [VFS|custom VFS implementations], ** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** ** The first parameter to these interfaces (hereafter referred to ** as F) must be one of: ** <ul> ** <li> A database filename pointer created by the SQLite core and ** passed into the xOpen() method of a VFS implemention, or ** <li> A filename obtained from [sqlite3_db_filename()], or ** <li> A new filename constructed using [sqlite3_create_filename()]. ** </ul> ** If the F parameter is not one of the above, then the behavior is ** undefined and probably undesirable. Older versions of SQLite were ** more tolerant of invalid F parameters than newer versions. ** ** If F is a suitable filename (as described in the previous paragraph) ** and if P is the name of the query parameter, then ** sqlite3_uri_parameter(F,P) returns the value of the P ** parameter if it exists or a NULL pointer if P does not appear as a ** query parameter on F. If P is a query parameter of F and it ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. ** |
| ︙ | ︙ | |||
4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 | ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ SQLITE_API const char *sqlite3_filename_database(const char*); SQLITE_API const char *sqlite3_filename_journal(const char*); SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of | > > > > > > > > > > > > > > > > > > > | 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 | ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ SQLITE_API const char *sqlite3_filename_database(const char*); SQLITE_API const char *sqlite3_filename_journal(const char*); SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is ** passed into the xOpen method of [sqlite3_vfs], then ** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file] ** object that represents the main database file. ** ** This routine is intended for use in custom [VFS] implementations ** only. It is not a general-purpose interface. ** The argument sqlite3_file_object(X) must be a filename pointer that ** has been passed into [sqlite3_vfs].xOpen method where the ** flags parameter to xOpen contains one of the bits ** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use ** of this routine results in undefined and probably undesirable ** behavior. */ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| ︙ | ︙ | |||
4689 4690 4691 4692 4693 4694 4695 | ** pointer if N is zero. None of the 2*N pointers in the P array may be ** NULL pointers and key pointers should not be empty strings. ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may ** be NULL pointers, though they can be empty strings. ** ** The sqlite3_free_filename(Y) routine releases a memory allocation ** previously obtained from sqlite3_create_filename(). Invoking | | | 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 | ** pointer if N is zero. None of the 2*N pointers in the P array may be ** NULL pointers and key pointers should not be empty strings. ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may ** be NULL pointers, though they can be empty strings. ** ** The sqlite3_free_filename(Y) routine releases a memory allocation ** previously obtained from sqlite3_create_filename(). Invoking ** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op. ** ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap ** corruption or segfaults may occur. The value Y should be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, |
| ︙ | ︙ | |||
14500 14501 14502 14503 14504 14505 14506 |
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
int (*xBusyHandler)(void *,int); /* The busy callback */
void *pBusyArg; /* First arg to busy callback */
int nBusy; /* Incremented with each busy call */
| < | 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 |
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
int (*xBusyHandler)(void *,int); /* The busy callback */
void *pBusyArg; /* First arg to busy callback */
int nBusy; /* Incremented with each busy call */
};
/*
** Name of the master database table. The master database table
** is a special table that holds the names and attributes of all
** user tables and indices.
*/
|
| ︙ | ︙ | |||
15020 15021 15022 15023 15024 15025 15026 | SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); #ifndef NDEBUG SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); #endif SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*); | < < | 15054 15055 15056 15057 15058 15059 15060 15061 15062 15063 15064 15065 15066 15067 15068 | SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); #ifndef NDEBUG SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); #endif SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*); SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*); #ifdef SQLITE_TEST SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); #endif #ifndef SQLITE_OMIT_WAL |
| ︙ | ︙ | |||
15597 15598 15599 15600 15601 15602 15603 15604 15605 15606 15607 15608 15609 15610 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on ** each VDBE opcode. ** ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op ** comments in VDBE programs that show key decision points in the code ** generator. | > > > | 15629 15630 15631 15632 15633 15634 15635 15636 15637 15638 15639 15640 15641 15642 15643 15644 15645 | typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); #ifdef SQLITE_ENABLE_BYTECODE_VTAB SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); #endif /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on ** each VDBE opcode. ** ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op ** comments in VDBE programs that show key decision points in the code ** generator. |
| ︙ | ︙ | |||
15882 15883 15884 15885 15886 15887 15888 | #ifndef SQLITE_OMIT_WAL SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*); SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); # ifdef SQLITE_ENABLE_SNAPSHOT | | | > > > > > > > > | 15917 15918 15919 15920 15921 15922 15923 15924 15925 15926 15927 15928 15929 15930 15931 15932 15933 15934 15935 15936 15937 15938 15939 15940 15941 15942 15943 15944 15945 | #ifndef SQLITE_OMIT_WAL SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*); SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); # ifdef SQLITE_ENABLE_SNAPSHOT SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot); SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot); SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager); # endif #endif #if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT) SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager*, int); SQLITE_PRIVATE void sqlite3PagerWalDb(Pager*, sqlite3*); #else # define sqlite3PagerWalWriteLock(y,z) SQLITE_OK # define sqlite3PagerWalDb(x,y) #endif #ifdef SQLITE_DIRECT_OVERFLOW_READ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno); #endif #ifdef SQLITE_ENABLE_ZIPVFS SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); |
| ︙ | ︙ | |||
15915 15916 15917 15918 15919 15920 15921 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); | < < < < < | 15958 15959 15960 15961 15962 15963 15964 15965 15966 15967 15968 15969 15970 15971 | SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); /* Functions used to truncate the database file. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16); /* Functions to support testing and debugging. */ |
| ︙ | ︙ | |||
16853 16854 16855 16856 16857 16858 16859 16860 16861 16862 16863 16864 16865 16866 | VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ #endif Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Savepoint *pSavepoint; /* List of active savepoints */ int busyTimeout; /* Busy handler timeout, in msec */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY | > | 16891 16892 16893 16894 16895 16896 16897 16898 16899 16900 16901 16902 16903 16904 16905 | VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ #endif Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Savepoint *pSavepoint; /* List of active savepoints */ int nAnalysisLimit; /* Number of index rows to ANALYZE */ int busyTimeout; /* Busy handler timeout, in msec */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| ︙ | ︙ | |||
19898 19899 19900 19901 19902 19903 19904 | SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*); SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); | | | 19937 19938 19939 19940 19941 19942 19943 19944 19945 19946 19947 19948 19949 19950 19951 | SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*); SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*); SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); |
| ︙ | ︙ | |||
20634 20635 20636 20637 20638 20639 20640 | #endif /* ** VDBE_DISPLAY_P4 is true or false depending on whether or not the ** "explain" P4 display logic is enabled. */ #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ | | > | 20673 20674 20675 20676 20677 20678 20679 20680 20681 20682 20683 20684 20685 20686 20687 20688 |
#endif
/*
** VDBE_DISPLAY_P4 is true or false depending on whether or not the
** "explain" P4 display logic is enabled.
*/
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
|| defined(SQLITE_ENABLE_BYTECODE_VTAB)
# define VDBE_DISPLAY_P4 1
#else
# define VDBE_DISPLAY_P4 0
#endif
/*
** SQL is translated into a sequence of instructions to be
|
| ︙ | ︙ | |||
21099 21100 21101 21102 21103 21104 21105 | SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); | > > > > > > > | | 21139 21140 21141 21142 21143 21144 21145 21146 21147 21148 21149 21150 21151 21152 21153 21154 21155 21156 21157 21158 21159 21160 | SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**); SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*); #endif #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*); #endif #if !defined(SQLITE_OMIT_EXPLAIN) SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); #endif SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); |
| ︙ | ︙ | |||
21141 21142 21143 21144 21145 21146 21147 | SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif | | | 21188 21189 21190 21191 21192 21193 21194 21195 21196 21197 21198 21199 21200 21201 21202 | SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) SQLITE_PRIVATE const char *sqlite3OpcodeName(int); #endif SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*); |
| ︙ | ︙ | |||
27314 27315 27316 27317 27318 27319 27320 |
return priorLimit;
}
if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
n = mem0.hardLimit;
}
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
| | | 27361 27362 27363 27364 27365 27366 27367 27368 27369 27370 27371 27372 27373 27374 27375 |
return priorLimit;
}
if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
n = mem0.hardLimit;
}
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
SQLITE_API void sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
|
| ︙ | ︙ | |||
27382 27383 27384 27385 27386 27387 27388 |
/*
** Return true if the heap is currently under memory pressure - in other
** words if the amount of heap used is close to the limit set by
** sqlite3_soft_heap_limit().
*/
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
| | | 27429 27430 27431 27432 27433 27434 27435 27436 27437 27438 27439 27440 27441 27442 27443 |
/*
** Return true if the heap is currently under memory pressure - in other
** words if the amount of heap used is close to the limit set by
** sqlite3_soft_heap_limit().
*/
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
return AtomicLoad(&mem0.nearlyFull);
}
/*
** Deinitialize the memory allocation subsystem.
*/
SQLITE_PRIVATE void sqlite3MallocEnd(void){
if( sqlite3GlobalConfig.m.xShutdown ){
|
| ︙ | ︙ | |||
27446 27447 27448 27449 27450 27451 27452 |
** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
| | | | 27493 27494 27495 27496 27497 27498 27499 27500 27501 27502 27503 27504 27505 27506 27507 27508 27509 27510 27511 27512 27513 27514 27515 27516 27517 |
** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
AtomicStore(&mem0.nearlyFull, 1);
sqlite3MallocAlarm(nFull);
if( mem0.hardLimit ){
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.hardLimit - nFull ){
*pp = 0;
return;
}
}
}else{
AtomicStore(&mem0.nearlyFull, 0);
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( p==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
| ︙ | ︙ | |||
27685 27686 27687 27688 27689 27690 27691 27692 27693 27694 27695 27696 27697 27698 27699 27700 27701 27702 |
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
}
sqlite3_mutex_leave(mem0.mutex);
}else{
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
| > > | 27732 27733 27734 27735 27736 27737 27738 27739 27740 27741 27742 27743 27744 27745 27746 27747 27748 27749 27750 27751 |
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
}
sqlite3_mutex_leave(mem0.mutex);
}else{
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
|
| ︙ | ︙ | |||
34926 34927 34928 34929 34930 34931 34932 34933 |
# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
#else
static int osSetPosixAdvisoryLock(
int h, /* The file descriptor on which to take the lock */
struct flock *pLock, /* The description of the lock */
unixFile *pFile /* Structure holding timeout value */
){
int rc = osFcntl(h,F_SETLK,pLock);
| > | | | 34975 34976 34977 34978 34979 34980 34981 34982 34983 34984 34985 34986 34987 34988 34989 34990 34991 34992 34993 34994 34995 34996 34997 34998 34999 |
# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
#else
static int osSetPosixAdvisoryLock(
int h, /* The file descriptor on which to take the lock */
struct flock *pLock, /* The description of the lock */
unixFile *pFile /* Structure holding timeout value */
){
int tm = pFile->iBusyTimeout;
int rc = osFcntl(h,F_SETLK,pLock);
while( rc<0 && tm>0 ){
/* On systems that support some kind of blocking file lock with a timeout,
** make appropriate changes here to invoke that blocking file lock. On
** generic posix, however, there is no such API. So we simply try the
** lock once every millisecond until either the timeout expires, or until
** the lock is obtained. */
usleep(1000);
rc = osFcntl(h,F_SETLK,pLock);
tm--;
}
return rc;
}
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
/*
|
| ︙ | ︙ | |||
37677 37678 37679 37680 37681 37682 37683 37684 37685 37686 37687 37688 |
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
| > | > > > > | > > | 37727 37728 37729 37730 37731 37732 37733 37734 37735 37736 37737 37738 37739 37740 37741 37742 37743 37744 37745 37746 37747 37748 37749 37750 37751 37752 37753 37754 |
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
int res;
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
if( res==-1 ){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
#else
rc = SQLITE_BUSY;
#endif
}
}
/* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
|
| ︙ | ︙ | |||
38180 38181 38182 38183 38184 38185 38186 |
|| flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
| | | | < < | > > | > | | 38237 38238 38239 38240 38241 38242 38243 38244 38245 38246 38247 38248 38249 38250 38251 38252 38253 38254 38255 38256 38257 38258 38259 38260 38261 38262 38263 38264 38265 38266 38267 |
|| flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Check that, if this to be a blocking lock, no locks that occur later
** in the following list than the lock being obtained are already held:
**
** 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. */
#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))
));
#endif
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
|
| ︙ | ︙ | |||
51503 51504 51505 51506 51507 51508 51509 51510 51511 51512 51513 51514 51515 51516 | ** stored in each frame (i.e. the db page-size when the WAL was created). */ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); #endif /* Return the sqlite3_file object for the WAL file */ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ /************** End of wal.h *************************************************/ /************** Continuing where we left off in pager.c **********************/ | > > > > > | 51561 51562 51563 51564 51565 51566 51567 51568 51569 51570 51571 51572 51573 51574 51575 51576 51577 51578 51579 | ** stored in each frame (i.e. the db page-size when the WAL was created). */ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); #endif /* Return the sqlite3_file object for the WAL file */ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); #ifdef SQLITE_ENABLE_SETLK_TIMEOUT SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock); SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); #endif #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ /************** End of wal.h *************************************************/ /************** Continuing where we left off in pager.c **********************/ |
| ︙ | ︙ | |||
54024 54025 54026 54027 54028 54029 54030 54031 54032 |
if( rc!=SQLITE_OK ){
goto delmaster_out;
}
if( exists ){
/* One of the journals pointed to by the master journal exists.
** Open it and check if it points at the master journal. If
** so, return without deleting the master journal file.
*/
int c;
| > > > | | 54087 54088 54089 54090 54091 54092 54093 54094 54095 54096 54097 54098 54099 54100 54101 54102 54103 54104 54105 54106 |
if( rc!=SQLITE_OK ){
goto delmaster_out;
}
if( exists ){
/* One of the journals pointed to by the master journal exists.
** Open it and check if it points at the master journal. If
** so, return without deleting the master journal file.
** NB: zJournal is really a MAIN_JOURNAL. But call it a
** MASTER_JOURNAL here so that the VFS will not send the zJournal
** name into sqlite3_database_file_object().
*/
int c;
int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
if( rc!=SQLITE_OK ){
goto delmaster_out;
}
rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
sqlite3OsClose(pJournal);
|
| ︙ | ︙ | |||
56230 56231 56232 56233 56234 56235 56236 56237 56238 56239 56240 56241 56242 56243 | ** file name. The layout in memory is as follows: ** ** Pager object (sizeof(Pager) bytes) ** PCache object (sqlite3PcacheSize() bytes) ** Database file handle (pVfs->szOsFile bytes) ** Sub-journal file handle (journalFileSize bytes) ** Main journal file handle (journalFileSize bytes) ** \0\0\0\0 database prefix (4 bytes) ** Database file name (nPathname+1 bytes) ** URI query parameters (nUriByte bytes) ** Journal filename (nPathname+8+1 bytes) ** WAL filename (nPathname+4+1 bytes) ** \0\0\0 terminator (3 bytes) ** | > | 56296 56297 56298 56299 56300 56301 56302 56303 56304 56305 56306 56307 56308 56309 56310 | ** file name. The layout in memory is as follows: ** ** Pager object (sizeof(Pager) bytes) ** PCache object (sqlite3PcacheSize() bytes) ** Database file handle (pVfs->szOsFile bytes) ** Sub-journal file handle (journalFileSize bytes) ** Main journal file handle (journalFileSize bytes) ** Ptr back to the Pager (sizeof(Pager*) bytes) ** \0\0\0\0 database prefix (4 bytes) ** Database file name (nPathname+1 bytes) ** URI query parameters (nUriByte bytes) ** Journal filename (nPathname+8+1 bytes) ** WAL filename (nPathname+4+1 bytes) ** \0\0\0 terminator (3 bytes) ** |
| ︙ | ︙ | |||
56269 56270 56271 56272 56273 56274 56275 56276 56277 56278 56279 56280 56281 56282 56283 56284 56285 56286 56287 56288 56289 56290 56291 56292 56293 56294 56295 56296 56297 56298 56299 56300 56301 56302 |
** changes here, be sure to change it there as well.
*/
pPtr = (u8 *)sqlite3MallocZero(
ROUND8(sizeof(*pPager)) + /* Pager structure */
ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */
journalFileSize * 2 + /* The two journal files */
4 + /* Database prefix */
nPathname + 1 + /* database filename */
nUriByte + /* query parameters */
nPathname + 8 + 1 + /* Journal filename */
#ifndef SQLITE_OMIT_WAL
nPathname + 4 + 1 + /* WAL filename */
#endif
3 /* Terminator */
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM_BKPT;
}
pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager));
pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
pPtr += 4; /* Skip zero prefix */
pPager->zFilename = (char*)pPtr;
if( nPathname>0 ){
memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1;
if( zUri ){
| > > | 56336 56337 56338 56339 56340 56341 56342 56343 56344 56345 56346 56347 56348 56349 56350 56351 56352 56353 56354 56355 56356 56357 56358 56359 56360 56361 56362 56363 56364 56365 56366 56367 56368 56369 56370 56371 |
** changes here, be sure to change it there as well.
*/
pPtr = (u8 *)sqlite3MallocZero(
ROUND8(sizeof(*pPager)) + /* Pager structure */
ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */
journalFileSize * 2 + /* The two journal files */
sizeof(pPager) + /* Space to hold a pointer */
4 + /* Database prefix */
nPathname + 1 + /* database filename */
nUriByte + /* query parameters */
nPathname + 8 + 1 + /* Journal filename */
#ifndef SQLITE_OMIT_WAL
nPathname + 4 + 1 + /* WAL filename */
#endif
3 /* Terminator */
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM_BKPT;
}
pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager));
pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
pPtr += 4; /* Skip zero prefix */
pPager->zFilename = (char*)pPtr;
if( nPathname>0 ){
memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1;
if( zUri ){
|
| ︙ | ︙ | |||
56489 56490 56491 56492 56493 56494 56495 56496 56497 56498 56499 56500 56501 56502 | /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ *ppPager = pPager; return SQLITE_OK; } /* ** This function is called after transitioning from PAGER_UNLOCK to ** PAGER_SHARED state. It tests if there is a hot journal present in ** the file-system for the given pager. A hot journal is one that ** needs to be played back. According to this function, a hot-journal | > > > > > > > > > > > > > | 56558 56559 56560 56561 56562 56563 56564 56565 56566 56567 56568 56569 56570 56571 56572 56573 56574 56575 56576 56577 56578 56579 56580 56581 56582 56583 56584 |
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
*ppPager = pPager;
return SQLITE_OK;
}
/*
** Return the sqlite3_file for the main database given the name
** of the corresonding WAL or Journal name as passed into
** xOpen.
*/
SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
Pager *pPager;
while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
zName--;
}
pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
return pPager->fd;
}
/*
** This function is called after transitioning from PAGER_UNLOCK to
** PAGER_SHARED state. It tests if there is a hot journal present in
** the file-system for the given pager. A hot journal is one that
** needs to be played back. According to this function, a hot-journal
|
| ︙ | ︙ | |||
57174 57175 57176 57177 57178 57179 57180 |
}
SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
Pager *pPager;
assert( pPg!=0 );
assert( pPg->pgno==1 );
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
pPager = pPg->pPager;
| < | 57256 57257 57258 57259 57260 57261 57262 57263 57264 57265 57266 57267 57268 57269 |
}
SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
Pager *pPager;
assert( pPg!=0 );
assert( pPg->pgno==1 );
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
pPager = pPg->pPager;
sqlite3PcacheRelease(pPg);
pagerUnlockIfUnused(pPager);
}
/*
** This function is called at the start of every write transaction.
** There must already be a RESERVED or EXCLUSIVE lock on the database
|
| ︙ | ︙ | |||
58467 58468 58469 58470 58471 58472 58473 |
** with the pager. This might return NULL if the file has
** not yet been opened.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
}
| < < < < < < < < < < | 58548 58549 58550 58551 58552 58553 58554 58555 58556 58557 58558 58559 58560 58561 |
** with the pager. This might return NULL if the file has
** not yet been opened.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
}
/*
** Return the file handle for the journal file (if it exists).
** This will be either the rollback journal or the WAL file.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
#if SQLITE_OMIT_WAL
return pPager->jfd;
|
| ︙ | ︙ | |||
58890 58891 58892 58893 58894 58895 58896 |
if( pPager->pWal ){
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
| < | 58961 58962 58963 58964 58965 58966 58967 58968 58969 58970 58971 58972 58973 58974 |
if( pPager->pWal ){
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
}
return rc;
}
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
return sqlite3WalCallback(pPager->pWal);
}
|
| ︙ | ︙ | |||
59055 59056 59057 59058 59059 59060 59061 |
pagerFixMaplimit(pPager);
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
}
}
return rc;
}
| > > > > > > > > > > > | > > > > > > > > > > > > > | > > > | 59125 59126 59127 59128 59129 59130 59131 59132 59133 59134 59135 59136 59137 59138 59139 59140 59141 59142 59143 59144 59145 59146 59147 59148 59149 59150 59151 59152 59153 59154 59155 59156 59157 59158 59159 59160 59161 59162 59163 59164 59165 59166 59167 59168 59169 59170 59171 59172 59173 59174 59175 59176 59177 59178 59179 59180 59181 59182 59183 59184 59185 59186 |
pagerFixMaplimit(pPager);
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
}
}
return rc;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** If pager pPager is a wal-mode database not in exclusive locking mode,
** invoke the sqlite3WalWriteLock() function on the associated Wal object
** with the same db and bLock parameters as were passed to this function.
** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
*/
SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
int rc = SQLITE_OK;
if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
rc = sqlite3WalWriteLock(pPager->pWal, bLock);
}
return rc;
}
/*
** Set the database handle used by the wal layer to determine if
** blocking locks are required.
*/
SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
if( pagerUseWal(pPager) ){
sqlite3WalDb(pPager->pWal, db);
}
}
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** If this is a WAL database, obtain a snapshot handle for the snapshot
** currently open. Otherwise, return an error.
*/
SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
int rc = SQLITE_ERROR;
if( pPager->pWal ){
rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot);
}
return rc;
}
/*
** If this is a WAL database, store a pointer to pSnapshot. Next time a
** read transaction is opened, attempt to read from the snapshot it
** identifies. If this is not a WAL database, return an error.
*/
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(
Pager *pPager,
sqlite3_snapshot *pSnapshot
){
int rc = SQLITE_OK;
if( pPager->pWal ){
sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
}else{
rc = SQLITE_ERROR;
}
return rc;
|
| ︙ | ︙ | |||
59620 59621 59622 59623 59624 59625 59626 59627 59628 59629 59630 59631 59632 59633 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ #endif }; /* ** Candidate values for Wal.exclusiveMode. */ #define WAL_NORMAL_MODE 0 #define WAL_EXCLUSIVE_MODE 1 | > > > | 59717 59718 59719 59720 59721 59722 59723 59724 59725 59726 59727 59728 59729 59730 59731 59732 59733 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; #endif }; /* ** Candidate values for Wal.exclusiveMode. */ #define WAL_NORMAL_MODE 0 #define WAL_EXCLUSIVE_MODE 1 |
| ︙ | ︙ | |||
59993 59994 59995 59996 59997 59998 59999 |
static int walLockShared(Wal *pWal, int lockIdx){
int rc;
if( pWal->exclusiveMode ) return SQLITE_OK;
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
walLockName(lockIdx), rc ? "failed" : "ok"));
| | | | 60093 60094 60095 60096 60097 60098 60099 60100 60101 60102 60103 60104 60105 60106 60107 60108 60109 60110 60111 60112 60113 60114 60115 60116 60117 60118 60119 60120 60121 60122 60123 |
static int walLockShared(Wal *pWal, int lockIdx){
int rc;
if( pWal->exclusiveMode ) return SQLITE_OK;
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
walLockName(lockIdx), rc ? "failed" : "ok"));
VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
return rc;
}
static void walUnlockShared(Wal *pWal, int lockIdx){
if( pWal->exclusiveMode ) return;
(void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
}
static int walLockExclusive(Wal *pWal, int lockIdx, int n){
int rc;
if( pWal->exclusiveMode ) return SQLITE_OK;
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
walLockName(lockIdx), n, rc ? "failed" : "ok"));
VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
return rc;
}
static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
if( pWal->exclusiveMode ) return;
(void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
|
| ︙ | ︙ | |||
60281 60282 60283 60284 60285 60286 60287 |
*/
static int walIndexRecover(Wal *pWal){
int rc; /* Return Code */
i64 nSize; /* Size of log file */
u32 aFrameCksum[2] = {0, 0};
int iLock; /* Lock offset to lock for checkpoint */
| < < < < < | 60381 60382 60383 60384 60385 60386 60387 60388 60389 60390 60391 60392 60393 60394 |
*/
static int walIndexRecover(Wal *pWal){
int rc; /* Return Code */
i64 nSize; /* Size of log file */
u32 aFrameCksum[2] = {0, 0};
int iLock; /* Lock offset to lock for checkpoint */
/* Obtain an exclusive lock on all byte in the locking range not already
** locked by the caller. The caller is guaranteed to have locked the
** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
** If successful, the same bytes that are locked here are unlocked before
** this function returns.
*/
assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
|
| ︙ | ︙ | |||
60833 60834 60835 60836 60837 60838 60839 60840 60841 60842 60843 60844 60845 60846 60847 60848 60849 60850 60851 60852 60853 60854 60855 60856 60857 60858 60859 60860 60861 60862 60863 60864 |
if( rc!=SQLITE_OK ){
walIteratorFree(p);
p = 0;
}
*pp = p;
return rc;
}
/*
** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
** n. If the attempt fails and parameter xBusy is not NULL, then it is a
** busy-handler function. Invoke it and retry the lock until either the
** lock is successfully obtained or the busy-handler returns 0.
*/
static int walBusyLock(
Wal *pWal, /* WAL connection */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
int lockIdx, /* Offset of first byte to lock */
int n /* Number of bytes to lock */
){
int rc;
do {
rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
return rc;
}
/*
** The cache of the wal-index header must be valid to call this function.
** Return the page-size in bytes used by the database.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 60928 60929 60930 60931 60932 60933 60934 60935 60936 60937 60938 60939 60940 60941 60942 60943 60944 60945 60946 60947 60948 60949 60950 60951 60952 60953 60954 60955 60956 60957 60958 60959 60960 60961 60962 60963 60964 60965 60966 60967 60968 60969 60970 60971 60972 60973 60974 60975 60976 60977 60978 60979 60980 60981 60982 60983 60984 60985 60986 60987 60988 60989 60990 60991 60992 60993 60994 60995 60996 60997 60998 60999 61000 61001 61002 61003 61004 61005 61006 61007 61008 61009 61010 61011 61012 61013 61014 61015 61016 61017 61018 61019 61020 61021 61022 61023 61024 61025 61026 61027 61028 61029 61030 61031 61032 61033 61034 61035 61036 61037 61038 61039 61040 61041 61042 61043 61044 61045 61046 61047 61048 |
if( rc!=SQLITE_OK ){
walIteratorFree(p);
p = 0;
}
*pp = p;
return rc;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
** they are supported by the VFS, and (b) the database handle is configured
** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
** or 0 otherwise.
*/
static int walEnableBlocking(Wal *pWal){
int res = 0;
if( pWal->db ){
int tmout = pWal->db->busyTimeout;
if( tmout ){
int rc;
rc = sqlite3OsFileControl(
pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
);
res = (rc==SQLITE_OK);
}
}
return res;
}
/*
** Disable blocking locks.
*/
static void walDisableBlocking(Wal *pWal){
int tmout = 0;
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
}
/*
** If parameter bLock is true, attempt to enable blocking locks, take
** the WRITER lock, and then disable blocking locks. If blocking locks
** cannot be enabled, no attempt to obtain the WRITER lock is made. Return
** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
** an error if blocking locks can not be enabled.
**
** If the bLock parameter is false and the WRITER lock is held, release it.
*/
SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){
int rc = SQLITE_OK;
assert( pWal->readLock<0 || bLock==0 );
if( bLock ){
assert( pWal->db );
if( walEnableBlocking(pWal) ){
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
if( rc==SQLITE_OK ){
pWal->writeLock = 1;
}
walDisableBlocking(pWal);
}
}else if( pWal->writeLock ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0;
}
return rc;
}
/*
** Set the database handle used to determine if blocking locks are required.
*/
SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
pWal->db = db;
}
/*
** Take an exclusive WRITE lock. Blocking if so configured.
*/
static int walLockWriter(Wal *pWal){
int rc;
walEnableBlocking(pWal);
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
walDisableBlocking(pWal);
return rc;
}
#else
# define walEnableBlocking(x) 0
# define walDisableBlocking(x)
# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
# define sqlite3WalDb(pWal, db)
#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
/*
** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
** n. If the attempt fails and parameter xBusy is not NULL, then it is a
** busy-handler function. Invoke it and retry the lock until either the
** lock is successfully obtained or the busy-handler returns 0.
*/
static int walBusyLock(
Wal *pWal, /* WAL connection */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
int lockIdx, /* Offset of first byte to lock */
int n /* Number of bytes to lock */
){
int rc;
do {
rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ){
walDisableBlocking(pWal);
rc = SQLITE_BUSY;
}
#endif
return rc;
}
/*
** The cache of the wal-index header must be valid to call this function.
** Return the page-size in bytes used by the database.
*/
|
| ︙ | ︙ | |||
61021 61022 61023 61024 61025 61026 61027 61028 61029 61030 61031 61032 61033 61034 |
/* If the database may grow as a result of this checkpoint, hint
** about the eventual size of the db file to the VFS layer.
*/
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
i64 nSize; /* Current size of database file */
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSize<nReq ){
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
}
}
| > | 61205 61206 61207 61208 61209 61210 61211 61212 61213 61214 61215 61216 61217 61218 61219 |
/* If the database may grow as a result of this checkpoint, hint
** about the eventual size of the db file to the VFS layer.
*/
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
i64 nSize; /* Current size of database file */
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSize<nReq ){
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
}
}
|
| ︙ | ︙ | |||
61048 61049 61050 61051 61052 61053 61054 61055 61056 61057 61058 61059 61060 61061 61062 61063 61064 61065 |
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
iOffset = (iDbpage-1)*(i64)szPage;
testcase( IS_BIG_INT(iOffset) );
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
}
/* If work was actually accomplished... */
if( rc==SQLITE_OK ){
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
i64 szDb = pWal->hdr.nPage*(i64)szPage;
testcase( IS_BIG_INT(szDb) );
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
if( rc==SQLITE_OK ){
rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
}
}
| > < < < < | 61233 61234 61235 61236 61237 61238 61239 61240 61241 61242 61243 61244 61245 61246 61247 61248 61249 61250 61251 61252 61253 61254 61255 61256 61257 61258 |
rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
iOffset = (iDbpage-1)*(i64)szPage;
testcase( IS_BIG_INT(iOffset) );
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
}
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
/* If work was actually accomplished... */
if( rc==SQLITE_OK ){
if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
i64 szDb = pWal->hdr.nPage*(i64)szPage;
testcase( IS_BIG_INT(szDb) );
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
if( rc==SQLITE_OK ){
rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
}
}
if( rc==SQLITE_OK ){
pInfo->nBackfill = mxSafeFrame;
}
}
/* Release the reader lock held while backfilling */
walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
|
| ︙ | ︙ | |||
61332 61333 61334 61335 61336 61337 61338 | ** being modified by another thread or process. */ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race ** with a writer. So get a WRITE lock and try again. */ | < > > | | | | | | | | | | | | | > | | > > | 61514 61515 61516 61517 61518 61519 61520 61521 61522 61523 61524 61525 61526 61527 61528 61529 61530 61531 61532 61533 61534 61535 61536 61537 61538 61539 61540 61541 61542 61543 61544 61545 61546 61547 61548 61549 61550 61551 61552 61553 |
** being modified by another thread or process.
*/
badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
/* If the first attempt failed, it might have been due to a race
** with a writer. So get a WRITE lock and try again.
*/
if( badHdr ){
if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
}
}else{
int bWriteLock = pWal->writeLock;
if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
pWal->writeLock = 1;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
if( badHdr ){
/* If the wal-index header is still malformed even while holding
** a WRITE lock, it can only mean that the header is corrupted and
** needs to be reconstructed. So run recovery to do exactly that.
*/
rc = walIndexRecover(pWal);
*pChanged = 1;
}
}
if( bWriteLock==0 ){
pWal->writeLock = 0;
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
}
}
}
}
/* If the header is read successfully, check the version number to make
** sure the wal-index was not constructed with some future format that
** this version of SQLite cannot understand.
*/
|
| ︙ | ︙ | |||
61905 61906 61907 61908 61909 61910 61911 |
** transaction, then *pChanged is set to 1 before returning. The
** Pager layer will use this to know that its cache is stale and
** needs to be flushed.
*/
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
| | | < > | | | | > > > > > > > > > > > | < < > > | > < < < < < < < < < < | 62091 62092 62093 62094 62095 62096 62097 62098 62099 62100 62101 62102 62103 62104 62105 62106 62107 62108 62109 62110 62111 62112 62113 62114 62115 62116 62117 62118 62119 62120 62121 62122 62123 62124 62125 62126 62127 62128 62129 62130 62131 62132 62133 62134 62135 62136 62137 62138 62139 62140 62141 62142 |
** transaction, then *pChanged is set to 1 before returning. The
** Pager layer will use this to know that its cache is stale and
** needs to be flushed.
*/
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
assert( pWal->ckptLock==0 );
#ifdef SQLITE_ENABLE_SNAPSHOT
int bChanged = 0;
WalIndexHdr *pSnapshot = pWal->pSnapshot;
if( pSnapshot ){
if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
bChanged = 1;
}
/* It is possible that there is a checkpointer thread running
** concurrent with this code. If this is the case, it may be that the
** checkpointer has already determined that it will checkpoint
** snapshot X, where X is later in the wal file than pSnapshot, but
** has not yet set the pInfo->nBackfillAttempted variable to indicate
** its intent. To avoid the race condition this leads to, ensure that
** there is no checkpointer process by taking a shared CKPT lock
** before checking pInfo->nBackfillAttempted. */
(void)walEnableBlocking(pWal);
rc = walLockShared(pWal, WAL_CKPT_LOCK);
walDisableBlocking(pWal);
if( rc!=SQLITE_OK ){
return rc;
}
pWal->ckptLock = 1;
}
#endif
do{
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
}while( rc==WAL_RETRY );
testcase( (rc&0xff)==SQLITE_BUSY );
testcase( (rc&0xff)==SQLITE_IOERR );
testcase( rc==SQLITE_PROTOCOL );
testcase( rc==SQLITE_OK );
#ifdef SQLITE_ENABLE_SNAPSHOT
if( rc==SQLITE_OK ){
if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
/* At this point the client has a lock on an aReadMark[] slot holding
** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr
** is populated with the wal-index header corresponding to the head
** of the wal file. Verify that pSnapshot is still valid before
|
| ︙ | ︙ | |||
61962 61963 61964 61965 61966 61967 61968 |
** checkpoint need not have completed for this to cause problems.
*/
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
| < < < < < < < < < < < < < < < | | | | | | | | | | | | | | | > > > > > | < | < < > > > > > > > | 62150 62151 62152 62153 62154 62155 62156 62157 62158 62159 62160 62161 62162 62163 62164 62165 62166 62167 62168 62169 62170 62171 62172 62173 62174 62175 62176 62177 62178 62179 62180 62181 62182 62183 62184 62185 62186 62187 62188 62189 62190 62191 62192 62193 62194 62195 62196 62197 62198 62199 |
** checkpoint need not have completed for this to cause problems.
*/
volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
/* Check that the wal file has not been wrapped. Assuming that it has
** not, also check that no checkpointer has attempted to checkpoint any
** frames beyond pSnapshot->mxFrame. If either of these conditions are
** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
** with *pSnapshot and set *pChanged as appropriate for opening the
** snapshot. */
if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
&& pSnapshot->mxFrame>=pInfo->nBackfillAttempted
){
assert( pWal->readLock>0 );
memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
*pChanged = bChanged;
}else{
rc = SQLITE_ERROR_SNAPSHOT;
}
/* A client using a non-current snapshot may not ignore any frames
** from the start of the wal file. This is because, for a system
** where (minFrame < iSnapshot < maxFrame), a checkpointer may
** have omitted to checkpoint a frame earlier than minFrame in
** the file because there exists a frame after iSnapshot that
** is the same database page. */
pWal->minFrame = 1;
if( rc!=SQLITE_OK ){
sqlite3WalEndReadTransaction(pWal);
}
}
}
/* Release the shared CKPT lock obtained above. */
if( pWal->ckptLock ){
assert( pSnapshot );
walUnlockShared(pWal, WAL_CKPT_LOCK);
pWal->ckptLock = 0;
}
#endif
return rc;
}
/*
** Finish with a read transaction. All this does is release the
** read-lock.
|
| ︙ | ︙ | |||
62173 62174 62175 62176 62177 62178 62179 62180 62181 62182 62183 62184 62185 62186 |
** thread to write as doing so would cause a fork. So this routine
** returns SQLITE_BUSY in that case and no write transaction is started.
**
** There can only be a single writer active at a time.
*/
SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
int rc;
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
if( pWal->readOnly ){
| > > > > > > > > > > | 62355 62356 62357 62358 62359 62360 62361 62362 62363 62364 62365 62366 62367 62368 62369 62370 62371 62372 62373 62374 62375 62376 62377 62378 |
** thread to write as doing so would cause a fork. So this routine
** returns SQLITE_BUSY in that case and no write transaction is started.
**
** There can only be a single writer active at a time.
*/
SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
int rc;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* If the write-lock is already held, then it was obtained before the
** read-transaction was even opened, making this call a no-op.
** Return early. */
if( pWal->writeLock ){
assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
return SQLITE_OK;
}
#endif
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
assert( pWal->writeLock==0 && pWal->iReCksum==0 );
if( pWal->readOnly ){
|
| ︙ | ︙ | |||
62749 62750 62751 62752 62753 62754 62755 62756 62757 |
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
| > > > > > | > > > > > > < < < < < < < | | | < | | | | | | | | | | | | | | | | | | | | | > > > > | 62941 62942 62943 62944 62945 62946 62947 62948 62949 62950 62951 62952 62953 62954 62955 62956 62957 62958 62959 62960 62961 62962 62963 62964 62965 62966 62967 62968 62969 62970 62971 62972 62973 62974 62975 62976 62977 62978 62979 62980 62981 62982 62983 62984 62985 62986 62987 62988 62989 62990 62991 62992 62993 62994 62995 62996 62997 62998 62999 63000 63001 |
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
/* Enable blocking locks, if possible. If blocking locks are successfully
** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
sqlite3WalDb(pWal, db);
(void)walEnableBlocking(pWal);
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file.
** EVIDENCE-OF: R-10421-19736 If any other process is running a
** checkpoint operation at the same time, the lock cannot be obtained and
** SQLITE_BUSY is returned.
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
** it will not be invoked in this case.
*/
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
testcase( rc==SQLITE_BUSY );
testcase( rc!=SQLITE_OK && xBusy2!=0 );
if( rc==SQLITE_OK ){
pWal->ckptLock = 1;
/* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
** TRUNCATE modes also obtain the exclusive "writer" lock on the database
** file.
**
** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
** immediately, and a busy-handler is configured, it is invoked and the
** writer lock retried until either the busy-handler returns 0 or the
** lock is successfully obtained.
*/
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
if( rc==SQLITE_OK ){
pWal->writeLock = 1;
}else if( rc==SQLITE_BUSY ){
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
xBusy2 = 0;
rc = SQLITE_OK;
}
}
}
/* Read the wal-index header. */
if( rc==SQLITE_OK ){
walDisableBlocking(pWal);
rc = walIndexReadHdr(pWal, &isChanged);
(void)walEnableBlocking(pWal);
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
}
/* Copy data from the log to the database file. */
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
62819 62820 62821 62822 62823 62824 62825 62826 62827 62828 |
** performed, then the pager-cache associated with pWal is now
** out of date. So zero the cached wal-index header to ensure that
** next time the pager opens a snapshot on this database it knows that
** the cache needs to be reset.
*/
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
/* Release the locks. */
sqlite3WalEndWriteTransaction(pWal);
| > > > > | | > > > > | 63018 63019 63020 63021 63022 63023 63024 63025 63026 63027 63028 63029 63030 63031 63032 63033 63034 63035 63036 63037 63038 63039 63040 63041 63042 63043 63044 63045 |
** performed, then the pager-cache associated with pWal is now
** out of date. So zero the cached wal-index header to ensure that
** next time the pager opens a snapshot on this database it knows that
** the cache needs to be reset.
*/
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
walDisableBlocking(pWal);
sqlite3WalDb(pWal, 0);
/* Release the locks. */
sqlite3WalEndWriteTransaction(pWal);
if( pWal->ckptLock ){
walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
pWal->ckptLock = 0;
}
WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
}
/* Return the value to pass to a sqlite3_wal_hook callback, the
** number of frames in the WAL at the point of the last commit since
** sqlite3WalCallback() was called. If no commits have occurred since
** the last call, then return 0.
|
| ︙ | ︙ | |||
62941 62942 62943 62944 62945 62946 62947 | } return rc; } /* Try to open on pSnapshot when the next read-transaction starts */ | | > > > | 63148 63149 63150 63151 63152 63153 63154 63155 63156 63157 63158 63159 63160 63161 63162 63163 63164 63165 |
}
return rc;
}
/* Try to open on pSnapshot when the next read-transaction starts
*/
SQLITE_PRIVATE void sqlite3WalSnapshotOpen(
Wal *pWal,
sqlite3_snapshot *pSnapshot
){
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}
/*
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
*/
|
| ︙ | ︙ | |||
63460 63461 63462 63463 63464 63465 63466 | #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ u8 bDoTruncate; /* True to truncate db on commit */ #endif u8 inTransaction; /* Transaction state */ u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ | | | 63670 63671 63672 63673 63674 63675 63676 63677 63678 63679 63680 63681 63682 63683 63684 | #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ u8 bDoTruncate; /* True to truncate db on commit */ #endif u8 inTransaction; /* Transaction state */ u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ u8 nReserveWanted; /* Desired number of extra bytes per page */ u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ u32 pageSize; /* Total number of bytes on a page */ u32 usableSize; /* Number of usable bytes on each page */ |
| ︙ | ︙ | |||
66354 66355 66356 66357 66358 66359 66360 |
/*
** Invoke the busy handler for a btree.
*/
static int btreeInvokeBusyHandler(void *pArg){
BtShared *pBt = (BtShared*)pArg;
assert( pBt->db );
assert( sqlite3_mutex_held(pBt->db->mutex) );
| | < | 66564 66565 66566 66567 66568 66569 66570 66571 66572 66573 66574 66575 66576 66577 66578 |
/*
** Invoke the busy handler for a btree.
*/
static int btreeInvokeBusyHandler(void *pArg){
BtShared *pBt = (BtShared*)pArg;
assert( pBt->db );
assert( sqlite3_mutex_held(pBt->db->mutex) );
return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
}
/*
** Open a database file.
**
** zFilename is the name of the database file. If zFilename is NULL
** then an ephemeral database is created. The ephemeral database might
|
| ︙ | ︙ | |||
66906 66907 66908 66909 66910 66911 66912 66913 |
** bytes per page is left unchanged.
**
** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
** and autovacuum mode can no longer be changed.
*/
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
int rc = SQLITE_OK;
BtShared *pBt = p->pBt;
| > | < | < > > < < < | 67115 67116 67117 67118 67119 67120 67121 67122 67123 67124 67125 67126 67127 67128 67129 67130 67131 67132 67133 67134 67135 67136 67137 67138 67139 |
** bytes per page is left unchanged.
**
** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
** and autovacuum mode can no longer be changed.
*/
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
int rc = SQLITE_OK;
int x;
BtShared *pBt = p->pBt;
assert( nReserve>=0 && nReserve<=255 );
sqlite3BtreeEnter(p);
pBt->nReserveWanted = nReserve;
x = pBt->pageSize - pBt->usableSize;
if( nReserve<x ) nReserve = x;
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
assert( !pBt->pCursor );
pBt->pageSize = (u32)pageSize;
freeTempSpace(pBt);
|
| ︙ | ︙ | |||
66963 66964 66965 66966 66967 66968 66969 66970 66971 |
return n;
}
/*
** Return the number of bytes of space at the end of every page that
** are intentually left unused. This is the "reserved" space that is
** sometimes used by extensions.
*/
SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
| > > > > | | | | | 67170 67171 67172 67173 67174 67175 67176 67177 67178 67179 67180 67181 67182 67183 67184 67185 67186 67187 67188 67189 67190 67191 67192 67193 67194 67195 |
return n;
}
/*
** Return the number of bytes of space at the end of every page that
** are intentually left unused. This is the "reserved" space that is
** sometimes used by extensions.
**
** The value returned is the larger of the current reserve size and
** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
** The amount of reserve can only grow - never shrink.
*/
SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
int n1, n2;
sqlite3BtreeEnter(p);
n1 = (int)p->pBt->nReserveWanted;
n2 = sqlite3BtreeGetReserveNoMutex(p);
sqlite3BtreeLeave(p);
return n1>n2 ? n1 : n2;
}
/*
** Set the maximum page count for a database if mxPage is positive.
** No changes are made if mxPage is 0 or negative.
** Regardless of the value of mxPage, return the maximum page count.
|
| ︙ | ︙ | |||
67420 67421 67422 67423 67424 67425 67426 67427 67428 67429 67430 67431 67432 67433 67434 67435 67436 67437 67438 67439 67440 67441 |
** One or the other of the two processes must give way or there can be
** no progress. By returning SQLITE_BUSY and not invoking the busy callback
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
BtShared *pBt = p->pBt;
int rc = SQLITE_OK;
sqlite3BtreeEnter(p);
btreeIntegrity(p);
/* If the btree is already in a write-transaction, or it
** is already in a read-transaction and a read-transaction
** is requested, this is a no-op.
*/
if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
goto trans_begun;
}
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
if( (p->db->flags & SQLITE_ResetDatabase)
| > | | 67631 67632 67633 67634 67635 67636 67637 67638 67639 67640 67641 67642 67643 67644 67645 67646 67647 67648 67649 67650 67651 67652 67653 67654 67655 67656 67657 67658 67659 67660 67661 |
** One or the other of the two processes must give way or there can be
** no progress. By returning SQLITE_BUSY and not invoking the busy callback
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
BtShared *pBt = p->pBt;
Pager *pPager = pBt->pPager;
int rc = SQLITE_OK;
sqlite3BtreeEnter(p);
btreeIntegrity(p);
/* If the btree is already in a write-transaction, or it
** is already in a read-transaction and a read-transaction
** is requested, this is a no-op.
*/
if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
goto trans_begun;
}
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
if( (p->db->flags & SQLITE_ResetDatabase)
&& sqlite3PagerIsreadonly(pPager)==0
){
pBt->btsFlags &= ~BTS_READ_ONLY;
}
/* Write transactions are not possible on a read-only database */
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
rc = SQLITE_READONLY;
|
| ︙ | ︙ | |||
67483 67484 67485 67486 67487 67488 67489 67490 67491 67492 67493 67494 67495 67496 67497 67498 67499 67500 67501 67502 |
** on page 1, the transaction cannot be opened. */
rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
if( SQLITE_OK!=rc ) goto trans_begun;
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
do {
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
** reading page 1 it discovers that the page-size of the database
** file is not pBt->pageSize. In this case lockBtree() will update
** pBt->pageSize to the page-size of the file on disk.
*/
while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) );
if( rc==SQLITE_OK && wrflag ){
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
rc = SQLITE_READONLY;
}else{
| > > > > > > > > > > > > | > | > > > | 67695 67696 67697 67698 67699 67700 67701 67702 67703 67704 67705 67706 67707 67708 67709 67710 67711 67712 67713 67714 67715 67716 67717 67718 67719 67720 67721 67722 67723 67724 67725 67726 67727 67728 67729 67730 67731 67732 67733 67734 67735 67736 67737 67738 67739 67740 67741 67742 67743 67744 67745 67746 67747 67748 67749 67750 67751 67752 67753 67754 67755 |
** on page 1, the transaction cannot be opened. */
rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
if( SQLITE_OK!=rc ) goto trans_begun;
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
do {
sqlite3PagerWalDb(pPager, p->db);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* If transitioning from no transaction directly to a write transaction,
** block for the WRITER lock first if possible. */
if( pBt->pPage1==0 && wrflag ){
assert( pBt->inTransaction==TRANS_NONE );
rc = sqlite3PagerWalWriteLock(pPager, 1);
if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
}
#endif
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
** reading page 1 it discovers that the page-size of the database
** file is not pBt->pageSize. In this case lockBtree() will update
** pBt->pageSize to the page-size of the file on disk.
*/
while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) );
if( rc==SQLITE_OK && wrflag ){
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
rc = SQLITE_READONLY;
}else{
rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
/* if there was no transaction opened when this function was
** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
** code to SQLITE_BUSY. */
rc = SQLITE_BUSY;
}
}
}
if( rc!=SQLITE_OK ){
(void)sqlite3PagerWalWriteLock(pPager, 0);
unlockBtreeIfUnused(pBt);
}
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
sqlite3PagerWalDb(pPager, 0);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
if( rc==SQLITE_OK ){
if( p->inTrans==TRANS_NONE ){
pBt->nTransaction++;
#ifndef SQLITE_OMIT_SHARED_CACHE
if( p->sharable ){
assert( p->lock.pBtree==p && p->lock.iTable==1 );
|
| ︙ | ︙ | |||
67565 67566 67567 67568 67569 67570 67571 |
*pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
}
if( wrflag ){
/* This call makes sure that the pager has the correct number of
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
| | | 67793 67794 67795 67796 67797 67798 67799 67800 67801 67802 67803 67804 67805 67806 67807 |
*pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
}
if( wrflag ){
/* This call makes sure that the pager has the correct number of
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
}
}
btreeIntegrity(p);
sqlite3BtreeLeave(p);
return rc;
}
|
| ︙ | ︙ | |||
71201 71202 71203 71204 71205 71206 71207 |
memcpy(pTmp, aData, pPg->pBt->usableSize);
#endif
/* Remove cells from the start and end of the page */
assert( nCell>=0 );
if( iOld<iNew ){
int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
| | | 71429 71430 71431 71432 71433 71434 71435 71436 71437 71438 71439 71440 71441 71442 71443 |
memcpy(pTmp, aData, pPg->pBt->usableSize);
#endif
/* Remove cells from the start and end of the page */
assert( nCell>=0 );
if( iOld<iNew ){
int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
if( NEVER(nShift>nCell) ) return SQLITE_CORRUPT_BKPT;
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
nCell -= nShift;
}
if( iNewEnd < iOldEnd ){
int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
assert( nCell>=nTail );
nCell -= nTail;
|
| ︙ | ︙ | |||
73558 73559 73560 73561 73562 73563 73564 |
}
#endif
}
sqlite3BtreeLeave(p);
return rc;
}
| < | 73786 73787 73788 73789 73790 73791 73792 73793 73794 73795 73796 73797 73798 73799 |
}
#endif
}
sqlite3BtreeLeave(p);
return rc;
}
/*
** The first argument, pCur, is a cursor opened on some b-tree. Count the
** number of entries in the b-tree and write the result to *pnEntry.
**
** SQLITE_OK is returned if the operation is successfully executed.
** Otherwise, if an error is encountered (i.e. an IO error or database
** corruption) an SQLite error code is returned.
|
| ︙ | ︙ | |||
73631 73632 73633 73634 73635 73636 73637 |
rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
}
}
/* An error has occurred. Return an error code. */
return rc;
}
| < | 73858 73859 73860 73861 73862 73863 73864 73865 73866 73867 73868 73869 73870 73871 |
rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
}
}
/* An error has occurred. Return an error code. */
return rc;
}
/*
** Return the pager associated with a BTree. This routine is used for
** testing and debugging only.
*/
SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){
return p->pBt->pPager;
|
| ︙ | ︙ | |||
74682 74683 74684 74685 74686 74687 74688 |
/*
** Attempt to set the page size of the destination to match the page size
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
int rc;
| | | 74908 74909 74910 74911 74912 74913 74914 74915 74916 74917 74918 74919 74920 74921 74922 |
/*
** Attempt to set the page size of the destination to match the page size
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
int rc;
rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
return rc;
}
/*
** Check that there is no open read-transaction on the b-tree passed as the
** second argument. If there is not, return SQLITE_OK. Otherwise, if there
** is an open read-transaction, return SQLITE_ERROR and leave an error
|
| ︙ | ︙ | |||
78707 78708 78709 78710 78711 78712 78713 | ** Some translation occurs: ** ** "PX" -> "r[X]" ** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 ** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 ** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x */ | | > | < < < > | 78933 78934 78935 78936 78937 78938 78939 78940 78941 78942 78943 78944 78945 78946 78947 78948 78949 78950 78951 78952 78953 78954 78955 78956 78957 78958 78959 |
** Some translation occurs:
**
** "PX" -> "r[X]"
** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
*/
SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
sqlite3 *db, /* Optional - Oom error reporting only */
const Op *pOp, /* The opcode to be commented */
const char *zP4 /* Previously obtained value for P4 */
){
const char *zOpName;
const char *zSynopsis;
int nOpName;
int ii;
char zAlt[50];
StrAccum x;
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
zOpName = sqlite3OpcodeName(pOp->opcode);
nOpName = sqlite3Strlen30(zOpName);
if( zOpName[nOpName+1] ){
int seenCom = 0;
char c;
zSynopsis = zOpName += nOpName + 1;
if( strncmp(zSynopsis,"IF ",3)==0 ){
|
| ︙ | ︙ | |||
78787 78788 78789 78790 78791 78792 78793 |
}
if( !seenCom && pOp->zComment ){
sqlite3_str_appendf(&x, "; %s", pOp->zComment);
}
}else if( pOp->zComment ){
sqlite3_str_appendall(&x, pOp->zComment);
}
| > > > | < | | 79012 79013 79014 79015 79016 79017 79018 79019 79020 79021 79022 79023 79024 79025 79026 79027 79028 79029 79030 79031 |
}
if( !seenCom && pOp->zComment ){
sqlite3_str_appendf(&x, "; %s", pOp->zComment);
}
}else if( pOp->zComment ){
sqlite3_str_appendall(&x, pOp->zComment);
}
if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
sqlite3OomFault(db);
}
return sqlite3StrAccumFinish(&x);
}
#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
/*
** Translate the P4.pExpr value for an OP_CursorHint opcode into text
** that can be displayed in the P4 column of EXPLAIN output.
*/
static void displayP4Expr(StrAccum *p, Expr *pExpr){
|
| ︙ | ︙ | |||
78871 78872 78873 78874 78875 78876 78877 | #if VDBE_DISPLAY_P4 /* ** Compute a string that describes the P4 parameter for an opcode. ** Use zTemp for any required temporary buffer space. */ | | | | | | 79098 79099 79100 79101 79102 79103 79104 79105 79106 79107 79108 79109 79110 79111 79112 79113 79114 79115 79116 |
#if VDBE_DISPLAY_P4
/*
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
char *zP4 = 0;
StrAccum x;
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
switch( pOp->p4type ){
case P4_KEYINFO: {
int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortFlags!=0 );
sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
for(j=0; j<pKeyInfo->nKeyField; j++){
|
| ︙ | ︙ | |||
78959 78960 78961 78962 78963 78964 78965 |
#endif
case P4_INTARRAY: {
int i;
int *ai = pOp->p4.ai;
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<=n; i++){
| | < | < | < < < | | > > > | < < | 79186 79187 79188 79189 79190 79191 79192 79193 79194 79195 79196 79197 79198 79199 79200 79201 79202 79203 79204 79205 79206 79207 79208 79209 79210 79211 79212 79213 79214 79215 79216 79217 79218 79219 79220 79221 79222 79223 79224 79225 |
#endif
case P4_INTARRAY: {
int i;
int *ai = pOp->p4.ai;
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<=n; i++){
sqlite3_str_appendf(&x, "%c%d", (i==1 ? '[' : ','), ai[i]);
}
sqlite3_str_append(&x, "]", 1);
break;
}
case P4_SUBPROGRAM: {
zP4 = "program";
break;
}
case P4_DYNBLOB:
case P4_ADVANCE: {
break;
}
case P4_TABLE: {
zP4 = pOp->p4.pTab->zName;
break;
}
default: {
zP4 = pOp->p4.z;
}
}
if( zP4 ) sqlite3_str_appendall(&x, zP4);
if( (x.accError & SQLITE_NOMEM)!=0 ){
sqlite3OomFault(db);
}
return sqlite3StrAccumFinish(&x);
}
#endif /* VDBE_DISPLAY_P4 */
/*
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
**
** The prepared statements need to know in advance the complete set of
|
| ︙ | ︙ | |||
79078 79079 79080 79081 79082 79083 79084 |
#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode. This routine is used for debugging only.
*/
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
char *zP4;
| | | > | | | | > | > > | 79301 79302 79303 79304 79305 79306 79307 79308 79309 79310 79311 79312 79313 79314 79315 79316 79317 79318 79319 79320 79321 79322 79323 79324 79325 79326 79327 79328 79329 79330 79331 79332 79333 79334 79335 79336 |
#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Print a single opcode. This routine is used for debugging only.
*/
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
char *zP4;
char *zCom;
sqlite3 dummyDb;
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
dummyDb.mallocFailed = 1;
zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
#else
zCom = 0;
#endif
/* NB: The sqlite3OpcodeName() function is implemented by code created
** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
** information from the vdbe.c source text */
fprintf(pOut, zFormat1, pc,
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3,
zP4 ? zP4 : "", pOp->p5,
zCom ? zCom : ""
);
fflush(pOut);
sqlite3_free(zP4);
sqlite3_free(zCom);
}
#endif
/*
** Initialize an array of N Mem element.
*/
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
|
| ︙ | ︙ | |||
79186 79187 79188 79189 79190 79191 79192 79193 79194 79195 79196 79197 79198 79199 |
SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){
VdbeFrame *pFrame = (VdbeFrame*)pArg;
assert( sqlite3VdbeFrameIsValid(pFrame) );
pFrame->pParent = pFrame->v->pDelFrame;
pFrame->v->pDelFrame = pFrame;
}
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite3VdbeExec().
*/
SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
int i;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 79413 79414 79415 79416 79417 79418 79419 79420 79421 79422 79423 79424 79425 79426 79427 79428 79429 79430 79431 79432 79433 79434 79435 79436 79437 79438 79439 79440 79441 79442 79443 79444 79445 79446 79447 79448 79449 79450 79451 79452 79453 79454 79455 79456 79457 79458 79459 79460 79461 79462 79463 79464 79465 79466 79467 79468 79469 79470 79471 79472 79473 79474 79475 79476 79477 79478 79479 79480 79481 79482 79483 79484 79485 79486 79487 79488 79489 79490 79491 79492 79493 79494 79495 79496 79497 79498 79499 79500 79501 79502 79503 79504 79505 79506 79507 79508 79509 79510 79511 79512 79513 79514 79515 79516 79517 79518 79519 79520 79521 79522 79523 79524 79525 79526 79527 79528 79529 79530 79531 79532 79533 79534 79535 79536 79537 79538 79539 79540 79541 |
SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){
VdbeFrame *pFrame = (VdbeFrame*)pArg;
assert( sqlite3VdbeFrameIsValid(pFrame) );
pFrame->pParent = pFrame->v->pDelFrame;
pFrame->v->pDelFrame = pFrame;
}
#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
/*
** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
** QUERY PLAN output.
**
** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no
** more opcodes to be displayed.
*/
SQLITE_PRIVATE int sqlite3VdbeNextOpcode(
Vdbe *p, /* The statement being explained */
Mem *pSub, /* Storage for keeping track of subprogram nesting */
int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */
int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */
int *piAddr, /* OUT: Write index into (*paOp)[] here */
Op **paOp /* OUT: Write the opcode array here */
){
int nRow; /* Stop when row count reaches this */
int nSub = 0; /* Number of sub-vdbes seen so far */
SubProgram **apSub = 0; /* Array of sub-vdbes */
int i; /* Next instruction address */
int rc = SQLITE_OK; /* Result code */
Op *aOp = 0; /* Opcode array */
int iPc; /* Rowid. Copy of value in *piPc */
/* When the number of output rows reaches nRow, that means the
** listing has finished and sqlite3_step() should return SQLITE_DONE.
** nRow is the sum of the number of rows in the main program, plus
** the sum of the number of rows in all trigger subprograms encountered
** so far. The nRow value will increase as new trigger subprograms are
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
if( pSub!=0 ){
if( pSub->flags&MEM_Blob ){
/* pSub is initiallly NULL. It is initialized to a BLOB by
** the P4_SUBPROGRAM processing logic below */
nSub = pSub->n/sizeof(Vdbe*);
apSub = (SubProgram **)pSub->z;
}
for(i=0; i<nSub; i++){
nRow += apSub[i]->nOp;
}
}
iPc = *piPc;
while(1){ /* Loop exits via break */
i = iPc++;
if( i>=nRow ){
p->rc = SQLITE_OK;
rc = SQLITE_DONE;
break;
}
if( i<p->nOp ){
/* The rowid is small enough that we are still in the
** main program. */
aOp = p->aOp;
}else{
/* We are currently listing subprograms. Figure out which one and
** pick up the appropriate opcode. */
int j;
i -= p->nOp;
assert( apSub!=0 );
assert( nSub>0 );
for(j=0; i>=apSub[j]->nOp; j++){
i -= apSub[j]->nOp;
assert( i<apSub[j]->nOp || j+1<nSub );
}
aOp = apSub[j]->aOp;
}
/* When an OP_Program opcode is encounter (the only opcode that has
** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
** kept in p->aMem[9].z to hold the new program - assuming this subprogram
** has not already been seen.
*/
if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
int nByte = (nSub+1)*sizeof(SubProgram*);
int j;
for(j=0; j<nSub; j++){
if( apSub[j]==aOp[i].p4.pProgram ) break;
}
if( j==nSub ){
p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
if( p->rc!=SQLITE_OK ){
rc = SQLITE_ERROR;
break;
}
apSub = (SubProgram **)pSub->z;
apSub[nSub++] = aOp[i].p4.pProgram;
MemSetTypeFlag(pSub, MEM_Blob);
pSub->n = nSub*sizeof(SubProgram*);
nRow += aOp[i].p4.pProgram->nOp;
}
}
if( eMode==0 ) break;
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
if( eMode==2 ){
Op *pOp = aOp + i;
if( pOp->opcode==OP_OpenRead ) break;
if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
if( pOp->opcode==OP_ReopenIdx ) break;
}else
#endif
{
assert( eMode==1 );
if( aOp[i].opcode==OP_Explain ) break;
if( aOp[i].opcode==OP_Init && iPc>1 ) break;
}
}
*piPc = iPc;
*piAddr = i;
*paOp = aOp;
return rc;
}
#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite3VdbeExec().
*/
SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
int i;
|
| ︙ | ︙ | |||
79226 79227 79228 79229 79230 79231 79232 |
**
** When p->explain==1, first the main program is listed, then each of
** the trigger subprograms are listed one by one.
*/
SQLITE_PRIVATE int sqlite3VdbeList(
Vdbe *p /* The VDBE */
){
| < < < > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < | < < < < | < | | < < < < < < < < < < < < | < < < | < < < < < < < < < < < < > | | < < < | < < < < < < < | < < < | < < < | < < < | < < < < < < < < < | | | < | | < | < < < < < < < | | > | < | < < < < > < | | > | > > > > | | > | 79568 79569 79570 79571 79572 79573 79574 79575 79576 79577 79578 79579 79580 79581 79582 79583 79584 79585 79586 79587 79588 79589 79590 79591 79592 79593 79594 79595 79596 79597 79598 79599 79600 79601 79602 79603 79604 79605 79606 79607 79608 79609 79610 79611 79612 79613 79614 79615 79616 79617 79618 79619 79620 79621 79622 79623 79624 79625 79626 79627 79628 79629 79630 79631 79632 79633 79634 79635 79636 79637 79638 79639 79640 79641 79642 79643 79644 79645 79646 79647 79648 79649 79650 79651 79652 79653 79654 79655 79656 79657 79658 79659 79660 79661 79662 79663 79664 |
**
** When p->explain==1, first the main program is listed, then each of
** the trigger subprograms are listed one by one.
*/
SQLITE_PRIVATE int sqlite3VdbeList(
Vdbe *p /* The VDBE */
){
Mem *pSub = 0; /* Memory cell hold array of subprogs */
sqlite3 *db = p->db; /* The database connection */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
Op *aOp; /* Array of opcodes */
Op *pOp; /* Current opcode */
assert( p->explain );
assert( p->magic==VDBE_MAGIC_RUN );
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
/* Even though this opcode does not use dynamic strings for
** the result, result columns may become dynamic if the user calls
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
*/
releaseMemArray(pMem, 8);
p->pResultSet = 0;
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
sqlite3OomFault(db);
return SQLITE_ERROR;
}
if( bListSubprogs ){
/* The first 8 memory cells are used for the result set. So we will
** commandeer the 9th cell to use as storage for an array of pointers
** to trigger subprograms. The VDBE is guaranteed to have at least 9
** cells. */
assert( p->nMem>9 );
pSub = &p->aMem[9];
}else{
pSub = 0;
}
/* Figure out which opcode is next to display */
rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
if( rc==SQLITE_OK ){
pOp = aOp + i;
if( AtomicLoad(&db->u1.isInterrupted) ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
}else{
char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
if( p->explain==2 ){
sqlite3VdbeMemSetInt64(pMem, pOp->p1);
sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 4;
}else{
sqlite3VdbeMemSetInt64(pMem+0, i);
sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
-1, SQLITE_UTF8, SQLITE_STATIC);
sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
/* pMem+5 for p4 is done last */
sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
{
char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
}
#else
sqlite3VdbeMemSetNull(pMem+7);
#endif
sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 8;
}
p->pResultSet = pMem;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
rc = SQLITE_ERROR;
}else{
p->rc = SQLITE_OK;
rc = SQLITE_ROW;
}
}
}
return rc;
}
#endif /* SQLITE_OMIT_EXPLAIN */
#ifdef SQLITE_DEBUG
|
| ︙ | ︙ | |||
79980 79981 79982 79983 79984 79985 79986 |
i64 offset = 0;
int res;
int retryCount = 0;
int nMainFile;
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
| | > | 80220 80221 80222 80223 80224 80225 80226 80227 80228 80229 80230 80231 80232 80233 80234 80235 80236 |
i64 offset = 0;
int res;
int retryCount = 0;
int nMainFile;
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
zMaster = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
zMaster += 4;
do {
u32 iRandom;
if( retryCount ){
if( retryCount>100 ){
sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
break;
|
| ︙ | ︙ | |||
80011 80012 80013 80014 80015 80016 80017 |
/* Open the master journal. */
rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
);
}
if( rc!=SQLITE_OK ){
| | | 80252 80253 80254 80255 80256 80257 80258 80259 80260 80261 80262 80263 80264 80265 80266 |
/* Open the master journal. */
rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
);
}
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, zMaster-4);
return rc;
}
/* Write the name of each database file in the transaction into the new
** master journal file. If an error occurs at this point close
** and delete the master journal file. All the individual journal files
** still have 'null' as the master journal pointer, so they will roll
|
| ︙ | ︙ | |||
80034 80035 80036 80037 80038 80039 80040 |
}
assert( zFile[0]!=0 );
rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
offset += sqlite3Strlen30(zFile)+1;
if( rc!=SQLITE_OK ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
| | | | 80275 80276 80277 80278 80279 80280 80281 80282 80283 80284 80285 80286 80287 80288 80289 80290 80291 80292 80293 80294 80295 80296 80297 80298 80299 80300 80301 80302 80303 |
}
assert( zFile[0]!=0 );
rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
offset += sqlite3Strlen30(zFile)+1;
if( rc!=SQLITE_OK ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
sqlite3DbFree(db, zMaster-4);
return rc;
}
}
}
/* Sync the master journal file. If the IOCAP_SEQUENTIAL device
** flag is set this is not required.
*/
if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
&& SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
sqlite3DbFree(db, zMaster-4);
return rc;
}
/* Sync all the db files involved in the transaction. The same call
** sets the master journal pointer in each individual journal. If
** an error occurs here, do not delete the master journal file.
**
|
| ︙ | ︙ | |||
80071 80072 80073 80074 80075 80076 80077 |
if( pBt ){
rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
}
}
sqlite3OsCloseFree(pMaster);
assert( rc!=SQLITE_BUSY );
if( rc!=SQLITE_OK ){
| | | | 80312 80313 80314 80315 80316 80317 80318 80319 80320 80321 80322 80323 80324 80325 80326 80327 80328 80329 80330 80331 80332 80333 80334 80335 |
if( pBt ){
rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
}
}
sqlite3OsCloseFree(pMaster);
assert( rc!=SQLITE_BUSY );
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, zMaster-4);
return rc;
}
/* Delete the master journal file. This commits the transaction. After
** doing this the directory is synced again before any individual
** transaction files are deleted.
*/
rc = sqlite3OsDelete(pVfs, zMaster, 1);
sqlite3DbFree(db, zMaster-4);
zMaster = 0;
if( rc ){
return rc;
}
/* All files and directories have already been synced, so the following
** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
|
| ︙ | ︙ | |||
87996 87997 87998 87999 88000 88001 88002 | assert( nByte==(int)(zPayload - (u8*)pOut->z) ); assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); REGISTER_TRACE(pOp->p3, pOut); break; } | | | > > > > < > > > | | | > < | 88237 88238 88239 88240 88241 88242 88243 88244 88245 88246 88247 88248 88249 88250 88251 88252 88253 88254 88255 88256 88257 88258 88259 88260 88261 88262 88263 88264 88265 88266 88267 88268 88269 88270 88271 88272 88273 88274 88275 88276 88277 88278 |
assert( nByte==(int)(zPayload - (u8*)pOut->z) );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
REGISTER_TRACE(pOp->p3, pOut);
break;
}
/* Opcode: Count P1 P2 p3 * *
** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2.
**
** If P3==0, then an exact count is obtained, which involves visiting
** every btree page of the table. But if P3 is non-zero, an estimate
** is returned based on the current cursor position.
*/
case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
assert( pCrsr );
if( pOp->p3 ){
nEntry = sqlite3BtreeRowCountEst(pCrsr);
}else{
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
if( rc ) goto abort_due_to_error;
}
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
goto check_for_interrupt;
}
/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
|
| ︙ | ︙ | |||
90455 90456 90457 90458 90459 90460 90461 | rc = ExpandBlob(pIn2); if( rc ) goto abort_due_to_error; rc = sqlite3VdbeSorterWrite(pC, pIn2); if( rc) goto abort_due_to_error; break; } | | > > > > > > > < > > > | 90702 90703 90704 90705 90706 90707 90708 90709 90710 90711 90712 90713 90714 90715 90716 90717 90718 90719 90720 90721 90722 90723 90724 90725 90726 90727 90728 90729 90730 90731 90732 90733 90734 90735 90736 90737 90738 90739 90740 90741 90742 90743 90744 90745 90746 90747 90748 90749 90750 90751 90752 90753 90754 90755 90756 |
rc = ExpandBlob(pIn2);
if( rc ) goto abort_due_to_error;
rc = sqlite3VdbeSorterWrite(pC, pIn2);
if( rc) goto abort_due_to_error;
break;
}
/* Opcode: IdxDelete P1 P2 P3 * P5
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the
** index opened by cursor P1.
**
** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
** if no matching index entry is found. This happens when running
** an UPDATE or DELETE statement and the index entry to be updated
** or deleted is not found. For some uses of IdxDelete
** (example: the EXCEPT operator) it does not matter that no matching
** entry is found. For those cases, P5 is zero.
*/
case OP_IdxDelete: {
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
UnpackedRecord r;
assert( pOp->p3>0 );
assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
sqlite3VdbeIncrWriteCounter(p, pC);
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
if( rc ) goto abort_due_to_error;
if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
if( rc ) goto abort_due_to_error;
}else if( pOp->p5 ){
rc = SQLITE_CORRUPT_INDEX;
goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
pC->seekResult = 0;
break;
}
|
| ︙ | ︙ | |||
96091 96092 96093 96094 96095 96096 96097 96098 96099 96100 96101 96102 96103 96104 | } *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); return SQLITE_OK; } /************** End of vdbesort.c ********************************************/ /************** Begin file memjournal.c **************************************/ /* ** 2008 October 7 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 96347 96348 96349 96350 96351 96352 96353 96354 96355 96356 96357 96358 96359 96360 96361 96362 96363 96364 96365 96366 96367 96368 96369 96370 96371 96372 96373 96374 96375 96376 96377 96378 96379 96380 96381 96382 96383 96384 96385 96386 96387 96388 96389 96390 96391 96392 96393 96394 96395 96396 96397 96398 96399 96400 96401 96402 96403 96404 96405 96406 96407 96408 96409 96410 96411 96412 96413 96414 96415 96416 96417 96418 96419 96420 96421 96422 96423 96424 96425 96426 96427 96428 96429 96430 96431 96432 96433 96434 96435 96436 96437 96438 96439 96440 96441 96442 96443 96444 96445 96446 96447 96448 96449 96450 96451 96452 96453 96454 96455 96456 96457 96458 96459 96460 96461 96462 96463 96464 96465 96466 96467 96468 96469 96470 96471 96472 96473 96474 96475 96476 96477 96478 96479 96480 96481 96482 96483 96484 96485 96486 96487 96488 96489 96490 96491 96492 96493 96494 96495 96496 96497 96498 96499 96500 96501 96502 96503 96504 96505 96506 96507 96508 96509 96510 96511 96512 96513 96514 96515 96516 96517 96518 96519 96520 96521 96522 96523 96524 96525 96526 96527 96528 96529 96530 96531 96532 96533 96534 96535 96536 96537 96538 96539 96540 96541 96542 96543 96544 96545 96546 96547 96548 96549 96550 96551 96552 96553 96554 96555 96556 96557 96558 96559 96560 96561 96562 96563 96564 96565 96566 96567 96568 96569 96570 96571 96572 96573 96574 96575 96576 96577 96578 96579 96580 96581 96582 96583 96584 96585 96586 96587 96588 96589 96590 96591 96592 96593 96594 96595 96596 96597 96598 96599 96600 96601 96602 96603 96604 96605 96606 96607 96608 96609 96610 96611 96612 96613 96614 96615 96616 96617 96618 96619 96620 96621 96622 96623 96624 96625 96626 96627 96628 96629 96630 96631 96632 96633 96634 96635 96636 96637 96638 96639 96640 96641 96642 96643 96644 96645 96646 96647 96648 96649 96650 96651 96652 96653 96654 96655 96656 96657 96658 96659 96660 96661 96662 96663 96664 96665 96666 96667 96668 96669 96670 96671 96672 96673 96674 96675 96676 96677 96678 96679 96680 96681 96682 96683 96684 96685 96686 96687 96688 96689 96690 96691 96692 96693 96694 96695 96696 96697 96698 96699 96700 96701 96702 96703 96704 96705 96706 96707 96708 96709 96710 96711 96712 96713 96714 96715 96716 96717 96718 96719 96720 96721 96722 96723 96724 96725 96726 96727 96728 96729 96730 96731 96732 96733 96734 96735 96736 96737 96738 96739 96740 96741 96742 96743 96744 96745 96746 96747 96748 96749 96750 96751 96752 96753 96754 96755 96756 96757 96758 96759 96760 96761 96762 96763 96764 96765 96766 96767 96768 96769 96770 96771 96772 96773 96774 96775 96776 96777 96778 96779 96780 96781 96782 96783 96784 96785 |
}
*pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
return SQLITE_OK;
}
/************** End of vdbesort.c ********************************************/
/************** Begin file vdbevtab.c ****************************************/
/*
** 2020-03-23
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements virtual-tables for examining the bytecode content
** of a prepared statement.
*/
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
/* An instance of the bytecode() table-valued function.
*/
typedef struct bytecodevtab bytecodevtab;
struct bytecodevtab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* Database connection */
int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
};
/* A cursor for scanning through the bytecode
*/
typedef struct bytecodevtab_cursor bytecodevtab_cursor;
struct bytecodevtab_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
int iRowid; /* The rowid of the output table */
int iAddr; /* Address */
int needFinalize; /* Cursors owns pStmt and must finalize it */
int showSubprograms; /* Provide a listing of subprograms */
Op *aOp; /* Operand array */
char *zP4; /* Rendered P4 value */
const char *zType; /* tables_used.type */
const char *zSchema; /* tables_used.schema */
const char *zName; /* tables_used.name */
Mem sub; /* Subprograms */
};
/*
** Create a new bytecode() table-valued function.
*/
static int bytecodevtabConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
bytecodevtab *pNew;
int rc;
int isTabUsed = pAux!=0;
const char *azSchema[2] = {
/* bytecode() schema */
"CREATE TABLE x("
"addr INT,"
"opcode TEXT,"
"p1 INT,"
"p2 INT,"
"p3 INT,"
"p4 TEXT,"
"p5 INT,"
"comment TEXT,"
"subprog TEXT,"
"stmt HIDDEN"
");",
/* Tables_used() schema */
"CREATE TABLE x("
"type TEXT,"
"schema TEXT,"
"name TEXT,"
"wr INT,"
"subprog TEXT,"
"stmt HIDDEN"
");"
};
rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
pNew->db = db;
pNew->bTablesUsed = isTabUsed*2;
}
return rc;
}
/*
** This method is the destructor for bytecodevtab objects.
*/
static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
bytecodevtab *p = (bytecodevtab*)pVtab;
sqlite3_free(p);
return SQLITE_OK;
}
/*
** Constructor for a new bytecodevtab_cursor object.
*/
static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
bytecodevtab *pVTab = (bytecodevtab*)p;
bytecodevtab_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Clear all internal content from a bytecodevtab cursor.
*/
static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
sqlite3_free(pCur->zP4);
pCur->zP4 = 0;
sqlite3VdbeMemRelease(&pCur->sub);
sqlite3VdbeMemSetNull(&pCur->sub);
if( pCur->needFinalize ){
sqlite3_finalize(pCur->pStmt);
}
pCur->pStmt = 0;
pCur->needFinalize = 0;
pCur->zType = 0;
pCur->zSchema = 0;
pCur->zName = 0;
}
/*
** Destructor for a bytecodevtab_cursor.
*/
static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
bytecodevtabCursorClear(pCur);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Advance a bytecodevtab_cursor to its next row of output.
*/
static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
int rc;
if( pCur->zP4 ){
sqlite3_free(pCur->zP4);
pCur->zP4 = 0;
}
if( pCur->zName ){
pCur->zName = 0;
pCur->zType = 0;
pCur->zSchema = 0;
}
rc = sqlite3VdbeNextOpcode(
(Vdbe*)pCur->pStmt,
pCur->showSubprograms ? &pCur->sub : 0,
pTab->bTablesUsed,
&pCur->iRowid,
&pCur->iAddr,
&pCur->aOp);
if( rc!=SQLITE_OK ){
sqlite3VdbeMemSetNull(&pCur->sub);
pCur->aOp = 0;
}
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
return pCur->aOp==0;
}
/*
** Return values of columns for the row at which the bytecodevtab_cursor
** is currently pointing.
*/
static int bytecodevtabColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
Op *pOp = pCur->aOp + pCur->iAddr;
if( pVTab->bTablesUsed ){
if( i==4 ){
i = 8;
}else{
if( i<=2 && pCur->zType==0 ){
Schema *pSchema;
HashElem *k;
int iDb = pOp->p3;
int iRoot = pOp->p2;
sqlite3 *db = pVTab->db;
pSchema = db->aDb[iDb].pSchema;
pCur->zSchema = db->aDb[iDb].zDbSName;
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
Table *pTab = (Table*)sqliteHashData(k);
if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
pCur->zName = pTab->zName;
pCur->zType = "table";
break;
}
}
if( pCur->zName==0 ){
for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
Index *pIdx = (Index*)sqliteHashData(k);
if( pIdx->tnum==iRoot ){
pCur->zName = pIdx->zName;
pCur->zType = "index";
}
}
}
}
i += 10;
}
}
switch( i ){
case 0: /* addr */
sqlite3_result_int(ctx, pCur->iAddr);
break;
case 1: /* opcode */
sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
-1, SQLITE_STATIC);
break;
case 2: /* p1 */
sqlite3_result_int(ctx, pOp->p1);
break;
case 3: /* p2 */
sqlite3_result_int(ctx, pOp->p2);
break;
case 4: /* p3 */
sqlite3_result_int(ctx, pOp->p3);
break;
case 5: /* p4 */
case 7: /* comment */
if( pCur->zP4==0 ){
pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
}
if( i==5 ){
sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
}else{
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
#endif
}
break;
case 6: /* p5 */
sqlite3_result_int(ctx, pOp->p5);
break;
case 8: { /* subprog */
Op *aOp = pCur->aOp;
assert( aOp[0].opcode==OP_Init );
assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
if( pCur->iRowid==pCur->iAddr+1 ){
break; /* Result is NULL for the main program */
}else if( aOp[0].p4.z!=0 ){
sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
}else{
sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
}
break;
}
case 10: /* tables_used.type */
sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
break;
case 11: /* tables_used.schema */
sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
break;
case 12: /* tables_used.name */
sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
break;
case 13: /* tables_used.wr */
sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
break;
}
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
*pRowid = pCur->iRowid;
return SQLITE_OK;
}
/*
** Initialize a cursor.
**
** idxNum==0 means show all subprograms
** idxNum==1 means show only the main bytecode and omit subprograms.
*/
static int bytecodevtabFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
int rc = SQLITE_OK;
bytecodevtabCursorClear(pCur);
pCur->iRowid = 0;
pCur->iAddr = 0;
pCur->showSubprograms = idxNum==0;
assert( argc==1 );
if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
const char *zSql = (const char*)sqlite3_value_text(argv[0]);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
pCur->needFinalize = 1;
}
}else{
pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
}
if( pCur->pStmt==0 ){
pVTab->base.zErrMsg = sqlite3_mprintf(
"argument to %s() is not a valid SQL statement",
pVTab->bTablesUsed ? "tables_used" : "bytecode"
);
rc = SQLITE_ERROR;
}else{
bytecodevtabNext(pVtabCursor);
}
return rc;
}
/*
** We must have a single stmt=? constraint that will be passed through
** into the xFilter method. If there is no valid stmt=? constraint,
** then return an SQLITE_CONSTRAINT error.
*/
static int bytecodevtabBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i;
int rc = SQLITE_CONSTRAINT;
struct sqlite3_index_constraint *p;
bytecodevtab *pVTab = (bytecodevtab*)tab;
int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
pIdxInfo->estimatedCost = (double)100;
pIdxInfo->estimatedRows = 100;
pIdxInfo->idxNum = 0;
for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
if( p->usable==0 ) continue;
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
rc = SQLITE_OK;
pIdxInfo->aConstraintUsage[i].omit = 1;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
}
if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
pIdxInfo->aConstraintUsage[i].omit = 1;
pIdxInfo->idxNum = 1;
}
}
return rc;
}
/*
** This following structure defines all the methods for the
** virtual table.
*/
static sqlite3_module bytecodevtabModule = {
/* iVersion */ 0,
/* xCreate */ 0,
/* xConnect */ bytecodevtabConnect,
/* xBestIndex */ bytecodevtabBestIndex,
/* xDisconnect */ bytecodevtabDisconnect,
/* xDestroy */ 0,
/* xOpen */ bytecodevtabOpen,
/* xClose */ bytecodevtabClose,
/* xFilter */ bytecodevtabFilter,
/* xNext */ bytecodevtabNext,
/* xEof */ bytecodevtabEof,
/* xColumn */ bytecodevtabColumn,
/* xRowid */ bytecodevtabRowid,
/* xUpdate */ 0,
/* xBegin */ 0,
/* xSync */ 0,
/* xCommit */ 0,
/* xRollback */ 0,
/* xFindMethod */ 0,
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
int rc;
rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
}
return rc;
}
#endif /* SQLITE_ENABLE_BYTECODE_VTAB */
/************** End of vdbevtab.c ********************************************/
/************** Begin file memjournal.c **************************************/
/*
** 2008 October 7
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
98737 98738 98739 98740 98741 98742 98743 |
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
int op;
while( ExprHasProperty(pExpr, EP_Skip) ){
| | | 99418 99419 99420 99421 99422 99423 99424 99425 99426 99427 99428 99429 99430 99431 99432 |
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
int op;
while( ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
assert( pExpr!=0 );
}
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
|
| ︙ | ︙ | |||
98804 98805 98806 98807 98808 98809 98810 |
}
/*
** Skip over any TK_COLLATE operators.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
| | | | 99485 99486 99487 99488 99489 99490 99491 99492 99493 99494 99495 99496 99497 99498 99499 99500 99501 99502 99503 99504 99505 99506 99507 99508 99509 99510 99511 99512 99513 99514 99515 99516 99517 99518 |
}
/*
** Skip over any TK_COLLATE operators.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
}
return pExpr;
}
/*
** Skip over any TK_COLLATE operators and/or any unlikely()
** or likelihood() or likely() functions at the root of an
** expression.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
}
}
return pExpr;
}
/*
|
| ︙ | ︙ | |||
103174 103175 103176 103177 103178 103179 103180 |
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
assert( pExpr->affExpr==OE_Rollback
|| pExpr->affExpr==OE_Abort
|| pExpr->affExpr==OE_Fail
|| pExpr->affExpr==OE_Ignore
);
| | | > | | 103855 103856 103857 103858 103859 103860 103861 103862 103863 103864 103865 103866 103867 103868 103869 103870 103871 103872 103873 103874 103875 103876 103877 103878 103879 103880 103881 103882 103883 103884 103885 |
#ifndef SQLITE_OMIT_TRIGGER
case TK_RAISE: {
assert( pExpr->affExpr==OE_Rollback
|| pExpr->affExpr==OE_Abort
|| pExpr->affExpr==OE_Fail
|| pExpr->affExpr==OE_Ignore
);
if( !pParse->pTriggerTab && !pParse->nested ){
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
}
if( pExpr->affExpr==OE_Abort ){
sqlite3MayAbort(pParse);
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
if( pExpr->affExpr==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
VdbeCoverage(v);
}else{
sqlite3HaltConstraint(pParse,
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
pExpr->affExpr, pExpr->u.zToken, 0, 0);
}
break;
}
#endif
}
sqlite3ReleaseTempReg(pParse, regFree1);
|
| ︙ | ︙ | |||
104944 104945 104946 104947 104948 104949 104950 104951 104952 104953 104954 104955 104956 104957 | renameTestSchema(pParse, zDb, iDb==1); exit_rename_table: sqlite3SrcListDelete(db, pSrc); sqlite3DbFree(db, zName); db->mDbFlags = savedDbFlags; } /* ** This function is called after an "ALTER TABLE ... ADD" statement ** has been parsed. Argument pColDef contains the text of the new ** column definition. ** ** The Table structure pParse->pNewTable was extended to include | > > > > > > > > > > > > > > > > | 105626 105627 105628 105629 105630 105631 105632 105633 105634 105635 105636 105637 105638 105639 105640 105641 105642 105643 105644 105645 105646 105647 105648 105649 105650 105651 105652 105653 105654 105655 |
renameTestSchema(pParse, zDb, iDb==1);
exit_rename_table:
sqlite3SrcListDelete(db, pSrc);
sqlite3DbFree(db, zName);
db->mDbFlags = savedDbFlags;
}
/*
** Write code that will raise an error if the table described by
** zDb and zTab is not empty.
*/
static void sqlite3ErrorIfNotEmpty(
Parse *pParse, /* Parsing context */
const char *zDb, /* Schema holding the table */
const char *zTab, /* Table to check for empty */
const char *zErr /* Error message text */
){
sqlite3NestedParse(pParse,
"SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
zErr, zDb, zTab
);
}
/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
**
** The Table structure pParse->pNewTable was extended to include
|
| ︙ | ︙ | |||
104997 104998 104999 105000 105001 105002 105003 |
** column must not be NULL.
*/
if( pCol->colFlags & COLFLAG_PRIMKEY ){
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
return;
}
if( pNew->pIndex ){
| | > | < | < > > | < | < | 105695 105696 105697 105698 105699 105700 105701 105702 105703 105704 105705 105706 105707 105708 105709 105710 105711 105712 105713 105714 105715 105716 105717 105718 105719 105720 105721 105722 105723 105724 105725 105726 105727 105728 105729 105730 105731 105732 105733 105734 105735 105736 105737 105738 105739 105740 105741 105742 105743 105744 105745 105746 105747 105748 105749 105750 105751 |
** column must not be NULL.
*/
if( pCol->colFlags & COLFLAG_PRIMKEY ){
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
return;
}
if( pNew->pIndex ){
sqlite3ErrorMsg(pParse,
"Cannot add a UNIQUE column");
return;
}
if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
/* If the default value for the new column was specified with a
** literal NULL, then set pDflt to 0. This simplifies checking
** for an SQL NULL default below.
*/
assert( pDflt==0 || pDflt->op==TK_SPAN );
if( pDflt && pDflt->pLeft->op==TK_NULL ){
pDflt = 0;
}
if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
"Cannot add a REFERENCES column with non-NULL default value");
}
if( pCol->notNull && !pDflt ){
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
"Cannot add a NOT NULL column with default value NULL");
}
/* Ensure the default expression is something that sqlite3ValueFromExpr()
** can handle (i.e. not CURRENT_TIME etc.)
*/
if( pDflt ){
sqlite3_value *pVal = 0;
int rc;
rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
if( rc!=SQLITE_OK ){
assert( db->mallocFailed == 1 );
return;
}
if( !pVal ){
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
"Cannot add a column with non-constant default");
}
sqlite3ValueFree(pVal);
}
}else if( pCol->colFlags & COLFLAG_STORED ){
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
}
/* Modify the CREATE TABLE statement. */
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
|
| ︙ | ︙ | |||
106603 106604 106605 106606 106607 106608 106609 106610 106611 106612 106613 106614 106615 106616 106617 106618 106619 106620 106621 106622 |
};
int i;
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
int aRoot[ArraySize(aTable)];
u8 aCreateTbl[ArraySize(aTable)];
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3VdbeDb(v)==db );
pDb = &db->aDb[iDb];
/* Create new statistic tables if they do not exist, or clear them
** if they do already exist.
*/
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
| > > > > > > | < | | 107300 107301 107302 107303 107304 107305 107306 107307 107308 107309 107310 107311 107312 107313 107314 107315 107316 107317 107318 107319 107320 107321 107322 107323 107324 107325 107326 107327 107328 107329 107330 107331 107332 107333 107334 107335 107336 107337 107338 107339 107340 107341 107342 107343 107344 107345 107346 107347 107348 107349 107350 107351 107352 107353 107354 107355 107356 107357 107358 107359 107360 107361 107362 107363 107364 107365 107366 107367 |
};
int i;
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
int aRoot[ArraySize(aTable)];
u8 aCreateTbl[ArraySize(aTable)];
#ifdef SQLITE_ENABLE_STAT4
const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
#else
const int nToOpen = 1;
#endif
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3VdbeDb(v)==db );
pDb = &db->aDb[iDb];
/* Create new statistic tables if they do not exist, or clear them
** if they do already exist.
*/
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
aCreateTbl[i] = 0;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
if( i<nToOpen ){
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
aRoot[i] = pParse->regRoot;
aCreateTbl[i] = OPFLAG_P2ISREG;
}
}else{
/* The table already exists. If zWhere is not NULL, delete all entries
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zDbSName, zTab, zWhereType, zWhere
);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
}else if( db->xPreUpdateCallback ){
sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
#endif
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
}
}
}
/* Open the sqlite_stat[134] tables for writing. */
for(i=0; i<nToOpen; i++){
assert( i<ArraySize(aTable) );
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
VdbeComment((v, aTable[i].zName));
}
}
|
| ︙ | ︙ | |||
106690 106691 106692 106693 106694 106695 106696 |
u8 isPSample; /* True if a periodic sample */
int iCol; /* If !isPSample, the reason for inclusion */
u32 iHash; /* Tiebreaker hash */
#endif
};
struct StatAccum {
sqlite3 *db; /* Database connection, for malloc() */
| > | > > | 107392 107393 107394 107395 107396 107397 107398 107399 107400 107401 107402 107403 107404 107405 107406 107407 107408 107409 107410 107411 |
u8 isPSample; /* True if a periodic sample */
int iCol; /* If !isPSample, the reason for inclusion */
u32 iHash; /* Tiebreaker hash */
#endif
};
struct StatAccum {
sqlite3 *db; /* Database connection, for malloc() */
tRowcnt nEst; /* Estimated number of rows */
tRowcnt nRow; /* Number of rows visited so far */
int nLimit; /* Analysis row-scan limit */
int nCol; /* Number of columns in index + pk/rowid */
int nKeyCol; /* Number of index columns w/o the pk/rowid */
u8 nSkipAhead; /* Number of times of skip-ahead */
StatSample current; /* Current row as a StatSample */
#ifdef SQLITE_ENABLE_STAT4
tRowcnt nPSample; /* How often to do a periodic sample */
int mxSample; /* Maximum number of samples to accumulate */
u32 iPrn; /* Pseudo-random number used for sampling */
StatSample *aBest; /* Array of nCol best samples */
int iMin; /* Index in a[] of entry with minimum score */
|
| ︙ | ︙ | |||
106772 106773 106774 106775 106776 106777 106778 |
/*
** Reclaim all memory of a StatAccum structure.
*/
static void statAccumDestructor(void *pOld){
StatAccum *p = (StatAccum*)pOld;
#ifdef SQLITE_ENABLE_STAT4
| > | | | | > | | > < < | > | | > | | | > < > > > < > > < | | 107477 107478 107479 107480 107481 107482 107483 107484 107485 107486 107487 107488 107489 107490 107491 107492 107493 107494 107495 107496 107497 107498 107499 107500 107501 107502 107503 107504 107505 107506 107507 107508 107509 107510 107511 107512 107513 107514 107515 107516 107517 107518 107519 107520 107521 107522 107523 107524 107525 107526 107527 107528 107529 107530 107531 107532 107533 107534 107535 107536 107537 107538 107539 107540 107541 107542 107543 107544 107545 107546 107547 107548 107549 107550 107551 107552 107553 107554 107555 107556 107557 107558 107559 107560 107561 107562 107563 107564 107565 107566 107567 107568 107569 107570 107571 107572 107573 107574 107575 107576 107577 107578 107579 107580 107581 107582 107583 |
/*
** Reclaim all memory of a StatAccum structure.
*/
static void statAccumDestructor(void *pOld){
StatAccum *p = (StatAccum*)pOld;
#ifdef SQLITE_ENABLE_STAT4
if( p->mxSample ){
int i;
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
sampleClear(p->db, &p->current);
}
#endif
sqlite3DbFree(p->db, p);
}
/*
** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
** are:
** N: The number of columns in the index including the rowid/pk (note 1)
** K: The number of columns in the index excluding the rowid/pk.
** C: Estimated number of rows in the index
** L: A limit on the number of rows to scan, or 0 for no-limit
**
** Note 1: In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table. The covering index that implements the
** original WITHOUT ROWID table as N==K as a special case.
**
** This routine allocates the StatAccum object in heap memory. The return
** value is a pointer to the StatAccum object. The datatype of the
** return value is BLOB, but it is really just a pointer to the StatAccum
** object.
*/
static void statInit(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
StatAccum *p;
int nCol; /* Number of columns in index being sampled */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
/* Maximum number of samples. 0 if STAT4 data is not collected */
int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
#endif
/* Decode the three function arguments */
UNUSED_PARAMETER(argc);
nCol = sqlite3_value_int(argv[0]);
assert( nCol>0 );
nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
nKeyCol = sqlite3_value_int(argv[1]);
assert( nKeyCol<=nCol );
assert( nKeyCol>0 );
/* Allocate the space required for the StatAccum object */
n = sizeof(*p)
+ sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
+ sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
#ifdef SQLITE_ENABLE_STAT4
if( mxSample ){
n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
}
#endif
db = sqlite3_context_db_handle(context);
p = sqlite3DbMallocZero(db, n);
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
p->db = db;
p->nEst = sqlite3_value_int64(argv[2]);
p->nRow = 0;
p->nLimit = sqlite3_value_int64(argv[3]);
p->nCol = nCol;
p->nKeyCol = nKeyCol;
p->nSkipAhead = 0;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
#ifdef SQLITE_ENABLE_STAT4
p->mxSample = p->nLimit==0 ? mxSample : 0;
if( mxSample ){
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
p->iGet = -1;
p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
p->current.anLt = &p->current.anEq[nColUp];
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
/* Set up the StatAccum.a[] and aBest[] arrays */
p->a = (struct StatSample*)&p->current.anLt[nColUp];
p->aBest = &p->a[mxSample];
pSpace = (u8*)(&p->a[mxSample+nCol]);
|
| ︙ | ︙ | |||
106886 106887 106888 106889 106890 106891 106892 |
/* Return a pointer to the allocated object to the caller. Note that
** only the pointer (the 2nd parameter) matters. The size of the object
** (given by the 3rd parameter) is never used and can be any positive
** value. */
sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
}
static const FuncDef statInitFuncdef = {
| | | 107597 107598 107599 107600 107601 107602 107603 107604 107605 107606 107607 107608 107609 107610 107611 |
/* Return a pointer to the allocated object to the caller. Note that
** only the pointer (the 2nd parameter) matters. The size of the object
** (given by the 3rd parameter) is never used and can be any positive
** value. */
sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
}
static const FuncDef statInitFuncdef = {
4, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
statInit, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"stat_init", /* zName */
|
| ︙ | ︙ | |||
107090 107091 107092 107093 107094 107095 107096 | ** Arguments: ** ** P Pointer to the StatAccum object created by stat_init() ** C Index of left-most column to differ from previous row ** R Rowid for the current row. Might be a key record for ** WITHOUT ROWID tables. ** | | | | | > > > | 107801 107802 107803 107804 107805 107806 107807 107808 107809 107810 107811 107812 107813 107814 107815 107816 107817 107818 107819 107820 107821 | ** Arguments: ** ** P Pointer to the StatAccum object created by stat_init() ** C Index of left-most column to differ from previous row ** R Rowid for the current row. Might be a key record for ** WITHOUT ROWID tables. ** ** The purpose of this routine is to collect statistical data and/or ** samples from the index being analyzed into the StatAccum object. ** The stat_get() SQL function will be used afterwards to ** retrieve the information gathered. ** ** This SQL function usually returns NULL, but might return an integer ** if it wants the byte-code to do special processing. ** ** The R parameter is only used for STAT4 */ static void statPush( sqlite3_context *context, int argc, sqlite3_value **argv |
| ︙ | ︙ | |||
107119 107120 107121 107122 107123 107124 107125 |
if( p->nRow==0 ){
/* This is the first call to this function. Do initialization. */
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}else{
/* Second and subsequent calls get processed here */
#ifdef SQLITE_ENABLE_STAT4
| | | > > > | | | | | | | < < < | < | > > > | > > | 107833 107834 107835 107836 107837 107838 107839 107840 107841 107842 107843 107844 107845 107846 107847 107848 107849 107850 107851 107852 107853 107854 107855 107856 107857 107858 107859 107860 107861 107862 107863 107864 107865 107866 107867 107868 107869 107870 107871 107872 107873 107874 107875 107876 107877 107878 107879 107880 107881 107882 107883 107884 107885 107886 107887 107888 107889 107890 107891 107892 107893 107894 107895 107896 107897 107898 107899 |
if( p->nRow==0 ){
/* This is the first call to this function. Do initialization. */
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}else{
/* Second and subsequent calls get processed here */
#ifdef SQLITE_ENABLE_STAT4
if( p->mxSample ) samplePushPrevious(p, iChng);
#endif
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
** to the current row of the index. */
for(i=0; i<iChng; i++){
p->current.anEq[i]++;
}
for(i=iChng; i<p->nCol; i++){
p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT4
if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
}
}
p->nRow++;
#ifdef SQLITE_ENABLE_STAT4
if( p->mxSample ){
tRowcnt nLt;
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
}else{
sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
sqlite3_value_blob(argv[2]));
}
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
nLt = p->current.anLt[p->nCol-1];
/* Check if this is to be a periodic sample. If so, add it. */
if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
p->current.isPSample = 1;
p->current.iCol = 0;
sampleInsert(p, &p->current, p->nCol-1);
p->current.isPSample = 0;
}
/* Update the aBest[] array. */
for(i=0; i<(p->nCol-1); i++){
p->current.iCol = i;
if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
sampleCopy(p, &p->aBest[i], &p->current);
}
}
}else
#endif
if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
p->nSkipAhead++;
sqlite3_result_int(context, p->current.anDLt[0]>0);
}
}
static const FuncDef statPushFuncdef = {
2+IsStat4, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
statPush, /* xSFunc */
0, /* xFinalize */
|
| ︙ | ︙ | |||
107219 107220 107221 107222 107223 107224 107225 107226 107227 107228 107229 107230 107231 107232 |
/* STAT4 has a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]);
assert( argc==2 );
assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|| eCall==STAT_GET_NDLT
);
if( eCall==STAT_GET_STAT1 )
#else
assert( argc==1 );
#endif
{
/* Return the value to store in the "stat" column of the sqlite_stat1
** table for this index.
| > | 107937 107938 107939 107940 107941 107942 107943 107944 107945 107946 107947 107948 107949 107950 107951 |
/* STAT4 has a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]);
assert( argc==2 );
assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|| eCall==STAT_GET_NDLT
);
assert( eCall==STAT_GET_STAT1 || p->mxSample );
if( eCall==STAT_GET_STAT1 )
#else
assert( argc==1 );
#endif
{
/* Return the value to store in the "stat" column of the sqlite_stat1
** table for this index.
|
| ︙ | ︙ | |||
107254 107255 107256 107257 107258 107259 107260 |
char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
if( zRet==0 ){
sqlite3_result_error_nomem(context);
return;
}
| | > | 107973 107974 107975 107976 107977 107978 107979 107980 107981 107982 107983 107984 107985 107986 107987 107988 |
char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
if( zRet==0 ){
sqlite3_result_error_nomem(context);
return;
}
sqlite3_snprintf(24, zRet, "%llu",
p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
z = zRet + sqlite3Strlen30(zRet);
for(i=0; i<p->nKeyCol; i++){
u64 nDistinct = p->current.anDLt[i] + 1;
u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
sqlite3_snprintf(24, z, " %llu", iVal);
z += sqlite3Strlen30(z);
assert( p->current.anEq[i] );
|
| ︙ | ︙ | |||
107330 107331 107332 107333 107334 107335 107336 |
statGet, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"stat_get", /* zName */
{0}
};
| | | | | | 108050 108051 108052 108053 108054 108055 108056 108057 108058 108059 108060 108061 108062 108063 108064 108065 108066 108067 108068 108069 108070 108071 108072 108073 |
statGet, /* xSFunc */
0, /* xFinalize */
0, 0, /* xValue, xInverse */
"stat_get", /* zName */
{0}
};
static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
#ifdef SQLITE_ENABLE_STAT4
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
#elif SQLITE_DEBUG
assert( iParam==STAT_GET_STAT1 );
#else
UNUSED_PARAMETER( iParam );
#endif
assert( regOut!=regStat && regOut!=regStat+1 );
sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
&statGetFuncdef, 0);
}
/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
|
| ︙ | ︙ | |||
107365 107366 107367 107368 107369 107370 107371 | int iTabCur; /* Table cursor */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ int regNewRowid = iMem++; /* Rowid for the inserted record */ | | < < > | 108085 108086 108087 108088 108089 108090 108091 108092 108093 108094 108095 108096 108097 108098 108099 108100 108101 108102 108103 | int iTabCur; /* Table cursor */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ int regNewRowid = iMem++; /* Rowid for the inserted record */ int regStat = iMem++; /* Register to hold StatAccum object */ int regChng = iMem++; /* Index of changed index field */ int regRowid = iMem++; /* Rowid argument passed to stat_push() */ int regTemp = iMem++; /* Temporary use register */ int regTemp2 = iMem++; /* Second temporary use register */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ int regPrev = iMem; /* MUST BE LAST (see below) */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK Table *pStat1 = 0; #endif |
| ︙ | ︙ | |||
107498 107499 107500 107501 107502 107503 107504 |
VdbeComment((v, "%s", pIdx->zName));
/* Invoke the stat_init() function. The arguments are:
**
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
| | < < < > > > > | > > > > | > > > > | | < < | 108217 108218 108219 108220 108221 108222 108223 108224 108225 108226 108227 108228 108229 108230 108231 108232 108233 108234 108235 108236 108237 108238 108239 108240 108241 108242 108243 108244 108245 108246 108247 108248 108249 108250 108251 108252 108253 108254 108255 108256 108257 108258 108259 108260 |
VdbeComment((v, "%s", pIdx->zName));
/* Invoke the stat_init() function. The arguments are:
**
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
** (3) estimated number of rows in the index,
*/
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
assert( regRowid==regStat+2 );
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
#ifdef SQLITE_ENABLE_STAT4
if( OptimizationEnabled(db, SQLITE_Stat4) ){
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
VdbeCoverage(v);
}else
#endif
{
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
}
assert( regTemp2==regStat+4 );
sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
&statInitFuncdef, 0);
/* Implementation of the following:
**
** Rewind csr
** if eof(csr) goto end_of_scan;
** regChng = 0
** goto next_push_0;
**
*/
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrNextRow = sqlite3VdbeCurrentAddr(v);
if( nColTest>0 ){
int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
int *aGotoChng; /* Array of jump instruction addresses */
aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
|
| ︙ | ︙ | |||
107553 107554 107555 107556 107557 107558 107559 107560 107561 107562 107563 107564 107565 107566 107567 107568 107569 107570 107571 107572 107573 107574 107575 107576 107577 107578 107579 107580 107581 107582 107583 107584 107585 107586 107587 107588 107589 107590 107591 107592 |
sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest);
VdbeCoverage(v);
}
for(i=0; i<nColTest; i++){
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
sqlite3VdbeGoto(v, endDistinctTest);
/*
** chng_addr_0:
** regPrev(0) = idx(0)
** chng_addr_1:
** regPrev(1) = idx(1)
** ...
*/
sqlite3VdbeJumpHere(v, addrNextRow-1);
for(i=0; i<nColTest; i++){
sqlite3VdbeJumpHere(v, aGotoChng[i]);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
}
sqlite3VdbeResolveLabel(v, endDistinctTest);
sqlite3DbFree(db, aGotoChng);
}
/*
** chng_addr_N:
** regRowid = idx(rowid) // STAT4 only
** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
** Next csr
** if !eof(csr) goto next_row;
*/
#ifdef SQLITE_ENABLE_STAT4
| > > > | | | | | | | | | | | | | | | | > | > | | > > > > > > > | > > > > | > > | < > | | | | | 108279 108280 108281 108282 108283 108284 108285 108286 108287 108288 108289 108290 108291 108292 108293 108294 108295 108296 108297 108298 108299 108300 108301 108302 108303 108304 108305 108306 108307 108308 108309 108310 108311 108312 108313 108314 108315 108316 108317 108318 108319 108320 108321 108322 108323 108324 108325 108326 108327 108328 108329 108330 108331 108332 108333 108334 108335 108336 108337 108338 108339 108340 108341 108342 108343 108344 108345 108346 108347 108348 108349 108350 108351 108352 108353 108354 108355 108356 108357 108358 108359 108360 108361 108362 108363 108364 108365 108366 108367 108368 108369 108370 108371 108372 108373 108374 108375 108376 108377 108378 108379 108380 108381 108382 108383 108384 108385 108386 108387 108388 108389 108390 108391 108392 108393 108394 108395 108396 108397 108398 |
sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest);
VdbeCoverage(v);
}
for(i=0; i<nColTest; i++){
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
sqlite3VdbeGoto(v, endDistinctTest);
/*
** chng_addr_0:
** regPrev(0) = idx(0)
** chng_addr_1:
** regPrev(1) = idx(1)
** ...
*/
sqlite3VdbeJumpHere(v, addrNextRow-1);
for(i=0; i<nColTest; i++){
sqlite3VdbeJumpHere(v, aGotoChng[i]);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
}
sqlite3VdbeResolveLabel(v, endDistinctTest);
sqlite3DbFree(db, aGotoChng);
}
/*
** chng_addr_N:
** regRowid = idx(rowid) // STAT4 only
** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
** Next csr
** if !eof(csr) goto next_row;
*/
#ifdef SQLITE_ENABLE_STAT4
if( OptimizationEnabled(db, SQLITE_Stat4) ){
assert( regRowid==(regStat+2) );
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
}else{
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
int j, k, regKey;
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; j<pPk->nKeyCol; j++){
k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
assert( k>=0 && k<pIdx->nColumn );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
}
#endif
assert( regChng==(regStat+1) );
{
sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
&statPushFuncdef, 0);
if( db->nAnalysisLimit ){
int j1, j2, j3;
j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeJumpHere(v, j3);
}else{
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
}
}
/* Add the entry to the stat1 table. */
callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
int regEq = regStat1;
int regLt = regStat1+1;
int regDLt = regStat1+2;
int regSample = regStat1+3;
int regCol = regStat1+4;
int regSampleRowid = regCol + nCol;
int addrNext;
int addrIsNull;
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
addrNext = sqlite3VdbeCurrentAddr(v);
callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
for(i=0; i<nCol; i++){
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
|
| ︙ | ︙ | |||
113816 113817 113818 113819 113820 113821 113822 |
sqlite3ErrorMsg(pParse, "unable to open a temporary database "
"file for storing temporary tables");
pParse->rc = rc;
return 1;
}
db->aDb[1].pBt = pBt;
assert( db->aDb[1].pSchema );
| | | 114560 114561 114562 114563 114564 114565 114566 114567 114568 114569 114570 114571 114572 114573 114574 |
sqlite3ErrorMsg(pParse, "unable to open a temporary database "
"file for storing temporary tables");
pParse->rc = rc;
return 1;
}
db->aDb[1].pBt = pBt;
assert( db->aDb[1].pSchema );
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
sqlite3OomFault(db);
return 1;
}
}
return 0;
}
|
| ︙ | ︙ | |||
113927 113928 113929 113930 113931 113932 113933 |
int errCode, /* extended error code */
int onError, /* Constraint type */
char *p4, /* Error message */
i8 p4type, /* P4_STATIC or P4_TRANSIENT */
u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
| | | 114671 114672 114673 114674 114675 114676 114677 114678 114679 114680 114681 114682 114683 114684 114685 |
int errCode, /* extended error code */
int onError, /* Constraint type */
char *p4, /* Error message */
i8 p4type, /* P4_STATIC or P4_TRANSIENT */
u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
sqlite3VdbeChangeP5(v, p5Errmsg);
}
|
| ︙ | ︙ | |||
115640 115641 115642 115643 115644 115645 115646 115647 115648 115649 115650 115651 115652 115653 |
if( pIdx==pPk ) continue;
if( iIdxCur+i==iIdxNoSeek ) continue;
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
}
}
/*
** Generate code that will assemble an index key and stores it in register
| > | 116384 116385 116386 116387 116388 116389 116390 116391 116392 116393 116394 116395 116396 116397 116398 |
if( pIdx==pPk ) continue;
if( iIdxCur+i==iIdxNoSeek ) continue;
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
}
}
/*
** Generate code that will assemble an index key and stores it in register
|
| ︙ | ︙ | |||
122627 122628 122629 122630 122631 122632 122633 122634 122635 122636 122637 122638 122639 122640 |
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(char*);
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
| > | 123372 123373 123374 123375 123376 123377 123378 123379 123380 123381 123382 123383 123384 123385 123386 |
const char *(*filename_database)(const char*);
const char *(*filename_journal)(const char*);
const char *(*filename_wal)(const char*);
/* Version 3.32.0 and later */
char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(char*);
sqlite3_file *(*database_file_object)(const char*);
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
|
| ︙ | ︙ | |||
122930 122931 122932 122933 122934 122935 122936 122937 122938 122939 122940 122941 122942 122943 | #define sqlite3_uri_key sqlite3_api->uri_key #define sqlite3_filename_database sqlite3_api->filename_database #define sqlite3_filename_journal sqlite3_api->filename_journal #define sqlite3_filename_wal sqlite3_api->filename_wal /* Version 3.32.0 and later */ #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; | > | 123676 123677 123678 123679 123680 123681 123682 123683 123684 123685 123686 123687 123688 123689 123690 | #define sqlite3_uri_key sqlite3_api->uri_key #define sqlite3_filename_database sqlite3_api->filename_database #define sqlite3_filename_journal sqlite3_api->filename_journal #define sqlite3_filename_wal sqlite3_api->filename_wal /* Version 3.32.0 and later */ #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #define sqlite3_database_file_object sqlite3_api->database_file_object #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; |
| ︙ | ︙ | |||
123411 123412 123413 123414 123415 123416 123417 123418 123419 123420 123421 123422 123423 123424 123425 | sqlite3_uri_key, sqlite3_filename_database, sqlite3_filename_journal, sqlite3_filename_wal, /* Version 3.32.0 and later */ sqlite3_create_filename, sqlite3_free_filename, }; /* ** Attempt to load an SQLite extension library contained in the file ** zFile. The entry point is zProc. zProc may be 0 in which case a ** default entry point name (sqlite3_extension_init) is used. Use ** of the default name is recommended. ** | > > > > > > > > > | 124158 124159 124160 124161 124162 124163 124164 124165 124166 124167 124168 124169 124170 124171 124172 124173 124174 124175 124176 124177 124178 124179 124180 124181 | sqlite3_uri_key, sqlite3_filename_database, sqlite3_filename_journal, sqlite3_filename_wal, /* Version 3.32.0 and later */ sqlite3_create_filename, sqlite3_free_filename, sqlite3_database_file_object, }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN # define DirSep(X) ((X)=='/'||(X)=='\\') #else # define DirSep(X) ((X)=='/') #endif /* ** Attempt to load an SQLite extension library contained in the file ** zFile. The entry point is zProc. zProc may be 0 in which case a ** default entry point name (sqlite3_extension_init) is used. Use ** of the default name is recommended. ** |
| ︙ | ︙ | |||
123514 123515 123516 123517 123518 123519 123520 |
int ncFile = sqlite3Strlen30(zFile);
zAltEntry = sqlite3_malloc64(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
return SQLITE_NOMEM_BKPT;
}
memcpy(zAltEntry, "sqlite3_", 8);
| | | 124270 124271 124272 124273 124274 124275 124276 124277 124278 124279 124280 124281 124282 124283 124284 |
int ncFile = sqlite3Strlen30(zFile);
zAltEntry = sqlite3_malloc64(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
return SQLITE_NOMEM_BKPT;
}
memcpy(zAltEntry, "sqlite3_", 8);
for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
iFile++;
if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
if( sqlite3Isalpha(c) ){
zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
}
}
|
| ︙ | ︙ | |||
123818 123819 123820 123821 123822 123823 123824 | ** This file is automatically generated by the script at ** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit ** that script and rerun it. */ /* The various pragma types */ #define PragTyp_ACTIVATE_EXTENSIONS 0 | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 124574 124575 124576 124577 124578 124579 124580 124581 124582 124583 124584 124585 124586 124587 124588 124589 124590 124591 124592 124593 124594 124595 124596 124597 124598 124599 124600 124601 124602 124603 124604 124605 124606 124607 124608 124609 124610 124611 124612 124613 124614 124615 124616 124617 124618 124619 124620 124621 124622 124623 124624 124625 124626 124627 124628 124629 124630 124631 | ** This file is automatically generated by the script at ** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit ** that script and rerun it. */ /* The various pragma types */ #define PragTyp_ACTIVATE_EXTENSIONS 0 #define PragTyp_ANALYSIS_LIMIT 1 #define PragTyp_HEADER_VALUE 2 #define PragTyp_AUTO_VACUUM 3 #define PragTyp_FLAG 4 #define PragTyp_BUSY_TIMEOUT 5 #define PragTyp_CACHE_SIZE 6 #define PragTyp_CACHE_SPILL 7 #define PragTyp_CASE_SENSITIVE_LIKE 8 #define PragTyp_COLLATION_LIST 9 #define PragTyp_COMPILE_OPTIONS 10 #define PragTyp_DATA_STORE_DIRECTORY 11 #define PragTyp_DATABASE_LIST 12 #define PragTyp_DEFAULT_CACHE_SIZE 13 #define PragTyp_ENCODING 14 #define PragTyp_FOREIGN_KEY_CHECK 15 #define PragTyp_FOREIGN_KEY_LIST 16 #define PragTyp_FUNCTION_LIST 17 #define PragTyp_HARD_HEAP_LIMIT 18 #define PragTyp_INCREMENTAL_VACUUM 19 #define PragTyp_INDEX_INFO 20 #define PragTyp_INDEX_LIST 21 #define PragTyp_INTEGRITY_CHECK 22 #define PragTyp_JOURNAL_MODE 23 #define PragTyp_JOURNAL_SIZE_LIMIT 24 #define PragTyp_LOCK_PROXY_FILE 25 #define PragTyp_LOCKING_MODE 26 #define PragTyp_PAGE_COUNT 27 #define PragTyp_MMAP_SIZE 28 #define PragTyp_MODULE_LIST 29 #define PragTyp_OPTIMIZE 30 #define PragTyp_PAGE_SIZE 31 #define PragTyp_PRAGMA_LIST 32 #define PragTyp_SECURE_DELETE 33 #define PragTyp_SHRINK_MEMORY 34 #define PragTyp_SOFT_HEAP_LIMIT 35 #define PragTyp_SYNCHRONOUS 36 #define PragTyp_TABLE_INFO 37 #define PragTyp_TEMP_STORE 38 #define PragTyp_TEMP_STORE_DIRECTORY 39 #define PragTyp_THREADS 40 #define PragTyp_WAL_AUTOCHECKPOINT 41 #define PragTyp_WAL_CHECKPOINT 42 #define PragTyp_LOCK_STATUS 43 #define PragTyp_STATS 44 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ #define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */ #define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */ #define PragFlg_Result0 0x10 /* Acts as query when no argument */ |
| ︙ | ︙ | |||
123951 123952 123953 123954 123955 123956 123957 123958 123959 123960 123961 123962 123963 123964 |
#if defined(SQLITE_ENABLE_CEROD)
{/* zName: */ "activate_extensions",
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "application_id",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ BTREE_APPLICATION_ID },
#endif
| > > > > > | 124708 124709 124710 124711 124712 124713 124714 124715 124716 124717 124718 124719 124720 124721 124722 124723 124724 124725 124726 |
#if defined(SQLITE_ENABLE_CEROD)
{/* zName: */ "activate_extensions",
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
{/* zName: */ "analysis_limit",
/* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "application_id",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ BTREE_APPLICATION_ID },
#endif
|
| ︙ | ︙ | |||
124451 124452 124453 124454 124455 124456 124457 |
{/* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
| | | 125213 125214 125215 125216 125217 125218 125219 125220 125221 125222 125223 125224 125225 125226 125227 |
{/* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 67 on by default, 77 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
/*
** Interpret the given string as a safety level. Return 0 for OFF,
** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or
|
| ︙ | ︙ | |||
124981 124982 124983 124984 124985 124986 124987 |
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
returnSingleInt(v, size);
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
*/
db->nextPagesize = sqlite3Atoi(zRight);
| | | 125743 125744 125745 125746 125747 125748 125749 125750 125751 125752 125753 125754 125755 125756 125757 |
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
returnSingleInt(v, size);
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
*/
db->nextPagesize = sqlite3Atoi(zRight);
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
sqlite3OomFault(db);
}
}
break;
}
/*
|
| ︙ | ︙ | |||
126155 126156 126157 126158 126159 126160 126161 |
}
sqlite3VdbeJumpHere(v, jmp4);
sqlite3ResolvePartIdxLabel(pParse, jmp3);
}
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
| < < | 126917 126918 126919 126920 126921 126922 126923 126924 126925 126926 126927 126928 126929 126930 126931 126932 126933 126934 126935 126936 126937 126938 126939 126940 126941 126942 126943 |
}
sqlite3VdbeJumpHere(v, jmp4);
sqlite3ResolvePartIdxLabel(pParse, jmp3);
}
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
if( !isQuick ){
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeLoadString(v, 4, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
}
}
}
}
{
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNotZero, 1, 4, 0}, /* 1 */
|
| ︙ | ︙ | |||
126603 126604 126605 126606 126607 126608 126609 126610 126611 126612 126613 126614 126615 126616 |
&& N>=0
){
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
}
returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
| > > > > > > > > > > > > > > > > > > > | 127363 127364 127365 127366 127367 127368 127369 127370 127371 127372 127373 127374 127375 127376 127377 127378 127379 127380 127381 127382 127383 127384 127385 127386 127387 127388 127389 127390 127391 127392 127393 127394 127395 |
&& N>=0
){
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
}
returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
/*
** PRAGMA analysis_limit
** PRAGMA analysis_limit = N
**
** Configure the maximum number of rows that ANALYZE will examine
** in each index that it looks at. Return the new limit.
*/
case PragTyp_ANALYSIS_LIMIT: {
sqlite3_int64 N;
if( zRight
&& sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
&& N>=0
){
db->nAnalysisLimit = (int)(N&0x7fffffff);
}
returnSingleInt(v, db->nAnalysisLimit);
break;
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
|
| ︙ | ︙ | |||
131402 131403 131404 131405 131406 131407 131408 131409 131410 131411 131412 131413 131414 131415 |
}else{
sqlite3 *db = pSubst->pParse->db;
if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
memset(&ifNullRow, 0, sizeof(ifNullRow));
ifNullRow.op = TK_IF_NULL_ROW;
ifNullRow.pLeft = pCopy;
ifNullRow.iTable = pSubst->iNewTable;
pCopy = &ifNullRow;
}
testcase( ExprHasProperty(pCopy, EP_Subquery) );
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && pSubst->isLeftJoin ){
ExprSetProperty(pNew, EP_CanBeNull);
}
| > | 132181 132182 132183 132184 132185 132186 132187 132188 132189 132190 132191 132192 132193 132194 132195 |
}else{
sqlite3 *db = pSubst->pParse->db;
if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
memset(&ifNullRow, 0, sizeof(ifNullRow));
ifNullRow.op = TK_IF_NULL_ROW;
ifNullRow.pLeft = pCopy;
ifNullRow.iTable = pSubst->iNewTable;
ifNullRow.flags = EP_Skip;
pCopy = &ifNullRow;
}
testcase( ExprHasProperty(pCopy, EP_Subquery) );
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && pSubst->isLeftJoin ){
ExprSetProperty(pNew, EP_CanBeNull);
}
|
| ︙ | ︙ | |||
134566 134567 134568 134569 134570 134571 134572 |
resetAccumulator(pParse, &sAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
VdbeComment((v, "indicate accumulator empty"));
sqlite3VdbeAddOp1(v, OP_Return, regReset);
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
| < | 135346 135347 135348 135349 135350 135351 135352 135353 135354 135355 135356 135357 135358 135359 |
resetAccumulator(pParse, &sAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
VdbeComment((v, "indicate accumulator empty"));
sqlite3VdbeAddOp1(v, OP_Return, regReset);
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
Table *pTab;
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
/* If isSimpleCount() returns a pointer to a Table structure, then
** the SQL statement is of the form:
**
** SELECT count(*) FROM <tbl>
**
|
| ︙ | ︙ | |||
134602 134603 134604 134605 134606 134607 134608 |
**
** (2013-10-03) Do not count the entries in a partial index.
**
** In practice the KeyInfo structure will not be used. It is only
** passed to keep OP_OpenRead happy.
*/
if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
| > | | | | | | | > | < < | 135381 135382 135383 135384 135385 135386 135387 135388 135389 135390 135391 135392 135393 135394 135395 135396 135397 135398 135399 135400 135401 135402 135403 135404 135405 135406 135407 135408 135409 135410 135411 135412 135413 135414 135415 135416 135417 135418 135419 |
**
** (2013-10-03) Do not count the entries in a partial index.
**
** In practice the KeyInfo structure will not be used. It is only
** passed to keep OP_OpenRead happy.
*/
if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
if( !p->pSrc->a[0].fg.notIndexed ){
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->bUnordered==0
&& pIdx->szIdxRow<pTab->szTabRow
&& pIdx->pPartIdxWhere==0
&& (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
){
pBest = pIdx;
}
}
}
if( pBest ){
iRoot = pBest->tnum;
pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
}
/* Open a read-only cursor, execute the OP_Count, close the cursor. */
sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
if( pKeyInfo ){
sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
}
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
explainSimpleCount(pParse, pTab, pBest);
}else{
int regAcc = 0; /* "populate accumulators" flag */
/* If there are accumulator registers but no min() or max() functions
** without FILTER clauses, allocate register regAcc. Register regAcc
** will contain 0 the first time the inner loop runs, and 1 thereafter.
** The code generated by updateAccumulator() uses this to ensure
** that the accumulator registers are (a) updated only once if
|
| ︙ | ︙ | |||
137850 137851 137852 137853 137854 137855 137856 | /* Restore the original value of db->flags */ db->init.iDb = 0; db->mDbFlags = saved_mDbFlags; db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; db->mTrace = saved_mTrace; | | | 138629 138630 138631 138632 138633 138634 138635 138636 138637 138638 138639 138640 138641 138642 138643 | /* Restore the original value of db->flags */ db->init.iDb = 0; db->mDbFlags = saved_mDbFlags; db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; db->mTrace = saved_mTrace; sqlite3BtreeSetPageSize(pMain, -1, 0, 1); /* Currently there is an SQL level transaction open on the vacuum ** database. No locks are held on any other files (since the main file ** was committed at the btree level). So it safe to end the transaction ** by manually setting the autoCommit flag to true and detaching the ** vacuum database. The vacuum_db journal file is deleted when the pager ** is closed by the DETACH. |
| ︙ | ︙ | |||
159253 159254 159255 159256 159257 159258 159259 159260 159261 159262 159263 159264 159265 159266 | } /* extern "C" */ #endif /* __cplusplus */ /************** End of sqliteicu.h *******************************************/ /************** Continuing where we left off in main.c ***********************/ #endif #ifdef SQLITE_ENABLE_JSON1 SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*); #endif #ifdef SQLITE_ENABLE_STMTVTAB SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); #endif #ifdef SQLITE_ENABLE_FTS5 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | 160032 160033 160034 160035 160036 160037 160038 160039 160040 160041 160042 160043 160044 160045 160046 160047 160048 160049 160050 160051 160052 160053 160054 160055 160056 160057 160058 160059 160060 160061 160062 160063 160064 160065 160066 160067 160068 160069 160070 160071 160072 160073 160074 160075 160076 160077 160078 160079 160080 160081 160082 160083 160084 160085 160086 160087 160088 160089 160090 160091 160092 160093 160094 160095 160096 160097 160098 160099 160100 160101 160102 160103 160104 160105 160106 160107 160108 160109 160110 160111 160112 160113 160114 160115 160116 160117 |
} /* extern "C" */
#endif /* __cplusplus */
/************** End of sqliteicu.h *******************************************/
/************** Continuing where we left off in main.c ***********************/
#endif
/*
** This is an extension initializer that is a no-op and always
** succeeds, except that it fails if the fault-simulation is set
** to 500.
*/
static int sqlite3TestExtInit(sqlite3 *db){
(void)db;
return sqlite3FaultSim(500);
}
/*
** Forward declarations of external module initializer functions
** for modules that need them.
*/
#ifdef SQLITE_ENABLE_FTS1
SQLITE_PRIVATE int sqlite3Fts1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS2
SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS5
SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_JSON1
SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*);
#endif
/*
** An array of pointers to extension initializer functions for
** built-in extensions.
*/
static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
#ifdef SQLITE_ENABLE_FTS1
sqlite3Fts1Init,
#endif
#ifdef SQLITE_ENABLE_FTS2
sqlite3Fts2Init,
#endif
#ifdef SQLITE_ENABLE_FTS3
sqlite3Fts3Init,
#endif
#ifdef SQLITE_ENABLE_FTS5
sqlite3Fts5Init,
#endif
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
sqlite3IcuInit,
#endif
#ifdef SQLITE_ENABLE_RTREE
sqlite3RtreeInit,
#endif
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
sqlite3DbpageRegister,
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
sqlite3DbstatRegister,
#endif
sqlite3TestExtInit,
#ifdef SQLITE_ENABLE_JSON1
sqlite3Json1Init,
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
sqlite3StmtVtabInit,
#endif
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
sqlite3VdbeBytecodeVtabInit,
#endif
};
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
** contains the text of SQLITE_VERSION macro.
*/
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
#endif
|
| ︙ | ︙ | |||
160779 160780 160781 160782 160783 160784 160785 | ** argument. ** ** Return non-zero to retry the lock. Return zero to stop trying ** and cause SQLite to return SQLITE_BUSY. */ static int sqliteDefaultBusyCallback( void *ptr, /* Database connection */ | | < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < | < | 161621 161622 161623 161624 161625 161626 161627 161628 161629 161630 161631 161632 161633 161634 161635 161636 161637 161638 161639 161640 161641 161642 161643 161644 161645 161646 161647 161648 161649 161650 161651 161652 161653 161654 161655 161656 161657 161658 161659 161660 161661 161662 161663 161664 161665 161666 161667 161668 161669 161670 161671 161672 161673 161674 161675 161676 161677 161678 161679 161680 161681 161682 161683 161684 161685 161686 161687 161688 |
** argument.
**
** Return non-zero to retry the lock. Return zero to stop trying
** and cause SQLite to return SQLITE_BUSY.
*/
static int sqliteDefaultBusyCallback(
void *ptr, /* Database connection */
int count /* Number of times table has been busy */
){
#if SQLITE_OS_WIN || HAVE_USLEEP
/* This case is for systems that have support for sleeping for fractions of
** a second. Examples: All windows systems, unix systems with usleep() */
static const u8 delays[] =
{ 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
static const u8 totals[] =
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
# define NDELAY ArraySize(delays)
sqlite3 *db = (sqlite3 *)ptr;
int tmout = db->busyTimeout;
int delay, prior;
assert( count>=0 );
if( count < NDELAY ){
delay = delays[count];
prior = totals[count];
}else{
delay = delays[NDELAY-1];
prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
}
if( prior + delay > tmout ){
delay = tmout - prior;
if( delay<=0 ) return 0;
}
sqlite3OsSleep(db->pVfs, delay*1000);
return 1;
#else
/* This case for unix systems that lack usleep() support. Sleeping
** must be done in increments of whole seconds */
sqlite3 *db = (sqlite3 *)ptr;
int tmout = ((sqlite3 *)ptr)->busyTimeout;
if( (count+1)*1000 > tmout ){
return 0;
}
sqlite3OsSleep(db->pVfs, 1000000);
return 1;
#endif
}
/*
** Invoke the given busy handler.
**
** This routine is called when an operation failed to acquire a
** lock on VFS file pFile.
**
** If this routine returns non-zero, the lock is retried. If it
** returns 0, the operation aborts with an SQLITE_BUSY error.
*/
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
int rc;
if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
if( rc==0 ){
p->nBusy = -1;
}else{
p->nBusy++;
}
return rc;
}
|
| ︙ | ︙ | |||
160893 160894 160895 160896 160897 160898 160899 | #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->busyHandler.xBusyHandler = xBusy; db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; | < | 161699 161700 161701 161702 161703 161704 161705 161706 161707 161708 161709 161710 161711 161712 | #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->busyHandler.xBusyHandler = xBusy; db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; db->busyTimeout = 0; sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* |
| ︙ | ︙ | |||
160944 160945 160946 160947 160948 160949 160950 |
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms>0 ){
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
(void*)db);
db->busyTimeout = ms;
| < | 161749 161750 161751 161752 161753 161754 161755 161756 161757 161758 161759 161760 161761 161762 |
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms>0 ){
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
(void*)db);
db->busyTimeout = ms;
}else{
sqlite3_busy_handler(db, 0, 0);
}
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
162270 162271 162272 162273 162274 162275 162276 162277 162278 162279 162280 162281 162282 162283 |
const char *zVfs /* Name of the VFS to use */
){
sqlite3 *db; /* Store allocated handle here */
int rc; /* Return code */
int isThreadsafe; /* True for threadsafe connections */
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
| > | 163074 163075 163076 163077 163078 163079 163080 163081 163082 163083 163084 163085 163086 163087 163088 |
const char *zVfs /* Name of the VFS to use */
){
sqlite3 *db; /* Store allocated handle here */
int rc; /* Return code */
int isThreadsafe; /* True for threadsafe connections */
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
int i; /* Loop counter */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
*ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
|
| ︙ | ︙ | |||
162418 162419 162420 162421 162422 162423 162424 162425 162426 162427 162428 162429 162430 162431 |
#endif
#if defined(SQLITE_ENABLE_QPSG)
| SQLITE_EnableQPSG
#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
| SQLITE_Defensive
#endif
;
sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3HashInit(&db->aModule);
#endif
/* Add the default collation sequence BINARY. BINARY works for both UTF-8
| > > > | 163223 163224 163225 163226 163227 163228 163229 163230 163231 163232 163233 163234 163235 163236 163237 163238 163239 |
#endif
#if defined(SQLITE_ENABLE_QPSG)
| SQLITE_EnableQPSG
#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
| SQLITE_Defensive
#endif
#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
| SQLITE_LegacyAlter
#endif
;
sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3HashInit(&db->aModule);
#endif
/* Add the default collation sequence BINARY. BINARY works for both UTF-8
|
| ︙ | ︙ | |||
162510 162511 162512 162513 162514 162515 162516 | ** database schema yet. This is delayed until the first time the database ** is accessed. */ sqlite3Error(db, SQLITE_OK); sqlite3RegisterPerConnectionBuiltinFunctions(db); rc = sqlite3_errcode(db); | | < | < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 163318 163319 163320 163321 163322 163323 163324 163325 163326 163327 163328 163329 163330 163331 163332 163333 163334 163335 163336 163337 163338 163339 163340 163341 163342 163343 163344 163345 163346 163347 163348 |
** database schema yet. This is delayed until the first time the database
** is accessed.
*/
sqlite3Error(db, SQLITE_OK);
sqlite3RegisterPerConnectionBuiltinFunctions(db);
rc = sqlite3_errcode(db);
/* Load compiled-in extensions */
for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
rc = sqlite3BuiltinExtensions[i](db);
}
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
if( rc==SQLITE_OK ){
sqlite3AutoLoadExtensions(db);
rc = sqlite3_errcode(db);
if( rc!=SQLITE_OK ){
goto opendb_out;
}
}
#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
/* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
** option gives access to internal functions by default.
** Testing use only!!! */
db->mDbFlags |= DBFLAG_InternalFunc;
#endif
|
| ︙ | ︙ | |||
163074 163075 163076 163077 163078 163079 163080 |
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_DATA_VERSION ){
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
int iNew = *(int*)pArg;
*(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
| | | 163823 163824 163825 163826 163827 163828 163829 163830 163831 163832 163833 163834 163835 163836 163837 |
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_DATA_VERSION ){
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
int iNew = *(int*)pArg;
*(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
if( iNew>=0 && iNew<=255 ){
sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
}
rc = SQLITE_OK;
}else{
rc = sqlite3OsFileControl(fd, op, pArg);
}
sqlite3BtreeLeave(pBtree);
|
| ︙ | ︙ | |||
165355 165356 165357 165358 165359 165360 165361 165362 165363 165364 165365 165366 165367 165368 |
SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
/* fts3_tokenizer.c */
SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
sqlite3_tokenizer **, char **
);
| > | 166104 166105 166106 166107 166108 166109 166110 166111 166112 166113 166114 166115 166116 166117 166118 |
SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut);
/* fts3_tokenizer.c */
SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
sqlite3_tokenizer **, char **
);
|
| ︙ | ︙ | |||
166086 166087 166088 166089 166090 166091 166092 166093 166094 166095 166096 166097 166098 166099 166100 166101 166102 166103 166104 166105 166106 166107 166108 |
}
if( p->zLanguageid ){
fts3Appendf(pRc, &zRet, ", ?");
}
sqlite3_free(zFree);
return zRet;
}
/*
** This function interprets the string at (*pp) as a non-negative integer
** value. It reads the integer and sets *pnOut to the value read, then
** sets *pp to point to the byte immediately following the last byte of
** the integer value.
**
** Only decimal digits ('0'..'9') may be part of an integer value.
**
** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
** the output value undefined. Otherwise SQLITE_OK is returned.
**
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
const int MAX_NPREFIX = 10000000;
| > > > > > > > > > > > > > > > > < | < | | | < | > > < | | 166836 166837 166838 166839 166840 166841 166842 166843 166844 166845 166846 166847 166848 166849 166850 166851 166852 166853 166854 166855 166856 166857 166858 166859 166860 166861 166862 166863 166864 166865 166866 166867 166868 166869 166870 166871 166872 166873 166874 166875 166876 166877 166878 166879 166880 166881 166882 166883 166884 166885 166886 166887 166888 166889 166890 166891 166892 |
}
if( p->zLanguageid ){
fts3Appendf(pRc, &zRet, ", ?");
}
sqlite3_free(zFree);
return zRet;
}
/*
** Buffer z contains a positive integer value encoded as utf-8 text.
** Decode this value and store it in *pnOut, returning the number of bytes
** consumed. If an overflow error occurs return a negative value.
*/
SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut){
u64 iVal = 0;
int i;
for(i=0; z[i]>='0' && z[i]<='9'; i++){
iVal = iVal*10 + (z[i] - '0');
if( iVal>0x7FFFFFFF ) return -1;
}
*pnOut = (int)iVal;
return i;
}
/*
** This function interprets the string at (*pp) as a non-negative integer
** value. It reads the integer and sets *pnOut to the value read, then
** sets *pp to point to the byte immediately following the last byte of
** the integer value.
**
** Only decimal digits ('0'..'9') may be part of an integer value.
**
** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
** the output value undefined. Otherwise SQLITE_OK is returned.
**
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
const int MAX_NPREFIX = 10000000;
int nInt = 0; /* Output value */
int nByte;
nByte = sqlite3Fts3ReadInt(*pp, &nInt);
if( nInt>MAX_NPREFIX ){
nInt = 0;
}
if( nByte==0 ){
return SQLITE_ERROR;
}
*pnOut = nInt;
*pp += nByte;
return SQLITE_OK;
}
/*
** This function is called to allocate an array of Fts3Index structures
** representing the indexes maintained by the current FTS table. FTS tables
** always maintain the main "terms" index, but may also maintain one or
|
| ︙ | ︙ | |||
167296 167297 167298 167299 167300 167301 167302 |
** the next position.
*/
static void fts3ReadNextPos(
char **pp, /* IN/OUT: Pointer into position-list buffer */
sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
){
if( (**pp)&0xFE ){
| > | > | 168060 168061 168062 168063 168064 168065 168066 168067 168068 168069 168070 168071 168072 168073 168074 168075 168076 |
** the next position.
*/
static void fts3ReadNextPos(
char **pp, /* IN/OUT: Pointer into position-list buffer */
sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
){
if( (**pp)&0xFE ){
int iVal;
*pp += fts3GetVarint32((*pp), &iVal);
*pi += iVal;
*pi -= 2;
}else{
*pi = POSITION_LIST_END;
}
}
/*
|
| ︙ | ︙ | |||
172196 172197 172198 172199 172200 172201 172202 |
int nKey = pKey->n;
char cNext;
/* If this is a "NEAR" keyword, check for an explicit nearness. */
if( pKey->eType==FTSQUERY_NEAR ){
assert( nKey==4 );
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
| < < | < | 172962 172963 172964 172965 172966 172967 172968 172969 172970 172971 172972 172973 172974 172975 172976 |
int nKey = pKey->n;
char cNext;
/* If this is a "NEAR" keyword, check for an explicit nearness. */
if( pKey->eType==FTSQUERY_NEAR ){
assert( nKey==4 );
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
}
}
/* At this point this is probably a keyword. But for that to be true,
** the next byte must contain either whitespace, an open or close
** parenthesis, a quote character, or EOF.
*/
|
| ︙ | ︙ | |||
178382 178383 178384 178385 178386 178387 178388 |
i64 *piEndBlock,
i64 *pnByte
){
const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
if( zText ){
int i;
int iMul = 1;
| | | | | 179145 179146 179147 179148 179149 179150 179151 179152 179153 179154 179155 179156 179157 179158 179159 179160 179161 179162 179163 179164 179165 179166 179167 179168 179169 179170 179171 179172 179173 |
i64 *piEndBlock,
i64 *pnByte
){
const unsigned char *zText = sqlite3_column_text(pStmt, iCol);
if( zText ){
int i;
int iMul = 1;
u64 iVal = 0;
for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
iVal = iVal*10 + (zText[i] - '0');
}
*piEndBlock = (i64)iVal;
while( zText[i]==' ' ) i++;
iVal = 0;
if( zText[i]=='-' ){
i++;
iMul = -1;
}
for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
iVal = iVal*10 + (zText[i] - '0');
}
*pnByte = ((i64)iVal * (i64)iMul);
}
}
/*
** A segment of size nByte bytes has just been written to absolute level
** iAbsLevel. Promote any segments that should be promoted as a result.
|
| ︙ | ︙ | |||
223899 223900 223901 223902 223903 223904 223905 |
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);
| | | 224662 224663 224664 224665 224666 224667 224668 224669 224670 224671 224672 224673 224674 224675 224676 |
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-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff", -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){
|
| ︙ | ︙ | |||
228550 228551 228552 228553 228554 228555 228556 |
sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
break;
}
case STMT_COLUMN_BUSY: {
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
}
| > | | 229313 229314 229315 229316 229317 229318 229319 229320 229321 229322 229323 229324 229325 229326 229327 229328 |
sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
break;
}
case STMT_COLUMN_BUSY: {
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
}
default: {
assert( i==STMT_COLUMN_MEM );
i = SQLITE_STMTSTATUS_MEMUSED +
STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
/* Fall thru */
}
case STMT_COLUMN_NSCAN:
case STMT_COLUMN_NSORT:
case STMT_COLUMN_NAIDX:
|
| ︙ | ︙ | |||
228681 228682 228683 228684 228685 228686 228687 | #endif return rc; } #endif /* SQLITE_CORE */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ | | | | 229445 229446 229447 229448 229449 229450 229451 229452 229453 229454 229455 229456 229457 229458 |
#endif
return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
#if __LINE__!=229452
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f96alt2"
#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.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.32.0" #define SQLITE_VERSION_NUMBER 3032000 | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.32.0" #define SQLITE_VERSION_NUMBER 3032000 #define SQLITE_SOURCE_ID "2020-05-08 19:02:21 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff" /* ** 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 |
| ︙ | ︙ | |||
295 296 297 298 299 300 301 302 | ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** ^If the database connection is associated with unfinalized prepared | > > > > | | | | > > | | | | | < < < < < < < < < < | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** Ideally, applications should [sqlite3_finalize | finalize] all ** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and ** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated ** with the [sqlite3] object prior to attempting to close the object. ** ^If the database connection is associated with unfinalized prepared ** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then ** sqlite3_close() will leave the database connection open and return ** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared ** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups, ** it returns [SQLITE_OK] regardless, but instead of deallocating the database ** connection immediately, it marks the database connection as an unusable ** "zombie" and makes arrangements to automatically deallocate the database ** connection after all prepared statements are finalized, all BLOB handles ** are closed, and all backups have finished. The sqlite3_close_v2() interface ** is intended for use with host languages that are garbage collected, and ** where the order in which destructors are called is arbitrary. ** ** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** ** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained |
| ︙ | ︙ | |||
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) #define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) | > > > | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) #define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) #define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) #define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) #define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| ︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 | ** omits changes made by other database connections. The ** [PRAGMA data_version] command provides a mechanism to detect changes to ** a single attached database that occur due to other database connections, ** but omits changes implemented by the database connection on which it is ** called. This file control is the only mechanism to detect changes that ** happen either internally or externally and that are associated with ** a particular attached database. ** ** <li>[[SQLITE_FCNTL_CKPT_DONE]] ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** </ul> | > > > > > | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 | ** omits changes made by other database connections. The ** [PRAGMA data_version] command provides a mechanism to detect changes to ** a single attached database that occur due to other database connections, ** but omits changes implemented by the database connection on which it is ** called. This file control is the only mechanism to detect changes that ** happen either internally or externally and that are associated with ** a particular attached database. ** ** <li>[[SQLITE_FCNTL_CKPT_START]] ** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint ** in wal mode before the client starts to copy pages from the wal ** file to the database file. ** ** <li>[[SQLITE_FCNTL_CKPT_DONE]] ** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint ** in wal mode after the client has finished copying pages from the wal ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** </ul> |
| ︙ | ︙ | |||
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 | #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 #define SQLITE_FCNTL_SIZE_LIMIT 36 #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO | > | 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 | #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 #define SQLITE_FCNTL_SIZE_LIMIT 36 #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
| ︙ | ︙ | |||
3532 3533 3534 3535 3536 3537 3538 | /* ** CAPI3REF: Obtain Values For URI Parameters ** ** These are utility routines, useful to [VFS|custom VFS implementations], ** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** | > > > > | | > > > > > > > | 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 | /* ** CAPI3REF: Obtain Values For URI Parameters ** ** These are utility routines, useful to [VFS|custom VFS implementations], ** that check if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of that query parameter. ** ** The first parameter to these interfaces (hereafter referred to ** as F) must be one of: ** <ul> ** <li> A database filename pointer created by the SQLite core and ** passed into the xOpen() method of a VFS implemention, or ** <li> A filename obtained from [sqlite3_db_filename()], or ** <li> A new filename constructed using [sqlite3_create_filename()]. ** </ul> ** If the F parameter is not one of the above, then the behavior is ** undefined and probably undesirable. Older versions of SQLite were ** more tolerant of invalid F parameters than newer versions. ** ** If F is a suitable filename (as described in the previous paragraph) ** and if P is the name of the query parameter, then ** sqlite3_uri_parameter(F,P) returns the value of the P ** parameter if it exists or a NULL pointer if P does not appear as a ** query parameter on F. If P is a query parameter of F and it ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. ** |
| ︙ | ︙ | |||
3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 | ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ SQLITE_API const char *sqlite3_filename_database(const char*); SQLITE_API const char *sqlite3_filename_journal(const char*); SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of | > > > > > > > > > > > > > > > > > > > | 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 | ** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ SQLITE_API const char *sqlite3_filename_database(const char*); SQLITE_API const char *sqlite3_filename_journal(const char*); SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is ** passed into the xOpen method of [sqlite3_vfs], then ** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file] ** object that represents the main database file. ** ** This routine is intended for use in custom [VFS] implementations ** only. It is not a general-purpose interface. ** The argument sqlite3_file_object(X) must be a filename pointer that ** has been passed into [sqlite3_vfs].xOpen method where the ** flags parameter to xOpen contains one of the bits ** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use ** of this routine results in undefined and probably undesirable ** behavior. */ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** ** These interfces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| ︙ | ︙ | |||
3650 3651 3652 3653 3654 3655 3656 | ** pointer if N is zero. None of the 2*N pointers in the P array may be ** NULL pointers and key pointers should not be empty strings. ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may ** be NULL pointers, though they can be empty strings. ** ** The sqlite3_free_filename(Y) routine releases a memory allocation ** previously obtained from sqlite3_create_filename(). Invoking | | | 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 | ** pointer if N is zero. None of the 2*N pointers in the P array may be ** NULL pointers and key pointers should not be empty strings. ** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may ** be NULL pointers, though they can be empty strings. ** ** The sqlite3_free_filename(Y) routine releases a memory allocation ** previously obtained from sqlite3_create_filename(). Invoking ** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op. ** ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap ** corruption or segfaults may occur. The value Y should be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, |
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
705 706 707 708 709 710 711 |
needCopyBtnJs = 1;
}
/*
** Generate code to load a single javascript file
*/
void style_load_one_js_file(const char *zFile){
| | | 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 |
needCopyBtnJs = 1;
}
/*
** Generate code to load a single javascript file
*/
void style_load_one_js_file(const char *zFile){
@ <script src='%R/builtin/%s(zFile)?id=%S(fossil_exe_id())'></script>
}
/*
** All extra JS files to load.
*/
static const char *azJsToLoad[4];
static int nJsToLoad = 0;
|
| ︙ | ︙ | |||
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 |
@ capabilities = %s(find_capabilities(zCap))<br />
if( zCap[0] ){
@ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
}
@ g.zRepositoryName = %h(g.zRepositoryName)<br />
@ load_average() = %f(load_average())<br />
@ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
@ <hr />
P("HTTP_USER_AGENT");
cgi_print_all(showAll, 0);
if( showAll && blob_size(&g.httpHeader)>0 ){
@ <hr />
@ <pre>
@ %h(blob_str(&g.httpHeader))
| > | 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 |
@ capabilities = %s(find_capabilities(zCap))<br />
if( zCap[0] ){
@ anonymous-adds = %s(find_anon_capabilities(zCap))<br />
}
@ g.zRepositoryName = %h(g.zRepositoryName)<br />
@ load_average() = %f(load_average())<br />
@ cgi_csrf_safe(0) = %d(cgi_csrf_safe(0))<br />
@ fossil_exe_id() = %h(fossil_exe_id())<br />
@ <hr />
P("HTTP_USER_AGENT");
cgi_print_all(showAll, 0);
if( showAll && blob_size(&g.httpHeader)>0 ){
@ <hr />
@ <pre>
@ %h(blob_str(&g.httpHeader))
|
| ︙ | ︙ |
Added src/terminal.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
/*
** Copyright (c) 2020 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to query terminal info
*/
#include "config.h"
#include "terminal.h"
#include <assert.h>
#ifdef _WIN32
# include <windows.h>
#else
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#endif
#if INTERFACE
/*
** Terminal size defined in terms of columns and lines.
*/
struct TerminalSize {
unsigned int nColumns; /* Number of characters on a single line */
unsigned int nLines; /* Number of lines */
};
#endif
/* Get the current terminal size by calling a system service.
**
** Return 1 on success. This sets the size parameters to the values retured by
** the system call, when such is supported; set the size to zero otherwise.
** Return 0 on the system service call failure.
**
** Under Linux/bash the size info is also available from env $LINES, $COLUMNS.
** Or it can be queried using tput `echo -e "lines\ncols"|tput -S`.
** Technically, this info could be cached, but then we'd need to handle
** SIGWINCH signal to requery the terminal on resize event.
*/
int terminal_get_size(TerminalSize *t){
memset(t, 0, sizeof(*t));
#if defined(TIOCGSIZE)
{
struct ttysize ts;
if( ioctl(STDIN_FILENO, TIOCGSIZE, &ts)!=-1 ){
t->nColumns = ts.ts_cols;
t->nLines = ts.ts_lines;
return 1;
}
return 0;
}
#elif defined(TIOCGWINSZ)
{
struct winsize ws;
if( ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)!=-1 ){
t->nColumns = ws.ws_col;
t->nLines = ws.ws_row;
return 1;
}
return 0;
}
#elif defined(_WIN32)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){
t->nColumns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
t->nLines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
return 1;
}
return 0;
}
#else
return 1;
#endif
}
/*
** Return the terminal's current width in columns when available, otherwise
** return the specified default value.
*/
unsigned int terminal_get_width(unsigned int nDefault){
TerminalSize ts;
if( terminal_get_size(&ts) ){
return ts.nColumns;
}
return nDefault;
}
/*
** Return the terminal's current height in lines when available, otherwise
** return the specified default value.
*/
unsigned int terminal_get_height(unsigned int nDefault){
TerminalSize ts;
if( terminal_get_size(&ts) ){
return ts.nLines;
}
return nDefault;
}
/*
** COMMAND: test-terminal-size
**
** Show the size of the terminal window from which the command is launched
** as two integers, the width in charaters and the height in lines.
**
** If the size cannot be determined, two zeros are shown.
*/
void test_terminal_size_cmd(void){
TerminalSize ts;
terminal_get_size(&ts);
fossil_print("%d %d\n", ts.nColumns, ts.nLines);
}
|
Changes to src/timeline.c.
| ︙ | ︙ | |||
1310 1311 1312 1313 1314 1315 1316 |
const char *zChng, /* The filename GLOB list */
Blob *pSql /* The SELECT statement under construction */
){
if( zChng==0 || zChng[0]==0 ) return;
blob_append_sql(pSql," AND event.objid IN ("
"SELECT mlink.mid FROM mlink, filename"
" WHERE mlink.fnid=filename.fnid AND %s)",
| | | 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 |
const char *zChng, /* The filename GLOB list */
Blob *pSql /* The SELECT statement under construction */
){
if( zChng==0 || zChng[0]==0 ) return;
blob_append_sql(pSql," AND event.objid IN ("
"SELECT mlink.mid FROM mlink, filename"
" WHERE mlink.fnid=filename.fnid AND %s)",
glob_expr("filename.name", mprintf("\"%s\"", zChng)));
}
static void addFileGlobDescription(
const char *zChng, /* The filename GLOB list */
Blob *pDescription /* Result description */
){
if( zChng==0 || zChng[0]==0 ) return;
blob_appendf(pDescription, " that include changes to files matching '%h'",
|
| ︙ | ︙ | |||
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 |
login_check_credentials();
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
|| (bisectLocal && !g.perm.Setup)
){
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
return;
}
cookie_read_parameter("y","y");
zType = P("y");
if( zType==0 ){
zType = g.perm.Read ? "ci" : "all";
cgi_set_parameter("y", zType);
}
if( zType[0]=='a' || zType[0]=='c' ){
| > | 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 |
login_check_credentials();
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
|| (bisectLocal && !g.perm.Setup)
){
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
return;
}
etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA, 0);
cookie_read_parameter("y","y");
zType = P("y");
if( zType==0 ){
zType = g.perm.Read ? "ci" : "all";
cgi_set_parameter("y", zType);
}
if( zType[0]=='a' || zType[0]=='c' ){
|
| ︙ | ︙ | |||
2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 |
if( zTagSql ){
db_multi_exec(
"CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO selected_nodes"
" SELECT tagxref.rid FROM tagxref NATURAL JOIN tag"
" WHERE %s AND tagtype>0", zTagSql/*safe-for-%s*/
);
if( !related ){
blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
}else{
db_multi_exec(
"CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
"INSERT INTO related_nodes SELECT rid FROM selected_nodes;"
);
| > > > > > > > | 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 |
if( zTagSql ){
db_multi_exec(
"CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO selected_nodes"
" SELECT tagxref.rid FROM tagxref NATURAL JOIN tag"
" WHERE %s AND tagtype>0", zTagSql/*safe-for-%s*/
);
if( zMark ){
/* If the t=release option is used with m=UUID, then also
** include the UUID check-in in the display list */
int ridMark = name_to_rid(zMark);
db_multi_exec(
"INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark);
}
if( !related ){
blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
}else{
db_multi_exec(
"CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
"INSERT INTO related_nodes SELECT rid FROM selected_nodes;"
);
|
| ︙ | ︙ | |||
2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 |
}else{
if( related ){
blob_appendf(&desc, " related to tags matching %h", zMatchDesc);
}else{
blob_appendf(&desc, " with tags matching %h", zMatchDesc);
}
}
tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
}
addFileGlobDescription(zChng, &desc);
if( rAfter>0.0 ){
if( rBefore>0.0 ){
blob_appendf(&desc, " occurring between %h and %h.<br />",
zAfter, zBefore);
| > > > | 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 |
}else{
if( related ){
blob_appendf(&desc, " related to tags matching %h", zMatchDesc);
}else{
blob_appendf(&desc, " with tags matching %h", zMatchDesc);
}
}
if( zMark ){
blob_appendf(&desc," plus check-in \"%h\"", zMark);
}
tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
}
addFileGlobDescription(zChng, &desc);
if( rAfter>0.0 ){
if( rBefore>0.0 ){
blob_appendf(&desc, " occurring between %h and %h.<br />",
zAfter, zBefore);
|
| ︙ | ︙ |
Changes to src/unversioned.c.
| ︙ | ︙ | |||
522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
int n = 0;
const char *zOrderBy = "name";
int showDel = 0;
char zSzName[100];
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("Unversioned Files");
if( !db_table_exists("repository","unversioned") ){
@ No unversioned files on this server
style_footer();
return;
}
if( PB("byage") ) zOrderBy = "mtime DESC";
| > | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
int n = 0;
const char *zOrderBy = "name";
int showDel = 0;
char zSzName[100];
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
etag_check(ETAG_DATA,0);
style_header("Unversioned Files");
if( !db_table_exists("repository","unversioned") ){
@ No unversioned files on this server
style_footer();
return;
}
if( PB("byage") ) zOrderBy = "mtime DESC";
|
| ︙ | ︙ | |||
634 635 636 637 638 639 640 641 642 643 644 645 646 647 |
Stmt q;
char *zSep = "[";
Blob json;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cgi_set_content_type("text/json");
if( !db_table_exists("repository","unversioned") ){
blob_init(&json, "[]", -1);
cgi_set_content(&json);
return;
}
blob_init(&json, 0, 0);
db_prepare(&q,
| > | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
Stmt q;
char *zSep = "[";
Blob json;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cgi_set_content_type("text/json");
etag_check(ETAG_DATA,0);
if( !db_table_exists("repository","unversioned") ){
blob_init(&json, "[]", -1);
cgi_set_content(&json);
return;
}
blob_init(&json, 0, 0);
db_prepare(&q,
|
| ︙ | ︙ |
Added test/subdir with spaces/filename with spaces.txt.
> > | 1 2 | This file has a name that contains spaces. It is used to help verify that fossil can handle filenames that contain spaces. |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 | 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_GET_TABLE -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_GET_TABLE -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 | | | | | 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 | 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_GET_TABLE -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_GET_TABLE -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 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)\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 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ APPNAME = $(OBJDIR)\fossil$(E) all: $(APPNAME) $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link cd $(OBJDIR) codecheck1$E $(SRC) $(DMDIR)\bin\link @link $(OBJDIR)\fossil.res: $B\win\fossil.rc $(RC) $(RCFLAGS) -o$@ $** $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res +echo add alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file finfo foci forum fshell fusefs fuzz glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ +echo fossil >> $@ +echo fossil >> $@ +echo $(LIBS) >> $@ +echo. >> $@ +echo fossil >> $@ translate$E: $(SRCDIR)\translate.c |
| ︙ | ︙ | |||
828 829 830 831 832 833 834 835 836 837 838 839 840 841 | +translate$E $** > $@ $(OBJDIR)\tar$O : tar_.c tar.h $(TCC) -o$@ -c tar_.c tar_.c : $(SRCDIR)\tar.c +translate$E $** > $@ $(OBJDIR)\th_main$O : th_main_.c th_main.h $(TCC) -o$@ -c th_main_.c th_main_.c : $(SRCDIR)\th_main.c +translate$E $** > $@ | > > > > > > | 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | +translate$E $** > $@ $(OBJDIR)\tar$O : tar_.c tar.h $(TCC) -o$@ -c tar_.c tar_.c : $(SRCDIR)\tar.c +translate$E $** > $@ $(OBJDIR)\terminal$O : terminal_.c terminal.h $(TCC) -o$@ -c terminal_.c terminal_.c : $(SRCDIR)\terminal.c +translate$E $** > $@ $(OBJDIR)\th_main$O : th_main_.c th_main.h $(TCC) -o$@ -c th_main_.c th_main_.c : $(SRCDIR)\th_main.c +translate$E $** > $@ |
| ︙ | ︙ | |||
968 969 970 971 972 973 974 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h | | | 974 975 976 977 978 979 980 981 982 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h @copy /Y nul: headers |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 | $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ $(SRCDIR)/style.c \ $(SRCDIR)/sync.c \ $(SRCDIR)/tag.c \ $(SRCDIR)/tar.c \ $(SRCDIR)/th_main.c \ $(SRCDIR)/timeline.c \ $(SRCDIR)/tkt.c \ $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/unicode.c \ $(SRCDIR)/unversioned.c \ | > | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ $(SRCDIR)/style.c \ $(SRCDIR)/sync.c \ $(SRCDIR)/tag.c \ $(SRCDIR)/tar.c \ $(SRCDIR)/terminal.c \ $(SRCDIR)/th_main.c \ $(SRCDIR)/timeline.c \ $(SRCDIR)/tkt.c \ $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/unicode.c \ $(SRCDIR)/unversioned.c \ |
| ︙ | ︙ | |||
784 785 786 787 788 789 790 791 792 793 794 795 796 797 | $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ $(OBJDIR)/style_.c \ $(OBJDIR)/sync_.c \ $(OBJDIR)/tag_.c \ $(OBJDIR)/tar_.c \ $(OBJDIR)/th_main_.c \ $(OBJDIR)/timeline_.c \ $(OBJDIR)/tkt_.c \ $(OBJDIR)/tktsetup_.c \ $(OBJDIR)/undo_.c \ $(OBJDIR)/unicode_.c \ $(OBJDIR)/unversioned_.c \ | > | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ $(OBJDIR)/style_.c \ $(OBJDIR)/sync_.c \ $(OBJDIR)/tag_.c \ $(OBJDIR)/tar_.c \ $(OBJDIR)/terminal_.c \ $(OBJDIR)/th_main_.c \ $(OBJDIR)/timeline_.c \ $(OBJDIR)/tkt_.c \ $(OBJDIR)/tktsetup_.c \ $(OBJDIR)/undo_.c \ $(OBJDIR)/unicode_.c \ $(OBJDIR)/unversioned_.c \ |
| ︙ | ︙ | |||
926 927 928 929 930 931 932 933 934 935 936 937 938 939 | $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ $(OBJDIR)/style.o \ $(OBJDIR)/sync.o \ $(OBJDIR)/tag.o \ $(OBJDIR)/tar.o \ $(OBJDIR)/th_main.o \ $(OBJDIR)/timeline.o \ $(OBJDIR)/tkt.o \ $(OBJDIR)/tktsetup.o \ $(OBJDIR)/undo.o \ $(OBJDIR)/unicode.o \ $(OBJDIR)/unversioned.o \ | > | 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 | $(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 \ |
| ︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \ $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \ $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \ $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \ $(OBJDIR)/unversioned_.c:$(OBJDIR)/unversioned.h \ | > | 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \ $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \ $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \ $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \ $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \ $(OBJDIR)/unversioned_.c:$(OBJDIR)/unversioned.h \ |
| ︙ | ︙ | |||
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 | $(OBJDIR)/tar_.c: $(SRCDIR)/tar.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/tar.c >$@ $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c $(OBJDIR)/tar.h: $(OBJDIR)/headers $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/th_main.c >$@ $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c | > > > > > > > > | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 | $(OBJDIR)/tar_.c: $(SRCDIR)/tar.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/tar.c >$@ $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c $(OBJDIR)/tar.h: $(OBJDIR)/headers $(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/terminal.c >$@ $(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h: $(OBJDIR)/headers $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/th_main.c >$@ $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c |
| ︙ | ︙ |
Changes to win/Makefile.mingw.mistachkin.
| ︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 | $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ $(SRCDIR)/style.c \ $(SRCDIR)/sync.c \ $(SRCDIR)/tag.c \ $(SRCDIR)/tar.c \ $(SRCDIR)/th_main.c \ $(SRCDIR)/timeline.c \ $(SRCDIR)/tkt.c \ $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/unicode.c \ $(SRCDIR)/unversioned.c \ | > | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | $(SRCDIR)/stash.c \ $(SRCDIR)/stat.c \ $(SRCDIR)/statrep.c \ $(SRCDIR)/style.c \ $(SRCDIR)/sync.c \ $(SRCDIR)/tag.c \ $(SRCDIR)/tar.c \ $(SRCDIR)/terminal.c \ $(SRCDIR)/th_main.c \ $(SRCDIR)/timeline.c \ $(SRCDIR)/tkt.c \ $(SRCDIR)/tktsetup.c \ $(SRCDIR)/undo.c \ $(SRCDIR)/unicode.c \ $(SRCDIR)/unversioned.c \ |
| ︙ | ︙ | |||
784 785 786 787 788 789 790 791 792 793 794 795 796 797 | $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ $(OBJDIR)/style_.c \ $(OBJDIR)/sync_.c \ $(OBJDIR)/tag_.c \ $(OBJDIR)/tar_.c \ $(OBJDIR)/th_main_.c \ $(OBJDIR)/timeline_.c \ $(OBJDIR)/tkt_.c \ $(OBJDIR)/tktsetup_.c \ $(OBJDIR)/undo_.c \ $(OBJDIR)/unicode_.c \ $(OBJDIR)/unversioned_.c \ | > | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | $(OBJDIR)/stash_.c \ $(OBJDIR)/stat_.c \ $(OBJDIR)/statrep_.c \ $(OBJDIR)/style_.c \ $(OBJDIR)/sync_.c \ $(OBJDIR)/tag_.c \ $(OBJDIR)/tar_.c \ $(OBJDIR)/terminal_.c \ $(OBJDIR)/th_main_.c \ $(OBJDIR)/timeline_.c \ $(OBJDIR)/tkt_.c \ $(OBJDIR)/tktsetup_.c \ $(OBJDIR)/undo_.c \ $(OBJDIR)/unicode_.c \ $(OBJDIR)/unversioned_.c \ |
| ︙ | ︙ | |||
926 927 928 929 930 931 932 933 934 935 936 937 938 939 | $(OBJDIR)/stash.o \ $(OBJDIR)/stat.o \ $(OBJDIR)/statrep.o \ $(OBJDIR)/style.o \ $(OBJDIR)/sync.o \ $(OBJDIR)/tag.o \ $(OBJDIR)/tar.o \ $(OBJDIR)/th_main.o \ $(OBJDIR)/timeline.o \ $(OBJDIR)/tkt.o \ $(OBJDIR)/tktsetup.o \ $(OBJDIR)/undo.o \ $(OBJDIR)/unicode.o \ $(OBJDIR)/unversioned.o \ | > | 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 | $(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 \ |
| ︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \ $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \ $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \ $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \ $(OBJDIR)/unversioned_.c:$(OBJDIR)/unversioned.h \ | > | 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ $(OBJDIR)/terminal_.c:$(OBJDIR)/terminal.h \ $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \ $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \ $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \ $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \ $(OBJDIR)/unversioned_.c:$(OBJDIR)/unversioned.h \ |
| ︙ | ︙ | |||
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 | $(OBJDIR)/tar_.c: $(SRCDIR)/tar.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/tar.c >$@ $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c $(OBJDIR)/tar.h: $(OBJDIR)/headers $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/th_main.c >$@ $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c | > > > > > > > > | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 | $(OBJDIR)/tar_.c: $(SRCDIR)/tar.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/tar.c >$@ $(OBJDIR)/tar.o: $(OBJDIR)/tar_.c $(OBJDIR)/tar.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c $(OBJDIR)/tar.h: $(OBJDIR)/headers $(OBJDIR)/terminal_.c: $(SRCDIR)/terminal.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/terminal.c >$@ $(OBJDIR)/terminal.o: $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/terminal.o -c $(OBJDIR)/terminal_.c $(OBJDIR)/terminal.h: $(OBJDIR)/headers $(OBJDIR)/th_main_.c: $(SRCDIR)/th_main.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/th_main.c >$@ $(OBJDIR)/th_main.o: $(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c |
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
stash_.c \
stat_.c \
statrep_.c \
style_.c \
sync_.c \
tag_.c \
tar_.c \
th_main_.c \
timeline_.c \
tkt_.c \
tktsetup_.c \
undo_.c \
unicode_.c \
unversioned_.c \
| > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
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 \
|
| ︙ | ︙ | |||
693 694 695 696 697 698 699 700 701 702 703 704 705 706 |
$(OX)\stash$O \
$(OX)\stat$O \
$(OX)\statrep$O \
$(OX)\style$O \
$(OX)\sync$O \
$(OX)\tag$O \
$(OX)\tar$O \
$(OX)\th$O \
$(OX)\th_lang$O \
$(OX)\th_main$O \
$(OX)\th_tcl$O \
$(OX)\timeline$O \
$(OX)\tkt$O \
$(OX)\tktsetup$O \
| > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
$(OX)\stash$O \
$(OX)\stat$O \
$(OX)\statrep$O \
$(OX)\style$O \
$(OX)\sync$O \
$(OX)\tag$O \
$(OX)\tar$O \
$(OX)\terminal$O \
$(OX)\th$O \
$(OX)\th_lang$O \
$(OX)\th_main$O \
$(OX)\th_tcl$O \
$(OX)\timeline$O \
$(OX)\tkt$O \
$(OX)\tktsetup$O \
|
| ︙ | ︙ | |||
897 898 899 900 901 902 903 904 905 906 907 908 909 910 | echo $(OX)\stash.obj >> $@ echo $(OX)\stat.obj >> $@ echo $(OX)\statrep.obj >> $@ echo $(OX)\style.obj >> $@ echo $(OX)\sync.obj >> $@ echo $(OX)\tag.obj >> $@ echo $(OX)\tar.obj >> $@ echo $(OX)\th.obj >> $@ echo $(OX)\th_lang.obj >> $@ echo $(OX)\th_main.obj >> $@ echo $(OX)\th_tcl.obj >> $@ echo $(OX)\timeline.obj >> $@ echo $(OX)\tkt.obj >> $@ echo $(OX)\tktsetup.obj >> $@ | > | 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 | echo $(OX)\stash.obj >> $@ echo $(OX)\stat.obj >> $@ echo $(OX)\statrep.obj >> $@ echo $(OX)\style.obj >> $@ echo $(OX)\sync.obj >> $@ echo $(OX)\tag.obj >> $@ echo $(OX)\tar.obj >> $@ echo $(OX)\terminal.obj >> $@ echo $(OX)\th.obj >> $@ echo $(OX)\th_lang.obj >> $@ echo $(OX)\th_main.obj >> $@ echo $(OX)\th_tcl.obj >> $@ echo $(OX)\timeline.obj >> $@ echo $(OX)\tkt.obj >> $@ echo $(OX)\tktsetup.obj >> $@ |
| ︙ | ︙ | |||
1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 | translate$E $** > $@ $(OX)\tar$O : tar_.c tar.h $(TCC) /Fo$@ -c tar_.c tar_.c : $(SRCDIR)\tar.c translate$E $** > $@ $(OX)\th_main$O : th_main_.c th_main.h $(TCC) /Fo$@ -c th_main_.c th_main_.c : $(SRCDIR)\th_main.c translate$E $** > $@ | > > > > > > | 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 | translate$E $** > $@ $(OX)\tar$O : tar_.c tar.h $(TCC) /Fo$@ -c tar_.c tar_.c : $(SRCDIR)\tar.c translate$E $** > $@ $(OX)\terminal$O : terminal_.c terminal.h $(TCC) /Fo$@ -c terminal_.c terminal_.c : $(SRCDIR)\terminal.c translate$E $** > $@ $(OX)\th_main$O : th_main_.c th_main.h $(TCC) /Fo$@ -c th_main_.c th_main_.c : $(SRCDIR)\th_main.c translate$E $** > $@ |
| ︙ | ︙ | |||
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 | stash_.c:stash.h \ stat_.c:stat.h \ statrep_.c:statrep.h \ style_.c:style.h \ sync_.c:sync.h \ tag_.c:tag.h \ tar_.c:tar.h \ th_main_.c:th_main.h \ timeline_.c:timeline.h \ tkt_.c:tkt.h \ tktsetup_.c:tktsetup.h \ undo_.c:undo.h \ unicode_.c:unicode.h \ unversioned_.c:unversioned.h \ | > | 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 | stash_.c:stash.h \ stat_.c:stat.h \ statrep_.c:statrep.h \ style_.c:style.h \ sync_.c:sync.h \ tag_.c:tag.h \ tar_.c:tar.h \ terminal_.c:terminal.h \ th_main_.c:th_main.h \ timeline_.c:timeline.h \ tkt_.c:tkt.h \ tktsetup_.c:tktsetup.h \ undo_.c:undo.h \ unicode_.c:unicode.h \ unversioned_.c:unversioned.h \ |
| ︙ | ︙ |
Changes to www/changes.wiki.
| ︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
database it opens has been tampered with by an adversary and takes
extra precautions to ensure that such tampering is harmless.
* Security: Fossil now puts the Content-Security-Policy in the
HTTP reply header, in addition to also leaving it in the
HTML <head> section, so that it is always available, even
if a custom skin overrides the HTML <head> and omits
the CSP in the process.
* The Content-Security-Policy is now set using the
[/help?cmd=default-csp|default-csp setting].
* Merge conflicts caused via the [/help?cmd=merge|merge] and
[/help?cmd=update|update] commands no longer leave temporary
files behind unless the new <tt>--keep-merge-files</tt> flag
is used.
* The [/help?cmd=/artifact_stats|/artifact_stats page] is now accessible
| > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
database it opens has been tampered with by an adversary and takes
extra precautions to ensure that such tampering is harmless.
* Security: Fossil now puts the Content-Security-Policy in the
HTTP reply header, in addition to also leaving it in the
HTML <head> section, so that it is always available, even
if a custom skin overrides the HTML <head> and omits
the CSP in the process.
* Output of the [/help?cmd=diff|fossil diff -y] command automatically
adjusts according to the terminal width.
* The Content-Security-Policy is now set using the
[/help?cmd=default-csp|default-csp setting].
* Merge conflicts caused via the [/help?cmd=merge|merge] and
[/help?cmd=update|update] commands no longer leave temporary
files behind unless the new <tt>--keep-merge-files</tt> flag
is used.
* The [/help?cmd=/artifact_stats|/artifact_stats page] is now accessible
|
| ︙ | ︙ |