Fossil SCM
merge trunk
Commit
f332f83b15e573543bb573dcbbeb89a31215616c
Parent
fb90d6c657c9db1…
34 files changed
+1
-1
+13
-5
+13
-5
+6
-6
+8
+8
+1
-1
+4
-4
+1
-1
+4
-4
+5
-5
+7
-2
+5
-5
+1
-1
+3
-3
+6
-6
+1
-1
+8
-9
+2
-2
+2
-2
+259
-129
+317
-203
+13
-5
+18
+5
-5
+17
-17
+2
-2
+2
-2
+2
-2
+1
-1
+1
-1
+2
-2
+2
-1
+3
-1
~
src/branch.c
~
src/checkin.c
~
src/checkin.c
~
src/clone.c
~
src/db.c
~
src/db.c
~
src/deltacmd.c
~
src/export.c
~
src/finfo.c
~
src/fusefs.c
~
src/graph.c
~
src/http.c
~
src/leaf.c
~
src/login.c
~
src/makemake.tcl
~
src/merge.c
~
src/mkbuiltin.c
~
src/report.c
~
src/search.c
~
src/setup.c
~
src/shell.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/style.c
~
src/sync.c
~
src/update.c
~
src/verify.c
~
win/Makefile.mingw
~
win/Makefile.mingw.mistachkin
~
win/Makefile.msc
~
www/build.wiki
~
www/delta_format.wiki
~
www/hints.wiki
~
www/qandc.wiki
+1
-1
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -379,11 +379,11 @@ | ||
| 379 | 379 | } |
| 380 | 380 | @ </tr> |
| 381 | 381 | } |
| 382 | 382 | @ </tbody></table></div> |
| 383 | 383 | db_finalize(&q); |
| 384 | - output_table_sorting_javascript("branchlisttable","tkktx",2); | |
| 384 | + output_table_sorting_javascript("branchlisttable","tkktt",2); | |
| 385 | 385 | style_footer(); |
| 386 | 386 | } |
| 387 | 387 | |
| 388 | 388 | /* |
| 389 | 389 | ** WEBPAGE: brlist |
| 390 | 390 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -379,11 +379,11 @@ | |
| 379 | } |
| 380 | @ </tr> |
| 381 | } |
| 382 | @ </tbody></table></div> |
| 383 | db_finalize(&q); |
| 384 | output_table_sorting_javascript("branchlisttable","tkktx",2); |
| 385 | style_footer(); |
| 386 | } |
| 387 | |
| 388 | /* |
| 389 | ** WEBPAGE: brlist |
| 390 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -379,11 +379,11 @@ | |
| 379 | } |
| 380 | @ </tr> |
| 381 | } |
| 382 | @ </tbody></table></div> |
| 383 | db_finalize(&q); |
| 384 | output_table_sorting_javascript("branchlisttable","tkktt",2); |
| 385 | style_footer(); |
| 386 | } |
| 387 | |
| 388 | /* |
| 389 | ** WEBPAGE: brlist |
| 390 |
+13
-5
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -213,11 +213,11 @@ | ||
| 213 | 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | 215 | int cwdRelative = 0; |
| 216 | 216 | db_must_be_within_tree(); |
| 217 | 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | - | |
| 218 | + | |
| 219 | 219 | /* We should be done with options.. */ |
| 220 | 220 | verify_all_options(); |
| 221 | 221 | |
| 222 | 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | 223 | } |
| @@ -249,11 +249,11 @@ | ||
| 249 | 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | 250 | int cwdRelative = 0; |
| 251 | 251 | db_must_be_within_tree(); |
| 252 | 252 | /* 012345678901234 */ |
| 253 | 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | - | |
| 254 | + | |
| 255 | 255 | /* We should be done with options.. */ |
| 256 | 256 | verify_all_options(); |
| 257 | 257 | |
| 258 | 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| @@ -262,11 +262,11 @@ | ||
| 262 | 262 | } |
| 263 | 263 | vid = db_lget_int("checkout", 0); |
| 264 | 264 | if( vid ){ |
| 265 | 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | 266 | } |
| 267 | - db_record_repository_filename(0); | |
| 267 | + db_record_repository_filename(0); | |
| 268 | 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | 271 | /* |
| 272 | 272 | ** COMMAND: ls |
| @@ -480,11 +480,11 @@ | ||
| 480 | 480 | const char *zPathname, *zDisplayName; |
| 481 | 481 | |
| 482 | 482 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 483 | 483 | db_must_be_within_tree(); |
| 484 | 484 | cwdRelative = determine_cwd_relative_option(); |
| 485 | - | |
| 485 | + | |
| 486 | 486 | /* We should be done with options.. */ |
| 487 | 487 | verify_all_options(); |
| 488 | 488 | |
| 489 | 489 | if( zIgnoreFlag==0 ){ |
| 490 | 490 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -498,10 +498,11 @@ | ||
| 498 | 498 | " ORDER BY 1", |
| 499 | 499 | fossil_all_reserved_names(0) |
| 500 | 500 | ); |
| 501 | 501 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 502 | 502 | blob_zero(&rewrittenPathname); |
| 503 | + g.allowSymlinks = 1; /* Report on symbolic links */ | |
| 503 | 504 | while( db_step(&q)==SQLITE_ROW ){ |
| 504 | 505 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 505 | 506 | if( cwdRelative ) { |
| 506 | 507 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 507 | 508 | file_relative_name(zFullName, &rewrittenPathname, 0); |
| @@ -563,10 +564,11 @@ | ||
| 563 | 564 | ** argument. Matching files, if any, are removed |
| 564 | 565 | ** prior to checking for any empty directories; |
| 565 | 566 | ** therefore, directories that contain only files |
| 566 | 567 | ** that were removed will be removed as well. |
| 567 | 568 | ** -f|--force Remove files without prompting. |
| 569 | +** --verily Shorthand for: -f --emptydirs --dotfiles | |
| 568 | 570 | ** --clean <CSG> Never prompt for files matching this |
| 569 | 571 | ** comma separated list of glob patterns. |
| 570 | 572 | ** --ignore <CSG> Ignore files matching patterns from the |
| 571 | 573 | ** comma separated list of glob patterns. |
| 572 | 574 | ** --keep <CSG> Keep files matching this comma separated |
| @@ -601,10 +603,15 @@ | ||
| 601 | 603 | zIgnoreFlag = find_option("ignore",0,1); |
| 602 | 604 | verboseFlag = find_option("verbose","v",0)!=0; |
| 603 | 605 | zKeepFlag = find_option("keep",0,1); |
| 604 | 606 | zCleanFlag = find_option("clean",0,1); |
| 605 | 607 | db_must_be_within_tree(); |
| 608 | + if( find_option("verily",0,0)!=0 ){ | |
| 609 | + allFileFlag = allDirFlag = 1; | |
| 610 | + emptyDirsFlag = 1; | |
| 611 | + scanFlags |= SCAN_ALL; | |
| 612 | + } | |
| 606 | 613 | if( zIgnoreFlag==0 ){ |
| 607 | 614 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 608 | 615 | } |
| 609 | 616 | if( zKeepFlag==0 ){ |
| 610 | 617 | zKeepFlag = db_get("keep-glob", 0); |
| @@ -615,10 +622,11 @@ | ||
| 615 | 622 | verify_all_options(); |
| 616 | 623 | pIgnore = glob_create(zIgnoreFlag); |
| 617 | 624 | pKeep = glob_create(zKeepFlag); |
| 618 | 625 | pClean = glob_create(zCleanFlag); |
| 619 | 626 | nRoot = (int)strlen(g.zLocalRoot); |
| 627 | + g.allowSymlinks = 1; /* Find symlinks too */ | |
| 620 | 628 | if( !dirsOnlyFlag ){ |
| 621 | 629 | Stmt q; |
| 622 | 630 | Blob repo; |
| 623 | 631 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| 624 | 632 | db_prepare(&q, |
| @@ -1720,11 +1728,11 @@ | ||
| 1720 | 1728 | |
| 1721 | 1729 | /* |
| 1722 | 1730 | ** Do not allow a commit against a closed leaf unless the commit |
| 1723 | 1731 | ** ends up on a different branch. |
| 1724 | 1732 | */ |
| 1725 | - if( | |
| 1733 | + if( | |
| 1726 | 1734 | /* parent checkin has the "closed" tag... */ |
| 1727 | 1735 | db_exists("SELECT 1 FROM tagxref" |
| 1728 | 1736 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1729 | 1737 | TAG_CLOSED, vid) |
| 1730 | 1738 | /* ... and the new checkin has no --branch option or the --branch |
| 1731 | 1739 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -213,11 +213,11 @@ | |
| 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | int cwdRelative = 0; |
| 216 | db_must_be_within_tree(); |
| 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | |
| 219 | /* We should be done with options.. */ |
| 220 | verify_all_options(); |
| 221 | |
| 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | } |
| @@ -249,11 +249,11 @@ | |
| 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | int cwdRelative = 0; |
| 251 | db_must_be_within_tree(); |
| 252 | /* 012345678901234 */ |
| 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | |
| 255 | /* We should be done with options.. */ |
| 256 | verify_all_options(); |
| 257 | |
| 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| @@ -262,11 +262,11 @@ | |
| 262 | } |
| 263 | vid = db_lget_int("checkout", 0); |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** COMMAND: ls |
| @@ -480,11 +480,11 @@ | |
| 480 | const char *zPathname, *zDisplayName; |
| 481 | |
| 482 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 483 | db_must_be_within_tree(); |
| 484 | cwdRelative = determine_cwd_relative_option(); |
| 485 | |
| 486 | /* We should be done with options.. */ |
| 487 | verify_all_options(); |
| 488 | |
| 489 | if( zIgnoreFlag==0 ){ |
| 490 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -498,10 +498,11 @@ | |
| 498 | " ORDER BY 1", |
| 499 | fossil_all_reserved_names(0) |
| 500 | ); |
| 501 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 502 | blob_zero(&rewrittenPathname); |
| 503 | while( db_step(&q)==SQLITE_ROW ){ |
| 504 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 505 | if( cwdRelative ) { |
| 506 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 507 | file_relative_name(zFullName, &rewrittenPathname, 0); |
| @@ -563,10 +564,11 @@ | |
| 563 | ** argument. Matching files, if any, are removed |
| 564 | ** prior to checking for any empty directories; |
| 565 | ** therefore, directories that contain only files |
| 566 | ** that were removed will be removed as well. |
| 567 | ** -f|--force Remove files without prompting. |
| 568 | ** --clean <CSG> Never prompt for files matching this |
| 569 | ** comma separated list of glob patterns. |
| 570 | ** --ignore <CSG> Ignore files matching patterns from the |
| 571 | ** comma separated list of glob patterns. |
| 572 | ** --keep <CSG> Keep files matching this comma separated |
| @@ -601,10 +603,15 @@ | |
| 601 | zIgnoreFlag = find_option("ignore",0,1); |
| 602 | verboseFlag = find_option("verbose","v",0)!=0; |
| 603 | zKeepFlag = find_option("keep",0,1); |
| 604 | zCleanFlag = find_option("clean",0,1); |
| 605 | db_must_be_within_tree(); |
| 606 | if( zIgnoreFlag==0 ){ |
| 607 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 608 | } |
| 609 | if( zKeepFlag==0 ){ |
| 610 | zKeepFlag = db_get("keep-glob", 0); |
| @@ -615,10 +622,11 @@ | |
| 615 | verify_all_options(); |
| 616 | pIgnore = glob_create(zIgnoreFlag); |
| 617 | pKeep = glob_create(zKeepFlag); |
| 618 | pClean = glob_create(zCleanFlag); |
| 619 | nRoot = (int)strlen(g.zLocalRoot); |
| 620 | if( !dirsOnlyFlag ){ |
| 621 | Stmt q; |
| 622 | Blob repo; |
| 623 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| 624 | db_prepare(&q, |
| @@ -1720,11 +1728,11 @@ | |
| 1720 | |
| 1721 | /* |
| 1722 | ** Do not allow a commit against a closed leaf unless the commit |
| 1723 | ** ends up on a different branch. |
| 1724 | */ |
| 1725 | if( |
| 1726 | /* parent checkin has the "closed" tag... */ |
| 1727 | db_exists("SELECT 1 FROM tagxref" |
| 1728 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1729 | TAG_CLOSED, vid) |
| 1730 | /* ... and the new checkin has no --branch option or the --branch |
| 1731 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -213,11 +213,11 @@ | |
| 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | int cwdRelative = 0; |
| 216 | db_must_be_within_tree(); |
| 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | |
| 219 | /* We should be done with options.. */ |
| 220 | verify_all_options(); |
| 221 | |
| 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | } |
| @@ -249,11 +249,11 @@ | |
| 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | int cwdRelative = 0; |
| 251 | db_must_be_within_tree(); |
| 252 | /* 012345678901234 */ |
| 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | |
| 255 | /* We should be done with options.. */ |
| 256 | verify_all_options(); |
| 257 | |
| 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| @@ -262,11 +262,11 @@ | |
| 262 | } |
| 263 | vid = db_lget_int("checkout", 0); |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** COMMAND: ls |
| @@ -480,11 +480,11 @@ | |
| 480 | const char *zPathname, *zDisplayName; |
| 481 | |
| 482 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 483 | db_must_be_within_tree(); |
| 484 | cwdRelative = determine_cwd_relative_option(); |
| 485 | |
| 486 | /* We should be done with options.. */ |
| 487 | verify_all_options(); |
| 488 | |
| 489 | if( zIgnoreFlag==0 ){ |
| 490 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -498,10 +498,11 @@ | |
| 498 | " ORDER BY 1", |
| 499 | fossil_all_reserved_names(0) |
| 500 | ); |
| 501 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 502 | blob_zero(&rewrittenPathname); |
| 503 | g.allowSymlinks = 1; /* Report on symbolic links */ |
| 504 | while( db_step(&q)==SQLITE_ROW ){ |
| 505 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 506 | if( cwdRelative ) { |
| 507 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 508 | file_relative_name(zFullName, &rewrittenPathname, 0); |
| @@ -563,10 +564,11 @@ | |
| 564 | ** argument. Matching files, if any, are removed |
| 565 | ** prior to checking for any empty directories; |
| 566 | ** therefore, directories that contain only files |
| 567 | ** that were removed will be removed as well. |
| 568 | ** -f|--force Remove files without prompting. |
| 569 | ** --verily Shorthand for: -f --emptydirs --dotfiles |
| 570 | ** --clean <CSG> Never prompt for files matching this |
| 571 | ** comma separated list of glob patterns. |
| 572 | ** --ignore <CSG> Ignore files matching patterns from the |
| 573 | ** comma separated list of glob patterns. |
| 574 | ** --keep <CSG> Keep files matching this comma separated |
| @@ -601,10 +603,15 @@ | |
| 603 | zIgnoreFlag = find_option("ignore",0,1); |
| 604 | verboseFlag = find_option("verbose","v",0)!=0; |
| 605 | zKeepFlag = find_option("keep",0,1); |
| 606 | zCleanFlag = find_option("clean",0,1); |
| 607 | db_must_be_within_tree(); |
| 608 | if( find_option("verily",0,0)!=0 ){ |
| 609 | allFileFlag = allDirFlag = 1; |
| 610 | emptyDirsFlag = 1; |
| 611 | scanFlags |= SCAN_ALL; |
| 612 | } |
| 613 | if( zIgnoreFlag==0 ){ |
| 614 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 615 | } |
| 616 | if( zKeepFlag==0 ){ |
| 617 | zKeepFlag = db_get("keep-glob", 0); |
| @@ -615,10 +622,11 @@ | |
| 622 | verify_all_options(); |
| 623 | pIgnore = glob_create(zIgnoreFlag); |
| 624 | pKeep = glob_create(zKeepFlag); |
| 625 | pClean = glob_create(zCleanFlag); |
| 626 | nRoot = (int)strlen(g.zLocalRoot); |
| 627 | g.allowSymlinks = 1; /* Find symlinks too */ |
| 628 | if( !dirsOnlyFlag ){ |
| 629 | Stmt q; |
| 630 | Blob repo; |
| 631 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| 632 | db_prepare(&q, |
| @@ -1720,11 +1728,11 @@ | |
| 1728 | |
| 1729 | /* |
| 1730 | ** Do not allow a commit against a closed leaf unless the commit |
| 1731 | ** ends up on a different branch. |
| 1732 | */ |
| 1733 | if( |
| 1734 | /* parent checkin has the "closed" tag... */ |
| 1735 | db_exists("SELECT 1 FROM tagxref" |
| 1736 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1737 | TAG_CLOSED, vid) |
| 1738 | /* ... and the new checkin has no --branch option or the --branch |
| 1739 |
+13
-5
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -213,11 +213,11 @@ | ||
| 213 | 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | 215 | int cwdRelative = 0; |
| 216 | 216 | db_must_be_within_tree(); |
| 217 | 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | - | |
| 218 | + | |
| 219 | 219 | /* We should be done with options.. */ |
| 220 | 220 | verify_all_options(); |
| 221 | 221 | |
| 222 | 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | 223 | } |
| @@ -249,11 +249,11 @@ | ||
| 249 | 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | 250 | int cwdRelative = 0; |
| 251 | 251 | db_must_be_within_tree(); |
| 252 | 252 | /* 012345678901234 */ |
| 253 | 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | - | |
| 254 | + | |
| 255 | 255 | /* We should be done with options.. */ |
| 256 | 256 | verify_all_options(); |
| 257 | 257 | |
| 258 | 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| @@ -262,11 +262,11 @@ | ||
| 262 | 262 | } |
| 263 | 263 | vid = db_lget_int("checkout", 0); |
| 264 | 264 | if( vid ){ |
| 265 | 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | 266 | } |
| 267 | - db_record_repository_filename(0); | |
| 267 | + db_record_repository_filename(0); | |
| 268 | 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | 271 | /* |
| 272 | 272 | ** COMMAND: ls |
| @@ -480,11 +480,11 @@ | ||
| 480 | 480 | const char *zPathname, *zDisplayName; |
| 481 | 481 | |
| 482 | 482 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 483 | 483 | db_must_be_within_tree(); |
| 484 | 484 | cwdRelative = determine_cwd_relative_option(); |
| 485 | - | |
| 485 | + | |
| 486 | 486 | /* We should be done with options.. */ |
| 487 | 487 | verify_all_options(); |
| 488 | 488 | |
| 489 | 489 | if( zIgnoreFlag==0 ){ |
| 490 | 490 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -498,10 +498,11 @@ | ||
| 498 | 498 | " ORDER BY 1", |
| 499 | 499 | fossil_all_reserved_names(0) |
| 500 | 500 | ); |
| 501 | 501 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 502 | 502 | blob_zero(&rewrittenPathname); |
| 503 | + g.allowSymlinks = 1; /* Report on symbolic links */ | |
| 503 | 504 | while( db_step(&q)==SQLITE_ROW ){ |
| 504 | 505 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 505 | 506 | if( cwdRelative ) { |
| 506 | 507 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 507 | 508 | file_relative_name(zFullName, &rewrittenPathname, 0); |
| @@ -563,10 +564,11 @@ | ||
| 563 | 564 | ** argument. Matching files, if any, are removed |
| 564 | 565 | ** prior to checking for any empty directories; |
| 565 | 566 | ** therefore, directories that contain only files |
| 566 | 567 | ** that were removed will be removed as well. |
| 567 | 568 | ** -f|--force Remove files without prompting. |
| 569 | +** --verily Shorthand for: -f --emptydirs --dotfiles | |
| 568 | 570 | ** --clean <CSG> Never prompt for files matching this |
| 569 | 571 | ** comma separated list of glob patterns. |
| 570 | 572 | ** --ignore <CSG> Ignore files matching patterns from the |
| 571 | 573 | ** comma separated list of glob patterns. |
| 572 | 574 | ** --keep <CSG> Keep files matching this comma separated |
| @@ -601,10 +603,15 @@ | ||
| 601 | 603 | zIgnoreFlag = find_option("ignore",0,1); |
| 602 | 604 | verboseFlag = find_option("verbose","v",0)!=0; |
| 603 | 605 | zKeepFlag = find_option("keep",0,1); |
| 604 | 606 | zCleanFlag = find_option("clean",0,1); |
| 605 | 607 | db_must_be_within_tree(); |
| 608 | + if( find_option("verily",0,0)!=0 ){ | |
| 609 | + allFileFlag = allDirFlag = 1; | |
| 610 | + emptyDirsFlag = 1; | |
| 611 | + scanFlags |= SCAN_ALL; | |
| 612 | + } | |
| 606 | 613 | if( zIgnoreFlag==0 ){ |
| 607 | 614 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 608 | 615 | } |
| 609 | 616 | if( zKeepFlag==0 ){ |
| 610 | 617 | zKeepFlag = db_get("keep-glob", 0); |
| @@ -615,10 +622,11 @@ | ||
| 615 | 622 | verify_all_options(); |
| 616 | 623 | pIgnore = glob_create(zIgnoreFlag); |
| 617 | 624 | pKeep = glob_create(zKeepFlag); |
| 618 | 625 | pClean = glob_create(zCleanFlag); |
| 619 | 626 | nRoot = (int)strlen(g.zLocalRoot); |
| 627 | + g.allowSymlinks = 1; /* Find symlinks too */ | |
| 620 | 628 | if( !dirsOnlyFlag ){ |
| 621 | 629 | Stmt q; |
| 622 | 630 | Blob repo; |
| 623 | 631 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| 624 | 632 | db_prepare(&q, |
| @@ -1720,11 +1728,11 @@ | ||
| 1720 | 1728 | |
| 1721 | 1729 | /* |
| 1722 | 1730 | ** Do not allow a commit against a closed leaf unless the commit |
| 1723 | 1731 | ** ends up on a different branch. |
| 1724 | 1732 | */ |
| 1725 | - if( | |
| 1733 | + if( | |
| 1726 | 1734 | /* parent checkin has the "closed" tag... */ |
| 1727 | 1735 | db_exists("SELECT 1 FROM tagxref" |
| 1728 | 1736 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1729 | 1737 | TAG_CLOSED, vid) |
| 1730 | 1738 | /* ... and the new checkin has no --branch option or the --branch |
| 1731 | 1739 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -213,11 +213,11 @@ | |
| 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | int cwdRelative = 0; |
| 216 | db_must_be_within_tree(); |
| 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | |
| 219 | /* We should be done with options.. */ |
| 220 | verify_all_options(); |
| 221 | |
| 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | } |
| @@ -249,11 +249,11 @@ | |
| 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | int cwdRelative = 0; |
| 251 | db_must_be_within_tree(); |
| 252 | /* 012345678901234 */ |
| 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | |
| 255 | /* We should be done with options.. */ |
| 256 | verify_all_options(); |
| 257 | |
| 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| @@ -262,11 +262,11 @@ | |
| 262 | } |
| 263 | vid = db_lget_int("checkout", 0); |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** COMMAND: ls |
| @@ -480,11 +480,11 @@ | |
| 480 | const char *zPathname, *zDisplayName; |
| 481 | |
| 482 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 483 | db_must_be_within_tree(); |
| 484 | cwdRelative = determine_cwd_relative_option(); |
| 485 | |
| 486 | /* We should be done with options.. */ |
| 487 | verify_all_options(); |
| 488 | |
| 489 | if( zIgnoreFlag==0 ){ |
| 490 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -498,10 +498,11 @@ | |
| 498 | " ORDER BY 1", |
| 499 | fossil_all_reserved_names(0) |
| 500 | ); |
| 501 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 502 | blob_zero(&rewrittenPathname); |
| 503 | while( db_step(&q)==SQLITE_ROW ){ |
| 504 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 505 | if( cwdRelative ) { |
| 506 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 507 | file_relative_name(zFullName, &rewrittenPathname, 0); |
| @@ -563,10 +564,11 @@ | |
| 563 | ** argument. Matching files, if any, are removed |
| 564 | ** prior to checking for any empty directories; |
| 565 | ** therefore, directories that contain only files |
| 566 | ** that were removed will be removed as well. |
| 567 | ** -f|--force Remove files without prompting. |
| 568 | ** --clean <CSG> Never prompt for files matching this |
| 569 | ** comma separated list of glob patterns. |
| 570 | ** --ignore <CSG> Ignore files matching patterns from the |
| 571 | ** comma separated list of glob patterns. |
| 572 | ** --keep <CSG> Keep files matching this comma separated |
| @@ -601,10 +603,15 @@ | |
| 601 | zIgnoreFlag = find_option("ignore",0,1); |
| 602 | verboseFlag = find_option("verbose","v",0)!=0; |
| 603 | zKeepFlag = find_option("keep",0,1); |
| 604 | zCleanFlag = find_option("clean",0,1); |
| 605 | db_must_be_within_tree(); |
| 606 | if( zIgnoreFlag==0 ){ |
| 607 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 608 | } |
| 609 | if( zKeepFlag==0 ){ |
| 610 | zKeepFlag = db_get("keep-glob", 0); |
| @@ -615,10 +622,11 @@ | |
| 615 | verify_all_options(); |
| 616 | pIgnore = glob_create(zIgnoreFlag); |
| 617 | pKeep = glob_create(zKeepFlag); |
| 618 | pClean = glob_create(zCleanFlag); |
| 619 | nRoot = (int)strlen(g.zLocalRoot); |
| 620 | if( !dirsOnlyFlag ){ |
| 621 | Stmt q; |
| 622 | Blob repo; |
| 623 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| 624 | db_prepare(&q, |
| @@ -1720,11 +1728,11 @@ | |
| 1720 | |
| 1721 | /* |
| 1722 | ** Do not allow a commit against a closed leaf unless the commit |
| 1723 | ** ends up on a different branch. |
| 1724 | */ |
| 1725 | if( |
| 1726 | /* parent checkin has the "closed" tag... */ |
| 1727 | db_exists("SELECT 1 FROM tagxref" |
| 1728 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1729 | TAG_CLOSED, vid) |
| 1730 | /* ... and the new checkin has no --branch option or the --branch |
| 1731 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -213,11 +213,11 @@ | |
| 213 | int showHdr = find_option("header",0,0)!=0; |
| 214 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 215 | int cwdRelative = 0; |
| 216 | db_must_be_within_tree(); |
| 217 | cwdRelative = determine_cwd_relative_option(); |
| 218 | |
| 219 | /* We should be done with options.. */ |
| 220 | verify_all_options(); |
| 221 | |
| 222 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 223 | } |
| @@ -249,11 +249,11 @@ | |
| 249 | int verboseFlag = find_option("verbose","v",0)!=0; |
| 250 | int cwdRelative = 0; |
| 251 | db_must_be_within_tree(); |
| 252 | /* 012345678901234 */ |
| 253 | cwdRelative = determine_cwd_relative_option(); |
| 254 | |
| 255 | /* We should be done with options.. */ |
| 256 | verify_all_options(); |
| 257 | |
| 258 | fossil_print("repository: %s\n", db_repository_filename()); |
| 259 | fossil_print("local-root: %s\n", g.zLocalRoot); |
| @@ -262,11 +262,11 @@ | |
| 262 | } |
| 263 | vid = db_lget_int("checkout", 0); |
| 264 | if( vid ){ |
| 265 | show_common_info(vid, "checkout:", 1, 1); |
| 266 | } |
| 267 | db_record_repository_filename(0); |
| 268 | print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative); |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | ** COMMAND: ls |
| @@ -480,11 +480,11 @@ | |
| 480 | const char *zPathname, *zDisplayName; |
| 481 | |
| 482 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 483 | db_must_be_within_tree(); |
| 484 | cwdRelative = determine_cwd_relative_option(); |
| 485 | |
| 486 | /* We should be done with options.. */ |
| 487 | verify_all_options(); |
| 488 | |
| 489 | if( zIgnoreFlag==0 ){ |
| 490 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -498,10 +498,11 @@ | |
| 498 | " ORDER BY 1", |
| 499 | fossil_all_reserved_names(0) |
| 500 | ); |
| 501 | db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)"); |
| 502 | blob_zero(&rewrittenPathname); |
| 503 | g.allowSymlinks = 1; /* Report on symbolic links */ |
| 504 | while( db_step(&q)==SQLITE_ROW ){ |
| 505 | zDisplayName = zPathname = db_column_text(&q, 0); |
| 506 | if( cwdRelative ) { |
| 507 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 508 | file_relative_name(zFullName, &rewrittenPathname, 0); |
| @@ -563,10 +564,11 @@ | |
| 564 | ** argument. Matching files, if any, are removed |
| 565 | ** prior to checking for any empty directories; |
| 566 | ** therefore, directories that contain only files |
| 567 | ** that were removed will be removed as well. |
| 568 | ** -f|--force Remove files without prompting. |
| 569 | ** --verily Shorthand for: -f --emptydirs --dotfiles |
| 570 | ** --clean <CSG> Never prompt for files matching this |
| 571 | ** comma separated list of glob patterns. |
| 572 | ** --ignore <CSG> Ignore files matching patterns from the |
| 573 | ** comma separated list of glob patterns. |
| 574 | ** --keep <CSG> Keep files matching this comma separated |
| @@ -601,10 +603,15 @@ | |
| 603 | zIgnoreFlag = find_option("ignore",0,1); |
| 604 | verboseFlag = find_option("verbose","v",0)!=0; |
| 605 | zKeepFlag = find_option("keep",0,1); |
| 606 | zCleanFlag = find_option("clean",0,1); |
| 607 | db_must_be_within_tree(); |
| 608 | if( find_option("verily",0,0)!=0 ){ |
| 609 | allFileFlag = allDirFlag = 1; |
| 610 | emptyDirsFlag = 1; |
| 611 | scanFlags |= SCAN_ALL; |
| 612 | } |
| 613 | if( zIgnoreFlag==0 ){ |
| 614 | zIgnoreFlag = db_get("ignore-glob", 0); |
| 615 | } |
| 616 | if( zKeepFlag==0 ){ |
| 617 | zKeepFlag = db_get("keep-glob", 0); |
| @@ -615,10 +622,11 @@ | |
| 622 | verify_all_options(); |
| 623 | pIgnore = glob_create(zIgnoreFlag); |
| 624 | pKeep = glob_create(zKeepFlag); |
| 625 | pClean = glob_create(zCleanFlag); |
| 626 | nRoot = (int)strlen(g.zLocalRoot); |
| 627 | g.allowSymlinks = 1; /* Find symlinks too */ |
| 628 | if( !dirsOnlyFlag ){ |
| 629 | Stmt q; |
| 630 | Blob repo; |
| 631 | locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0); |
| 632 | db_prepare(&q, |
| @@ -1720,11 +1728,11 @@ | |
| 1728 | |
| 1729 | /* |
| 1730 | ** Do not allow a commit against a closed leaf unless the commit |
| 1731 | ** ends up on a different branch. |
| 1732 | */ |
| 1733 | if( |
| 1734 | /* parent checkin has the "closed" tag... */ |
| 1735 | db_exists("SELECT 1 FROM tagxref" |
| 1736 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1737 | TAG_CLOSED, vid) |
| 1738 | /* ... and the new checkin has no --branch option or the --branch |
| 1739 |
+6
-6
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -83,11 +83,11 @@ | ||
| 83 | 83 | ** COMMAND: clone |
| 84 | 84 | ** |
| 85 | 85 | ** Usage: %fossil clone ?OPTIONS? URL FILENAME |
| 86 | 86 | ** |
| 87 | 87 | ** Make a clone of a repository specified by URL in the local |
| 88 | -** file named FILENAME. | |
| 88 | +** file named FILENAME. | |
| 89 | 89 | ** |
| 90 | 90 | ** URL must be in one of the following form: ([...] mean optional) |
| 91 | 91 | ** HTTP/HTTPS protocol: |
| 92 | 92 | ** http[s]://[userid[:password]@]host[:port][/path] |
| 93 | 93 | ** |
| @@ -96,21 +96,21 @@ | ||
| 96 | 96 | ** [?fossil=path/to/fossil.exe] |
| 97 | 97 | ** |
| 98 | 98 | ** Filesystem: |
| 99 | 99 | ** [file://]path/to/repo.fossil |
| 100 | 100 | ** |
| 101 | -** Note: For ssh and filesystem, path must have an extra leading | |
| 101 | +** Note: For ssh and filesystem, path must have an extra leading | |
| 102 | 102 | ** '/' to use an absolute path. |
| 103 | 103 | ** |
| 104 | 104 | ** By default, your current login name is used to create the default |
| 105 | 105 | ** admin user. This can be overridden using the -A|--admin-user |
| 106 | 106 | ** parameter. |
| 107 | 107 | ** |
| 108 | 108 | ** Options: |
| 109 | 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | 110 | ** --once Don't save url. |
| 111 | -** --private Also clone private branches | |
| 111 | +** --private Also clone private branches | |
| 112 | 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | 113 | ** --ssh-command|-c 'command' Use this SSH command |
| 114 | 114 | ** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests |
| 115 | 115 | ** --verbose Show more statistics in output |
| 116 | 116 | ** |
| @@ -130,11 +130,11 @@ | ||
| 130 | 130 | if( find_option("verbose",0,0)!=0) syncFlags |= SYNC_VERBOSE; |
| 131 | 131 | zHttpAuth = find_option("httpauth","B",1); |
| 132 | 132 | zDefaultUser = find_option("admin-user","A",1); |
| 133 | 133 | clone_ssh_find_options(); |
| 134 | 134 | url_proxy_options(); |
| 135 | - | |
| 135 | + | |
| 136 | 136 | /* We should be done with options.. */ |
| 137 | 137 | verify_all_options(); |
| 138 | 138 | |
| 139 | 139 | if( g.argc < 4 ){ |
| 140 | 140 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| @@ -210,11 +210,11 @@ | ||
| 210 | 210 | db_end_transaction(0); |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | /* |
| 214 | 214 | ** If user chooses to use HTTP Authentication over unencrypted HTTP, |
| 215 | -** remember decision. Otherwise, if the URL is being changed and no | |
| 215 | +** remember decision. Otherwise, if the URL is being changed and no | |
| 216 | 216 | ** preference has been indicated, err on the safe side and revert the |
| 217 | 217 | ** decision. Set the global preference if the URL is not being changed. |
| 218 | 218 | */ |
| 219 | 219 | void remember_or_get_http_auth( |
| 220 | 220 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| @@ -269,13 +269,13 @@ | ||
| 269 | 269 | g.zSshCmd = mprintf("%s", zSshCmd); |
| 270 | 270 | } |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | 273 | /* |
| 274 | -** Set SSH options discovered in global variables (set from command line | |
| 274 | +** Set SSH options discovered in global variables (set from command line | |
| 275 | 275 | ** options). |
| 276 | 276 | */ |
| 277 | 277 | void clone_ssh_db_set_options(void){ |
| 278 | 278 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 279 | 279 | db_set("ssh-command", g.zSshCmd, 0); |
| 280 | 280 | } |
| 281 | 281 | } |
| 282 | 282 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -83,11 +83,11 @@ | |
| 83 | ** COMMAND: clone |
| 84 | ** |
| 85 | ** Usage: %fossil clone ?OPTIONS? URL FILENAME |
| 86 | ** |
| 87 | ** Make a clone of a repository specified by URL in the local |
| 88 | ** file named FILENAME. |
| 89 | ** |
| 90 | ** URL must be in one of the following form: ([...] mean optional) |
| 91 | ** HTTP/HTTPS protocol: |
| 92 | ** http[s]://[userid[:password]@]host[:port][/path] |
| 93 | ** |
| @@ -96,21 +96,21 @@ | |
| 96 | ** [?fossil=path/to/fossil.exe] |
| 97 | ** |
| 98 | ** Filesystem: |
| 99 | ** [file://]path/to/repo.fossil |
| 100 | ** |
| 101 | ** Note: For ssh and filesystem, path must have an extra leading |
| 102 | ** '/' to use an absolute path. |
| 103 | ** |
| 104 | ** By default, your current login name is used to create the default |
| 105 | ** admin user. This can be overridden using the -A|--admin-user |
| 106 | ** parameter. |
| 107 | ** |
| 108 | ** Options: |
| 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | ** --once Don't save url. |
| 111 | ** --private Also clone private branches |
| 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | ** --ssh-command|-c 'command' Use this SSH command |
| 114 | ** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests |
| 115 | ** --verbose Show more statistics in output |
| 116 | ** |
| @@ -130,11 +130,11 @@ | |
| 130 | if( find_option("verbose",0,0)!=0) syncFlags |= SYNC_VERBOSE; |
| 131 | zHttpAuth = find_option("httpauth","B",1); |
| 132 | zDefaultUser = find_option("admin-user","A",1); |
| 133 | clone_ssh_find_options(); |
| 134 | url_proxy_options(); |
| 135 | |
| 136 | /* We should be done with options.. */ |
| 137 | verify_all_options(); |
| 138 | |
| 139 | if( g.argc < 4 ){ |
| 140 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| @@ -210,11 +210,11 @@ | |
| 210 | db_end_transaction(0); |
| 211 | } |
| 212 | |
| 213 | /* |
| 214 | ** If user chooses to use HTTP Authentication over unencrypted HTTP, |
| 215 | ** remember decision. Otherwise, if the URL is being changed and no |
| 216 | ** preference has been indicated, err on the safe side and revert the |
| 217 | ** decision. Set the global preference if the URL is not being changed. |
| 218 | */ |
| 219 | void remember_or_get_http_auth( |
| 220 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| @@ -269,13 +269,13 @@ | |
| 269 | g.zSshCmd = mprintf("%s", zSshCmd); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | /* |
| 274 | ** Set SSH options discovered in global variables (set from command line |
| 275 | ** options). |
| 276 | */ |
| 277 | void clone_ssh_db_set_options(void){ |
| 278 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 279 | db_set("ssh-command", g.zSshCmd, 0); |
| 280 | } |
| 281 | } |
| 282 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -83,11 +83,11 @@ | |
| 83 | ** COMMAND: clone |
| 84 | ** |
| 85 | ** Usage: %fossil clone ?OPTIONS? URL FILENAME |
| 86 | ** |
| 87 | ** Make a clone of a repository specified by URL in the local |
| 88 | ** file named FILENAME. |
| 89 | ** |
| 90 | ** URL must be in one of the following form: ([...] mean optional) |
| 91 | ** HTTP/HTTPS protocol: |
| 92 | ** http[s]://[userid[:password]@]host[:port][/path] |
| 93 | ** |
| @@ -96,21 +96,21 @@ | |
| 96 | ** [?fossil=path/to/fossil.exe] |
| 97 | ** |
| 98 | ** Filesystem: |
| 99 | ** [file://]path/to/repo.fossil |
| 100 | ** |
| 101 | ** Note: For ssh and filesystem, path must have an extra leading |
| 102 | ** '/' to use an absolute path. |
| 103 | ** |
| 104 | ** By default, your current login name is used to create the default |
| 105 | ** admin user. This can be overridden using the -A|--admin-user |
| 106 | ** parameter. |
| 107 | ** |
| 108 | ** Options: |
| 109 | ** --admin-user|-A USERNAME Make USERNAME the administrator |
| 110 | ** --once Don't save url. |
| 111 | ** --private Also clone private branches |
| 112 | ** --ssl-identity=filename Use the SSL identity if requested by the server |
| 113 | ** --ssh-command|-c 'command' Use this SSH command |
| 114 | ** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests |
| 115 | ** --verbose Show more statistics in output |
| 116 | ** |
| @@ -130,11 +130,11 @@ | |
| 130 | if( find_option("verbose",0,0)!=0) syncFlags |= SYNC_VERBOSE; |
| 131 | zHttpAuth = find_option("httpauth","B",1); |
| 132 | zDefaultUser = find_option("admin-user","A",1); |
| 133 | clone_ssh_find_options(); |
| 134 | url_proxy_options(); |
| 135 | |
| 136 | /* We should be done with options.. */ |
| 137 | verify_all_options(); |
| 138 | |
| 139 | if( g.argc < 4 ){ |
| 140 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| @@ -210,11 +210,11 @@ | |
| 210 | db_end_transaction(0); |
| 211 | } |
| 212 | |
| 213 | /* |
| 214 | ** If user chooses to use HTTP Authentication over unencrypted HTTP, |
| 215 | ** remember decision. Otherwise, if the URL is being changed and no |
| 216 | ** preference has been indicated, err on the safe side and revert the |
| 217 | ** decision. Set the global preference if the URL is not being changed. |
| 218 | */ |
| 219 | void remember_or_get_http_auth( |
| 220 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| @@ -269,13 +269,13 @@ | |
| 269 | g.zSshCmd = mprintf("%s", zSshCmd); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | /* |
| 274 | ** Set SSH options discovered in global variables (set from command line |
| 275 | ** options). |
| 276 | */ |
| 277 | void clone_ssh_db_set_options(void){ |
| 278 | if( g.zSshCmd && g.zSshCmd[0] ){ |
| 279 | db_set("ssh-command", g.zSshCmd, 0); |
| 280 | } |
| 281 | } |
| 282 |
M
src/db.c
+8
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -735,10 +735,18 @@ | ||
| 735 | 735 | sqlite3_result_int64(context, time(0)); |
| 736 | 736 | } |
| 737 | 737 | |
| 738 | 738 | /* |
| 739 | 739 | ** Function to return the check-in time for a file. |
| 740 | +** | |
| 741 | +** checkin_mtime(CKINID,RID) | |
| 742 | +** | |
| 743 | +** CKINID: The RID for the manifest for a check-in. | |
| 744 | +** RID: The RID of a file in CKINID for which the check-in time | |
| 745 | +** is desired. | |
| 746 | +** | |
| 747 | +** Returns: The check-in time in seconds since 1970. | |
| 740 | 748 | */ |
| 741 | 749 | void db_checkin_mtime_function( |
| 742 | 750 | sqlite3_context *context, |
| 743 | 751 | int argc, |
| 744 | 752 | sqlite3_value **argv |
| 745 | 753 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -735,10 +735,18 @@ | |
| 735 | sqlite3_result_int64(context, time(0)); |
| 736 | } |
| 737 | |
| 738 | /* |
| 739 | ** Function to return the check-in time for a file. |
| 740 | */ |
| 741 | void db_checkin_mtime_function( |
| 742 | sqlite3_context *context, |
| 743 | int argc, |
| 744 | sqlite3_value **argv |
| 745 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -735,10 +735,18 @@ | |
| 735 | sqlite3_result_int64(context, time(0)); |
| 736 | } |
| 737 | |
| 738 | /* |
| 739 | ** Function to return the check-in time for a file. |
| 740 | ** |
| 741 | ** checkin_mtime(CKINID,RID) |
| 742 | ** |
| 743 | ** CKINID: The RID for the manifest for a check-in. |
| 744 | ** RID: The RID of a file in CKINID for which the check-in time |
| 745 | ** is desired. |
| 746 | ** |
| 747 | ** Returns: The check-in time in seconds since 1970. |
| 748 | */ |
| 749 | void db_checkin_mtime_function( |
| 750 | sqlite3_context *context, |
| 751 | int argc, |
| 752 | sqlite3_value **argv |
| 753 |
M
src/db.c
+8
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -735,10 +735,18 @@ | ||
| 735 | 735 | sqlite3_result_int64(context, time(0)); |
| 736 | 736 | } |
| 737 | 737 | |
| 738 | 738 | /* |
| 739 | 739 | ** Function to return the check-in time for a file. |
| 740 | +** | |
| 741 | +** checkin_mtime(CKINID,RID) | |
| 742 | +** | |
| 743 | +** CKINID: The RID for the manifest for a check-in. | |
| 744 | +** RID: The RID of a file in CKINID for which the check-in time | |
| 745 | +** is desired. | |
| 746 | +** | |
| 747 | +** Returns: The check-in time in seconds since 1970. | |
| 740 | 748 | */ |
| 741 | 749 | void db_checkin_mtime_function( |
| 742 | 750 | sqlite3_context *context, |
| 743 | 751 | int argc, |
| 744 | 752 | sqlite3_value **argv |
| 745 | 753 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -735,10 +735,18 @@ | |
| 735 | sqlite3_result_int64(context, time(0)); |
| 736 | } |
| 737 | |
| 738 | /* |
| 739 | ** Function to return the check-in time for a file. |
| 740 | */ |
| 741 | void db_checkin_mtime_function( |
| 742 | sqlite3_context *context, |
| 743 | int argc, |
| 744 | sqlite3_value **argv |
| 745 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -735,10 +735,18 @@ | |
| 735 | sqlite3_result_int64(context, time(0)); |
| 736 | } |
| 737 | |
| 738 | /* |
| 739 | ** Function to return the check-in time for a file. |
| 740 | ** |
| 741 | ** checkin_mtime(CKINID,RID) |
| 742 | ** |
| 743 | ** CKINID: The RID for the manifest for a check-in. |
| 744 | ** RID: The RID of a file in CKINID for which the check-in time |
| 745 | ** is desired. |
| 746 | ** |
| 747 | ** Returns: The check-in time in seconds since 1970. |
| 748 | */ |
| 749 | void db_checkin_mtime_function( |
| 750 | sqlite3_context *context, |
| 751 | int argc, |
| 752 | sqlite3_value **argv |
| 753 |
+1
-1
| --- src/deltacmd.c | ||
| +++ src/deltacmd.c | ||
| @@ -17,11 +17,11 @@ | ||
| 17 | 17 | ** |
| 18 | 18 | ** This module implements the interface to the delta generator. |
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "deltacmd.h" |
| 22 | - | |
| 22 | + | |
| 23 | 23 | /* |
| 24 | 24 | ** Create a delta that describes the change from pOriginal to pTarget |
| 25 | 25 | ** and put that delta in pDelta. The pDelta blob is assumed to be |
| 26 | 26 | ** uninitialized. |
| 27 | 27 | */ |
| 28 | 28 |
| --- src/deltacmd.c | |
| +++ src/deltacmd.c | |
| @@ -17,11 +17,11 @@ | |
| 17 | ** |
| 18 | ** This module implements the interface to the delta generator. |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "deltacmd.h" |
| 22 | |
| 23 | /* |
| 24 | ** Create a delta that describes the change from pOriginal to pTarget |
| 25 | ** and put that delta in pDelta. The pDelta blob is assumed to be |
| 26 | ** uninitialized. |
| 27 | */ |
| 28 |
| --- src/deltacmd.c | |
| +++ src/deltacmd.c | |
| @@ -17,11 +17,11 @@ | |
| 17 | ** |
| 18 | ** This module implements the interface to the delta generator. |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "deltacmd.h" |
| 22 | |
| 23 | /* |
| 24 | ** Create a delta that describes the change from pOriginal to pTarget |
| 25 | ** and put that delta in pDelta. The pDelta blob is assumed to be |
| 26 | ** uninitialized. |
| 27 | */ |
| 28 |
+4
-4
| --- src/export.c | ||
| +++ src/export.c | ||
| @@ -104,18 +104,18 @@ | ||
| 104 | 104 | ** |
| 105 | 105 | ** Usage: %fossil export --git ?OPTIONS? ?REPOSITORY? |
| 106 | 106 | ** |
| 107 | 107 | ** Write an export of all check-ins to standard output. The export is |
| 108 | 108 | ** written in the git-fast-export file format assuming the --git option is |
| 109 | -** provided. The git-fast-export format is currently the only VCS | |
| 109 | +** provided. The git-fast-export format is currently the only VCS | |
| 110 | 110 | ** interchange format supported, though other formats may be added in |
| 111 | 111 | ** the future. |
| 112 | 112 | ** |
| 113 | 113 | ** Run this command within a checkout. Or use the -R or --repository |
| 114 | 114 | ** option to specify a Fossil repository to be exported. |
| 115 | 115 | ** |
| 116 | -** Only check-ins are exported using --git. Git does not support tickets | |
| 116 | +** Only check-ins are exported using --git. Git does not support tickets | |
| 117 | 117 | ** or wiki or events or attachments, so none of those are exported. |
| 118 | 118 | ** |
| 119 | 119 | ** If the "--import-marks FILE" option is used, it contains a list of |
| 120 | 120 | ** rids to skip. |
| 121 | 121 | ** |
| @@ -124,11 +124,11 @@ | ||
| 124 | 124 | ** |
| 125 | 125 | ** Options: |
| 126 | 126 | ** --export-marks FILE export rids of exported data to FILE |
| 127 | 127 | ** --import-marks FILE read rids of data to ignore from FILE |
| 128 | 128 | ** --repository|-R REPOSITORY export the given REPOSITORY |
| 129 | -** | |
| 129 | +** | |
| 130 | 130 | ** See also: import |
| 131 | 131 | */ |
| 132 | 132 | void export_cmd(void){ |
| 133 | 133 | Stmt q, q2, q3; |
| 134 | 134 | int i; |
| @@ -179,11 +179,11 @@ | ||
| 179 | 179 | db_finalize(&qc); |
| 180 | 180 | fclose(f); |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | /* Step 1: Generate "blob" records for every artifact that is part |
| 184 | - ** of a check-in | |
| 184 | + ** of a check-in | |
| 185 | 185 | */ |
| 186 | 186 | fossil_binary_mode(stdout); |
| 187 | 187 | db_multi_exec("CREATE TEMP TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); |
| 188 | 188 | db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); |
| 189 | 189 | db_multi_exec( |
| 190 | 190 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -104,18 +104,18 @@ | |
| 104 | ** |
| 105 | ** Usage: %fossil export --git ?OPTIONS? ?REPOSITORY? |
| 106 | ** |
| 107 | ** Write an export of all check-ins to standard output. The export is |
| 108 | ** written in the git-fast-export file format assuming the --git option is |
| 109 | ** provided. The git-fast-export format is currently the only VCS |
| 110 | ** interchange format supported, though other formats may be added in |
| 111 | ** the future. |
| 112 | ** |
| 113 | ** Run this command within a checkout. Or use the -R or --repository |
| 114 | ** option to specify a Fossil repository to be exported. |
| 115 | ** |
| 116 | ** Only check-ins are exported using --git. Git does not support tickets |
| 117 | ** or wiki or events or attachments, so none of those are exported. |
| 118 | ** |
| 119 | ** If the "--import-marks FILE" option is used, it contains a list of |
| 120 | ** rids to skip. |
| 121 | ** |
| @@ -124,11 +124,11 @@ | |
| 124 | ** |
| 125 | ** Options: |
| 126 | ** --export-marks FILE export rids of exported data to FILE |
| 127 | ** --import-marks FILE read rids of data to ignore from FILE |
| 128 | ** --repository|-R REPOSITORY export the given REPOSITORY |
| 129 | ** |
| 130 | ** See also: import |
| 131 | */ |
| 132 | void export_cmd(void){ |
| 133 | Stmt q, q2, q3; |
| 134 | int i; |
| @@ -179,11 +179,11 @@ | |
| 179 | db_finalize(&qc); |
| 180 | fclose(f); |
| 181 | } |
| 182 | |
| 183 | /* Step 1: Generate "blob" records for every artifact that is part |
| 184 | ** of a check-in |
| 185 | */ |
| 186 | fossil_binary_mode(stdout); |
| 187 | db_multi_exec("CREATE TEMP TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); |
| 188 | db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); |
| 189 | db_multi_exec( |
| 190 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -104,18 +104,18 @@ | |
| 104 | ** |
| 105 | ** Usage: %fossil export --git ?OPTIONS? ?REPOSITORY? |
| 106 | ** |
| 107 | ** Write an export of all check-ins to standard output. The export is |
| 108 | ** written in the git-fast-export file format assuming the --git option is |
| 109 | ** provided. The git-fast-export format is currently the only VCS |
| 110 | ** interchange format supported, though other formats may be added in |
| 111 | ** the future. |
| 112 | ** |
| 113 | ** Run this command within a checkout. Or use the -R or --repository |
| 114 | ** option to specify a Fossil repository to be exported. |
| 115 | ** |
| 116 | ** Only check-ins are exported using --git. Git does not support tickets |
| 117 | ** or wiki or events or attachments, so none of those are exported. |
| 118 | ** |
| 119 | ** If the "--import-marks FILE" option is used, it contains a list of |
| 120 | ** rids to skip. |
| 121 | ** |
| @@ -124,11 +124,11 @@ | |
| 124 | ** |
| 125 | ** Options: |
| 126 | ** --export-marks FILE export rids of exported data to FILE |
| 127 | ** --import-marks FILE read rids of data to ignore from FILE |
| 128 | ** --repository|-R REPOSITORY export the given REPOSITORY |
| 129 | ** |
| 130 | ** See also: import |
| 131 | */ |
| 132 | void export_cmd(void){ |
| 133 | Stmt q, q2, q3; |
| 134 | int i; |
| @@ -179,11 +179,11 @@ | |
| 179 | db_finalize(&qc); |
| 180 | fclose(f); |
| 181 | } |
| 182 | |
| 183 | /* Step 1: Generate "blob" records for every artifact that is part |
| 184 | ** of a check-in |
| 185 | */ |
| 186 | fossil_binary_mode(stdout); |
| 187 | db_multi_exec("CREATE TEMP TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); |
| 188 | db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); |
| 189 | db_multi_exec( |
| 190 |
+1
-1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -250,11 +250,11 @@ | ||
| 250 | 250 | int rc; |
| 251 | 251 | Blob content, fname; |
| 252 | 252 | const char *zRev; |
| 253 | 253 | db_find_and_open_repository(0, 0); |
| 254 | 254 | zRev = find_option("r","r",1); |
| 255 | - | |
| 255 | + | |
| 256 | 256 | /* We should be done with options.. */ |
| 257 | 257 | verify_all_options(); |
| 258 | 258 | |
| 259 | 259 | for(i=2; i<g.argc; i++){ |
| 260 | 260 | file_tree_name(g.argv[i], &fname, 1); |
| 261 | 261 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -250,11 +250,11 @@ | |
| 250 | int rc; |
| 251 | Blob content, fname; |
| 252 | const char *zRev; |
| 253 | db_find_and_open_repository(0, 0); |
| 254 | zRev = find_option("r","r",1); |
| 255 | |
| 256 | /* We should be done with options.. */ |
| 257 | verify_all_options(); |
| 258 | |
| 259 | for(i=2; i<g.argc; i++){ |
| 260 | file_tree_name(g.argv[i], &fname, 1); |
| 261 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -250,11 +250,11 @@ | |
| 250 | int rc; |
| 251 | Blob content, fname; |
| 252 | const char *zRev; |
| 253 | db_find_and_open_repository(0, 0); |
| 254 | zRev = find_option("r","r",1); |
| 255 | |
| 256 | /* We should be done with options.. */ |
| 257 | verify_all_options(); |
| 258 | |
| 259 | for(i=2; i<g.argc; i++){ |
| 260 | file_tree_name(g.argv[i], &fname, 1); |
| 261 |
+4
-4
| --- src/fusefs.c | ||
| +++ src/fusefs.c | ||
| @@ -14,11 +14,11 @@ | ||
| 14 | 14 | ** http://www.hwaci.com/drh/ |
| 15 | 15 | ** |
| 16 | 16 | ******************************************************************************* |
| 17 | 17 | ** |
| 18 | 18 | ** This module implements the userspace side of a Fuse Filesystem that |
| 19 | -** contains all check-ins for a fossil repository. | |
| 19 | +** contains all check-ins for a fossil repository. | |
| 20 | 20 | ** |
| 21 | 21 | ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS. |
| 22 | 22 | ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for |
| 23 | 23 | ** the Fuse Filesystem, of course. |
| 24 | 24 | */ |
| @@ -193,11 +193,11 @@ | ||
| 193 | 193 | int cnt = 0; |
| 194 | 194 | n = fusefs_parse_path(zPath); |
| 195 | 195 | if( n==0 ){ |
| 196 | 196 | filler(buf, ".", NULL, 0); |
| 197 | 197 | filler(buf, "..", NULL, 0); |
| 198 | - filler(buf, "checkins", NULL, 0); | |
| 198 | + filler(buf, "checkins", NULL, 0); | |
| 199 | 199 | return 0; |
| 200 | 200 | } |
| 201 | 201 | if( strcmp(fusefs.az[0],"checkins")!=0 ) return -ENOENT; |
| 202 | 202 | if( n==1 ) return -ENOENT; |
| 203 | 203 | rid = fusefs_name_to_rid(fusefs.az[1]); |
| @@ -275,11 +275,11 @@ | ||
| 275 | 275 | if( offset+size>blob_size(&fusefs.content) ){ |
| 276 | 276 | size = blob_size(&fusefs.content) - offset; |
| 277 | 277 | } |
| 278 | 278 | memcpy(buf, blob_buffer(&fusefs.content)+offset, size); |
| 279 | 279 | return size; |
| 280 | -} | |
| 280 | +} | |
| 281 | 281 | |
| 282 | 282 | static struct fuse_operations fusefs_methods = { |
| 283 | 283 | .getattr = fusefs_getattr, |
| 284 | 284 | .readdir = fusefs_readdir, |
| 285 | 285 | .read = fusefs_read, |
| @@ -293,11 +293,11 @@ | ||
| 293 | 293 | ** |
| 294 | 294 | ** This command uses the Fuse Filesystem to mount a directory at |
| 295 | 295 | ** DIRECTORY that contains the content of all check-ins in the |
| 296 | 296 | ** repository. The names of files are DIRECTORY/checkins/VERSION/PATH |
| 297 | 297 | ** where DIRECTORY is the root of the mount, VERSION is any valid |
| 298 | -** check-in name (examples: "trunk" or "tip" or a tag or any unique | |
| 298 | +** check-in name (examples: "trunk" or "tip" or a tag or any unique | |
| 299 | 299 | ** prefix of a SHA1 hash, etc) and PATH is the pathname of the file |
| 300 | 300 | ** in the checkin. If DIRECTORY does not exist, then an attempt is |
| 301 | 301 | ** made to create it. |
| 302 | 302 | ** |
| 303 | 303 | ** The DIRECTORY/checkins directory is not searchable so one cannot |
| 304 | 304 |
| --- src/fusefs.c | |
| +++ src/fusefs.c | |
| @@ -14,11 +14,11 @@ | |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** This module implements the userspace side of a Fuse Filesystem that |
| 19 | ** contains all check-ins for a fossil repository. |
| 20 | ** |
| 21 | ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS. |
| 22 | ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for |
| 23 | ** the Fuse Filesystem, of course. |
| 24 | */ |
| @@ -193,11 +193,11 @@ | |
| 193 | int cnt = 0; |
| 194 | n = fusefs_parse_path(zPath); |
| 195 | if( n==0 ){ |
| 196 | filler(buf, ".", NULL, 0); |
| 197 | filler(buf, "..", NULL, 0); |
| 198 | filler(buf, "checkins", NULL, 0); |
| 199 | return 0; |
| 200 | } |
| 201 | if( strcmp(fusefs.az[0],"checkins")!=0 ) return -ENOENT; |
| 202 | if( n==1 ) return -ENOENT; |
| 203 | rid = fusefs_name_to_rid(fusefs.az[1]); |
| @@ -275,11 +275,11 @@ | |
| 275 | if( offset+size>blob_size(&fusefs.content) ){ |
| 276 | size = blob_size(&fusefs.content) - offset; |
| 277 | } |
| 278 | memcpy(buf, blob_buffer(&fusefs.content)+offset, size); |
| 279 | return size; |
| 280 | } |
| 281 | |
| 282 | static struct fuse_operations fusefs_methods = { |
| 283 | .getattr = fusefs_getattr, |
| 284 | .readdir = fusefs_readdir, |
| 285 | .read = fusefs_read, |
| @@ -293,11 +293,11 @@ | |
| 293 | ** |
| 294 | ** This command uses the Fuse Filesystem to mount a directory at |
| 295 | ** DIRECTORY that contains the content of all check-ins in the |
| 296 | ** repository. The names of files are DIRECTORY/checkins/VERSION/PATH |
| 297 | ** where DIRECTORY is the root of the mount, VERSION is any valid |
| 298 | ** check-in name (examples: "trunk" or "tip" or a tag or any unique |
| 299 | ** prefix of a SHA1 hash, etc) and PATH is the pathname of the file |
| 300 | ** in the checkin. If DIRECTORY does not exist, then an attempt is |
| 301 | ** made to create it. |
| 302 | ** |
| 303 | ** The DIRECTORY/checkins directory is not searchable so one cannot |
| 304 |
| --- src/fusefs.c | |
| +++ src/fusefs.c | |
| @@ -14,11 +14,11 @@ | |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** This module implements the userspace side of a Fuse Filesystem that |
| 19 | ** contains all check-ins for a fossil repository. |
| 20 | ** |
| 21 | ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS. |
| 22 | ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for |
| 23 | ** the Fuse Filesystem, of course. |
| 24 | */ |
| @@ -193,11 +193,11 @@ | |
| 193 | int cnt = 0; |
| 194 | n = fusefs_parse_path(zPath); |
| 195 | if( n==0 ){ |
| 196 | filler(buf, ".", NULL, 0); |
| 197 | filler(buf, "..", NULL, 0); |
| 198 | filler(buf, "checkins", NULL, 0); |
| 199 | return 0; |
| 200 | } |
| 201 | if( strcmp(fusefs.az[0],"checkins")!=0 ) return -ENOENT; |
| 202 | if( n==1 ) return -ENOENT; |
| 203 | rid = fusefs_name_to_rid(fusefs.az[1]); |
| @@ -275,11 +275,11 @@ | |
| 275 | if( offset+size>blob_size(&fusefs.content) ){ |
| 276 | size = blob_size(&fusefs.content) - offset; |
| 277 | } |
| 278 | memcpy(buf, blob_buffer(&fusefs.content)+offset, size); |
| 279 | return size; |
| 280 | } |
| 281 | |
| 282 | static struct fuse_operations fusefs_methods = { |
| 283 | .getattr = fusefs_getattr, |
| 284 | .readdir = fusefs_readdir, |
| 285 | .read = fusefs_read, |
| @@ -293,11 +293,11 @@ | |
| 293 | ** |
| 294 | ** This command uses the Fuse Filesystem to mount a directory at |
| 295 | ** DIRECTORY that contains the content of all check-ins in the |
| 296 | ** repository. The names of files are DIRECTORY/checkins/VERSION/PATH |
| 297 | ** where DIRECTORY is the root of the mount, VERSION is any valid |
| 298 | ** check-in name (examples: "trunk" or "tip" or a tag or any unique |
| 299 | ** prefix of a SHA1 hash, etc) and PATH is the pathname of the file |
| 300 | ** in the checkin. If DIRECTORY does not exist, then an attempt is |
| 301 | ** made to create it. |
| 302 | ** |
| 303 | ** The DIRECTORY/checkins directory is not searchable so one cannot |
| 304 |
+5
-5
| --- src/graph.c | ||
| +++ src/graph.c | ||
| @@ -38,11 +38,11 @@ | ||
| 38 | 38 | char *zBgClr; /* Background Color */ |
| 39 | 39 | char zUuid[41]; /* Check-in for file ID */ |
| 40 | 40 | |
| 41 | 41 | GraphRow *pNext; /* Next row down in the list of all rows */ |
| 42 | 42 | GraphRow *pPrev; /* Previous row */ |
| 43 | - | |
| 43 | + | |
| 44 | 44 | int idx; /* Row index. First is 1. 0 used for "none" */ |
| 45 | 45 | int idxTop; /* Direct descendent highest up on the graph */ |
| 46 | 46 | GraphRow *pChild; /* Child immediately above this node */ |
| 47 | 47 | u8 isDup; /* True if this is duplicate of a prior entry */ |
| 48 | 48 | u8 isLeaf; /* True if this is a leaf node */ |
| @@ -154,11 +154,11 @@ | ||
| 154 | 154 | ** Return the canonical pointer for a given branch name. |
| 155 | 155 | ** Multiple calls to this routine with equivalent strings |
| 156 | 156 | ** will return the same pointer. |
| 157 | 157 | ** |
| 158 | 158 | ** The returned value is a pointer to a (readonly) string that |
| 159 | -** has the useful property that strings can be checked for | |
| 159 | +** has the useful property that strings can be checked for | |
| 160 | 160 | ** equality by comparing pointers. |
| 161 | 161 | ** |
| 162 | 162 | ** Note: also used for background color names. |
| 163 | 163 | */ |
| 164 | 164 | static char *persistBranchName(GraphContext *p, const char *zBranch){ |
| @@ -214,11 +214,11 @@ | ||
| 214 | 214 | return pRow->idx; |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | 217 | /* |
| 218 | 218 | ** Return the index of a rail currently not in use for any row between |
| 219 | -** top and bottom, inclusive. | |
| 219 | +** top and bottom, inclusive. | |
| 220 | 220 | */ |
| 221 | 221 | static int findFreeRail( |
| 222 | 222 | GraphContext *p, /* The graph context */ |
| 223 | 223 | int top, int btm, /* Span of rows for which the rail is needed */ |
| 224 | 224 | u64 inUseMask, /* Mask or rails already in use */ |
| @@ -380,11 +380,11 @@ | ||
| 380 | 380 | } |
| 381 | 381 | } |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | 384 | |
| 385 | - /* Find the pChild pointer for each node. | |
| 385 | + /* Find the pChild pointer for each node. | |
| 386 | 386 | ** |
| 387 | 387 | ** The pChild points to the node directly above on the same rail. |
| 388 | 388 | ** The pChild must be in the same branch. Leaf nodes have a NULL |
| 389 | 389 | ** pChild. |
| 390 | 390 | ** |
| @@ -533,11 +533,11 @@ | ||
| 533 | 533 | } |
| 534 | 534 | } |
| 535 | 535 | } |
| 536 | 536 | |
| 537 | 537 | /* |
| 538 | - ** Insert merge rails from primaries to duplicates. | |
| 538 | + ** Insert merge rails from primaries to duplicates. | |
| 539 | 539 | */ |
| 540 | 540 | if( hasDup ){ |
| 541 | 541 | int dupRail; |
| 542 | 542 | int mxRail; |
| 543 | 543 | find_max_rail(p); |
| 544 | 544 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -38,11 +38,11 @@ | |
| 38 | char *zBgClr; /* Background Color */ |
| 39 | char zUuid[41]; /* Check-in for file ID */ |
| 40 | |
| 41 | GraphRow *pNext; /* Next row down in the list of all rows */ |
| 42 | GraphRow *pPrev; /* Previous row */ |
| 43 | |
| 44 | int idx; /* Row index. First is 1. 0 used for "none" */ |
| 45 | int idxTop; /* Direct descendent highest up on the graph */ |
| 46 | GraphRow *pChild; /* Child immediately above this node */ |
| 47 | u8 isDup; /* True if this is duplicate of a prior entry */ |
| 48 | u8 isLeaf; /* True if this is a leaf node */ |
| @@ -154,11 +154,11 @@ | |
| 154 | ** Return the canonical pointer for a given branch name. |
| 155 | ** Multiple calls to this routine with equivalent strings |
| 156 | ** will return the same pointer. |
| 157 | ** |
| 158 | ** The returned value is a pointer to a (readonly) string that |
| 159 | ** has the useful property that strings can be checked for |
| 160 | ** equality by comparing pointers. |
| 161 | ** |
| 162 | ** Note: also used for background color names. |
| 163 | */ |
| 164 | static char *persistBranchName(GraphContext *p, const char *zBranch){ |
| @@ -214,11 +214,11 @@ | |
| 214 | return pRow->idx; |
| 215 | } |
| 216 | |
| 217 | /* |
| 218 | ** Return the index of a rail currently not in use for any row between |
| 219 | ** top and bottom, inclusive. |
| 220 | */ |
| 221 | static int findFreeRail( |
| 222 | GraphContext *p, /* The graph context */ |
| 223 | int top, int btm, /* Span of rows for which the rail is needed */ |
| 224 | u64 inUseMask, /* Mask or rails already in use */ |
| @@ -380,11 +380,11 @@ | |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | |
| 385 | /* Find the pChild pointer for each node. |
| 386 | ** |
| 387 | ** The pChild points to the node directly above on the same rail. |
| 388 | ** The pChild must be in the same branch. Leaf nodes have a NULL |
| 389 | ** pChild. |
| 390 | ** |
| @@ -533,11 +533,11 @@ | |
| 533 | } |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | /* |
| 538 | ** Insert merge rails from primaries to duplicates. |
| 539 | */ |
| 540 | if( hasDup ){ |
| 541 | int dupRail; |
| 542 | int mxRail; |
| 543 | find_max_rail(p); |
| 544 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -38,11 +38,11 @@ | |
| 38 | char *zBgClr; /* Background Color */ |
| 39 | char zUuid[41]; /* Check-in for file ID */ |
| 40 | |
| 41 | GraphRow *pNext; /* Next row down in the list of all rows */ |
| 42 | GraphRow *pPrev; /* Previous row */ |
| 43 | |
| 44 | int idx; /* Row index. First is 1. 0 used for "none" */ |
| 45 | int idxTop; /* Direct descendent highest up on the graph */ |
| 46 | GraphRow *pChild; /* Child immediately above this node */ |
| 47 | u8 isDup; /* True if this is duplicate of a prior entry */ |
| 48 | u8 isLeaf; /* True if this is a leaf node */ |
| @@ -154,11 +154,11 @@ | |
| 154 | ** Return the canonical pointer for a given branch name. |
| 155 | ** Multiple calls to this routine with equivalent strings |
| 156 | ** will return the same pointer. |
| 157 | ** |
| 158 | ** The returned value is a pointer to a (readonly) string that |
| 159 | ** has the useful property that strings can be checked for |
| 160 | ** equality by comparing pointers. |
| 161 | ** |
| 162 | ** Note: also used for background color names. |
| 163 | */ |
| 164 | static char *persistBranchName(GraphContext *p, const char *zBranch){ |
| @@ -214,11 +214,11 @@ | |
| 214 | return pRow->idx; |
| 215 | } |
| 216 | |
| 217 | /* |
| 218 | ** Return the index of a rail currently not in use for any row between |
| 219 | ** top and bottom, inclusive. |
| 220 | */ |
| 221 | static int findFreeRail( |
| 222 | GraphContext *p, /* The graph context */ |
| 223 | int top, int btm, /* Span of rows for which the rail is needed */ |
| 224 | u64 inUseMask, /* Mask or rails already in use */ |
| @@ -380,11 +380,11 @@ | |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | |
| 385 | /* Find the pChild pointer for each node. |
| 386 | ** |
| 387 | ** The pChild points to the node directly above on the same rail. |
| 388 | ** The pChild must be in the same branch. Leaf nodes have a NULL |
| 389 | ** pChild. |
| 390 | ** |
| @@ -533,11 +533,11 @@ | |
| 533 | } |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | /* |
| 538 | ** Insert merge rails from primaries to duplicates. |
| 539 | */ |
| 540 | if( hasDup ){ |
| 541 | int dupRail; |
| 542 | int mxRail; |
| 543 | find_max_rail(p); |
| 544 |
+7
-2
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -205,11 +205,12 @@ | ||
| 205 | 205 | int http_exchange(Blob *pSend, Blob *pReply, int useLogin, int maxRedirect){ |
| 206 | 206 | Blob login; /* The login card */ |
| 207 | 207 | Blob payload; /* The complete payload including login card */ |
| 208 | 208 | Blob hdr; /* The HTTP request header */ |
| 209 | 209 | int closeConnection; /* True to close the connection when done */ |
| 210 | - int iLength; /* Length of the reply payload */ | |
| 210 | + int iLength; /* Expected length of the reply payload */ | |
| 211 | + int iRecvLen; /* Received length of the reply payload */ | |
| 211 | 212 | int rc = 0; /* Result code */ |
| 212 | 213 | int iHttpVersion; /* Which version of HTTP protocol server uses */ |
| 213 | 214 | char *zLine; /* A single line of the reply header */ |
| 214 | 215 | int i; /* Loop counter */ |
| 215 | 216 | int isError = 0; /* True if the reply is an error message */ |
| @@ -370,11 +371,15 @@ | ||
| 370 | 371 | /* |
| 371 | 372 | ** Extract the reply payload that follows the header |
| 372 | 373 | */ |
| 373 | 374 | blob_zero(pReply); |
| 374 | 375 | blob_resize(pReply, iLength); |
| 375 | - iLength = transport_receive(&g.url, blob_buffer(pReply), iLength); | |
| 376 | + iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); | |
| 377 | + if( iRecvLen != iLength ){ | |
| 378 | + fossil_warning("response truncated: got %d bytes of %d", iRecvLen, iLength); | |
| 379 | + goto write_err; | |
| 380 | + } | |
| 376 | 381 | blob_resize(pReply, iLength); |
| 377 | 382 | if( isError ){ |
| 378 | 383 | char *z; |
| 379 | 384 | int i, j; |
| 380 | 385 | z = blob_str(pReply); |
| 381 | 386 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -205,11 +205,12 @@ | |
| 205 | int http_exchange(Blob *pSend, Blob *pReply, int useLogin, int maxRedirect){ |
| 206 | Blob login; /* The login card */ |
| 207 | Blob payload; /* The complete payload including login card */ |
| 208 | Blob hdr; /* The HTTP request header */ |
| 209 | int closeConnection; /* True to close the connection when done */ |
| 210 | int iLength; /* Length of the reply payload */ |
| 211 | int rc = 0; /* Result code */ |
| 212 | int iHttpVersion; /* Which version of HTTP protocol server uses */ |
| 213 | char *zLine; /* A single line of the reply header */ |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| @@ -370,11 +371,15 @@ | |
| 370 | /* |
| 371 | ** Extract the reply payload that follows the header |
| 372 | */ |
| 373 | blob_zero(pReply); |
| 374 | blob_resize(pReply, iLength); |
| 375 | iLength = transport_receive(&g.url, blob_buffer(pReply), iLength); |
| 376 | blob_resize(pReply, iLength); |
| 377 | if( isError ){ |
| 378 | char *z; |
| 379 | int i, j; |
| 380 | z = blob_str(pReply); |
| 381 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -205,11 +205,12 @@ | |
| 205 | int http_exchange(Blob *pSend, Blob *pReply, int useLogin, int maxRedirect){ |
| 206 | Blob login; /* The login card */ |
| 207 | Blob payload; /* The complete payload including login card */ |
| 208 | Blob hdr; /* The HTTP request header */ |
| 209 | int closeConnection; /* True to close the connection when done */ |
| 210 | int iLength; /* Expected length of the reply payload */ |
| 211 | int iRecvLen; /* Received length of the reply payload */ |
| 212 | int rc = 0; /* Result code */ |
| 213 | int iHttpVersion; /* Which version of HTTP protocol server uses */ |
| 214 | char *zLine; /* A single line of the reply header */ |
| 215 | int i; /* Loop counter */ |
| 216 | int isError = 0; /* True if the reply is an error message */ |
| @@ -370,11 +371,15 @@ | |
| 371 | /* |
| 372 | ** Extract the reply payload that follows the header |
| 373 | */ |
| 374 | blob_zero(pReply); |
| 375 | blob_resize(pReply, iLength); |
| 376 | iRecvLen = transport_receive(&g.url, blob_buffer(pReply), iLength); |
| 377 | if( iRecvLen != iLength ){ |
| 378 | fossil_warning("response truncated: got %d bytes of %d", iRecvLen, iLength); |
| 379 | goto write_err; |
| 380 | } |
| 381 | blob_resize(pReply, iLength); |
| 382 | if( isError ){ |
| 383 | char *z; |
| 384 | int i, j; |
| 385 | z = blob_str(pReply); |
| 386 |
+5
-5
| --- src/leaf.c | ||
| +++ src/leaf.c | ||
| @@ -27,15 +27,15 @@ | ||
| 27 | 27 | |
| 28 | 28 | |
| 29 | 29 | /* |
| 30 | 30 | ** Return true if the check-in with RID=rid is a leaf. |
| 31 | 31 | ** |
| 32 | -** A leaf has no children in the same branch. | |
| 32 | +** A leaf has no children in the same branch. | |
| 33 | 33 | */ |
| 34 | 34 | int is_a_leaf(int rid){ |
| 35 | 35 | int rc; |
| 36 | - static const char zSql[] = | |
| 36 | + static const char zSql[] = | |
| 37 | 37 | @ SELECT 1 FROM plink |
| 38 | 38 | @ WHERE pid=%d |
| 39 | 39 | @ AND coalesce((SELECT value FROM tagxref |
| 40 | 40 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 41 | 41 | @ =coalesce((SELECT value FROM tagxref |
| @@ -56,11 +56,11 @@ | ||
| 56 | 56 | ** A non-branch child is one which is on the same branch as the parent. |
| 57 | 57 | */ |
| 58 | 58 | int count_nonbranch_children(int pid){ |
| 59 | 59 | int nNonBranch = 0; |
| 60 | 60 | static Stmt q; |
| 61 | - static const char zSql[] = | |
| 61 | + static const char zSql[] = | |
| 62 | 62 | @ SELECT count(*) FROM plink |
| 63 | 63 | @ WHERE pid=:pid AND isprim |
| 64 | 64 | @ AND coalesce((SELECT value FROM tagxref |
| 65 | 65 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 66 | 66 | @ =coalesce((SELECT value FROM tagxref |
| @@ -75,11 +75,11 @@ | ||
| 75 | 75 | return nNonBranch; |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | |
| 79 | 79 | /* |
| 80 | -** Recompute the entire LEAF table. | |
| 80 | +** Recompute the entire LEAF table. | |
| 81 | 81 | ** |
| 82 | 82 | ** This can be expensive (5 seconds or so) for a really large repository. |
| 83 | 83 | ** So it is only done for things like a rebuild. |
| 84 | 84 | */ |
| 85 | 85 | void leaf_rebuild(void){ |
| @@ -159,11 +159,11 @@ | ||
| 159 | 159 | ** Schedule a leaf check for "rid" and its parents. |
| 160 | 160 | */ |
| 161 | 161 | void leaf_eventually_check(int rid){ |
| 162 | 162 | static Stmt parentsOf; |
| 163 | 163 | |
| 164 | - db_static_prepare(&parentsOf, | |
| 164 | + db_static_prepare(&parentsOf, | |
| 165 | 165 | "SELECT pid FROM plink WHERE cid=:rid AND pid>0" |
| 166 | 166 | ); |
| 167 | 167 | db_bind_int(&parentsOf, ":rid", rid); |
| 168 | 168 | bag_insert(&needToCheck, rid); |
| 169 | 169 | while( db_step(&parentsOf)==SQLITE_ROW ){ |
| 170 | 170 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -27,15 +27,15 @@ | |
| 27 | |
| 28 | |
| 29 | /* |
| 30 | ** Return true if the check-in with RID=rid is a leaf. |
| 31 | ** |
| 32 | ** A leaf has no children in the same branch. |
| 33 | */ |
| 34 | int is_a_leaf(int rid){ |
| 35 | int rc; |
| 36 | static const char zSql[] = |
| 37 | @ SELECT 1 FROM plink |
| 38 | @ WHERE pid=%d |
| 39 | @ AND coalesce((SELECT value FROM tagxref |
| 40 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 41 | @ =coalesce((SELECT value FROM tagxref |
| @@ -56,11 +56,11 @@ | |
| 56 | ** A non-branch child is one which is on the same branch as the parent. |
| 57 | */ |
| 58 | int count_nonbranch_children(int pid){ |
| 59 | int nNonBranch = 0; |
| 60 | static Stmt q; |
| 61 | static const char zSql[] = |
| 62 | @ SELECT count(*) FROM plink |
| 63 | @ WHERE pid=:pid AND isprim |
| 64 | @ AND coalesce((SELECT value FROM tagxref |
| 65 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 66 | @ =coalesce((SELECT value FROM tagxref |
| @@ -75,11 +75,11 @@ | |
| 75 | return nNonBranch; |
| 76 | } |
| 77 | |
| 78 | |
| 79 | /* |
| 80 | ** Recompute the entire LEAF table. |
| 81 | ** |
| 82 | ** This can be expensive (5 seconds or so) for a really large repository. |
| 83 | ** So it is only done for things like a rebuild. |
| 84 | */ |
| 85 | void leaf_rebuild(void){ |
| @@ -159,11 +159,11 @@ | |
| 159 | ** Schedule a leaf check for "rid" and its parents. |
| 160 | */ |
| 161 | void leaf_eventually_check(int rid){ |
| 162 | static Stmt parentsOf; |
| 163 | |
| 164 | db_static_prepare(&parentsOf, |
| 165 | "SELECT pid FROM plink WHERE cid=:rid AND pid>0" |
| 166 | ); |
| 167 | db_bind_int(&parentsOf, ":rid", rid); |
| 168 | bag_insert(&needToCheck, rid); |
| 169 | while( db_step(&parentsOf)==SQLITE_ROW ){ |
| 170 |
| --- src/leaf.c | |
| +++ src/leaf.c | |
| @@ -27,15 +27,15 @@ | |
| 27 | |
| 28 | |
| 29 | /* |
| 30 | ** Return true if the check-in with RID=rid is a leaf. |
| 31 | ** |
| 32 | ** A leaf has no children in the same branch. |
| 33 | */ |
| 34 | int is_a_leaf(int rid){ |
| 35 | int rc; |
| 36 | static const char zSql[] = |
| 37 | @ SELECT 1 FROM plink |
| 38 | @ WHERE pid=%d |
| 39 | @ AND coalesce((SELECT value FROM tagxref |
| 40 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 41 | @ =coalesce((SELECT value FROM tagxref |
| @@ -56,11 +56,11 @@ | |
| 56 | ** A non-branch child is one which is on the same branch as the parent. |
| 57 | */ |
| 58 | int count_nonbranch_children(int pid){ |
| 59 | int nNonBranch = 0; |
| 60 | static Stmt q; |
| 61 | static const char zSql[] = |
| 62 | @ SELECT count(*) FROM plink |
| 63 | @ WHERE pid=:pid AND isprim |
| 64 | @ AND coalesce((SELECT value FROM tagxref |
| 65 | @ WHERE tagid=%d AND rid=plink.pid), 'trunk') |
| 66 | @ =coalesce((SELECT value FROM tagxref |
| @@ -75,11 +75,11 @@ | |
| 75 | return nNonBranch; |
| 76 | } |
| 77 | |
| 78 | |
| 79 | /* |
| 80 | ** Recompute the entire LEAF table. |
| 81 | ** |
| 82 | ** This can be expensive (5 seconds or so) for a really large repository. |
| 83 | ** So it is only done for things like a rebuild. |
| 84 | */ |
| 85 | void leaf_rebuild(void){ |
| @@ -159,11 +159,11 @@ | |
| 159 | ** Schedule a leaf check for "rid" and its parents. |
| 160 | */ |
| 161 | void leaf_eventually_check(int rid){ |
| 162 | static Stmt parentsOf; |
| 163 | |
| 164 | db_static_prepare(&parentsOf, |
| 165 | "SELECT pid FROM plink WHERE cid=:rid AND pid>0" |
| 166 | ); |
| 167 | db_bind_int(&parentsOf, ":rid", rid); |
| 168 | bag_insert(&needToCheck, rid); |
| 169 | while( db_step(&parentsOf)==SQLITE_ROW ){ |
| 170 |
+1
-1
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -483,11 +483,11 @@ | ||
| 483 | 483 | zQS = ""; |
| 484 | 484 | }else if( zQS[0]!=0 ){ |
| 485 | 485 | zQS = mprintf("?%s", zQS); |
| 486 | 486 | } |
| 487 | 487 | cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS); |
| 488 | - return; | |
| 488 | + return; | |
| 489 | 489 | } |
| 490 | 490 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 491 | 491 | constant_time_cmp_function, 0, 0); |
| 492 | 492 | zUsername = P("u"); |
| 493 | 493 | zPasswd = P("p"); |
| 494 | 494 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -483,11 +483,11 @@ | |
| 483 | zQS = ""; |
| 484 | }else if( zQS[0]!=0 ){ |
| 485 | zQS = mprintf("?%s", zQS); |
| 486 | } |
| 487 | cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS); |
| 488 | return; |
| 489 | } |
| 490 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 491 | constant_time_cmp_function, 0, 0); |
| 492 | zUsername = P("u"); |
| 493 | zPasswd = P("p"); |
| 494 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -483,11 +483,11 @@ | |
| 483 | zQS = ""; |
| 484 | }else if( zQS[0]!=0 ){ |
| 485 | zQS = mprintf("?%s", zQS); |
| 486 | } |
| 487 | cgi_redirectf("%s%s%s", g.zHttpsURL, P("PATH_INFO"), zQS); |
| 488 | return; |
| 489 | } |
| 490 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 491 | constant_time_cmp_function, 0, 0); |
| 492 | zUsername = P("u"); |
| 493 | zPasswd = P("p"); |
| 494 |
+3
-3
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -573,12 +573,12 @@ | ||
| 573 | 573 | #### The directories where the OpenSSL include and library files are located. |
| 574 | 574 | # The recommended usage here is to use the Sysinternals junction tool |
| 575 | 575 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 576 | 576 | # Fossil source code directory and the target OpenSSL source directory. |
| 577 | 577 | # |
| 578 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include | |
| 579 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j | |
| 578 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1k/include | |
| 579 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1k | |
| 580 | 580 | |
| 581 | 581 | #### Either the directory where the Tcl library is installed or the Tcl |
| 582 | 582 | # source code directory resides (depending on the value of the macro |
| 583 | 583 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 584 | 584 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -1305,11 +1305,11 @@ | ||
| 1305 | 1305 | |
| 1306 | 1306 | # Uncomment to enable Tcl support |
| 1307 | 1307 | # FOSSIL_ENABLE_TCL = 1 |
| 1308 | 1308 | |
| 1309 | 1309 | !ifdef FOSSIL_ENABLE_SSL |
| 1310 | -SSLDIR = $(B)\compat\openssl-1.0.1j | |
| 1310 | +SSLDIR = $(B)\compat\openssl-1.0.1k | |
| 1311 | 1311 | SSLINCDIR = $(SSLDIR)\inc32 |
| 1312 | 1312 | SSLLIBDIR = $(SSLDIR)\out32 |
| 1313 | 1313 | SSLLFLAGS = /nologo /opt:ref /debug |
| 1314 | 1314 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1315 | 1315 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1316 | 1316 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -573,12 +573,12 @@ | |
| 573 | #### The directories where the OpenSSL include and library files are located. |
| 574 | # The recommended usage here is to use the Sysinternals junction tool |
| 575 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 576 | # Fossil source code directory and the target OpenSSL source directory. |
| 577 | # |
| 578 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include |
| 579 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j |
| 580 | |
| 581 | #### Either the directory where the Tcl library is installed or the Tcl |
| 582 | # source code directory resides (depending on the value of the macro |
| 583 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 584 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -1305,11 +1305,11 @@ | |
| 1305 | |
| 1306 | # Uncomment to enable Tcl support |
| 1307 | # FOSSIL_ENABLE_TCL = 1 |
| 1308 | |
| 1309 | !ifdef FOSSIL_ENABLE_SSL |
| 1310 | SSLDIR = $(B)\compat\openssl-1.0.1j |
| 1311 | SSLINCDIR = $(SSLDIR)\inc32 |
| 1312 | SSLLIBDIR = $(SSLDIR)\out32 |
| 1313 | SSLLFLAGS = /nologo /opt:ref /debug |
| 1314 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1315 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1316 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -573,12 +573,12 @@ | |
| 573 | #### The directories where the OpenSSL include and library files are located. |
| 574 | # The recommended usage here is to use the Sysinternals junction tool |
| 575 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 576 | # Fossil source code directory and the target OpenSSL source directory. |
| 577 | # |
| 578 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1k/include |
| 579 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1k |
| 580 | |
| 581 | #### Either the directory where the Tcl library is installed or the Tcl |
| 582 | # source code directory resides (depending on the value of the macro |
| 583 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 584 | # this directory must have "include" and "lib" sub-directories. If |
| @@ -1305,11 +1305,11 @@ | |
| 1305 | |
| 1306 | # Uncomment to enable Tcl support |
| 1307 | # FOSSIL_ENABLE_TCL = 1 |
| 1308 | |
| 1309 | !ifdef FOSSIL_ENABLE_SSL |
| 1310 | SSLDIR = $(B)\compat\openssl-1.0.1k |
| 1311 | SSLINCDIR = $(SSLDIR)\inc32 |
| 1312 | SSLLIBDIR = $(SSLDIR)\out32 |
| 1313 | SSLLFLAGS = /nologo /opt:ref /debug |
| 1314 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 1315 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 1316 |
+6
-6
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -41,11 +41,11 @@ | ||
| 41 | 41 | if( zTagList && zTagList[0] ){ |
| 42 | 42 | zCom = mprintf("%s (%s)", db_column_text(&q, 2), zTagList); |
| 43 | 43 | }else{ |
| 44 | 44 | zCom = mprintf("%s", db_column_text(&q,2)); |
| 45 | 45 | } |
| 46 | - fossil_print("%-*s [%S] by %s on %s\n%*s", | |
| 46 | + fossil_print("%-*s [%S] by %s on %s\n%*s", | |
| 47 | 47 | indent-1, zLabel, |
| 48 | 48 | db_column_text(&q, 3), |
| 49 | 49 | db_column_text(&q, 1), |
| 50 | 50 | db_column_text(&q, 0), |
| 51 | 51 | indent, ""); |
| @@ -166,11 +166,11 @@ | ||
| 166 | 166 | }else if( g.argc==2 ){ |
| 167 | 167 | /* No version specified on the command-line so pick the most recent |
| 168 | 168 | ** leaf that is (1) not the version currently checked out and (2) |
| 169 | 169 | ** has not already been merged into the current checkout and (3) |
| 170 | 170 | ** the leaf is not closed and (4) the leaf is in the same branch |
| 171 | - ** as the current checkout. | |
| 171 | + ** as the current checkout. | |
| 172 | 172 | */ |
| 173 | 173 | Stmt q; |
| 174 | 174 | if( pickFlag || backoutFlag || integrateFlag){ |
| 175 | 175 | fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge"); |
| 176 | 176 | } |
| @@ -472,13 +472,13 @@ | ||
| 472 | 472 | undo_save(zName); |
| 473 | 473 | vfile_to_disk(0, idm, 0, 0); |
| 474 | 474 | } |
| 475 | 475 | } |
| 476 | 476 | db_finalize(&q); |
| 477 | - | |
| 477 | + | |
| 478 | 478 | /* |
| 479 | - ** Find files that have changed from P->M but not P->V. | |
| 479 | + ** Find files that have changed from P->M but not P->V. | |
| 480 | 480 | ** Copy the M content over into V. |
| 481 | 481 | */ |
| 482 | 482 | db_prepare(&q, |
| 483 | 483 | "SELECT idv, ridm, fn, islinkm FROM fv" |
| 484 | 484 | " WHERE idp>0 AND idv>0 AND idm>0" |
| @@ -524,18 +524,18 @@ | ||
| 524 | 524 | int rc; |
| 525 | 525 | char *zFullPath; |
| 526 | 526 | Blob m, p, r; |
| 527 | 527 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| 528 | 528 | if( verboseFlag ){ |
| 529 | - fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", | |
| 529 | + fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", | |
| 530 | 530 | zName, ridp, ridm, ridv); |
| 531 | 531 | }else{ |
| 532 | 532 | fossil_print("MERGE %s\n", zName); |
| 533 | 533 | } |
| 534 | 534 | if( islinkv || islinkm /* || file_wd_islink(zFullPath) */ ){ |
| 535 | 535 | fossil_print("***** Cannot merge symlink %s\n", zName); |
| 536 | - nConflict++; | |
| 536 | + nConflict++; | |
| 537 | 537 | }else{ |
| 538 | 538 | undo_save(zName); |
| 539 | 539 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 540 | 540 | content_get(ridp, &p); |
| 541 | 541 | content_get(ridm, &m); |
| 542 | 542 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -41,11 +41,11 @@ | |
| 41 | if( zTagList && zTagList[0] ){ |
| 42 | zCom = mprintf("%s (%s)", db_column_text(&q, 2), zTagList); |
| 43 | }else{ |
| 44 | zCom = mprintf("%s", db_column_text(&q,2)); |
| 45 | } |
| 46 | fossil_print("%-*s [%S] by %s on %s\n%*s", |
| 47 | indent-1, zLabel, |
| 48 | db_column_text(&q, 3), |
| 49 | db_column_text(&q, 1), |
| 50 | db_column_text(&q, 0), |
| 51 | indent, ""); |
| @@ -166,11 +166,11 @@ | |
| 166 | }else if( g.argc==2 ){ |
| 167 | /* No version specified on the command-line so pick the most recent |
| 168 | ** leaf that is (1) not the version currently checked out and (2) |
| 169 | ** has not already been merged into the current checkout and (3) |
| 170 | ** the leaf is not closed and (4) the leaf is in the same branch |
| 171 | ** as the current checkout. |
| 172 | */ |
| 173 | Stmt q; |
| 174 | if( pickFlag || backoutFlag || integrateFlag){ |
| 175 | fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge"); |
| 176 | } |
| @@ -472,13 +472,13 @@ | |
| 472 | undo_save(zName); |
| 473 | vfile_to_disk(0, idm, 0, 0); |
| 474 | } |
| 475 | } |
| 476 | db_finalize(&q); |
| 477 | |
| 478 | /* |
| 479 | ** Find files that have changed from P->M but not P->V. |
| 480 | ** Copy the M content over into V. |
| 481 | */ |
| 482 | db_prepare(&q, |
| 483 | "SELECT idv, ridm, fn, islinkm FROM fv" |
| 484 | " WHERE idp>0 AND idv>0 AND idm>0" |
| @@ -524,18 +524,18 @@ | |
| 524 | int rc; |
| 525 | char *zFullPath; |
| 526 | Blob m, p, r; |
| 527 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| 528 | if( verboseFlag ){ |
| 529 | fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", |
| 530 | zName, ridp, ridm, ridv); |
| 531 | }else{ |
| 532 | fossil_print("MERGE %s\n", zName); |
| 533 | } |
| 534 | if( islinkv || islinkm /* || file_wd_islink(zFullPath) */ ){ |
| 535 | fossil_print("***** Cannot merge symlink %s\n", zName); |
| 536 | nConflict++; |
| 537 | }else{ |
| 538 | undo_save(zName); |
| 539 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 540 | content_get(ridp, &p); |
| 541 | content_get(ridm, &m); |
| 542 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -41,11 +41,11 @@ | |
| 41 | if( zTagList && zTagList[0] ){ |
| 42 | zCom = mprintf("%s (%s)", db_column_text(&q, 2), zTagList); |
| 43 | }else{ |
| 44 | zCom = mprintf("%s", db_column_text(&q,2)); |
| 45 | } |
| 46 | fossil_print("%-*s [%S] by %s on %s\n%*s", |
| 47 | indent-1, zLabel, |
| 48 | db_column_text(&q, 3), |
| 49 | db_column_text(&q, 1), |
| 50 | db_column_text(&q, 0), |
| 51 | indent, ""); |
| @@ -166,11 +166,11 @@ | |
| 166 | }else if( g.argc==2 ){ |
| 167 | /* No version specified on the command-line so pick the most recent |
| 168 | ** leaf that is (1) not the version currently checked out and (2) |
| 169 | ** has not already been merged into the current checkout and (3) |
| 170 | ** the leaf is not closed and (4) the leaf is in the same branch |
| 171 | ** as the current checkout. |
| 172 | */ |
| 173 | Stmt q; |
| 174 | if( pickFlag || backoutFlag || integrateFlag){ |
| 175 | fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge"); |
| 176 | } |
| @@ -472,13 +472,13 @@ | |
| 472 | undo_save(zName); |
| 473 | vfile_to_disk(0, idm, 0, 0); |
| 474 | } |
| 475 | } |
| 476 | db_finalize(&q); |
| 477 | |
| 478 | /* |
| 479 | ** Find files that have changed from P->M but not P->V. |
| 480 | ** Copy the M content over into V. |
| 481 | */ |
| 482 | db_prepare(&q, |
| 483 | "SELECT idv, ridm, fn, islinkm FROM fv" |
| 484 | " WHERE idp>0 AND idv>0 AND idm>0" |
| @@ -524,18 +524,18 @@ | |
| 524 | int rc; |
| 525 | char *zFullPath; |
| 526 | Blob m, p, r; |
| 527 | /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ |
| 528 | if( verboseFlag ){ |
| 529 | fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", |
| 530 | zName, ridp, ridm, ridv); |
| 531 | }else{ |
| 532 | fossil_print("MERGE %s\n", zName); |
| 533 | } |
| 534 | if( islinkv || islinkm /* || file_wd_islink(zFullPath) */ ){ |
| 535 | fossil_print("***** Cannot merge symlink %s\n", zName); |
| 536 | nConflict++; |
| 537 | }else{ |
| 538 | undo_save(zName); |
| 539 | zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); |
| 540 | content_get(ridp, &p); |
| 541 | content_get(ridm, &m); |
| 542 |
+1
-1
| --- src/mkbuiltin.c | ||
| +++ src/mkbuiltin.c | ||
| @@ -82,11 +82,11 @@ | ||
| 82 | 82 | int j, n; |
| 83 | 83 | Resource *aRes; |
| 84 | 84 | int nRes = argc-1; |
| 85 | 85 | unsigned char *pData; |
| 86 | 86 | int nErr = 0; |
| 87 | - | |
| 87 | + | |
| 88 | 88 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 89 | 89 | if( aRes==0 ){ |
| 90 | 90 | fprintf(stderr, "malloc failed\n"); |
| 91 | 91 | return 1; |
| 92 | 92 | } |
| 93 | 93 |
| --- src/mkbuiltin.c | |
| +++ src/mkbuiltin.c | |
| @@ -82,11 +82,11 @@ | |
| 82 | int j, n; |
| 83 | Resource *aRes; |
| 84 | int nRes = argc-1; |
| 85 | unsigned char *pData; |
| 86 | int nErr = 0; |
| 87 | |
| 88 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 89 | if( aRes==0 ){ |
| 90 | fprintf(stderr, "malloc failed\n"); |
| 91 | return 1; |
| 92 | } |
| 93 |
| --- src/mkbuiltin.c | |
| +++ src/mkbuiltin.c | |
| @@ -82,11 +82,11 @@ | |
| 82 | int j, n; |
| 83 | Resource *aRes; |
| 84 | int nRes = argc-1; |
| 85 | unsigned char *pData; |
| 86 | int nErr = 0; |
| 87 | |
| 88 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 89 | if( aRes==0 ){ |
| 90 | fprintf(stderr, "malloc failed\n"); |
| 91 | return 1; |
| 92 | } |
| 93 |
+8
-9
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -982,25 +982,24 @@ | ||
| 982 | 982 | @ this.tbody[0].appendChild(newRows[i]); |
| 983 | 983 | @ } |
| 984 | 984 | @ this.setHdrIcons(); |
| 985 | 985 | @ } |
| 986 | 986 | @ this.setHdrIcons = function() { |
| 987 | - @ var arrowdiv = this.hdrRow.getElementsByClassName("sortarrow"); | |
| 988 | - @ while( arrowdiv[0] ){ | |
| 989 | - @ arrowdiv[0].parentNode.removeChild(arrowdiv[0]); | |
| 990 | - @ } | |
| 991 | 987 | @ for (var i=0; i<this.hdrRow.cells.length; i++) { |
| 992 | 988 | @ if( this.columnTypes[i]=='x' ) continue; |
| 989 | + @ var sortType; | |
| 993 | 990 | @ if( this.prevColumn==i+1 ){ |
| 994 | - @ arrow = "↓" | |
| 991 | + @ sortType = 'asc'; | |
| 995 | 992 | @ }else if( this.prevColumn==(-1-i) ){ |
| 996 | - @ arrow = "↑" | |
| 993 | + @ sortType = 'desc' | |
| 997 | 994 | @ }else{ |
| 998 | - @ arrow = "♦" | |
| 995 | + @ sortType = 'none'; | |
| 999 | 996 | @ } |
| 1000 | - @ this.hdrRow.cells[i].innerHTML += | |
| 1001 | - @ "<span class='sortarrow'>" + arrow + "</div>"; | |
| 997 | + @ var hdrCell = this.hdrRow.cells[i]; | |
| 998 | + @ var clsName = hdrCell.className.replace(/\s*\bsort\s*\w+/, ''); | |
| 999 | + @ clsName += ' sort ' + sortType; | |
| 1000 | + @ hdrCell.className = clsName; | |
| 1002 | 1001 | @ } |
| 1003 | 1002 | @ } |
| 1004 | 1003 | @ this.sortText = function(a,b) { |
| 1005 | 1004 | @ var i = thisObject.sortIndex; |
| 1006 | 1005 | @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase(); |
| 1007 | 1006 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -982,25 +982,24 @@ | |
| 982 | @ this.tbody[0].appendChild(newRows[i]); |
| 983 | @ } |
| 984 | @ this.setHdrIcons(); |
| 985 | @ } |
| 986 | @ this.setHdrIcons = function() { |
| 987 | @ var arrowdiv = this.hdrRow.getElementsByClassName("sortarrow"); |
| 988 | @ while( arrowdiv[0] ){ |
| 989 | @ arrowdiv[0].parentNode.removeChild(arrowdiv[0]); |
| 990 | @ } |
| 991 | @ for (var i=0; i<this.hdrRow.cells.length; i++) { |
| 992 | @ if( this.columnTypes[i]=='x' ) continue; |
| 993 | @ if( this.prevColumn==i+1 ){ |
| 994 | @ arrow = "↓" |
| 995 | @ }else if( this.prevColumn==(-1-i) ){ |
| 996 | @ arrow = "↑" |
| 997 | @ }else{ |
| 998 | @ arrow = "♦" |
| 999 | @ } |
| 1000 | @ this.hdrRow.cells[i].innerHTML += |
| 1001 | @ "<span class='sortarrow'>" + arrow + "</div>"; |
| 1002 | @ } |
| 1003 | @ } |
| 1004 | @ this.sortText = function(a,b) { |
| 1005 | @ var i = thisObject.sortIndex; |
| 1006 | @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase(); |
| 1007 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -982,25 +982,24 @@ | |
| 982 | @ this.tbody[0].appendChild(newRows[i]); |
| 983 | @ } |
| 984 | @ this.setHdrIcons(); |
| 985 | @ } |
| 986 | @ this.setHdrIcons = function() { |
| 987 | @ for (var i=0; i<this.hdrRow.cells.length; i++) { |
| 988 | @ if( this.columnTypes[i]=='x' ) continue; |
| 989 | @ var sortType; |
| 990 | @ if( this.prevColumn==i+1 ){ |
| 991 | @ sortType = 'asc'; |
| 992 | @ }else if( this.prevColumn==(-1-i) ){ |
| 993 | @ sortType = 'desc' |
| 994 | @ }else{ |
| 995 | @ sortType = 'none'; |
| 996 | @ } |
| 997 | @ var hdrCell = this.hdrRow.cells[i]; |
| 998 | @ var clsName = hdrCell.className.replace(/\s*\bsort\s*\w+/, ''); |
| 999 | @ clsName += ' sort ' + sortType; |
| 1000 | @ hdrCell.className = clsName; |
| 1001 | @ } |
| 1002 | @ } |
| 1003 | @ this.sortText = function(a,b) { |
| 1004 | @ var i = thisObject.sortIndex; |
| 1005 | @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase(); |
| 1006 |
+2
-2
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -34,11 +34,11 @@ | ||
| 34 | 34 | struct Search { |
| 35 | 35 | int nTerm; /* Number of search terms */ |
| 36 | 36 | struct srchTerm { /* For each search term */ |
| 37 | 37 | char *z; /* Text */ |
| 38 | 38 | int n; /* length */ |
| 39 | - } a[8]; | |
| 39 | + } a[8]; | |
| 40 | 40 | }; |
| 41 | 41 | #endif |
| 42 | 42 | |
| 43 | 43 | /* |
| 44 | 44 | ** Compile a search pattern |
| @@ -139,11 +139,11 @@ | ||
| 139 | 139 | } |
| 140 | 140 | iBonus /= 2; |
| 141 | 141 | while( !isBoundary[zDoc[i]&0xff] ){ i++; } |
| 142 | 142 | } |
| 143 | 143 | } |
| 144 | - | |
| 144 | + | |
| 145 | 145 | /* Every term must be seen or else the score is zero */ |
| 146 | 146 | for(j=0; j<p->nTerm; j++){ |
| 147 | 147 | if( !seen[j] ) return 0; |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | struct Search { |
| 35 | int nTerm; /* Number of search terms */ |
| 36 | struct srchTerm { /* For each search term */ |
| 37 | char *z; /* Text */ |
| 38 | int n; /* length */ |
| 39 | } a[8]; |
| 40 | }; |
| 41 | #endif |
| 42 | |
| 43 | /* |
| 44 | ** Compile a search pattern |
| @@ -139,11 +139,11 @@ | |
| 139 | } |
| 140 | iBonus /= 2; |
| 141 | while( !isBoundary[zDoc[i]&0xff] ){ i++; } |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | /* Every term must be seen or else the score is zero */ |
| 146 | for(j=0; j<p->nTerm; j++){ |
| 147 | if( !seen[j] ) return 0; |
| 148 | } |
| 149 | |
| 150 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | struct Search { |
| 35 | int nTerm; /* Number of search terms */ |
| 36 | struct srchTerm { /* For each search term */ |
| 37 | char *z; /* Text */ |
| 38 | int n; /* length */ |
| 39 | } a[8]; |
| 40 | }; |
| 41 | #endif |
| 42 | |
| 43 | /* |
| 44 | ** Compile a search pattern |
| @@ -139,11 +139,11 @@ | |
| 139 | } |
| 140 | iBonus /= 2; |
| 141 | while( !isBoundary[zDoc[i]&0xff] ){ i++; } |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | /* Every term must be seen or else the score is zero */ |
| 146 | for(j=0; j<p->nTerm; j++){ |
| 147 | if( !seen[j] ) return 0; |
| 148 | } |
| 149 | |
| 150 |
+2
-2
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -151,11 +151,11 @@ | ||
| 151 | 151 | "SELECT uid, login, cap, info, 1 FROM user" |
| 152 | 152 | " WHERE login IN ('anonymous','nobody','developer','reader') " |
| 153 | 153 | " UNION ALL " |
| 154 | 154 | "SELECT uid, login, cap, info, 2 FROM user" |
| 155 | 155 | " WHERE login NOT IN ('anonymous','nobody','developer','reader') " |
| 156 | - "ORDER BY 5, 2" | |
| 156 | + "ORDER BY 5, 2 COLLATE nocase" | |
| 157 | 157 | ); |
| 158 | 158 | while( db_step(&s)==SQLITE_ROW ){ |
| 159 | 159 | int iLevel = db_column_int(&s, 4); |
| 160 | 160 | const char *zCap = db_column_text(&s, 2); |
| 161 | 161 | const char *zLogin = db_column_text(&s, 1); |
| @@ -995,11 +995,11 @@ | ||
| 995 | 995 | login_insert_csrf_secret(); |
| 996 | 996 | @ <hr /> |
| 997 | 997 | onoff_attribute("Redirect to HTTPS on the Login page", |
| 998 | 998 | "redirect-to-https", "redirhttps", 0, 0); |
| 999 | 999 | @ <p>When selected, force the use of HTTPS for the Login page. |
| 1000 | - @ <p>Details: When enabled, this option causes the $secureurl TH1 | |
| 1000 | + @ <p>Details: When enabled, this option causes the $secureurl TH1 | |
| 1001 | 1001 | @ variable is set to an "https:" variant of $baseurl. Otherwise, |
| 1002 | 1002 | @ $secureurl is just an alias for $baseurl. Also when enabled, the |
| 1003 | 1003 | @ Login page redirects to https if accessed via http. |
| 1004 | 1004 | @ <hr /> |
| 1005 | 1005 | onoff_attribute("Require password for local access", |
| 1006 | 1006 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -151,11 +151,11 @@ | |
| 151 | "SELECT uid, login, cap, info, 1 FROM user" |
| 152 | " WHERE login IN ('anonymous','nobody','developer','reader') " |
| 153 | " UNION ALL " |
| 154 | "SELECT uid, login, cap, info, 2 FROM user" |
| 155 | " WHERE login NOT IN ('anonymous','nobody','developer','reader') " |
| 156 | "ORDER BY 5, 2" |
| 157 | ); |
| 158 | while( db_step(&s)==SQLITE_ROW ){ |
| 159 | int iLevel = db_column_int(&s, 4); |
| 160 | const char *zCap = db_column_text(&s, 2); |
| 161 | const char *zLogin = db_column_text(&s, 1); |
| @@ -995,11 +995,11 @@ | |
| 995 | login_insert_csrf_secret(); |
| 996 | @ <hr /> |
| 997 | onoff_attribute("Redirect to HTTPS on the Login page", |
| 998 | "redirect-to-https", "redirhttps", 0, 0); |
| 999 | @ <p>When selected, force the use of HTTPS for the Login page. |
| 1000 | @ <p>Details: When enabled, this option causes the $secureurl TH1 |
| 1001 | @ variable is set to an "https:" variant of $baseurl. Otherwise, |
| 1002 | @ $secureurl is just an alias for $baseurl. Also when enabled, the |
| 1003 | @ Login page redirects to https if accessed via http. |
| 1004 | @ <hr /> |
| 1005 | onoff_attribute("Require password for local access", |
| 1006 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -151,11 +151,11 @@ | |
| 151 | "SELECT uid, login, cap, info, 1 FROM user" |
| 152 | " WHERE login IN ('anonymous','nobody','developer','reader') " |
| 153 | " UNION ALL " |
| 154 | "SELECT uid, login, cap, info, 2 FROM user" |
| 155 | " WHERE login NOT IN ('anonymous','nobody','developer','reader') " |
| 156 | "ORDER BY 5, 2 COLLATE nocase" |
| 157 | ); |
| 158 | while( db_step(&s)==SQLITE_ROW ){ |
| 159 | int iLevel = db_column_int(&s, 4); |
| 160 | const char *zCap = db_column_text(&s, 2); |
| 161 | const char *zLogin = db_column_text(&s, 1); |
| @@ -995,11 +995,11 @@ | |
| 995 | login_insert_csrf_secret(); |
| 996 | @ <hr /> |
| 997 | onoff_attribute("Redirect to HTTPS on the Login page", |
| 998 | "redirect-to-https", "redirhttps", 0, 0); |
| 999 | @ <p>When selected, force the use of HTTPS for the Login page. |
| 1000 | @ <p>Details: When enabled, this option causes the $secureurl TH1 |
| 1001 | @ variable is set to an "https:" variant of $baseurl. Otherwise, |
| 1002 | @ $secureurl is just an alias for $baseurl. Also when enabled, the |
| 1003 | @ Login page redirects to https if accessed via http. |
| 1004 | @ <hr /> |
| 1005 | onoff_attribute("Require password for local access", |
| 1006 |
+259
-129
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -15,10 +15,17 @@ | ||
| 15 | 15 | #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) |
| 16 | 16 | /* This needs to come before any includes for MSVC compiler */ |
| 17 | 17 | #define _CRT_SECURE_NO_WARNINGS |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | +/* | |
| 21 | +** If requested, include the SQLite compiler options file for MSVC. | |
| 22 | +*/ | |
| 23 | +#if defined(INCLUDE_MSVC_H) | |
| 24 | +#include "msvc.h" | |
| 25 | +#endif | |
| 26 | + | |
| 20 | 27 | /* |
| 21 | 28 | ** Enable large-file support for fopen() and friends on unix. |
| 22 | 29 | */ |
| 23 | 30 | #ifndef SQLITE_DISABLE_LFS |
| 24 | 31 | # define _LARGE_FILE 1 |
| @@ -46,21 +53,20 @@ | ||
| 46 | 53 | # endif |
| 47 | 54 | # include <unistd.h> |
| 48 | 55 | # include <sys/types.h> |
| 49 | 56 | #endif |
| 50 | 57 | |
| 51 | -#if defined(HAVE_READLINE) && HAVE_READLINE!=0 | |
| 58 | +#if HAVE_READLINE | |
| 52 | 59 | # include <readline/readline.h> |
| 53 | 60 | # include <readline/history.h> |
| 54 | -#else | |
| 55 | -# undef HAVE_READLINE | |
| 56 | 61 | #endif |
| 57 | -#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE) | |
| 62 | +#if HAVE_EDITLINE | |
| 63 | +# undef HAVE_READLINE | |
| 58 | 64 | # define HAVE_READLINE 1 |
| 59 | 65 | # include <editline/readline.h> |
| 60 | 66 | #endif |
| 61 | -#if !defined(HAVE_READLINE) | |
| 67 | +#if !HAVE_READLINE | |
| 62 | 68 | # define add_history(X) |
| 63 | 69 | # define read_history(X) |
| 64 | 70 | # define write_history(X) |
| 65 | 71 | # define stifle_history(X) |
| 66 | 72 | #endif |
| @@ -423,11 +429,11 @@ | ||
| 423 | 429 | char *zResult; |
| 424 | 430 | if( in!=0 ){ |
| 425 | 431 | zResult = local_getline(zPrior, in); |
| 426 | 432 | }else{ |
| 427 | 433 | zPrompt = isContinuation ? continuePrompt : mainPrompt; |
| 428 | -#if defined(HAVE_READLINE) | |
| 434 | +#if HAVE_READLINE | |
| 429 | 435 | free(zPrior); |
| 430 | 436 | zResult = readline(zPrompt); |
| 431 | 437 | if( zResult && *zResult ) add_history(zResult); |
| 432 | 438 | #else |
| 433 | 439 | printf("%s", zPrompt); |
| @@ -469,15 +475,15 @@ | ||
| 469 | 475 | int mode; /* An output mode setting */ |
| 470 | 476 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
| 471 | 477 | int showHeader; /* True to show column names in List or Column mode */ |
| 472 | 478 | unsigned shellFlgs; /* Various flags */ |
| 473 | 479 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
| 474 | - char separator[20]; /* Separator character for MODE_List */ | |
| 475 | - char newline[20]; /* Record separator in MODE_Csv */ | |
| 480 | + char colSeparator[20]; /* Column separator character for several modes */ | |
| 481 | + char rowSeparator[20]; /* Row separator character for MODE_Ascii */ | |
| 476 | 482 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
| 477 | 483 | int actualWidth[100]; /* Actual width of each column */ |
| 478 | - char nullvalue[20]; /* The text to print when a NULL comes back from | |
| 484 | + char nullValue[20]; /* The text to print when a NULL comes back from | |
| 479 | 485 | ** the database */ |
| 480 | 486 | SavedModeInfo normalMode;/* Holds the mode just before .explain ON */ |
| 481 | 487 | char outfile[FILENAME_MAX]; /* Filename for *out */ |
| 482 | 488 | const char *zDbFilename; /* name of the database file */ |
| 483 | 489 | char *zFreeOnClose; /* Filename to free when closing */ |
| @@ -506,10 +512,11 @@ | ||
| 506 | 512 | #define MODE_Html 4 /* Generate an XHTML table */ |
| 507 | 513 | #define MODE_Insert 5 /* Generate SQL "insert" statements */ |
| 508 | 514 | #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ |
| 509 | 515 | #define MODE_Csv 7 /* Quote strings, numbers are plain */ |
| 510 | 516 | #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ |
| 517 | +#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */ | |
| 511 | 518 | |
| 512 | 519 | static const char *modeDescr[] = { |
| 513 | 520 | "line", |
| 514 | 521 | "column", |
| 515 | 522 | "list", |
| @@ -517,12 +524,26 @@ | ||
| 517 | 524 | "html", |
| 518 | 525 | "insert", |
| 519 | 526 | "tcl", |
| 520 | 527 | "csv", |
| 521 | 528 | "explain", |
| 529 | + "ascii", | |
| 522 | 530 | }; |
| 523 | 531 | |
| 532 | +/* | |
| 533 | +** These are the column/row/line separators used by the various | |
| 534 | +** import/export modes. | |
| 535 | +*/ | |
| 536 | +#define SEP_Column "|" | |
| 537 | +#define SEP_Row "\n" | |
| 538 | +#define SEP_Tab "\t" | |
| 539 | +#define SEP_Space " " | |
| 540 | +#define SEP_Comma "," | |
| 541 | +#define SEP_CrLf "\r\n" | |
| 542 | +#define SEP_Unit "\x1F" | |
| 543 | +#define SEP_Record "\x1E" | |
| 544 | + | |
| 524 | 545 | /* |
| 525 | 546 | ** Number of elements in an array |
| 526 | 547 | */ |
| 527 | 548 | #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) |
| 528 | 549 | |
| @@ -675,26 +696,26 @@ | ||
| 675 | 696 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 676 | 697 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 677 | 698 | }; |
| 678 | 699 | |
| 679 | 700 | /* |
| 680 | -** Output a single term of CSV. Actually, p->separator is used for | |
| 681 | -** the separator, which may or may not be a comma. p->nullvalue is | |
| 701 | +** Output a single term of CSV. Actually, p->colSeparator is used for | |
| 702 | +** the separator, which may or may not be a comma. p->nullValue is | |
| 682 | 703 | ** the null value. Strings are quoted if necessary. The separator |
| 683 | 704 | ** is only issued if bSep is true. |
| 684 | 705 | */ |
| 685 | 706 | static void output_csv(ShellState *p, const char *z, int bSep){ |
| 686 | 707 | FILE *out = p->out; |
| 687 | 708 | if( z==0 ){ |
| 688 | - fprintf(out,"%s",p->nullvalue); | |
| 709 | + fprintf(out,"%s",p->nullValue); | |
| 689 | 710 | }else{ |
| 690 | 711 | int i; |
| 691 | - int nSep = strlen30(p->separator); | |
| 712 | + int nSep = strlen30(p->colSeparator); | |
| 692 | 713 | for(i=0; z[i]; i++){ |
| 693 | 714 | if( needCsvQuote[((unsigned char*)z)[i]] |
| 694 | - || (z[i]==p->separator[0] && | |
| 695 | - (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){ | |
| 715 | + || (z[i]==p->colSeparator[0] && | |
| 716 | + (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ | |
| 696 | 717 | i = 0; |
| 697 | 718 | break; |
| 698 | 719 | } |
| 699 | 720 | } |
| 700 | 721 | if( i==0 ){ |
| @@ -707,11 +728,11 @@ | ||
| 707 | 728 | }else{ |
| 708 | 729 | fprintf(out, "%s", z); |
| 709 | 730 | } |
| 710 | 731 | } |
| 711 | 732 | if( bSep ){ |
| 712 | - fprintf(p->out, "%s", p->separator); | |
| 733 | + fprintf(p->out, "%s", p->colSeparator); | |
| 713 | 734 | } |
| 714 | 735 | } |
| 715 | 736 | |
| 716 | 737 | #ifdef SIGINT |
| 717 | 738 | /* |
| @@ -745,14 +766,14 @@ | ||
| 745 | 766 | if( azArg==0 ) break; |
| 746 | 767 | for(i=0; i<nArg; i++){ |
| 747 | 768 | int len = strlen30(azCol[i] ? azCol[i] : ""); |
| 748 | 769 | if( len>w ) w = len; |
| 749 | 770 | } |
| 750 | - if( p->cnt++>0 ) fprintf(p->out,"\n"); | |
| 771 | + if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator); | |
| 751 | 772 | for(i=0; i<nArg; i++){ |
| 752 | - fprintf(p->out,"%*s = %s\n", w, azCol[i], | |
| 753 | - azArg[i] ? azArg[i] : p->nullvalue); | |
| 773 | + fprintf(p->out,"%*s = %s%s", w, azCol[i], | |
| 774 | + azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); | |
| 754 | 775 | } |
| 755 | 776 | break; |
| 756 | 777 | } |
| 757 | 778 | case MODE_Explain: |
| 758 | 779 | case MODE_Column: { |
| @@ -765,21 +786,23 @@ | ||
| 765 | 786 | w = 0; |
| 766 | 787 | } |
| 767 | 788 | if( w==0 ){ |
| 768 | 789 | w = strlen30(azCol[i] ? azCol[i] : ""); |
| 769 | 790 | if( w<10 ) w = 10; |
| 770 | - n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue); | |
| 791 | + n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue); | |
| 771 | 792 | if( w<n ) w = n; |
| 772 | 793 | } |
| 773 | 794 | if( i<ArraySize(p->actualWidth) ){ |
| 774 | 795 | p->actualWidth[i] = w; |
| 775 | 796 | } |
| 776 | 797 | if( p->showHeader ){ |
| 777 | 798 | if( w<0 ){ |
| 778 | - fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " "); | |
| 799 | + fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], | |
| 800 | + i==nArg-1 ? p->rowSeparator : " "); | |
| 779 | 801 | }else{ |
| 780 | - fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); | |
| 802 | + fprintf(p->out,"%-*.*s%s",w,w,azCol[i], | |
| 803 | + i==nArg-1 ? p->rowSeparator : " "); | |
| 781 | 804 | } |
| 782 | 805 | } |
| 783 | 806 | } |
| 784 | 807 | if( p->showHeader ){ |
| 785 | 808 | for(i=0; i<nArg; i++){ |
| @@ -790,11 +813,11 @@ | ||
| 790 | 813 | }else{ |
| 791 | 814 | w = 10; |
| 792 | 815 | } |
| 793 | 816 | fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" |
| 794 | 817 | "----------------------------------------------------------", |
| 795 | - i==nArg-1 ? "\n": " "); | |
| 818 | + i==nArg-1 ? p->rowSeparator : " "); | |
| 796 | 819 | } |
| 797 | 820 | } |
| 798 | 821 | } |
| 799 | 822 | if( azArg==0 ) break; |
| 800 | 823 | for(i=0; i<nArg; i++){ |
| @@ -813,36 +836,39 @@ | ||
| 813 | 836 | } |
| 814 | 837 | p->iIndent++; |
| 815 | 838 | } |
| 816 | 839 | if( w<0 ){ |
| 817 | 840 | fprintf(p->out,"%*.*s%s",-w,-w, |
| 818 | - azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); | |
| 841 | + azArg[i] ? azArg[i] : p->nullValue, | |
| 842 | + i==nArg-1 ? p->rowSeparator : " "); | |
| 819 | 843 | }else{ |
| 820 | 844 | fprintf(p->out,"%-*.*s%s",w,w, |
| 821 | - azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); | |
| 845 | + azArg[i] ? azArg[i] : p->nullValue, | |
| 846 | + i==nArg-1 ? p->rowSeparator : " "); | |
| 822 | 847 | } |
| 823 | 848 | } |
| 824 | 849 | break; |
| 825 | 850 | } |
| 826 | 851 | case MODE_Semi: |
| 827 | 852 | case MODE_List: { |
| 828 | 853 | if( p->cnt++==0 && p->showHeader ){ |
| 829 | 854 | for(i=0; i<nArg; i++){ |
| 830 | - fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator); | |
| 855 | + fprintf(p->out,"%s%s",azCol[i], | |
| 856 | + i==nArg-1 ? p->rowSeparator : p->colSeparator); | |
| 831 | 857 | } |
| 832 | 858 | } |
| 833 | 859 | if( azArg==0 ) break; |
| 834 | 860 | for(i=0; i<nArg; i++){ |
| 835 | 861 | char *z = azArg[i]; |
| 836 | - if( z==0 ) z = p->nullvalue; | |
| 862 | + if( z==0 ) z = p->nullValue; | |
| 837 | 863 | fprintf(p->out, "%s", z); |
| 838 | 864 | if( i<nArg-1 ){ |
| 839 | - fprintf(p->out, "%s", p->separator); | |
| 865 | + fprintf(p->out, "%s", p->colSeparator); | |
| 840 | 866 | }else if( p->mode==MODE_Semi ){ |
| 841 | - fprintf(p->out, ";\n"); | |
| 867 | + fprintf(p->out, ";%s", p->rowSeparator); | |
| 842 | 868 | }else{ |
| 843 | - fprintf(p->out, "\n"); | |
| 869 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 844 | 870 | } |
| 845 | 871 | } |
| 846 | 872 | break; |
| 847 | 873 | } |
| 848 | 874 | case MODE_Html: { |
| @@ -857,30 +883,30 @@ | ||
| 857 | 883 | } |
| 858 | 884 | if( azArg==0 ) break; |
| 859 | 885 | fprintf(p->out,"<TR>"); |
| 860 | 886 | for(i=0; i<nArg; i++){ |
| 861 | 887 | fprintf(p->out,"<TD>"); |
| 862 | - output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); | |
| 888 | + output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); | |
| 863 | 889 | fprintf(p->out,"</TD>\n"); |
| 864 | 890 | } |
| 865 | 891 | fprintf(p->out,"</TR>\n"); |
| 866 | 892 | break; |
| 867 | 893 | } |
| 868 | 894 | case MODE_Tcl: { |
| 869 | 895 | if( p->cnt++==0 && p->showHeader ){ |
| 870 | 896 | for(i=0; i<nArg; i++){ |
| 871 | 897 | output_c_string(p->out,azCol[i] ? azCol[i] : ""); |
| 872 | - if(i<nArg-1) fprintf(p->out, "%s", p->separator); | |
| 898 | + if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator); | |
| 873 | 899 | } |
| 874 | - fprintf(p->out,"\n"); | |
| 900 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 875 | 901 | } |
| 876 | 902 | if( azArg==0 ) break; |
| 877 | 903 | for(i=0; i<nArg; i++){ |
| 878 | - output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); | |
| 879 | - if(i<nArg-1) fprintf(p->out, "%s", p->separator); | |
| 904 | + output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); | |
| 905 | + if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator); | |
| 880 | 906 | } |
| 881 | - fprintf(p->out,"\n"); | |
| 907 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 882 | 908 | break; |
| 883 | 909 | } |
| 884 | 910 | case MODE_Csv: { |
| 885 | 911 | #if defined(WIN32) || defined(_WIN32) |
| 886 | 912 | fflush(p->out); |
| @@ -888,17 +914,17 @@ | ||
| 888 | 914 | #endif |
| 889 | 915 | if( p->cnt++==0 && p->showHeader ){ |
| 890 | 916 | for(i=0; i<nArg; i++){ |
| 891 | 917 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 892 | 918 | } |
| 893 | - fprintf(p->out,"%s",p->newline); | |
| 919 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 894 | 920 | } |
| 895 | 921 | if( nArg>0 ){ |
| 896 | 922 | for(i=0; i<nArg; i++){ |
| 897 | 923 | output_csv(p, azArg[i], i<nArg-1); |
| 898 | 924 | } |
| 899 | - fprintf(p->out,"%s",p->newline); | |
| 925 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 900 | 926 | } |
| 901 | 927 | #if defined(WIN32) || defined(_WIN32) |
| 902 | 928 | fflush(p->out); |
| 903 | 929 | _setmode(_fileno(p->out), _O_TEXT); |
| 904 | 930 | #endif |
| @@ -930,10 +956,26 @@ | ||
| 930 | 956 | output_quoted_string(p->out, azArg[i]); |
| 931 | 957 | } |
| 932 | 958 | } |
| 933 | 959 | fprintf(p->out,");\n"); |
| 934 | 960 | break; |
| 961 | + } | |
| 962 | + case MODE_Ascii: { | |
| 963 | + if( p->cnt++==0 && p->showHeader ){ | |
| 964 | + for(i=0; i<nArg; i++){ | |
| 965 | + if( i>0 ) fprintf(p->out, "%s", p->colSeparator); | |
| 966 | + fprintf(p->out,"%s",azCol[i] ? azCol[i] : ""); | |
| 967 | + } | |
| 968 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 969 | + } | |
| 970 | + if( azArg==0 ) break; | |
| 971 | + for(i=0; i<nArg; i++){ | |
| 972 | + if( i>0 ) fprintf(p->out, "%s", p->colSeparator); | |
| 973 | + fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); | |
| 974 | + } | |
| 975 | + fprintf(p->out, "%s", p->rowSeparator); | |
| 976 | + break; | |
| 935 | 977 | } |
| 936 | 978 | } |
| 937 | 979 | return 0; |
| 938 | 980 | } |
| 939 | 981 | |
| @@ -1696,16 +1738,17 @@ | ||
| 1696 | 1738 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1697 | 1739 | ".load FILE ?ENTRY? Load an extension library\n" |
| 1698 | 1740 | #endif |
| 1699 | 1741 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" |
| 1700 | 1742 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" |
| 1743 | + " ascii Columns/rows delimited by 0x1F and 0x1E\n" | |
| 1701 | 1744 | " csv Comma-separated values\n" |
| 1702 | 1745 | " column Left-aligned columns. (See .width)\n" |
| 1703 | 1746 | " html HTML <table> code\n" |
| 1704 | 1747 | " insert SQL insert statements for TABLE\n" |
| 1705 | 1748 | " line One value per line\n" |
| 1706 | - " list Values delimited by .separator string\n" | |
| 1749 | + " list Values delimited by .separator strings\n" | |
| 1707 | 1750 | " tabs Tab-separated values\n" |
| 1708 | 1751 | " tcl TCL list elements\n" |
| 1709 | 1752 | ".nullvalue STRING Use STRING in place of NULL values\n" |
| 1710 | 1753 | ".once FILENAME Output for the next SQL command only to FILENAME\n" |
| 1711 | 1754 | ".open ?FILENAME? Close existing database and reopen FILENAME\n" |
| @@ -1718,12 +1761,12 @@ | ||
| 1718 | 1761 | ".save FILE Write in-memory database into FILE\n" |
| 1719 | 1762 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" |
| 1720 | 1763 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1721 | 1764 | " If TABLE specified, only show tables matching\n" |
| 1722 | 1765 | " LIKE pattern TABLE.\n" |
| 1723 | - ".separator STRING ?NL? Change separator used by output mode and .import\n" | |
| 1724 | - " NL is the end-of-line mark for CSV\n" | |
| 1766 | + ".separator COL ?ROW? Change the column separator and optionally the row\n" | |
| 1767 | + " separator for both the output mode and .import\n" | |
| 1725 | 1768 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1726 | 1769 | ".show Show the current values for various settings\n" |
| 1727 | 1770 | ".stats on|off Turn stats on or off\n" |
| 1728 | 1771 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1729 | 1772 | ".tables ?TABLE? List names of tables\n" |
| @@ -2000,26 +2043,27 @@ | ||
| 2000 | 2043 | static int nCall = 0; |
| 2001 | 2044 | nCall++; |
| 2002 | 2045 | } |
| 2003 | 2046 | |
| 2004 | 2047 | /* |
| 2005 | -** An object used to read a CSV file | |
| 2048 | +** An object used to read a CSV and other files for import. | |
| 2006 | 2049 | */ |
| 2007 | -typedef struct CSVReader CSVReader; | |
| 2008 | -struct CSVReader { | |
| 2050 | +typedef struct ImportCtx ImportCtx; | |
| 2051 | +struct ImportCtx { | |
| 2009 | 2052 | const char *zFile; /* Name of the input file */ |
| 2010 | 2053 | FILE *in; /* Read the CSV text from this input stream */ |
| 2011 | 2054 | char *z; /* Accumulated text for a field */ |
| 2012 | 2055 | int n; /* Number of bytes in z */ |
| 2013 | 2056 | int nAlloc; /* Space allocated for z[] */ |
| 2014 | 2057 | int nLine; /* Current line number */ |
| 2015 | 2058 | int cTerm; /* Character that terminated the most recent field */ |
| 2016 | - int cSeparator; /* The separator character. (Usually ",") */ | |
| 2059 | + int cColSep; /* The column separator character. (Usually ",") */ | |
| 2060 | + int cRowSep; /* The row separator character. (Usually "\n") */ | |
| 2017 | 2061 | }; |
| 2018 | 2062 | |
| 2019 | 2063 | /* Append a single byte to z[] */ |
| 2020 | -static void csv_append_char(CSVReader *p, int c){ | |
| 2064 | +static void import_append_char(ImportCtx *p, int c){ | |
| 2021 | 2065 | if( p->n+1>=p->nAlloc ){ |
| 2022 | 2066 | p->nAlloc += p->nAlloc + 100; |
| 2023 | 2067 | p->z = sqlite3_realloc(p->z, p->nAlloc); |
| 2024 | 2068 | if( p->z==0 ){ |
| 2025 | 2069 | fprintf(stderr, "out of memory\n"); |
| @@ -2033,41 +2077,44 @@ | ||
| 2033 | 2077 | ** with the option of having a separator other than ",". |
| 2034 | 2078 | ** |
| 2035 | 2079 | ** + Input comes from p->in. |
| 2036 | 2080 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2037 | 2081 | ** from sqlite3_malloc(). |
| 2038 | -** + Use p->cSep as the separator. The default is ",". | |
| 2082 | +** + Use p->cSep as the column separator. The default is ",". | |
| 2083 | +** + Use p->rSep as the row separator. The default is "\n". | |
| 2039 | 2084 | ** + Keep track of the line number in p->nLine. |
| 2040 | 2085 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2041 | 2086 | ** EOF on end-of-file. |
| 2042 | 2087 | ** + Report syntax errors on stderr |
| 2043 | 2088 | */ |
| 2044 | -static char *csv_read_one_field(CSVReader *p){ | |
| 2045 | - int c, pc, ppc; | |
| 2046 | - int cSep = p->cSeparator; | |
| 2089 | +static char *csv_read_one_field(ImportCtx *p){ | |
| 2090 | + int c; | |
| 2091 | + int cSep = p->cColSep; | |
| 2092 | + int rSep = p->cRowSep; | |
| 2047 | 2093 | p->n = 0; |
| 2048 | 2094 | c = fgetc(p->in); |
| 2049 | 2095 | if( c==EOF || seenInterrupt ){ |
| 2050 | 2096 | p->cTerm = EOF; |
| 2051 | 2097 | return 0; |
| 2052 | 2098 | } |
| 2053 | 2099 | if( c=='"' ){ |
| 2100 | + int pc, ppc; | |
| 2054 | 2101 | int startLine = p->nLine; |
| 2055 | 2102 | int cQuote = c; |
| 2056 | 2103 | pc = ppc = 0; |
| 2057 | 2104 | while( 1 ){ |
| 2058 | 2105 | c = fgetc(p->in); |
| 2059 | - if( c=='\n' ) p->nLine++; | |
| 2106 | + if( c==rSep ) p->nLine++; | |
| 2060 | 2107 | if( c==cQuote ){ |
| 2061 | 2108 | if( pc==cQuote ){ |
| 2062 | 2109 | pc = 0; |
| 2063 | 2110 | continue; |
| 2064 | 2111 | } |
| 2065 | 2112 | } |
| 2066 | 2113 | if( (c==cSep && pc==cQuote) |
| 2067 | - || (c=='\n' && pc==cQuote) | |
| 2068 | - || (c=='\n' && pc=='\r' && ppc==cQuote) | |
| 2114 | + || (c==rSep && pc==cQuote) | |
| 2115 | + || (c==rSep && pc=='\r' && ppc==cQuote) | |
| 2069 | 2116 | || (c==EOF && pc==cQuote) |
| 2070 | 2117 | ){ |
| 2071 | 2118 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
| 2072 | 2119 | p->cTerm = c; |
| 2073 | 2120 | break; |
| @@ -2077,31 +2124,65 @@ | ||
| 2077 | 2124 | p->zFile, p->nLine, cQuote); |
| 2078 | 2125 | } |
| 2079 | 2126 | if( c==EOF ){ |
| 2080 | 2127 | fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", |
| 2081 | 2128 | p->zFile, startLine, cQuote); |
| 2082 | - p->cTerm = EOF; | |
| 2129 | + p->cTerm = c; | |
| 2083 | 2130 | break; |
| 2084 | 2131 | } |
| 2085 | - csv_append_char(p, c); | |
| 2132 | + import_append_char(p, c); | |
| 2086 | 2133 | ppc = pc; |
| 2087 | 2134 | pc = c; |
| 2088 | 2135 | } |
| 2089 | 2136 | }else{ |
| 2090 | - while( c!=EOF && c!=cSep && c!='\n' ){ | |
| 2091 | - csv_append_char(p, c); | |
| 2137 | + while( c!=EOF && c!=cSep && c!=rSep ){ | |
| 2138 | + import_append_char(p, c); | |
| 2092 | 2139 | c = fgetc(p->in); |
| 2093 | 2140 | } |
| 2094 | - if( c=='\n' ){ | |
| 2141 | + if( c==rSep ){ | |
| 2095 | 2142 | p->nLine++; |
| 2096 | 2143 | if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; |
| 2097 | 2144 | } |
| 2098 | 2145 | p->cTerm = c; |
| 2099 | 2146 | } |
| 2100 | 2147 | if( p->z ) p->z[p->n] = 0; |
| 2101 | 2148 | return p->z; |
| 2102 | 2149 | } |
| 2150 | + | |
| 2151 | +/* Read a single field of ASCII delimited text. | |
| 2152 | +** | |
| 2153 | +** + Input comes from p->in. | |
| 2154 | +** + Store results in p->z of length p->n. Space to hold p->z comes | |
| 2155 | +** from sqlite3_malloc(). | |
| 2156 | +** + Use p->cSep as the column separator. The default is "\x1F". | |
| 2157 | +** + Use p->rSep as the row separator. The default is "\x1E". | |
| 2158 | +** + Keep track of the row number in p->nLine. | |
| 2159 | +** + Store the character that terminates the field in p->cTerm. Store | |
| 2160 | +** EOF on end-of-file. | |
| 2161 | +** + Report syntax errors on stderr | |
| 2162 | +*/ | |
| 2163 | +static char *ascii_read_one_field(ImportCtx *p){ | |
| 2164 | + int c; | |
| 2165 | + int cSep = p->cColSep; | |
| 2166 | + int rSep = p->cRowSep; | |
| 2167 | + p->n = 0; | |
| 2168 | + c = fgetc(p->in); | |
| 2169 | + if( c==EOF || seenInterrupt ){ | |
| 2170 | + p->cTerm = EOF; | |
| 2171 | + return 0; | |
| 2172 | + } | |
| 2173 | + while( c!=EOF && c!=cSep && c!=rSep ){ | |
| 2174 | + import_append_char(p, c); | |
| 2175 | + c = fgetc(p->in); | |
| 2176 | + } | |
| 2177 | + if( c==rSep ){ | |
| 2178 | + p->nLine++; | |
| 2179 | + } | |
| 2180 | + p->cTerm = c; | |
| 2181 | + if( p->z ) p->z[p->n] = 0; | |
| 2182 | + return p->z; | |
| 2183 | +} | |
| 2103 | 2184 | |
| 2104 | 2185 | /* |
| 2105 | 2186 | ** Try to transfer data for table zTable. If an error is seen while |
| 2106 | 2187 | ** moving forward, try to go backwards. The backwards movement won't |
| 2107 | 2188 | ** work for WITHOUT ROWID tables. |
| @@ -2653,100 +2734,125 @@ | ||
| 2653 | 2734 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
| 2654 | 2735 | int nCol; /* Number of columns in the table */ |
| 2655 | 2736 | int nByte; /* Number of bytes in an SQL string */ |
| 2656 | 2737 | int i, j; /* Loop counters */ |
| 2657 | 2738 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
| 2658 | - int nSep; /* Number of bytes in p->separator[] */ | |
| 2739 | + int nSep; /* Number of bytes in p->colSeparator[] */ | |
| 2659 | 2740 | char *zSql; /* An SQL statement */ |
| 2660 | - CSVReader sCsv; /* Reader context */ | |
| 2741 | + ImportCtx sCtx; /* Reader context */ | |
| 2742 | + char *(*xRead)(ImportCtx*); /* Procedure to read one value */ | |
| 2661 | 2743 | int (*xCloser)(FILE*); /* Procedure to close th3 connection */ |
| 2662 | 2744 | |
| 2663 | 2745 | if( nArg!=3 ){ |
| 2664 | 2746 | fprintf(stderr, "Usage: .import FILE TABLE\n"); |
| 2665 | 2747 | goto meta_command_exit; |
| 2666 | 2748 | } |
| 2667 | 2749 | zFile = azArg[1]; |
| 2668 | 2750 | zTable = azArg[2]; |
| 2669 | 2751 | seenInterrupt = 0; |
| 2670 | - memset(&sCsv, 0, sizeof(sCsv)); | |
| 2752 | + memset(&sCtx, 0, sizeof(sCtx)); | |
| 2671 | 2753 | open_db(p, 0); |
| 2672 | - nSep = strlen30(p->separator); | |
| 2754 | + nSep = strlen30(p->colSeparator); | |
| 2755 | + if( nSep==0 ){ | |
| 2756 | + fprintf(stderr, "Error: non-null column separator required for import\n"); | |
| 2757 | + return 1; | |
| 2758 | + } | |
| 2759 | + if( nSep>1 ){ | |
| 2760 | + fprintf(stderr, "Error: multi-character column separators not allowed" | |
| 2761 | + " for import\n"); | |
| 2762 | + return 1; | |
| 2763 | + } | |
| 2764 | + nSep = strlen30(p->rowSeparator); | |
| 2673 | 2765 | if( nSep==0 ){ |
| 2674 | - fprintf(stderr, "Error: non-null separator required for import\n"); | |
| 2766 | + fprintf(stderr, "Error: non-null row separator required for import\n"); | |
| 2675 | 2767 | return 1; |
| 2768 | + } | |
| 2769 | + if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ | |
| 2770 | + /* When importing CSV (only), if the row separator is set to the | |
| 2771 | + ** default output row separator, change it to the default input | |
| 2772 | + ** row separator. This avoids having to maintain different input | |
| 2773 | + ** and output row separators. */ | |
| 2774 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 2775 | + nSep = strlen30(p->rowSeparator); | |
| 2676 | 2776 | } |
| 2677 | 2777 | if( nSep>1 ){ |
| 2678 | - fprintf(stderr, "Error: multi-character separators not allowed" | |
| 2778 | + fprintf(stderr, "Error: multi-character row separators not allowed" | |
| 2679 | 2779 | " for import\n"); |
| 2680 | 2780 | return 1; |
| 2681 | 2781 | } |
| 2682 | - sCsv.zFile = zFile; | |
| 2683 | - sCsv.nLine = 1; | |
| 2684 | - if( sCsv.zFile[0]=='|' ){ | |
| 2685 | - sCsv.in = popen(sCsv.zFile+1, "r"); | |
| 2686 | - sCsv.zFile = "<pipe>"; | |
| 2782 | + sCtx.zFile = zFile; | |
| 2783 | + sCtx.nLine = 1; | |
| 2784 | + if( sCtx.zFile[0]=='|' ){ | |
| 2785 | + sCtx.in = popen(sCtx.zFile+1, "r"); | |
| 2786 | + sCtx.zFile = "<pipe>"; | |
| 2687 | 2787 | xCloser = pclose; |
| 2688 | 2788 | }else{ |
| 2689 | - sCsv.in = fopen(sCsv.zFile, "rb"); | |
| 2789 | + sCtx.in = fopen(sCtx.zFile, "rb"); | |
| 2690 | 2790 | xCloser = fclose; |
| 2691 | 2791 | } |
| 2692 | - if( sCsv.in==0 ){ | |
| 2792 | + if( p->mode==MODE_Ascii ){ | |
| 2793 | + xRead = ascii_read_one_field; | |
| 2794 | + }else{ | |
| 2795 | + xRead = csv_read_one_field; | |
| 2796 | + } | |
| 2797 | + if( sCtx.in==0 ){ | |
| 2693 | 2798 | fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); |
| 2694 | 2799 | return 1; |
| 2695 | 2800 | } |
| 2696 | - sCsv.cSeparator = p->separator[0]; | |
| 2801 | + sCtx.cColSep = p->colSeparator[0]; | |
| 2802 | + sCtx.cRowSep = p->rowSeparator[0]; | |
| 2697 | 2803 | zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); |
| 2698 | 2804 | if( zSql==0 ){ |
| 2699 | 2805 | fprintf(stderr, "Error: out of memory\n"); |
| 2700 | - xCloser(sCsv.in); | |
| 2806 | + xCloser(sCtx.in); | |
| 2701 | 2807 | return 1; |
| 2702 | 2808 | } |
| 2703 | 2809 | nByte = strlen30(zSql); |
| 2704 | 2810 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2705 | - csv_append_char(&sCsv, 0); /* To ensure sCsv.z is allocated */ | |
| 2811 | + import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ | |
| 2706 | 2812 | if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ |
| 2707 | 2813 | char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
| 2708 | 2814 | char cSep = '('; |
| 2709 | - while( csv_read_one_field(&sCsv) ){ | |
| 2710 | - zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z); | |
| 2815 | + while( xRead(&sCtx) ){ | |
| 2816 | + zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z); | |
| 2711 | 2817 | cSep = ','; |
| 2712 | - if( sCsv.cTerm!=sCsv.cSeparator ) break; | |
| 2818 | + if( sCtx.cTerm!=sCtx.cColSep ) break; | |
| 2713 | 2819 | } |
| 2714 | 2820 | if( cSep=='(' ){ |
| 2715 | 2821 | sqlite3_free(zCreate); |
| 2716 | - sqlite3_free(sCsv.z); | |
| 2717 | - xCloser(sCsv.in); | |
| 2718 | - fprintf(stderr,"%s: empty file\n", sCsv.zFile); | |
| 2822 | + sqlite3_free(sCtx.z); | |
| 2823 | + xCloser(sCtx.in); | |
| 2824 | + fprintf(stderr,"%s: empty file\n", sCtx.zFile); | |
| 2719 | 2825 | return 1; |
| 2720 | 2826 | } |
| 2721 | 2827 | zCreate = sqlite3_mprintf("%z\n)", zCreate); |
| 2722 | 2828 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
| 2723 | 2829 | sqlite3_free(zCreate); |
| 2724 | 2830 | if( rc ){ |
| 2725 | 2831 | fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
| 2726 | 2832 | sqlite3_errmsg(db)); |
| 2727 | - sqlite3_free(sCsv.z); | |
| 2728 | - xCloser(sCsv.in); | |
| 2833 | + sqlite3_free(sCtx.z); | |
| 2834 | + xCloser(sCtx.in); | |
| 2729 | 2835 | return 1; |
| 2730 | 2836 | } |
| 2731 | 2837 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2732 | 2838 | } |
| 2733 | 2839 | sqlite3_free(zSql); |
| 2734 | 2840 | if( rc ){ |
| 2735 | 2841 | if (pStmt) sqlite3_finalize(pStmt); |
| 2736 | 2842 | fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |
| 2737 | - xCloser(sCsv.in); | |
| 2843 | + xCloser(sCtx.in); | |
| 2738 | 2844 | return 1; |
| 2739 | 2845 | } |
| 2740 | 2846 | nCol = sqlite3_column_count(pStmt); |
| 2741 | 2847 | sqlite3_finalize(pStmt); |
| 2742 | 2848 | pStmt = 0; |
| 2743 | 2849 | if( nCol==0 ) return 0; /* no columns, no error */ |
| 2744 | 2850 | zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); |
| 2745 | 2851 | if( zSql==0 ){ |
| 2746 | 2852 | fprintf(stderr, "Error: out of memory\n"); |
| 2747 | - xCloser(sCsv.in); | |
| 2853 | + xCloser(sCtx.in); | |
| 2748 | 2854 | return 1; |
| 2749 | 2855 | } |
| 2750 | 2856 | sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); |
| 2751 | 2857 | j = strlen30(zSql); |
| 2752 | 2858 | for(i=1; i<nCol; i++){ |
| @@ -2758,50 +2864,60 @@ | ||
| 2758 | 2864 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2759 | 2865 | sqlite3_free(zSql); |
| 2760 | 2866 | if( rc ){ |
| 2761 | 2867 | fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |
| 2762 | 2868 | if (pStmt) sqlite3_finalize(pStmt); |
| 2763 | - xCloser(sCsv.in); | |
| 2869 | + xCloser(sCtx.in); | |
| 2764 | 2870 | return 1; |
| 2765 | 2871 | } |
| 2766 | 2872 | needCommit = sqlite3_get_autocommit(db); |
| 2767 | 2873 | if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); |
| 2768 | 2874 | do{ |
| 2769 | - int startLine = sCsv.nLine; | |
| 2875 | + int startLine = sCtx.nLine; | |
| 2770 | 2876 | for(i=0; i<nCol; i++){ |
| 2771 | - char *z = csv_read_one_field(&sCsv); | |
| 2877 | + char *z = xRead(&sCtx); | |
| 2878 | + /* | |
| 2879 | + ** Did we reach end-of-file before finding any columns? | |
| 2880 | + ** If so, stop instead of NULL filling the remaining columns. | |
| 2881 | + */ | |
| 2772 | 2882 | if( z==0 && i==0 ) break; |
| 2883 | + /* | |
| 2884 | + ** Did we reach end-of-file OR end-of-line before finding any | |
| 2885 | + ** columns in ASCII mode? If so, stop instead of NULL filling | |
| 2886 | + ** the remaining columns. | |
| 2887 | + */ | |
| 2888 | + if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; | |
| 2773 | 2889 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2774 | - if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){ | |
| 2890 | + if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ | |
| 2775 | 2891 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2776 | 2892 | "filling the rest with NULL\n", |
| 2777 | - sCsv.zFile, startLine, nCol, i+1); | |
| 2893 | + sCtx.zFile, startLine, nCol, i+1); | |
| 2778 | 2894 | i++; |
| 2779 | 2895 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2780 | 2896 | } |
| 2781 | 2897 | } |
| 2782 | - if( sCsv.cTerm==sCsv.cSeparator ){ | |
| 2898 | + if( sCtx.cTerm==sCtx.cColSep ){ | |
| 2783 | 2899 | do{ |
| 2784 | - csv_read_one_field(&sCsv); | |
| 2900 | + xRead(&sCtx); | |
| 2785 | 2901 | i++; |
| 2786 | - }while( sCsv.cTerm==sCsv.cSeparator ); | |
| 2902 | + }while( sCtx.cTerm==sCtx.cColSep ); | |
| 2787 | 2903 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2788 | 2904 | "extras ignored\n", |
| 2789 | - sCsv.zFile, startLine, nCol, i); | |
| 2905 | + sCtx.zFile, startLine, nCol, i); | |
| 2790 | 2906 | } |
| 2791 | 2907 | if( i>=nCol ){ |
| 2792 | 2908 | sqlite3_step(pStmt); |
| 2793 | 2909 | rc = sqlite3_reset(pStmt); |
| 2794 | 2910 | if( rc!=SQLITE_OK ){ |
| 2795 | - fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine, | |
| 2911 | + fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, | |
| 2796 | 2912 | sqlite3_errmsg(db)); |
| 2797 | 2913 | } |
| 2798 | 2914 | } |
| 2799 | - }while( sCsv.cTerm!=EOF ); | |
| 2915 | + }while( sCtx.cTerm!=EOF ); | |
| 2800 | 2916 | |
| 2801 | - xCloser(sCsv.in); | |
| 2802 | - sqlite3_free(sCsv.z); | |
| 2917 | + xCloser(sCtx.in); | |
| 2918 | + sqlite3_free(sCtx.z); | |
| 2803 | 2919 | sqlite3_finalize(pStmt); |
| 2804 | 2920 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2805 | 2921 | }else |
| 2806 | 2922 | |
| 2807 | 2923 | if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ |
| @@ -2915,32 +3031,36 @@ | ||
| 2915 | 3031 | p->mode = MODE_List; |
| 2916 | 3032 | }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ |
| 2917 | 3033 | p->mode = MODE_Html; |
| 2918 | 3034 | }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ |
| 2919 | 3035 | p->mode = MODE_Tcl; |
| 2920 | - sqlite3_snprintf(sizeof(p->separator), p->separator, " "); | |
| 3036 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); | |
| 2921 | 3037 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 2922 | 3038 | p->mode = MODE_Csv; |
| 2923 | - sqlite3_snprintf(sizeof(p->separator), p->separator, ","); | |
| 2924 | - sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n"); | |
| 3039 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); | |
| 3040 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); | |
| 2925 | 3041 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 2926 | 3042 | p->mode = MODE_List; |
| 2927 | - sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); | |
| 3043 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); | |
| 2928 | 3044 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 2929 | 3045 | p->mode = MODE_Insert; |
| 2930 | 3046 | set_table_name(p, nArg>=3 ? azArg[2] : "table"); |
| 3047 | + }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ | |
| 3048 | + p->mode = MODE_Ascii; | |
| 3049 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); | |
| 3050 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); | |
| 2931 | 3051 | }else { |
| 2932 | 3052 | fprintf(stderr,"Error: mode should be one of: " |
| 2933 | - "column csv html insert line list tabs tcl\n"); | |
| 3053 | + "ascii column csv html insert line list tabs tcl\n"); | |
| 2934 | 3054 | rc = 1; |
| 2935 | 3055 | } |
| 2936 | 3056 | }else |
| 2937 | 3057 | |
| 2938 | 3058 | if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ |
| 2939 | 3059 | if( nArg==2 ){ |
| 2940 | - sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, | |
| 2941 | - "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); | |
| 3060 | + sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, | |
| 3061 | + "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); | |
| 2942 | 3062 | }else{ |
| 2943 | 3063 | fprintf(stderr, "Usage: .nullvalue STRING\n"); |
| 2944 | 3064 | rc = 1; |
| 2945 | 3065 | } |
| 2946 | 3066 | }else |
| @@ -3221,18 +3341,20 @@ | ||
| 3221 | 3341 | }else |
| 3222 | 3342 | #endif |
| 3223 | 3343 | |
| 3224 | 3344 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3225 | 3345 | if( nArg<2 || nArg>3 ){ |
| 3226 | - fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n"); | |
| 3346 | + fprintf(stderr, "Usage: .separator COL ?ROW?\n"); | |
| 3227 | 3347 | rc = 1; |
| 3228 | 3348 | } |
| 3229 | 3349 | if( nArg>=2 ){ |
| 3230 | - sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]); | |
| 3350 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, | |
| 3351 | + "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); | |
| 3231 | 3352 | } |
| 3232 | 3353 | if( nArg>=3 ){ |
| 3233 | - sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]); | |
| 3354 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, | |
| 3355 | + "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); | |
| 3234 | 3356 | } |
| 3235 | 3357 | }else |
| 3236 | 3358 | |
| 3237 | 3359 | if( c=='s' |
| 3238 | 3360 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| @@ -3259,27 +3381,28 @@ | ||
| 3259 | 3381 | if( nArg!=1 ){ |
| 3260 | 3382 | fprintf(stderr, "Usage: .show\n"); |
| 3261 | 3383 | rc = 1; |
| 3262 | 3384 | goto meta_command_exit; |
| 3263 | 3385 | } |
| 3264 | - fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); | |
| 3265 | - fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off"); | |
| 3386 | + fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); | |
| 3387 | + fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); | |
| 3266 | 3388 | fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off"); |
| 3267 | - fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); | |
| 3268 | - fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); | |
| 3269 | - fprintf(p->out,"%9.9s: ", "nullvalue"); | |
| 3270 | - output_c_string(p->out, p->nullvalue); | |
| 3389 | + fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); | |
| 3390 | + fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]); | |
| 3391 | + fprintf(p->out,"%12.12s: ", "nullvalue"); | |
| 3392 | + output_c_string(p->out, p->nullValue); | |
| 3271 | 3393 | fprintf(p->out, "\n"); |
| 3272 | - fprintf(p->out,"%9.9s: %s\n","output", | |
| 3394 | + fprintf(p->out,"%12.12s: %s\n","output", | |
| 3273 | 3395 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3274 | - fprintf(p->out,"%9.9s: ", "separator"); | |
| 3275 | - output_c_string(p->out, p->separator); | |
| 3276 | - fprintf(p->out," "); | |
| 3277 | - output_c_string(p->out, p->newline); | |
| 3396 | + fprintf(p->out,"%12.12s: ", "colseparator"); | |
| 3397 | + output_c_string(p->out, p->colSeparator); | |
| 3398 | + fprintf(p->out, "\n"); | |
| 3399 | + fprintf(p->out,"%12.12s: ", "rowseparator"); | |
| 3400 | + output_c_string(p->out, p->rowSeparator); | |
| 3278 | 3401 | fprintf(p->out, "\n"); |
| 3279 | - fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); | |
| 3280 | - fprintf(p->out,"%9.9s: ","width"); | |
| 3402 | + fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); | |
| 3403 | + fprintf(p->out,"%12.12s: ","width"); | |
| 3281 | 3404 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3282 | 3405 | fprintf(p->out,"%d ",p->colWidth[i]); |
| 3283 | 3406 | } |
| 3284 | 3407 | fprintf(p->out,"\n"); |
| 3285 | 3408 | }else |
| @@ -3936,10 +4059,11 @@ | ||
| 3936 | 4059 | |
| 3937 | 4060 | /* |
| 3938 | 4061 | ** Show available command line options |
| 3939 | 4062 | */ |
| 3940 | 4063 | static const char zOptions[] = |
| 4064 | + " -ascii set output mode to 'ascii'\n" | |
| 3941 | 4065 | " -bail stop after hitting an error\n" |
| 3942 | 4066 | " -batch force batch I/O\n" |
| 3943 | 4067 | " -column set output mode to 'column'\n" |
| 3944 | 4068 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
| 3945 | 4069 | " -csv set output mode to 'csv'\n" |
| @@ -3957,15 +4081,15 @@ | ||
| 3957 | 4081 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| 3958 | 4082 | " -mmap N default mmap size set to N\n" |
| 3959 | 4083 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 3960 | 4084 | " -multiplex enable the multiplexor VFS\n" |
| 3961 | 4085 | #endif |
| 3962 | - " -newline SEP set newline character(s) for CSV\n" | |
| 4086 | + " -newline SEP set output row separator. Default: '\\n'\n" | |
| 3963 | 4087 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 3964 | 4088 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
| 3965 | 4089 | " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" |
| 3966 | - " -separator SEP set output field separator. Default: '|'\n" | |
| 4090 | + " -separator SEP set output column separator. Default: '|'\n" | |
| 3967 | 4091 | " -stats print memory stats before each finalize\n" |
| 3968 | 4092 | " -version show SQLite version\n" |
| 3969 | 4093 | " -vfs NAME use NAME as the default VFS\n" |
| 3970 | 4094 | #ifdef SQLITE_ENABLE_VFSTRACE |
| 3971 | 4095 | " -vfstrace enable tracing of all VFS calls\n" |
| @@ -3988,12 +4112,12 @@ | ||
| 3988 | 4112 | ** Initialize the state information in data |
| 3989 | 4113 | */ |
| 3990 | 4114 | static void main_init(ShellState *data) { |
| 3991 | 4115 | memset(data, 0, sizeof(*data)); |
| 3992 | 4116 | data->mode = MODE_List; |
| 3993 | - memcpy(data->separator,"|", 2); | |
| 3994 | - memcpy(data->newline,"\r\n", 3); | |
| 4117 | + memcpy(data->colSeparator,SEP_Column, 2); | |
| 4118 | + memcpy(data->rowSeparator,SEP_Row, 2); | |
| 3995 | 4119 | data->showHeader = 0; |
| 3996 | 4120 | data->shellFlgs = SHFLG_Lookaside; |
| 3997 | 4121 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 3998 | 4122 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 3999 | 4123 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| @@ -4228,19 +4352,25 @@ | ||
| 4228 | 4352 | data.mode = MODE_Line; |
| 4229 | 4353 | }else if( strcmp(z,"-column")==0 ){ |
| 4230 | 4354 | data.mode = MODE_Column; |
| 4231 | 4355 | }else if( strcmp(z,"-csv")==0 ){ |
| 4232 | 4356 | data.mode = MODE_Csv; |
| 4233 | - memcpy(data.separator,",",2); | |
| 4357 | + memcpy(data.colSeparator,",",2); | |
| 4358 | + }else if( strcmp(z,"-ascii")==0 ){ | |
| 4359 | + data.mode = MODE_Ascii; | |
| 4360 | + sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, | |
| 4361 | + SEP_Unit); | |
| 4362 | + sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, | |
| 4363 | + SEP_Record); | |
| 4234 | 4364 | }else if( strcmp(z,"-separator")==0 ){ |
| 4235 | - sqlite3_snprintf(sizeof(data.separator), data.separator, | |
| 4365 | + sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, | |
| 4236 | 4366 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4237 | 4367 | }else if( strcmp(z,"-newline")==0 ){ |
| 4238 | - sqlite3_snprintf(sizeof(data.newline), data.newline, | |
| 4368 | + sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, | |
| 4239 | 4369 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4240 | 4370 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 4241 | - sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, | |
| 4371 | + sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, | |
| 4242 | 4372 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4243 | 4373 | }else if( strcmp(z,"-header")==0 ){ |
| 4244 | 4374 | data.showHeader = 1; |
| 4245 | 4375 | }else if( strcmp(z,"-noheader")==0 ){ |
| 4246 | 4376 | data.showHeader = 0; |
| @@ -4356,11 +4486,11 @@ | ||
| 4356 | 4486 | nHistory = strlen30(zHome) + 20; |
| 4357 | 4487 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 4358 | 4488 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
| 4359 | 4489 | } |
| 4360 | 4490 | } |
| 4361 | -#if defined(HAVE_READLINE) | |
| 4491 | +#if HAVE_READLINE | |
| 4362 | 4492 | if( zHistory ) read_history(zHistory); |
| 4363 | 4493 | #endif |
| 4364 | 4494 | rc = process_input(&data, 0); |
| 4365 | 4495 | if( zHistory ){ |
| 4366 | 4496 | stifle_history(100); |
| 4367 | 4497 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -15,10 +15,17 @@ | |
| 15 | #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) |
| 16 | /* This needs to come before any includes for MSVC compiler */ |
| 17 | #define _CRT_SECURE_NO_WARNINGS |
| 18 | #endif |
| 19 | |
| 20 | /* |
| 21 | ** Enable large-file support for fopen() and friends on unix. |
| 22 | */ |
| 23 | #ifndef SQLITE_DISABLE_LFS |
| 24 | # define _LARGE_FILE 1 |
| @@ -46,21 +53,20 @@ | |
| 46 | # endif |
| 47 | # include <unistd.h> |
| 48 | # include <sys/types.h> |
| 49 | #endif |
| 50 | |
| 51 | #if defined(HAVE_READLINE) && HAVE_READLINE!=0 |
| 52 | # include <readline/readline.h> |
| 53 | # include <readline/history.h> |
| 54 | #else |
| 55 | # undef HAVE_READLINE |
| 56 | #endif |
| 57 | #if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE) |
| 58 | # define HAVE_READLINE 1 |
| 59 | # include <editline/readline.h> |
| 60 | #endif |
| 61 | #if !defined(HAVE_READLINE) |
| 62 | # define add_history(X) |
| 63 | # define read_history(X) |
| 64 | # define write_history(X) |
| 65 | # define stifle_history(X) |
| 66 | #endif |
| @@ -423,11 +429,11 @@ | |
| 423 | char *zResult; |
| 424 | if( in!=0 ){ |
| 425 | zResult = local_getline(zPrior, in); |
| 426 | }else{ |
| 427 | zPrompt = isContinuation ? continuePrompt : mainPrompt; |
| 428 | #if defined(HAVE_READLINE) |
| 429 | free(zPrior); |
| 430 | zResult = readline(zPrompt); |
| 431 | if( zResult && *zResult ) add_history(zResult); |
| 432 | #else |
| 433 | printf("%s", zPrompt); |
| @@ -469,15 +475,15 @@ | |
| 469 | int mode; /* An output mode setting */ |
| 470 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
| 471 | int showHeader; /* True to show column names in List or Column mode */ |
| 472 | unsigned shellFlgs; /* Various flags */ |
| 473 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
| 474 | char separator[20]; /* Separator character for MODE_List */ |
| 475 | char newline[20]; /* Record separator in MODE_Csv */ |
| 476 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
| 477 | int actualWidth[100]; /* Actual width of each column */ |
| 478 | char nullvalue[20]; /* The text to print when a NULL comes back from |
| 479 | ** the database */ |
| 480 | SavedModeInfo normalMode;/* Holds the mode just before .explain ON */ |
| 481 | char outfile[FILENAME_MAX]; /* Filename for *out */ |
| 482 | const char *zDbFilename; /* name of the database file */ |
| 483 | char *zFreeOnClose; /* Filename to free when closing */ |
| @@ -506,10 +512,11 @@ | |
| 506 | #define MODE_Html 4 /* Generate an XHTML table */ |
| 507 | #define MODE_Insert 5 /* Generate SQL "insert" statements */ |
| 508 | #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ |
| 509 | #define MODE_Csv 7 /* Quote strings, numbers are plain */ |
| 510 | #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ |
| 511 | |
| 512 | static const char *modeDescr[] = { |
| 513 | "line", |
| 514 | "column", |
| 515 | "list", |
| @@ -517,12 +524,26 @@ | |
| 517 | "html", |
| 518 | "insert", |
| 519 | "tcl", |
| 520 | "csv", |
| 521 | "explain", |
| 522 | }; |
| 523 | |
| 524 | /* |
| 525 | ** Number of elements in an array |
| 526 | */ |
| 527 | #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) |
| 528 | |
| @@ -675,26 +696,26 @@ | |
| 675 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 676 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 677 | }; |
| 678 | |
| 679 | /* |
| 680 | ** Output a single term of CSV. Actually, p->separator is used for |
| 681 | ** the separator, which may or may not be a comma. p->nullvalue is |
| 682 | ** the null value. Strings are quoted if necessary. The separator |
| 683 | ** is only issued if bSep is true. |
| 684 | */ |
| 685 | static void output_csv(ShellState *p, const char *z, int bSep){ |
| 686 | FILE *out = p->out; |
| 687 | if( z==0 ){ |
| 688 | fprintf(out,"%s",p->nullvalue); |
| 689 | }else{ |
| 690 | int i; |
| 691 | int nSep = strlen30(p->separator); |
| 692 | for(i=0; z[i]; i++){ |
| 693 | if( needCsvQuote[((unsigned char*)z)[i]] |
| 694 | || (z[i]==p->separator[0] && |
| 695 | (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){ |
| 696 | i = 0; |
| 697 | break; |
| 698 | } |
| 699 | } |
| 700 | if( i==0 ){ |
| @@ -707,11 +728,11 @@ | |
| 707 | }else{ |
| 708 | fprintf(out, "%s", z); |
| 709 | } |
| 710 | } |
| 711 | if( bSep ){ |
| 712 | fprintf(p->out, "%s", p->separator); |
| 713 | } |
| 714 | } |
| 715 | |
| 716 | #ifdef SIGINT |
| 717 | /* |
| @@ -745,14 +766,14 @@ | |
| 745 | if( azArg==0 ) break; |
| 746 | for(i=0; i<nArg; i++){ |
| 747 | int len = strlen30(azCol[i] ? azCol[i] : ""); |
| 748 | if( len>w ) w = len; |
| 749 | } |
| 750 | if( p->cnt++>0 ) fprintf(p->out,"\n"); |
| 751 | for(i=0; i<nArg; i++){ |
| 752 | fprintf(p->out,"%*s = %s\n", w, azCol[i], |
| 753 | azArg[i] ? azArg[i] : p->nullvalue); |
| 754 | } |
| 755 | break; |
| 756 | } |
| 757 | case MODE_Explain: |
| 758 | case MODE_Column: { |
| @@ -765,21 +786,23 @@ | |
| 765 | w = 0; |
| 766 | } |
| 767 | if( w==0 ){ |
| 768 | w = strlen30(azCol[i] ? azCol[i] : ""); |
| 769 | if( w<10 ) w = 10; |
| 770 | n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue); |
| 771 | if( w<n ) w = n; |
| 772 | } |
| 773 | if( i<ArraySize(p->actualWidth) ){ |
| 774 | p->actualWidth[i] = w; |
| 775 | } |
| 776 | if( p->showHeader ){ |
| 777 | if( w<0 ){ |
| 778 | fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " "); |
| 779 | }else{ |
| 780 | fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " "); |
| 781 | } |
| 782 | } |
| 783 | } |
| 784 | if( p->showHeader ){ |
| 785 | for(i=0; i<nArg; i++){ |
| @@ -790,11 +813,11 @@ | |
| 790 | }else{ |
| 791 | w = 10; |
| 792 | } |
| 793 | fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" |
| 794 | "----------------------------------------------------------", |
| 795 | i==nArg-1 ? "\n": " "); |
| 796 | } |
| 797 | } |
| 798 | } |
| 799 | if( azArg==0 ) break; |
| 800 | for(i=0; i<nArg; i++){ |
| @@ -813,36 +836,39 @@ | |
| 813 | } |
| 814 | p->iIndent++; |
| 815 | } |
| 816 | if( w<0 ){ |
| 817 | fprintf(p->out,"%*.*s%s",-w,-w, |
| 818 | azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); |
| 819 | }else{ |
| 820 | fprintf(p->out,"%-*.*s%s",w,w, |
| 821 | azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " "); |
| 822 | } |
| 823 | } |
| 824 | break; |
| 825 | } |
| 826 | case MODE_Semi: |
| 827 | case MODE_List: { |
| 828 | if( p->cnt++==0 && p->showHeader ){ |
| 829 | for(i=0; i<nArg; i++){ |
| 830 | fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator); |
| 831 | } |
| 832 | } |
| 833 | if( azArg==0 ) break; |
| 834 | for(i=0; i<nArg; i++){ |
| 835 | char *z = azArg[i]; |
| 836 | if( z==0 ) z = p->nullvalue; |
| 837 | fprintf(p->out, "%s", z); |
| 838 | if( i<nArg-1 ){ |
| 839 | fprintf(p->out, "%s", p->separator); |
| 840 | }else if( p->mode==MODE_Semi ){ |
| 841 | fprintf(p->out, ";\n"); |
| 842 | }else{ |
| 843 | fprintf(p->out, "\n"); |
| 844 | } |
| 845 | } |
| 846 | break; |
| 847 | } |
| 848 | case MODE_Html: { |
| @@ -857,30 +883,30 @@ | |
| 857 | } |
| 858 | if( azArg==0 ) break; |
| 859 | fprintf(p->out,"<TR>"); |
| 860 | for(i=0; i<nArg; i++){ |
| 861 | fprintf(p->out,"<TD>"); |
| 862 | output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); |
| 863 | fprintf(p->out,"</TD>\n"); |
| 864 | } |
| 865 | fprintf(p->out,"</TR>\n"); |
| 866 | break; |
| 867 | } |
| 868 | case MODE_Tcl: { |
| 869 | if( p->cnt++==0 && p->showHeader ){ |
| 870 | for(i=0; i<nArg; i++){ |
| 871 | output_c_string(p->out,azCol[i] ? azCol[i] : ""); |
| 872 | if(i<nArg-1) fprintf(p->out, "%s", p->separator); |
| 873 | } |
| 874 | fprintf(p->out,"\n"); |
| 875 | } |
| 876 | if( azArg==0 ) break; |
| 877 | for(i=0; i<nArg; i++){ |
| 878 | output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); |
| 879 | if(i<nArg-1) fprintf(p->out, "%s", p->separator); |
| 880 | } |
| 881 | fprintf(p->out,"\n"); |
| 882 | break; |
| 883 | } |
| 884 | case MODE_Csv: { |
| 885 | #if defined(WIN32) || defined(_WIN32) |
| 886 | fflush(p->out); |
| @@ -888,17 +914,17 @@ | |
| 888 | #endif |
| 889 | if( p->cnt++==0 && p->showHeader ){ |
| 890 | for(i=0; i<nArg; i++){ |
| 891 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 892 | } |
| 893 | fprintf(p->out,"%s",p->newline); |
| 894 | } |
| 895 | if( nArg>0 ){ |
| 896 | for(i=0; i<nArg; i++){ |
| 897 | output_csv(p, azArg[i], i<nArg-1); |
| 898 | } |
| 899 | fprintf(p->out,"%s",p->newline); |
| 900 | } |
| 901 | #if defined(WIN32) || defined(_WIN32) |
| 902 | fflush(p->out); |
| 903 | _setmode(_fileno(p->out), _O_TEXT); |
| 904 | #endif |
| @@ -930,10 +956,26 @@ | |
| 930 | output_quoted_string(p->out, azArg[i]); |
| 931 | } |
| 932 | } |
| 933 | fprintf(p->out,");\n"); |
| 934 | break; |
| 935 | } |
| 936 | } |
| 937 | return 0; |
| 938 | } |
| 939 | |
| @@ -1696,16 +1738,17 @@ | |
| 1696 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1697 | ".load FILE ?ENTRY? Load an extension library\n" |
| 1698 | #endif |
| 1699 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" |
| 1700 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" |
| 1701 | " csv Comma-separated values\n" |
| 1702 | " column Left-aligned columns. (See .width)\n" |
| 1703 | " html HTML <table> code\n" |
| 1704 | " insert SQL insert statements for TABLE\n" |
| 1705 | " line One value per line\n" |
| 1706 | " list Values delimited by .separator string\n" |
| 1707 | " tabs Tab-separated values\n" |
| 1708 | " tcl TCL list elements\n" |
| 1709 | ".nullvalue STRING Use STRING in place of NULL values\n" |
| 1710 | ".once FILENAME Output for the next SQL command only to FILENAME\n" |
| 1711 | ".open ?FILENAME? Close existing database and reopen FILENAME\n" |
| @@ -1718,12 +1761,12 @@ | |
| 1718 | ".save FILE Write in-memory database into FILE\n" |
| 1719 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" |
| 1720 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1721 | " If TABLE specified, only show tables matching\n" |
| 1722 | " LIKE pattern TABLE.\n" |
| 1723 | ".separator STRING ?NL? Change separator used by output mode and .import\n" |
| 1724 | " NL is the end-of-line mark for CSV\n" |
| 1725 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1726 | ".show Show the current values for various settings\n" |
| 1727 | ".stats on|off Turn stats on or off\n" |
| 1728 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1729 | ".tables ?TABLE? List names of tables\n" |
| @@ -2000,26 +2043,27 @@ | |
| 2000 | static int nCall = 0; |
| 2001 | nCall++; |
| 2002 | } |
| 2003 | |
| 2004 | /* |
| 2005 | ** An object used to read a CSV file |
| 2006 | */ |
| 2007 | typedef struct CSVReader CSVReader; |
| 2008 | struct CSVReader { |
| 2009 | const char *zFile; /* Name of the input file */ |
| 2010 | FILE *in; /* Read the CSV text from this input stream */ |
| 2011 | char *z; /* Accumulated text for a field */ |
| 2012 | int n; /* Number of bytes in z */ |
| 2013 | int nAlloc; /* Space allocated for z[] */ |
| 2014 | int nLine; /* Current line number */ |
| 2015 | int cTerm; /* Character that terminated the most recent field */ |
| 2016 | int cSeparator; /* The separator character. (Usually ",") */ |
| 2017 | }; |
| 2018 | |
| 2019 | /* Append a single byte to z[] */ |
| 2020 | static void csv_append_char(CSVReader *p, int c){ |
| 2021 | if( p->n+1>=p->nAlloc ){ |
| 2022 | p->nAlloc += p->nAlloc + 100; |
| 2023 | p->z = sqlite3_realloc(p->z, p->nAlloc); |
| 2024 | if( p->z==0 ){ |
| 2025 | fprintf(stderr, "out of memory\n"); |
| @@ -2033,41 +2077,44 @@ | |
| 2033 | ** with the option of having a separator other than ",". |
| 2034 | ** |
| 2035 | ** + Input comes from p->in. |
| 2036 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2037 | ** from sqlite3_malloc(). |
| 2038 | ** + Use p->cSep as the separator. The default is ",". |
| 2039 | ** + Keep track of the line number in p->nLine. |
| 2040 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2041 | ** EOF on end-of-file. |
| 2042 | ** + Report syntax errors on stderr |
| 2043 | */ |
| 2044 | static char *csv_read_one_field(CSVReader *p){ |
| 2045 | int c, pc, ppc; |
| 2046 | int cSep = p->cSeparator; |
| 2047 | p->n = 0; |
| 2048 | c = fgetc(p->in); |
| 2049 | if( c==EOF || seenInterrupt ){ |
| 2050 | p->cTerm = EOF; |
| 2051 | return 0; |
| 2052 | } |
| 2053 | if( c=='"' ){ |
| 2054 | int startLine = p->nLine; |
| 2055 | int cQuote = c; |
| 2056 | pc = ppc = 0; |
| 2057 | while( 1 ){ |
| 2058 | c = fgetc(p->in); |
| 2059 | if( c=='\n' ) p->nLine++; |
| 2060 | if( c==cQuote ){ |
| 2061 | if( pc==cQuote ){ |
| 2062 | pc = 0; |
| 2063 | continue; |
| 2064 | } |
| 2065 | } |
| 2066 | if( (c==cSep && pc==cQuote) |
| 2067 | || (c=='\n' && pc==cQuote) |
| 2068 | || (c=='\n' && pc=='\r' && ppc==cQuote) |
| 2069 | || (c==EOF && pc==cQuote) |
| 2070 | ){ |
| 2071 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
| 2072 | p->cTerm = c; |
| 2073 | break; |
| @@ -2077,31 +2124,65 @@ | |
| 2077 | p->zFile, p->nLine, cQuote); |
| 2078 | } |
| 2079 | if( c==EOF ){ |
| 2080 | fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", |
| 2081 | p->zFile, startLine, cQuote); |
| 2082 | p->cTerm = EOF; |
| 2083 | break; |
| 2084 | } |
| 2085 | csv_append_char(p, c); |
| 2086 | ppc = pc; |
| 2087 | pc = c; |
| 2088 | } |
| 2089 | }else{ |
| 2090 | while( c!=EOF && c!=cSep && c!='\n' ){ |
| 2091 | csv_append_char(p, c); |
| 2092 | c = fgetc(p->in); |
| 2093 | } |
| 2094 | if( c=='\n' ){ |
| 2095 | p->nLine++; |
| 2096 | if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; |
| 2097 | } |
| 2098 | p->cTerm = c; |
| 2099 | } |
| 2100 | if( p->z ) p->z[p->n] = 0; |
| 2101 | return p->z; |
| 2102 | } |
| 2103 | |
| 2104 | /* |
| 2105 | ** Try to transfer data for table zTable. If an error is seen while |
| 2106 | ** moving forward, try to go backwards. The backwards movement won't |
| 2107 | ** work for WITHOUT ROWID tables. |
| @@ -2653,100 +2734,125 @@ | |
| 2653 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
| 2654 | int nCol; /* Number of columns in the table */ |
| 2655 | int nByte; /* Number of bytes in an SQL string */ |
| 2656 | int i, j; /* Loop counters */ |
| 2657 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
| 2658 | int nSep; /* Number of bytes in p->separator[] */ |
| 2659 | char *zSql; /* An SQL statement */ |
| 2660 | CSVReader sCsv; /* Reader context */ |
| 2661 | int (*xCloser)(FILE*); /* Procedure to close th3 connection */ |
| 2662 | |
| 2663 | if( nArg!=3 ){ |
| 2664 | fprintf(stderr, "Usage: .import FILE TABLE\n"); |
| 2665 | goto meta_command_exit; |
| 2666 | } |
| 2667 | zFile = azArg[1]; |
| 2668 | zTable = azArg[2]; |
| 2669 | seenInterrupt = 0; |
| 2670 | memset(&sCsv, 0, sizeof(sCsv)); |
| 2671 | open_db(p, 0); |
| 2672 | nSep = strlen30(p->separator); |
| 2673 | if( nSep==0 ){ |
| 2674 | fprintf(stderr, "Error: non-null separator required for import\n"); |
| 2675 | return 1; |
| 2676 | } |
| 2677 | if( nSep>1 ){ |
| 2678 | fprintf(stderr, "Error: multi-character separators not allowed" |
| 2679 | " for import\n"); |
| 2680 | return 1; |
| 2681 | } |
| 2682 | sCsv.zFile = zFile; |
| 2683 | sCsv.nLine = 1; |
| 2684 | if( sCsv.zFile[0]=='|' ){ |
| 2685 | sCsv.in = popen(sCsv.zFile+1, "r"); |
| 2686 | sCsv.zFile = "<pipe>"; |
| 2687 | xCloser = pclose; |
| 2688 | }else{ |
| 2689 | sCsv.in = fopen(sCsv.zFile, "rb"); |
| 2690 | xCloser = fclose; |
| 2691 | } |
| 2692 | if( sCsv.in==0 ){ |
| 2693 | fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); |
| 2694 | return 1; |
| 2695 | } |
| 2696 | sCsv.cSeparator = p->separator[0]; |
| 2697 | zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); |
| 2698 | if( zSql==0 ){ |
| 2699 | fprintf(stderr, "Error: out of memory\n"); |
| 2700 | xCloser(sCsv.in); |
| 2701 | return 1; |
| 2702 | } |
| 2703 | nByte = strlen30(zSql); |
| 2704 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2705 | csv_append_char(&sCsv, 0); /* To ensure sCsv.z is allocated */ |
| 2706 | if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ |
| 2707 | char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
| 2708 | char cSep = '('; |
| 2709 | while( csv_read_one_field(&sCsv) ){ |
| 2710 | zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z); |
| 2711 | cSep = ','; |
| 2712 | if( sCsv.cTerm!=sCsv.cSeparator ) break; |
| 2713 | } |
| 2714 | if( cSep=='(' ){ |
| 2715 | sqlite3_free(zCreate); |
| 2716 | sqlite3_free(sCsv.z); |
| 2717 | xCloser(sCsv.in); |
| 2718 | fprintf(stderr,"%s: empty file\n", sCsv.zFile); |
| 2719 | return 1; |
| 2720 | } |
| 2721 | zCreate = sqlite3_mprintf("%z\n)", zCreate); |
| 2722 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
| 2723 | sqlite3_free(zCreate); |
| 2724 | if( rc ){ |
| 2725 | fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
| 2726 | sqlite3_errmsg(db)); |
| 2727 | sqlite3_free(sCsv.z); |
| 2728 | xCloser(sCsv.in); |
| 2729 | return 1; |
| 2730 | } |
| 2731 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2732 | } |
| 2733 | sqlite3_free(zSql); |
| 2734 | if( rc ){ |
| 2735 | if (pStmt) sqlite3_finalize(pStmt); |
| 2736 | fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |
| 2737 | xCloser(sCsv.in); |
| 2738 | return 1; |
| 2739 | } |
| 2740 | nCol = sqlite3_column_count(pStmt); |
| 2741 | sqlite3_finalize(pStmt); |
| 2742 | pStmt = 0; |
| 2743 | if( nCol==0 ) return 0; /* no columns, no error */ |
| 2744 | zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); |
| 2745 | if( zSql==0 ){ |
| 2746 | fprintf(stderr, "Error: out of memory\n"); |
| 2747 | xCloser(sCsv.in); |
| 2748 | return 1; |
| 2749 | } |
| 2750 | sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); |
| 2751 | j = strlen30(zSql); |
| 2752 | for(i=1; i<nCol; i++){ |
| @@ -2758,50 +2864,60 @@ | |
| 2758 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2759 | sqlite3_free(zSql); |
| 2760 | if( rc ){ |
| 2761 | fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |
| 2762 | if (pStmt) sqlite3_finalize(pStmt); |
| 2763 | xCloser(sCsv.in); |
| 2764 | return 1; |
| 2765 | } |
| 2766 | needCommit = sqlite3_get_autocommit(db); |
| 2767 | if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); |
| 2768 | do{ |
| 2769 | int startLine = sCsv.nLine; |
| 2770 | for(i=0; i<nCol; i++){ |
| 2771 | char *z = csv_read_one_field(&sCsv); |
| 2772 | if( z==0 && i==0 ) break; |
| 2773 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2774 | if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){ |
| 2775 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2776 | "filling the rest with NULL\n", |
| 2777 | sCsv.zFile, startLine, nCol, i+1); |
| 2778 | i++; |
| 2779 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2780 | } |
| 2781 | } |
| 2782 | if( sCsv.cTerm==sCsv.cSeparator ){ |
| 2783 | do{ |
| 2784 | csv_read_one_field(&sCsv); |
| 2785 | i++; |
| 2786 | }while( sCsv.cTerm==sCsv.cSeparator ); |
| 2787 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2788 | "extras ignored\n", |
| 2789 | sCsv.zFile, startLine, nCol, i); |
| 2790 | } |
| 2791 | if( i>=nCol ){ |
| 2792 | sqlite3_step(pStmt); |
| 2793 | rc = sqlite3_reset(pStmt); |
| 2794 | if( rc!=SQLITE_OK ){ |
| 2795 | fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine, |
| 2796 | sqlite3_errmsg(db)); |
| 2797 | } |
| 2798 | } |
| 2799 | }while( sCsv.cTerm!=EOF ); |
| 2800 | |
| 2801 | xCloser(sCsv.in); |
| 2802 | sqlite3_free(sCsv.z); |
| 2803 | sqlite3_finalize(pStmt); |
| 2804 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2805 | }else |
| 2806 | |
| 2807 | if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ |
| @@ -2915,32 +3031,36 @@ | |
| 2915 | p->mode = MODE_List; |
| 2916 | }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ |
| 2917 | p->mode = MODE_Html; |
| 2918 | }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ |
| 2919 | p->mode = MODE_Tcl; |
| 2920 | sqlite3_snprintf(sizeof(p->separator), p->separator, " "); |
| 2921 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 2922 | p->mode = MODE_Csv; |
| 2923 | sqlite3_snprintf(sizeof(p->separator), p->separator, ","); |
| 2924 | sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n"); |
| 2925 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 2926 | p->mode = MODE_List; |
| 2927 | sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); |
| 2928 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 2929 | p->mode = MODE_Insert; |
| 2930 | set_table_name(p, nArg>=3 ? azArg[2] : "table"); |
| 2931 | }else { |
| 2932 | fprintf(stderr,"Error: mode should be one of: " |
| 2933 | "column csv html insert line list tabs tcl\n"); |
| 2934 | rc = 1; |
| 2935 | } |
| 2936 | }else |
| 2937 | |
| 2938 | if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ |
| 2939 | if( nArg==2 ){ |
| 2940 | sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, |
| 2941 | "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); |
| 2942 | }else{ |
| 2943 | fprintf(stderr, "Usage: .nullvalue STRING\n"); |
| 2944 | rc = 1; |
| 2945 | } |
| 2946 | }else |
| @@ -3221,18 +3341,20 @@ | |
| 3221 | }else |
| 3222 | #endif |
| 3223 | |
| 3224 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3225 | if( nArg<2 || nArg>3 ){ |
| 3226 | fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n"); |
| 3227 | rc = 1; |
| 3228 | } |
| 3229 | if( nArg>=2 ){ |
| 3230 | sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]); |
| 3231 | } |
| 3232 | if( nArg>=3 ){ |
| 3233 | sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]); |
| 3234 | } |
| 3235 | }else |
| 3236 | |
| 3237 | if( c=='s' |
| 3238 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| @@ -3259,27 +3381,28 @@ | |
| 3259 | if( nArg!=1 ){ |
| 3260 | fprintf(stderr, "Usage: .show\n"); |
| 3261 | rc = 1; |
| 3262 | goto meta_command_exit; |
| 3263 | } |
| 3264 | fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); |
| 3265 | fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off"); |
| 3266 | fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off"); |
| 3267 | fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); |
| 3268 | fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); |
| 3269 | fprintf(p->out,"%9.9s: ", "nullvalue"); |
| 3270 | output_c_string(p->out, p->nullvalue); |
| 3271 | fprintf(p->out, "\n"); |
| 3272 | fprintf(p->out,"%9.9s: %s\n","output", |
| 3273 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3274 | fprintf(p->out,"%9.9s: ", "separator"); |
| 3275 | output_c_string(p->out, p->separator); |
| 3276 | fprintf(p->out," "); |
| 3277 | output_c_string(p->out, p->newline); |
| 3278 | fprintf(p->out, "\n"); |
| 3279 | fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); |
| 3280 | fprintf(p->out,"%9.9s: ","width"); |
| 3281 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3282 | fprintf(p->out,"%d ",p->colWidth[i]); |
| 3283 | } |
| 3284 | fprintf(p->out,"\n"); |
| 3285 | }else |
| @@ -3936,10 +4059,11 @@ | |
| 3936 | |
| 3937 | /* |
| 3938 | ** Show available command line options |
| 3939 | */ |
| 3940 | static const char zOptions[] = |
| 3941 | " -bail stop after hitting an error\n" |
| 3942 | " -batch force batch I/O\n" |
| 3943 | " -column set output mode to 'column'\n" |
| 3944 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
| 3945 | " -csv set output mode to 'csv'\n" |
| @@ -3957,15 +4081,15 @@ | |
| 3957 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| 3958 | " -mmap N default mmap size set to N\n" |
| 3959 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 3960 | " -multiplex enable the multiplexor VFS\n" |
| 3961 | #endif |
| 3962 | " -newline SEP set newline character(s) for CSV\n" |
| 3963 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 3964 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
| 3965 | " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" |
| 3966 | " -separator SEP set output field separator. Default: '|'\n" |
| 3967 | " -stats print memory stats before each finalize\n" |
| 3968 | " -version show SQLite version\n" |
| 3969 | " -vfs NAME use NAME as the default VFS\n" |
| 3970 | #ifdef SQLITE_ENABLE_VFSTRACE |
| 3971 | " -vfstrace enable tracing of all VFS calls\n" |
| @@ -3988,12 +4112,12 @@ | |
| 3988 | ** Initialize the state information in data |
| 3989 | */ |
| 3990 | static void main_init(ShellState *data) { |
| 3991 | memset(data, 0, sizeof(*data)); |
| 3992 | data->mode = MODE_List; |
| 3993 | memcpy(data->separator,"|", 2); |
| 3994 | memcpy(data->newline,"\r\n", 3); |
| 3995 | data->showHeader = 0; |
| 3996 | data->shellFlgs = SHFLG_Lookaside; |
| 3997 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 3998 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 3999 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| @@ -4228,19 +4352,25 @@ | |
| 4228 | data.mode = MODE_Line; |
| 4229 | }else if( strcmp(z,"-column")==0 ){ |
| 4230 | data.mode = MODE_Column; |
| 4231 | }else if( strcmp(z,"-csv")==0 ){ |
| 4232 | data.mode = MODE_Csv; |
| 4233 | memcpy(data.separator,",",2); |
| 4234 | }else if( strcmp(z,"-separator")==0 ){ |
| 4235 | sqlite3_snprintf(sizeof(data.separator), data.separator, |
| 4236 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4237 | }else if( strcmp(z,"-newline")==0 ){ |
| 4238 | sqlite3_snprintf(sizeof(data.newline), data.newline, |
| 4239 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4240 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 4241 | sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, |
| 4242 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4243 | }else if( strcmp(z,"-header")==0 ){ |
| 4244 | data.showHeader = 1; |
| 4245 | }else if( strcmp(z,"-noheader")==0 ){ |
| 4246 | data.showHeader = 0; |
| @@ -4356,11 +4486,11 @@ | |
| 4356 | nHistory = strlen30(zHome) + 20; |
| 4357 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 4358 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
| 4359 | } |
| 4360 | } |
| 4361 | #if defined(HAVE_READLINE) |
| 4362 | if( zHistory ) read_history(zHistory); |
| 4363 | #endif |
| 4364 | rc = process_input(&data, 0); |
| 4365 | if( zHistory ){ |
| 4366 | stifle_history(100); |
| 4367 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -15,10 +15,17 @@ | |
| 15 | #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) |
| 16 | /* This needs to come before any includes for MSVC compiler */ |
| 17 | #define _CRT_SECURE_NO_WARNINGS |
| 18 | #endif |
| 19 | |
| 20 | /* |
| 21 | ** If requested, include the SQLite compiler options file for MSVC. |
| 22 | */ |
| 23 | #if defined(INCLUDE_MSVC_H) |
| 24 | #include "msvc.h" |
| 25 | #endif |
| 26 | |
| 27 | /* |
| 28 | ** Enable large-file support for fopen() and friends on unix. |
| 29 | */ |
| 30 | #ifndef SQLITE_DISABLE_LFS |
| 31 | # define _LARGE_FILE 1 |
| @@ -46,21 +53,20 @@ | |
| 53 | # endif |
| 54 | # include <unistd.h> |
| 55 | # include <sys/types.h> |
| 56 | #endif |
| 57 | |
| 58 | #if HAVE_READLINE |
| 59 | # include <readline/readline.h> |
| 60 | # include <readline/history.h> |
| 61 | #endif |
| 62 | #if HAVE_EDITLINE |
| 63 | # undef HAVE_READLINE |
| 64 | # define HAVE_READLINE 1 |
| 65 | # include <editline/readline.h> |
| 66 | #endif |
| 67 | #if !HAVE_READLINE |
| 68 | # define add_history(X) |
| 69 | # define read_history(X) |
| 70 | # define write_history(X) |
| 71 | # define stifle_history(X) |
| 72 | #endif |
| @@ -423,11 +429,11 @@ | |
| 429 | char *zResult; |
| 430 | if( in!=0 ){ |
| 431 | zResult = local_getline(zPrior, in); |
| 432 | }else{ |
| 433 | zPrompt = isContinuation ? continuePrompt : mainPrompt; |
| 434 | #if HAVE_READLINE |
| 435 | free(zPrior); |
| 436 | zResult = readline(zPrompt); |
| 437 | if( zResult && *zResult ) add_history(zResult); |
| 438 | #else |
| 439 | printf("%s", zPrompt); |
| @@ -469,15 +475,15 @@ | |
| 475 | int mode; /* An output mode setting */ |
| 476 | int writableSchema; /* True if PRAGMA writable_schema=ON */ |
| 477 | int showHeader; /* True to show column names in List or Column mode */ |
| 478 | unsigned shellFlgs; /* Various flags */ |
| 479 | char *zDestTable; /* Name of destination table when MODE_Insert */ |
| 480 | char colSeparator[20]; /* Column separator character for several modes */ |
| 481 | char rowSeparator[20]; /* Row separator character for MODE_Ascii */ |
| 482 | int colWidth[100]; /* Requested width of each column when in column mode*/ |
| 483 | int actualWidth[100]; /* Actual width of each column */ |
| 484 | char nullValue[20]; /* The text to print when a NULL comes back from |
| 485 | ** the database */ |
| 486 | SavedModeInfo normalMode;/* Holds the mode just before .explain ON */ |
| 487 | char outfile[FILENAME_MAX]; /* Filename for *out */ |
| 488 | const char *zDbFilename; /* name of the database file */ |
| 489 | char *zFreeOnClose; /* Filename to free when closing */ |
| @@ -506,10 +512,11 @@ | |
| 512 | #define MODE_Html 4 /* Generate an XHTML table */ |
| 513 | #define MODE_Insert 5 /* Generate SQL "insert" statements */ |
| 514 | #define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ |
| 515 | #define MODE_Csv 7 /* Quote strings, numbers are plain */ |
| 516 | #define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ |
| 517 | #define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */ |
| 518 | |
| 519 | static const char *modeDescr[] = { |
| 520 | "line", |
| 521 | "column", |
| 522 | "list", |
| @@ -517,12 +524,26 @@ | |
| 524 | "html", |
| 525 | "insert", |
| 526 | "tcl", |
| 527 | "csv", |
| 528 | "explain", |
| 529 | "ascii", |
| 530 | }; |
| 531 | |
| 532 | /* |
| 533 | ** These are the column/row/line separators used by the various |
| 534 | ** import/export modes. |
| 535 | */ |
| 536 | #define SEP_Column "|" |
| 537 | #define SEP_Row "\n" |
| 538 | #define SEP_Tab "\t" |
| 539 | #define SEP_Space " " |
| 540 | #define SEP_Comma "," |
| 541 | #define SEP_CrLf "\r\n" |
| 542 | #define SEP_Unit "\x1F" |
| 543 | #define SEP_Record "\x1E" |
| 544 | |
| 545 | /* |
| 546 | ** Number of elements in an array |
| 547 | */ |
| 548 | #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) |
| 549 | |
| @@ -675,26 +696,26 @@ | |
| 696 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 697 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 698 | }; |
| 699 | |
| 700 | /* |
| 701 | ** Output a single term of CSV. Actually, p->colSeparator is used for |
| 702 | ** the separator, which may or may not be a comma. p->nullValue is |
| 703 | ** the null value. Strings are quoted if necessary. The separator |
| 704 | ** is only issued if bSep is true. |
| 705 | */ |
| 706 | static void output_csv(ShellState *p, const char *z, int bSep){ |
| 707 | FILE *out = p->out; |
| 708 | if( z==0 ){ |
| 709 | fprintf(out,"%s",p->nullValue); |
| 710 | }else{ |
| 711 | int i; |
| 712 | int nSep = strlen30(p->colSeparator); |
| 713 | for(i=0; z[i]; i++){ |
| 714 | if( needCsvQuote[((unsigned char*)z)[i]] |
| 715 | || (z[i]==p->colSeparator[0] && |
| 716 | (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ |
| 717 | i = 0; |
| 718 | break; |
| 719 | } |
| 720 | } |
| 721 | if( i==0 ){ |
| @@ -707,11 +728,11 @@ | |
| 728 | }else{ |
| 729 | fprintf(out, "%s", z); |
| 730 | } |
| 731 | } |
| 732 | if( bSep ){ |
| 733 | fprintf(p->out, "%s", p->colSeparator); |
| 734 | } |
| 735 | } |
| 736 | |
| 737 | #ifdef SIGINT |
| 738 | /* |
| @@ -745,14 +766,14 @@ | |
| 766 | if( azArg==0 ) break; |
| 767 | for(i=0; i<nArg; i++){ |
| 768 | int len = strlen30(azCol[i] ? azCol[i] : ""); |
| 769 | if( len>w ) w = len; |
| 770 | } |
| 771 | if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator); |
| 772 | for(i=0; i<nArg; i++){ |
| 773 | fprintf(p->out,"%*s = %s%s", w, azCol[i], |
| 774 | azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); |
| 775 | } |
| 776 | break; |
| 777 | } |
| 778 | case MODE_Explain: |
| 779 | case MODE_Column: { |
| @@ -765,21 +786,23 @@ | |
| 786 | w = 0; |
| 787 | } |
| 788 | if( w==0 ){ |
| 789 | w = strlen30(azCol[i] ? azCol[i] : ""); |
| 790 | if( w<10 ) w = 10; |
| 791 | n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue); |
| 792 | if( w<n ) w = n; |
| 793 | } |
| 794 | if( i<ArraySize(p->actualWidth) ){ |
| 795 | p->actualWidth[i] = w; |
| 796 | } |
| 797 | if( p->showHeader ){ |
| 798 | if( w<0 ){ |
| 799 | fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], |
| 800 | i==nArg-1 ? p->rowSeparator : " "); |
| 801 | }else{ |
| 802 | fprintf(p->out,"%-*.*s%s",w,w,azCol[i], |
| 803 | i==nArg-1 ? p->rowSeparator : " "); |
| 804 | } |
| 805 | } |
| 806 | } |
| 807 | if( p->showHeader ){ |
| 808 | for(i=0; i<nArg; i++){ |
| @@ -790,11 +813,11 @@ | |
| 813 | }else{ |
| 814 | w = 10; |
| 815 | } |
| 816 | fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" |
| 817 | "----------------------------------------------------------", |
| 818 | i==nArg-1 ? p->rowSeparator : " "); |
| 819 | } |
| 820 | } |
| 821 | } |
| 822 | if( azArg==0 ) break; |
| 823 | for(i=0; i<nArg; i++){ |
| @@ -813,36 +836,39 @@ | |
| 836 | } |
| 837 | p->iIndent++; |
| 838 | } |
| 839 | if( w<0 ){ |
| 840 | fprintf(p->out,"%*.*s%s",-w,-w, |
| 841 | azArg[i] ? azArg[i] : p->nullValue, |
| 842 | i==nArg-1 ? p->rowSeparator : " "); |
| 843 | }else{ |
| 844 | fprintf(p->out,"%-*.*s%s",w,w, |
| 845 | azArg[i] ? azArg[i] : p->nullValue, |
| 846 | i==nArg-1 ? p->rowSeparator : " "); |
| 847 | } |
| 848 | } |
| 849 | break; |
| 850 | } |
| 851 | case MODE_Semi: |
| 852 | case MODE_List: { |
| 853 | if( p->cnt++==0 && p->showHeader ){ |
| 854 | for(i=0; i<nArg; i++){ |
| 855 | fprintf(p->out,"%s%s",azCol[i], |
| 856 | i==nArg-1 ? p->rowSeparator : p->colSeparator); |
| 857 | } |
| 858 | } |
| 859 | if( azArg==0 ) break; |
| 860 | for(i=0; i<nArg; i++){ |
| 861 | char *z = azArg[i]; |
| 862 | if( z==0 ) z = p->nullValue; |
| 863 | fprintf(p->out, "%s", z); |
| 864 | if( i<nArg-1 ){ |
| 865 | fprintf(p->out, "%s", p->colSeparator); |
| 866 | }else if( p->mode==MODE_Semi ){ |
| 867 | fprintf(p->out, ";%s", p->rowSeparator); |
| 868 | }else{ |
| 869 | fprintf(p->out, "%s", p->rowSeparator); |
| 870 | } |
| 871 | } |
| 872 | break; |
| 873 | } |
| 874 | case MODE_Html: { |
| @@ -857,30 +883,30 @@ | |
| 883 | } |
| 884 | if( azArg==0 ) break; |
| 885 | fprintf(p->out,"<TR>"); |
| 886 | for(i=0; i<nArg; i++){ |
| 887 | fprintf(p->out,"<TD>"); |
| 888 | output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
| 889 | fprintf(p->out,"</TD>\n"); |
| 890 | } |
| 891 | fprintf(p->out,"</TR>\n"); |
| 892 | break; |
| 893 | } |
| 894 | case MODE_Tcl: { |
| 895 | if( p->cnt++==0 && p->showHeader ){ |
| 896 | for(i=0; i<nArg; i++){ |
| 897 | output_c_string(p->out,azCol[i] ? azCol[i] : ""); |
| 898 | if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator); |
| 899 | } |
| 900 | fprintf(p->out, "%s", p->rowSeparator); |
| 901 | } |
| 902 | if( azArg==0 ) break; |
| 903 | for(i=0; i<nArg; i++){ |
| 904 | output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
| 905 | if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator); |
| 906 | } |
| 907 | fprintf(p->out, "%s", p->rowSeparator); |
| 908 | break; |
| 909 | } |
| 910 | case MODE_Csv: { |
| 911 | #if defined(WIN32) || defined(_WIN32) |
| 912 | fflush(p->out); |
| @@ -888,17 +914,17 @@ | |
| 914 | #endif |
| 915 | if( p->cnt++==0 && p->showHeader ){ |
| 916 | for(i=0; i<nArg; i++){ |
| 917 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 918 | } |
| 919 | fprintf(p->out, "%s", p->rowSeparator); |
| 920 | } |
| 921 | if( nArg>0 ){ |
| 922 | for(i=0; i<nArg; i++){ |
| 923 | output_csv(p, azArg[i], i<nArg-1); |
| 924 | } |
| 925 | fprintf(p->out, "%s", p->rowSeparator); |
| 926 | } |
| 927 | #if defined(WIN32) || defined(_WIN32) |
| 928 | fflush(p->out); |
| 929 | _setmode(_fileno(p->out), _O_TEXT); |
| 930 | #endif |
| @@ -930,10 +956,26 @@ | |
| 956 | output_quoted_string(p->out, azArg[i]); |
| 957 | } |
| 958 | } |
| 959 | fprintf(p->out,");\n"); |
| 960 | break; |
| 961 | } |
| 962 | case MODE_Ascii: { |
| 963 | if( p->cnt++==0 && p->showHeader ){ |
| 964 | for(i=0; i<nArg; i++){ |
| 965 | if( i>0 ) fprintf(p->out, "%s", p->colSeparator); |
| 966 | fprintf(p->out,"%s",azCol[i] ? azCol[i] : ""); |
| 967 | } |
| 968 | fprintf(p->out, "%s", p->rowSeparator); |
| 969 | } |
| 970 | if( azArg==0 ) break; |
| 971 | for(i=0; i<nArg; i++){ |
| 972 | if( i>0 ) fprintf(p->out, "%s", p->colSeparator); |
| 973 | fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); |
| 974 | } |
| 975 | fprintf(p->out, "%s", p->rowSeparator); |
| 976 | break; |
| 977 | } |
| 978 | } |
| 979 | return 0; |
| 980 | } |
| 981 | |
| @@ -1696,16 +1738,17 @@ | |
| 1738 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1739 | ".load FILE ?ENTRY? Load an extension library\n" |
| 1740 | #endif |
| 1741 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" |
| 1742 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" |
| 1743 | " ascii Columns/rows delimited by 0x1F and 0x1E\n" |
| 1744 | " csv Comma-separated values\n" |
| 1745 | " column Left-aligned columns. (See .width)\n" |
| 1746 | " html HTML <table> code\n" |
| 1747 | " insert SQL insert statements for TABLE\n" |
| 1748 | " line One value per line\n" |
| 1749 | " list Values delimited by .separator strings\n" |
| 1750 | " tabs Tab-separated values\n" |
| 1751 | " tcl TCL list elements\n" |
| 1752 | ".nullvalue STRING Use STRING in place of NULL values\n" |
| 1753 | ".once FILENAME Output for the next SQL command only to FILENAME\n" |
| 1754 | ".open ?FILENAME? Close existing database and reopen FILENAME\n" |
| @@ -1718,12 +1761,12 @@ | |
| 1761 | ".save FILE Write in-memory database into FILE\n" |
| 1762 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" |
| 1763 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1764 | " If TABLE specified, only show tables matching\n" |
| 1765 | " LIKE pattern TABLE.\n" |
| 1766 | ".separator COL ?ROW? Change the column separator and optionally the row\n" |
| 1767 | " separator for both the output mode and .import\n" |
| 1768 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1769 | ".show Show the current values for various settings\n" |
| 1770 | ".stats on|off Turn stats on or off\n" |
| 1771 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1772 | ".tables ?TABLE? List names of tables\n" |
| @@ -2000,26 +2043,27 @@ | |
| 2043 | static int nCall = 0; |
| 2044 | nCall++; |
| 2045 | } |
| 2046 | |
| 2047 | /* |
| 2048 | ** An object used to read a CSV and other files for import. |
| 2049 | */ |
| 2050 | typedef struct ImportCtx ImportCtx; |
| 2051 | struct ImportCtx { |
| 2052 | const char *zFile; /* Name of the input file */ |
| 2053 | FILE *in; /* Read the CSV text from this input stream */ |
| 2054 | char *z; /* Accumulated text for a field */ |
| 2055 | int n; /* Number of bytes in z */ |
| 2056 | int nAlloc; /* Space allocated for z[] */ |
| 2057 | int nLine; /* Current line number */ |
| 2058 | int cTerm; /* Character that terminated the most recent field */ |
| 2059 | int cColSep; /* The column separator character. (Usually ",") */ |
| 2060 | int cRowSep; /* The row separator character. (Usually "\n") */ |
| 2061 | }; |
| 2062 | |
| 2063 | /* Append a single byte to z[] */ |
| 2064 | static void import_append_char(ImportCtx *p, int c){ |
| 2065 | if( p->n+1>=p->nAlloc ){ |
| 2066 | p->nAlloc += p->nAlloc + 100; |
| 2067 | p->z = sqlite3_realloc(p->z, p->nAlloc); |
| 2068 | if( p->z==0 ){ |
| 2069 | fprintf(stderr, "out of memory\n"); |
| @@ -2033,41 +2077,44 @@ | |
| 2077 | ** with the option of having a separator other than ",". |
| 2078 | ** |
| 2079 | ** + Input comes from p->in. |
| 2080 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2081 | ** from sqlite3_malloc(). |
| 2082 | ** + Use p->cSep as the column separator. The default is ",". |
| 2083 | ** + Use p->rSep as the row separator. The default is "\n". |
| 2084 | ** + Keep track of the line number in p->nLine. |
| 2085 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2086 | ** EOF on end-of-file. |
| 2087 | ** + Report syntax errors on stderr |
| 2088 | */ |
| 2089 | static char *csv_read_one_field(ImportCtx *p){ |
| 2090 | int c; |
| 2091 | int cSep = p->cColSep; |
| 2092 | int rSep = p->cRowSep; |
| 2093 | p->n = 0; |
| 2094 | c = fgetc(p->in); |
| 2095 | if( c==EOF || seenInterrupt ){ |
| 2096 | p->cTerm = EOF; |
| 2097 | return 0; |
| 2098 | } |
| 2099 | if( c=='"' ){ |
| 2100 | int pc, ppc; |
| 2101 | int startLine = p->nLine; |
| 2102 | int cQuote = c; |
| 2103 | pc = ppc = 0; |
| 2104 | while( 1 ){ |
| 2105 | c = fgetc(p->in); |
| 2106 | if( c==rSep ) p->nLine++; |
| 2107 | if( c==cQuote ){ |
| 2108 | if( pc==cQuote ){ |
| 2109 | pc = 0; |
| 2110 | continue; |
| 2111 | } |
| 2112 | } |
| 2113 | if( (c==cSep && pc==cQuote) |
| 2114 | || (c==rSep && pc==cQuote) |
| 2115 | || (c==rSep && pc=='\r' && ppc==cQuote) |
| 2116 | || (c==EOF && pc==cQuote) |
| 2117 | ){ |
| 2118 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
| 2119 | p->cTerm = c; |
| 2120 | break; |
| @@ -2077,31 +2124,65 @@ | |
| 2124 | p->zFile, p->nLine, cQuote); |
| 2125 | } |
| 2126 | if( c==EOF ){ |
| 2127 | fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", |
| 2128 | p->zFile, startLine, cQuote); |
| 2129 | p->cTerm = c; |
| 2130 | break; |
| 2131 | } |
| 2132 | import_append_char(p, c); |
| 2133 | ppc = pc; |
| 2134 | pc = c; |
| 2135 | } |
| 2136 | }else{ |
| 2137 | while( c!=EOF && c!=cSep && c!=rSep ){ |
| 2138 | import_append_char(p, c); |
| 2139 | c = fgetc(p->in); |
| 2140 | } |
| 2141 | if( c==rSep ){ |
| 2142 | p->nLine++; |
| 2143 | if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; |
| 2144 | } |
| 2145 | p->cTerm = c; |
| 2146 | } |
| 2147 | if( p->z ) p->z[p->n] = 0; |
| 2148 | return p->z; |
| 2149 | } |
| 2150 | |
| 2151 | /* Read a single field of ASCII delimited text. |
| 2152 | ** |
| 2153 | ** + Input comes from p->in. |
| 2154 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2155 | ** from sqlite3_malloc(). |
| 2156 | ** + Use p->cSep as the column separator. The default is "\x1F". |
| 2157 | ** + Use p->rSep as the row separator. The default is "\x1E". |
| 2158 | ** + Keep track of the row number in p->nLine. |
| 2159 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2160 | ** EOF on end-of-file. |
| 2161 | ** + Report syntax errors on stderr |
| 2162 | */ |
| 2163 | static char *ascii_read_one_field(ImportCtx *p){ |
| 2164 | int c; |
| 2165 | int cSep = p->cColSep; |
| 2166 | int rSep = p->cRowSep; |
| 2167 | p->n = 0; |
| 2168 | c = fgetc(p->in); |
| 2169 | if( c==EOF || seenInterrupt ){ |
| 2170 | p->cTerm = EOF; |
| 2171 | return 0; |
| 2172 | } |
| 2173 | while( c!=EOF && c!=cSep && c!=rSep ){ |
| 2174 | import_append_char(p, c); |
| 2175 | c = fgetc(p->in); |
| 2176 | } |
| 2177 | if( c==rSep ){ |
| 2178 | p->nLine++; |
| 2179 | } |
| 2180 | p->cTerm = c; |
| 2181 | if( p->z ) p->z[p->n] = 0; |
| 2182 | return p->z; |
| 2183 | } |
| 2184 | |
| 2185 | /* |
| 2186 | ** Try to transfer data for table zTable. If an error is seen while |
| 2187 | ** moving forward, try to go backwards. The backwards movement won't |
| 2188 | ** work for WITHOUT ROWID tables. |
| @@ -2653,100 +2734,125 @@ | |
| 2734 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
| 2735 | int nCol; /* Number of columns in the table */ |
| 2736 | int nByte; /* Number of bytes in an SQL string */ |
| 2737 | int i, j; /* Loop counters */ |
| 2738 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
| 2739 | int nSep; /* Number of bytes in p->colSeparator[] */ |
| 2740 | char *zSql; /* An SQL statement */ |
| 2741 | ImportCtx sCtx; /* Reader context */ |
| 2742 | char *(*xRead)(ImportCtx*); /* Procedure to read one value */ |
| 2743 | int (*xCloser)(FILE*); /* Procedure to close th3 connection */ |
| 2744 | |
| 2745 | if( nArg!=3 ){ |
| 2746 | fprintf(stderr, "Usage: .import FILE TABLE\n"); |
| 2747 | goto meta_command_exit; |
| 2748 | } |
| 2749 | zFile = azArg[1]; |
| 2750 | zTable = azArg[2]; |
| 2751 | seenInterrupt = 0; |
| 2752 | memset(&sCtx, 0, sizeof(sCtx)); |
| 2753 | open_db(p, 0); |
| 2754 | nSep = strlen30(p->colSeparator); |
| 2755 | if( nSep==0 ){ |
| 2756 | fprintf(stderr, "Error: non-null column separator required for import\n"); |
| 2757 | return 1; |
| 2758 | } |
| 2759 | if( nSep>1 ){ |
| 2760 | fprintf(stderr, "Error: multi-character column separators not allowed" |
| 2761 | " for import\n"); |
| 2762 | return 1; |
| 2763 | } |
| 2764 | nSep = strlen30(p->rowSeparator); |
| 2765 | if( nSep==0 ){ |
| 2766 | fprintf(stderr, "Error: non-null row separator required for import\n"); |
| 2767 | return 1; |
| 2768 | } |
| 2769 | if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ |
| 2770 | /* When importing CSV (only), if the row separator is set to the |
| 2771 | ** default output row separator, change it to the default input |
| 2772 | ** row separator. This avoids having to maintain different input |
| 2773 | ** and output row separators. */ |
| 2774 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
| 2775 | nSep = strlen30(p->rowSeparator); |
| 2776 | } |
| 2777 | if( nSep>1 ){ |
| 2778 | fprintf(stderr, "Error: multi-character row separators not allowed" |
| 2779 | " for import\n"); |
| 2780 | return 1; |
| 2781 | } |
| 2782 | sCtx.zFile = zFile; |
| 2783 | sCtx.nLine = 1; |
| 2784 | if( sCtx.zFile[0]=='|' ){ |
| 2785 | sCtx.in = popen(sCtx.zFile+1, "r"); |
| 2786 | sCtx.zFile = "<pipe>"; |
| 2787 | xCloser = pclose; |
| 2788 | }else{ |
| 2789 | sCtx.in = fopen(sCtx.zFile, "rb"); |
| 2790 | xCloser = fclose; |
| 2791 | } |
| 2792 | if( p->mode==MODE_Ascii ){ |
| 2793 | xRead = ascii_read_one_field; |
| 2794 | }else{ |
| 2795 | xRead = csv_read_one_field; |
| 2796 | } |
| 2797 | if( sCtx.in==0 ){ |
| 2798 | fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); |
| 2799 | return 1; |
| 2800 | } |
| 2801 | sCtx.cColSep = p->colSeparator[0]; |
| 2802 | sCtx.cRowSep = p->rowSeparator[0]; |
| 2803 | zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); |
| 2804 | if( zSql==0 ){ |
| 2805 | fprintf(stderr, "Error: out of memory\n"); |
| 2806 | xCloser(sCtx.in); |
| 2807 | return 1; |
| 2808 | } |
| 2809 | nByte = strlen30(zSql); |
| 2810 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2811 | import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ |
| 2812 | if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ |
| 2813 | char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
| 2814 | char cSep = '('; |
| 2815 | while( xRead(&sCtx) ){ |
| 2816 | zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z); |
| 2817 | cSep = ','; |
| 2818 | if( sCtx.cTerm!=sCtx.cColSep ) break; |
| 2819 | } |
| 2820 | if( cSep=='(' ){ |
| 2821 | sqlite3_free(zCreate); |
| 2822 | sqlite3_free(sCtx.z); |
| 2823 | xCloser(sCtx.in); |
| 2824 | fprintf(stderr,"%s: empty file\n", sCtx.zFile); |
| 2825 | return 1; |
| 2826 | } |
| 2827 | zCreate = sqlite3_mprintf("%z\n)", zCreate); |
| 2828 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
| 2829 | sqlite3_free(zCreate); |
| 2830 | if( rc ){ |
| 2831 | fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
| 2832 | sqlite3_errmsg(db)); |
| 2833 | sqlite3_free(sCtx.z); |
| 2834 | xCloser(sCtx.in); |
| 2835 | return 1; |
| 2836 | } |
| 2837 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2838 | } |
| 2839 | sqlite3_free(zSql); |
| 2840 | if( rc ){ |
| 2841 | if (pStmt) sqlite3_finalize(pStmt); |
| 2842 | fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |
| 2843 | xCloser(sCtx.in); |
| 2844 | return 1; |
| 2845 | } |
| 2846 | nCol = sqlite3_column_count(pStmt); |
| 2847 | sqlite3_finalize(pStmt); |
| 2848 | pStmt = 0; |
| 2849 | if( nCol==0 ) return 0; /* no columns, no error */ |
| 2850 | zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); |
| 2851 | if( zSql==0 ){ |
| 2852 | fprintf(stderr, "Error: out of memory\n"); |
| 2853 | xCloser(sCtx.in); |
| 2854 | return 1; |
| 2855 | } |
| 2856 | sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); |
| 2857 | j = strlen30(zSql); |
| 2858 | for(i=1; i<nCol; i++){ |
| @@ -2758,50 +2864,60 @@ | |
| 2864 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2865 | sqlite3_free(zSql); |
| 2866 | if( rc ){ |
| 2867 | fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |
| 2868 | if (pStmt) sqlite3_finalize(pStmt); |
| 2869 | xCloser(sCtx.in); |
| 2870 | return 1; |
| 2871 | } |
| 2872 | needCommit = sqlite3_get_autocommit(db); |
| 2873 | if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); |
| 2874 | do{ |
| 2875 | int startLine = sCtx.nLine; |
| 2876 | for(i=0; i<nCol; i++){ |
| 2877 | char *z = xRead(&sCtx); |
| 2878 | /* |
| 2879 | ** Did we reach end-of-file before finding any columns? |
| 2880 | ** If so, stop instead of NULL filling the remaining columns. |
| 2881 | */ |
| 2882 | if( z==0 && i==0 ) break; |
| 2883 | /* |
| 2884 | ** Did we reach end-of-file OR end-of-line before finding any |
| 2885 | ** columns in ASCII mode? If so, stop instead of NULL filling |
| 2886 | ** the remaining columns. |
| 2887 | */ |
| 2888 | if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; |
| 2889 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2890 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
| 2891 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2892 | "filling the rest with NULL\n", |
| 2893 | sCtx.zFile, startLine, nCol, i+1); |
| 2894 | i++; |
| 2895 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2896 | } |
| 2897 | } |
| 2898 | if( sCtx.cTerm==sCtx.cColSep ){ |
| 2899 | do{ |
| 2900 | xRead(&sCtx); |
| 2901 | i++; |
| 2902 | }while( sCtx.cTerm==sCtx.cColSep ); |
| 2903 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2904 | "extras ignored\n", |
| 2905 | sCtx.zFile, startLine, nCol, i); |
| 2906 | } |
| 2907 | if( i>=nCol ){ |
| 2908 | sqlite3_step(pStmt); |
| 2909 | rc = sqlite3_reset(pStmt); |
| 2910 | if( rc!=SQLITE_OK ){ |
| 2911 | fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, |
| 2912 | sqlite3_errmsg(db)); |
| 2913 | } |
| 2914 | } |
| 2915 | }while( sCtx.cTerm!=EOF ); |
| 2916 | |
| 2917 | xCloser(sCtx.in); |
| 2918 | sqlite3_free(sCtx.z); |
| 2919 | sqlite3_finalize(pStmt); |
| 2920 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2921 | }else |
| 2922 | |
| 2923 | if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ |
| @@ -2915,32 +3031,36 @@ | |
| 3031 | p->mode = MODE_List; |
| 3032 | }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ |
| 3033 | p->mode = MODE_Html; |
| 3034 | }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ |
| 3035 | p->mode = MODE_Tcl; |
| 3036 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); |
| 3037 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 3038 | p->mode = MODE_Csv; |
| 3039 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
| 3040 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
| 3041 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 3042 | p->mode = MODE_List; |
| 3043 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); |
| 3044 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 3045 | p->mode = MODE_Insert; |
| 3046 | set_table_name(p, nArg>=3 ? azArg[2] : "table"); |
| 3047 | }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ |
| 3048 | p->mode = MODE_Ascii; |
| 3049 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); |
| 3050 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); |
| 3051 | }else { |
| 3052 | fprintf(stderr,"Error: mode should be one of: " |
| 3053 | "ascii column csv html insert line list tabs tcl\n"); |
| 3054 | rc = 1; |
| 3055 | } |
| 3056 | }else |
| 3057 | |
| 3058 | if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ |
| 3059 | if( nArg==2 ){ |
| 3060 | sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, |
| 3061 | "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); |
| 3062 | }else{ |
| 3063 | fprintf(stderr, "Usage: .nullvalue STRING\n"); |
| 3064 | rc = 1; |
| 3065 | } |
| 3066 | }else |
| @@ -3221,18 +3341,20 @@ | |
| 3341 | }else |
| 3342 | #endif |
| 3343 | |
| 3344 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3345 | if( nArg<2 || nArg>3 ){ |
| 3346 | fprintf(stderr, "Usage: .separator COL ?ROW?\n"); |
| 3347 | rc = 1; |
| 3348 | } |
| 3349 | if( nArg>=2 ){ |
| 3350 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, |
| 3351 | "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); |
| 3352 | } |
| 3353 | if( nArg>=3 ){ |
| 3354 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, |
| 3355 | "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); |
| 3356 | } |
| 3357 | }else |
| 3358 | |
| 3359 | if( c=='s' |
| 3360 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| @@ -3259,27 +3381,28 @@ | |
| 3381 | if( nArg!=1 ){ |
| 3382 | fprintf(stderr, "Usage: .show\n"); |
| 3383 | rc = 1; |
| 3384 | goto meta_command_exit; |
| 3385 | } |
| 3386 | fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); |
| 3387 | fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); |
| 3388 | fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off"); |
| 3389 | fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); |
| 3390 | fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]); |
| 3391 | fprintf(p->out,"%12.12s: ", "nullvalue"); |
| 3392 | output_c_string(p->out, p->nullValue); |
| 3393 | fprintf(p->out, "\n"); |
| 3394 | fprintf(p->out,"%12.12s: %s\n","output", |
| 3395 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3396 | fprintf(p->out,"%12.12s: ", "colseparator"); |
| 3397 | output_c_string(p->out, p->colSeparator); |
| 3398 | fprintf(p->out, "\n"); |
| 3399 | fprintf(p->out,"%12.12s: ", "rowseparator"); |
| 3400 | output_c_string(p->out, p->rowSeparator); |
| 3401 | fprintf(p->out, "\n"); |
| 3402 | fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); |
| 3403 | fprintf(p->out,"%12.12s: ","width"); |
| 3404 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3405 | fprintf(p->out,"%d ",p->colWidth[i]); |
| 3406 | } |
| 3407 | fprintf(p->out,"\n"); |
| 3408 | }else |
| @@ -3936,10 +4059,11 @@ | |
| 4059 | |
| 4060 | /* |
| 4061 | ** Show available command line options |
| 4062 | */ |
| 4063 | static const char zOptions[] = |
| 4064 | " -ascii set output mode to 'ascii'\n" |
| 4065 | " -bail stop after hitting an error\n" |
| 4066 | " -batch force batch I/O\n" |
| 4067 | " -column set output mode to 'column'\n" |
| 4068 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
| 4069 | " -csv set output mode to 'csv'\n" |
| @@ -3957,15 +4081,15 @@ | |
| 4081 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| 4082 | " -mmap N default mmap size set to N\n" |
| 4083 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 4084 | " -multiplex enable the multiplexor VFS\n" |
| 4085 | #endif |
| 4086 | " -newline SEP set output row separator. Default: '\\n'\n" |
| 4087 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 4088 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
| 4089 | " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" |
| 4090 | " -separator SEP set output column separator. Default: '|'\n" |
| 4091 | " -stats print memory stats before each finalize\n" |
| 4092 | " -version show SQLite version\n" |
| 4093 | " -vfs NAME use NAME as the default VFS\n" |
| 4094 | #ifdef SQLITE_ENABLE_VFSTRACE |
| 4095 | " -vfstrace enable tracing of all VFS calls\n" |
| @@ -3988,12 +4112,12 @@ | |
| 4112 | ** Initialize the state information in data |
| 4113 | */ |
| 4114 | static void main_init(ShellState *data) { |
| 4115 | memset(data, 0, sizeof(*data)); |
| 4116 | data->mode = MODE_List; |
| 4117 | memcpy(data->colSeparator,SEP_Column, 2); |
| 4118 | memcpy(data->rowSeparator,SEP_Row, 2); |
| 4119 | data->showHeader = 0; |
| 4120 | data->shellFlgs = SHFLG_Lookaside; |
| 4121 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 4122 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 4123 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| @@ -4228,19 +4352,25 @@ | |
| 4352 | data.mode = MODE_Line; |
| 4353 | }else if( strcmp(z,"-column")==0 ){ |
| 4354 | data.mode = MODE_Column; |
| 4355 | }else if( strcmp(z,"-csv")==0 ){ |
| 4356 | data.mode = MODE_Csv; |
| 4357 | memcpy(data.colSeparator,",",2); |
| 4358 | }else if( strcmp(z,"-ascii")==0 ){ |
| 4359 | data.mode = MODE_Ascii; |
| 4360 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, |
| 4361 | SEP_Unit); |
| 4362 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, |
| 4363 | SEP_Record); |
| 4364 | }else if( strcmp(z,"-separator")==0 ){ |
| 4365 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, |
| 4366 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4367 | }else if( strcmp(z,"-newline")==0 ){ |
| 4368 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, |
| 4369 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4370 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 4371 | sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, |
| 4372 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4373 | }else if( strcmp(z,"-header")==0 ){ |
| 4374 | data.showHeader = 1; |
| 4375 | }else if( strcmp(z,"-noheader")==0 ){ |
| 4376 | data.showHeader = 0; |
| @@ -4356,11 +4486,11 @@ | |
| 4486 | nHistory = strlen30(zHome) + 20; |
| 4487 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 4488 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
| 4489 | } |
| 4490 | } |
| 4491 | #if HAVE_READLINE |
| 4492 | if( zHistory ) read_history(zHistory); |
| 4493 | #endif |
| 4494 | rc = process_input(&data, 0); |
| 4495 | if( zHistory ){ |
| 4496 | stifle_history(100); |
| 4497 |
+317
-203
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -41,10 +41,57 @@ | ||
| 41 | 41 | ** |
| 42 | 42 | */ |
| 43 | 43 | #ifndef _SQLITEINT_H_ |
| 44 | 44 | #define _SQLITEINT_H_ |
| 45 | 45 | |
| 46 | +/* | |
| 47 | +** Include the header file used to customize the compiler options for MSVC. | |
| 48 | +** This should be done first so that it can successfully prevent spurious | |
| 49 | +** compiler warnings due to subsequent content in this file and other files | |
| 50 | +** that are included by this file. | |
| 51 | +*/ | |
| 52 | +/************** Include msvc.h in the middle of sqliteInt.h ******************/ | |
| 53 | +/************** Begin file msvc.h ********************************************/ | |
| 54 | +/* | |
| 55 | +** 2015 January 12 | |
| 56 | +** | |
| 57 | +** The author disclaims copyright to this source code. In place of | |
| 58 | +** a legal notice, here is a blessing: | |
| 59 | +** | |
| 60 | +** May you do good and not evil. | |
| 61 | +** May you find forgiveness for yourself and forgive others. | |
| 62 | +** May you share freely, never taking more than you give. | |
| 63 | +** | |
| 64 | +****************************************************************************** | |
| 65 | +** | |
| 66 | +** This file contains code that is specific to MSVC. | |
| 67 | +*/ | |
| 68 | +#ifndef _MSVC_H_ | |
| 69 | +#define _MSVC_H_ | |
| 70 | + | |
| 71 | +#if defined(_MSC_VER) | |
| 72 | +#pragma warning(disable : 4054) | |
| 73 | +#pragma warning(disable : 4055) | |
| 74 | +#pragma warning(disable : 4100) | |
| 75 | +#pragma warning(disable : 4127) | |
| 76 | +#pragma warning(disable : 4152) | |
| 77 | +#pragma warning(disable : 4189) | |
| 78 | +#pragma warning(disable : 4206) | |
| 79 | +#pragma warning(disable : 4210) | |
| 80 | +#pragma warning(disable : 4232) | |
| 81 | +#pragma warning(disable : 4244) | |
| 82 | +#pragma warning(disable : 4305) | |
| 83 | +#pragma warning(disable : 4306) | |
| 84 | +#pragma warning(disable : 4702) | |
| 85 | +#pragma warning(disable : 4706) | |
| 86 | +#endif /* defined(_MSC_VER) */ | |
| 87 | + | |
| 88 | +#endif /* _MSVC_H_ */ | |
| 89 | + | |
| 90 | +/************** End of msvc.h ************************************************/ | |
| 91 | +/************** Continuing where we left off in sqliteInt.h ******************/ | |
| 92 | + | |
| 46 | 93 | /* |
| 47 | 94 | ** These #defines should enable >2GB file support on POSIX if the |
| 48 | 95 | ** underlying operating system supports it. If the OS lacks |
| 49 | 96 | ** large file support, or if the OS is windows, these should be no-ops. |
| 50 | 97 | ** |
| @@ -231,11 +278,11 @@ | ||
| 231 | 278 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | 279 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | 280 | */ |
| 234 | 281 | #define SQLITE_VERSION "3.8.8" |
| 235 | 282 | #define SQLITE_VERSION_NUMBER 3008008 |
| 236 | -#define SQLITE_SOURCE_ID "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6" | |
| 283 | +#define SQLITE_SOURCE_ID "2015-01-12 21:43:00 e693e11d1b9265974c32bddba873ea30a4d0b708" | |
| 237 | 284 | |
| 238 | 285 | /* |
| 239 | 286 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | 287 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | 288 | ** |
| @@ -7613,10 +7660,14 @@ | ||
| 7613 | 7660 | ** |
| 7614 | 7661 | ** The following constants can be used for the T parameter to the |
| 7615 | 7662 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7616 | 7663 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7617 | 7664 | ** |
| 7665 | +** When the value returned to V is a string, space to hold that string is | |
| 7666 | +** managed by the prepared statement S and will be automatically freed when | |
| 7667 | +** S is finalized. | |
| 7668 | +** | |
| 7618 | 7669 | ** <dl> |
| 7619 | 7670 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7620 | 7671 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7621 | 7672 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7622 | 7673 | ** |
| @@ -7658,11 +7709,18 @@ | ||
| 7658 | 7709 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 7659 | 7710 | |
| 7660 | 7711 | /* |
| 7661 | 7712 | ** CAPI3REF: Prepared Statement Scan Status |
| 7662 | 7713 | ** |
| 7663 | -** Return status data for a single loop within query pStmt. | |
| 7714 | +** This interface returns information about the predicted and measured | |
| 7715 | +** performance for pStmt. Advanced applications can use this | |
| 7716 | +** interface to compare the predicted and the measured performance and | |
| 7717 | +** issue warnings and/or rerun [ANALYZE] if discrepancies are found. | |
| 7718 | +** | |
| 7719 | +** Since this interface is expected to be rarely used, it is only | |
| 7720 | +** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] | |
| 7721 | +** compile-time option. | |
| 7664 | 7722 | ** |
| 7665 | 7723 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7666 | 7724 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7667 | 7725 | ** of this interface is undefined. |
| 7668 | 7726 | ** ^The requested measurement is written into a variable pointed to by |
| @@ -7676,13 +7734,10 @@ | ||
| 7676 | 7734 | ** ^Statistics might not be available for all loops in all statements. ^In cases |
| 7677 | 7735 | ** where there exist loops with no available statistics, this function behaves |
| 7678 | 7736 | ** as if the loop did not exist - it returns non-zero and leave the variable |
| 7679 | 7737 | ** that pOut points to unchanged. |
| 7680 | 7738 | ** |
| 7681 | -** This API is only available if the library is built with pre-processor | |
| 7682 | -** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. | |
| 7683 | -** | |
| 7684 | 7739 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 7685 | 7740 | */ |
| 7686 | 7741 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( |
| 7687 | 7742 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ |
| 7688 | 7743 | int idx, /* Index of loop to report on */ |
| @@ -12054,11 +12109,11 @@ | ||
| 12054 | 12109 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 12055 | 12110 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 12056 | 12111 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 12057 | 12112 | #define SF_Compound 0x0040 /* Part of a compound query */ |
| 12058 | 12113 | #define SF_Values 0x0080 /* Synthesized from VALUES clause */ |
| 12059 | - /* 0x0100 NOT USED */ | |
| 12114 | +#define SF_AllValues 0x0100 /* All terms of compound are VALUES */ | |
| 12060 | 12115 | #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ |
| 12061 | 12116 | #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ |
| 12062 | 12117 | #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ |
| 12063 | 12118 | #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ |
| 12064 | 12119 | |
| @@ -12682,11 +12737,11 @@ | ||
| 12682 | 12737 | ** FTS4 is really an extension for FTS3. It is enabled using the |
| 12683 | 12738 | ** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call |
| 12684 | 12739 | ** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. |
| 12685 | 12740 | */ |
| 12686 | 12741 | #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) |
| 12687 | -# define SQLITE_ENABLE_FTS3 | |
| 12742 | +# define SQLITE_ENABLE_FTS3 1 | |
| 12688 | 12743 | #endif |
| 12689 | 12744 | |
| 12690 | 12745 | /* |
| 12691 | 12746 | ** The ctype.h header is needed for non-ASCII systems. It is also |
| 12692 | 12747 | ** needed by FTS3 when FTS3 is included in the amalgamation. |
| @@ -13824,355 +13879,355 @@ | ||
| 13824 | 13879 | /* These macros are provided to "stringify" the value of the define |
| 13825 | 13880 | ** for those options in which the value is meaningful. */ |
| 13826 | 13881 | #define CTIMEOPT_VAL_(opt) #opt |
| 13827 | 13882 | #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) |
| 13828 | 13883 | |
| 13829 | -#ifdef SQLITE_32BIT_ROWID | |
| 13884 | +#if SQLITE_32BIT_ROWID | |
| 13830 | 13885 | "32BIT_ROWID", |
| 13831 | 13886 | #endif |
| 13832 | -#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC | |
| 13887 | +#if SQLITE_4_BYTE_ALIGNED_MALLOC | |
| 13833 | 13888 | "4_BYTE_ALIGNED_MALLOC", |
| 13834 | 13889 | #endif |
| 13835 | -#ifdef SQLITE_CASE_SENSITIVE_LIKE | |
| 13890 | +#if SQLITE_CASE_SENSITIVE_LIKE | |
| 13836 | 13891 | "CASE_SENSITIVE_LIKE", |
| 13837 | 13892 | #endif |
| 13838 | -#ifdef SQLITE_CHECK_PAGES | |
| 13893 | +#if SQLITE_CHECK_PAGES | |
| 13839 | 13894 | "CHECK_PAGES", |
| 13840 | 13895 | #endif |
| 13841 | -#ifdef SQLITE_COVERAGE_TEST | |
| 13896 | +#if SQLITE_COVERAGE_TEST | |
| 13842 | 13897 | "COVERAGE_TEST", |
| 13843 | 13898 | #endif |
| 13844 | -#ifdef SQLITE_DEBUG | |
| 13899 | +#if SQLITE_DEBUG | |
| 13845 | 13900 | "DEBUG", |
| 13846 | 13901 | #endif |
| 13847 | -#ifdef SQLITE_DEFAULT_LOCKING_MODE | |
| 13902 | +#if SQLITE_DEFAULT_LOCKING_MODE | |
| 13848 | 13903 | "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), |
| 13849 | 13904 | #endif |
| 13850 | 13905 | #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) |
| 13851 | 13906 | "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), |
| 13852 | 13907 | #endif |
| 13853 | -#ifdef SQLITE_DISABLE_DIRSYNC | |
| 13908 | +#if SQLITE_DISABLE_DIRSYNC | |
| 13854 | 13909 | "DISABLE_DIRSYNC", |
| 13855 | 13910 | #endif |
| 13856 | -#ifdef SQLITE_DISABLE_LFS | |
| 13911 | +#if SQLITE_DISABLE_LFS | |
| 13857 | 13912 | "DISABLE_LFS", |
| 13858 | 13913 | #endif |
| 13859 | -#ifdef SQLITE_ENABLE_API_ARMOR | |
| 13914 | +#if SQLITE_ENABLE_API_ARMOR | |
| 13860 | 13915 | "ENABLE_API_ARMOR", |
| 13861 | 13916 | #endif |
| 13862 | -#ifdef SQLITE_ENABLE_ATOMIC_WRITE | |
| 13917 | +#if SQLITE_ENABLE_ATOMIC_WRITE | |
| 13863 | 13918 | "ENABLE_ATOMIC_WRITE", |
| 13864 | 13919 | #endif |
| 13865 | -#ifdef SQLITE_ENABLE_CEROD | |
| 13920 | +#if SQLITE_ENABLE_CEROD | |
| 13866 | 13921 | "ENABLE_CEROD", |
| 13867 | 13922 | #endif |
| 13868 | -#ifdef SQLITE_ENABLE_COLUMN_METADATA | |
| 13923 | +#if SQLITE_ENABLE_COLUMN_METADATA | |
| 13869 | 13924 | "ENABLE_COLUMN_METADATA", |
| 13870 | 13925 | #endif |
| 13871 | -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT | |
| 13926 | +#if SQLITE_ENABLE_EXPENSIVE_ASSERT | |
| 13872 | 13927 | "ENABLE_EXPENSIVE_ASSERT", |
| 13873 | 13928 | #endif |
| 13874 | -#ifdef SQLITE_ENABLE_FTS1 | |
| 13929 | +#if SQLITE_ENABLE_FTS1 | |
| 13875 | 13930 | "ENABLE_FTS1", |
| 13876 | 13931 | #endif |
| 13877 | -#ifdef SQLITE_ENABLE_FTS2 | |
| 13932 | +#if SQLITE_ENABLE_FTS2 | |
| 13878 | 13933 | "ENABLE_FTS2", |
| 13879 | 13934 | #endif |
| 13880 | -#ifdef SQLITE_ENABLE_FTS3 | |
| 13935 | +#if SQLITE_ENABLE_FTS3 | |
| 13881 | 13936 | "ENABLE_FTS3", |
| 13882 | 13937 | #endif |
| 13883 | -#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS | |
| 13938 | +#if SQLITE_ENABLE_FTS3_PARENTHESIS | |
| 13884 | 13939 | "ENABLE_FTS3_PARENTHESIS", |
| 13885 | 13940 | #endif |
| 13886 | -#ifdef SQLITE_ENABLE_FTS4 | |
| 13941 | +#if SQLITE_ENABLE_FTS4 | |
| 13887 | 13942 | "ENABLE_FTS4", |
| 13888 | 13943 | #endif |
| 13889 | -#ifdef SQLITE_ENABLE_ICU | |
| 13944 | +#if SQLITE_ENABLE_ICU | |
| 13890 | 13945 | "ENABLE_ICU", |
| 13891 | 13946 | #endif |
| 13892 | -#ifdef SQLITE_ENABLE_IOTRACE | |
| 13947 | +#if SQLITE_ENABLE_IOTRACE | |
| 13893 | 13948 | "ENABLE_IOTRACE", |
| 13894 | 13949 | #endif |
| 13895 | -#ifdef SQLITE_ENABLE_LOAD_EXTENSION | |
| 13950 | +#if SQLITE_ENABLE_LOAD_EXTENSION | |
| 13896 | 13951 | "ENABLE_LOAD_EXTENSION", |
| 13897 | 13952 | #endif |
| 13898 | -#ifdef SQLITE_ENABLE_LOCKING_STYLE | |
| 13953 | +#if SQLITE_ENABLE_LOCKING_STYLE | |
| 13899 | 13954 | "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), |
| 13900 | 13955 | #endif |
| 13901 | -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | |
| 13956 | +#if SQLITE_ENABLE_MEMORY_MANAGEMENT | |
| 13902 | 13957 | "ENABLE_MEMORY_MANAGEMENT", |
| 13903 | 13958 | #endif |
| 13904 | -#ifdef SQLITE_ENABLE_MEMSYS3 | |
| 13959 | +#if SQLITE_ENABLE_MEMSYS3 | |
| 13905 | 13960 | "ENABLE_MEMSYS3", |
| 13906 | 13961 | #endif |
| 13907 | -#ifdef SQLITE_ENABLE_MEMSYS5 | |
| 13962 | +#if SQLITE_ENABLE_MEMSYS5 | |
| 13908 | 13963 | "ENABLE_MEMSYS5", |
| 13909 | 13964 | #endif |
| 13910 | -#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK | |
| 13965 | +#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK | |
| 13911 | 13966 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 13912 | 13967 | #endif |
| 13913 | -#ifdef SQLITE_ENABLE_RTREE | |
| 13968 | +#if SQLITE_ENABLE_RTREE | |
| 13914 | 13969 | "ENABLE_RTREE", |
| 13915 | 13970 | #endif |
| 13916 | 13971 | #if defined(SQLITE_ENABLE_STAT4) |
| 13917 | 13972 | "ENABLE_STAT4", |
| 13918 | 13973 | #elif defined(SQLITE_ENABLE_STAT3) |
| 13919 | 13974 | "ENABLE_STAT3", |
| 13920 | 13975 | #endif |
| 13921 | -#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY | |
| 13976 | +#if SQLITE_ENABLE_UNLOCK_NOTIFY | |
| 13922 | 13977 | "ENABLE_UNLOCK_NOTIFY", |
| 13923 | 13978 | #endif |
| 13924 | -#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT | |
| 13979 | +#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT | |
| 13925 | 13980 | "ENABLE_UPDATE_DELETE_LIMIT", |
| 13926 | 13981 | #endif |
| 13927 | -#ifdef SQLITE_HAS_CODEC | |
| 13982 | +#if SQLITE_HAS_CODEC | |
| 13928 | 13983 | "HAS_CODEC", |
| 13929 | 13984 | #endif |
| 13930 | -#ifdef SQLITE_HAVE_ISNAN | |
| 13985 | +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN | |
| 13931 | 13986 | "HAVE_ISNAN", |
| 13932 | 13987 | #endif |
| 13933 | -#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX | |
| 13988 | +#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX | |
| 13934 | 13989 | "HOMEGROWN_RECURSIVE_MUTEX", |
| 13935 | 13990 | #endif |
| 13936 | -#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS | |
| 13991 | +#if SQLITE_IGNORE_AFP_LOCK_ERRORS | |
| 13937 | 13992 | "IGNORE_AFP_LOCK_ERRORS", |
| 13938 | 13993 | #endif |
| 13939 | -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS | |
| 13994 | +#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS | |
| 13940 | 13995 | "IGNORE_FLOCK_LOCK_ERRORS", |
| 13941 | 13996 | #endif |
| 13942 | 13997 | #ifdef SQLITE_INT64_TYPE |
| 13943 | 13998 | "INT64_TYPE", |
| 13944 | 13999 | #endif |
| 13945 | -#ifdef SQLITE_LOCK_TRACE | |
| 14000 | +#if SQLITE_LOCK_TRACE | |
| 13946 | 14001 | "LOCK_TRACE", |
| 13947 | 14002 | #endif |
| 13948 | 14003 | #if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc) |
| 13949 | 14004 | "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), |
| 13950 | 14005 | #endif |
| 13951 | 14006 | #ifdef SQLITE_MAX_SCHEMA_RETRY |
| 13952 | 14007 | "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), |
| 13953 | 14008 | #endif |
| 13954 | -#ifdef SQLITE_MEMDEBUG | |
| 14009 | +#if SQLITE_MEMDEBUG | |
| 13955 | 14010 | "MEMDEBUG", |
| 13956 | 14011 | #endif |
| 13957 | -#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT | |
| 14012 | +#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT | |
| 13958 | 14013 | "MIXED_ENDIAN_64BIT_FLOAT", |
| 13959 | 14014 | #endif |
| 13960 | -#ifdef SQLITE_NO_SYNC | |
| 14015 | +#if SQLITE_NO_SYNC | |
| 13961 | 14016 | "NO_SYNC", |
| 13962 | 14017 | #endif |
| 13963 | -#ifdef SQLITE_OMIT_ALTERTABLE | |
| 14018 | +#if SQLITE_OMIT_ALTERTABLE | |
| 13964 | 14019 | "OMIT_ALTERTABLE", |
| 13965 | 14020 | #endif |
| 13966 | -#ifdef SQLITE_OMIT_ANALYZE | |
| 14021 | +#if SQLITE_OMIT_ANALYZE | |
| 13967 | 14022 | "OMIT_ANALYZE", |
| 13968 | 14023 | #endif |
| 13969 | -#ifdef SQLITE_OMIT_ATTACH | |
| 14024 | +#if SQLITE_OMIT_ATTACH | |
| 13970 | 14025 | "OMIT_ATTACH", |
| 13971 | 14026 | #endif |
| 13972 | -#ifdef SQLITE_OMIT_AUTHORIZATION | |
| 14027 | +#if SQLITE_OMIT_AUTHORIZATION | |
| 13973 | 14028 | "OMIT_AUTHORIZATION", |
| 13974 | 14029 | #endif |
| 13975 | -#ifdef SQLITE_OMIT_AUTOINCREMENT | |
| 14030 | +#if SQLITE_OMIT_AUTOINCREMENT | |
| 13976 | 14031 | "OMIT_AUTOINCREMENT", |
| 13977 | 14032 | #endif |
| 13978 | -#ifdef SQLITE_OMIT_AUTOINIT | |
| 14033 | +#if SQLITE_OMIT_AUTOINIT | |
| 13979 | 14034 | "OMIT_AUTOINIT", |
| 13980 | 14035 | #endif |
| 13981 | -#ifdef SQLITE_OMIT_AUTOMATIC_INDEX | |
| 14036 | +#if SQLITE_OMIT_AUTOMATIC_INDEX | |
| 13982 | 14037 | "OMIT_AUTOMATIC_INDEX", |
| 13983 | 14038 | #endif |
| 13984 | -#ifdef SQLITE_OMIT_AUTORESET | |
| 14039 | +#if SQLITE_OMIT_AUTORESET | |
| 13985 | 14040 | "OMIT_AUTORESET", |
| 13986 | 14041 | #endif |
| 13987 | -#ifdef SQLITE_OMIT_AUTOVACUUM | |
| 14042 | +#if SQLITE_OMIT_AUTOVACUUM | |
| 13988 | 14043 | "OMIT_AUTOVACUUM", |
| 13989 | 14044 | #endif |
| 13990 | -#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION | |
| 14045 | +#if SQLITE_OMIT_BETWEEN_OPTIMIZATION | |
| 13991 | 14046 | "OMIT_BETWEEN_OPTIMIZATION", |
| 13992 | 14047 | #endif |
| 13993 | -#ifdef SQLITE_OMIT_BLOB_LITERAL | |
| 14048 | +#if SQLITE_OMIT_BLOB_LITERAL | |
| 13994 | 14049 | "OMIT_BLOB_LITERAL", |
| 13995 | 14050 | #endif |
| 13996 | -#ifdef SQLITE_OMIT_BTREECOUNT | |
| 14051 | +#if SQLITE_OMIT_BTREECOUNT | |
| 13997 | 14052 | "OMIT_BTREECOUNT", |
| 13998 | 14053 | #endif |
| 13999 | -#ifdef SQLITE_OMIT_BUILTIN_TEST | |
| 14054 | +#if SQLITE_OMIT_BUILTIN_TEST | |
| 14000 | 14055 | "OMIT_BUILTIN_TEST", |
| 14001 | 14056 | #endif |
| 14002 | -#ifdef SQLITE_OMIT_CAST | |
| 14057 | +#if SQLITE_OMIT_CAST | |
| 14003 | 14058 | "OMIT_CAST", |
| 14004 | 14059 | #endif |
| 14005 | -#ifdef SQLITE_OMIT_CHECK | |
| 14060 | +#if SQLITE_OMIT_CHECK | |
| 14006 | 14061 | "OMIT_CHECK", |
| 14007 | 14062 | #endif |
| 14008 | -#ifdef SQLITE_OMIT_COMPLETE | |
| 14063 | +#if SQLITE_OMIT_COMPLETE | |
| 14009 | 14064 | "OMIT_COMPLETE", |
| 14010 | 14065 | #endif |
| 14011 | -#ifdef SQLITE_OMIT_COMPOUND_SELECT | |
| 14066 | +#if SQLITE_OMIT_COMPOUND_SELECT | |
| 14012 | 14067 | "OMIT_COMPOUND_SELECT", |
| 14013 | 14068 | #endif |
| 14014 | -#ifdef SQLITE_OMIT_CTE | |
| 14069 | +#if SQLITE_OMIT_CTE | |
| 14015 | 14070 | "OMIT_CTE", |
| 14016 | 14071 | #endif |
| 14017 | -#ifdef SQLITE_OMIT_DATETIME_FUNCS | |
| 14072 | +#if SQLITE_OMIT_DATETIME_FUNCS | |
| 14018 | 14073 | "OMIT_DATETIME_FUNCS", |
| 14019 | 14074 | #endif |
| 14020 | -#ifdef SQLITE_OMIT_DECLTYPE | |
| 14075 | +#if SQLITE_OMIT_DECLTYPE | |
| 14021 | 14076 | "OMIT_DECLTYPE", |
| 14022 | 14077 | #endif |
| 14023 | -#ifdef SQLITE_OMIT_DEPRECATED | |
| 14078 | +#if SQLITE_OMIT_DEPRECATED | |
| 14024 | 14079 | "OMIT_DEPRECATED", |
| 14025 | 14080 | #endif |
| 14026 | -#ifdef SQLITE_OMIT_DISKIO | |
| 14081 | +#if SQLITE_OMIT_DISKIO | |
| 14027 | 14082 | "OMIT_DISKIO", |
| 14028 | 14083 | #endif |
| 14029 | -#ifdef SQLITE_OMIT_EXPLAIN | |
| 14084 | +#if SQLITE_OMIT_EXPLAIN | |
| 14030 | 14085 | "OMIT_EXPLAIN", |
| 14031 | 14086 | #endif |
| 14032 | -#ifdef SQLITE_OMIT_FLAG_PRAGMAS | |
| 14087 | +#if SQLITE_OMIT_FLAG_PRAGMAS | |
| 14033 | 14088 | "OMIT_FLAG_PRAGMAS", |
| 14034 | 14089 | #endif |
| 14035 | -#ifdef SQLITE_OMIT_FLOATING_POINT | |
| 14090 | +#if SQLITE_OMIT_FLOATING_POINT | |
| 14036 | 14091 | "OMIT_FLOATING_POINT", |
| 14037 | 14092 | #endif |
| 14038 | -#ifdef SQLITE_OMIT_FOREIGN_KEY | |
| 14093 | +#if SQLITE_OMIT_FOREIGN_KEY | |
| 14039 | 14094 | "OMIT_FOREIGN_KEY", |
| 14040 | 14095 | #endif |
| 14041 | -#ifdef SQLITE_OMIT_GET_TABLE | |
| 14096 | +#if SQLITE_OMIT_GET_TABLE | |
| 14042 | 14097 | "OMIT_GET_TABLE", |
| 14043 | 14098 | #endif |
| 14044 | -#ifdef SQLITE_OMIT_INCRBLOB | |
| 14099 | +#if SQLITE_OMIT_INCRBLOB | |
| 14045 | 14100 | "OMIT_INCRBLOB", |
| 14046 | 14101 | #endif |
| 14047 | -#ifdef SQLITE_OMIT_INTEGRITY_CHECK | |
| 14102 | +#if SQLITE_OMIT_INTEGRITY_CHECK | |
| 14048 | 14103 | "OMIT_INTEGRITY_CHECK", |
| 14049 | 14104 | #endif |
| 14050 | -#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION | |
| 14105 | +#if SQLITE_OMIT_LIKE_OPTIMIZATION | |
| 14051 | 14106 | "OMIT_LIKE_OPTIMIZATION", |
| 14052 | 14107 | #endif |
| 14053 | -#ifdef SQLITE_OMIT_LOAD_EXTENSION | |
| 14108 | +#if SQLITE_OMIT_LOAD_EXTENSION | |
| 14054 | 14109 | "OMIT_LOAD_EXTENSION", |
| 14055 | 14110 | #endif |
| 14056 | -#ifdef SQLITE_OMIT_LOCALTIME | |
| 14111 | +#if SQLITE_OMIT_LOCALTIME | |
| 14057 | 14112 | "OMIT_LOCALTIME", |
| 14058 | 14113 | #endif |
| 14059 | -#ifdef SQLITE_OMIT_LOOKASIDE | |
| 14114 | +#if SQLITE_OMIT_LOOKASIDE | |
| 14060 | 14115 | "OMIT_LOOKASIDE", |
| 14061 | 14116 | #endif |
| 14062 | -#ifdef SQLITE_OMIT_MEMORYDB | |
| 14117 | +#if SQLITE_OMIT_MEMORYDB | |
| 14063 | 14118 | "OMIT_MEMORYDB", |
| 14064 | 14119 | #endif |
| 14065 | -#ifdef SQLITE_OMIT_OR_OPTIMIZATION | |
| 14120 | +#if SQLITE_OMIT_OR_OPTIMIZATION | |
| 14066 | 14121 | "OMIT_OR_OPTIMIZATION", |
| 14067 | 14122 | #endif |
| 14068 | -#ifdef SQLITE_OMIT_PAGER_PRAGMAS | |
| 14123 | +#if SQLITE_OMIT_PAGER_PRAGMAS | |
| 14069 | 14124 | "OMIT_PAGER_PRAGMAS", |
| 14070 | 14125 | #endif |
| 14071 | -#ifdef SQLITE_OMIT_PRAGMA | |
| 14126 | +#if SQLITE_OMIT_PRAGMA | |
| 14072 | 14127 | "OMIT_PRAGMA", |
| 14073 | 14128 | #endif |
| 14074 | -#ifdef SQLITE_OMIT_PROGRESS_CALLBACK | |
| 14129 | +#if SQLITE_OMIT_PROGRESS_CALLBACK | |
| 14075 | 14130 | "OMIT_PROGRESS_CALLBACK", |
| 14076 | 14131 | #endif |
| 14077 | -#ifdef SQLITE_OMIT_QUICKBALANCE | |
| 14132 | +#if SQLITE_OMIT_QUICKBALANCE | |
| 14078 | 14133 | "OMIT_QUICKBALANCE", |
| 14079 | 14134 | #endif |
| 14080 | -#ifdef SQLITE_OMIT_REINDEX | |
| 14135 | +#if SQLITE_OMIT_REINDEX | |
| 14081 | 14136 | "OMIT_REINDEX", |
| 14082 | 14137 | #endif |
| 14083 | -#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS | |
| 14138 | +#if SQLITE_OMIT_SCHEMA_PRAGMAS | |
| 14084 | 14139 | "OMIT_SCHEMA_PRAGMAS", |
| 14085 | 14140 | #endif |
| 14086 | -#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS | |
| 14141 | +#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS | |
| 14087 | 14142 | "OMIT_SCHEMA_VERSION_PRAGMAS", |
| 14088 | 14143 | #endif |
| 14089 | -#ifdef SQLITE_OMIT_SHARED_CACHE | |
| 14144 | +#if SQLITE_OMIT_SHARED_CACHE | |
| 14090 | 14145 | "OMIT_SHARED_CACHE", |
| 14091 | 14146 | #endif |
| 14092 | -#ifdef SQLITE_OMIT_SUBQUERY | |
| 14147 | +#if SQLITE_OMIT_SUBQUERY | |
| 14093 | 14148 | "OMIT_SUBQUERY", |
| 14094 | 14149 | #endif |
| 14095 | -#ifdef SQLITE_OMIT_TCL_VARIABLE | |
| 14150 | +#if SQLITE_OMIT_TCL_VARIABLE | |
| 14096 | 14151 | "OMIT_TCL_VARIABLE", |
| 14097 | 14152 | #endif |
| 14098 | -#ifdef SQLITE_OMIT_TEMPDB | |
| 14153 | +#if SQLITE_OMIT_TEMPDB | |
| 14099 | 14154 | "OMIT_TEMPDB", |
| 14100 | 14155 | #endif |
| 14101 | -#ifdef SQLITE_OMIT_TRACE | |
| 14156 | +#if SQLITE_OMIT_TRACE | |
| 14102 | 14157 | "OMIT_TRACE", |
| 14103 | 14158 | #endif |
| 14104 | -#ifdef SQLITE_OMIT_TRIGGER | |
| 14159 | +#if SQLITE_OMIT_TRIGGER | |
| 14105 | 14160 | "OMIT_TRIGGER", |
| 14106 | 14161 | #endif |
| 14107 | -#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION | |
| 14162 | +#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION | |
| 14108 | 14163 | "OMIT_TRUNCATE_OPTIMIZATION", |
| 14109 | 14164 | #endif |
| 14110 | -#ifdef SQLITE_OMIT_UTF16 | |
| 14165 | +#if SQLITE_OMIT_UTF16 | |
| 14111 | 14166 | "OMIT_UTF16", |
| 14112 | 14167 | #endif |
| 14113 | -#ifdef SQLITE_OMIT_VACUUM | |
| 14168 | +#if SQLITE_OMIT_VACUUM | |
| 14114 | 14169 | "OMIT_VACUUM", |
| 14115 | 14170 | #endif |
| 14116 | -#ifdef SQLITE_OMIT_VIEW | |
| 14171 | +#if SQLITE_OMIT_VIEW | |
| 14117 | 14172 | "OMIT_VIEW", |
| 14118 | 14173 | #endif |
| 14119 | -#ifdef SQLITE_OMIT_VIRTUALTABLE | |
| 14174 | +#if SQLITE_OMIT_VIRTUALTABLE | |
| 14120 | 14175 | "OMIT_VIRTUALTABLE", |
| 14121 | 14176 | #endif |
| 14122 | -#ifdef SQLITE_OMIT_WAL | |
| 14177 | +#if SQLITE_OMIT_WAL | |
| 14123 | 14178 | "OMIT_WAL", |
| 14124 | 14179 | #endif |
| 14125 | -#ifdef SQLITE_OMIT_WSD | |
| 14180 | +#if SQLITE_OMIT_WSD | |
| 14126 | 14181 | "OMIT_WSD", |
| 14127 | 14182 | #endif |
| 14128 | -#ifdef SQLITE_OMIT_XFER_OPT | |
| 14183 | +#if SQLITE_OMIT_XFER_OPT | |
| 14129 | 14184 | "OMIT_XFER_OPT", |
| 14130 | 14185 | #endif |
| 14131 | -#ifdef SQLITE_PERFORMANCE_TRACE | |
| 14186 | +#if SQLITE_PERFORMANCE_TRACE | |
| 14132 | 14187 | "PERFORMANCE_TRACE", |
| 14133 | 14188 | #endif |
| 14134 | -#ifdef SQLITE_PROXY_DEBUG | |
| 14189 | +#if SQLITE_PROXY_DEBUG | |
| 14135 | 14190 | "PROXY_DEBUG", |
| 14136 | 14191 | #endif |
| 14137 | -#ifdef SQLITE_RTREE_INT_ONLY | |
| 14192 | +#if SQLITE_RTREE_INT_ONLY | |
| 14138 | 14193 | "RTREE_INT_ONLY", |
| 14139 | 14194 | #endif |
| 14140 | -#ifdef SQLITE_SECURE_DELETE | |
| 14195 | +#if SQLITE_SECURE_DELETE | |
| 14141 | 14196 | "SECURE_DELETE", |
| 14142 | 14197 | #endif |
| 14143 | -#ifdef SQLITE_SMALL_STACK | |
| 14198 | +#if SQLITE_SMALL_STACK | |
| 14144 | 14199 | "SMALL_STACK", |
| 14145 | 14200 | #endif |
| 14146 | -#ifdef SQLITE_SOUNDEX | |
| 14201 | +#if SQLITE_SOUNDEX | |
| 14147 | 14202 | "SOUNDEX", |
| 14148 | 14203 | #endif |
| 14149 | -#ifdef SQLITE_SYSTEM_MALLOC | |
| 14204 | +#if SQLITE_SYSTEM_MALLOC | |
| 14150 | 14205 | "SYSTEM_MALLOC", |
| 14151 | 14206 | #endif |
| 14152 | -#ifdef SQLITE_TCL | |
| 14207 | +#if SQLITE_TCL | |
| 14153 | 14208 | "TCL", |
| 14154 | 14209 | #endif |
| 14155 | 14210 | #if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) |
| 14156 | 14211 | "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), |
| 14157 | 14212 | #endif |
| 14158 | -#ifdef SQLITE_TEST | |
| 14213 | +#if SQLITE_TEST | |
| 14159 | 14214 | "TEST", |
| 14160 | 14215 | #endif |
| 14161 | 14216 | #if defined(SQLITE_THREADSAFE) |
| 14162 | 14217 | "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), |
| 14163 | 14218 | #endif |
| 14164 | -#ifdef SQLITE_USE_ALLOCA | |
| 14219 | +#if SQLITE_USE_ALLOCA | |
| 14165 | 14220 | "USE_ALLOCA", |
| 14166 | 14221 | #endif |
| 14167 | -#ifdef SQLITE_USER_AUTHENTICATION | |
| 14222 | +#if SQLITE_USER_AUTHENTICATION | |
| 14168 | 14223 | "USER_AUTHENTICATION", |
| 14169 | 14224 | #endif |
| 14170 | -#ifdef SQLITE_WIN32_MALLOC | |
| 14225 | +#if SQLITE_WIN32_MALLOC | |
| 14171 | 14226 | "WIN32_MALLOC", |
| 14172 | 14227 | #endif |
| 14173 | -#ifdef SQLITE_ZERO_MALLOC | |
| 14228 | +#if SQLITE_ZERO_MALLOC | |
| 14174 | 14229 | "ZERO_MALLOC" |
| 14175 | 14230 | #endif |
| 14176 | 14231 | }; |
| 14177 | 14232 | |
| 14178 | 14233 | /* |
| @@ -14183,11 +14238,11 @@ | ||
| 14183 | 14238 | ** is not required for a match. |
| 14184 | 14239 | */ |
| 14185 | 14240 | SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ |
| 14186 | 14241 | int i, n; |
| 14187 | 14242 | |
| 14188 | -#ifdef SQLITE_ENABLE_API_ARMOR | |
| 14243 | +#if SQLITE_ENABLE_API_ARMOR | |
| 14189 | 14244 | if( zOptName==0 ){ |
| 14190 | 14245 | (void)SQLITE_MISUSE_BKPT; |
| 14191 | 14246 | return 0; |
| 14192 | 14247 | } |
| 14193 | 14248 | #endif |
| @@ -15411,12 +15466,13 @@ | ||
| 15411 | 15466 | ** |
| 15412 | 15467 | ** If the user has not indicated to use localtime_r() or localtime_s() |
| 15413 | 15468 | ** already, check for an MSVC build environment that provides |
| 15414 | 15469 | ** localtime_s(). |
| 15415 | 15470 | */ |
| 15416 | -#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ | |
| 15417 | - defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) | |
| 15471 | +#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \ | |
| 15472 | + && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) | |
| 15473 | +#undef HAVE_LOCALTIME_S | |
| 15418 | 15474 | #define HAVE_LOCALTIME_S 1 |
| 15419 | 15475 | #endif |
| 15420 | 15476 | |
| 15421 | 15477 | #ifndef SQLITE_OMIT_LOCALTIME |
| 15422 | 15478 | /* |
| @@ -15432,12 +15488,11 @@ | ||
| 15432 | 15488 | ** library function localtime_r() is used to assist in the calculation of |
| 15433 | 15489 | ** local time. |
| 15434 | 15490 | */ |
| 15435 | 15491 | static int osLocaltime(time_t *t, struct tm *pTm){ |
| 15436 | 15492 | int rc; |
| 15437 | -#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ | |
| 15438 | - && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) | |
| 15493 | +#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S | |
| 15439 | 15494 | struct tm *pX; |
| 15440 | 15495 | #if SQLITE_THREADSAFE>0 |
| 15441 | 15496 | sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
| 15442 | 15497 | #endif |
| 15443 | 15498 | sqlite3_mutex_enter(mutex); |
| @@ -15450,11 +15505,11 @@ | ||
| 15450 | 15505 | rc = pX==0; |
| 15451 | 15506 | #else |
| 15452 | 15507 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 15453 | 15508 | if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; |
| 15454 | 15509 | #endif |
| 15455 | -#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R | |
| 15510 | +#if HAVE_LOCALTIME_R | |
| 15456 | 15511 | rc = localtime_r(t, pTm)==0; |
| 15457 | 15512 | #else |
| 15458 | 15513 | rc = localtime_s(pTm, t); |
| 15459 | 15514 | #endif /* HAVE_LOCALTIME_R */ |
| 15460 | 15515 | #endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ |
| @@ -15894,12 +15949,14 @@ | ||
| 15894 | 15949 | DateTime x; |
| 15895 | 15950 | u64 n; |
| 15896 | 15951 | size_t i,j; |
| 15897 | 15952 | char *z; |
| 15898 | 15953 | sqlite3 *db; |
| 15899 | - const char *zFmt = (const char*)sqlite3_value_text(argv[0]); | |
| 15954 | + const char *zFmt; | |
| 15900 | 15955 | char zBuf[100]; |
| 15956 | + if( argc==0 ) return; | |
| 15957 | + zFmt = (const char*)sqlite3_value_text(argv[0]); | |
| 15901 | 15958 | if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; |
| 15902 | 15959 | db = sqlite3_context_db_handle(context); |
| 15903 | 15960 | for(i=0, n=1; zFmt[i]; i++, n++){ |
| 15904 | 15961 | if( zFmt[i]=='%' ){ |
| 15905 | 15962 | switch( zFmt[i+1] ){ |
| @@ -16089,11 +16146,11 @@ | ||
| 16089 | 16146 | UNUSED_PARAMETER(argv); |
| 16090 | 16147 | |
| 16091 | 16148 | iT = sqlite3StmtCurrentTime(context); |
| 16092 | 16149 | if( iT<=0 ) return; |
| 16093 | 16150 | t = iT/1000 - 10000*(sqlite3_int64)21086676; |
| 16094 | -#ifdef HAVE_GMTIME_R | |
| 16151 | +#if HAVE_GMTIME_R | |
| 16095 | 16152 | pTm = gmtime_r(&t, &sNow); |
| 16096 | 16153 | #else |
| 16097 | 16154 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
| 16098 | 16155 | pTm = gmtime(&t); |
| 16099 | 16156 | if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); |
| @@ -16763,13 +16820,13 @@ | ||
| 16763 | 16820 | |
| 16764 | 16821 | /* |
| 16765 | 16822 | ** The malloc.h header file is needed for malloc_usable_size() function |
| 16766 | 16823 | ** on some systems (e.g. Linux). |
| 16767 | 16824 | */ |
| 16768 | -#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE) | |
| 16769 | -# define SQLITE_USE_MALLOC_H | |
| 16770 | -# define SQLITE_USE_MALLOC_USABLE_SIZE | |
| 16825 | +#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE | |
| 16826 | +# define SQLITE_USE_MALLOC_H 1 | |
| 16827 | +# define SQLITE_USE_MALLOC_USABLE_SIZE 1 | |
| 16771 | 16828 | /* |
| 16772 | 16829 | ** The MSVCRT has malloc_usable_size(), but it is called _msize(). The |
| 16773 | 16830 | ** use of _msize() is automatic, but can be disabled by compiling with |
| 16774 | 16831 | ** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires |
| 16775 | 16832 | ** the malloc.h header file. |
| @@ -21004,21 +21061,10 @@ | ||
| 21004 | 21061 | ** This file contains code for a set of "printf"-like routines. These |
| 21005 | 21062 | ** routines format strings much like the printf() from the standard C |
| 21006 | 21063 | ** library, though the implementation here has enhancements to support |
| 21007 | 21064 | ** SQLlite. |
| 21008 | 21065 | */ |
| 21009 | - | |
| 21010 | -/* | |
| 21011 | -** If the strchrnul() library function is available, then set | |
| 21012 | -** HAVE_STRCHRNUL. If that routine is not available, this module | |
| 21013 | -** will supply its own. The built-in version is slower than | |
| 21014 | -** the glibc version so the glibc version is definitely preferred. | |
| 21015 | -*/ | |
| 21016 | -#if !defined(HAVE_STRCHRNUL) | |
| 21017 | -# define HAVE_STRCHRNUL 0 | |
| 21018 | -#endif | |
| 21019 | - | |
| 21020 | 21066 | |
| 21021 | 21067 | /* |
| 21022 | 21068 | ** Conversion types fall into various categories as defined by the |
| 21023 | 21069 | ** following enumeration. |
| 21024 | 21070 | */ |
| @@ -22313,10 +22359,12 @@ | ||
| 22313 | 22359 | ** single threaded systems. Nothing in SQLite requires multiple threads. |
| 22314 | 22360 | ** This interface exists so that applications that want to take advantage |
| 22315 | 22361 | ** of multiple cores can do so, while also allowing applications to stay |
| 22316 | 22362 | ** single-threaded if desired. |
| 22317 | 22363 | */ |
| 22364 | +#if SQLITE_OS_WIN | |
| 22365 | +#endif | |
| 22318 | 22366 | |
| 22319 | 22367 | #if SQLITE_MAX_WORKER_THREADS>0 |
| 22320 | 22368 | |
| 22321 | 22369 | /********************************* Unix Pthreads ****************************/ |
| 22322 | 22370 | #if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 |
| @@ -23099,11 +23147,11 @@ | ||
| 23099 | 23147 | ** This file contains functions for allocating memory, comparing |
| 23100 | 23148 | ** strings, and stuff like that. |
| 23101 | 23149 | ** |
| 23102 | 23150 | */ |
| 23103 | 23151 | /* #include <stdarg.h> */ |
| 23104 | -#ifdef SQLITE_HAVE_ISNAN | |
| 23152 | +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN | |
| 23105 | 23153 | # include <math.h> |
| 23106 | 23154 | #endif |
| 23107 | 23155 | |
| 23108 | 23156 | /* |
| 23109 | 23157 | ** Routine needed to support the testcase() macro. |
| @@ -23140,11 +23188,11 @@ | ||
| 23140 | 23188 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
| 23141 | 23189 | ** Otherwise, we have our own implementation that works on most systems. |
| 23142 | 23190 | */ |
| 23143 | 23191 | SQLITE_PRIVATE int sqlite3IsNaN(double x){ |
| 23144 | 23192 | int rc; /* The value return */ |
| 23145 | -#if !defined(SQLITE_HAVE_ISNAN) | |
| 23193 | +#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN | |
| 23146 | 23194 | /* |
| 23147 | 23195 | ** Systems that support the isnan() library function should probably |
| 23148 | 23196 | ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have |
| 23149 | 23197 | ** found that many systems do not have a working isnan() function so |
| 23150 | 23198 | ** this implementation is provided as an alternative. |
| @@ -23170,13 +23218,13 @@ | ||
| 23170 | 23218 | # error SQLite will not work correctly with the -ffast-math option of GCC. |
| 23171 | 23219 | #endif |
| 23172 | 23220 | volatile double y = x; |
| 23173 | 23221 | volatile double z = y; |
| 23174 | 23222 | rc = (y!=z); |
| 23175 | -#else /* if defined(SQLITE_HAVE_ISNAN) */ | |
| 23223 | +#else /* if HAVE_ISNAN */ | |
| 23176 | 23224 | rc = isnan(x); |
| 23177 | -#endif /* SQLITE_HAVE_ISNAN */ | |
| 23225 | +#endif /* HAVE_ISNAN */ | |
| 23178 | 23226 | testcase( rc ); |
| 23179 | 23227 | return rc; |
| 23180 | 23228 | } |
| 23181 | 23229 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 23182 | 23230 | |
| @@ -28493,13 +28541,13 @@ | ||
| 28493 | 28541 | |
| 28494 | 28542 | /* |
| 28495 | 28543 | ** We do not trust systems to provide a working fdatasync(). Some do. |
| 28496 | 28544 | ** Others do no. To be safe, we will stick with the (slightly slower) |
| 28497 | 28545 | ** fsync(). If you know that your system does support fdatasync() correctly, |
| 28498 | -** then simply compile with -Dfdatasync=fdatasync | |
| 28546 | +** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC | |
| 28499 | 28547 | */ |
| 28500 | -#if !defined(fdatasync) | |
| 28548 | +#if !defined(fdatasync) && !HAVE_FDATASYNC | |
| 28501 | 28549 | # define fdatasync fsync |
| 28502 | 28550 | #endif |
| 28503 | 28551 | |
| 28504 | 28552 | /* |
| 28505 | 28553 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| @@ -28824,22 +28872,23 @@ | ||
| 28824 | 28872 | ** at offset (nSize-1), to set the size of the file correctly. |
| 28825 | 28873 | ** This is a similar technique to that used by glibc on systems |
| 28826 | 28874 | ** that do not have a real fallocate() call. |
| 28827 | 28875 | */ |
| 28828 | 28876 | int nBlk = buf.st_blksize; /* File-system block size */ |
| 28877 | + int nWrite = 0; /* Number of bytes written by seekAndWrite */ | |
| 28829 | 28878 | i64 iWrite; /* Next offset to write to */ |
| 28830 | 28879 | |
| 28831 | 28880 | iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; |
| 28832 | 28881 | assert( iWrite>=buf.st_size ); |
| 28833 | 28882 | assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) ); |
| 28834 | 28883 | assert( ((iWrite+1)%nBlk)==0 ); |
| 28835 | 28884 | for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){ |
| 28836 | - int nWrite = seekAndWrite(pFile, iWrite, "", 1); | |
| 28885 | + nWrite = seekAndWrite(pFile, iWrite, "", 1); | |
| 28837 | 28886 | if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
| 28838 | 28887 | } |
| 28839 | - if( nSize%nBlk ){ | |
| 28840 | - int nWrite = seekAndWrite(pFile, nSize-1, "", 1); | |
| 28888 | + if( nWrite==0 || (nSize%nBlk) ){ | |
| 28889 | + nWrite = seekAndWrite(pFile, nSize-1, "", 1); | |
| 28841 | 28890 | if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
| 28842 | 28891 | } |
| 28843 | 28892 | #endif |
| 28844 | 28893 | } |
| 28845 | 28894 | } |
| @@ -38849,22 +38898,10 @@ | ||
| 38849 | 38898 | void *pStress; /* Argument to xStress */ |
| 38850 | 38899 | sqlite3_pcache *pCache; /* Pluggable cache module */ |
| 38851 | 38900 | PgHdr *pPage1; /* Reference to page 1 */ |
| 38852 | 38901 | }; |
| 38853 | 38902 | |
| 38854 | -/* | |
| 38855 | -** Some of the assert() macros in this code are too expensive to run | |
| 38856 | -** even during normal debugging. Use them only rarely on long-running | |
| 38857 | -** tests. Enable the expensive asserts using the | |
| 38858 | -** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option. | |
| 38859 | -*/ | |
| 38860 | -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT | |
| 38861 | -# define expensive_assert(X) assert(X) | |
| 38862 | -#else | |
| 38863 | -# define expensive_assert(X) | |
| 38864 | -#endif | |
| 38865 | - | |
| 38866 | 38903 | /********************************** Linked List Management ********************/ |
| 38867 | 38904 | |
| 38868 | 38905 | /* Allowed values for second argument to pcacheManageDirtyList() */ |
| 38869 | 38906 | #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ |
| 38870 | 38907 | #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ |
| @@ -73905,12 +73942,12 @@ | ||
| 73905 | 73942 | pIdxKey->default_rc = 0; |
| 73906 | 73943 | if( pOp->opcode==OP_NoConflict ){ |
| 73907 | 73944 | /* For the OP_NoConflict opcode, take the jump if any of the |
| 73908 | 73945 | ** input fields are NULL, since any key with a NULL will not |
| 73909 | 73946 | ** conflict */ |
| 73910 | - for(ii=0; ii<r.nField; ii++){ | |
| 73911 | - if( r.aMem[ii].flags & MEM_Null ){ | |
| 73947 | + for(ii=0; ii<pIdxKey->nField; ii++){ | |
| 73948 | + if( pIdxKey->aMem[ii].flags & MEM_Null ){ | |
| 73912 | 73949 | pc = pOp->p2 - 1; VdbeBranchTaken(1,2); |
| 73913 | 73950 | break; |
| 73914 | 73951 | } |
| 73915 | 73952 | } |
| 73916 | 73953 | } |
| @@ -79464,10 +79501,11 @@ | ||
| 79464 | 79501 | rc = vdbePmaReaderNext(pSorter->pReader); |
| 79465 | 79502 | *pbEof = (pSorter->pReader->pFd==0); |
| 79466 | 79503 | }else |
| 79467 | 79504 | #endif |
| 79468 | 79505 | /*if( !pSorter->bUseThreads )*/ { |
| 79506 | + assert( pSorter->pMerger!=0 ); | |
| 79469 | 79507 | assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); |
| 79470 | 79508 | rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); |
| 79471 | 79509 | } |
| 79472 | 79510 | }else{ |
| 79473 | 79511 | SorterRecord *pFree = pSorter->list.pList; |
| @@ -82230,11 +82268,11 @@ | ||
| 82230 | 82268 | Expr *pLeft, /* Left operand */ |
| 82231 | 82269 | Expr *pRight, /* Right operand */ |
| 82232 | 82270 | const Token *pToken /* Argument token */ |
| 82233 | 82271 | ){ |
| 82234 | 82272 | Expr *p; |
| 82235 | - if( op==TK_AND && pLeft && pRight ){ | |
| 82273 | + if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){ | |
| 82236 | 82274 | /* Take advantage of short-circuit false optimization for AND */ |
| 82237 | 82275 | p = sqlite3ExprAnd(pParse->db, pLeft, pRight); |
| 82238 | 82276 | }else{ |
| 82239 | 82277 | p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); |
| 82240 | 82278 | sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); |
| @@ -85784,14 +85822,15 @@ | ||
| 85784 | 85822 | ** NEVER() will need to be removed. */ |
| 85785 | 85823 | if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ |
| 85786 | 85824 | int i; |
| 85787 | 85825 | struct SrcCount *p = pWalker->u.pSrcCount; |
| 85788 | 85826 | SrcList *pSrc = p->pSrc; |
| 85789 | - for(i=0; i<pSrc->nSrc; i++){ | |
| 85827 | + int nSrc = pSrc ? pSrc->nSrc : 0; | |
| 85828 | + for(i=0; i<nSrc; i++){ | |
| 85790 | 85829 | if( pExpr->iTable==pSrc->a[i].iCursor ) break; |
| 85791 | 85830 | } |
| 85792 | - if( i<pSrc->nSrc ){ | |
| 85831 | + if( i<nSrc ){ | |
| 85793 | 85832 | p->nThis++; |
| 85794 | 85833 | }else{ |
| 85795 | 85834 | p->nOther++; |
| 85796 | 85835 | } |
| 85797 | 85836 | } |
| @@ -94664,12 +94703,12 @@ | ||
| 94664 | 94703 | const char *zDb; /* Name of database holding pTab */ |
| 94665 | 94704 | int i; /* Loop counter */ |
| 94666 | 94705 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| 94667 | 94706 | Index *pIdx; /* For looping over indices of the table */ |
| 94668 | 94707 | int iTabCur; /* Cursor number for the table */ |
| 94669 | - int iDataCur; /* VDBE cursor for the canonical data source */ | |
| 94670 | - int iIdxCur; /* Cursor number of the first index */ | |
| 94708 | + int iDataCur = 0; /* VDBE cursor for the canonical data source */ | |
| 94709 | + int iIdxCur = 0; /* Cursor number of the first index */ | |
| 94671 | 94710 | int nIdx; /* Number of indices */ |
| 94672 | 94711 | sqlite3 *db; /* Main database structure */ |
| 94673 | 94712 | AuthContext sContext; /* Authorization context */ |
| 94674 | 94713 | NameContext sNC; /* Name context to resolve expressions in */ |
| 94675 | 94714 | int iDb; /* Database number */ |
| @@ -102658,11 +102697,11 @@ | ||
| 102658 | 102697 | char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ |
| 102659 | 102698 | const char *zDb = 0; /* The database name */ |
| 102660 | 102699 | Token *pId; /* Pointer to <id> token */ |
| 102661 | 102700 | char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ |
| 102662 | 102701 | int iDb; /* Database index for <database> */ |
| 102663 | - int lwr, upr, mid; /* Binary search bounds */ | |
| 102702 | + int lwr, upr, mid = 0; /* Binary search bounds */ | |
| 102664 | 102703 | int rc; /* return value form SQLITE_FCNTL_PRAGMA */ |
| 102665 | 102704 | sqlite3 *db = pParse->db; /* The database connection */ |
| 102666 | 102705 | Db *pDb; /* The specific database being pragmaed */ |
| 102667 | 102706 | Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ |
| 102668 | 102707 | |
| @@ -105271,24 +105310,29 @@ | ||
| 105271 | 105310 | u8 sortFlags; /* Zero or more SORTFLAG_* bits */ |
| 105272 | 105311 | }; |
| 105273 | 105312 | #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ |
| 105274 | 105313 | |
| 105275 | 105314 | /* |
| 105276 | -** Delete all the content of a Select structure but do not deallocate | |
| 105277 | -** the select structure itself. | |
| 105315 | +** Delete all the content of a Select structure. Deallocate the structure | |
| 105316 | +** itself only if bFree is true. | |
| 105278 | 105317 | */ |
| 105279 | -static void clearSelect(sqlite3 *db, Select *p){ | |
| 105280 | - sqlite3ExprListDelete(db, p->pEList); | |
| 105281 | - sqlite3SrcListDelete(db, p->pSrc); | |
| 105282 | - sqlite3ExprDelete(db, p->pWhere); | |
| 105283 | - sqlite3ExprListDelete(db, p->pGroupBy); | |
| 105284 | - sqlite3ExprDelete(db, p->pHaving); | |
| 105285 | - sqlite3ExprListDelete(db, p->pOrderBy); | |
| 105286 | - sqlite3SelectDelete(db, p->pPrior); | |
| 105287 | - sqlite3ExprDelete(db, p->pLimit); | |
| 105288 | - sqlite3ExprDelete(db, p->pOffset); | |
| 105289 | - sqlite3WithDelete(db, p->pWith); | |
| 105318 | +static void clearSelect(sqlite3 *db, Select *p, int bFree){ | |
| 105319 | + while( p ){ | |
| 105320 | + Select *pPrior = p->pPrior; | |
| 105321 | + sqlite3ExprListDelete(db, p->pEList); | |
| 105322 | + sqlite3SrcListDelete(db, p->pSrc); | |
| 105323 | + sqlite3ExprDelete(db, p->pWhere); | |
| 105324 | + sqlite3ExprListDelete(db, p->pGroupBy); | |
| 105325 | + sqlite3ExprDelete(db, p->pHaving); | |
| 105326 | + sqlite3ExprListDelete(db, p->pOrderBy); | |
| 105327 | + sqlite3ExprDelete(db, p->pLimit); | |
| 105328 | + sqlite3ExprDelete(db, p->pOffset); | |
| 105329 | + sqlite3WithDelete(db, p->pWith); | |
| 105330 | + if( bFree ) sqlite3DbFree(db, p); | |
| 105331 | + p = pPrior; | |
| 105332 | + bFree = 1; | |
| 105333 | + } | |
| 105290 | 105334 | } |
| 105291 | 105335 | |
| 105292 | 105336 | /* |
| 105293 | 105337 | ** Initialize a SelectDest structure. |
| 105294 | 105338 | */ |
| @@ -105343,12 +105387,11 @@ | ||
| 105343 | 105387 | pNew->pOffset = pOffset; |
| 105344 | 105388 | assert( pOffset==0 || pLimit!=0 ); |
| 105345 | 105389 | pNew->addrOpenEphm[0] = -1; |
| 105346 | 105390 | pNew->addrOpenEphm[1] = -1; |
| 105347 | 105391 | if( db->mallocFailed ) { |
| 105348 | - clearSelect(db, pNew); | |
| 105349 | - if( pNew!=&standin ) sqlite3DbFree(db, pNew); | |
| 105392 | + clearSelect(db, pNew, pNew!=&standin); | |
| 105350 | 105393 | pNew = 0; |
| 105351 | 105394 | }else{ |
| 105352 | 105395 | assert( pNew->pSrc!=0 || pParse->nErr>0 ); |
| 105353 | 105396 | } |
| 105354 | 105397 | assert( pNew!=&standin ); |
| @@ -105369,14 +105412,11 @@ | ||
| 105369 | 105412 | |
| 105370 | 105413 | /* |
| 105371 | 105414 | ** Delete the given Select structure and all of its substructures. |
| 105372 | 105415 | */ |
| 105373 | 105416 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ |
| 105374 | - if( p ){ | |
| 105375 | - clearSelect(db, p); | |
| 105376 | - sqlite3DbFree(db, p); | |
| 105377 | - } | |
| 105417 | + clearSelect(db, p, 1); | |
| 105378 | 105418 | } |
| 105379 | 105419 | |
| 105380 | 105420 | /* |
| 105381 | 105421 | ** Return a pointer to the right-most SELECT statement in a compound. |
| 105382 | 105422 | */ |
| @@ -107288,10 +107328,70 @@ | ||
| 107288 | 107328 | Parse *pParse, /* Parsing context */ |
| 107289 | 107329 | Select *p, /* The right-most of SELECTs to be coded */ |
| 107290 | 107330 | SelectDest *pDest /* What to do with query results */ |
| 107291 | 107331 | ); |
| 107292 | 107332 | |
| 107333 | +/* | |
| 107334 | +** Error message for when two or more terms of a compound select have different | |
| 107335 | +** size result sets. | |
| 107336 | +*/ | |
| 107337 | +static void selectWrongNumTermsError(Parse *pParse, Select *p){ | |
| 107338 | + if( p->selFlags & SF_Values ){ | |
| 107339 | + sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); | |
| 107340 | + }else{ | |
| 107341 | + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" | |
| 107342 | + " do not have the same number of result columns", selectOpName(p->op)); | |
| 107343 | + } | |
| 107344 | +} | |
| 107345 | + | |
| 107346 | +/* | |
| 107347 | +** Handle the special case of a compound-select that originates from a | |
| 107348 | +** VALUES clause. By handling this as a special case, we avoid deep | |
| 107349 | +** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT | |
| 107350 | +** on a VALUES clause. | |
| 107351 | +** | |
| 107352 | +** Because the Select object originates from a VALUES clause: | |
| 107353 | +** (1) It has no LIMIT or OFFSET | |
| 107354 | +** (2) All terms are UNION ALL | |
| 107355 | +** (3) There is no ORDER BY clause | |
| 107356 | +*/ | |
| 107357 | +static int multiSelectValues( | |
| 107358 | + Parse *pParse, /* Parsing context */ | |
| 107359 | + Select *p, /* The right-most of SELECTs to be coded */ | |
| 107360 | + SelectDest *pDest /* What to do with query results */ | |
| 107361 | +){ | |
| 107362 | + Select *pPrior; | |
| 107363 | + int nExpr = p->pEList->nExpr; | |
| 107364 | + int nRow = 1; | |
| 107365 | + int rc = 0; | |
| 107366 | + assert( p->pNext==0 ); | |
| 107367 | + assert( p->selFlags & SF_AllValues ); | |
| 107368 | + do{ | |
| 107369 | + assert( p->selFlags & SF_Values ); | |
| 107370 | + assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); | |
| 107371 | + assert( p->pLimit==0 ); | |
| 107372 | + assert( p->pOffset==0 ); | |
| 107373 | + if( p->pEList->nExpr!=nExpr ){ | |
| 107374 | + selectWrongNumTermsError(pParse, p); | |
| 107375 | + return 1; | |
| 107376 | + } | |
| 107377 | + if( p->pPrior==0 ) break; | |
| 107378 | + assert( p->pPrior->pNext==p ); | |
| 107379 | + p = p->pPrior; | |
| 107380 | + nRow++; | |
| 107381 | + }while(1); | |
| 107382 | + while( p ){ | |
| 107383 | + pPrior = p->pPrior; | |
| 107384 | + p->pPrior = 0; | |
| 107385 | + rc = sqlite3Select(pParse, p, pDest); | |
| 107386 | + p->pPrior = pPrior; | |
| 107387 | + if( rc ) break; | |
| 107388 | + p->nSelectRow = nRow; | |
| 107389 | + p = p->pNext; | |
| 107390 | + } | |
| 107391 | + return rc; | |
| 107392 | +} | |
| 107293 | 107393 | |
| 107294 | 107394 | /* |
| 107295 | 107395 | ** This routine is called to process a compound query form from |
| 107296 | 107396 | ** two or more separate queries using UNION, UNION ALL, EXCEPT, or |
| 107297 | 107397 | ** INTERSECT |
| @@ -107368,22 +107468,24 @@ | ||
| 107368 | 107468 | assert( p->pEList ); |
| 107369 | 107469 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); |
| 107370 | 107470 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 107371 | 107471 | dest.eDest = SRT_Table; |
| 107372 | 107472 | } |
| 107473 | + | |
| 107474 | + /* Special handling for a compound-select that originates as a VALUES clause. | |
| 107475 | + */ | |
| 107476 | + if( p->selFlags & SF_AllValues ){ | |
| 107477 | + rc = multiSelectValues(pParse, p, &dest); | |
| 107478 | + goto multi_select_end; | |
| 107479 | + } | |
| 107373 | 107480 | |
| 107374 | 107481 | /* Make sure all SELECTs in the statement have the same number of elements |
| 107375 | 107482 | ** in their result sets. |
| 107376 | 107483 | */ |
| 107377 | 107484 | assert( p->pEList && pPrior->pEList ); |
| 107378 | 107485 | if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ |
| 107379 | - if( p->selFlags & SF_Values ){ | |
| 107380 | - sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); | |
| 107381 | - }else{ | |
| 107382 | - sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" | |
| 107383 | - " do not have the same number of result columns", selectOpName(p->op)); | |
| 107384 | - } | |
| 107486 | + selectWrongNumTermsError(pParse, p); | |
| 107385 | 107487 | rc = 1; |
| 107386 | 107488 | goto multi_select_end; |
| 107387 | 107489 | } |
| 107388 | 107490 | |
| 107389 | 107491 | #ifndef SQLITE_OMIT_CTE |
| @@ -109265,11 +109367,13 @@ | ||
| 109265 | 109367 | if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ |
| 109266 | 109368 | return WRC_Prune; |
| 109267 | 109369 | } |
| 109268 | 109370 | pTabList = p->pSrc; |
| 109269 | 109371 | pEList = p->pEList; |
| 109270 | - sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); | |
| 109372 | + if( pWalker->xSelectCallback2==selectPopWith ){ | |
| 109373 | + sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); | |
| 109374 | + } | |
| 109271 | 109375 | |
| 109272 | 109376 | /* Make sure cursor numbers have been assigned to all entries in |
| 109273 | 109377 | ** the FROM clause of the SELECT statement. |
| 109274 | 109378 | */ |
| 109275 | 109379 | sqlite3SrcListAssignCursors(pParse, pTabList); |
| @@ -109556,11 +109660,13 @@ | ||
| 109556 | 109660 | if( pParse->hasCompound ){ |
| 109557 | 109661 | w.xSelectCallback = convertCompoundSelectToSubquery; |
| 109558 | 109662 | sqlite3WalkSelect(&w, pSelect); |
| 109559 | 109663 | } |
| 109560 | 109664 | w.xSelectCallback = selectExpander; |
| 109561 | - w.xSelectCallback2 = selectPopWith; | |
| 109665 | + if( (pSelect->selFlags & SF_AllValues)==0 ){ | |
| 109666 | + w.xSelectCallback2 = selectPopWith; | |
| 109667 | + } | |
| 109562 | 109668 | sqlite3WalkSelect(&w, pSelect); |
| 109563 | 109669 | } |
| 109564 | 109670 | |
| 109565 | 109671 | |
| 109566 | 109672 | #ifndef SQLITE_OMIT_SUBQUERY |
| @@ -123884,17 +123990,23 @@ | ||
| 123884 | 123990 | Select *p = yymsp[0].minor.yy3, *pNext, *pLoop; |
| 123885 | 123991 | if( p ){ |
| 123886 | 123992 | int cnt = 0, mxSelect; |
| 123887 | 123993 | p->pWith = yymsp[-1].minor.yy59; |
| 123888 | 123994 | if( p->pPrior ){ |
| 123995 | + u16 allValues = SF_Values; | |
| 123889 | 123996 | pNext = 0; |
| 123890 | 123997 | for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ |
| 123891 | 123998 | pLoop->pNext = pNext; |
| 123892 | 123999 | pLoop->selFlags |= SF_Compound; |
| 124000 | + allValues &= pLoop->selFlags; | |
| 123893 | 124001 | } |
| 123894 | - mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; | |
| 123895 | - if( mxSelect && cnt>mxSelect ){ | |
| 124002 | + if( allValues ){ | |
| 124003 | + p->selFlags |= SF_AllValues; | |
| 124004 | + }else if( | |
| 124005 | + (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 | |
| 124006 | + && cnt>mxSelect | |
| 124007 | + ){ | |
| 123896 | 124008 | sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); |
| 123897 | 124009 | } |
| 123898 | 124010 | } |
| 123899 | 124011 | }else{ |
| 123900 | 124012 | sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59); |
| @@ -127600,11 +127712,11 @@ | ||
| 127600 | 127712 | */ |
| 127601 | 127713 | static int sqliteDefaultBusyCallback( |
| 127602 | 127714 | void *ptr, /* Database connection */ |
| 127603 | 127715 | int count /* Number of times table has been busy */ |
| 127604 | 127716 | ){ |
| 127605 | -#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP) | |
| 127717 | +#if SQLITE_OS_WIN || HAVE_USLEEP | |
| 127606 | 127718 | static const u8 delays[] = |
| 127607 | 127719 | { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; |
| 127608 | 127720 | static const u8 totals[] = |
| 127609 | 127721 | { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; |
| 127610 | 127722 | # define NDELAY ArraySize(delays) |
| @@ -129390,11 +129502,11 @@ | ||
| 129390 | 129502 | ){ |
| 129391 | 129503 | int rc; |
| 129392 | 129504 | char *zErrMsg = 0; |
| 129393 | 129505 | Table *pTab = 0; |
| 129394 | 129506 | Column *pCol = 0; |
| 129395 | - int iCol; | |
| 129507 | + int iCol = 0; | |
| 129396 | 129508 | |
| 129397 | 129509 | char const *zDataType = 0; |
| 129398 | 129510 | char const *zCollSeq = 0; |
| 129399 | 129511 | int notnull = 0; |
| 129400 | 129512 | int primarykey = 0; |
| @@ -133013,11 +133125,11 @@ | ||
| 133013 | 133125 | const char *zNode, /* Buffer containing segment interior node */ |
| 133014 | 133126 | int nNode, /* Size of buffer at zNode */ |
| 133015 | 133127 | sqlite3_int64 *piLeaf, /* Selected leaf node */ |
| 133016 | 133128 | sqlite3_int64 *piLeaf2 /* Selected leaf node */ |
| 133017 | 133129 | ){ |
| 133018 | - int rc; /* Return code */ | |
| 133130 | + int rc = SQLITE_OK; /* Return code */ | |
| 133019 | 133131 | int iHeight; /* Height of this node in tree */ |
| 133020 | 133132 | |
| 133021 | 133133 | assert( piLeaf || piLeaf2 ); |
| 133022 | 133134 | |
| 133023 | 133135 | fts3GetVarint32(zNode, &iHeight); |
| @@ -133024,11 +133136,11 @@ | ||
| 133024 | 133136 | rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); |
| 133025 | 133137 | assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); |
| 133026 | 133138 | |
| 133027 | 133139 | if( rc==SQLITE_OK && iHeight>1 ){ |
| 133028 | 133140 | char *zBlob = 0; /* Blob read from %_segments table */ |
| 133029 | - int nBlob; /* Size of zBlob in bytes */ | |
| 133141 | + int nBlob = 0; /* Size of zBlob in bytes */ | |
| 133030 | 133142 | |
| 133031 | 133143 | if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ |
| 133032 | 133144 | rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); |
| 133033 | 133145 | if( rc==SQLITE_OK ){ |
| 133034 | 133146 | rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); |
| @@ -134246,11 +134358,11 @@ | ||
| 134246 | 134358 | int idxNum, /* Strategy index */ |
| 134247 | 134359 | const char *idxStr, /* Unused */ |
| 134248 | 134360 | int nVal, /* Number of elements in apVal */ |
| 134249 | 134361 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 134250 | 134362 | ){ |
| 134251 | - int rc; | |
| 134363 | + int rc = SQLITE_OK; | |
| 134252 | 134364 | char *zSql; /* SQL statement used to access %_content */ |
| 134253 | 134365 | int eSearch; |
| 134254 | 134366 | Fts3Table *p = (Fts3Table *)pCursor->pVtab; |
| 134255 | 134367 | Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; |
| 134256 | 134368 | |
| @@ -140734,11 +140846,11 @@ | ||
| 140734 | 140846 | int argc, /* Number of elements in argv array */ |
| 140735 | 140847 | const char * const *argv, /* xCreate/xConnect argument array */ |
| 140736 | 140848 | sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
| 140737 | 140849 | char **pzErr /* OUT: sqlite3_malloc'd error message */ |
| 140738 | 140850 | ){ |
| 140739 | - Fts3tokTable *pTab; | |
| 140851 | + Fts3tokTable *pTab = 0; | |
| 140740 | 140852 | const sqlite3_tokenizer_module *pMod = 0; |
| 140741 | 140853 | sqlite3_tokenizer *pTok = 0; |
| 140742 | 140854 | int rc; |
| 140743 | 140855 | char **azDequote = 0; |
| 140744 | 140856 | int nDequote; |
| @@ -144109,12 +144221,12 @@ | ||
| 144109 | 144221 | } |
| 144110 | 144222 | rc = sqlite3_reset(pRange); |
| 144111 | 144223 | |
| 144112 | 144224 | if( bOk ){ |
| 144113 | 144225 | int iIdx = 0; |
| 144114 | - sqlite3_stmt *pUpdate1; | |
| 144115 | - sqlite3_stmt *pUpdate2; | |
| 144226 | + sqlite3_stmt *pUpdate1 = 0; | |
| 144227 | + sqlite3_stmt *pUpdate2 = 0; | |
| 144116 | 144228 | |
| 144117 | 144229 | if( rc==SQLITE_OK ){ |
| 144118 | 144230 | rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); |
| 144119 | 144231 | } |
| 144120 | 144232 | if( rc==SQLITE_OK ){ |
| @@ -151778,10 +151890,12 @@ | ||
| 151778 | 151890 | RtreeCell cell; /* New cell to insert if nData>1 */ |
| 151779 | 151891 | int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ |
| 151780 | 151892 | |
| 151781 | 151893 | rtreeReference(pRtree); |
| 151782 | 151894 | assert(nData>=1); |
| 151895 | + | |
| 151896 | + cell.iRowid = 0; /* Used only to suppress a compiler warning */ | |
| 151783 | 151897 | |
| 151784 | 151898 | /* Constraint handling. A write operation on an r-tree table may return |
| 151785 | 151899 | ** SQLITE_CONSTRAINT for two reasons: |
| 151786 | 151900 | ** |
| 151787 | 151901 | ** 1. A duplicate rowid value, or |
| 151788 | 151902 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -41,10 +41,57 @@ | |
| 41 | ** |
| 42 | */ |
| 43 | #ifndef _SQLITEINT_H_ |
| 44 | #define _SQLITEINT_H_ |
| 45 | |
| 46 | /* |
| 47 | ** These #defines should enable >2GB file support on POSIX if the |
| 48 | ** underlying operating system supports it. If the OS lacks |
| 49 | ** large file support, or if the OS is windows, these should be no-ops. |
| 50 | ** |
| @@ -231,11 +278,11 @@ | |
| 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | */ |
| 234 | #define SQLITE_VERSION "3.8.8" |
| 235 | #define SQLITE_VERSION_NUMBER 3008008 |
| 236 | #define SQLITE_SOURCE_ID "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6" |
| 237 | |
| 238 | /* |
| 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | ** |
| @@ -7613,10 +7660,14 @@ | |
| 7613 | ** |
| 7614 | ** The following constants can be used for the T parameter to the |
| 7615 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7616 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7617 | ** |
| 7618 | ** <dl> |
| 7619 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7620 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7621 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7622 | ** |
| @@ -7658,11 +7709,18 @@ | |
| 7658 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 7659 | |
| 7660 | /* |
| 7661 | ** CAPI3REF: Prepared Statement Scan Status |
| 7662 | ** |
| 7663 | ** Return status data for a single loop within query pStmt. |
| 7664 | ** |
| 7665 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7666 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7667 | ** of this interface is undefined. |
| 7668 | ** ^The requested measurement is written into a variable pointed to by |
| @@ -7676,13 +7734,10 @@ | |
| 7676 | ** ^Statistics might not be available for all loops in all statements. ^In cases |
| 7677 | ** where there exist loops with no available statistics, this function behaves |
| 7678 | ** as if the loop did not exist - it returns non-zero and leave the variable |
| 7679 | ** that pOut points to unchanged. |
| 7680 | ** |
| 7681 | ** This API is only available if the library is built with pre-processor |
| 7682 | ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. |
| 7683 | ** |
| 7684 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 7685 | */ |
| 7686 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( |
| 7687 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ |
| 7688 | int idx, /* Index of loop to report on */ |
| @@ -12054,11 +12109,11 @@ | |
| 12054 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 12055 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 12056 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 12057 | #define SF_Compound 0x0040 /* Part of a compound query */ |
| 12058 | #define SF_Values 0x0080 /* Synthesized from VALUES clause */ |
| 12059 | /* 0x0100 NOT USED */ |
| 12060 | #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ |
| 12061 | #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ |
| 12062 | #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ |
| 12063 | #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ |
| 12064 | |
| @@ -12682,11 +12737,11 @@ | |
| 12682 | ** FTS4 is really an extension for FTS3. It is enabled using the |
| 12683 | ** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call |
| 12684 | ** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. |
| 12685 | */ |
| 12686 | #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) |
| 12687 | # define SQLITE_ENABLE_FTS3 |
| 12688 | #endif |
| 12689 | |
| 12690 | /* |
| 12691 | ** The ctype.h header is needed for non-ASCII systems. It is also |
| 12692 | ** needed by FTS3 when FTS3 is included in the amalgamation. |
| @@ -13824,355 +13879,355 @@ | |
| 13824 | /* These macros are provided to "stringify" the value of the define |
| 13825 | ** for those options in which the value is meaningful. */ |
| 13826 | #define CTIMEOPT_VAL_(opt) #opt |
| 13827 | #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) |
| 13828 | |
| 13829 | #ifdef SQLITE_32BIT_ROWID |
| 13830 | "32BIT_ROWID", |
| 13831 | #endif |
| 13832 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC |
| 13833 | "4_BYTE_ALIGNED_MALLOC", |
| 13834 | #endif |
| 13835 | #ifdef SQLITE_CASE_SENSITIVE_LIKE |
| 13836 | "CASE_SENSITIVE_LIKE", |
| 13837 | #endif |
| 13838 | #ifdef SQLITE_CHECK_PAGES |
| 13839 | "CHECK_PAGES", |
| 13840 | #endif |
| 13841 | #ifdef SQLITE_COVERAGE_TEST |
| 13842 | "COVERAGE_TEST", |
| 13843 | #endif |
| 13844 | #ifdef SQLITE_DEBUG |
| 13845 | "DEBUG", |
| 13846 | #endif |
| 13847 | #ifdef SQLITE_DEFAULT_LOCKING_MODE |
| 13848 | "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), |
| 13849 | #endif |
| 13850 | #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) |
| 13851 | "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), |
| 13852 | #endif |
| 13853 | #ifdef SQLITE_DISABLE_DIRSYNC |
| 13854 | "DISABLE_DIRSYNC", |
| 13855 | #endif |
| 13856 | #ifdef SQLITE_DISABLE_LFS |
| 13857 | "DISABLE_LFS", |
| 13858 | #endif |
| 13859 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 13860 | "ENABLE_API_ARMOR", |
| 13861 | #endif |
| 13862 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 13863 | "ENABLE_ATOMIC_WRITE", |
| 13864 | #endif |
| 13865 | #ifdef SQLITE_ENABLE_CEROD |
| 13866 | "ENABLE_CEROD", |
| 13867 | #endif |
| 13868 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
| 13869 | "ENABLE_COLUMN_METADATA", |
| 13870 | #endif |
| 13871 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 13872 | "ENABLE_EXPENSIVE_ASSERT", |
| 13873 | #endif |
| 13874 | #ifdef SQLITE_ENABLE_FTS1 |
| 13875 | "ENABLE_FTS1", |
| 13876 | #endif |
| 13877 | #ifdef SQLITE_ENABLE_FTS2 |
| 13878 | "ENABLE_FTS2", |
| 13879 | #endif |
| 13880 | #ifdef SQLITE_ENABLE_FTS3 |
| 13881 | "ENABLE_FTS3", |
| 13882 | #endif |
| 13883 | #ifdef SQLITE_ENABLE_FTS3_PARENTHESIS |
| 13884 | "ENABLE_FTS3_PARENTHESIS", |
| 13885 | #endif |
| 13886 | #ifdef SQLITE_ENABLE_FTS4 |
| 13887 | "ENABLE_FTS4", |
| 13888 | #endif |
| 13889 | #ifdef SQLITE_ENABLE_ICU |
| 13890 | "ENABLE_ICU", |
| 13891 | #endif |
| 13892 | #ifdef SQLITE_ENABLE_IOTRACE |
| 13893 | "ENABLE_IOTRACE", |
| 13894 | #endif |
| 13895 | #ifdef SQLITE_ENABLE_LOAD_EXTENSION |
| 13896 | "ENABLE_LOAD_EXTENSION", |
| 13897 | #endif |
| 13898 | #ifdef SQLITE_ENABLE_LOCKING_STYLE |
| 13899 | "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), |
| 13900 | #endif |
| 13901 | #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT |
| 13902 | "ENABLE_MEMORY_MANAGEMENT", |
| 13903 | #endif |
| 13904 | #ifdef SQLITE_ENABLE_MEMSYS3 |
| 13905 | "ENABLE_MEMSYS3", |
| 13906 | #endif |
| 13907 | #ifdef SQLITE_ENABLE_MEMSYS5 |
| 13908 | "ENABLE_MEMSYS5", |
| 13909 | #endif |
| 13910 | #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK |
| 13911 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 13912 | #endif |
| 13913 | #ifdef SQLITE_ENABLE_RTREE |
| 13914 | "ENABLE_RTREE", |
| 13915 | #endif |
| 13916 | #if defined(SQLITE_ENABLE_STAT4) |
| 13917 | "ENABLE_STAT4", |
| 13918 | #elif defined(SQLITE_ENABLE_STAT3) |
| 13919 | "ENABLE_STAT3", |
| 13920 | #endif |
| 13921 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 13922 | "ENABLE_UNLOCK_NOTIFY", |
| 13923 | #endif |
| 13924 | #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT |
| 13925 | "ENABLE_UPDATE_DELETE_LIMIT", |
| 13926 | #endif |
| 13927 | #ifdef SQLITE_HAS_CODEC |
| 13928 | "HAS_CODEC", |
| 13929 | #endif |
| 13930 | #ifdef SQLITE_HAVE_ISNAN |
| 13931 | "HAVE_ISNAN", |
| 13932 | #endif |
| 13933 | #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX |
| 13934 | "HOMEGROWN_RECURSIVE_MUTEX", |
| 13935 | #endif |
| 13936 | #ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS |
| 13937 | "IGNORE_AFP_LOCK_ERRORS", |
| 13938 | #endif |
| 13939 | #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS |
| 13940 | "IGNORE_FLOCK_LOCK_ERRORS", |
| 13941 | #endif |
| 13942 | #ifdef SQLITE_INT64_TYPE |
| 13943 | "INT64_TYPE", |
| 13944 | #endif |
| 13945 | #ifdef SQLITE_LOCK_TRACE |
| 13946 | "LOCK_TRACE", |
| 13947 | #endif |
| 13948 | #if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc) |
| 13949 | "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), |
| 13950 | #endif |
| 13951 | #ifdef SQLITE_MAX_SCHEMA_RETRY |
| 13952 | "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), |
| 13953 | #endif |
| 13954 | #ifdef SQLITE_MEMDEBUG |
| 13955 | "MEMDEBUG", |
| 13956 | #endif |
| 13957 | #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
| 13958 | "MIXED_ENDIAN_64BIT_FLOAT", |
| 13959 | #endif |
| 13960 | #ifdef SQLITE_NO_SYNC |
| 13961 | "NO_SYNC", |
| 13962 | #endif |
| 13963 | #ifdef SQLITE_OMIT_ALTERTABLE |
| 13964 | "OMIT_ALTERTABLE", |
| 13965 | #endif |
| 13966 | #ifdef SQLITE_OMIT_ANALYZE |
| 13967 | "OMIT_ANALYZE", |
| 13968 | #endif |
| 13969 | #ifdef SQLITE_OMIT_ATTACH |
| 13970 | "OMIT_ATTACH", |
| 13971 | #endif |
| 13972 | #ifdef SQLITE_OMIT_AUTHORIZATION |
| 13973 | "OMIT_AUTHORIZATION", |
| 13974 | #endif |
| 13975 | #ifdef SQLITE_OMIT_AUTOINCREMENT |
| 13976 | "OMIT_AUTOINCREMENT", |
| 13977 | #endif |
| 13978 | #ifdef SQLITE_OMIT_AUTOINIT |
| 13979 | "OMIT_AUTOINIT", |
| 13980 | #endif |
| 13981 | #ifdef SQLITE_OMIT_AUTOMATIC_INDEX |
| 13982 | "OMIT_AUTOMATIC_INDEX", |
| 13983 | #endif |
| 13984 | #ifdef SQLITE_OMIT_AUTORESET |
| 13985 | "OMIT_AUTORESET", |
| 13986 | #endif |
| 13987 | #ifdef SQLITE_OMIT_AUTOVACUUM |
| 13988 | "OMIT_AUTOVACUUM", |
| 13989 | #endif |
| 13990 | #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION |
| 13991 | "OMIT_BETWEEN_OPTIMIZATION", |
| 13992 | #endif |
| 13993 | #ifdef SQLITE_OMIT_BLOB_LITERAL |
| 13994 | "OMIT_BLOB_LITERAL", |
| 13995 | #endif |
| 13996 | #ifdef SQLITE_OMIT_BTREECOUNT |
| 13997 | "OMIT_BTREECOUNT", |
| 13998 | #endif |
| 13999 | #ifdef SQLITE_OMIT_BUILTIN_TEST |
| 14000 | "OMIT_BUILTIN_TEST", |
| 14001 | #endif |
| 14002 | #ifdef SQLITE_OMIT_CAST |
| 14003 | "OMIT_CAST", |
| 14004 | #endif |
| 14005 | #ifdef SQLITE_OMIT_CHECK |
| 14006 | "OMIT_CHECK", |
| 14007 | #endif |
| 14008 | #ifdef SQLITE_OMIT_COMPLETE |
| 14009 | "OMIT_COMPLETE", |
| 14010 | #endif |
| 14011 | #ifdef SQLITE_OMIT_COMPOUND_SELECT |
| 14012 | "OMIT_COMPOUND_SELECT", |
| 14013 | #endif |
| 14014 | #ifdef SQLITE_OMIT_CTE |
| 14015 | "OMIT_CTE", |
| 14016 | #endif |
| 14017 | #ifdef SQLITE_OMIT_DATETIME_FUNCS |
| 14018 | "OMIT_DATETIME_FUNCS", |
| 14019 | #endif |
| 14020 | #ifdef SQLITE_OMIT_DECLTYPE |
| 14021 | "OMIT_DECLTYPE", |
| 14022 | #endif |
| 14023 | #ifdef SQLITE_OMIT_DEPRECATED |
| 14024 | "OMIT_DEPRECATED", |
| 14025 | #endif |
| 14026 | #ifdef SQLITE_OMIT_DISKIO |
| 14027 | "OMIT_DISKIO", |
| 14028 | #endif |
| 14029 | #ifdef SQLITE_OMIT_EXPLAIN |
| 14030 | "OMIT_EXPLAIN", |
| 14031 | #endif |
| 14032 | #ifdef SQLITE_OMIT_FLAG_PRAGMAS |
| 14033 | "OMIT_FLAG_PRAGMAS", |
| 14034 | #endif |
| 14035 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 14036 | "OMIT_FLOATING_POINT", |
| 14037 | #endif |
| 14038 | #ifdef SQLITE_OMIT_FOREIGN_KEY |
| 14039 | "OMIT_FOREIGN_KEY", |
| 14040 | #endif |
| 14041 | #ifdef SQLITE_OMIT_GET_TABLE |
| 14042 | "OMIT_GET_TABLE", |
| 14043 | #endif |
| 14044 | #ifdef SQLITE_OMIT_INCRBLOB |
| 14045 | "OMIT_INCRBLOB", |
| 14046 | #endif |
| 14047 | #ifdef SQLITE_OMIT_INTEGRITY_CHECK |
| 14048 | "OMIT_INTEGRITY_CHECK", |
| 14049 | #endif |
| 14050 | #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION |
| 14051 | "OMIT_LIKE_OPTIMIZATION", |
| 14052 | #endif |
| 14053 | #ifdef SQLITE_OMIT_LOAD_EXTENSION |
| 14054 | "OMIT_LOAD_EXTENSION", |
| 14055 | #endif |
| 14056 | #ifdef SQLITE_OMIT_LOCALTIME |
| 14057 | "OMIT_LOCALTIME", |
| 14058 | #endif |
| 14059 | #ifdef SQLITE_OMIT_LOOKASIDE |
| 14060 | "OMIT_LOOKASIDE", |
| 14061 | #endif |
| 14062 | #ifdef SQLITE_OMIT_MEMORYDB |
| 14063 | "OMIT_MEMORYDB", |
| 14064 | #endif |
| 14065 | #ifdef SQLITE_OMIT_OR_OPTIMIZATION |
| 14066 | "OMIT_OR_OPTIMIZATION", |
| 14067 | #endif |
| 14068 | #ifdef SQLITE_OMIT_PAGER_PRAGMAS |
| 14069 | "OMIT_PAGER_PRAGMAS", |
| 14070 | #endif |
| 14071 | #ifdef SQLITE_OMIT_PRAGMA |
| 14072 | "OMIT_PRAGMA", |
| 14073 | #endif |
| 14074 | #ifdef SQLITE_OMIT_PROGRESS_CALLBACK |
| 14075 | "OMIT_PROGRESS_CALLBACK", |
| 14076 | #endif |
| 14077 | #ifdef SQLITE_OMIT_QUICKBALANCE |
| 14078 | "OMIT_QUICKBALANCE", |
| 14079 | #endif |
| 14080 | #ifdef SQLITE_OMIT_REINDEX |
| 14081 | "OMIT_REINDEX", |
| 14082 | #endif |
| 14083 | #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS |
| 14084 | "OMIT_SCHEMA_PRAGMAS", |
| 14085 | #endif |
| 14086 | #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS |
| 14087 | "OMIT_SCHEMA_VERSION_PRAGMAS", |
| 14088 | #endif |
| 14089 | #ifdef SQLITE_OMIT_SHARED_CACHE |
| 14090 | "OMIT_SHARED_CACHE", |
| 14091 | #endif |
| 14092 | #ifdef SQLITE_OMIT_SUBQUERY |
| 14093 | "OMIT_SUBQUERY", |
| 14094 | #endif |
| 14095 | #ifdef SQLITE_OMIT_TCL_VARIABLE |
| 14096 | "OMIT_TCL_VARIABLE", |
| 14097 | #endif |
| 14098 | #ifdef SQLITE_OMIT_TEMPDB |
| 14099 | "OMIT_TEMPDB", |
| 14100 | #endif |
| 14101 | #ifdef SQLITE_OMIT_TRACE |
| 14102 | "OMIT_TRACE", |
| 14103 | #endif |
| 14104 | #ifdef SQLITE_OMIT_TRIGGER |
| 14105 | "OMIT_TRIGGER", |
| 14106 | #endif |
| 14107 | #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION |
| 14108 | "OMIT_TRUNCATE_OPTIMIZATION", |
| 14109 | #endif |
| 14110 | #ifdef SQLITE_OMIT_UTF16 |
| 14111 | "OMIT_UTF16", |
| 14112 | #endif |
| 14113 | #ifdef SQLITE_OMIT_VACUUM |
| 14114 | "OMIT_VACUUM", |
| 14115 | #endif |
| 14116 | #ifdef SQLITE_OMIT_VIEW |
| 14117 | "OMIT_VIEW", |
| 14118 | #endif |
| 14119 | #ifdef SQLITE_OMIT_VIRTUALTABLE |
| 14120 | "OMIT_VIRTUALTABLE", |
| 14121 | #endif |
| 14122 | #ifdef SQLITE_OMIT_WAL |
| 14123 | "OMIT_WAL", |
| 14124 | #endif |
| 14125 | #ifdef SQLITE_OMIT_WSD |
| 14126 | "OMIT_WSD", |
| 14127 | #endif |
| 14128 | #ifdef SQLITE_OMIT_XFER_OPT |
| 14129 | "OMIT_XFER_OPT", |
| 14130 | #endif |
| 14131 | #ifdef SQLITE_PERFORMANCE_TRACE |
| 14132 | "PERFORMANCE_TRACE", |
| 14133 | #endif |
| 14134 | #ifdef SQLITE_PROXY_DEBUG |
| 14135 | "PROXY_DEBUG", |
| 14136 | #endif |
| 14137 | #ifdef SQLITE_RTREE_INT_ONLY |
| 14138 | "RTREE_INT_ONLY", |
| 14139 | #endif |
| 14140 | #ifdef SQLITE_SECURE_DELETE |
| 14141 | "SECURE_DELETE", |
| 14142 | #endif |
| 14143 | #ifdef SQLITE_SMALL_STACK |
| 14144 | "SMALL_STACK", |
| 14145 | #endif |
| 14146 | #ifdef SQLITE_SOUNDEX |
| 14147 | "SOUNDEX", |
| 14148 | #endif |
| 14149 | #ifdef SQLITE_SYSTEM_MALLOC |
| 14150 | "SYSTEM_MALLOC", |
| 14151 | #endif |
| 14152 | #ifdef SQLITE_TCL |
| 14153 | "TCL", |
| 14154 | #endif |
| 14155 | #if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) |
| 14156 | "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), |
| 14157 | #endif |
| 14158 | #ifdef SQLITE_TEST |
| 14159 | "TEST", |
| 14160 | #endif |
| 14161 | #if defined(SQLITE_THREADSAFE) |
| 14162 | "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), |
| 14163 | #endif |
| 14164 | #ifdef SQLITE_USE_ALLOCA |
| 14165 | "USE_ALLOCA", |
| 14166 | #endif |
| 14167 | #ifdef SQLITE_USER_AUTHENTICATION |
| 14168 | "USER_AUTHENTICATION", |
| 14169 | #endif |
| 14170 | #ifdef SQLITE_WIN32_MALLOC |
| 14171 | "WIN32_MALLOC", |
| 14172 | #endif |
| 14173 | #ifdef SQLITE_ZERO_MALLOC |
| 14174 | "ZERO_MALLOC" |
| 14175 | #endif |
| 14176 | }; |
| 14177 | |
| 14178 | /* |
| @@ -14183,11 +14238,11 @@ | |
| 14183 | ** is not required for a match. |
| 14184 | */ |
| 14185 | SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ |
| 14186 | int i, n; |
| 14187 | |
| 14188 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 14189 | if( zOptName==0 ){ |
| 14190 | (void)SQLITE_MISUSE_BKPT; |
| 14191 | return 0; |
| 14192 | } |
| 14193 | #endif |
| @@ -15411,12 +15466,13 @@ | |
| 15411 | ** |
| 15412 | ** If the user has not indicated to use localtime_r() or localtime_s() |
| 15413 | ** already, check for an MSVC build environment that provides |
| 15414 | ** localtime_s(). |
| 15415 | */ |
| 15416 | #if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ |
| 15417 | defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) |
| 15418 | #define HAVE_LOCALTIME_S 1 |
| 15419 | #endif |
| 15420 | |
| 15421 | #ifndef SQLITE_OMIT_LOCALTIME |
| 15422 | /* |
| @@ -15432,12 +15488,11 @@ | |
| 15432 | ** library function localtime_r() is used to assist in the calculation of |
| 15433 | ** local time. |
| 15434 | */ |
| 15435 | static int osLocaltime(time_t *t, struct tm *pTm){ |
| 15436 | int rc; |
| 15437 | #if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ |
| 15438 | && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) |
| 15439 | struct tm *pX; |
| 15440 | #if SQLITE_THREADSAFE>0 |
| 15441 | sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
| 15442 | #endif |
| 15443 | sqlite3_mutex_enter(mutex); |
| @@ -15450,11 +15505,11 @@ | |
| 15450 | rc = pX==0; |
| 15451 | #else |
| 15452 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 15453 | if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; |
| 15454 | #endif |
| 15455 | #if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R |
| 15456 | rc = localtime_r(t, pTm)==0; |
| 15457 | #else |
| 15458 | rc = localtime_s(pTm, t); |
| 15459 | #endif /* HAVE_LOCALTIME_R */ |
| 15460 | #endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ |
| @@ -15894,12 +15949,14 @@ | |
| 15894 | DateTime x; |
| 15895 | u64 n; |
| 15896 | size_t i,j; |
| 15897 | char *z; |
| 15898 | sqlite3 *db; |
| 15899 | const char *zFmt = (const char*)sqlite3_value_text(argv[0]); |
| 15900 | char zBuf[100]; |
| 15901 | if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; |
| 15902 | db = sqlite3_context_db_handle(context); |
| 15903 | for(i=0, n=1; zFmt[i]; i++, n++){ |
| 15904 | if( zFmt[i]=='%' ){ |
| 15905 | switch( zFmt[i+1] ){ |
| @@ -16089,11 +16146,11 @@ | |
| 16089 | UNUSED_PARAMETER(argv); |
| 16090 | |
| 16091 | iT = sqlite3StmtCurrentTime(context); |
| 16092 | if( iT<=0 ) return; |
| 16093 | t = iT/1000 - 10000*(sqlite3_int64)21086676; |
| 16094 | #ifdef HAVE_GMTIME_R |
| 16095 | pTm = gmtime_r(&t, &sNow); |
| 16096 | #else |
| 16097 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
| 16098 | pTm = gmtime(&t); |
| 16099 | if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); |
| @@ -16763,13 +16820,13 @@ | |
| 16763 | |
| 16764 | /* |
| 16765 | ** The malloc.h header file is needed for malloc_usable_size() function |
| 16766 | ** on some systems (e.g. Linux). |
| 16767 | */ |
| 16768 | #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE) |
| 16769 | # define SQLITE_USE_MALLOC_H |
| 16770 | # define SQLITE_USE_MALLOC_USABLE_SIZE |
| 16771 | /* |
| 16772 | ** The MSVCRT has malloc_usable_size(), but it is called _msize(). The |
| 16773 | ** use of _msize() is automatic, but can be disabled by compiling with |
| 16774 | ** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires |
| 16775 | ** the malloc.h header file. |
| @@ -21004,21 +21061,10 @@ | |
| 21004 | ** This file contains code for a set of "printf"-like routines. These |
| 21005 | ** routines format strings much like the printf() from the standard C |
| 21006 | ** library, though the implementation here has enhancements to support |
| 21007 | ** SQLlite. |
| 21008 | */ |
| 21009 | |
| 21010 | /* |
| 21011 | ** If the strchrnul() library function is available, then set |
| 21012 | ** HAVE_STRCHRNUL. If that routine is not available, this module |
| 21013 | ** will supply its own. The built-in version is slower than |
| 21014 | ** the glibc version so the glibc version is definitely preferred. |
| 21015 | */ |
| 21016 | #if !defined(HAVE_STRCHRNUL) |
| 21017 | # define HAVE_STRCHRNUL 0 |
| 21018 | #endif |
| 21019 | |
| 21020 | |
| 21021 | /* |
| 21022 | ** Conversion types fall into various categories as defined by the |
| 21023 | ** following enumeration. |
| 21024 | */ |
| @@ -22313,10 +22359,12 @@ | |
| 22313 | ** single threaded systems. Nothing in SQLite requires multiple threads. |
| 22314 | ** This interface exists so that applications that want to take advantage |
| 22315 | ** of multiple cores can do so, while also allowing applications to stay |
| 22316 | ** single-threaded if desired. |
| 22317 | */ |
| 22318 | |
| 22319 | #if SQLITE_MAX_WORKER_THREADS>0 |
| 22320 | |
| 22321 | /********************************* Unix Pthreads ****************************/ |
| 22322 | #if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 |
| @@ -23099,11 +23147,11 @@ | |
| 23099 | ** This file contains functions for allocating memory, comparing |
| 23100 | ** strings, and stuff like that. |
| 23101 | ** |
| 23102 | */ |
| 23103 | /* #include <stdarg.h> */ |
| 23104 | #ifdef SQLITE_HAVE_ISNAN |
| 23105 | # include <math.h> |
| 23106 | #endif |
| 23107 | |
| 23108 | /* |
| 23109 | ** Routine needed to support the testcase() macro. |
| @@ -23140,11 +23188,11 @@ | |
| 23140 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
| 23141 | ** Otherwise, we have our own implementation that works on most systems. |
| 23142 | */ |
| 23143 | SQLITE_PRIVATE int sqlite3IsNaN(double x){ |
| 23144 | int rc; /* The value return */ |
| 23145 | #if !defined(SQLITE_HAVE_ISNAN) |
| 23146 | /* |
| 23147 | ** Systems that support the isnan() library function should probably |
| 23148 | ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have |
| 23149 | ** found that many systems do not have a working isnan() function so |
| 23150 | ** this implementation is provided as an alternative. |
| @@ -23170,13 +23218,13 @@ | |
| 23170 | # error SQLite will not work correctly with the -ffast-math option of GCC. |
| 23171 | #endif |
| 23172 | volatile double y = x; |
| 23173 | volatile double z = y; |
| 23174 | rc = (y!=z); |
| 23175 | #else /* if defined(SQLITE_HAVE_ISNAN) */ |
| 23176 | rc = isnan(x); |
| 23177 | #endif /* SQLITE_HAVE_ISNAN */ |
| 23178 | testcase( rc ); |
| 23179 | return rc; |
| 23180 | } |
| 23181 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 23182 | |
| @@ -28493,13 +28541,13 @@ | |
| 28493 | |
| 28494 | /* |
| 28495 | ** We do not trust systems to provide a working fdatasync(). Some do. |
| 28496 | ** Others do no. To be safe, we will stick with the (slightly slower) |
| 28497 | ** fsync(). If you know that your system does support fdatasync() correctly, |
| 28498 | ** then simply compile with -Dfdatasync=fdatasync |
| 28499 | */ |
| 28500 | #if !defined(fdatasync) |
| 28501 | # define fdatasync fsync |
| 28502 | #endif |
| 28503 | |
| 28504 | /* |
| 28505 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| @@ -28824,22 +28872,23 @@ | |
| 28824 | ** at offset (nSize-1), to set the size of the file correctly. |
| 28825 | ** This is a similar technique to that used by glibc on systems |
| 28826 | ** that do not have a real fallocate() call. |
| 28827 | */ |
| 28828 | int nBlk = buf.st_blksize; /* File-system block size */ |
| 28829 | i64 iWrite; /* Next offset to write to */ |
| 28830 | |
| 28831 | iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; |
| 28832 | assert( iWrite>=buf.st_size ); |
| 28833 | assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) ); |
| 28834 | assert( ((iWrite+1)%nBlk)==0 ); |
| 28835 | for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){ |
| 28836 | int nWrite = seekAndWrite(pFile, iWrite, "", 1); |
| 28837 | if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
| 28838 | } |
| 28839 | if( nSize%nBlk ){ |
| 28840 | int nWrite = seekAndWrite(pFile, nSize-1, "", 1); |
| 28841 | if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
| 28842 | } |
| 28843 | #endif |
| 28844 | } |
| 28845 | } |
| @@ -38849,22 +38898,10 @@ | |
| 38849 | void *pStress; /* Argument to xStress */ |
| 38850 | sqlite3_pcache *pCache; /* Pluggable cache module */ |
| 38851 | PgHdr *pPage1; /* Reference to page 1 */ |
| 38852 | }; |
| 38853 | |
| 38854 | /* |
| 38855 | ** Some of the assert() macros in this code are too expensive to run |
| 38856 | ** even during normal debugging. Use them only rarely on long-running |
| 38857 | ** tests. Enable the expensive asserts using the |
| 38858 | ** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option. |
| 38859 | */ |
| 38860 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 38861 | # define expensive_assert(X) assert(X) |
| 38862 | #else |
| 38863 | # define expensive_assert(X) |
| 38864 | #endif |
| 38865 | |
| 38866 | /********************************** Linked List Management ********************/ |
| 38867 | |
| 38868 | /* Allowed values for second argument to pcacheManageDirtyList() */ |
| 38869 | #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ |
| 38870 | #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ |
| @@ -73905,12 +73942,12 @@ | |
| 73905 | pIdxKey->default_rc = 0; |
| 73906 | if( pOp->opcode==OP_NoConflict ){ |
| 73907 | /* For the OP_NoConflict opcode, take the jump if any of the |
| 73908 | ** input fields are NULL, since any key with a NULL will not |
| 73909 | ** conflict */ |
| 73910 | for(ii=0; ii<r.nField; ii++){ |
| 73911 | if( r.aMem[ii].flags & MEM_Null ){ |
| 73912 | pc = pOp->p2 - 1; VdbeBranchTaken(1,2); |
| 73913 | break; |
| 73914 | } |
| 73915 | } |
| 73916 | } |
| @@ -79464,10 +79501,11 @@ | |
| 79464 | rc = vdbePmaReaderNext(pSorter->pReader); |
| 79465 | *pbEof = (pSorter->pReader->pFd==0); |
| 79466 | }else |
| 79467 | #endif |
| 79468 | /*if( !pSorter->bUseThreads )*/ { |
| 79469 | assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); |
| 79470 | rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); |
| 79471 | } |
| 79472 | }else{ |
| 79473 | SorterRecord *pFree = pSorter->list.pList; |
| @@ -82230,11 +82268,11 @@ | |
| 82230 | Expr *pLeft, /* Left operand */ |
| 82231 | Expr *pRight, /* Right operand */ |
| 82232 | const Token *pToken /* Argument token */ |
| 82233 | ){ |
| 82234 | Expr *p; |
| 82235 | if( op==TK_AND && pLeft && pRight ){ |
| 82236 | /* Take advantage of short-circuit false optimization for AND */ |
| 82237 | p = sqlite3ExprAnd(pParse->db, pLeft, pRight); |
| 82238 | }else{ |
| 82239 | p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); |
| 82240 | sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); |
| @@ -85784,14 +85822,15 @@ | |
| 85784 | ** NEVER() will need to be removed. */ |
| 85785 | if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ |
| 85786 | int i; |
| 85787 | struct SrcCount *p = pWalker->u.pSrcCount; |
| 85788 | SrcList *pSrc = p->pSrc; |
| 85789 | for(i=0; i<pSrc->nSrc; i++){ |
| 85790 | if( pExpr->iTable==pSrc->a[i].iCursor ) break; |
| 85791 | } |
| 85792 | if( i<pSrc->nSrc ){ |
| 85793 | p->nThis++; |
| 85794 | }else{ |
| 85795 | p->nOther++; |
| 85796 | } |
| 85797 | } |
| @@ -94664,12 +94703,12 @@ | |
| 94664 | const char *zDb; /* Name of database holding pTab */ |
| 94665 | int i; /* Loop counter */ |
| 94666 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| 94667 | Index *pIdx; /* For looping over indices of the table */ |
| 94668 | int iTabCur; /* Cursor number for the table */ |
| 94669 | int iDataCur; /* VDBE cursor for the canonical data source */ |
| 94670 | int iIdxCur; /* Cursor number of the first index */ |
| 94671 | int nIdx; /* Number of indices */ |
| 94672 | sqlite3 *db; /* Main database structure */ |
| 94673 | AuthContext sContext; /* Authorization context */ |
| 94674 | NameContext sNC; /* Name context to resolve expressions in */ |
| 94675 | int iDb; /* Database number */ |
| @@ -102658,11 +102697,11 @@ | |
| 102658 | char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ |
| 102659 | const char *zDb = 0; /* The database name */ |
| 102660 | Token *pId; /* Pointer to <id> token */ |
| 102661 | char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ |
| 102662 | int iDb; /* Database index for <database> */ |
| 102663 | int lwr, upr, mid; /* Binary search bounds */ |
| 102664 | int rc; /* return value form SQLITE_FCNTL_PRAGMA */ |
| 102665 | sqlite3 *db = pParse->db; /* The database connection */ |
| 102666 | Db *pDb; /* The specific database being pragmaed */ |
| 102667 | Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ |
| 102668 | |
| @@ -105271,24 +105310,29 @@ | |
| 105271 | u8 sortFlags; /* Zero or more SORTFLAG_* bits */ |
| 105272 | }; |
| 105273 | #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ |
| 105274 | |
| 105275 | /* |
| 105276 | ** Delete all the content of a Select structure but do not deallocate |
| 105277 | ** the select structure itself. |
| 105278 | */ |
| 105279 | static void clearSelect(sqlite3 *db, Select *p){ |
| 105280 | sqlite3ExprListDelete(db, p->pEList); |
| 105281 | sqlite3SrcListDelete(db, p->pSrc); |
| 105282 | sqlite3ExprDelete(db, p->pWhere); |
| 105283 | sqlite3ExprListDelete(db, p->pGroupBy); |
| 105284 | sqlite3ExprDelete(db, p->pHaving); |
| 105285 | sqlite3ExprListDelete(db, p->pOrderBy); |
| 105286 | sqlite3SelectDelete(db, p->pPrior); |
| 105287 | sqlite3ExprDelete(db, p->pLimit); |
| 105288 | sqlite3ExprDelete(db, p->pOffset); |
| 105289 | sqlite3WithDelete(db, p->pWith); |
| 105290 | } |
| 105291 | |
| 105292 | /* |
| 105293 | ** Initialize a SelectDest structure. |
| 105294 | */ |
| @@ -105343,12 +105387,11 @@ | |
| 105343 | pNew->pOffset = pOffset; |
| 105344 | assert( pOffset==0 || pLimit!=0 ); |
| 105345 | pNew->addrOpenEphm[0] = -1; |
| 105346 | pNew->addrOpenEphm[1] = -1; |
| 105347 | if( db->mallocFailed ) { |
| 105348 | clearSelect(db, pNew); |
| 105349 | if( pNew!=&standin ) sqlite3DbFree(db, pNew); |
| 105350 | pNew = 0; |
| 105351 | }else{ |
| 105352 | assert( pNew->pSrc!=0 || pParse->nErr>0 ); |
| 105353 | } |
| 105354 | assert( pNew!=&standin ); |
| @@ -105369,14 +105412,11 @@ | |
| 105369 | |
| 105370 | /* |
| 105371 | ** Delete the given Select structure and all of its substructures. |
| 105372 | */ |
| 105373 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ |
| 105374 | if( p ){ |
| 105375 | clearSelect(db, p); |
| 105376 | sqlite3DbFree(db, p); |
| 105377 | } |
| 105378 | } |
| 105379 | |
| 105380 | /* |
| 105381 | ** Return a pointer to the right-most SELECT statement in a compound. |
| 105382 | */ |
| @@ -107288,10 +107328,70 @@ | |
| 107288 | Parse *pParse, /* Parsing context */ |
| 107289 | Select *p, /* The right-most of SELECTs to be coded */ |
| 107290 | SelectDest *pDest /* What to do with query results */ |
| 107291 | ); |
| 107292 | |
| 107293 | |
| 107294 | /* |
| 107295 | ** This routine is called to process a compound query form from |
| 107296 | ** two or more separate queries using UNION, UNION ALL, EXCEPT, or |
| 107297 | ** INTERSECT |
| @@ -107368,22 +107468,24 @@ | |
| 107368 | assert( p->pEList ); |
| 107369 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); |
| 107370 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 107371 | dest.eDest = SRT_Table; |
| 107372 | } |
| 107373 | |
| 107374 | /* Make sure all SELECTs in the statement have the same number of elements |
| 107375 | ** in their result sets. |
| 107376 | */ |
| 107377 | assert( p->pEList && pPrior->pEList ); |
| 107378 | if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ |
| 107379 | if( p->selFlags & SF_Values ){ |
| 107380 | sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); |
| 107381 | }else{ |
| 107382 | sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" |
| 107383 | " do not have the same number of result columns", selectOpName(p->op)); |
| 107384 | } |
| 107385 | rc = 1; |
| 107386 | goto multi_select_end; |
| 107387 | } |
| 107388 | |
| 107389 | #ifndef SQLITE_OMIT_CTE |
| @@ -109265,11 +109367,13 @@ | |
| 109265 | if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ |
| 109266 | return WRC_Prune; |
| 109267 | } |
| 109268 | pTabList = p->pSrc; |
| 109269 | pEList = p->pEList; |
| 109270 | sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); |
| 109271 | |
| 109272 | /* Make sure cursor numbers have been assigned to all entries in |
| 109273 | ** the FROM clause of the SELECT statement. |
| 109274 | */ |
| 109275 | sqlite3SrcListAssignCursors(pParse, pTabList); |
| @@ -109556,11 +109660,13 @@ | |
| 109556 | if( pParse->hasCompound ){ |
| 109557 | w.xSelectCallback = convertCompoundSelectToSubquery; |
| 109558 | sqlite3WalkSelect(&w, pSelect); |
| 109559 | } |
| 109560 | w.xSelectCallback = selectExpander; |
| 109561 | w.xSelectCallback2 = selectPopWith; |
| 109562 | sqlite3WalkSelect(&w, pSelect); |
| 109563 | } |
| 109564 | |
| 109565 | |
| 109566 | #ifndef SQLITE_OMIT_SUBQUERY |
| @@ -123884,17 +123990,23 @@ | |
| 123884 | Select *p = yymsp[0].minor.yy3, *pNext, *pLoop; |
| 123885 | if( p ){ |
| 123886 | int cnt = 0, mxSelect; |
| 123887 | p->pWith = yymsp[-1].minor.yy59; |
| 123888 | if( p->pPrior ){ |
| 123889 | pNext = 0; |
| 123890 | for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ |
| 123891 | pLoop->pNext = pNext; |
| 123892 | pLoop->selFlags |= SF_Compound; |
| 123893 | } |
| 123894 | mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT]; |
| 123895 | if( mxSelect && cnt>mxSelect ){ |
| 123896 | sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); |
| 123897 | } |
| 123898 | } |
| 123899 | }else{ |
| 123900 | sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59); |
| @@ -127600,11 +127712,11 @@ | |
| 127600 | */ |
| 127601 | static int sqliteDefaultBusyCallback( |
| 127602 | void *ptr, /* Database connection */ |
| 127603 | int count /* Number of times table has been busy */ |
| 127604 | ){ |
| 127605 | #if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP) |
| 127606 | static const u8 delays[] = |
| 127607 | { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; |
| 127608 | static const u8 totals[] = |
| 127609 | { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; |
| 127610 | # define NDELAY ArraySize(delays) |
| @@ -129390,11 +129502,11 @@ | |
| 129390 | ){ |
| 129391 | int rc; |
| 129392 | char *zErrMsg = 0; |
| 129393 | Table *pTab = 0; |
| 129394 | Column *pCol = 0; |
| 129395 | int iCol; |
| 129396 | |
| 129397 | char const *zDataType = 0; |
| 129398 | char const *zCollSeq = 0; |
| 129399 | int notnull = 0; |
| 129400 | int primarykey = 0; |
| @@ -133013,11 +133125,11 @@ | |
| 133013 | const char *zNode, /* Buffer containing segment interior node */ |
| 133014 | int nNode, /* Size of buffer at zNode */ |
| 133015 | sqlite3_int64 *piLeaf, /* Selected leaf node */ |
| 133016 | sqlite3_int64 *piLeaf2 /* Selected leaf node */ |
| 133017 | ){ |
| 133018 | int rc; /* Return code */ |
| 133019 | int iHeight; /* Height of this node in tree */ |
| 133020 | |
| 133021 | assert( piLeaf || piLeaf2 ); |
| 133022 | |
| 133023 | fts3GetVarint32(zNode, &iHeight); |
| @@ -133024,11 +133136,11 @@ | |
| 133024 | rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); |
| 133025 | assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); |
| 133026 | |
| 133027 | if( rc==SQLITE_OK && iHeight>1 ){ |
| 133028 | char *zBlob = 0; /* Blob read from %_segments table */ |
| 133029 | int nBlob; /* Size of zBlob in bytes */ |
| 133030 | |
| 133031 | if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ |
| 133032 | rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); |
| 133033 | if( rc==SQLITE_OK ){ |
| 133034 | rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); |
| @@ -134246,11 +134358,11 @@ | |
| 134246 | int idxNum, /* Strategy index */ |
| 134247 | const char *idxStr, /* Unused */ |
| 134248 | int nVal, /* Number of elements in apVal */ |
| 134249 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 134250 | ){ |
| 134251 | int rc; |
| 134252 | char *zSql; /* SQL statement used to access %_content */ |
| 134253 | int eSearch; |
| 134254 | Fts3Table *p = (Fts3Table *)pCursor->pVtab; |
| 134255 | Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; |
| 134256 | |
| @@ -140734,11 +140846,11 @@ | |
| 140734 | int argc, /* Number of elements in argv array */ |
| 140735 | const char * const *argv, /* xCreate/xConnect argument array */ |
| 140736 | sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
| 140737 | char **pzErr /* OUT: sqlite3_malloc'd error message */ |
| 140738 | ){ |
| 140739 | Fts3tokTable *pTab; |
| 140740 | const sqlite3_tokenizer_module *pMod = 0; |
| 140741 | sqlite3_tokenizer *pTok = 0; |
| 140742 | int rc; |
| 140743 | char **azDequote = 0; |
| 140744 | int nDequote; |
| @@ -144109,12 +144221,12 @@ | |
| 144109 | } |
| 144110 | rc = sqlite3_reset(pRange); |
| 144111 | |
| 144112 | if( bOk ){ |
| 144113 | int iIdx = 0; |
| 144114 | sqlite3_stmt *pUpdate1; |
| 144115 | sqlite3_stmt *pUpdate2; |
| 144116 | |
| 144117 | if( rc==SQLITE_OK ){ |
| 144118 | rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); |
| 144119 | } |
| 144120 | if( rc==SQLITE_OK ){ |
| @@ -151778,10 +151890,12 @@ | |
| 151778 | RtreeCell cell; /* New cell to insert if nData>1 */ |
| 151779 | int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ |
| 151780 | |
| 151781 | rtreeReference(pRtree); |
| 151782 | assert(nData>=1); |
| 151783 | |
| 151784 | /* Constraint handling. A write operation on an r-tree table may return |
| 151785 | ** SQLITE_CONSTRAINT for two reasons: |
| 151786 | ** |
| 151787 | ** 1. A duplicate rowid value, or |
| 151788 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -41,10 +41,57 @@ | |
| 41 | ** |
| 42 | */ |
| 43 | #ifndef _SQLITEINT_H_ |
| 44 | #define _SQLITEINT_H_ |
| 45 | |
| 46 | /* |
| 47 | ** Include the header file used to customize the compiler options for MSVC. |
| 48 | ** This should be done first so that it can successfully prevent spurious |
| 49 | ** compiler warnings due to subsequent content in this file and other files |
| 50 | ** that are included by this file. |
| 51 | */ |
| 52 | /************** Include msvc.h in the middle of sqliteInt.h ******************/ |
| 53 | /************** Begin file msvc.h ********************************************/ |
| 54 | /* |
| 55 | ** 2015 January 12 |
| 56 | ** |
| 57 | ** The author disclaims copyright to this source code. In place of |
| 58 | ** a legal notice, here is a blessing: |
| 59 | ** |
| 60 | ** May you do good and not evil. |
| 61 | ** May you find forgiveness for yourself and forgive others. |
| 62 | ** May you share freely, never taking more than you give. |
| 63 | ** |
| 64 | ****************************************************************************** |
| 65 | ** |
| 66 | ** This file contains code that is specific to MSVC. |
| 67 | */ |
| 68 | #ifndef _MSVC_H_ |
| 69 | #define _MSVC_H_ |
| 70 | |
| 71 | #if defined(_MSC_VER) |
| 72 | #pragma warning(disable : 4054) |
| 73 | #pragma warning(disable : 4055) |
| 74 | #pragma warning(disable : 4100) |
| 75 | #pragma warning(disable : 4127) |
| 76 | #pragma warning(disable : 4152) |
| 77 | #pragma warning(disable : 4189) |
| 78 | #pragma warning(disable : 4206) |
| 79 | #pragma warning(disable : 4210) |
| 80 | #pragma warning(disable : 4232) |
| 81 | #pragma warning(disable : 4244) |
| 82 | #pragma warning(disable : 4305) |
| 83 | #pragma warning(disable : 4306) |
| 84 | #pragma warning(disable : 4702) |
| 85 | #pragma warning(disable : 4706) |
| 86 | #endif /* defined(_MSC_VER) */ |
| 87 | |
| 88 | #endif /* _MSVC_H_ */ |
| 89 | |
| 90 | /************** End of msvc.h ************************************************/ |
| 91 | /************** Continuing where we left off in sqliteInt.h ******************/ |
| 92 | |
| 93 | /* |
| 94 | ** These #defines should enable >2GB file support on POSIX if the |
| 95 | ** underlying operating system supports it. If the OS lacks |
| 96 | ** large file support, or if the OS is windows, these should be no-ops. |
| 97 | ** |
| @@ -231,11 +278,11 @@ | |
| 278 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 279 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 280 | */ |
| 281 | #define SQLITE_VERSION "3.8.8" |
| 282 | #define SQLITE_VERSION_NUMBER 3008008 |
| 283 | #define SQLITE_SOURCE_ID "2015-01-12 21:43:00 e693e11d1b9265974c32bddba873ea30a4d0b708" |
| 284 | |
| 285 | /* |
| 286 | ** CAPI3REF: Run-Time Library Version Numbers |
| 287 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 288 | ** |
| @@ -7613,10 +7660,14 @@ | |
| 7660 | ** |
| 7661 | ** The following constants can be used for the T parameter to the |
| 7662 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7663 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7664 | ** |
| 7665 | ** When the value returned to V is a string, space to hold that string is |
| 7666 | ** managed by the prepared statement S and will be automatically freed when |
| 7667 | ** S is finalized. |
| 7668 | ** |
| 7669 | ** <dl> |
| 7670 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7671 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7672 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7673 | ** |
| @@ -7658,11 +7709,18 @@ | |
| 7709 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 7710 | |
| 7711 | /* |
| 7712 | ** CAPI3REF: Prepared Statement Scan Status |
| 7713 | ** |
| 7714 | ** This interface returns information about the predicted and measured |
| 7715 | ** performance for pStmt. Advanced applications can use this |
| 7716 | ** interface to compare the predicted and the measured performance and |
| 7717 | ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. |
| 7718 | ** |
| 7719 | ** Since this interface is expected to be rarely used, it is only |
| 7720 | ** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] |
| 7721 | ** compile-time option. |
| 7722 | ** |
| 7723 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7724 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7725 | ** of this interface is undefined. |
| 7726 | ** ^The requested measurement is written into a variable pointed to by |
| @@ -7676,13 +7734,10 @@ | |
| 7734 | ** ^Statistics might not be available for all loops in all statements. ^In cases |
| 7735 | ** where there exist loops with no available statistics, this function behaves |
| 7736 | ** as if the loop did not exist - it returns non-zero and leave the variable |
| 7737 | ** that pOut points to unchanged. |
| 7738 | ** |
| 7739 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 7740 | */ |
| 7741 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( |
| 7742 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ |
| 7743 | int idx, /* Index of loop to report on */ |
| @@ -12054,11 +12109,11 @@ | |
| 12109 | #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ |
| 12110 | #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ |
| 12111 | #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ |
| 12112 | #define SF_Compound 0x0040 /* Part of a compound query */ |
| 12113 | #define SF_Values 0x0080 /* Synthesized from VALUES clause */ |
| 12114 | #define SF_AllValues 0x0100 /* All terms of compound are VALUES */ |
| 12115 | #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ |
| 12116 | #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ |
| 12117 | #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ |
| 12118 | #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ |
| 12119 | |
| @@ -12682,11 +12737,11 @@ | |
| 12737 | ** FTS4 is really an extension for FTS3. It is enabled using the |
| 12738 | ** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call |
| 12739 | ** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. |
| 12740 | */ |
| 12741 | #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) |
| 12742 | # define SQLITE_ENABLE_FTS3 1 |
| 12743 | #endif |
| 12744 | |
| 12745 | /* |
| 12746 | ** The ctype.h header is needed for non-ASCII systems. It is also |
| 12747 | ** needed by FTS3 when FTS3 is included in the amalgamation. |
| @@ -13824,355 +13879,355 @@ | |
| 13879 | /* These macros are provided to "stringify" the value of the define |
| 13880 | ** for those options in which the value is meaningful. */ |
| 13881 | #define CTIMEOPT_VAL_(opt) #opt |
| 13882 | #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) |
| 13883 | |
| 13884 | #if SQLITE_32BIT_ROWID |
| 13885 | "32BIT_ROWID", |
| 13886 | #endif |
| 13887 | #if SQLITE_4_BYTE_ALIGNED_MALLOC |
| 13888 | "4_BYTE_ALIGNED_MALLOC", |
| 13889 | #endif |
| 13890 | #if SQLITE_CASE_SENSITIVE_LIKE |
| 13891 | "CASE_SENSITIVE_LIKE", |
| 13892 | #endif |
| 13893 | #if SQLITE_CHECK_PAGES |
| 13894 | "CHECK_PAGES", |
| 13895 | #endif |
| 13896 | #if SQLITE_COVERAGE_TEST |
| 13897 | "COVERAGE_TEST", |
| 13898 | #endif |
| 13899 | #if SQLITE_DEBUG |
| 13900 | "DEBUG", |
| 13901 | #endif |
| 13902 | #if SQLITE_DEFAULT_LOCKING_MODE |
| 13903 | "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), |
| 13904 | #endif |
| 13905 | #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) |
| 13906 | "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), |
| 13907 | #endif |
| 13908 | #if SQLITE_DISABLE_DIRSYNC |
| 13909 | "DISABLE_DIRSYNC", |
| 13910 | #endif |
| 13911 | #if SQLITE_DISABLE_LFS |
| 13912 | "DISABLE_LFS", |
| 13913 | #endif |
| 13914 | #if SQLITE_ENABLE_API_ARMOR |
| 13915 | "ENABLE_API_ARMOR", |
| 13916 | #endif |
| 13917 | #if SQLITE_ENABLE_ATOMIC_WRITE |
| 13918 | "ENABLE_ATOMIC_WRITE", |
| 13919 | #endif |
| 13920 | #if SQLITE_ENABLE_CEROD |
| 13921 | "ENABLE_CEROD", |
| 13922 | #endif |
| 13923 | #if SQLITE_ENABLE_COLUMN_METADATA |
| 13924 | "ENABLE_COLUMN_METADATA", |
| 13925 | #endif |
| 13926 | #if SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 13927 | "ENABLE_EXPENSIVE_ASSERT", |
| 13928 | #endif |
| 13929 | #if SQLITE_ENABLE_FTS1 |
| 13930 | "ENABLE_FTS1", |
| 13931 | #endif |
| 13932 | #if SQLITE_ENABLE_FTS2 |
| 13933 | "ENABLE_FTS2", |
| 13934 | #endif |
| 13935 | #if SQLITE_ENABLE_FTS3 |
| 13936 | "ENABLE_FTS3", |
| 13937 | #endif |
| 13938 | #if SQLITE_ENABLE_FTS3_PARENTHESIS |
| 13939 | "ENABLE_FTS3_PARENTHESIS", |
| 13940 | #endif |
| 13941 | #if SQLITE_ENABLE_FTS4 |
| 13942 | "ENABLE_FTS4", |
| 13943 | #endif |
| 13944 | #if SQLITE_ENABLE_ICU |
| 13945 | "ENABLE_ICU", |
| 13946 | #endif |
| 13947 | #if SQLITE_ENABLE_IOTRACE |
| 13948 | "ENABLE_IOTRACE", |
| 13949 | #endif |
| 13950 | #if SQLITE_ENABLE_LOAD_EXTENSION |
| 13951 | "ENABLE_LOAD_EXTENSION", |
| 13952 | #endif |
| 13953 | #if SQLITE_ENABLE_LOCKING_STYLE |
| 13954 | "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), |
| 13955 | #endif |
| 13956 | #if SQLITE_ENABLE_MEMORY_MANAGEMENT |
| 13957 | "ENABLE_MEMORY_MANAGEMENT", |
| 13958 | #endif |
| 13959 | #if SQLITE_ENABLE_MEMSYS3 |
| 13960 | "ENABLE_MEMSYS3", |
| 13961 | #endif |
| 13962 | #if SQLITE_ENABLE_MEMSYS5 |
| 13963 | "ENABLE_MEMSYS5", |
| 13964 | #endif |
| 13965 | #if SQLITE_ENABLE_OVERSIZE_CELL_CHECK |
| 13966 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 13967 | #endif |
| 13968 | #if SQLITE_ENABLE_RTREE |
| 13969 | "ENABLE_RTREE", |
| 13970 | #endif |
| 13971 | #if defined(SQLITE_ENABLE_STAT4) |
| 13972 | "ENABLE_STAT4", |
| 13973 | #elif defined(SQLITE_ENABLE_STAT3) |
| 13974 | "ENABLE_STAT3", |
| 13975 | #endif |
| 13976 | #if SQLITE_ENABLE_UNLOCK_NOTIFY |
| 13977 | "ENABLE_UNLOCK_NOTIFY", |
| 13978 | #endif |
| 13979 | #if SQLITE_ENABLE_UPDATE_DELETE_LIMIT |
| 13980 | "ENABLE_UPDATE_DELETE_LIMIT", |
| 13981 | #endif |
| 13982 | #if SQLITE_HAS_CODEC |
| 13983 | "HAS_CODEC", |
| 13984 | #endif |
| 13985 | #if HAVE_ISNAN || SQLITE_HAVE_ISNAN |
| 13986 | "HAVE_ISNAN", |
| 13987 | #endif |
| 13988 | #if SQLITE_HOMEGROWN_RECURSIVE_MUTEX |
| 13989 | "HOMEGROWN_RECURSIVE_MUTEX", |
| 13990 | #endif |
| 13991 | #if SQLITE_IGNORE_AFP_LOCK_ERRORS |
| 13992 | "IGNORE_AFP_LOCK_ERRORS", |
| 13993 | #endif |
| 13994 | #if SQLITE_IGNORE_FLOCK_LOCK_ERRORS |
| 13995 | "IGNORE_FLOCK_LOCK_ERRORS", |
| 13996 | #endif |
| 13997 | #ifdef SQLITE_INT64_TYPE |
| 13998 | "INT64_TYPE", |
| 13999 | #endif |
| 14000 | #if SQLITE_LOCK_TRACE |
| 14001 | "LOCK_TRACE", |
| 14002 | #endif |
| 14003 | #if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc) |
| 14004 | "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), |
| 14005 | #endif |
| 14006 | #ifdef SQLITE_MAX_SCHEMA_RETRY |
| 14007 | "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), |
| 14008 | #endif |
| 14009 | #if SQLITE_MEMDEBUG |
| 14010 | "MEMDEBUG", |
| 14011 | #endif |
| 14012 | #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT |
| 14013 | "MIXED_ENDIAN_64BIT_FLOAT", |
| 14014 | #endif |
| 14015 | #if SQLITE_NO_SYNC |
| 14016 | "NO_SYNC", |
| 14017 | #endif |
| 14018 | #if SQLITE_OMIT_ALTERTABLE |
| 14019 | "OMIT_ALTERTABLE", |
| 14020 | #endif |
| 14021 | #if SQLITE_OMIT_ANALYZE |
| 14022 | "OMIT_ANALYZE", |
| 14023 | #endif |
| 14024 | #if SQLITE_OMIT_ATTACH |
| 14025 | "OMIT_ATTACH", |
| 14026 | #endif |
| 14027 | #if SQLITE_OMIT_AUTHORIZATION |
| 14028 | "OMIT_AUTHORIZATION", |
| 14029 | #endif |
| 14030 | #if SQLITE_OMIT_AUTOINCREMENT |
| 14031 | "OMIT_AUTOINCREMENT", |
| 14032 | #endif |
| 14033 | #if SQLITE_OMIT_AUTOINIT |
| 14034 | "OMIT_AUTOINIT", |
| 14035 | #endif |
| 14036 | #if SQLITE_OMIT_AUTOMATIC_INDEX |
| 14037 | "OMIT_AUTOMATIC_INDEX", |
| 14038 | #endif |
| 14039 | #if SQLITE_OMIT_AUTORESET |
| 14040 | "OMIT_AUTORESET", |
| 14041 | #endif |
| 14042 | #if SQLITE_OMIT_AUTOVACUUM |
| 14043 | "OMIT_AUTOVACUUM", |
| 14044 | #endif |
| 14045 | #if SQLITE_OMIT_BETWEEN_OPTIMIZATION |
| 14046 | "OMIT_BETWEEN_OPTIMIZATION", |
| 14047 | #endif |
| 14048 | #if SQLITE_OMIT_BLOB_LITERAL |
| 14049 | "OMIT_BLOB_LITERAL", |
| 14050 | #endif |
| 14051 | #if SQLITE_OMIT_BTREECOUNT |
| 14052 | "OMIT_BTREECOUNT", |
| 14053 | #endif |
| 14054 | #if SQLITE_OMIT_BUILTIN_TEST |
| 14055 | "OMIT_BUILTIN_TEST", |
| 14056 | #endif |
| 14057 | #if SQLITE_OMIT_CAST |
| 14058 | "OMIT_CAST", |
| 14059 | #endif |
| 14060 | #if SQLITE_OMIT_CHECK |
| 14061 | "OMIT_CHECK", |
| 14062 | #endif |
| 14063 | #if SQLITE_OMIT_COMPLETE |
| 14064 | "OMIT_COMPLETE", |
| 14065 | #endif |
| 14066 | #if SQLITE_OMIT_COMPOUND_SELECT |
| 14067 | "OMIT_COMPOUND_SELECT", |
| 14068 | #endif |
| 14069 | #if SQLITE_OMIT_CTE |
| 14070 | "OMIT_CTE", |
| 14071 | #endif |
| 14072 | #if SQLITE_OMIT_DATETIME_FUNCS |
| 14073 | "OMIT_DATETIME_FUNCS", |
| 14074 | #endif |
| 14075 | #if SQLITE_OMIT_DECLTYPE |
| 14076 | "OMIT_DECLTYPE", |
| 14077 | #endif |
| 14078 | #if SQLITE_OMIT_DEPRECATED |
| 14079 | "OMIT_DEPRECATED", |
| 14080 | #endif |
| 14081 | #if SQLITE_OMIT_DISKIO |
| 14082 | "OMIT_DISKIO", |
| 14083 | #endif |
| 14084 | #if SQLITE_OMIT_EXPLAIN |
| 14085 | "OMIT_EXPLAIN", |
| 14086 | #endif |
| 14087 | #if SQLITE_OMIT_FLAG_PRAGMAS |
| 14088 | "OMIT_FLAG_PRAGMAS", |
| 14089 | #endif |
| 14090 | #if SQLITE_OMIT_FLOATING_POINT |
| 14091 | "OMIT_FLOATING_POINT", |
| 14092 | #endif |
| 14093 | #if SQLITE_OMIT_FOREIGN_KEY |
| 14094 | "OMIT_FOREIGN_KEY", |
| 14095 | #endif |
| 14096 | #if SQLITE_OMIT_GET_TABLE |
| 14097 | "OMIT_GET_TABLE", |
| 14098 | #endif |
| 14099 | #if SQLITE_OMIT_INCRBLOB |
| 14100 | "OMIT_INCRBLOB", |
| 14101 | #endif |
| 14102 | #if SQLITE_OMIT_INTEGRITY_CHECK |
| 14103 | "OMIT_INTEGRITY_CHECK", |
| 14104 | #endif |
| 14105 | #if SQLITE_OMIT_LIKE_OPTIMIZATION |
| 14106 | "OMIT_LIKE_OPTIMIZATION", |
| 14107 | #endif |
| 14108 | #if SQLITE_OMIT_LOAD_EXTENSION |
| 14109 | "OMIT_LOAD_EXTENSION", |
| 14110 | #endif |
| 14111 | #if SQLITE_OMIT_LOCALTIME |
| 14112 | "OMIT_LOCALTIME", |
| 14113 | #endif |
| 14114 | #if SQLITE_OMIT_LOOKASIDE |
| 14115 | "OMIT_LOOKASIDE", |
| 14116 | #endif |
| 14117 | #if SQLITE_OMIT_MEMORYDB |
| 14118 | "OMIT_MEMORYDB", |
| 14119 | #endif |
| 14120 | #if SQLITE_OMIT_OR_OPTIMIZATION |
| 14121 | "OMIT_OR_OPTIMIZATION", |
| 14122 | #endif |
| 14123 | #if SQLITE_OMIT_PAGER_PRAGMAS |
| 14124 | "OMIT_PAGER_PRAGMAS", |
| 14125 | #endif |
| 14126 | #if SQLITE_OMIT_PRAGMA |
| 14127 | "OMIT_PRAGMA", |
| 14128 | #endif |
| 14129 | #if SQLITE_OMIT_PROGRESS_CALLBACK |
| 14130 | "OMIT_PROGRESS_CALLBACK", |
| 14131 | #endif |
| 14132 | #if SQLITE_OMIT_QUICKBALANCE |
| 14133 | "OMIT_QUICKBALANCE", |
| 14134 | #endif |
| 14135 | #if SQLITE_OMIT_REINDEX |
| 14136 | "OMIT_REINDEX", |
| 14137 | #endif |
| 14138 | #if SQLITE_OMIT_SCHEMA_PRAGMAS |
| 14139 | "OMIT_SCHEMA_PRAGMAS", |
| 14140 | #endif |
| 14141 | #if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS |
| 14142 | "OMIT_SCHEMA_VERSION_PRAGMAS", |
| 14143 | #endif |
| 14144 | #if SQLITE_OMIT_SHARED_CACHE |
| 14145 | "OMIT_SHARED_CACHE", |
| 14146 | #endif |
| 14147 | #if SQLITE_OMIT_SUBQUERY |
| 14148 | "OMIT_SUBQUERY", |
| 14149 | #endif |
| 14150 | #if SQLITE_OMIT_TCL_VARIABLE |
| 14151 | "OMIT_TCL_VARIABLE", |
| 14152 | #endif |
| 14153 | #if SQLITE_OMIT_TEMPDB |
| 14154 | "OMIT_TEMPDB", |
| 14155 | #endif |
| 14156 | #if SQLITE_OMIT_TRACE |
| 14157 | "OMIT_TRACE", |
| 14158 | #endif |
| 14159 | #if SQLITE_OMIT_TRIGGER |
| 14160 | "OMIT_TRIGGER", |
| 14161 | #endif |
| 14162 | #if SQLITE_OMIT_TRUNCATE_OPTIMIZATION |
| 14163 | "OMIT_TRUNCATE_OPTIMIZATION", |
| 14164 | #endif |
| 14165 | #if SQLITE_OMIT_UTF16 |
| 14166 | "OMIT_UTF16", |
| 14167 | #endif |
| 14168 | #if SQLITE_OMIT_VACUUM |
| 14169 | "OMIT_VACUUM", |
| 14170 | #endif |
| 14171 | #if SQLITE_OMIT_VIEW |
| 14172 | "OMIT_VIEW", |
| 14173 | #endif |
| 14174 | #if SQLITE_OMIT_VIRTUALTABLE |
| 14175 | "OMIT_VIRTUALTABLE", |
| 14176 | #endif |
| 14177 | #if SQLITE_OMIT_WAL |
| 14178 | "OMIT_WAL", |
| 14179 | #endif |
| 14180 | #if SQLITE_OMIT_WSD |
| 14181 | "OMIT_WSD", |
| 14182 | #endif |
| 14183 | #if SQLITE_OMIT_XFER_OPT |
| 14184 | "OMIT_XFER_OPT", |
| 14185 | #endif |
| 14186 | #if SQLITE_PERFORMANCE_TRACE |
| 14187 | "PERFORMANCE_TRACE", |
| 14188 | #endif |
| 14189 | #if SQLITE_PROXY_DEBUG |
| 14190 | "PROXY_DEBUG", |
| 14191 | #endif |
| 14192 | #if SQLITE_RTREE_INT_ONLY |
| 14193 | "RTREE_INT_ONLY", |
| 14194 | #endif |
| 14195 | #if SQLITE_SECURE_DELETE |
| 14196 | "SECURE_DELETE", |
| 14197 | #endif |
| 14198 | #if SQLITE_SMALL_STACK |
| 14199 | "SMALL_STACK", |
| 14200 | #endif |
| 14201 | #if SQLITE_SOUNDEX |
| 14202 | "SOUNDEX", |
| 14203 | #endif |
| 14204 | #if SQLITE_SYSTEM_MALLOC |
| 14205 | "SYSTEM_MALLOC", |
| 14206 | #endif |
| 14207 | #if SQLITE_TCL |
| 14208 | "TCL", |
| 14209 | #endif |
| 14210 | #if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) |
| 14211 | "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), |
| 14212 | #endif |
| 14213 | #if SQLITE_TEST |
| 14214 | "TEST", |
| 14215 | #endif |
| 14216 | #if defined(SQLITE_THREADSAFE) |
| 14217 | "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), |
| 14218 | #endif |
| 14219 | #if SQLITE_USE_ALLOCA |
| 14220 | "USE_ALLOCA", |
| 14221 | #endif |
| 14222 | #if SQLITE_USER_AUTHENTICATION |
| 14223 | "USER_AUTHENTICATION", |
| 14224 | #endif |
| 14225 | #if SQLITE_WIN32_MALLOC |
| 14226 | "WIN32_MALLOC", |
| 14227 | #endif |
| 14228 | #if SQLITE_ZERO_MALLOC |
| 14229 | "ZERO_MALLOC" |
| 14230 | #endif |
| 14231 | }; |
| 14232 | |
| 14233 | /* |
| @@ -14183,11 +14238,11 @@ | |
| 14238 | ** is not required for a match. |
| 14239 | */ |
| 14240 | SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ |
| 14241 | int i, n; |
| 14242 | |
| 14243 | #if SQLITE_ENABLE_API_ARMOR |
| 14244 | if( zOptName==0 ){ |
| 14245 | (void)SQLITE_MISUSE_BKPT; |
| 14246 | return 0; |
| 14247 | } |
| 14248 | #endif |
| @@ -15411,12 +15466,13 @@ | |
| 15466 | ** |
| 15467 | ** If the user has not indicated to use localtime_r() or localtime_s() |
| 15468 | ** already, check for an MSVC build environment that provides |
| 15469 | ** localtime_s(). |
| 15470 | */ |
| 15471 | #if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \ |
| 15472 | && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) |
| 15473 | #undef HAVE_LOCALTIME_S |
| 15474 | #define HAVE_LOCALTIME_S 1 |
| 15475 | #endif |
| 15476 | |
| 15477 | #ifndef SQLITE_OMIT_LOCALTIME |
| 15478 | /* |
| @@ -15432,12 +15488,11 @@ | |
| 15488 | ** library function localtime_r() is used to assist in the calculation of |
| 15489 | ** local time. |
| 15490 | */ |
| 15491 | static int osLocaltime(time_t *t, struct tm *pTm){ |
| 15492 | int rc; |
| 15493 | #if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S |
| 15494 | struct tm *pX; |
| 15495 | #if SQLITE_THREADSAFE>0 |
| 15496 | sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
| 15497 | #endif |
| 15498 | sqlite3_mutex_enter(mutex); |
| @@ -15450,11 +15505,11 @@ | |
| 15505 | rc = pX==0; |
| 15506 | #else |
| 15507 | #ifndef SQLITE_OMIT_BUILTIN_TEST |
| 15508 | if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; |
| 15509 | #endif |
| 15510 | #if HAVE_LOCALTIME_R |
| 15511 | rc = localtime_r(t, pTm)==0; |
| 15512 | #else |
| 15513 | rc = localtime_s(pTm, t); |
| 15514 | #endif /* HAVE_LOCALTIME_R */ |
| 15515 | #endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ |
| @@ -15894,12 +15949,14 @@ | |
| 15949 | DateTime x; |
| 15950 | u64 n; |
| 15951 | size_t i,j; |
| 15952 | char *z; |
| 15953 | sqlite3 *db; |
| 15954 | const char *zFmt; |
| 15955 | char zBuf[100]; |
| 15956 | if( argc==0 ) return; |
| 15957 | zFmt = (const char*)sqlite3_value_text(argv[0]); |
| 15958 | if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; |
| 15959 | db = sqlite3_context_db_handle(context); |
| 15960 | for(i=0, n=1; zFmt[i]; i++, n++){ |
| 15961 | if( zFmt[i]=='%' ){ |
| 15962 | switch( zFmt[i+1] ){ |
| @@ -16089,11 +16146,11 @@ | |
| 16146 | UNUSED_PARAMETER(argv); |
| 16147 | |
| 16148 | iT = sqlite3StmtCurrentTime(context); |
| 16149 | if( iT<=0 ) return; |
| 16150 | t = iT/1000 - 10000*(sqlite3_int64)21086676; |
| 16151 | #if HAVE_GMTIME_R |
| 16152 | pTm = gmtime_r(&t, &sNow); |
| 16153 | #else |
| 16154 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
| 16155 | pTm = gmtime(&t); |
| 16156 | if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); |
| @@ -16763,13 +16820,13 @@ | |
| 16820 | |
| 16821 | /* |
| 16822 | ** The malloc.h header file is needed for malloc_usable_size() function |
| 16823 | ** on some systems (e.g. Linux). |
| 16824 | */ |
| 16825 | #if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE |
| 16826 | # define SQLITE_USE_MALLOC_H 1 |
| 16827 | # define SQLITE_USE_MALLOC_USABLE_SIZE 1 |
| 16828 | /* |
| 16829 | ** The MSVCRT has malloc_usable_size(), but it is called _msize(). The |
| 16830 | ** use of _msize() is automatic, but can be disabled by compiling with |
| 16831 | ** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires |
| 16832 | ** the malloc.h header file. |
| @@ -21004,21 +21061,10 @@ | |
| 21061 | ** This file contains code for a set of "printf"-like routines. These |
| 21062 | ** routines format strings much like the printf() from the standard C |
| 21063 | ** library, though the implementation here has enhancements to support |
| 21064 | ** SQLlite. |
| 21065 | */ |
| 21066 | |
| 21067 | /* |
| 21068 | ** Conversion types fall into various categories as defined by the |
| 21069 | ** following enumeration. |
| 21070 | */ |
| @@ -22313,10 +22359,12 @@ | |
| 22359 | ** single threaded systems. Nothing in SQLite requires multiple threads. |
| 22360 | ** This interface exists so that applications that want to take advantage |
| 22361 | ** of multiple cores can do so, while also allowing applications to stay |
| 22362 | ** single-threaded if desired. |
| 22363 | */ |
| 22364 | #if SQLITE_OS_WIN |
| 22365 | #endif |
| 22366 | |
| 22367 | #if SQLITE_MAX_WORKER_THREADS>0 |
| 22368 | |
| 22369 | /********************************* Unix Pthreads ****************************/ |
| 22370 | #if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 |
| @@ -23099,11 +23147,11 @@ | |
| 23147 | ** This file contains functions for allocating memory, comparing |
| 23148 | ** strings, and stuff like that. |
| 23149 | ** |
| 23150 | */ |
| 23151 | /* #include <stdarg.h> */ |
| 23152 | #if HAVE_ISNAN || SQLITE_HAVE_ISNAN |
| 23153 | # include <math.h> |
| 23154 | #endif |
| 23155 | |
| 23156 | /* |
| 23157 | ** Routine needed to support the testcase() macro. |
| @@ -23140,11 +23188,11 @@ | |
| 23188 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
| 23189 | ** Otherwise, we have our own implementation that works on most systems. |
| 23190 | */ |
| 23191 | SQLITE_PRIVATE int sqlite3IsNaN(double x){ |
| 23192 | int rc; /* The value return */ |
| 23193 | #if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN |
| 23194 | /* |
| 23195 | ** Systems that support the isnan() library function should probably |
| 23196 | ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have |
| 23197 | ** found that many systems do not have a working isnan() function so |
| 23198 | ** this implementation is provided as an alternative. |
| @@ -23170,13 +23218,13 @@ | |
| 23218 | # error SQLite will not work correctly with the -ffast-math option of GCC. |
| 23219 | #endif |
| 23220 | volatile double y = x; |
| 23221 | volatile double z = y; |
| 23222 | rc = (y!=z); |
| 23223 | #else /* if HAVE_ISNAN */ |
| 23224 | rc = isnan(x); |
| 23225 | #endif /* HAVE_ISNAN */ |
| 23226 | testcase( rc ); |
| 23227 | return rc; |
| 23228 | } |
| 23229 | #endif /* SQLITE_OMIT_FLOATING_POINT */ |
| 23230 | |
| @@ -28493,13 +28541,13 @@ | |
| 28541 | |
| 28542 | /* |
| 28543 | ** We do not trust systems to provide a working fdatasync(). Some do. |
| 28544 | ** Others do no. To be safe, we will stick with the (slightly slower) |
| 28545 | ** fsync(). If you know that your system does support fdatasync() correctly, |
| 28546 | ** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC |
| 28547 | */ |
| 28548 | #if !defined(fdatasync) && !HAVE_FDATASYNC |
| 28549 | # define fdatasync fsync |
| 28550 | #endif |
| 28551 | |
| 28552 | /* |
| 28553 | ** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not |
| @@ -28824,22 +28872,23 @@ | |
| 28872 | ** at offset (nSize-1), to set the size of the file correctly. |
| 28873 | ** This is a similar technique to that used by glibc on systems |
| 28874 | ** that do not have a real fallocate() call. |
| 28875 | */ |
| 28876 | int nBlk = buf.st_blksize; /* File-system block size */ |
| 28877 | int nWrite = 0; /* Number of bytes written by seekAndWrite */ |
| 28878 | i64 iWrite; /* Next offset to write to */ |
| 28879 | |
| 28880 | iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1; |
| 28881 | assert( iWrite>=buf.st_size ); |
| 28882 | assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) ); |
| 28883 | assert( ((iWrite+1)%nBlk)==0 ); |
| 28884 | for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){ |
| 28885 | nWrite = seekAndWrite(pFile, iWrite, "", 1); |
| 28886 | if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
| 28887 | } |
| 28888 | if( nWrite==0 || (nSize%nBlk) ){ |
| 28889 | nWrite = seekAndWrite(pFile, nSize-1, "", 1); |
| 28890 | if( nWrite!=1 ) return SQLITE_IOERR_WRITE; |
| 28891 | } |
| 28892 | #endif |
| 28893 | } |
| 28894 | } |
| @@ -38849,22 +38898,10 @@ | |
| 38898 | void *pStress; /* Argument to xStress */ |
| 38899 | sqlite3_pcache *pCache; /* Pluggable cache module */ |
| 38900 | PgHdr *pPage1; /* Reference to page 1 */ |
| 38901 | }; |
| 38902 | |
| 38903 | /********************************** Linked List Management ********************/ |
| 38904 | |
| 38905 | /* Allowed values for second argument to pcacheManageDirtyList() */ |
| 38906 | #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ |
| 38907 | #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ |
| @@ -73905,12 +73942,12 @@ | |
| 73942 | pIdxKey->default_rc = 0; |
| 73943 | if( pOp->opcode==OP_NoConflict ){ |
| 73944 | /* For the OP_NoConflict opcode, take the jump if any of the |
| 73945 | ** input fields are NULL, since any key with a NULL will not |
| 73946 | ** conflict */ |
| 73947 | for(ii=0; ii<pIdxKey->nField; ii++){ |
| 73948 | if( pIdxKey->aMem[ii].flags & MEM_Null ){ |
| 73949 | pc = pOp->p2 - 1; VdbeBranchTaken(1,2); |
| 73950 | break; |
| 73951 | } |
| 73952 | } |
| 73953 | } |
| @@ -79464,10 +79501,11 @@ | |
| 79501 | rc = vdbePmaReaderNext(pSorter->pReader); |
| 79502 | *pbEof = (pSorter->pReader->pFd==0); |
| 79503 | }else |
| 79504 | #endif |
| 79505 | /*if( !pSorter->bUseThreads )*/ { |
| 79506 | assert( pSorter->pMerger!=0 ); |
| 79507 | assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); |
| 79508 | rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); |
| 79509 | } |
| 79510 | }else{ |
| 79511 | SorterRecord *pFree = pSorter->list.pList; |
| @@ -82230,11 +82268,11 @@ | |
| 82268 | Expr *pLeft, /* Left operand */ |
| 82269 | Expr *pRight, /* Right operand */ |
| 82270 | const Token *pToken /* Argument token */ |
| 82271 | ){ |
| 82272 | Expr *p; |
| 82273 | if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){ |
| 82274 | /* Take advantage of short-circuit false optimization for AND */ |
| 82275 | p = sqlite3ExprAnd(pParse->db, pLeft, pRight); |
| 82276 | }else{ |
| 82277 | p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); |
| 82278 | sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); |
| @@ -85784,14 +85822,15 @@ | |
| 85822 | ** NEVER() will need to be removed. */ |
| 85823 | if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ |
| 85824 | int i; |
| 85825 | struct SrcCount *p = pWalker->u.pSrcCount; |
| 85826 | SrcList *pSrc = p->pSrc; |
| 85827 | int nSrc = pSrc ? pSrc->nSrc : 0; |
| 85828 | for(i=0; i<nSrc; i++){ |
| 85829 | if( pExpr->iTable==pSrc->a[i].iCursor ) break; |
| 85830 | } |
| 85831 | if( i<nSrc ){ |
| 85832 | p->nThis++; |
| 85833 | }else{ |
| 85834 | p->nOther++; |
| 85835 | } |
| 85836 | } |
| @@ -94664,12 +94703,12 @@ | |
| 94703 | const char *zDb; /* Name of database holding pTab */ |
| 94704 | int i; /* Loop counter */ |
| 94705 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| 94706 | Index *pIdx; /* For looping over indices of the table */ |
| 94707 | int iTabCur; /* Cursor number for the table */ |
| 94708 | int iDataCur = 0; /* VDBE cursor for the canonical data source */ |
| 94709 | int iIdxCur = 0; /* Cursor number of the first index */ |
| 94710 | int nIdx; /* Number of indices */ |
| 94711 | sqlite3 *db; /* Main database structure */ |
| 94712 | AuthContext sContext; /* Authorization context */ |
| 94713 | NameContext sNC; /* Name context to resolve expressions in */ |
| 94714 | int iDb; /* Database number */ |
| @@ -102658,11 +102697,11 @@ | |
| 102697 | char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ |
| 102698 | const char *zDb = 0; /* The database name */ |
| 102699 | Token *pId; /* Pointer to <id> token */ |
| 102700 | char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ |
| 102701 | int iDb; /* Database index for <database> */ |
| 102702 | int lwr, upr, mid = 0; /* Binary search bounds */ |
| 102703 | int rc; /* return value form SQLITE_FCNTL_PRAGMA */ |
| 102704 | sqlite3 *db = pParse->db; /* The database connection */ |
| 102705 | Db *pDb; /* The specific database being pragmaed */ |
| 102706 | Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ |
| 102707 | |
| @@ -105271,24 +105310,29 @@ | |
| 105310 | u8 sortFlags; /* Zero or more SORTFLAG_* bits */ |
| 105311 | }; |
| 105312 | #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ |
| 105313 | |
| 105314 | /* |
| 105315 | ** Delete all the content of a Select structure. Deallocate the structure |
| 105316 | ** itself only if bFree is true. |
| 105317 | */ |
| 105318 | static void clearSelect(sqlite3 *db, Select *p, int bFree){ |
| 105319 | while( p ){ |
| 105320 | Select *pPrior = p->pPrior; |
| 105321 | sqlite3ExprListDelete(db, p->pEList); |
| 105322 | sqlite3SrcListDelete(db, p->pSrc); |
| 105323 | sqlite3ExprDelete(db, p->pWhere); |
| 105324 | sqlite3ExprListDelete(db, p->pGroupBy); |
| 105325 | sqlite3ExprDelete(db, p->pHaving); |
| 105326 | sqlite3ExprListDelete(db, p->pOrderBy); |
| 105327 | sqlite3ExprDelete(db, p->pLimit); |
| 105328 | sqlite3ExprDelete(db, p->pOffset); |
| 105329 | sqlite3WithDelete(db, p->pWith); |
| 105330 | if( bFree ) sqlite3DbFree(db, p); |
| 105331 | p = pPrior; |
| 105332 | bFree = 1; |
| 105333 | } |
| 105334 | } |
| 105335 | |
| 105336 | /* |
| 105337 | ** Initialize a SelectDest structure. |
| 105338 | */ |
| @@ -105343,12 +105387,11 @@ | |
| 105387 | pNew->pOffset = pOffset; |
| 105388 | assert( pOffset==0 || pLimit!=0 ); |
| 105389 | pNew->addrOpenEphm[0] = -1; |
| 105390 | pNew->addrOpenEphm[1] = -1; |
| 105391 | if( db->mallocFailed ) { |
| 105392 | clearSelect(db, pNew, pNew!=&standin); |
| 105393 | pNew = 0; |
| 105394 | }else{ |
| 105395 | assert( pNew->pSrc!=0 || pParse->nErr>0 ); |
| 105396 | } |
| 105397 | assert( pNew!=&standin ); |
| @@ -105369,14 +105412,11 @@ | |
| 105412 | |
| 105413 | /* |
| 105414 | ** Delete the given Select structure and all of its substructures. |
| 105415 | */ |
| 105416 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ |
| 105417 | clearSelect(db, p, 1); |
| 105418 | } |
| 105419 | |
| 105420 | /* |
| 105421 | ** Return a pointer to the right-most SELECT statement in a compound. |
| 105422 | */ |
| @@ -107288,10 +107328,70 @@ | |
| 107328 | Parse *pParse, /* Parsing context */ |
| 107329 | Select *p, /* The right-most of SELECTs to be coded */ |
| 107330 | SelectDest *pDest /* What to do with query results */ |
| 107331 | ); |
| 107332 | |
| 107333 | /* |
| 107334 | ** Error message for when two or more terms of a compound select have different |
| 107335 | ** size result sets. |
| 107336 | */ |
| 107337 | static void selectWrongNumTermsError(Parse *pParse, Select *p){ |
| 107338 | if( p->selFlags & SF_Values ){ |
| 107339 | sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); |
| 107340 | }else{ |
| 107341 | sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" |
| 107342 | " do not have the same number of result columns", selectOpName(p->op)); |
| 107343 | } |
| 107344 | } |
| 107345 | |
| 107346 | /* |
| 107347 | ** Handle the special case of a compound-select that originates from a |
| 107348 | ** VALUES clause. By handling this as a special case, we avoid deep |
| 107349 | ** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT |
| 107350 | ** on a VALUES clause. |
| 107351 | ** |
| 107352 | ** Because the Select object originates from a VALUES clause: |
| 107353 | ** (1) It has no LIMIT or OFFSET |
| 107354 | ** (2) All terms are UNION ALL |
| 107355 | ** (3) There is no ORDER BY clause |
| 107356 | */ |
| 107357 | static int multiSelectValues( |
| 107358 | Parse *pParse, /* Parsing context */ |
| 107359 | Select *p, /* The right-most of SELECTs to be coded */ |
| 107360 | SelectDest *pDest /* What to do with query results */ |
| 107361 | ){ |
| 107362 | Select *pPrior; |
| 107363 | int nExpr = p->pEList->nExpr; |
| 107364 | int nRow = 1; |
| 107365 | int rc = 0; |
| 107366 | assert( p->pNext==0 ); |
| 107367 | assert( p->selFlags & SF_AllValues ); |
| 107368 | do{ |
| 107369 | assert( p->selFlags & SF_Values ); |
| 107370 | assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); |
| 107371 | assert( p->pLimit==0 ); |
| 107372 | assert( p->pOffset==0 ); |
| 107373 | if( p->pEList->nExpr!=nExpr ){ |
| 107374 | selectWrongNumTermsError(pParse, p); |
| 107375 | return 1; |
| 107376 | } |
| 107377 | if( p->pPrior==0 ) break; |
| 107378 | assert( p->pPrior->pNext==p ); |
| 107379 | p = p->pPrior; |
| 107380 | nRow++; |
| 107381 | }while(1); |
| 107382 | while( p ){ |
| 107383 | pPrior = p->pPrior; |
| 107384 | p->pPrior = 0; |
| 107385 | rc = sqlite3Select(pParse, p, pDest); |
| 107386 | p->pPrior = pPrior; |
| 107387 | if( rc ) break; |
| 107388 | p->nSelectRow = nRow; |
| 107389 | p = p->pNext; |
| 107390 | } |
| 107391 | return rc; |
| 107392 | } |
| 107393 | |
| 107394 | /* |
| 107395 | ** This routine is called to process a compound query form from |
| 107396 | ** two or more separate queries using UNION, UNION ALL, EXCEPT, or |
| 107397 | ** INTERSECT |
| @@ -107368,22 +107468,24 @@ | |
| 107468 | assert( p->pEList ); |
| 107469 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); |
| 107470 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 107471 | dest.eDest = SRT_Table; |
| 107472 | } |
| 107473 | |
| 107474 | /* Special handling for a compound-select that originates as a VALUES clause. |
| 107475 | */ |
| 107476 | if( p->selFlags & SF_AllValues ){ |
| 107477 | rc = multiSelectValues(pParse, p, &dest); |
| 107478 | goto multi_select_end; |
| 107479 | } |
| 107480 | |
| 107481 | /* Make sure all SELECTs in the statement have the same number of elements |
| 107482 | ** in their result sets. |
| 107483 | */ |
| 107484 | assert( p->pEList && pPrior->pEList ); |
| 107485 | if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ |
| 107486 | selectWrongNumTermsError(pParse, p); |
| 107487 | rc = 1; |
| 107488 | goto multi_select_end; |
| 107489 | } |
| 107490 | |
| 107491 | #ifndef SQLITE_OMIT_CTE |
| @@ -109265,11 +109367,13 @@ | |
| 109367 | if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ |
| 109368 | return WRC_Prune; |
| 109369 | } |
| 109370 | pTabList = p->pSrc; |
| 109371 | pEList = p->pEList; |
| 109372 | if( pWalker->xSelectCallback2==selectPopWith ){ |
| 109373 | sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); |
| 109374 | } |
| 109375 | |
| 109376 | /* Make sure cursor numbers have been assigned to all entries in |
| 109377 | ** the FROM clause of the SELECT statement. |
| 109378 | */ |
| 109379 | sqlite3SrcListAssignCursors(pParse, pTabList); |
| @@ -109556,11 +109660,13 @@ | |
| 109660 | if( pParse->hasCompound ){ |
| 109661 | w.xSelectCallback = convertCompoundSelectToSubquery; |
| 109662 | sqlite3WalkSelect(&w, pSelect); |
| 109663 | } |
| 109664 | w.xSelectCallback = selectExpander; |
| 109665 | if( (pSelect->selFlags & SF_AllValues)==0 ){ |
| 109666 | w.xSelectCallback2 = selectPopWith; |
| 109667 | } |
| 109668 | sqlite3WalkSelect(&w, pSelect); |
| 109669 | } |
| 109670 | |
| 109671 | |
| 109672 | #ifndef SQLITE_OMIT_SUBQUERY |
| @@ -123884,17 +123990,23 @@ | |
| 123990 | Select *p = yymsp[0].minor.yy3, *pNext, *pLoop; |
| 123991 | if( p ){ |
| 123992 | int cnt = 0, mxSelect; |
| 123993 | p->pWith = yymsp[-1].minor.yy59; |
| 123994 | if( p->pPrior ){ |
| 123995 | u16 allValues = SF_Values; |
| 123996 | pNext = 0; |
| 123997 | for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ |
| 123998 | pLoop->pNext = pNext; |
| 123999 | pLoop->selFlags |= SF_Compound; |
| 124000 | allValues &= pLoop->selFlags; |
| 124001 | } |
| 124002 | if( allValues ){ |
| 124003 | p->selFlags |= SF_AllValues; |
| 124004 | }else if( |
| 124005 | (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 |
| 124006 | && cnt>mxSelect |
| 124007 | ){ |
| 124008 | sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); |
| 124009 | } |
| 124010 | } |
| 124011 | }else{ |
| 124012 | sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59); |
| @@ -127600,11 +127712,11 @@ | |
| 127712 | */ |
| 127713 | static int sqliteDefaultBusyCallback( |
| 127714 | void *ptr, /* Database connection */ |
| 127715 | int count /* Number of times table has been busy */ |
| 127716 | ){ |
| 127717 | #if SQLITE_OS_WIN || HAVE_USLEEP |
| 127718 | static const u8 delays[] = |
| 127719 | { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; |
| 127720 | static const u8 totals[] = |
| 127721 | { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; |
| 127722 | # define NDELAY ArraySize(delays) |
| @@ -129390,11 +129502,11 @@ | |
| 129502 | ){ |
| 129503 | int rc; |
| 129504 | char *zErrMsg = 0; |
| 129505 | Table *pTab = 0; |
| 129506 | Column *pCol = 0; |
| 129507 | int iCol = 0; |
| 129508 | |
| 129509 | char const *zDataType = 0; |
| 129510 | char const *zCollSeq = 0; |
| 129511 | int notnull = 0; |
| 129512 | int primarykey = 0; |
| @@ -133013,11 +133125,11 @@ | |
| 133125 | const char *zNode, /* Buffer containing segment interior node */ |
| 133126 | int nNode, /* Size of buffer at zNode */ |
| 133127 | sqlite3_int64 *piLeaf, /* Selected leaf node */ |
| 133128 | sqlite3_int64 *piLeaf2 /* Selected leaf node */ |
| 133129 | ){ |
| 133130 | int rc = SQLITE_OK; /* Return code */ |
| 133131 | int iHeight; /* Height of this node in tree */ |
| 133132 | |
| 133133 | assert( piLeaf || piLeaf2 ); |
| 133134 | |
| 133135 | fts3GetVarint32(zNode, &iHeight); |
| @@ -133024,11 +133136,11 @@ | |
| 133136 | rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); |
| 133137 | assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); |
| 133138 | |
| 133139 | if( rc==SQLITE_OK && iHeight>1 ){ |
| 133140 | char *zBlob = 0; /* Blob read from %_segments table */ |
| 133141 | int nBlob = 0; /* Size of zBlob in bytes */ |
| 133142 | |
| 133143 | if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ |
| 133144 | rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); |
| 133145 | if( rc==SQLITE_OK ){ |
| 133146 | rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); |
| @@ -134246,11 +134358,11 @@ | |
| 134358 | int idxNum, /* Strategy index */ |
| 134359 | const char *idxStr, /* Unused */ |
| 134360 | int nVal, /* Number of elements in apVal */ |
| 134361 | sqlite3_value **apVal /* Arguments for the indexing scheme */ |
| 134362 | ){ |
| 134363 | int rc = SQLITE_OK; |
| 134364 | char *zSql; /* SQL statement used to access %_content */ |
| 134365 | int eSearch; |
| 134366 | Fts3Table *p = (Fts3Table *)pCursor->pVtab; |
| 134367 | Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; |
| 134368 | |
| @@ -140734,11 +140846,11 @@ | |
| 140846 | int argc, /* Number of elements in argv array */ |
| 140847 | const char * const *argv, /* xCreate/xConnect argument array */ |
| 140848 | sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
| 140849 | char **pzErr /* OUT: sqlite3_malloc'd error message */ |
| 140850 | ){ |
| 140851 | Fts3tokTable *pTab = 0; |
| 140852 | const sqlite3_tokenizer_module *pMod = 0; |
| 140853 | sqlite3_tokenizer *pTok = 0; |
| 140854 | int rc; |
| 140855 | char **azDequote = 0; |
| 140856 | int nDequote; |
| @@ -144109,12 +144221,12 @@ | |
| 144221 | } |
| 144222 | rc = sqlite3_reset(pRange); |
| 144223 | |
| 144224 | if( bOk ){ |
| 144225 | int iIdx = 0; |
| 144226 | sqlite3_stmt *pUpdate1 = 0; |
| 144227 | sqlite3_stmt *pUpdate2 = 0; |
| 144228 | |
| 144229 | if( rc==SQLITE_OK ){ |
| 144230 | rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); |
| 144231 | } |
| 144232 | if( rc==SQLITE_OK ){ |
| @@ -151778,10 +151890,12 @@ | |
| 151890 | RtreeCell cell; /* New cell to insert if nData>1 */ |
| 151891 | int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ |
| 151892 | |
| 151893 | rtreeReference(pRtree); |
| 151894 | assert(nData>=1); |
| 151895 | |
| 151896 | cell.iRowid = 0; /* Used only to suppress a compiler warning */ |
| 151897 | |
| 151898 | /* Constraint handling. A write operation on an r-tree table may return |
| 151899 | ** SQLITE_CONSTRAINT for two reasons: |
| 151900 | ** |
| 151901 | ** 1. A duplicate rowid value, or |
| 151902 |
+13
-5
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.8.8" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008008 |
| 112 | -#define SQLITE_SOURCE_ID "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6" | |
| 112 | +#define SQLITE_SOURCE_ID "2015-01-12 21:43:00 e693e11d1b9265974c32bddba873ea30a4d0b708" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -7489,10 +7489,14 @@ | ||
| 7489 | 7489 | ** |
| 7490 | 7490 | ** The following constants can be used for the T parameter to the |
| 7491 | 7491 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7492 | 7492 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7493 | 7493 | ** |
| 7494 | +** When the value returned to V is a string, space to hold that string is | |
| 7495 | +** managed by the prepared statement S and will be automatically freed when | |
| 7496 | +** S is finalized. | |
| 7497 | +** | |
| 7494 | 7498 | ** <dl> |
| 7495 | 7499 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7496 | 7500 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7497 | 7501 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7498 | 7502 | ** |
| @@ -7534,11 +7538,18 @@ | ||
| 7534 | 7538 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 7535 | 7539 | |
| 7536 | 7540 | /* |
| 7537 | 7541 | ** CAPI3REF: Prepared Statement Scan Status |
| 7538 | 7542 | ** |
| 7539 | -** Return status data for a single loop within query pStmt. | |
| 7543 | +** This interface returns information about the predicted and measured | |
| 7544 | +** performance for pStmt. Advanced applications can use this | |
| 7545 | +** interface to compare the predicted and the measured performance and | |
| 7546 | +** issue warnings and/or rerun [ANALYZE] if discrepancies are found. | |
| 7547 | +** | |
| 7548 | +** Since this interface is expected to be rarely used, it is only | |
| 7549 | +** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] | |
| 7550 | +** compile-time option. | |
| 7540 | 7551 | ** |
| 7541 | 7552 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7542 | 7553 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7543 | 7554 | ** of this interface is undefined. |
| 7544 | 7555 | ** ^The requested measurement is written into a variable pointed to by |
| @@ -7552,13 +7563,10 @@ | ||
| 7552 | 7563 | ** ^Statistics might not be available for all loops in all statements. ^In cases |
| 7553 | 7564 | ** where there exist loops with no available statistics, this function behaves |
| 7554 | 7565 | ** as if the loop did not exist - it returns non-zero and leave the variable |
| 7555 | 7566 | ** that pOut points to unchanged. |
| 7556 | 7567 | ** |
| 7557 | -** This API is only available if the library is built with pre-processor | |
| 7558 | -** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. | |
| 7559 | -** | |
| 7560 | 7568 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 7561 | 7569 | */ |
| 7562 | 7570 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( |
| 7563 | 7571 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ |
| 7564 | 7572 | int idx, /* Index of loop to report on */ |
| 7565 | 7573 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.8" |
| 111 | #define SQLITE_VERSION_NUMBER 3008008 |
| 112 | #define SQLITE_SOURCE_ID "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -7489,10 +7489,14 @@ | |
| 7489 | ** |
| 7490 | ** The following constants can be used for the T parameter to the |
| 7491 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7492 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7493 | ** |
| 7494 | ** <dl> |
| 7495 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7496 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7497 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7498 | ** |
| @@ -7534,11 +7538,18 @@ | |
| 7534 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 7535 | |
| 7536 | /* |
| 7537 | ** CAPI3REF: Prepared Statement Scan Status |
| 7538 | ** |
| 7539 | ** Return status data for a single loop within query pStmt. |
| 7540 | ** |
| 7541 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7542 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7543 | ** of this interface is undefined. |
| 7544 | ** ^The requested measurement is written into a variable pointed to by |
| @@ -7552,13 +7563,10 @@ | |
| 7552 | ** ^Statistics might not be available for all loops in all statements. ^In cases |
| 7553 | ** where there exist loops with no available statistics, this function behaves |
| 7554 | ** as if the loop did not exist - it returns non-zero and leave the variable |
| 7555 | ** that pOut points to unchanged. |
| 7556 | ** |
| 7557 | ** This API is only available if the library is built with pre-processor |
| 7558 | ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. |
| 7559 | ** |
| 7560 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 7561 | */ |
| 7562 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( |
| 7563 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ |
| 7564 | int idx, /* Index of loop to report on */ |
| 7565 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.8" |
| 111 | #define SQLITE_VERSION_NUMBER 3008008 |
| 112 | #define SQLITE_SOURCE_ID "2015-01-12 21:43:00 e693e11d1b9265974c32bddba873ea30a4d0b708" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -7489,10 +7489,14 @@ | |
| 7489 | ** |
| 7490 | ** The following constants can be used for the T parameter to the |
| 7491 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7492 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7493 | ** |
| 7494 | ** When the value returned to V is a string, space to hold that string is |
| 7495 | ** managed by the prepared statement S and will be automatically freed when |
| 7496 | ** S is finalized. |
| 7497 | ** |
| 7498 | ** <dl> |
| 7499 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7500 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7501 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7502 | ** |
| @@ -7534,11 +7538,18 @@ | |
| 7538 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 7539 | |
| 7540 | /* |
| 7541 | ** CAPI3REF: Prepared Statement Scan Status |
| 7542 | ** |
| 7543 | ** This interface returns information about the predicted and measured |
| 7544 | ** performance for pStmt. Advanced applications can use this |
| 7545 | ** interface to compare the predicted and the measured performance and |
| 7546 | ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. |
| 7547 | ** |
| 7548 | ** Since this interface is expected to be rarely used, it is only |
| 7549 | ** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] |
| 7550 | ** compile-time option. |
| 7551 | ** |
| 7552 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7553 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7554 | ** of this interface is undefined. |
| 7555 | ** ^The requested measurement is written into a variable pointed to by |
| @@ -7552,13 +7563,10 @@ | |
| 7563 | ** ^Statistics might not be available for all loops in all statements. ^In cases |
| 7564 | ** where there exist loops with no available statistics, this function behaves |
| 7565 | ** as if the loop did not exist - it returns non-zero and leave the variable |
| 7566 | ** that pOut points to unchanged. |
| 7567 | ** |
| 7568 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 7569 | */ |
| 7570 | SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus( |
| 7571 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ |
| 7572 | int idx, /* Index of loop to report on */ |
| 7573 |
+18
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1280,10 +1280,28 @@ | ||
| 1280 | 1280 | @ padding: 0px 1em 0.5ex 0px; |
| 1281 | 1281 | }, |
| 1282 | 1282 | { ".brlist table td", "Branch list table headers", |
| 1283 | 1283 | @ padding: 0px 2em 0px 0px; |
| 1284 | 1284 | }, |
| 1285 | + { "th.sort:after", | |
| 1286 | + "General styles for sortable column marker", | |
| 1287 | + @ margin-left: .4em; | |
| 1288 | + @ cursor: pointer; | |
| 1289 | + @ text-shadow: 0 0 0 #000; /* Makes arrow darker */ | |
| 1290 | + }, | |
| 1291 | + { "th.sort.none:after", | |
| 1292 | + "None sort column marker", | |
| 1293 | + @ content: '\2666'; | |
| 1294 | + }, | |
| 1295 | + { "th.sort.asc:after", | |
| 1296 | + "Ascending sort column marker", | |
| 1297 | + @ content: '\2193'; | |
| 1298 | + }, | |
| 1299 | + { "th.sort.desc:after", | |
| 1300 | + "Descending sort column marker", | |
| 1301 | + @ content: '\2191'; | |
| 1302 | + }, | |
| 1285 | 1303 | { 0, |
| 1286 | 1304 | 0, |
| 1287 | 1305 | 0 |
| 1288 | 1306 | } |
| 1289 | 1307 | }; |
| 1290 | 1308 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1280,10 +1280,28 @@ | |
| 1280 | @ padding: 0px 1em 0.5ex 0px; |
| 1281 | }, |
| 1282 | { ".brlist table td", "Branch list table headers", |
| 1283 | @ padding: 0px 2em 0px 0px; |
| 1284 | }, |
| 1285 | { 0, |
| 1286 | 0, |
| 1287 | 0 |
| 1288 | } |
| 1289 | }; |
| 1290 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1280,10 +1280,28 @@ | |
| 1280 | @ padding: 0px 1em 0.5ex 0px; |
| 1281 | }, |
| 1282 | { ".brlist table td", "Branch list table headers", |
| 1283 | @ padding: 0px 2em 0px 0px; |
| 1284 | }, |
| 1285 | { "th.sort:after", |
| 1286 | "General styles for sortable column marker", |
| 1287 | @ margin-left: .4em; |
| 1288 | @ cursor: pointer; |
| 1289 | @ text-shadow: 0 0 0 #000; /* Makes arrow darker */ |
| 1290 | }, |
| 1291 | { "th.sort.none:after", |
| 1292 | "None sort column marker", |
| 1293 | @ content: '\2666'; |
| 1294 | }, |
| 1295 | { "th.sort.asc:after", |
| 1296 | "Ascending sort column marker", |
| 1297 | @ content: '\2193'; |
| 1298 | }, |
| 1299 | { "th.sort.desc:after", |
| 1300 | "Descending sort column marker", |
| 1301 | @ content: '\2191'; |
| 1302 | }, |
| 1303 | { 0, |
| 1304 | 0, |
| 1305 | 0 |
| 1306 | } |
| 1307 | }; |
| 1308 |
+5
-5
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -48,11 +48,11 @@ | ||
| 48 | 48 | } |
| 49 | 49 | }else{ |
| 50 | 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | 51 | } |
| 52 | 52 | url_parse(0, URL_REMEMBER); |
| 53 | - if( g.url.protocol==0 ) return 0; | |
| 53 | + if( g.url.protocol==0 ) return 0; | |
| 54 | 54 | if( g.url.user!=0 && g.url.passwd==0 ){ |
| 55 | 55 | g.url.passwd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | 56 | g.url.flags |= URL_PROMPT_PW; |
| 57 | 57 | url_prompt_for_password(); |
| 58 | 58 | } |
| @@ -61,11 +61,11 @@ | ||
| 61 | 61 | #if 0 /* Disabled for now */ |
| 62 | 62 | if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){ |
| 63 | 63 | /* When doing an automatic pull, also automatically pull shuns from |
| 64 | 64 | ** the server if pull_shuns is enabled. |
| 65 | 65 | ** |
| 66 | - ** TODO: What happens if the shun list gets really big? | |
| 66 | + ** TODO: What happens if the shun list gets really big? | |
| 67 | 67 | ** Maybe the shunning list should only be pulled on every 10th |
| 68 | 68 | ** autosync, or something? |
| 69 | 69 | */ |
| 70 | 70 | configSync = CONFIGSET_SHUN; |
| 71 | 71 | } |
| @@ -186,11 +186,11 @@ | ||
| 186 | 186 | */ |
| 187 | 187 | void pull_cmd(void){ |
| 188 | 188 | unsigned configFlags = 0; |
| 189 | 189 | unsigned syncFlags = SYNC_PULL; |
| 190 | 190 | process_sync_args(&configFlags, &syncFlags); |
| 191 | - | |
| 191 | + | |
| 192 | 192 | /* We should be done with options.. */ |
| 193 | 193 | verify_all_options(); |
| 194 | 194 | |
| 195 | 195 | client_sync(syncFlags, configFlags, 0); |
| 196 | 196 | } |
| @@ -221,11 +221,11 @@ | ||
| 221 | 221 | */ |
| 222 | 222 | void push_cmd(void){ |
| 223 | 223 | unsigned configFlags = 0; |
| 224 | 224 | unsigned syncFlags = SYNC_PUSH; |
| 225 | 225 | process_sync_args(&configFlags, &syncFlags); |
| 226 | - | |
| 226 | + | |
| 227 | 227 | /* We should be done with options.. */ |
| 228 | 228 | verify_all_options(); |
| 229 | 229 | |
| 230 | 230 | if( db_get_boolean("dont-push",0) ){ |
| 231 | 231 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| @@ -261,11 +261,11 @@ | ||
| 261 | 261 | */ |
| 262 | 262 | void sync_cmd(void){ |
| 263 | 263 | unsigned configFlags = 0; |
| 264 | 264 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 265 | 265 | process_sync_args(&configFlags, &syncFlags); |
| 266 | - | |
| 266 | + | |
| 267 | 267 | /* We should be done with options.. */ |
| 268 | 268 | verify_all_options(); |
| 269 | 269 | |
| 270 | 270 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 271 | 271 | client_sync(syncFlags, configFlags, 0); |
| 272 | 272 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -48,11 +48,11 @@ | |
| 48 | } |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.url.protocol==0 ) return 0; |
| 54 | if( g.url.user!=0 && g.url.passwd==0 ){ |
| 55 | g.url.passwd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | g.url.flags |= URL_PROMPT_PW; |
| 57 | url_prompt_for_password(); |
| 58 | } |
| @@ -61,11 +61,11 @@ | |
| 61 | #if 0 /* Disabled for now */ |
| 62 | if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){ |
| 63 | /* When doing an automatic pull, also automatically pull shuns from |
| 64 | ** the server if pull_shuns is enabled. |
| 65 | ** |
| 66 | ** TODO: What happens if the shun list gets really big? |
| 67 | ** Maybe the shunning list should only be pulled on every 10th |
| 68 | ** autosync, or something? |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| @@ -186,11 +186,11 @@ | |
| 186 | */ |
| 187 | void pull_cmd(void){ |
| 188 | unsigned configFlags = 0; |
| 189 | unsigned syncFlags = SYNC_PULL; |
| 190 | process_sync_args(&configFlags, &syncFlags); |
| 191 | |
| 192 | /* We should be done with options.. */ |
| 193 | verify_all_options(); |
| 194 | |
| 195 | client_sync(syncFlags, configFlags, 0); |
| 196 | } |
| @@ -221,11 +221,11 @@ | |
| 221 | */ |
| 222 | void push_cmd(void){ |
| 223 | unsigned configFlags = 0; |
| 224 | unsigned syncFlags = SYNC_PUSH; |
| 225 | process_sync_args(&configFlags, &syncFlags); |
| 226 | |
| 227 | /* We should be done with options.. */ |
| 228 | verify_all_options(); |
| 229 | |
| 230 | if( db_get_boolean("dont-push",0) ){ |
| 231 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| @@ -261,11 +261,11 @@ | |
| 261 | */ |
| 262 | void sync_cmd(void){ |
| 263 | unsigned configFlags = 0; |
| 264 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 265 | process_sync_args(&configFlags, &syncFlags); |
| 266 | |
| 267 | /* We should be done with options.. */ |
| 268 | verify_all_options(); |
| 269 | |
| 270 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 271 | client_sync(syncFlags, configFlags, 0); |
| 272 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -48,11 +48,11 @@ | |
| 48 | } |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.url.protocol==0 ) return 0; |
| 54 | if( g.url.user!=0 && g.url.passwd==0 ){ |
| 55 | g.url.passwd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | g.url.flags |= URL_PROMPT_PW; |
| 57 | url_prompt_for_password(); |
| 58 | } |
| @@ -61,11 +61,11 @@ | |
| 61 | #if 0 /* Disabled for now */ |
| 62 | if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){ |
| 63 | /* When doing an automatic pull, also automatically pull shuns from |
| 64 | ** the server if pull_shuns is enabled. |
| 65 | ** |
| 66 | ** TODO: What happens if the shun list gets really big? |
| 67 | ** Maybe the shunning list should only be pulled on every 10th |
| 68 | ** autosync, or something? |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| @@ -186,11 +186,11 @@ | |
| 186 | */ |
| 187 | void pull_cmd(void){ |
| 188 | unsigned configFlags = 0; |
| 189 | unsigned syncFlags = SYNC_PULL; |
| 190 | process_sync_args(&configFlags, &syncFlags); |
| 191 | |
| 192 | /* We should be done with options.. */ |
| 193 | verify_all_options(); |
| 194 | |
| 195 | client_sync(syncFlags, configFlags, 0); |
| 196 | } |
| @@ -221,11 +221,11 @@ | |
| 221 | */ |
| 222 | void push_cmd(void){ |
| 223 | unsigned configFlags = 0; |
| 224 | unsigned syncFlags = SYNC_PUSH; |
| 225 | process_sync_args(&configFlags, &syncFlags); |
| 226 | |
| 227 | /* We should be done with options.. */ |
| 228 | verify_all_options(); |
| 229 | |
| 230 | if( db_get_boolean("dont-push",0) ){ |
| 231 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| @@ -261,11 +261,11 @@ | |
| 261 | */ |
| 262 | void sync_cmd(void){ |
| 263 | unsigned configFlags = 0; |
| 264 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 265 | process_sync_args(&configFlags, &syncFlags); |
| 266 | |
| 267 | /* We should be done with options.. */ |
| 268 | verify_all_options(); |
| 269 | |
| 270 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 271 | client_sync(syncFlags, configFlags, 0); |
| 272 |
+17
-17
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -34,11 +34,11 @@ | ||
| 34 | 34 | */ |
| 35 | 35 | static int internalUpdate = 0; |
| 36 | 36 | static int internalConflictCnt = 0; |
| 37 | 37 | |
| 38 | 38 | /* |
| 39 | -** Do an update to version vid. | |
| 39 | +** Do an update to version vid. | |
| 40 | 40 | ** |
| 41 | 41 | ** Start an undo session but do not terminate it. Do not autosync. |
| 42 | 42 | */ |
| 43 | 43 | int update_to(int vid){ |
| 44 | 44 | int savedArgc; |
| @@ -157,11 +157,11 @@ | ||
| 157 | 157 | if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, |
| 158 | 158 | db_get_int("autosync-tries", 1)) ){ |
| 159 | 159 | fossil_fatal("Cannot proceed with update"); |
| 160 | 160 | } |
| 161 | 161 | } |
| 162 | - | |
| 162 | + | |
| 163 | 163 | /* Create any empty directories now, as well as after the update, |
| 164 | 164 | ** so changes in settings are reflected now */ |
| 165 | 165 | if( !dryRunFlag ) ensure_empty_dirs_created(); |
| 166 | 166 | |
| 167 | 167 | if( internalUpdate ){ |
| @@ -182,11 +182,11 @@ | ||
| 182 | 182 | }else if( !is_a_version(tid) ){ |
| 183 | 183 | fossil_fatal("no such version: %s", g.argv[2]); |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | } |
| 187 | - | |
| 187 | + | |
| 188 | 188 | /* If no VERSION is specified on the command-line, then look for a |
| 189 | 189 | ** descendent of the current version. If there are multiple descendants, |
| 190 | 190 | ** look for one from the same branch as the current version. If there |
| 191 | 191 | ** are still multiple descendants, show them all and refuse to update |
| 192 | 192 | ** until the user selects one. |
| @@ -207,11 +207,11 @@ | ||
| 207 | 207 | " WHERE tagid=%d AND rid=%d))", |
| 208 | 208 | TAG_BRANCH, TAG_BRANCH, vid |
| 209 | 209 | ); |
| 210 | 210 | if( db_int(0, "SELECT count(*) FROM leaves")>1 ){ |
| 211 | 211 | compute_leaves(vid, closeCode); |
| 212 | - db_prepare(&q, | |
| 212 | + db_prepare(&q, | |
| 213 | 213 | "%s " |
| 214 | 214 | " AND event.objid IN leaves" |
| 215 | 215 | " ORDER BY event.mtime DESC", |
| 216 | 216 | timeline_query_for_tty() |
| 217 | 217 | ); |
| @@ -220,11 +220,11 @@ | ||
| 220 | 220 | fossil_fatal("Multiple descendants"); |
| 221 | 221 | } |
| 222 | 222 | } |
| 223 | 223 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 224 | 224 | " WHERE event.objid=leaves.rid" |
| 225 | - " ORDER BY event.mtime DESC"); | |
| 225 | + " ORDER BY event.mtime DESC"); | |
| 226 | 226 | if( tid==0 ) tid = vid; |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | if( tid==0 ){ |
| 230 | 230 | return; |
| @@ -357,11 +357,11 @@ | ||
| 357 | 357 | zSep = ""; |
| 358 | 358 | for(i=3; i<g.argc; i++){ |
| 359 | 359 | file_tree_name(g.argv[i], &treename, 1); |
| 360 | 360 | if( file_wd_isdir(g.argv[i])==1 ){ |
| 361 | 361 | if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){ |
| 362 | - blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", | |
| 362 | + blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", | |
| 363 | 363 | zSep /*safe-for-%s*/, blob_str(&treename)); |
| 364 | 364 | }else{ |
| 365 | 365 | blob_reset(&sql); |
| 366 | 366 | break; |
| 367 | 367 | } |
| @@ -378,11 +378,11 @@ | ||
| 378 | 378 | |
| 379 | 379 | /* |
| 380 | 380 | ** Alter the content of the checkout so that it conforms with the |
| 381 | 381 | ** target |
| 382 | 382 | */ |
| 383 | - db_prepare(&q, | |
| 383 | + db_prepare(&q, | |
| 384 | 384 | "SELECT fn, idv, ridv, idt, ridt, chnged, fnt," |
| 385 | 385 | " isexe, islinkv, islinkt, deleted FROM fv ORDER BY 1" |
| 386 | 386 | ); |
| 387 | 387 | db_prepare(&mtimeXfer, |
| 388 | 388 | "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" |
| @@ -470,11 +470,11 @@ | ||
| 470 | 470 | }else{ |
| 471 | 471 | fossil_print("MERGE %s\n", zName); |
| 472 | 472 | } |
| 473 | 473 | if( islinkv || islinkt /* || file_wd_islink(zFullPath) */ ){ |
| 474 | 474 | fossil_print("***** Cannot merge symlink %s\n", zNewName); |
| 475 | - nConflict++; | |
| 475 | + nConflict++; | |
| 476 | 476 | }else{ |
| 477 | 477 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 478 | 478 | undo_save(zName); |
| 479 | 479 | content_get(ridt, &t); |
| 480 | 480 | content_get(ridv, &v); |
| @@ -544,11 +544,11 @@ | ||
| 544 | 544 | fossil_warning("uncommitted %s against %S.", |
| 545 | 545 | zLabel, db_column_text(&q, 0)); |
| 546 | 546 | nMerge++; |
| 547 | 547 | } |
| 548 | 548 | db_finalize(&q); |
| 549 | - | |
| 549 | + | |
| 550 | 550 | if( nConflict ){ |
| 551 | 551 | if( internalUpdate ){ |
| 552 | 552 | internalConflictCnt = nConflict; |
| 553 | 553 | nConflict = 0; |
| 554 | 554 | }else{ |
| @@ -561,11 +561,11 @@ | ||
| 561 | 561 | } |
| 562 | 562 | if( nMerge ){ |
| 563 | 563 | fossil_warning("WARNING: %d uncommitted prior merges", nMerge); |
| 564 | 564 | } |
| 565 | 565 | } |
| 566 | - | |
| 566 | + | |
| 567 | 567 | /* |
| 568 | 568 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 569 | 569 | */ |
| 570 | 570 | if( dryRunFlag ){ |
| 571 | 571 | db_end_transaction(1); /* With --dry-run, rollback changes */ |
| @@ -615,27 +615,27 @@ | ||
| 615 | 615 | Blob path; |
| 616 | 616 | const char *zPath; |
| 617 | 617 | |
| 618 | 618 | blob_zero(&path); |
| 619 | 619 | blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); |
| 620 | - zPath = blob_str(&path); | |
| 620 | + zPath = blob_str(&path); | |
| 621 | 621 | /* Handle various cases of existence of the directory */ |
| 622 | 622 | switch( file_wd_isdir(zPath) ){ |
| 623 | 623 | case 0: { /* doesn't exist */ |
| 624 | 624 | if( file_mkdir(zPath, 0)!=0 ) { |
| 625 | 625 | fossil_warning("couldn't create directory %s as " |
| 626 | 626 | "required by empty-dirs setting", zDir); |
| 627 | - } | |
| 627 | + } | |
| 628 | 628 | break; |
| 629 | 629 | } |
| 630 | 630 | case 1: { /* exists, and is a directory */ |
| 631 | 631 | /* do nothing - required directory exists already */ |
| 632 | 632 | break; |
| 633 | 633 | } |
| 634 | 634 | case 2: { /* exists, but isn't a directory */ |
| 635 | 635 | fossil_warning("file %s found, but a directory is required " |
| 636 | - "by empty-dirs setting", zDir); | |
| 636 | + "by empty-dirs setting", zDir); | |
| 637 | 637 | } |
| 638 | 638 | } |
| 639 | 639 | blob_reset(&path); |
| 640 | 640 | } |
| 641 | 641 | } |
| @@ -656,11 +656,11 @@ | ||
| 656 | 656 | int errCode /* Error code if file not found. Panic if 0. */ |
| 657 | 657 | ){ |
| 658 | 658 | Manifest *pManifest; |
| 659 | 659 | ManifestFile *pFile; |
| 660 | 660 | int rid=0; |
| 661 | - | |
| 661 | + | |
| 662 | 662 | if( revision ){ |
| 663 | 663 | rid = name_to_typed_rid(revision,"ci"); |
| 664 | 664 | }else if( !g.localOpen ){ |
| 665 | 665 | rid = name_to_typed_rid(db_get("main-branch","trunk"),"ci"); |
| 666 | 666 | }else{ |
| @@ -669,11 +669,11 @@ | ||
| 669 | 669 | if( !is_a_version(rid) ){ |
| 670 | 670 | if( errCode>0 ) return errCode; |
| 671 | 671 | fossil_fatal("no such checkin: %s", revision); |
| 672 | 672 | } |
| 673 | 673 | pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0); |
| 674 | - | |
| 674 | + | |
| 675 | 675 | if( pManifest ){ |
| 676 | 676 | pFile = manifest_file_find(pManifest, file); |
| 677 | 677 | if( pFile ){ |
| 678 | 678 | int rc; |
| 679 | 679 | rid = uuid_to_rid(pFile->zUuid, 0); |
| @@ -728,14 +728,14 @@ | ||
| 728 | 728 | Blob record; |
| 729 | 729 | int i; |
| 730 | 730 | int errCode; |
| 731 | 731 | Stmt q; |
| 732 | 732 | |
| 733 | - undo_capture_command_line(); | |
| 733 | + undo_capture_command_line(); | |
| 734 | 734 | zRevision = find_option("revision", "r", 1); |
| 735 | 735 | verify_all_options(); |
| 736 | - | |
| 736 | + | |
| 737 | 737 | if( g.argc<2 ){ |
| 738 | 738 | usage("?OPTIONS? [FILE] ..."); |
| 739 | 739 | } |
| 740 | 740 | if( zRevision && g.argc<3 ){ |
| 741 | 741 | fossil_fatal("the --revision option does not work for the entire tree"); |
| 742 | 742 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | */ |
| 35 | static int internalUpdate = 0; |
| 36 | static int internalConflictCnt = 0; |
| 37 | |
| 38 | /* |
| 39 | ** Do an update to version vid. |
| 40 | ** |
| 41 | ** Start an undo session but do not terminate it. Do not autosync. |
| 42 | */ |
| 43 | int update_to(int vid){ |
| 44 | int savedArgc; |
| @@ -157,11 +157,11 @@ | |
| 157 | if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, |
| 158 | db_get_int("autosync-tries", 1)) ){ |
| 159 | fossil_fatal("Cannot proceed with update"); |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | /* Create any empty directories now, as well as after the update, |
| 164 | ** so changes in settings are reflected now */ |
| 165 | if( !dryRunFlag ) ensure_empty_dirs_created(); |
| 166 | |
| 167 | if( internalUpdate ){ |
| @@ -182,11 +182,11 @@ | |
| 182 | }else if( !is_a_version(tid) ){ |
| 183 | fossil_fatal("no such version: %s", g.argv[2]); |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | /* If no VERSION is specified on the command-line, then look for a |
| 189 | ** descendent of the current version. If there are multiple descendants, |
| 190 | ** look for one from the same branch as the current version. If there |
| 191 | ** are still multiple descendants, show them all and refuse to update |
| 192 | ** until the user selects one. |
| @@ -207,11 +207,11 @@ | |
| 207 | " WHERE tagid=%d AND rid=%d))", |
| 208 | TAG_BRANCH, TAG_BRANCH, vid |
| 209 | ); |
| 210 | if( db_int(0, "SELECT count(*) FROM leaves")>1 ){ |
| 211 | compute_leaves(vid, closeCode); |
| 212 | db_prepare(&q, |
| 213 | "%s " |
| 214 | " AND event.objid IN leaves" |
| 215 | " ORDER BY event.mtime DESC", |
| 216 | timeline_query_for_tty() |
| 217 | ); |
| @@ -220,11 +220,11 @@ | |
| 220 | fossil_fatal("Multiple descendants"); |
| 221 | } |
| 222 | } |
| 223 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 224 | " WHERE event.objid=leaves.rid" |
| 225 | " ORDER BY event.mtime DESC"); |
| 226 | if( tid==0 ) tid = vid; |
| 227 | } |
| 228 | |
| 229 | if( tid==0 ){ |
| 230 | return; |
| @@ -357,11 +357,11 @@ | |
| 357 | zSep = ""; |
| 358 | for(i=3; i<g.argc; i++){ |
| 359 | file_tree_name(g.argv[i], &treename, 1); |
| 360 | if( file_wd_isdir(g.argv[i])==1 ){ |
| 361 | if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){ |
| 362 | blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", |
| 363 | zSep /*safe-for-%s*/, blob_str(&treename)); |
| 364 | }else{ |
| 365 | blob_reset(&sql); |
| 366 | break; |
| 367 | } |
| @@ -378,11 +378,11 @@ | |
| 378 | |
| 379 | /* |
| 380 | ** Alter the content of the checkout so that it conforms with the |
| 381 | ** target |
| 382 | */ |
| 383 | db_prepare(&q, |
| 384 | "SELECT fn, idv, ridv, idt, ridt, chnged, fnt," |
| 385 | " isexe, islinkv, islinkt, deleted FROM fv ORDER BY 1" |
| 386 | ); |
| 387 | db_prepare(&mtimeXfer, |
| 388 | "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" |
| @@ -470,11 +470,11 @@ | |
| 470 | }else{ |
| 471 | fossil_print("MERGE %s\n", zName); |
| 472 | } |
| 473 | if( islinkv || islinkt /* || file_wd_islink(zFullPath) */ ){ |
| 474 | fossil_print("***** Cannot merge symlink %s\n", zNewName); |
| 475 | nConflict++; |
| 476 | }else{ |
| 477 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 478 | undo_save(zName); |
| 479 | content_get(ridt, &t); |
| 480 | content_get(ridv, &v); |
| @@ -544,11 +544,11 @@ | |
| 544 | fossil_warning("uncommitted %s against %S.", |
| 545 | zLabel, db_column_text(&q, 0)); |
| 546 | nMerge++; |
| 547 | } |
| 548 | db_finalize(&q); |
| 549 | |
| 550 | if( nConflict ){ |
| 551 | if( internalUpdate ){ |
| 552 | internalConflictCnt = nConflict; |
| 553 | nConflict = 0; |
| 554 | }else{ |
| @@ -561,11 +561,11 @@ | |
| 561 | } |
| 562 | if( nMerge ){ |
| 563 | fossil_warning("WARNING: %d uncommitted prior merges", nMerge); |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | /* |
| 568 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 569 | */ |
| 570 | if( dryRunFlag ){ |
| 571 | db_end_transaction(1); /* With --dry-run, rollback changes */ |
| @@ -615,27 +615,27 @@ | |
| 615 | Blob path; |
| 616 | const char *zPath; |
| 617 | |
| 618 | blob_zero(&path); |
| 619 | blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); |
| 620 | zPath = blob_str(&path); |
| 621 | /* Handle various cases of existence of the directory */ |
| 622 | switch( file_wd_isdir(zPath) ){ |
| 623 | case 0: { /* doesn't exist */ |
| 624 | if( file_mkdir(zPath, 0)!=0 ) { |
| 625 | fossil_warning("couldn't create directory %s as " |
| 626 | "required by empty-dirs setting", zDir); |
| 627 | } |
| 628 | break; |
| 629 | } |
| 630 | case 1: { /* exists, and is a directory */ |
| 631 | /* do nothing - required directory exists already */ |
| 632 | break; |
| 633 | } |
| 634 | case 2: { /* exists, but isn't a directory */ |
| 635 | fossil_warning("file %s found, but a directory is required " |
| 636 | "by empty-dirs setting", zDir); |
| 637 | } |
| 638 | } |
| 639 | blob_reset(&path); |
| 640 | } |
| 641 | } |
| @@ -656,11 +656,11 @@ | |
| 656 | int errCode /* Error code if file not found. Panic if 0. */ |
| 657 | ){ |
| 658 | Manifest *pManifest; |
| 659 | ManifestFile *pFile; |
| 660 | int rid=0; |
| 661 | |
| 662 | if( revision ){ |
| 663 | rid = name_to_typed_rid(revision,"ci"); |
| 664 | }else if( !g.localOpen ){ |
| 665 | rid = name_to_typed_rid(db_get("main-branch","trunk"),"ci"); |
| 666 | }else{ |
| @@ -669,11 +669,11 @@ | |
| 669 | if( !is_a_version(rid) ){ |
| 670 | if( errCode>0 ) return errCode; |
| 671 | fossil_fatal("no such checkin: %s", revision); |
| 672 | } |
| 673 | pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0); |
| 674 | |
| 675 | if( pManifest ){ |
| 676 | pFile = manifest_file_find(pManifest, file); |
| 677 | if( pFile ){ |
| 678 | int rc; |
| 679 | rid = uuid_to_rid(pFile->zUuid, 0); |
| @@ -728,14 +728,14 @@ | |
| 728 | Blob record; |
| 729 | int i; |
| 730 | int errCode; |
| 731 | Stmt q; |
| 732 | |
| 733 | undo_capture_command_line(); |
| 734 | zRevision = find_option("revision", "r", 1); |
| 735 | verify_all_options(); |
| 736 | |
| 737 | if( g.argc<2 ){ |
| 738 | usage("?OPTIONS? [FILE] ..."); |
| 739 | } |
| 740 | if( zRevision && g.argc<3 ){ |
| 741 | fossil_fatal("the --revision option does not work for the entire tree"); |
| 742 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -34,11 +34,11 @@ | |
| 34 | */ |
| 35 | static int internalUpdate = 0; |
| 36 | static int internalConflictCnt = 0; |
| 37 | |
| 38 | /* |
| 39 | ** Do an update to version vid. |
| 40 | ** |
| 41 | ** Start an undo session but do not terminate it. Do not autosync. |
| 42 | */ |
| 43 | int update_to(int vid){ |
| 44 | int savedArgc; |
| @@ -157,11 +157,11 @@ | |
| 157 | if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, |
| 158 | db_get_int("autosync-tries", 1)) ){ |
| 159 | fossil_fatal("Cannot proceed with update"); |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | /* Create any empty directories now, as well as after the update, |
| 164 | ** so changes in settings are reflected now */ |
| 165 | if( !dryRunFlag ) ensure_empty_dirs_created(); |
| 166 | |
| 167 | if( internalUpdate ){ |
| @@ -182,11 +182,11 @@ | |
| 182 | }else if( !is_a_version(tid) ){ |
| 183 | fossil_fatal("no such version: %s", g.argv[2]); |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | |
| 188 | /* If no VERSION is specified on the command-line, then look for a |
| 189 | ** descendent of the current version. If there are multiple descendants, |
| 190 | ** look for one from the same branch as the current version. If there |
| 191 | ** are still multiple descendants, show them all and refuse to update |
| 192 | ** until the user selects one. |
| @@ -207,11 +207,11 @@ | |
| 207 | " WHERE tagid=%d AND rid=%d))", |
| 208 | TAG_BRANCH, TAG_BRANCH, vid |
| 209 | ); |
| 210 | if( db_int(0, "SELECT count(*) FROM leaves")>1 ){ |
| 211 | compute_leaves(vid, closeCode); |
| 212 | db_prepare(&q, |
| 213 | "%s " |
| 214 | " AND event.objid IN leaves" |
| 215 | " ORDER BY event.mtime DESC", |
| 216 | timeline_query_for_tty() |
| 217 | ); |
| @@ -220,11 +220,11 @@ | |
| 220 | fossil_fatal("Multiple descendants"); |
| 221 | } |
| 222 | } |
| 223 | tid = db_int(0, "SELECT rid FROM leaves, event" |
| 224 | " WHERE event.objid=leaves.rid" |
| 225 | " ORDER BY event.mtime DESC"); |
| 226 | if( tid==0 ) tid = vid; |
| 227 | } |
| 228 | |
| 229 | if( tid==0 ){ |
| 230 | return; |
| @@ -357,11 +357,11 @@ | |
| 357 | zSep = ""; |
| 358 | for(i=3; i<g.argc; i++){ |
| 359 | file_tree_name(g.argv[i], &treename, 1); |
| 360 | if( file_wd_isdir(g.argv[i])==1 ){ |
| 361 | if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){ |
| 362 | blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ", |
| 363 | zSep /*safe-for-%s*/, blob_str(&treename)); |
| 364 | }else{ |
| 365 | blob_reset(&sql); |
| 366 | break; |
| 367 | } |
| @@ -378,11 +378,11 @@ | |
| 378 | |
| 379 | /* |
| 380 | ** Alter the content of the checkout so that it conforms with the |
| 381 | ** target |
| 382 | */ |
| 383 | db_prepare(&q, |
| 384 | "SELECT fn, idv, ridv, idt, ridt, chnged, fnt," |
| 385 | " isexe, islinkv, islinkt, deleted FROM fv ORDER BY 1" |
| 386 | ); |
| 387 | db_prepare(&mtimeXfer, |
| 388 | "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" |
| @@ -470,11 +470,11 @@ | |
| 470 | }else{ |
| 471 | fossil_print("MERGE %s\n", zName); |
| 472 | } |
| 473 | if( islinkv || islinkt /* || file_wd_islink(zFullPath) */ ){ |
| 474 | fossil_print("***** Cannot merge symlink %s\n", zNewName); |
| 475 | nConflict++; |
| 476 | }else{ |
| 477 | unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0; |
| 478 | undo_save(zName); |
| 479 | content_get(ridt, &t); |
| 480 | content_get(ridv, &v); |
| @@ -544,11 +544,11 @@ | |
| 544 | fossil_warning("uncommitted %s against %S.", |
| 545 | zLabel, db_column_text(&q, 0)); |
| 546 | nMerge++; |
| 547 | } |
| 548 | db_finalize(&q); |
| 549 | |
| 550 | if( nConflict ){ |
| 551 | if( internalUpdate ){ |
| 552 | internalConflictCnt = nConflict; |
| 553 | nConflict = 0; |
| 554 | }else{ |
| @@ -561,11 +561,11 @@ | |
| 561 | } |
| 562 | if( nMerge ){ |
| 563 | fossil_warning("WARNING: %d uncommitted prior merges", nMerge); |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | /* |
| 568 | ** Clean up the mid and pid VFILE entries. Then commit the changes. |
| 569 | */ |
| 570 | if( dryRunFlag ){ |
| 571 | db_end_transaction(1); /* With --dry-run, rollback changes */ |
| @@ -615,27 +615,27 @@ | |
| 615 | Blob path; |
| 616 | const char *zPath; |
| 617 | |
| 618 | blob_zero(&path); |
| 619 | blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir); |
| 620 | zPath = blob_str(&path); |
| 621 | /* Handle various cases of existence of the directory */ |
| 622 | switch( file_wd_isdir(zPath) ){ |
| 623 | case 0: { /* doesn't exist */ |
| 624 | if( file_mkdir(zPath, 0)!=0 ) { |
| 625 | fossil_warning("couldn't create directory %s as " |
| 626 | "required by empty-dirs setting", zDir); |
| 627 | } |
| 628 | break; |
| 629 | } |
| 630 | case 1: { /* exists, and is a directory */ |
| 631 | /* do nothing - required directory exists already */ |
| 632 | break; |
| 633 | } |
| 634 | case 2: { /* exists, but isn't a directory */ |
| 635 | fossil_warning("file %s found, but a directory is required " |
| 636 | "by empty-dirs setting", zDir); |
| 637 | } |
| 638 | } |
| 639 | blob_reset(&path); |
| 640 | } |
| 641 | } |
| @@ -656,11 +656,11 @@ | |
| 656 | int errCode /* Error code if file not found. Panic if 0. */ |
| 657 | ){ |
| 658 | Manifest *pManifest; |
| 659 | ManifestFile *pFile; |
| 660 | int rid=0; |
| 661 | |
| 662 | if( revision ){ |
| 663 | rid = name_to_typed_rid(revision,"ci"); |
| 664 | }else if( !g.localOpen ){ |
| 665 | rid = name_to_typed_rid(db_get("main-branch","trunk"),"ci"); |
| 666 | }else{ |
| @@ -669,11 +669,11 @@ | |
| 669 | if( !is_a_version(rid) ){ |
| 670 | if( errCode>0 ) return errCode; |
| 671 | fossil_fatal("no such checkin: %s", revision); |
| 672 | } |
| 673 | pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0); |
| 674 | |
| 675 | if( pManifest ){ |
| 676 | pFile = manifest_file_find(pManifest, file); |
| 677 | if( pFile ){ |
| 678 | int rc; |
| 679 | rid = uuid_to_rid(pFile->zUuid, 0); |
| @@ -728,14 +728,14 @@ | |
| 728 | Blob record; |
| 729 | int i; |
| 730 | int errCode; |
| 731 | Stmt q; |
| 732 | |
| 733 | undo_capture_command_line(); |
| 734 | zRevision = find_option("revision", "r", 1); |
| 735 | verify_all_options(); |
| 736 | |
| 737 | if( g.argc<2 ){ |
| 738 | usage("?OPTIONS? [FILE] ..."); |
| 739 | } |
| 740 | if( zRevision && g.argc<3 ){ |
| 741 | fossil_fatal("the --revision option does not work for the entire tree"); |
| 742 |
+2
-2
| --- src/verify.c | ||
| +++ src/verify.c | ||
| @@ -63,11 +63,11 @@ | ||
| 63 | 63 | */ |
| 64 | 64 | static Bag toVerify; |
| 65 | 65 | static int inFinalVerify = 0; |
| 66 | 66 | |
| 67 | 67 | /* |
| 68 | -** This routine is called just prior to each commit operation. | |
| 68 | +** This routine is called just prior to each commit operation. | |
| 69 | 69 | ** |
| 70 | 70 | ** Invoke verify_rid() on every record that has been added or modified |
| 71 | 71 | ** in the repository, in order to make sure that the repository is sane. |
| 72 | 72 | */ |
| 73 | 73 | static int verify_at_commit(void){ |
| @@ -84,11 +84,11 @@ | ||
| 84 | 84 | return 0; |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | /* |
| 88 | 88 | ** Arrange to verify a particular record prior to committing. |
| 89 | -** | |
| 89 | +** | |
| 90 | 90 | ** If the record rid is less than 1, then just initialize the |
| 91 | 91 | ** verification system but do not record anything as needing |
| 92 | 92 | ** verification. |
| 93 | 93 | */ |
| 94 | 94 | void verify_before_commit(int rid){ |
| 95 | 95 |
| --- src/verify.c | |
| +++ src/verify.c | |
| @@ -63,11 +63,11 @@ | |
| 63 | */ |
| 64 | static Bag toVerify; |
| 65 | static int inFinalVerify = 0; |
| 66 | |
| 67 | /* |
| 68 | ** This routine is called just prior to each commit operation. |
| 69 | ** |
| 70 | ** Invoke verify_rid() on every record that has been added or modified |
| 71 | ** in the repository, in order to make sure that the repository is sane. |
| 72 | */ |
| 73 | static int verify_at_commit(void){ |
| @@ -84,11 +84,11 @@ | |
| 84 | return 0; |
| 85 | } |
| 86 | |
| 87 | /* |
| 88 | ** Arrange to verify a particular record prior to committing. |
| 89 | ** |
| 90 | ** If the record rid is less than 1, then just initialize the |
| 91 | ** verification system but do not record anything as needing |
| 92 | ** verification. |
| 93 | */ |
| 94 | void verify_before_commit(int rid){ |
| 95 |
| --- src/verify.c | |
| +++ src/verify.c | |
| @@ -63,11 +63,11 @@ | |
| 63 | */ |
| 64 | static Bag toVerify; |
| 65 | static int inFinalVerify = 0; |
| 66 | |
| 67 | /* |
| 68 | ** This routine is called just prior to each commit operation. |
| 69 | ** |
| 70 | ** Invoke verify_rid() on every record that has been added or modified |
| 71 | ** in the repository, in order to make sure that the repository is sane. |
| 72 | */ |
| 73 | static int verify_at_commit(void){ |
| @@ -84,11 +84,11 @@ | |
| 84 | return 0; |
| 85 | } |
| 86 | |
| 87 | /* |
| 88 | ** Arrange to verify a particular record prior to committing. |
| 89 | ** |
| 90 | ** If the record rid is less than 1, then just initialize the |
| 91 | ** verification system but do not record anything as needing |
| 92 | ** verification. |
| 93 | */ |
| 94 | void verify_before_commit(int rid){ |
| 95 |
+2
-2
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -146,12 +146,12 @@ | ||
| 146 | 146 | #### The directories where the OpenSSL include and library files are located. |
| 147 | 147 | # The recommended usage here is to use the Sysinternals junction tool |
| 148 | 148 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 149 | 149 | # Fossil source code directory and the target OpenSSL source directory. |
| 150 | 150 | # |
| 151 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include | |
| 152 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j | |
| 151 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1k/include | |
| 152 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1k | |
| 153 | 153 | |
| 154 | 154 | #### Either the directory where the Tcl library is installed or the Tcl |
| 155 | 155 | # source code directory resides (depending on the value of the macro |
| 156 | 156 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 157 | 157 | # this directory must have "include" and "lib" sub-directories. If |
| 158 | 158 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -146,12 +146,12 @@ | |
| 146 | #### The directories where the OpenSSL include and library files are located. |
| 147 | # The recommended usage here is to use the Sysinternals junction tool |
| 148 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 149 | # Fossil source code directory and the target OpenSSL source directory. |
| 150 | # |
| 151 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include |
| 152 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j |
| 153 | |
| 154 | #### Either the directory where the Tcl library is installed or the Tcl |
| 155 | # source code directory resides (depending on the value of the macro |
| 156 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 157 | # this directory must have "include" and "lib" sub-directories. If |
| 158 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -146,12 +146,12 @@ | |
| 146 | #### The directories where the OpenSSL include and library files are located. |
| 147 | # The recommended usage here is to use the Sysinternals junction tool |
| 148 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 149 | # Fossil source code directory and the target OpenSSL source directory. |
| 150 | # |
| 151 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1k/include |
| 152 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1k |
| 153 | |
| 154 | #### Either the directory where the Tcl library is installed or the Tcl |
| 155 | # source code directory resides (depending on the value of the macro |
| 156 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 157 | # this directory must have "include" and "lib" sub-directories. If |
| 158 |
+2
-2
| --- win/Makefile.mingw.mistachkin | ||
| +++ win/Makefile.mingw.mistachkin | ||
| @@ -146,12 +146,12 @@ | ||
| 146 | 146 | #### The directories where the OpenSSL include and library files are located. |
| 147 | 147 | # The recommended usage here is to use the Sysinternals junction tool |
| 148 | 148 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 149 | 149 | # Fossil source code directory and the target OpenSSL source directory. |
| 150 | 150 | # |
| 151 | -OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include | |
| 152 | -OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j | |
| 151 | +OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1k/include | |
| 152 | +OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1k | |
| 153 | 153 | |
| 154 | 154 | #### Either the directory where the Tcl library is installed or the Tcl |
| 155 | 155 | # source code directory resides (depending on the value of the macro |
| 156 | 156 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 157 | 157 | # this directory must have "include" and "lib" sub-directories. If |
| 158 | 158 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -146,12 +146,12 @@ | |
| 146 | #### The directories where the OpenSSL include and library files are located. |
| 147 | # The recommended usage here is to use the Sysinternals junction tool |
| 148 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 149 | # Fossil source code directory and the target OpenSSL source directory. |
| 150 | # |
| 151 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1j/include |
| 152 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1j |
| 153 | |
| 154 | #### Either the directory where the Tcl library is installed or the Tcl |
| 155 | # source code directory resides (depending on the value of the macro |
| 156 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 157 | # this directory must have "include" and "lib" sub-directories. If |
| 158 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -146,12 +146,12 @@ | |
| 146 | #### The directories where the OpenSSL include and library files are located. |
| 147 | # The recommended usage here is to use the Sysinternals junction tool |
| 148 | # to create a hard link between an "openssl-1.x" sub-directory of the |
| 149 | # Fossil source code directory and the target OpenSSL source directory. |
| 150 | # |
| 151 | OPENSSLINCDIR = $(SRCDIR)/../compat/openssl-1.0.1k/include |
| 152 | OPENSSLLIBDIR = $(SRCDIR)/../compat/openssl-1.0.1k |
| 153 | |
| 154 | #### Either the directory where the Tcl library is installed or the Tcl |
| 155 | # source code directory resides (depending on the value of the macro |
| 156 | # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, |
| 157 | # this directory must have "include" and "lib" sub-directories. If |
| 158 |
+1
-1
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -55,11 +55,11 @@ | ||
| 55 | 55 | |
| 56 | 56 | # Uncomment to enable Tcl support |
| 57 | 57 | # FOSSIL_ENABLE_TCL = 1 |
| 58 | 58 | |
| 59 | 59 | !ifdef FOSSIL_ENABLE_SSL |
| 60 | -SSLDIR = $(B)\compat\openssl-1.0.1j | |
| 60 | +SSLDIR = $(B)\compat\openssl-1.0.1k | |
| 61 | 61 | SSLINCDIR = $(SSLDIR)\inc32 |
| 62 | 62 | SSLLIBDIR = $(SSLDIR)\out32 |
| 63 | 63 | SSLLFLAGS = /nologo /opt:ref /debug |
| 64 | 64 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 65 | 65 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 66 | 66 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -55,11 +55,11 @@ | |
| 55 | |
| 56 | # Uncomment to enable Tcl support |
| 57 | # FOSSIL_ENABLE_TCL = 1 |
| 58 | |
| 59 | !ifdef FOSSIL_ENABLE_SSL |
| 60 | SSLDIR = $(B)\compat\openssl-1.0.1j |
| 61 | SSLINCDIR = $(SSLDIR)\inc32 |
| 62 | SSLLIBDIR = $(SSLDIR)\out32 |
| 63 | SSLLFLAGS = /nologo /opt:ref /debug |
| 64 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 65 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 66 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -55,11 +55,11 @@ | |
| 55 | |
| 56 | # Uncomment to enable Tcl support |
| 57 | # FOSSIL_ENABLE_TCL = 1 |
| 58 | |
| 59 | !ifdef FOSSIL_ENABLE_SSL |
| 60 | SSLDIR = $(B)\compat\openssl-1.0.1k |
| 61 | SSLINCDIR = $(SSLDIR)\inc32 |
| 62 | SSLLIBDIR = $(SSLDIR)\out32 |
| 63 | SSLLFLAGS = /nologo /opt:ref /debug |
| 64 | SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib |
| 65 | !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" |
| 66 |
+1
-1
| --- www/build.wiki | ||
| +++ www/build.wiki | ||
| @@ -122,11 +122,11 @@ | ||
| 122 | 122 | the optional <a href="https://www.openssl.org/">OpenSSL</a> support, |
| 123 | 123 | first <a href="https://www.openssl.org/source/">download the official |
| 124 | 124 | source code for OpenSSL</a> and extract it to an appropriately named |
| 125 | 125 | "<b>openssl-X.Y.ZA</b>" subdirectory within the local |
| 126 | 126 | [/tree?ci=trunk&name=compat | compat] directory (e.g. |
| 127 | -"<b>compat/openssl-1.0.1j</b>"), then make sure that some recent | |
| 127 | +"<b>compat/openssl-1.0.1k</b>"), then make sure that some recent | |
| 128 | 128 | <a href="http://www.perl.org/">Perl</a> binaries are installed locally, |
| 129 | 129 | and finally run one of the following commands: |
| 130 | 130 | <blockquote><pre> |
| 131 | 131 | nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin |
| 132 | 132 | </pre></blockquote> |
| 133 | 133 |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -122,11 +122,11 @@ | |
| 122 | the optional <a href="https://www.openssl.org/">OpenSSL</a> support, |
| 123 | first <a href="https://www.openssl.org/source/">download the official |
| 124 | source code for OpenSSL</a> and extract it to an appropriately named |
| 125 | "<b>openssl-X.Y.ZA</b>" subdirectory within the local |
| 126 | [/tree?ci=trunk&name=compat | compat] directory (e.g. |
| 127 | "<b>compat/openssl-1.0.1j</b>"), then make sure that some recent |
| 128 | <a href="http://www.perl.org/">Perl</a> binaries are installed locally, |
| 129 | and finally run one of the following commands: |
| 130 | <blockquote><pre> |
| 131 | nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin |
| 132 | </pre></blockquote> |
| 133 |
| --- www/build.wiki | |
| +++ www/build.wiki | |
| @@ -122,11 +122,11 @@ | |
| 122 | the optional <a href="https://www.openssl.org/">OpenSSL</a> support, |
| 123 | first <a href="https://www.openssl.org/source/">download the official |
| 124 | source code for OpenSSL</a> and extract it to an appropriately named |
| 125 | "<b>openssl-X.Y.ZA</b>" subdirectory within the local |
| 126 | [/tree?ci=trunk&name=compat | compat] directory (e.g. |
| 127 | "<b>compat/openssl-1.0.1k</b>"), then make sure that some recent |
| 128 | <a href="http://www.perl.org/">Perl</a> binaries are installed locally, |
| 129 | and finally run one of the following commands: |
| 130 | <blockquote><pre> |
| 131 | nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin |
| 132 | </pre></blockquote> |
| 133 |
+2
-2
| --- www/delta_format.wiki | ||
| +++ www/delta_format.wiki | ||
| @@ -66,11 +66,11 @@ | ||
| 66 | 66 | <a name="slist"></a><h3>1.3 Segment-List</h3> |
| 67 | 67 | <img src="delta2.gif" align="left" hspace="10"> |
| 68 | 68 | |
| 69 | 69 | <p>The segment-list of a delta describes how to create the target from |
| 70 | 70 | the original by a combination of inserting literal byte-sequences and |
| 71 | -copying ranges of bytes from the original. This is there the | |
| 71 | +copying ranges of bytes from the original. This is where the | |
| 72 | 72 | compression takes place, by encoding the large common parts of |
| 73 | 73 | original and target in small copy instructions.</p> |
| 74 | 74 | |
| 75 | 75 | <p>The target is constructed from beginning to end, with the data |
| 76 | 76 | generated by each instruction appended after the data of all previous |
| @@ -213,11 +213,11 @@ | ||
| 213 | 213 | <ul> |
| 214 | 214 | <li>Pure text files generate a pure text delta. |
| 215 | 215 | </li> |
| 216 | 216 | <li>Binary files generate a delta that may contain some binary data. |
| 217 | 217 | </li> |
| 218 | -<li>The delta encoding does not attempt to compress the content | |
| 218 | +<li>The delta encoding does not attempt to compress the content. | |
| 219 | 219 | It was considered to be much |
| 220 | 220 | more sensible to do compression using a separate general-purpose |
| 221 | 221 | compression library, like <a href="http://www.zlib.net">zlib</a>. |
| 222 | 222 | </li> |
| 223 | 223 | </ul> |
| 224 | 224 |
| --- www/delta_format.wiki | |
| +++ www/delta_format.wiki | |
| @@ -66,11 +66,11 @@ | |
| 66 | <a name="slist"></a><h3>1.3 Segment-List</h3> |
| 67 | <img src="delta2.gif" align="left" hspace="10"> |
| 68 | |
| 69 | <p>The segment-list of a delta describes how to create the target from |
| 70 | the original by a combination of inserting literal byte-sequences and |
| 71 | copying ranges of bytes from the original. This is there the |
| 72 | compression takes place, by encoding the large common parts of |
| 73 | original and target in small copy instructions.</p> |
| 74 | |
| 75 | <p>The target is constructed from beginning to end, with the data |
| 76 | generated by each instruction appended after the data of all previous |
| @@ -213,11 +213,11 @@ | |
| 213 | <ul> |
| 214 | <li>Pure text files generate a pure text delta. |
| 215 | </li> |
| 216 | <li>Binary files generate a delta that may contain some binary data. |
| 217 | </li> |
| 218 | <li>The delta encoding does not attempt to compress the content |
| 219 | It was considered to be much |
| 220 | more sensible to do compression using a separate general-purpose |
| 221 | compression library, like <a href="http://www.zlib.net">zlib</a>. |
| 222 | </li> |
| 223 | </ul> |
| 224 |
| --- www/delta_format.wiki | |
| +++ www/delta_format.wiki | |
| @@ -66,11 +66,11 @@ | |
| 66 | <a name="slist"></a><h3>1.3 Segment-List</h3> |
| 67 | <img src="delta2.gif" align="left" hspace="10"> |
| 68 | |
| 69 | <p>The segment-list of a delta describes how to create the target from |
| 70 | the original by a combination of inserting literal byte-sequences and |
| 71 | copying ranges of bytes from the original. This is where the |
| 72 | compression takes place, by encoding the large common parts of |
| 73 | original and target in small copy instructions.</p> |
| 74 | |
| 75 | <p>The target is constructed from beginning to end, with the data |
| 76 | generated by each instruction appended after the data of all previous |
| @@ -213,11 +213,11 @@ | |
| 213 | <ul> |
| 214 | <li>Pure text files generate a pure text delta. |
| 215 | </li> |
| 216 | <li>Binary files generate a delta that may contain some binary data. |
| 217 | </li> |
| 218 | <li>The delta encoding does not attempt to compress the content. |
| 219 | It was considered to be much |
| 220 | more sensible to do compression using a separate general-purpose |
| 221 | compression library, like <a href="http://www.zlib.net">zlib</a>. |
| 222 | </li> |
| 223 | </ul> |
| 224 |
+2
-1
| --- www/hints.wiki | ||
| +++ www/hints.wiki | ||
| @@ -9,11 +9,12 @@ | ||
| 9 | 9 | window is run as a separate Tcl/Tk process, so you will need to |
| 10 | 10 | have Tcl/Tk installed on your machine for this to work. Visit |
| 11 | 11 | [http://www.activestate.com/activetcl] to for a quick download of |
| 12 | 12 | Tcl/Tk if you do not already have it on your system.) |
| 13 | 13 | |
| 14 | - 3. The "[/help?cmd=clean | fossil clean -f]" command makes a great | |
| 14 | + 3. The "[/help/clean | fossil clean -f]" or | |
| 15 | + "[/help/clean | fossil clean --verily]" command is a great | |
| 15 | 16 | alternative to "make clean". |
| 16 | 17 | |
| 17 | 18 | 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted |
| 18 | 19 | edits in any of your Fossil projects. Use |
| 19 | 20 | "[/help?cmd=all | fossil all pull]" on your laptop |
| 20 | 21 |
| --- www/hints.wiki | |
| +++ www/hints.wiki | |
| @@ -9,11 +9,12 @@ | |
| 9 | window is run as a separate Tcl/Tk process, so you will need to |
| 10 | have Tcl/Tk installed on your machine for this to work. Visit |
| 11 | [http://www.activestate.com/activetcl] to for a quick download of |
| 12 | Tcl/Tk if you do not already have it on your system.) |
| 13 | |
| 14 | 3. The "[/help?cmd=clean | fossil clean -f]" command makes a great |
| 15 | alternative to "make clean". |
| 16 | |
| 17 | 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted |
| 18 | edits in any of your Fossil projects. Use |
| 19 | "[/help?cmd=all | fossil all pull]" on your laptop |
| 20 |
| --- www/hints.wiki | |
| +++ www/hints.wiki | |
| @@ -9,11 +9,12 @@ | |
| 9 | window is run as a separate Tcl/Tk process, so you will need to |
| 10 | have Tcl/Tk installed on your machine for this to work. Visit |
| 11 | [http://www.activestate.com/activetcl] to for a quick download of |
| 12 | Tcl/Tk if you do not already have it on your system.) |
| 13 | |
| 14 | 3. The "[/help/clean | fossil clean -f]" or |
| 15 | "[/help/clean | fossil clean --verily]" command is a great |
| 16 | alternative to "make clean". |
| 17 | |
| 18 | 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted |
| 19 | edits in any of your Fossil projects. Use |
| 20 | "[/help?cmd=all | fossil all pull]" on your laptop |
| 21 |
+3
-1
| --- www/qandc.wiki | ||
| +++ www/qandc.wiki | ||
| @@ -146,11 +146,13 @@ | ||
| 146 | 146 | You do not need any other packages |
| 147 | 147 | (diff, patch, merge, cvs, svn, rcs, git, python, perl, tcl, apache, |
| 148 | 148 | sqlite, and so forth) |
| 149 | 149 | in order to run fossil. Fossil runs just fine in a chroot jail all |
| 150 | 150 | by itself. And the self-contained fossil |
| 151 | -executable is much less than 1MB in size. | |
| 151 | +executable is much less than 1MB in size. (Update 2015-01-12: Fossil has | |
| 152 | +grown in the years since the previous sentence was written but is still | |
| 153 | +much less than 2MB according to "size" when compiled using -Os on x64 Linux.) | |
| 152 | 154 | Fossil is the very opposite of bloat.</p> |
| 153 | 155 | </blockquote> |
| 154 | 156 | |
| 155 | 157 | |
| 156 | 158 | </nowiki> |
| 157 | 159 |
| --- www/qandc.wiki | |
| +++ www/qandc.wiki | |
| @@ -146,11 +146,13 @@ | |
| 146 | You do not need any other packages |
| 147 | (diff, patch, merge, cvs, svn, rcs, git, python, perl, tcl, apache, |
| 148 | sqlite, and so forth) |
| 149 | in order to run fossil. Fossil runs just fine in a chroot jail all |
| 150 | by itself. And the self-contained fossil |
| 151 | executable is much less than 1MB in size. |
| 152 | Fossil is the very opposite of bloat.</p> |
| 153 | </blockquote> |
| 154 | |
| 155 | |
| 156 | </nowiki> |
| 157 |
| --- www/qandc.wiki | |
| +++ www/qandc.wiki | |
| @@ -146,11 +146,13 @@ | |
| 146 | You do not need any other packages |
| 147 | (diff, patch, merge, cvs, svn, rcs, git, python, perl, tcl, apache, |
| 148 | sqlite, and so forth) |
| 149 | in order to run fossil. Fossil runs just fine in a chroot jail all |
| 150 | by itself. And the self-contained fossil |
| 151 | executable is much less than 1MB in size. (Update 2015-01-12: Fossil has |
| 152 | grown in the years since the previous sentence was written but is still |
| 153 | much less than 2MB according to "size" when compiled using -Os on x64 Linux.) |
| 154 | Fossil is the very opposite of bloat.</p> |
| 155 | </blockquote> |
| 156 | |
| 157 | |
| 158 | </nowiki> |
| 159 |