Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merged main trunk into private branch. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | newbuild | ttmrichter |
Files: | files | file ages | folders |
SHA1: |
1c28a41cf1957b126173e7a79bcd2889 |
User & Date: | michael 2010-07-09 16:25:09 |
Context
2010-07-09
| ||
16:57 | Named the mingw32 fragment properly. Forced mingw32 to use GCC. ... (check-in: cd98f05dbe user: michael tags: newbuild, ttmrichter) | |
16:25 | Merged main trunk into private branch. ... (check-in: 1c28a41cf1 user: michael tags: newbuild, ttmrichter) | |
16:23 | Started the process of modifying the build system to permit more flexible and reliable cross-platform support. Currently the build system is set up for Linux (GCC or CLANG as the compiler) and for MinGW32 (GCC as the compiler). Of these, only the Linux builds have been tested so far and confirmed to work as expected. The way to use this new system is as follows: make Builds the default platform and compiler (linux and gcc). PLATFORM=mingw32 make Builds the mingw32 build (untested!) using the default compiler (gcc). COMPILER=clang make Builds the default platform (linux) using the clang compiler. Other platform and compiler fragment files can be added in the ./make directory based on the models already there. ... (check-in: d3252d7488 user: michael tags: newbuild, ttmrichter) | |
2010-07-08
| ||
17:57 | Update the built-in sqlite3 to the latest development version. ... (check-in: 1e6ded9856 user: drh tags: trunk) | |
Changes
Changes to src/blob.c.
︙ | ︙ | |||
97 98 99 100 101 102 103 | /* ** This routine is called if a blob operation fails because we ** have run out of memory. */ static void blob_panic(void){ static const char zErrMsg[] = "out of memory\n"; write(2, zErrMsg, sizeof(zErrMsg)-1); | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | /* ** This routine is called if a blob operation fails because we ** have run out of memory. */ static void blob_panic(void){ static const char zErrMsg[] = "out of memory\n"; write(2, zErrMsg, sizeof(zErrMsg)-1); fossil_exit(1); } /* ** A reallocation function that assumes that aData came from malloc(). ** This function attempts to resize the buffer of the blob to hold ** newSize bytes. ** |
︙ | ︙ |
Changes to src/branch.c.
︙ | ︙ | |||
127 128 129 130 131 132 133 | blob_appendf(&branch, "Z %b\n", &mcksum); if( !noSign && clearsign(&branch, &branch) ){ Blob ans; blob_zero(&ans); prompt_user("unable to sign manifest. continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ db_end_transaction(1); | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | blob_appendf(&branch, "Z %b\n", &mcksum); if( !noSign && clearsign(&branch, &branch) ){ Blob ans; blob_zero(&ans); prompt_user("unable to sign manifest. continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ db_end_transaction(1); fossil_exit(1); } } brid = content_put(&branch, 0, 0); if( brid==0 ){ fossil_panic("trouble committing manifest: %s", g.zErrMsg); } |
︙ | ︙ |
Changes to src/cgi.c.
︙ | ︙ | |||
347 348 349 350 351 352 353 | } cgi_append_header(zLocation); cgi_reset_content(); cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zURL); cgi_set_status(302, "Moved Temporarily"); free(zLocation); cgi_reply(); | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | } cgi_append_header(zLocation); cgi_reset_content(); cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zURL); cgi_set_status(302, "Moved Temporarily"); free(zLocation); cgi_reply(); fossil_exit(0); } void cgi_redirectf(const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); cgi_redirect(vmprintf(zFormat, ap)); va_end(ap); } |
︙ | ︙ | |||
382 383 384 385 386 387 388 | ** zName and zValue are not copied and must not change or be ** deallocated after this routine returns. */ void cgi_set_parameter_nocopy(const char *zName, const char *zValue){ if( nAllocQP<=nUsedQP ){ nAllocQP = nAllocQP*2 + 10; aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) ); | | | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | ** zName and zValue are not copied and must not change or be ** deallocated after this routine returns. */ void cgi_set_parameter_nocopy(const char *zName, const char *zValue){ if( nAllocQP<=nUsedQP ){ nAllocQP = nAllocQP*2 + 10; aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) ); if( aParamQP==0 ) fossil_exit(1); } aParamQP[nUsedQP].zName = zName; aParamQP[nUsedQP].zValue = zValue; if( g.fHttpTrace ){ fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue); } aParamQP[nUsedQP].seq = seqQP++; |
︙ | ︙ | |||
676 677 678 679 680 681 682 | len = atoi(PD("CONTENT_LENGTH", "0")); g.zContentType = zType = P("CONTENT_TYPE"); if( len>0 && zType ){ blob_zero(&g.cgiIn); if( strcmp(zType,"application/x-www-form-urlencoded")==0 || strncmp(zType,"multipart/form-data",19)==0 ){ z = malloc( len+1 ); | | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | len = atoi(PD("CONTENT_LENGTH", "0")); g.zContentType = zType = P("CONTENT_TYPE"); if( len>0 && zType ){ blob_zero(&g.cgiIn); if( strcmp(zType,"application/x-www-form-urlencoded")==0 || strncmp(zType,"multipart/form-data",19)==0 ){ z = malloc( len+1 ); if( z==0 ) fossil_exit(1); len = fread(z, 1, len, g.httpIn); z[len] = 0; if( zType[0]=='a' ){ add_param_list(z, '&'); }else{ process_multipart_form_data(z, len); } |
︙ | ︙ | |||
1013 1014 1015 1016 1017 1018 1019 | */ static void malformed_request(void){ cgi_set_status(501, "Not Implemented"); cgi_printf( "<html><body>Unrecognized HTTP Request</body></html>\n" ); cgi_reply(); | | | | 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | */ static void malformed_request(void){ cgi_set_status(501, "Not Implemented"); cgi_printf( "<html><body>Unrecognized HTTP Request</body></html>\n" ); cgi_reply(); fossil_exit(0); } /* ** Panic and die while processing a webpage. */ void cgi_panic(const char *zFormat, ...){ va_list ap; cgi_reset_content(); cgi_set_status(500, "Internal Server Error"); cgi_printf( "<html><body><h1>Internal Server Error</h1>\n" "<plaintext>" ); va_start(ap, zFormat); vxprintf(pContent,zFormat,ap); va_end(ap); cgi_reply(); fossil_exit(1); } /* ** Remove the first space-delimited token from a string and return ** a pointer to it. Add a NULL to the string to terminate the token. ** Make *zLeftOver point to the start of the next token. */ |
︙ | ︙ | |||
1161 1162 1163 1164 1165 1166 1167 | ** ** Return 0 to each child as it runs. If unable to establish a ** listening socket, return non-zero. */ int cgi_http_server(int mnPort, int mxPort, char *zBrowser){ #ifdef __MINGW32__ /* Use win32_http_server() instead */ | | | 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | ** ** Return 0 to each child as it runs. If unable to establish a ** listening socket, return non-zero. */ int cgi_http_server(int mnPort, int mxPort, char *zBrowser){ #ifdef __MINGW32__ /* Use win32_http_server() instead */ fossil_exit(1); #else int listener = -1; /* The server socket */ int connection; /* A socket for each individual connection */ fd_set readfds; /* Set of file descriptors for select() */ size_t lenaddr; /* Length of the inaddr structure */ int child; /* PID of the child process */ int nchildren = 0; /* Number of child processes */ |
︙ | ︙ | |||
1251 1252 1253 1254 1255 1256 1257 | } /* Bury dead children */ while( waitpid(0, 0, WNOHANG)>0 ){ nchildren--; } } /* NOT REACHED */ | | | 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 | } /* Bury dead children */ while( waitpid(0, 0, WNOHANG)>0 ){ nchildren--; } } /* NOT REACHED */ fossil_exit(1); #endif } /* ** Name of days and months. */ |
︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 | void cgi_modified_since(time_t objectTime){ const char *zIf = P("HTTP_IF_MODIFIED_SINCE"); if( zIf==0 ) return; if( objectTime > cgi_rfc822_parsedate(zIf) ) return; cgi_set_status(304,"Not Modified"); cgi_reset_content(); cgi_reply(); | | | 1354 1355 1356 1357 1358 1359 1360 1361 1362 | void cgi_modified_since(time_t objectTime){ const char *zIf = P("HTTP_IF_MODIFIED_SINCE"); if( zIf==0 ) return; if( objectTime > cgi_rfc822_parsedate(zIf) ) return; cgi_set_status(304,"Not Modified"); cgi_reset_content(); cgi_reply(); fossil_exit(0); } |
Changes to src/checkin.c.
︙ | ︙ | |||
689 690 691 692 693 694 695 | free(zInit); } if( blob_size(&comment)==0 ){ Blob ans; blob_zero(&ans); prompt_user("empty check-in comment. continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ | < | | 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | free(zInit); } if( blob_size(&comment)==0 ){ Blob ans; blob_zero(&ans); prompt_user("empty check-in comment. continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ fossil_exit(1); } }else{ db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment); db_end_transaction(0); db_begin_transaction(); } |
︙ | ︙ | |||
827 828 829 830 831 832 833 | blob_appendf(&manifest, "Z %b\n", &mcksum); zManifestFile = mprintf("%smanifest", g.zLocalRoot); if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){ Blob ans; blob_zero(&ans); prompt_user("unable to sign manifest. continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ | < | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 | blob_appendf(&manifest, "Z %b\n", &mcksum); zManifestFile = mprintf("%smanifest", g.zLocalRoot); if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){ Blob ans; blob_zero(&ans); prompt_user("unable to sign manifest. continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ fossil_exit(1); } } blob_write_to_file(&manifest, zManifestFile); blob_reset(&manifest); blob_read_from_file(&manifest, zManifestFile); free(zManifestFile); nvid = content_put(&manifest, 0, 0); |
︙ | ︙ |
Changes to src/db.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 | cgi_printf("<h1>Database Error</h1>\n" "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n\n%s", g.argv[0], z, zRebuildMsg); } db_force_rollback(); | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | cgi_printf("<h1>Database Error</h1>\n" "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n\n%s", g.argv[0], z, zRebuildMsg); } db_force_rollback(); fossil_exit(1); } static int nBegin = 0; /* Nesting depth of BEGIN */ static int isNewRepo = 0; /* True if the repository is newly created */ static int doRollback = 0; /* True to force a rollback */ static int nCommitHook = 0; /* Number of commit hooks */ static struct sCommitHook { |
︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | if( nBegin==0 ){ db_multi_exec("BEGIN"); sqlite3_commit_hook(g.db, db_verify_at_commit, 0); } nBegin++; } void db_end_transaction(int rollbackFlag){ if( nBegin<=0 ) return; if( rollbackFlag ) doRollback = 1; nBegin--; if( nBegin==0 ){ int i; for(i=0; doRollback==0 && i<nCommitHook; i++){ doRollback |= aHook[i].xHook(); } db_multi_exec(doRollback ? "ROLLBACK" : "COMMIT"); doRollback = 0; } } void db_force_rollback(void){ static int busy = 0; | > | | 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 | if( nBegin==0 ){ db_multi_exec("BEGIN"); sqlite3_commit_hook(g.db, db_verify_at_commit, 0); } nBegin++; } void db_end_transaction(int rollbackFlag){ if( g.db==0 ) return; if( nBegin<=0 ) return; if( rollbackFlag ) doRollback = 1; nBegin--; if( nBegin==0 ){ int i; for(i=0; doRollback==0 && i<nCommitHook; i++){ doRollback |= aHook[i].xHook(); } db_multi_exec(doRollback ? "ROLLBACK" : "COMMIT"); doRollback = 0; } } void db_force_rollback(void){ static int busy = 0; if( busy || g.db==0 ) return; busy = 1; undo_rollback(); if( nBegin ){ sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); if( isNewRepo ){ db_close(); unlink(g.zRepositoryName); |
︙ | ︙ | |||
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, zVfs ); if( rc!=SQLITE_OK ){ db_err(sqlite3_errmsg(db)); } sqlite3_busy_timeout(db, 5000); return db; } /* ** zDbName is the name of a database file. If no other database ** file is open, then open this one. If another database file is ** already open, then attach zDbName using the name zLabel. */ void db_open_or_attach(const char *zDbName, const char *zLabel){ if( !g.db ){ g.db = openDatabase(zDbName); db_connection_init(); }else{ #ifdef __MINGW32__ zDbName = sqlite3_win32_mbcs_to_utf8(zDbName); #endif db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); } } /* ** Open the user database in "~/.fossil". Create the database anew if ** it does not already exist. ** | > > > | 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, zVfs ); if( rc!=SQLITE_OK ){ db_err(sqlite3_errmsg(db)); } sqlite3_busy_timeout(db, 5000); sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ return db; } /* ** zDbName is the name of a database file. If no other database ** file is open, then open this one. If another database file is ** already open, then attach zDbName using the name zLabel. */ void db_open_or_attach(const char *zDbName, const char *zLabel){ if( !g.db ){ g.db = openDatabase(zDbName); g.zRepoDb = "main"; db_connection_init(); }else{ #ifdef __MINGW32__ zDbName = sqlite3_win32_mbcs_to_utf8(zDbName); #endif db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); g.zRepoDb = mprintf("%s", zLabel); } } /* ** Open the user database in "~/.fossil". Create the database anew if ** it does not already exist. ** |
︙ | ︙ | |||
892 893 894 895 896 897 898 899 900 901 902 903 904 905 | ** Close the database connection. */ void db_close(void){ if( g.db==0 ) return; while( pAllStmt ){ db_finalize(pAllStmt); } g.repositoryOpen = 0; g.localOpen = 0; g.configOpen = 0; sqlite3_close(g.db); g.db = 0; } | > | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | ** Close the database connection. */ void db_close(void){ if( g.db==0 ) return; while( pAllStmt ){ db_finalize(pAllStmt); } db_end_transaction(1); g.repositoryOpen = 0; g.localOpen = 0; g.configOpen = 0; sqlite3_close(g.db); g.db = 0; } |
︙ | ︙ |
Changes to src/deltacmd.c.
︙ | ︙ | |||
48 49 50 51 52 53 54 | ** Given two input files, create and output a delta that carries ** the first file into the second. */ void delta_create_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ fprintf(stderr,"Usage: %s %s ORIGIN TARGET DELTA\n", g.argv[0], g.argv[1]); | | | | | | 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 | ** Given two input files, create and output a delta that carries ** the first file into the second. */ void delta_create_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ fprintf(stderr,"Usage: %s %s ORIGIN TARGET DELTA\n", g.argv[0], g.argv[1]); fossil_exit(1); } if( blob_read_from_file(&orig, g.argv[2])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[2]); fossil_exit(1); } if( blob_read_from_file(&target, g.argv[3])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[3]); fossil_exit(1); } blob_delta_create(&orig, &target, &delta); if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){ fprintf(stderr,"cannot write %s\n", g.argv[4]); fossil_exit(1); } blob_reset(&orig); blob_reset(&target); blob_reset(&delta); } /* |
︙ | ︙ | |||
111 112 113 114 115 116 117 | ** Given an input files and a delta, apply the delta to the input file ** and write the result. */ void delta_apply_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ fprintf(stderr,"Usage: %s %s ORIGIN DELTA TARGET\n", g.argv[0], g.argv[1]); | | | | | | 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 | ** Given an input files and a delta, apply the delta to the input file ** and write the result. */ void delta_apply_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ fprintf(stderr,"Usage: %s %s ORIGIN DELTA TARGET\n", g.argv[0], g.argv[1]); fossil_exit(1); } if( blob_read_from_file(&orig, g.argv[2])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[2]); fossil_exit(1); } if( blob_read_from_file(&delta, g.argv[3])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[3]); fossil_exit(1); } blob_delta_apply(&orig, &delta, &target); if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){ fprintf(stderr,"cannot write %s\n", g.argv[4]); fossil_exit(1); } blob_reset(&orig); blob_reset(&target); blob_reset(&delta); } /* |
︙ | ︙ |
Changes to src/file.c.
︙ | ︙ | |||
276 277 278 279 280 281 282 | ){ blob_set(pOut, zOrigName); blob_materialize(pOut); }else{ char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | ){ blob_set(pOut, zOrigName); blob_materialize(pOut); }else{ char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); fossil_exit(1); } blob_zero(pOut); blob_appendf(pOut, "%//%/", zPwd, zOrigName); } blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); } |
︙ | ︙ | |||
341 342 343 344 345 346 347 | zPath = blob_buffer(pOut); if( zPath[0]=='/' ){ int i, j; Blob tmp; char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); | | | 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | zPath = blob_buffer(pOut); if( zPath[0]=='/' ){ int i, j; Blob tmp; char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){ fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20); fossil_exit(1); } for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){} if( zPath[i]==0 ){ blob_reset(pOut); if( zPwd[i]==0 ){ blob_append(pOut, ".", 1); }else{ |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 | sqlite3 *db; /* The connection to the databases */ sqlite3 *dbConfig; /* Separate connection for global_config table */ int useAttach; /* True if global_config is attached to repository */ int configOpen; /* True if the config database is open */ long long int now; /* Seconds since 1970 */ int repositoryOpen; /* True if the main repository database is open */ char *zRepositoryName; /* Name of the repository database */ const char *zHome; /* Name of user home directory */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if -sqltrace flag is present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ | > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | sqlite3 *db; /* The connection to the databases */ sqlite3 *dbConfig; /* Separate connection for global_config table */ int useAttach; /* True if global_config is attached to repository */ int configOpen; /* True if the config database is open */ long long int now; /* Seconds since 1970 */ int repositoryOpen; /* True if the main repository database is open */ char *zRepositoryName; /* Name of the repository database */ char *zRepoDb; /* SQLite database name for the repository */ const char *zHome; /* Name of user home directory */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if -sqltrace flag is present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ |
︙ | ︙ | |||
214 215 216 217 218 219 220 | } /* ** This procedure runs first. */ int main(int argc, char **argv){ | | | | | > > > > > > > > > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | } /* ** This procedure runs first. */ int main(int argc, char **argv){ const char *zCmdName = "unknown"; int idx; int rc; sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); g.now = time(0); g.argc = argc; g.argv = argv; if( getenv("GATEWAY_INTERFACE")!=0 ){ zCmdName = "cgi"; }else if( argc<2 ){ fprintf(stderr, "Usage: %s COMMAND ...\n", argv[0]); fossil_exit(1); }else{ g.fQuiet = find_option("quiet", 0, 0)!=0; g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; g.fHttpTrace = find_option("httptrace", 0, 0)!=0; g.zLogin = find_option("user", "U", 1); zCmdName = argv[1]; } rc = name_search(zCmdName, aCommand, count(aCommand), &idx); if( rc==1 ){ fprintf(stderr,"%s: unknown command: %s\n" "%s: use \"help\" for more information\n", argv[0], zCmdName, argv[0]); fossil_exit(1); }else if( rc==2 ){ fprintf(stderr,"%s: ambiguous command prefix: %s\n" "%s: use \"help\" for more information\n", argv[0], zCmdName, argv[0]); fossil_exit(1); } aCommand[idx].xFunc(); fossil_exit(0); /*NOT_REACHED*/ return 0; } /* ** The following variable becomes true while processing a fatal error ** or a panic. If additional "recursive-fatal" errors occur while ** shutting down, the recursive errors are silently ignored. */ static int mainInFatalError = 0; /* ** Exit. Take care to close the database first. */ void fossil_exit(int rc){ db_close(); exit(rc); } /* ** Print an error message, rollback all databases, and quit. These ** routines never return. */ void fossil_panic(const char *zFormat, ...){ char *z; |
︙ | ︙ | |||
278 279 280 281 282 283 284 | once = 0; cgi_printf("<p><font color=\"red\">%h</font></p>", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); | | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | once = 0; cgi_printf("<p><font color=\"red\">%h</font></p>", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); fossil_exit(1); } void fossil_fatal(const char *zFormat, ...){ char *z; va_list ap; mainInFatalError = 1; va_start(ap, zFormat); z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput ){ g.cgiOutput = 0; cgi_printf("<p><font color=\"red\">%h</font></p>", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); fossil_exit(1); } /* This routine works like fossil_fatal() except that if called ** recursively, the recursive call is a no-op. ** ** Use this in places where an error might occur while doing ** fatal error shutdown processing. Unlike fossil_panic() and |
︙ | ︙ | |||
323 324 325 326 327 328 329 | g.cgiOutput = 0; cgi_printf("<p><font color=\"red\">%h</font></p>", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | g.cgiOutput = 0; cgi_printf("<p><font color=\"red\">%h</font></p>", z); cgi_reply(); }else{ fprintf(stderr, "%s: %s\n", g.argv[0], z); } db_force_rollback(); fossil_exit(1); } /* Print a warning message */ void fossil_warning(const char *zFormat, ...){ char *z; va_list ap; |
︙ | ︙ | |||
386 387 388 389 390 391 392 | } /* ** Print a usage comment and quit */ void usage(const char *zFormat){ fprintf(stderr, "Usage: %s %s %s\n", g.argv[0], g.argv[1], zFormat); | | | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | } /* ** Print a usage comment and quit */ void usage(const char *zFormat){ fprintf(stderr, "Usage: %s %s %s\n", g.argv[0], g.argv[1], zFormat); fossil_exit(1); } /* ** Remove n elements from g.argv beginning with the i-th element. */ void remove_from_argv(int i, int n){ int j; |
︙ | ︙ |
Changes to src/merge3.c.
︙ | ︙ | |||
301 302 303 304 305 306 307 | ** Combine change in going from PIVOT->VERSION1 with the change going ** from PIVOT->VERSION2 and write the combined changes into MERGED. */ void delta_3waymerge_cmd(void){ Blob pivot, v1, v2, merged; if( g.argc!=6 ){ fprintf(stderr,"Usage: %s %s PIVOT V1 V2 MERGED\n", g.argv[0], g.argv[1]); | | | | | | | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | ** Combine change in going from PIVOT->VERSION1 with the change going ** from PIVOT->VERSION2 and write the combined changes into MERGED. */ void delta_3waymerge_cmd(void){ Blob pivot, v1, v2, merged; if( g.argc!=6 ){ fprintf(stderr,"Usage: %s %s PIVOT V1 V2 MERGED\n", g.argv[0], g.argv[1]); fossil_exit(1); } if( blob_read_from_file(&pivot, g.argv[2])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[2]); fossil_exit(1); } if( blob_read_from_file(&v1, g.argv[3])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[3]); fossil_exit(1); } if( blob_read_from_file(&v2, g.argv[4])<0 ){ fprintf(stderr,"cannot read %s\n", g.argv[4]); fossil_exit(1); } blob_merge(&pivot, &v1, &v2, &merged); if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){ fprintf(stderr,"cannot write %s\n", g.argv[4]); fossil_exit(1); } blob_reset(&pivot); blob_reset(&v1); blob_reset(&v2); blob_reset(&merged); } |
Changes to src/name.c.
︙ | ︙ | |||
363 364 365 366 367 368 369 | return 0; }else{ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); blob_reset(&name); } return rid; } | < | 363 364 365 366 367 368 369 | return 0; }else{ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); blob_reset(&name); } return rid; } |
Changes to src/rebuild.c.
︙ | ︙ | |||
372 373 374 375 376 377 378 | if( !bForce ){ Blob ans; blob_zero(&ans); prompt_user("Scrubbing the repository will permanently remove user\n" "passwords and other information. Changes cannot be undone.\n" "Continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ | | | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | if( !bForce ){ Blob ans; blob_zero(&ans); prompt_user("Scrubbing the repository will permanently remove user\n" "passwords and other information. Changes cannot be undone.\n" "Continue (y/N)? ", &ans); if( blob_str(&ans)[0]!='y' ){ fossil_exit(1); } } db_begin_transaction(); db_multi_exec( "UPDATE user SET pw='';" "DELETE FROM config WHERE name GLOB 'last-sync-*';" ); |
︙ | ︙ |
Changes to src/sqlite3.c.
︙ | ︙ | |||
507 508 509 510 511 512 513 514 515 516 517 518 519 520 | # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds ** a boolean expression that is usually true. GCC is able to ** use these hints to generate better code, sometimes. */ #if defined(__GNUC__) && 0 | > > > > > > > | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif /* ** Return true (non-zero) if the input is a integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() ** macros to verify that we have tested SQLite for large-file support. */ #define IS_BIG_INT(X) (((X)&(i64)0xffffffff)!=0) /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds ** a boolean expression that is usually true. GCC is able to ** use these hints to generate better code, sometimes. */ #if defined(__GNUC__) && 0 |
︙ | ︙ | |||
634 635 636 637 638 639 640 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.0" #define SQLITE_VERSION_NUMBER 3007000 | | | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.0" #define SQLITE_VERSION_NUMBER 3007000 #define SQLITE_SOURCE_ID "2010-07-08 17:40:38 e396184cd3bdb96e29ac33af5d1f631cac553341" /* ** 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 |
︙ | ︙ | |||
1357 1358 1359 1360 1361 1362 1363 | ** SQLite will always allocate at least mxPathname+1 bytes for the ** output buffer xFullPathname. The exact size of the output buffer ** is also passed as a parameter to both methods. If the output buffer ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is ** handled as a fatal error by SQLite, vfs implementations should endeavor ** to prevent this by setting mxPathname to a sufficiently large value. ** | | | | > > > | > > > > | 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 | ** SQLite will always allocate at least mxPathname+1 bytes for the ** output buffer xFullPathname. The exact size of the output buffer ** is also passed as a parameter to both methods. If the output buffer ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is ** handled as a fatal error by SQLite, vfs implementations should endeavor ** to prevent this by setting mxPathname to a sufficiently large value. ** ** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() ** interfaces are not strictly a part of the filesystem, but they are ** included in the VFS structure for completeness. ** The xRandomness() function attempts to return nBytes bytes ** of good-quality randomness into zOut. The return value is ** the actual number of bytes of randomness obtained. ** The xSleep() method causes the calling thread to sleep for at ** least the number of microseconds given. The xCurrentTime() ** method returns a Julian Day Number for the current date and time as ** a floating point value. ** The xCurrentTimeInt64() method returns, as an integer, the Julian ** Day Number multipled by 86400000 (the number of milliseconds in ** a 24-hour day). ** ^SQLite will use the xCurrentTimeInt64() method to get the current ** date and time if that method is available (if iVersion is 2 or ** greater and the function pointer is not NULL) and will fall back ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. */ typedef struct sqlite3_vfs sqlite3_vfs; struct sqlite3_vfs { int iVersion; /* Structure version number (currently 2) */ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ |
︙ | ︙ | |||
1393 1394 1395 1396 1397 1398 1399 | int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); int (*xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ | < | 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 | int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); int (*xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** New fields may be appended in figure versions. The iVersion ** value will increment whenever this happens. */ }; |
︙ | ︙ | |||
8557 8558 8559 8560 8561 8562 8563 | int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ | < | 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 | int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ int nextPagesize; /* Pagesize after VACUUM if >0 */ int nTable; /* Number of tables in the database */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ i64 lastRowid; /* ROWID of most recent insert (see above) */ u32 magic; /* Magic number for detect library misuse */ |
︙ | ︙ | |||
11325 11326 11327 11328 11329 11330 11331 | #endif #ifdef SQLITE_OMIT_CAST "OMIT_CAST", #endif #ifdef SQLITE_OMIT_CHECK "OMIT_CHECK", #endif | > | | | > | 11337 11338 11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353 11354 11355 | #endif #ifdef SQLITE_OMIT_CAST "OMIT_CAST", #endif #ifdef SQLITE_OMIT_CHECK "OMIT_CHECK", #endif /* // redundant ** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS ** "OMIT_COMPILEOPTION_DIAGS", ** #endif */ #ifdef SQLITE_OMIT_COMPLETE "OMIT_COMPLETE", #endif #ifdef SQLITE_OMIT_COMPOUND_SELECT "OMIT_COMPOUND_SELECT", #endif #ifdef SQLITE_OMIT_DATETIME_FUNCS |
︙ | ︙ | |||
11361 11362 11363 11364 11365 11366 11367 | #endif #ifdef SQLITE_OMIT_FOREIGN_KEY "OMIT_FOREIGN_KEY", #endif #ifdef SQLITE_OMIT_GET_TABLE "OMIT_GET_TABLE", #endif | < < < | 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384 11385 11386 11387 11388 | #endif #ifdef SQLITE_OMIT_FOREIGN_KEY "OMIT_FOREIGN_KEY", #endif #ifdef SQLITE_OMIT_GET_TABLE "OMIT_GET_TABLE", #endif #ifdef SQLITE_OMIT_INCRBLOB "OMIT_INCRBLOB", #endif #ifdef SQLITE_OMIT_INTEGRITY_CHECK "OMIT_INTEGRITY_CHECK", #endif #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION |
︙ | ︙ | |||
11441 11442 11443 11444 11445 11446 11447 11448 11449 11450 11451 11452 11453 11454 | "OMIT_VACUUM", #endif #ifdef SQLITE_OMIT_VIEW "OMIT_VIEW", #endif #ifdef SQLITE_OMIT_VIRTUALTABLE "OMIT_VIRTUALTABLE", #endif #ifdef SQLITE_OMIT_WSD "OMIT_WSD", #endif #ifdef SQLITE_OMIT_XFER_OPT "OMIT_XFER_OPT", #endif | > > > | 11452 11453 11454 11455 11456 11457 11458 11459 11460 11461 11462 11463 11464 11465 11466 11467 11468 | "OMIT_VACUUM", #endif #ifdef SQLITE_OMIT_VIEW "OMIT_VIEW", #endif #ifdef SQLITE_OMIT_VIRTUALTABLE "OMIT_VIRTUALTABLE", #endif #ifdef SQLITE_OMIT_WAL "OMIT_WAL", #endif #ifdef SQLITE_OMIT_WSD "OMIT_WSD", #endif #ifdef SQLITE_OMIT_XFER_OPT "OMIT_XFER_OPT", #endif |
︙ | ︙ | |||
28501 28502 28503 28504 28505 28506 28507 | unixDlError, /* xDlError */ \ unixDlSym, /* xDlSym */ \ unixDlClose, /* xDlClose */ \ unixRandomness, /* xRandomness */ \ unixSleep, /* xSleep */ \ unixCurrentTime, /* xCurrentTime */ \ unixGetLastError, /* xGetLastError */ \ | < | 28515 28516 28517 28518 28519 28520 28521 28522 28523 28524 28525 28526 28527 28528 | unixDlError, /* xDlError */ \ unixDlSym, /* xDlSym */ \ unixDlClose, /* xDlClose */ \ unixRandomness, /* xRandomness */ \ unixSleep, /* xSleep */ \ unixCurrentTime, /* xCurrentTime */ \ unixGetLastError, /* xGetLastError */ \ unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ } /* ** All default VFSes for unix are contained in the following array. ** ** Note that the sqlite3_vfs.pNext field of the VFS object is modified |
︙ | ︙ | |||
29404 29405 29406 29407 29408 29409 29410 29411 29412 29413 29414 29415 29416 29417 | winFile *pFile = (winFile*)id; assert( id!=0 ); assert( pFile->pShm==0 ); OSTRACE(("CLOSE %d\n", pFile->h)); do{ rc = CloseHandle(pFile->h); }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ int cnt = 0; while( | > | 29417 29418 29419 29420 29421 29422 29423 29424 29425 29426 29427 29428 29429 29430 29431 | winFile *pFile = (winFile*)id; assert( id!=0 ); assert( pFile->pShm==0 ); OSTRACE(("CLOSE %d\n", pFile->h)); do{ rc = CloseHandle(pFile->h); /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ int cnt = 0; while( |
︙ | ︙ | |||
29495 29496 29497 29498 29499 29500 29501 | assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ pFile->lastErrno = error; | > | > > > > | > > > | 29509 29510 29511 29512 29513 29514 29515 29516 29517 29518 29519 29520 29521 29522 29523 29524 29525 29526 29527 29528 29529 29530 29531 29532 29533 29534 29535 29536 29537 29538 29539 29540 29541 29542 29543 29544 | assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ pFile->lastErrno = error; if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ return SQLITE_FULL; }else{ return SQLITE_IOERR_WRITE; } } assert( amt>0 ); while( amt>0 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ amt -= wrote; pBuf = &((char*)pBuf)[wrote]; } if( !rc || amt>(int)wrote ){ pFile->lastErrno = GetLastError(); if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ return SQLITE_FULL; }else{ return SQLITE_IOERR_WRITE; } } return SQLITE_OK; } /* ** Truncate an open file to a specified size */ |
︙ | ︙ | |||
29553 29554 29555 29556 29557 29558 29559 | SQLITE_API int sqlite3_fullsync_count = 0; #endif /* ** Make sure all writes to a particular file are committed to disk. */ static int winSync(sqlite3_file *id, int flags){ | | < < < > > > > > > > > > > > > > > > > | | 29575 29576 29577 29578 29579 29580 29581 29582 29583 29584 29585 29586 29587 29588 29589 29590 29591 29592 29593 29594 29595 29596 29597 29598 29599 29600 29601 29602 29603 29604 29605 29606 29607 29608 29609 29610 29611 29612 29613 29614 29615 29616 29617 29618 29619 29620 29621 29622 | SQLITE_API int sqlite3_fullsync_count = 0; #endif /* ** Make sure all writes to a particular file are committed to disk. */ static int winSync(sqlite3_file *id, int flags){ #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG) winFile *pFile = (winFile*)id; #else UNUSED_PARAMETER(id); #endif assert( pFile ); /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ assert((flags&0x0F)==SQLITE_SYNC_NORMAL || (flags&0x0F)==SQLITE_SYNC_FULL ); OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); #ifndef SQLITE_TEST UNUSED_PARAMETER(flags); #else if( flags & SQLITE_SYNC_FULL ){ sqlite3_fullsync_count++; } sqlite3_sync_count++; #endif /* Unix cannot, but some systems may return SQLITE_FULL from here. This ** line is to test that doing so does not cause any problems. */ SimulateDiskfullError( return SQLITE_FULL ); SimulateIOError( return SQLITE_IOERR; ); /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a ** no-op */ #ifdef SQLITE_NO_SYNC return SQLITE_OK; #else if( FlushFileBuffers(pFile->h) ){ return SQLITE_OK; }else{ pFile->lastErrno = GetLastError(); return SQLITE_IOERR; } |
︙ | ︙ | |||
29816 29817 29818 29819 29820 29821 29822 29823 29824 29825 29826 29827 29828 29829 | ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc; winFile *pFile = (winFile*)id; assert( id!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ rc = 1; OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( rc ){ | > > | 29851 29852 29853 29854 29855 29856 29857 29858 29859 29860 29861 29862 29863 29864 29865 29866 | ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc; winFile *pFile = (winFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( id!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ rc = 1; OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( rc ){ |
︙ | ︙ | |||
29888 29889 29890 29891 29892 29893 29894 29895 29896 29897 29898 29899 29900 29901 29902 | } case SQLITE_LAST_ERRNO: { *(int*)pArg = (int)((winFile*)id)->lastErrno; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { sqlite3_int64 sz = *(sqlite3_int64*)pArg; winTruncate(id, sz); return SQLITE_OK; } } return SQLITE_ERROR; } /* | > > | 29925 29926 29927 29928 29929 29930 29931 29932 29933 29934 29935 29936 29937 29938 29939 29940 29941 | } case SQLITE_LAST_ERRNO: { *(int*)pArg = (int)((winFile*)id)->lastErrno; return SQLITE_OK; } case SQLITE_FCNTL_SIZE_HINT: { sqlite3_int64 sz = *(sqlite3_int64*)pArg; SimulateIOErrorBenign(1); winTruncate(id, sz); SimulateIOErrorBenign(0); return SQLITE_OK; } } return SQLITE_ERROR; } /* |
︙ | ︙ | |||
30099 30100 30101 30102 30103 30104 30105 | if( p->nRef==0 ){ int i; if( p->mutex ) sqlite3_mutex_free(p->mutex); for(i=0; i<p->nRegion; i++){ UnmapViewOfFile(p->aRegion[i].pMap); CloseHandle(p->aRegion[i].hMap); } | | > > > > | > > | 30138 30139 30140 30141 30142 30143 30144 30145 30146 30147 30148 30149 30150 30151 30152 30153 30154 30155 30156 30157 30158 30159 30160 30161 | if( p->nRef==0 ){ int i; if( p->mutex ) sqlite3_mutex_free(p->mutex); for(i=0; i<p->nRegion; i++){ UnmapViewOfFile(p->aRegion[i].pMap); CloseHandle(p->aRegion[i].hMap); } if( p->hFile.h != INVALID_HANDLE_VALUE ){ SimulateIOErrorBenign(1); winClose((sqlite3_file *)&p->hFile); SimulateIOErrorBenign(0); } if( deleteFlag ){ SimulateIOErrorBenign(1); winDelete(pVfs, p->zFilename, 0); SimulateIOErrorBenign(0); } *pp = p->pNext; sqlite3_free(p->aRegion); sqlite3_free(p); }else{ pp = &p->pNext; } } |
︙ | ︙ | |||
30504 30505 30506 30507 30508 30509 30510 30511 30512 30513 30514 30515 30516 30517 | static int getTempname(int nBuf, char *zBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; char zTempPath[MAX_PATH+1]; if( sqlite3_temp_directory ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; GetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); | > > > > > > > | 30549 30550 30551 30552 30553 30554 30555 30556 30557 30558 30559 30560 30561 30562 30563 30564 30565 30566 30567 30568 30569 | static int getTempname(int nBuf, char *zBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; char zTempPath[MAX_PATH+1]; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. */ SimulateIOError( return SQLITE_IOERR ); if( sqlite3_temp_directory ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; GetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); |
︙ | ︙ | |||
30535 30536 30537 30538 30539 30540 30541 30542 30543 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); free(zUtf8); }else{ return SQLITE_NOMEM; } #endif } for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; | > > > > > > > > > | | | > | 30587 30588 30589 30590 30591 30592 30593 30594 30595 30596 30597 30598 30599 30600 30601 30602 30603 30604 30605 30606 30607 30608 30609 30610 30611 30612 30613 30614 30615 30616 30617 30618 30619 30620 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); free(zUtf8); }else{ return SQLITE_NOMEM; } #endif } /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){ return SQLITE_ERROR; } for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; sqlite3_snprintf(nBuf-17, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); j = sqlite3Strlen30(zBuf); sqlite3_randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; OSTRACE(("TEMP FILENAME: %s\n", zBuf)); return SQLITE_OK; } /* ** The return value of getLastErrorMsg ** is zero if the error message fits in the buffer, or non-zero |
︙ | ︙ | |||
30788 30789 30790 30791 30792 30793 30794 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; DWORD rc; DWORD error = 0; | | > > > < | 30850 30851 30852 30853 30854 30855 30856 30857 30858 30859 30860 30861 30862 30863 30864 30865 30866 30867 30868 30869 30870 30871 30872 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; DWORD rc; DWORD error = 0; void *zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); SimulateIOError(return SQLITE_IOERR_DELETE); zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ do{ DeleteFileW(zConverted); }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES) || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) && (++cnt < MX_DELETION_ATTEMPTS) && (Sleep(100), 1) ); |
︙ | ︙ | |||
30836 30837 30838 30839 30840 30841 30842 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ){ DWORD attr; int rc = 0; | | > > > > > | > > > > > > > > > > > > > > > > > > > > | 30900 30901 30902 30903 30904 30905 30906 30907 30908 30909 30910 30911 30912 30913 30914 30915 30916 30917 30918 30919 30920 30921 30922 30923 30924 30925 30926 30927 30928 30929 30930 30931 30932 30933 30934 30935 30936 30937 30938 30939 30940 30941 30942 30943 30944 30945 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ){ DWORD attr; int rc = 0; void *zConverted; UNUSED_PARAMETER(pVfs); SimulateIOError( return SQLITE_IOERR_ACCESS; ); zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ WIN32_FILE_ATTRIBUTE_DATA sAttrData; memset(&sAttrData, 0, sizeof(sAttrData)); if( GetFileAttributesExW((WCHAR*)zConverted, GetFileExInfoStandard, &sAttrData) ){ /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file ** as if it does not exist. */ if( flags==SQLITE_ACCESS_EXISTS && sAttrData.nFileSizeHigh==0 && sAttrData.nFileSizeLow==0 ){ attr = INVALID_FILE_ATTRIBUTES; }else{ attr = sAttrData.dwFileAttributes; } }else{ if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ free(zConverted); return SQLITE_IOERR_ACCESS; }else{ attr = INVALID_FILE_ATTRIBUTES; } } /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ attr = GetFileAttributesA((char*)zConverted); |
︙ | ︙ | |||
30882 30883 30884 30885 30886 30887 30888 30889 30890 30891 30892 30893 30894 30895 30896 30897 30898 30899 30900 30901 30902 30903 30904 30905 30906 30907 30908 30909 30910 30911 | sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ #if defined(__CYGWIN__) UNUSED_PARAMETER(nFull); cygwin_conv_to_full_win32_path(zRelative, zFull); return SQLITE_OK; #endif #if SQLITE_OS_WINCE UNUSED_PARAMETER(nFull); /* WinCE has no concept of a relative pathname, or so I am told. */ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); return SQLITE_OK; #endif #if !SQLITE_OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; UNUSED_PARAMETER(nFull); zConverted = convertUtf8Filename(zRelative); if( isNT() ){ WCHAR *zTemp; nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ | > > > > > > > > > | 30971 30972 30973 30974 30975 30976 30977 30978 30979 30980 30981 30982 30983 30984 30985 30986 30987 30988 30989 30990 30991 30992 30993 30994 30995 30996 30997 30998 30999 31000 31001 31002 31003 31004 31005 31006 31007 31008 31009 | sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ #if defined(__CYGWIN__) SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); cygwin_conv_to_full_win32_path(zRelative, zFull); return SQLITE_OK; #endif #if SQLITE_OS_WINCE SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); /* WinCE has no concept of a relative pathname, or so I am told. */ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); return SQLITE_OK; #endif #if !SQLITE_OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); zConverted = convertUtf8Filename(zRelative); if( isNT() ){ WCHAR *zTemp; nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ |
︙ | ︙ | |||
30965 30966 30967 30968 30969 30970 30971 30972 30973 30974 30975 30976 30977 30978 30979 | DWORD dwDummy; /* ** We need to get the full path name of the file ** to get the drive letter to look up the sector ** size. */ rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); if( rc == SQLITE_OK ) { void *zConverted = convertUtf8Filename(zFullpath); if( zConverted ){ if( isNT() ){ /* trim path to just drive reference */ WCHAR *p = zConverted; | > > | 31063 31064 31065 31066 31067 31068 31069 31070 31071 31072 31073 31074 31075 31076 31077 31078 31079 | DWORD dwDummy; /* ** We need to get the full path name of the file ** to get the drive letter to look up the sector ** size. */ SimulateIOErrorBenign(1); rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); SimulateIOErrorBenign(0); if( rc == SQLITE_OK ) { void *zConverted = convertUtf8Filename(zFullpath); if( zConverted ){ if( isNT() ){ /* trim path to just drive reference */ WCHAR *p = zConverted; |
︙ | ︙ | |||
31242 31243 31244 31245 31246 31247 31248 | winDlError, /* xDlError */ winDlSym, /* xDlSym */ winDlClose, /* xDlClose */ winRandomness, /* xRandomness */ winSleep, /* xSleep */ winCurrentTime, /* xCurrentTime */ winGetLastError, /* xGetLastError */ | < | 31342 31343 31344 31345 31346 31347 31348 31349 31350 31351 31352 31353 31354 31355 | winDlError, /* xDlError */ winDlSym, /* xDlSym */ winDlClose, /* xDlClose */ winRandomness, /* xRandomness */ winSleep, /* xSleep */ winCurrentTime, /* xCurrentTime */ winGetLastError, /* xGetLastError */ winCurrentTimeInt64, /* xCurrentTimeInt64 */ }; sqlite3_vfs_register(&winVfs, 1); return SQLITE_OK; } SQLITE_API int sqlite3_os_end(void){ |
︙ | ︙ | |||
33979 33980 33981 33982 33983 33984 33985 33986 33987 33988 33989 33990 33991 33992 | void *pCodec; /* First argument to xCodec... methods */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ #endif }; /* ** The following global variables hold counters used for ** testing purposes only. These variables do not exist in ** a non-testing build. These variables are not thread-safe. | > | 34078 34079 34080 34081 34082 34083 34084 34085 34086 34087 34088 34089 34090 34091 34092 | void *pCodec; /* First argument to xCodec... methods */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ #ifndef SQLITE_OMIT_WAL Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ char *zWal; /* File name for write-ahead log */ #endif }; /* ** The following global variables hold counters used for ** testing purposes only. These variables do not exist in ** a non-testing build. These variables are not thread-safe. |
︙ | ︙ | |||
35089 35090 35091 35092 35093 35094 35095 35096 35097 35098 35099 35100 35101 35102 | while( i>0 ){ cksum += aData[i]; i -= 200; } return cksum; } /* ** Read a single page from either the journal file (if isMainJrnl==1) or ** from the sub-journal (if isMainJrnl==0) and playback that page. ** The page begins at offset *pOffset into the file. The *pOffset ** value is increased to the start of the next page in the journal. ** ** The isMainJrnl flag is true if this is the main rollback journal and | > > > > > > > > > > > > > > > | 35189 35190 35191 35192 35193 35194 35195 35196 35197 35198 35199 35200 35201 35202 35203 35204 35205 35206 35207 35208 35209 35210 35211 35212 35213 35214 35215 35216 35217 | while( i>0 ){ cksum += aData[i]; i -= 200; } return cksum; } /* ** Report the current page size and number of reserved bytes back ** to the codec. */ #ifdef SQLITE_HAS_CODEC static void pagerReportSize(Pager *pPager){ if( pPager->xCodecSizeChng ){ pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, (int)pPager->nReserve); } } #else # define pagerReportSize(X) /* No-op if we do not support a codec */ #endif /* ** Read a single page from either the journal file (if isMainJrnl==1) or ** from the sub-journal (if isMainJrnl==0) and playback that page. ** The page begins at offset *pOffset into the file. The *pOffset ** value is increased to the start of the next page in the journal. ** ** The isMainJrnl flag is true if this is the main rollback journal and |
︙ | ︙ | |||
35181 35182 35183 35184 35185 35186 35187 35188 35189 35190 35191 | rc = read32bits(jfd, (*pOffset)-4, &cksum); if( rc ) return rc; if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ return SQLITE_DONE; } } if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ return rc; } | > > > > > > > | > > | 35296 35297 35298 35299 35300 35301 35302 35303 35304 35305 35306 35307 35308 35309 35310 35311 35312 35313 35314 35315 35316 35317 35318 35319 35320 35321 35322 35323 | rc = read32bits(jfd, (*pOffset)-4, &cksum); if( rc ) return rc; if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ return SQLITE_DONE; } } /* If this page has already been played by before during the current ** rollback, then don't bother to play it back again. */ if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ return rc; } assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE ); /* When playing back page 1, restore the nReserve setting */ if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ pPager->nReserve = ((u8*)aData)[20]; pagerReportSize(pPager); } /* If the pager is in RESERVED state, then there must be a copy of this ** page in the pager cache. In this case just update the pager cache, ** not the database file. The page is left marked dirty in this case. ** ** An exception to the above rule: If the database is in no-sync mode ** and a page is moved during an incremental vacuum then the page may |
︙ | ︙ | |||
35985 35986 35987 35988 35989 35990 35991 | rc = sqlite3PagerPagecount(pPager, &dummy); } pPager->state = PAGER_SHARED; return rc; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 36109 36110 36111 36112 36113 36114 36115 36116 36117 36118 36119 36120 36121 36122 | rc = sqlite3PagerPagecount(pPager, &dummy); } pPager->state = PAGER_SHARED; return rc; } /* ** Check if the *-wal file that corresponds to the database opened by pPager ** exists if the database is not empy, or verify that the *-wal file does ** not exist (by deleting it) if the database file is empty. ** ** If the database is not empty and the *-wal file exists, open the pager ** in WAL mode. If the database is empty or if no *-wal file exists and |
︙ | ︙ | |||
36046 36047 36048 36049 36050 36051 36052 | if( !pPager->tempFile ){ int isWal; /* True if WAL file exists */ int nPage; /* Size of the database file */ assert( pPager->state>=SHARED_LOCK ); rc = sqlite3PagerPagecount(pPager, &nPage); if( rc ) return rc; if( nPage==0 ){ | | | > > | 36138 36139 36140 36141 36142 36143 36144 36145 36146 36147 36148 36149 36150 36151 36152 36153 36154 36155 36156 36157 | if( !pPager->tempFile ){ int isWal; /* True if WAL file exists */ int nPage; /* Size of the database file */ assert( pPager->state>=SHARED_LOCK ); rc = sqlite3PagerPagecount(pPager, &nPage); if( rc ) return rc; if( nPage==0 ){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); isWal = 0; }else{ rc = sqlite3OsAccess( pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal ); } if( rc==SQLITE_OK ){ if( isWal ){ pager_reset(pPager); rc = sqlite3PagerOpenWal(pPager, 0); if( rc==SQLITE_OK ){ rc = pagerBeginReadTransaction(pPager); |
︙ | ︙ | |||
36123 36124 36125 36126 36127 36128 36129 36130 36131 36132 36133 36134 36135 36136 | } } /* Set the database size back to the value it was before the savepoint ** being reverted was opened. */ pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; if( !pSavepoint && pagerUseWal(pPager) ){ return pagerRollbackWal(pPager); } /* Use pPager->journalOff as the effective size of the main rollback ** journal. The actual file might be larger than this in | > | 36217 36218 36219 36220 36221 36222 36223 36224 36225 36226 36227 36228 36229 36230 36231 | } } /* Set the database size back to the value it was before the savepoint ** being reverted was opened. */ pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; pPager->changeCountDone = pPager->tempFile; if( !pSavepoint && pagerUseWal(pPager) ){ return pagerRollbackWal(pPager); } /* Use pPager->journalOff as the effective size of the main rollback ** journal. The actual file might be larger than this in |
︙ | ︙ | |||
36323 36324 36325 36326 36327 36328 36329 | int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ ){ pPager->xBusyHandler = xBusyHandler; pPager->pBusyHandlerArg = pBusyHandlerArg; } | < < < < < < < < < < < < < < < | 36418 36419 36420 36421 36422 36423 36424 36425 36426 36427 36428 36429 36430 36431 | int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ ){ pPager->xBusyHandler = xBusyHandler; pPager->pBusyHandlerArg = pBusyHandlerArg; } /* ** Change the page size used by the Pager object. The new page size ** is passed in *pPageSize. ** ** If the pager is in the error state when this function is called, it ** is a no-op. The value returned is the error state error code (i.e. ** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL). |
︙ | ︙ | |||
36477 36478 36479 36480 36481 36482 36483 | assert( isOpen(pPager->fd) || pPager->tempFile ); /* This routine is only called by btree immediately after creating ** the Pager object. There has not been an opportunity to transition ** to WAL mode yet. */ assert( !pagerUseWal(pPager) ); | < < < < < < < < < | 36557 36558 36559 36560 36561 36562 36563 36564 36565 36566 36567 36568 36569 36570 | assert( isOpen(pPager->fd) || pPager->tempFile ); /* This routine is only called by btree immediately after creating ** the Pager object. There has not been an opportunity to transition ** to WAL mode yet. */ assert( !pagerUseWal(pPager) ); if( isOpen(pPager->fd) ){ IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) rc = sqlite3OsRead(pPager->fd, pDest, N, 0); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } |
︙ | ︙ | |||
36929 36930 36931 36932 36933 36934 36935 | ** in Pager.dbFileVers[] is updated to match the new value stored in ** the database file. ** ** If everything is successful, SQLITE_OK is returned. If an IO error ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot ** be obtained, SQLITE_BUSY is returned. */ | | < < < < | | > | 37000 37001 37002 37003 37004 37005 37006 37007 37008 37009 37010 37011 37012 37013 37014 37015 37016 37017 37018 37019 37020 37021 37022 37023 37024 37025 37026 37027 37028 37029 37030 37031 37032 37033 37034 37035 37036 37037 37038 37039 37040 37041 37042 37043 37044 37045 37046 37047 37048 37049 37050 | ** in Pager.dbFileVers[] is updated to match the new value stored in ** the database file. ** ** If everything is successful, SQLITE_OK is returned. If an IO error ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot ** be obtained, SQLITE_BUSY is returned. */ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ int rc; /* Return code */ /* At this point there may be either a RESERVED or EXCLUSIVE lock on the ** database file. If there is already an EXCLUSIVE lock, the following ** call is a no-op. ** ** Moving the lock from RESERVED to EXCLUSIVE actually involves going ** through an intermediate state PENDING. A PENDING lock prevents new ** readers from attaching to the database but is unsufficient for us to ** write. The idea of a PENDING lock is to prevent new readers from ** coming in while we wait for existing readers to clear. ** ** While the pager is in the RESERVED state, the original database file ** is unchanged and we can rollback without having to playback the ** journal into the original database file. Once we transition to ** EXCLUSIVE, it means the database file has been changed and any rollback ** will require a journal playback. */ assert( !pagerUseWal(pPager) ); assert( pPager->state>=PAGER_RESERVED ); rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); /* If the file is a temp-file has not yet been opened, open it now. It ** is not possible for rc to be other than SQLITE_OK if this branch ** is taken, as pager_wait_on_lock() is a no-op for temp-files. */ if( !isOpen(pPager->fd) ){ assert( pPager->tempFile && rc==SQLITE_OK ); rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); } /* Before the first write, give the VFS a hint of what the final ** file size will be. */ assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); if( rc==SQLITE_OK && pPager->dbSize>(pPager->dbOrigSize+1) ){ sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); } while( rc==SQLITE_OK && pList ){ Pgno pgno = pList->pgno; |
︙ | ︙ | |||
37197 37198 37199 37200 37201 37202 37203 | rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) ) ){ rc = subjournalPage(pPg); } /* Write the contents of the page out to the database file. */ if( rc==SQLITE_OK ){ | | | 37265 37266 37267 37268 37269 37270 37271 37272 37273 37274 37275 37276 37277 37278 37279 | rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) ) ){ rc = subjournalPage(pPg); } /* Write the contents of the page out to the database file. */ if( rc==SQLITE_OK ){ rc = pager_write_pagelist(pPager, pPg); } } /* Mark the page as clean. */ if( rc==SQLITE_OK ){ PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); sqlite3PcacheMakeClean(pPg); |
︙ | ︙ | |||
37337 37338 37339 37340 37341 37342 37343 37344 37345 37346 37347 37348 37349 37350 37351 37352 37353 37354 37355 37356 37357 37358 37359 37360 37361 37362 37363 | 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 */ nPathname + 1 + /* zFilename */ nPathname + 8 + 1 /* zJournal */ ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); if( !pPtr ){ sqlite3_free(zPathname); return SQLITE_NOMEM; } pPager = (Pager*)(pPtr); pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile)); pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); pPager->zFilename = (char*)(pPtr += journalFileSize); assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ if( zPathname ){ pPager->zJournal = (char*)(pPtr += nPathname + 1); memcpy(pPager->zFilename, zPathname, nPathname); memcpy(pPager->zJournal, zPathname, nPathname); memcpy(&pPager->zJournal[nPathname], "-journal", 8); | > > > | > > > > > > > > > | 37405 37406 37407 37408 37409 37410 37411 37412 37413 37414 37415 37416 37417 37418 37419 37420 37421 37422 37423 37424 37425 37426 37427 37428 37429 37430 37431 37432 37433 37434 37435 37436 37437 37438 37439 37440 37441 37442 37443 37444 37445 37446 37447 37448 37449 37450 37451 | 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 */ nPathname + 1 + /* zFilename */ nPathname + 8 + 1 /* zJournal */ #ifndef SQLITE_OMIT_WAL + nPathname + 4 + 1 /* zWal */ #endif ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); if( !pPtr ){ sqlite3_free(zPathname); return SQLITE_NOMEM; } pPager = (Pager*)(pPtr); pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile)); pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); pPager->zFilename = (char*)(pPtr += journalFileSize); assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ if( zPathname ){ pPager->zJournal = (char*)(pPtr += nPathname + 1); memcpy(pPager->zFilename, zPathname, nPathname); memcpy(pPager->zJournal, zPathname, nPathname); memcpy(&pPager->zJournal[nPathname], "-journal", 8); if( pPager->zFilename[0]==0 ){ pPager->zJournal[0] = 0; } #ifndef SQLITE_OMIT_WAL else{ pPager->zWal = &pPager->zJournal[nPathname+8+1]; memcpy(pPager->zWal, zPathname, nPathname); memcpy(&pPager->zWal[nPathname], "-wal", 4); } #endif sqlite3_free(zPathname); } pPager->pVfs = pVfs; pPager->vfsFlags = vfsFlags; /* Open the pager file. */ |
︙ | ︙ | |||
38814 38815 38816 38817 38818 38819 38820 | ** used, this call will not create the journal file or perform any ** real IO. */ rc = syncJournal(pPager); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; /* Write all dirty pages to the database file. */ | | | 38894 38895 38896 38897 38898 38899 38900 38901 38902 38903 38904 38905 38906 38907 38908 | ** used, this call will not create the journal file or perform any ** real IO. */ rc = syncJournal(pPager); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; /* Write all dirty pages to the database file. */ rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); if( rc!=SQLITE_OK ){ assert( rc!=SQLITE_IOERR_BLOCKED ); goto commit_phase_one_exit; } sqlite3PcacheCleanAll(pPager->pPCache); /* If the file on disk is not the same size as the database image, |
︙ | ︙ | |||
39649 39650 39651 39652 39653 39654 39655 | if( !pPager->tempFile && !pPager->pWal ){ if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; /* Open the connection to the log file. If this operation fails, ** (e.g. due to malloc() failure), unlock the database file and ** return an error code. */ | | < | 39729 39730 39731 39732 39733 39734 39735 39736 39737 39738 39739 39740 39741 39742 39743 | if( !pPager->tempFile && !pPager->pWal ){ if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; /* Open the connection to the log file. If this operation fails, ** (e.g. due to malloc() failure), unlock the database file and ** return an error code. */ rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal); if( rc==SQLITE_OK ){ pPager->journalMode = PAGER_JOURNALMODE_WAL; } }else{ *pisOpen = 1; } |
︙ | ︙ | |||
39683 39684 39685 39686 39687 39688 39689 | ** it may need to be checkpointed before the connection can switch to ** rollback mode. Open it now so this can happen. */ if( !pPager->pWal ){ int logexists = 0; rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ | > | > | | 39762 39763 39764 39765 39766 39767 39768 39769 39770 39771 39772 39773 39774 39775 39776 39777 39778 39779 39780 39781 39782 | ** it may need to be checkpointed before the connection can switch to ** rollback mode. Open it now so this can happen. */ if( !pPager->pWal ){ int logexists = 0; rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ rc = sqlite3OsAccess( pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists ); } if( rc==SQLITE_OK && logexists ){ rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal); } } /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on ** the database file, the log and log-summary files will be deleted. */ if( rc==SQLITE_OK && pPager->pWal ){ |
︙ | ︙ | |||
40129 40130 40131 40132 40133 40134 40135 | /* ** Return the offset of frame iFrame in the write-ahead log file, ** assuming a database page size of szPage bytes. The offset returned ** is to the start of the write-ahead log frame-header. */ #define walFrameOffset(iFrame, szPage) ( \ | | | | 40210 40211 40212 40213 40214 40215 40216 40217 40218 40219 40220 40221 40222 40223 40224 40225 40226 40227 40228 40229 40230 40231 40232 40233 40234 40235 40236 40237 40238 40239 40240 40241 40242 40243 40244 40245 | /* ** Return the offset of frame iFrame in the write-ahead log file, ** assuming a database page size of szPage bytes. The offset returned ** is to the start of the write-ahead log frame-header. */ #define walFrameOffset(iFrame, szPage) ( \ WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ ) /* ** An open write-ahead log file is represented by an instance of the ** following object. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ sqlite3_file *pDbFd; /* File handle for the database file */ sqlite3_file *pWalFd; /* File handle for WAL file */ u32 iCallback; /* Value to pass to log callback (or 0) */ int nWiData; /* Size of array apWiData */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u16 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 isWIndexOpen; /* True if ShmOpen() called on pDbFd */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif }; /* |
︙ | ︙ | |||
40905 40906 40907 40908 40909 40910 40911 | if( pWal->isWIndexOpen ){ sqlite3OsShmClose(pWal->pDbFd, isDelete); pWal->isWIndexOpen = 0; } } /* | | | > | < < | < | < | < | | 40986 40987 40988 40989 40990 40991 40992 40993 40994 40995 40996 40997 40998 40999 41000 41001 41002 41003 41004 41005 41006 41007 41008 41009 41010 41011 41012 41013 41014 41015 41016 41017 41018 41019 41020 41021 41022 41023 41024 41025 41026 41027 41028 41029 41030 41031 41032 41033 41034 41035 41036 41037 41038 41039 41040 41041 41042 41043 41044 41045 41046 41047 41048 41049 41050 41051 41052 41053 41054 41055 41056 41057 | if( pWal->isWIndexOpen ){ sqlite3OsShmClose(pWal->pDbFd, isDelete); pWal->isWIndexOpen = 0; } } /* ** Open a connection to the WAL file zWalName. The database file must ** already be opened on connection pDbFd. The buffer that zWalName points ** to must remain valid for the lifetime of the returned Wal* handle. ** ** A SHARED lock should be held on the database file when this function ** is called. The purpose of this SHARED lock is to prevent any other ** client from unlinking the WAL or wal-index file. If another process ** were to do this just after this client opened one of these files, the ** system would be badly broken. ** ** If the log file is successfully opened, SQLITE_OK is returned and ** *ppWal is set to point to a new WAL handle. If an error occurs, ** an SQLite error code is returned and *ppWal is left unmodified. */ SQLITE_PRIVATE int sqlite3WalOpen( sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ sqlite3_file *pDbFd, /* The open database file */ const char *zWalName, /* Name of the WAL file */ Wal **ppWal /* OUT: Allocated Wal handle */ ){ int rc; /* Return Code */ Wal *pRet; /* Object to allocate and return */ int flags; /* Flags passed to OsOpen() */ assert( zWalName && zWalName[0] ); assert( pDbFd ); /* In the amalgamation, the os_unix.c and os_win.c source files come before ** this source file. Verify that the #defines of the locking byte offsets ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. */ #ifdef WIN_SHM_BASE assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); #endif #ifdef UNIX_SHM_BASE assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET ); #endif /* Allocate an instance of struct Wal to return. */ *ppWal = 0; pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); if( !pRet ){ return SQLITE_NOMEM; } pRet->pVfs = pVfs; pRet->pWalFd = (sqlite3_file *)&pRet[1]; pRet->pDbFd = pDbFd; pRet->readLock = -1; pRet->zWalName = zWalName; rc = sqlite3OsShmOpen(pDbFd); /* Open file handle on the write-ahead log file. */ if( rc==SQLITE_OK ){ pRet->isWIndexOpen = 1; flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL); rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); } if( rc!=SQLITE_OK ){ walIndexClose(pRet, 0); sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ |
︙ | ︙ | |||
41308 41309 41310 41311 41312 41313 41314 41315 41316 | /* Sync the WAL to disk */ if( sync_flags ){ rc = sqlite3OsSync(pWal->pWalFd, sync_flags); } /* Iterate through the contents of the WAL, copying data to the db file. */ while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ assert( walFramePgno(pWal, iFrame)==iDbpage ); if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue; | > < | | > > > | > > | | 41385 41386 41387 41388 41389 41390 41391 41392 41393 41394 41395 41396 41397 41398 41399 41400 41401 41402 41403 41404 41405 41406 41407 41408 41409 41410 41411 41412 41413 41414 41415 41416 41417 | /* Sync the WAL to disk */ if( sync_flags ){ rc = sqlite3OsSync(pWal->pWalFd, sync_flags); } /* Iterate through the contents of the WAL, copying data to the db file. */ while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ i64 iOffset; assert( walFramePgno(pWal, iFrame)==iDbpage ); if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue; iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ 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 && sync_flags ){ rc = sqlite3OsSync(pWal->pDbFd, sync_flags); } } if( rc==SQLITE_OK ){ pInfo->nBackfill = mxSafeFrame; } |
︙ | ︙ | |||
41859 41860 41861 41862 41863 41864 41865 41866 41867 41868 41869 41870 41871 41872 | /* If iRead is non-zero, then it is the log frame number that contains the ** required page. Read and return data from the log file. */ if( iRead ){ i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE; *pInWal = 1; return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); } *pInWal = 0; return SQLITE_OK; } | > | 41941 41942 41943 41944 41945 41946 41947 41948 41949 41950 41951 41952 41953 41954 41955 | /* If iRead is non-zero, then it is the log frame number that contains the ** required page. Read and return data from the log file. */ if( iRead ){ i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE; *pInWal = 1; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); } *pInWal = 0; return SQLITE_OK; } |
︙ | ︙ | |||
42125 42126 42127 42128 42129 42130 42131 42132 42133 42134 42135 42136 42137 42138 | u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ u32 aCksum[2]; /* Checksum for wal-header */ sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); sqlite3Put4byte(&aWalHdr[8], szPage); sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); sqlite3Put4byte(&aWalHdr[24], aCksum[0]); sqlite3Put4byte(&aWalHdr[28], aCksum[1]); pWal->szPage = (u16)szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; | > | 42208 42209 42210 42211 42212 42213 42214 42215 42216 42217 42218 42219 42220 42221 42222 | u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ u32 aCksum[2]; /* Checksum for wal-header */ sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); sqlite3Put4byte(&aWalHdr[8], szPage); sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); sqlite3_randomness(8, pWal->hdr.aSalt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); sqlite3Put4byte(&aWalHdr[24], aCksum[0]); sqlite3Put4byte(&aWalHdr[28], aCksum[1]); pWal->szPage = (u16)szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; |
︙ | ︙ | |||
42149 42150 42151 42152 42153 42154 42155 | /* Write the log file. */ for(p=pList; p; p=p->pDirty){ u32 nDbsize; /* Db-size field for frame header */ i64 iOffset; /* Write offset in log file */ void *pData; | < > | 42233 42234 42235 42236 42237 42238 42239 42240 42241 42242 42243 42244 42245 42246 42247 42248 | /* Write the log file. */ for(p=pList; p; p=p->pDirty){ u32 nDbsize; /* Db-size field for frame header */ i64 iOffset; /* Write offset in log file */ void *pData; iOffset = walFrameOffset(++iFrame, szPage); /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ /* Populate and write the frame header */ nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0; #if defined(SQLITE_HAS_CODEC) if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; #else pData = p->pData; |
︙ | ︙ | |||
42190 42191 42192 42193 42194 42195 42196 42197 42198 42199 42200 42201 42202 42203 | void *pData; #if defined(SQLITE_HAS_CODEC) if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM; #else pData = pLast->pData; #endif walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); if( rc!=SQLITE_OK ){ return rc; } iOffset += WAL_FRAME_HDRSIZE; rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); if( rc!=SQLITE_OK ){ | > | 42274 42275 42276 42277 42278 42279 42280 42281 42282 42283 42284 42285 42286 42287 42288 | void *pData; #if defined(SQLITE_HAS_CODEC) if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM; #else pData = pLast->pData; #endif walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); if( rc!=SQLITE_OK ){ return rc; } iOffset += WAL_FRAME_HDRSIZE; rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
63499 63500 63501 63502 63503 63504 63505 | ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback ** modes (delete, truncate, persist, off and memory), this is a simple ** operation. No IO is required. ** ** If changing into or out of WAL mode the procedure is more complicated. ** ** Write a string containing the final journal-mode to register P2. | < < < < < | 63584 63585 63586 63587 63588 63589 63590 63591 63592 63593 63594 63595 63596 63597 | ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback ** modes (delete, truncate, persist, off and memory), this is a simple ** operation. No IO is required. ** ** If changing into or out of WAL mode the procedure is more complicated. ** ** Write a string containing the final journal-mode to register P2. */ case OP_JournalMode: { /* out2-prerelease */ #if 0 /* local variables moved into u.cd */ Btree *pBt; /* Btree to change journal mode of */ Pager *pPager; /* Pager associated with pBt */ int eNew; /* New journal mode */ int eOld; /* The old journal mode */ |
︙ | ︙ | |||
63603 63604 63605 63606 63607 63608 63609 | rc = sqlite3BtreeSetVersion(u.cd.pBt, (u.cd.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); } } } #endif /* ifndef SQLITE_OMIT_WAL */ if( rc ){ | < | | 63683 63684 63685 63686 63687 63688 63689 63690 63691 63692 63693 63694 63695 63696 63697 63698 63699 63700 63701 63702 63703 63704 63705 63706 63707 63708 | rc = sqlite3BtreeSetVersion(u.cd.pBt, (u.cd.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); } } } #endif /* ifndef SQLITE_OMIT_WAL */ if( rc ){ u.cd.eNew = u.cd.eOld; } u.cd.eNew = sqlite3PagerSetJournalMode(u.cd.pPager, u.cd.eNew); pOut = &aMem[pOp->p2]; pOut->flags = MEM_Str|MEM_Static|MEM_Term; pOut->z = (char *)sqlite3JournalModename(u.cd.eNew); pOut->n = sqlite3Strlen30(pOut->z); pOut->enc = SQLITE_UTF8; sqlite3VdbeChangeEncoding(pOut, encoding); break; }; #endif /* SQLITE_OMIT_PRAGMA */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* Opcode: Vacuum * * * * * ** ** Vacuum the entire database. This opcode will cause other virtual ** machines to be created and run. It may not be called from within |
︙ | ︙ | |||
71828 71829 71830 71831 71832 71833 71834 | }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); | < < | 71907 71908 71909 71910 71911 71912 71913 71914 71915 71916 71917 71918 71919 71920 | }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); } aNew->safety_level = 3; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM; |
︙ | ︙ | |||
72025 72026 72027 72028 72029 72030 72031 | assert( v || db->mallocFailed ); if( v ){ sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3); assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); | < < < < < < < < < < < | 72102 72103 72104 72105 72106 72107 72108 72109 72110 72111 72112 72113 72114 72115 | assert( v || db->mallocFailed ); if( v ){ sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3); assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); } |
︙ | ︙ | |||
75912 75913 75914 75915 75916 75917 75918 | } db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ db->mallocFailed = 1; return 1; } | < | 75978 75979 75980 75981 75982 75983 75984 75985 75986 75987 75988 75989 75990 75991 | } db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ db->mallocFailed = 1; return 1; } } return 0; } /* ** Generate VDBE code that will verify the schema cookie and start ** a read-transaction for all named database files. |
︙ | ︙ | |||
83581 83582 83583 83584 83585 83586 83587 | /* ** PRAGMA [database.]journal_mode ** PRAGMA [database.]journal_mode = ** (delete|persist|off|truncate|memory|wal|off) */ if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ | | > > > > > > > > > | > > | | < < < < < < < < | | < < < < < < < < < | < | | | | | | < < | 83646 83647 83648 83649 83650 83651 83652 83653 83654 83655 83656 83657 83658 83659 83660 83661 83662 83663 83664 83665 83666 83667 83668 83669 83670 83671 83672 83673 83674 83675 83676 83677 83678 83679 83680 83681 83682 83683 83684 83685 83686 83687 83688 83689 83690 83691 83692 83693 83694 83695 83696 83697 83698 | /* ** PRAGMA [database.]journal_mode ** PRAGMA [database.]journal_mode = ** (delete|persist|off|truncate|memory|wal|off) */ if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ int ii; /* Loop counter */ /* Force the schema to be loaded on all databases. This cases all ** database files to be opened and the journal_modes set. */ if( sqlite3ReadSchema(pParse) ){ goto pragma_out; } sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); if( zRight==0 ){ /* If there is no "=MODE" part of the pragma, do a query for the ** current mode */ eMode = PAGER_JOURNALMODE_QUERY; }else{ const char *zMode; int n = sqlite3Strlen30(zRight); for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; } if( !zMode ){ /* If the "=MODE" part does not match any known journal mode, ** then do a query */ eMode = PAGER_JOURNALMODE_QUERY; } } if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ iDb = 0; pId2->n = 1; } for(ii=db->nDb-1; ii>=0; ii--){ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ sqlite3VdbeUsesBtree(v, ii); sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); } } sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); }else /* ** PRAGMA [database.]journal_size_limit ** PRAGMA [database.]journal_size_limit=N ** |
︙ | ︙ | |||
84646 84647 84648 84649 84650 84651 84652 84653 84654 84655 84656 84657 | /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ int rc; sqlite3_stmt *pStmt; assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); db->init.orphanTrigger = 0; | > | > > | | 84702 84703 84704 84705 84706 84707 84708 84709 84710 84711 84712 84713 84714 84715 84716 84717 84718 84719 84720 84721 84722 84723 84724 84725 84726 84727 84728 84729 84730 84731 84732 84733 | /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ int rc; sqlite3_stmt *pStmt; TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); db->init.orphanTrigger = 0; TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = 0; if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[0]==0 ){ corruptSchema(pData, 0, 0); |
︙ | ︙ | |||
104121 104122 104123 104124 104125 104126 104127 | db->xCollNeeded16 = xCollNeeded16; db->pCollNeededArg = pCollNeededArg; sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } #endif /* SQLITE_OMIT_UTF16 */ | < < | 104180 104181 104182 104183 104184 104185 104186 104187 104188 104189 104190 104191 104192 104193 104194 104195 104196 104197 104198 104199 104200 104201 | db->xCollNeeded16 = xCollNeeded16; db->pCollNeededArg = pCollNeededArg; sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } #endif /* SQLITE_OMIT_UTF16 */ #ifndef SQLITE_OMIT_DEPRECATED /* ** This function is now an anachronism. It used to be used to recover from a ** malloc() failure, but SQLite now does this automatically. */ SQLITE_API int sqlite3_global_recover(void){ return SQLITE_OK; } #endif /* ** Test to see whether or not the database connection is in autocommit ** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on ** by default. Autocommit is disabled by a BEGIN statement and reenabled ** by the next COMMIT or ROLLBACK. |
︙ | ︙ |
Changes to src/sqlite3.h.
︙ | ︙ | |||
105 106 107 108 109 110 111 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.0" #define SQLITE_VERSION_NUMBER 3007000 | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.0" #define SQLITE_VERSION_NUMBER 3007000 #define SQLITE_SOURCE_ID "2010-07-08 17:40:38 e396184cd3bdb96e29ac33af5d1f631cac553341" /* ** 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 |
︙ | ︙ | |||
828 829 830 831 832 833 834 | ** SQLite will always allocate at least mxPathname+1 bytes for the ** output buffer xFullPathname. The exact size of the output buffer ** is also passed as a parameter to both methods. If the output buffer ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is ** handled as a fatal error by SQLite, vfs implementations should endeavor ** to prevent this by setting mxPathname to a sufficiently large value. ** | | | | > > > | > > > > | 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 | ** SQLite will always allocate at least mxPathname+1 bytes for the ** output buffer xFullPathname. The exact size of the output buffer ** is also passed as a parameter to both methods. If the output buffer ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is ** handled as a fatal error by SQLite, vfs implementations should endeavor ** to prevent this by setting mxPathname to a sufficiently large value. ** ** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() ** interfaces are not strictly a part of the filesystem, but they are ** included in the VFS structure for completeness. ** The xRandomness() function attempts to return nBytes bytes ** of good-quality randomness into zOut. The return value is ** the actual number of bytes of randomness obtained. ** The xSleep() method causes the calling thread to sleep for at ** least the number of microseconds given. The xCurrentTime() ** method returns a Julian Day Number for the current date and time as ** a floating point value. ** The xCurrentTimeInt64() method returns, as an integer, the Julian ** Day Number multipled by 86400000 (the number of milliseconds in ** a 24-hour day). ** ^SQLite will use the xCurrentTimeInt64() method to get the current ** date and time if that method is available (if iVersion is 2 or ** greater and the function pointer is not NULL) and will fall back ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. */ typedef struct sqlite3_vfs sqlite3_vfs; struct sqlite3_vfs { int iVersion; /* Structure version number (currently 2) */ int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ sqlite3_vfs *pNext; /* Next registered VFS */ |
︙ | ︙ | |||
864 865 866 867 868 869 870 | int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); int (*xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ | < | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 | int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); int (*xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** New fields may be appended in figure versions. The iVersion ** value will increment whenever this happens. */ }; |
︙ | ︙ |
Changes to src/stat.c.
︙ | ︙ | |||
59 60 61 62 63 64 65 | b = 1; } a = t/fsize; @ %d(a):%d(b) @ </td></tr> } @ <tr><th>Number Of Check-ins:</th><td> | | | | > | > | > > > > > > > > > > > > > > > > > | 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 | b = 1; } a = t/fsize; @ %d(a):%d(b) @ </td></tr> } @ <tr><th>Number Of Check-ins:</th><td> n = db_int(0, "SELECT count(distinct mid) FROM mlink /*scan*/"); @ %d(n) @ </td></tr> @ <tr><th>Number Of Files:</th><td> n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); @ %d(n) @ </td></tr> @ <tr><th>Number Of Wiki Pages:</th><td> n = db_int(0, "SELECT count(*) FROM tag /*scan*/" " WHERE +tagname GLOB 'wiki-*'"); @ %d(n) @ </td></tr> @ <tr><th>Number Of Tickets:</th><td> n = db_int(0, "SELECT count(*) FROM tag /*scan*/" " WHERE +tagname GLOB 'tkt-*'"); @ %d(n) @ </td></tr> @ <tr><th>Duration Of Project:</th><td> n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" " + 0.99"); @ %d(n) days @ </td></tr> @ <tr><th>Project ID:</th><td> @ %h(db_get("project-code","")) @ </td></tr> @ <tr><th>Server ID:</th><td> @ %h(db_get("server-code","")) @ </td></tr> @ <tr><th>Fossil Version:</th><td> @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) @ </td></tr> @ <tr><th>SQLite Version:</th><td> @ %h(db_text(0, "SELECT substr(sqlite_source_id(),1,30)")) @ (%h(SQLITE_VERSION)) @ </td></tr> @ <tr><th>Database Stats:</th><td> @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages, @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page, @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages, @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)), @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode @ </td></tr> @ </table></p> style_footer(); } |
Changes to src/sync.c.
︙ | ︙ | |||
97 98 99 100 101 102 103 | zUrl = db_get("last-sync-url", 0); zPw = db_get("last-sync-pw", 0); if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN; }else if( g.argc==3 ){ zUrl = g.argv[2]; } if( zUrl==0 ){ | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | zUrl = db_get("last-sync-url", 0); zPw = db_get("last-sync-pw", 0); if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN; }else if( g.argc==3 ){ zUrl = g.argv[2]; } if( zUrl==0 ){ if( urlOptional ) fossil_exit(0); usage("URL"); } url_parse(zUrl); if( !g.dontKeepUrl ){ db_set("last-sync-url", g.urlCanonical, 0); if( g.urlPasswd ) db_set("last-sync-pw", g.urlPasswd, 0); } |
︙ | ︙ |