Fossil SCM
Merge cleanX
Commit
ac1fc1c675cf65dbe90fe709beeb1a1581bbe7f8
Parent
8e94814d8fdab83…
43 files changed
+26
+7
-16
+6
-6
+6
-6
+6
-6
+35
-14
+35
-14
+1
-1
+4
-4
+1
-1
+25
-5
+4
-4
-19
+5
-5
+7
-2
+5
-5
+1
-1
+3
-3
+6
-6
+1
-1
+1
-1
+5
-5
+2
-2
+2
-2
+270
-129
+30
-1
+322
-210
+13
-5
+4
+5
-5
-1
+17
-17
+2
-2
+1
-1
+12
-11
+2
-2
+2
-2
+1
-1
+1
-1
+55
-13
+2
-2
+2
-1
+3
-1
~
.dockerignore
~
Dockerfile
~
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/foci.c
~
src/fusefs.c
~
src/glob.c
~
src/graph.c
~
src/http.c
~
src/leaf.c
~
src/login.c
~
src/makemake.tcl
~
src/merge.c
~
src/mkbuiltin.c
~
src/publish.c
~
src/schema.c
~
src/search.c
~
src/setup.c
~
src/shell.c
~
src/sqlcmd.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/style.c
~
src/sync.c
~
src/timeline.c
~
src/update.c
~
src/verify.c
~
test/diff-test-1.wiki
~
test/graph-test-1.wiki
~
win/Makefile.mingw
~
win/Makefile.mingw.mistachkin
~
win/Makefile.msc
~
www/build.wiki
~
www/changes.wiki
~
www/delta_format.wiki
~
www/hints.wiki
~
www/qandc.wiki
+26
| --- a/.dockerignore | ||
| +++ b/.dockerignore | ||
| @@ -0,0 +1,26 @@ | ||
| 1 | +_FOSSIL_ | |
| 2 | +.fslckout | |
| 3 | +ajax | |
| 4 | +art | |
| 5 | +autosetup | |
| 6 | +bld | |
| 7 | +compat | |
| 8 | +debian | |
| 9 | +fossil | |
| 10 | +fossil.exe | |
| 11 | +setup | |
| 12 | +src | |
| 13 | +test | |
| 14 | +tools | |
| 15 | +win | |
| 16 | +wbld | |
| 17 | +win | |
| 18 | +www | |
| 19 | +*.a | |
| 20 | +*.lib | |
| 21 | +*.log | |
| 22 | +*.manifest | |
| 23 | +*.o | |
| 24 | +*.obj | |
| 25 | +*.pdb | |
| 26 | +*.res |
| --- a/.dockerignore | |
| +++ b/.dockerignore | |
| @@ -0,0 +1,26 @@ | |
| --- a/.dockerignore | |
| +++ b/.dockerignore | |
| @@ -0,0 +1,26 @@ | |
| 1 | _FOSSIL_ |
| 2 | .fslckout |
| 3 | ajax |
| 4 | art |
| 5 | autosetup |
| 6 | bld |
| 7 | compat |
| 8 | debian |
| 9 | fossil |
| 10 | fossil.exe |
| 11 | setup |
| 12 | src |
| 13 | test |
| 14 | tools |
| 15 | win |
| 16 | wbld |
| 17 | win |
| 18 | www |
| 19 | *.a |
| 20 | *.lib |
| 21 | *.log |
| 22 | *.manifest |
| 23 | *.o |
| 24 | *.obj |
| 25 | *.pdb |
| 26 | *.res |
+7
-16
| --- Dockerfile | ||
| +++ Dockerfile | ||
| @@ -2,35 +2,26 @@ | ||
| 2 | 2 | # Dockerfile for Fossil |
| 3 | 3 | ### |
| 4 | 4 | FROM fedora:21 |
| 5 | 5 | |
| 6 | 6 | ### Now install some additional parts we will need for the build |
| 7 | -# RUN yum update -y && yum clean all | |
| 8 | -RUN yum install -y gcc make zlib-devel openssl-devel tcl-devel && yum clean all | |
| 9 | -RUN groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil | |
| 7 | +RUN yum update -y && yum install -y gcc make zlib-devel openssl-devel tcl-devel tar && yum clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil | |
| 10 | 8 | |
| 11 | -### If you want to build "release", change the next line accordingly. | |
| 12 | -ENV FOSSIL_INSTALL_VERSION trunk | |
| 9 | +### If you want to build "trunk", change the next line accordingly. | |
| 10 | +ENV FOSSIL_INSTALL_VERSION release | |
| 13 | 11 | |
| 14 | 12 | RUN curl "http://www.fossil-scm.org/index.html/tarball/fossil-src.tar.gz?name=fossil-src&uuid=${FOSSIL_INSTALL_VERSION}" | tar zx |
| 15 | -RUN cd fossil-src && ./configure --lineedit=0 --json --with-tcl --with-tcl-stubs --with-tcl-private-stubs && make; | |
| 16 | -RUN cp fossil-src/fossil /usr/bin | |
| 17 | -RUN rm -rf fossil-src | |
| 18 | -RUN chmod a+rx /usr/bin/fossil | |
| 19 | -RUN mkdir -p /opt/fossil | |
| 20 | -RUN chown fossil:fossil /opt/fossil | |
| 13 | +RUN cd fossil-src && ./configure --disable-lineedit --disable-fusefs --json --with-th1-docs --with-th1-hooks --with-tcl --with-tcl-stubs --with-tcl-private-stubs && make; | |
| 14 | +RUN cp fossil-src/fossil /usr/bin && rm -rf fossil-src && chmod a+rx /usr/bin/fossil && mkdir -p /opt/fossil && chown fossil:fossil /opt/fossil | |
| 21 | 15 | |
| 22 | 16 | ### Build is done, remove modules no longer needed |
| 23 | -RUN yum remove -y gcc make zlib-devel openssl-devel tcl-devel && yum clean all | |
| 17 | +RUN yum remove -y gcc make zlib-devel openssl-devel tcl-devel tar && yum clean all | |
| 24 | 18 | |
| 25 | 19 | USER fossil |
| 26 | 20 | |
| 27 | 21 | ENV HOME /opt/fossil |
| 28 | 22 | |
| 29 | -RUN fossil new --docker -A admin /opt/fossil/repository.fossil | |
| 30 | -RUN fossil user password -R /opt/fossil/repository.fossil admin admin | |
| 31 | -RUN fossil cache init -R /opt/fossil/repository.fossil | |
| 23 | +RUN fossil new --docker -A admin /opt/fossil/repository.fossil && fossil user password -R /opt/fossil/repository.fossil admin admin && fossil cache init -R /opt/fossil/repository.fossil | |
| 32 | 24 | |
| 33 | 25 | EXPOSE 8080 |
| 34 | 26 | |
| 35 | 27 | CMD ["/usr/bin/fossil", "server", "/opt/fossil/repository.fossil"] |
| 36 | - | |
| 37 | 28 |
| --- Dockerfile | |
| +++ Dockerfile | |
| @@ -2,35 +2,26 @@ | |
| 2 | # Dockerfile for Fossil |
| 3 | ### |
| 4 | FROM fedora:21 |
| 5 | |
| 6 | ### Now install some additional parts we will need for the build |
| 7 | # RUN yum update -y && yum clean all |
| 8 | RUN yum install -y gcc make zlib-devel openssl-devel tcl-devel && yum clean all |
| 9 | RUN groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil |
| 10 | |
| 11 | ### If you want to build "release", change the next line accordingly. |
| 12 | ENV FOSSIL_INSTALL_VERSION trunk |
| 13 | |
| 14 | RUN curl "http://www.fossil-scm.org/index.html/tarball/fossil-src.tar.gz?name=fossil-src&uuid=${FOSSIL_INSTALL_VERSION}" | tar zx |
| 15 | RUN cd fossil-src && ./configure --lineedit=0 --json --with-tcl --with-tcl-stubs --with-tcl-private-stubs && make; |
| 16 | RUN cp fossil-src/fossil /usr/bin |
| 17 | RUN rm -rf fossil-src |
| 18 | RUN chmod a+rx /usr/bin/fossil |
| 19 | RUN mkdir -p /opt/fossil |
| 20 | RUN chown fossil:fossil /opt/fossil |
| 21 | |
| 22 | ### Build is done, remove modules no longer needed |
| 23 | RUN yum remove -y gcc make zlib-devel openssl-devel tcl-devel && yum clean all |
| 24 | |
| 25 | USER fossil |
| 26 | |
| 27 | ENV HOME /opt/fossil |
| 28 | |
| 29 | RUN fossil new --docker -A admin /opt/fossil/repository.fossil |
| 30 | RUN fossil user password -R /opt/fossil/repository.fossil admin admin |
| 31 | RUN fossil cache init -R /opt/fossil/repository.fossil |
| 32 | |
| 33 | EXPOSE 8080 |
| 34 | |
| 35 | CMD ["/usr/bin/fossil", "server", "/opt/fossil/repository.fossil"] |
| 36 | |
| 37 |
| --- Dockerfile | |
| +++ Dockerfile | |
| @@ -2,35 +2,26 @@ | |
| 2 | # Dockerfile for Fossil |
| 3 | ### |
| 4 | FROM fedora:21 |
| 5 | |
| 6 | ### Now install some additional parts we will need for the build |
| 7 | RUN yum update -y && yum install -y gcc make zlib-devel openssl-devel tcl-devel tar && yum clean all && groupadd -r fossil -g 433 && useradd -u 431 -r -g fossil -d /opt/fossil -s /sbin/nologin -c "Fossil user" fossil |
| 8 | |
| 9 | ### If you want to build "trunk", change the next line accordingly. |
| 10 | ENV FOSSIL_INSTALL_VERSION release |
| 11 | |
| 12 | RUN curl "http://www.fossil-scm.org/index.html/tarball/fossil-src.tar.gz?name=fossil-src&uuid=${FOSSIL_INSTALL_VERSION}" | tar zx |
| 13 | RUN cd fossil-src && ./configure --disable-lineedit --disable-fusefs --json --with-th1-docs --with-th1-hooks --with-tcl --with-tcl-stubs --with-tcl-private-stubs && make; |
| 14 | RUN cp fossil-src/fossil /usr/bin && rm -rf fossil-src && chmod a+rx /usr/bin/fossil && mkdir -p /opt/fossil && chown fossil:fossil /opt/fossil |
| 15 | |
| 16 | ### Build is done, remove modules no longer needed |
| 17 | RUN yum remove -y gcc make zlib-devel openssl-devel tcl-devel tar && yum clean all |
| 18 | |
| 19 | USER fossil |
| 20 | |
| 21 | ENV HOME /opt/fossil |
| 22 | |
| 23 | RUN fossil new --docker -A admin /opt/fossil/repository.fossil && fossil user password -R /opt/fossil/repository.fossil admin admin && fossil cache init -R /opt/fossil/repository.fossil |
| 24 | |
| 25 | EXPOSE 8080 |
| 26 | |
| 27 | CMD ["/usr/bin/fossil", "server", "/opt/fossil/repository.fossil"] |
| 28 |
+6
-6
| --- 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 |
| @@ -479,11 +479,11 @@ | ||
| 479 | 479 | const char *zPathname, *zDisplayName; |
| 480 | 480 | |
| 481 | 481 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 482 | 482 | db_must_be_within_tree(); |
| 483 | 483 | cwdRelative = determine_cwd_relative_option(); |
| 484 | - | |
| 484 | + | |
| 485 | 485 | /* We should be done with options.. */ |
| 486 | 486 | verify_all_options(); |
| 487 | 487 | |
| 488 | 488 | if( zIgnoreFlag==0 ){ |
| 489 | 489 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -578,11 +578,11 @@ | ||
| 578 | 578 | ** -n|--dry-run If given, display instead of run actions. |
| 579 | 579 | ** --temp Remove only Fossil-generated temporary files. |
| 580 | 580 | ** -v|--verbose Show all files as they are removed. |
| 581 | 581 | ** -x|--extreme Remove all files not part of the current |
| 582 | 582 | ** checkout, except the ones matching --keep. |
| 583 | -** Files not matching any of --clean/--ignore/-keep, | |
| 583 | +** Files not matching any of --clean/--ignore/--keep, | |
| 584 | 584 | ** will be prompted for. |
| 585 | 585 | ** Compatibile with "git clean -x". |
| 586 | 586 | ** |
| 587 | 587 | ** See also: addremove, extras, status |
| 588 | 588 | */ |
| @@ -1760,11 +1760,11 @@ | ||
| 1760 | 1760 | |
| 1761 | 1761 | /* |
| 1762 | 1762 | ** Do not allow a commit against a closed leaf unless the commit |
| 1763 | 1763 | ** ends up on a different branch. |
| 1764 | 1764 | */ |
| 1765 | - if( | |
| 1765 | + if( | |
| 1766 | 1766 | /* parent checkin has the "closed" tag... */ |
| 1767 | 1767 | db_exists("SELECT 1 FROM tagxref" |
| 1768 | 1768 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1769 | 1769 | TAG_CLOSED, vid) |
| 1770 | 1770 | /* ... and the new checkin has no --branch option or the --branch |
| 1771 | 1771 |
| --- 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 |
| @@ -479,11 +479,11 @@ | |
| 479 | const char *zPathname, *zDisplayName; |
| 480 | |
| 481 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 482 | db_must_be_within_tree(); |
| 483 | cwdRelative = determine_cwd_relative_option(); |
| 484 | |
| 485 | /* We should be done with options.. */ |
| 486 | verify_all_options(); |
| 487 | |
| 488 | if( zIgnoreFlag==0 ){ |
| 489 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -578,11 +578,11 @@ | |
| 578 | ** -n|--dry-run If given, display instead of run actions. |
| 579 | ** --temp Remove only Fossil-generated temporary files. |
| 580 | ** -v|--verbose Show all files as they are removed. |
| 581 | ** -x|--extreme Remove all files not part of the current |
| 582 | ** checkout, except the ones matching --keep. |
| 583 | ** Files not matching any of --clean/--ignore/-keep, |
| 584 | ** will be prompted for. |
| 585 | ** Compatibile with "git clean -x". |
| 586 | ** |
| 587 | ** See also: addremove, extras, status |
| 588 | */ |
| @@ -1760,11 +1760,11 @@ | |
| 1760 | |
| 1761 | /* |
| 1762 | ** Do not allow a commit against a closed leaf unless the commit |
| 1763 | ** ends up on a different branch. |
| 1764 | */ |
| 1765 | if( |
| 1766 | /* parent checkin has the "closed" tag... */ |
| 1767 | db_exists("SELECT 1 FROM tagxref" |
| 1768 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1769 | TAG_CLOSED, vid) |
| 1770 | /* ... and the new checkin has no --branch option or the --branch |
| 1771 |
| --- 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 |
| @@ -479,11 +479,11 @@ | |
| 479 | const char *zPathname, *zDisplayName; |
| 480 | |
| 481 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 482 | db_must_be_within_tree(); |
| 483 | cwdRelative = determine_cwd_relative_option(); |
| 484 | |
| 485 | /* We should be done with options.. */ |
| 486 | verify_all_options(); |
| 487 | |
| 488 | if( zIgnoreFlag==0 ){ |
| 489 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -578,11 +578,11 @@ | |
| 578 | ** -n|--dry-run If given, display instead of run actions. |
| 579 | ** --temp Remove only Fossil-generated temporary files. |
| 580 | ** -v|--verbose Show all files as they are removed. |
| 581 | ** -x|--extreme Remove all files not part of the current |
| 582 | ** checkout, except the ones matching --keep. |
| 583 | ** Files not matching any of --clean/--ignore/--keep, |
| 584 | ** will be prompted for. |
| 585 | ** Compatibile with "git clean -x". |
| 586 | ** |
| 587 | ** See also: addremove, extras, status |
| 588 | */ |
| @@ -1760,11 +1760,11 @@ | |
| 1760 | |
| 1761 | /* |
| 1762 | ** Do not allow a commit against a closed leaf unless the commit |
| 1763 | ** ends up on a different branch. |
| 1764 | */ |
| 1765 | if( |
| 1766 | /* parent checkin has the "closed" tag... */ |
| 1767 | db_exists("SELECT 1 FROM tagxref" |
| 1768 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1769 | TAG_CLOSED, vid) |
| 1770 | /* ... and the new checkin has no --branch option or the --branch |
| 1771 |
+6
-6
| --- 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 |
| @@ -479,11 +479,11 @@ | ||
| 479 | 479 | const char *zPathname, *zDisplayName; |
| 480 | 480 | |
| 481 | 481 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 482 | 482 | db_must_be_within_tree(); |
| 483 | 483 | cwdRelative = determine_cwd_relative_option(); |
| 484 | - | |
| 484 | + | |
| 485 | 485 | /* We should be done with options.. */ |
| 486 | 486 | verify_all_options(); |
| 487 | 487 | |
| 488 | 488 | if( zIgnoreFlag==0 ){ |
| 489 | 489 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -578,11 +578,11 @@ | ||
| 578 | 578 | ** -n|--dry-run If given, display instead of run actions. |
| 579 | 579 | ** --temp Remove only Fossil-generated temporary files. |
| 580 | 580 | ** -v|--verbose Show all files as they are removed. |
| 581 | 581 | ** -x|--extreme Remove all files not part of the current |
| 582 | 582 | ** checkout, except the ones matching --keep. |
| 583 | -** Files not matching any of --clean/--ignore/-keep, | |
| 583 | +** Files not matching any of --clean/--ignore/--keep, | |
| 584 | 584 | ** will be prompted for. |
| 585 | 585 | ** Compatibile with "git clean -x". |
| 586 | 586 | ** |
| 587 | 587 | ** See also: addremove, extras, status |
| 588 | 588 | */ |
| @@ -1760,11 +1760,11 @@ | ||
| 1760 | 1760 | |
| 1761 | 1761 | /* |
| 1762 | 1762 | ** Do not allow a commit against a closed leaf unless the commit |
| 1763 | 1763 | ** ends up on a different branch. |
| 1764 | 1764 | */ |
| 1765 | - if( | |
| 1765 | + if( | |
| 1766 | 1766 | /* parent checkin has the "closed" tag... */ |
| 1767 | 1767 | db_exists("SELECT 1 FROM tagxref" |
| 1768 | 1768 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1769 | 1769 | TAG_CLOSED, vid) |
| 1770 | 1770 | /* ... and the new checkin has no --branch option or the --branch |
| 1771 | 1771 |
| --- 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 |
| @@ -479,11 +479,11 @@ | |
| 479 | const char *zPathname, *zDisplayName; |
| 480 | |
| 481 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 482 | db_must_be_within_tree(); |
| 483 | cwdRelative = determine_cwd_relative_option(); |
| 484 | |
| 485 | /* We should be done with options.. */ |
| 486 | verify_all_options(); |
| 487 | |
| 488 | if( zIgnoreFlag==0 ){ |
| 489 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -578,11 +578,11 @@ | |
| 578 | ** -n|--dry-run If given, display instead of run actions. |
| 579 | ** --temp Remove only Fossil-generated temporary files. |
| 580 | ** -v|--verbose Show all files as they are removed. |
| 581 | ** -x|--extreme Remove all files not part of the current |
| 582 | ** checkout, except the ones matching --keep. |
| 583 | ** Files not matching any of --clean/--ignore/-keep, |
| 584 | ** will be prompted for. |
| 585 | ** Compatibile with "git clean -x". |
| 586 | ** |
| 587 | ** See also: addremove, extras, status |
| 588 | */ |
| @@ -1760,11 +1760,11 @@ | |
| 1760 | |
| 1761 | /* |
| 1762 | ** Do not allow a commit against a closed leaf unless the commit |
| 1763 | ** ends up on a different branch. |
| 1764 | */ |
| 1765 | if( |
| 1766 | /* parent checkin has the "closed" tag... */ |
| 1767 | db_exists("SELECT 1 FROM tagxref" |
| 1768 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1769 | TAG_CLOSED, vid) |
| 1770 | /* ... and the new checkin has no --branch option or the --branch |
| 1771 |
| --- 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 |
| @@ -479,11 +479,11 @@ | |
| 479 | const char *zPathname, *zDisplayName; |
| 480 | |
| 481 | if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP; |
| 482 | db_must_be_within_tree(); |
| 483 | cwdRelative = determine_cwd_relative_option(); |
| 484 | |
| 485 | /* We should be done with options.. */ |
| 486 | verify_all_options(); |
| 487 | |
| 488 | if( zIgnoreFlag==0 ){ |
| 489 | zIgnoreFlag = db_get("ignore-glob", 0); |
| @@ -578,11 +578,11 @@ | |
| 578 | ** -n|--dry-run If given, display instead of run actions. |
| 579 | ** --temp Remove only Fossil-generated temporary files. |
| 580 | ** -v|--verbose Show all files as they are removed. |
| 581 | ** -x|--extreme Remove all files not part of the current |
| 582 | ** checkout, except the ones matching --keep. |
| 583 | ** Files not matching any of --clean/--ignore/--keep, |
| 584 | ** will be prompted for. |
| 585 | ** Compatibile with "git clean -x". |
| 586 | ** |
| 587 | ** See also: addremove, extras, status |
| 588 | */ |
| @@ -1760,11 +1760,11 @@ | |
| 1760 | |
| 1761 | /* |
| 1762 | ** Do not allow a commit against a closed leaf unless the commit |
| 1763 | ** ends up on a different branch. |
| 1764 | */ |
| 1765 | if( |
| 1766 | /* parent checkin has the "closed" tag... */ |
| 1767 | db_exists("SELECT 1 FROM tagxref" |
| 1768 | " WHERE tagid=%d AND rid=%d AND tagtype>0", |
| 1769 | TAG_CLOSED, vid) |
| 1770 | /* ... and the new checkin has no --branch option or the --branch |
| 1771 |
+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
+35
-14
| --- 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 |
| @@ -749,10 +757,18 @@ | ||
| 749 | 757 | if( rc==0 ){ |
| 750 | 758 | sqlite3_result_int64(context, mtime); |
| 751 | 759 | } |
| 752 | 760 | } |
| 753 | 761 | |
| 762 | +/* | |
| 763 | +** SQL wrapper around the symbolic_name_to_rid() C-language API. | |
| 764 | +** Examples: | |
| 765 | +** | |
| 766 | +** symbolic_name_to_rid('trunk'); | |
| 767 | +** symbolic_name_to_rid('trunk','w'); | |
| 768 | +** | |
| 769 | +*/ | |
| 754 | 770 | void db_sym2rid_function( |
| 755 | 771 | sqlite3_context *context, |
| 756 | 772 | int argc, |
| 757 | 773 | sqlite3_value **argv |
| 758 | 774 | ){ |
| @@ -778,10 +794,23 @@ | ||
| 778 | 794 | sqlite3_result_int64(context, rid); |
| 779 | 795 | } |
| 780 | 796 | } |
| 781 | 797 | } |
| 782 | 798 | |
| 799 | +/* | |
| 800 | +** Register the SQL functions that are useful both to the internal | |
| 801 | +** representation and to the "fossil sql" command. | |
| 802 | +*/ | |
| 803 | +void db_add_aux_functions(sqlite3 *db){ | |
| 804 | + sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, | |
| 805 | + db_checkin_mtime_function, 0, 0); | |
| 806 | + sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, | |
| 807 | + db_sym2rid_function, 0, 0); | |
| 808 | + sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, | |
| 809 | + db_sym2rid_function, 0, 0); | |
| 810 | +} | |
| 811 | + | |
| 783 | 812 | |
| 784 | 813 | /* |
| 785 | 814 | ** Open a database file. Return a pointer to the new database |
| 786 | 815 | ** connection. An error results in process abort. |
| 787 | 816 | */ |
| @@ -798,13 +827,12 @@ | ||
| 798 | 827 | if( rc!=SQLITE_OK ){ |
| 799 | 828 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 800 | 829 | } |
| 801 | 830 | sqlite3_busy_timeout(db, 5000); |
| 802 | 831 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 803 | - sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, db_now_function, 0, 0); | |
| 804 | - sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, | |
| 805 | - db_checkin_mtime_function, 0, 0); | |
| 832 | + sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, | |
| 833 | + db_now_function, 0, 0); | |
| 806 | 834 | sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0); |
| 807 | 835 | sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 808 | 836 | sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 809 | 837 | sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0); |
| 810 | 838 | sqlite3_create_function( |
| @@ -811,21 +839,14 @@ | ||
| 811 | 839 | db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 812 | 840 | ); |
| 813 | 841 | sqlite3_create_function( |
| 814 | 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 815 | 843 | ); |
| 816 | - sqlite3_create_function( | |
| 817 | - db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, db_sym2rid_function, | |
| 818 | - 0, 0 | |
| 819 | - ); | |
| 820 | - sqlite3_create_function( | |
| 821 | - db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, db_sym2rid_function, | |
| 822 | - 0, 0 | |
| 823 | - ); | |
| 824 | 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 825 | - re_add_sql_func(db); | |
| 826 | - foci_register(db); | |
| 845 | + db_add_aux_functions(db); | |
| 846 | + re_add_sql_func(db); /* The REGEXP operator */ | |
| 847 | + foci_register(db); /* The "files_of_checkin" virtual table */ | |
| 827 | 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 828 | 849 | return db; |
| 829 | 850 | } |
| 830 | 851 | |
| 831 | 852 | |
| @@ -2636,11 +2657,11 @@ | ||
| 2636 | 2657 | } |
| 2637 | 2658 | } |
| 2638 | 2659 | }else{ |
| 2639 | 2660 | isManifest = 0; |
| 2640 | 2661 | while( ctrlSettings[i].name |
| 2641 | - && strncmp(ctrlSettings[i].name, zName, n)==0 | |
| 2662 | + && strncmp(ctrlSettings[i].name, zName, n)==0 | |
| 2642 | 2663 | ){ |
| 2643 | 2664 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2644 | 2665 | i++; |
| 2645 | 2666 | } |
| 2646 | 2667 | } |
| 2647 | 2668 |
| --- 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 |
| @@ -749,10 +757,18 @@ | |
| 749 | if( rc==0 ){ |
| 750 | sqlite3_result_int64(context, mtime); |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | void db_sym2rid_function( |
| 755 | sqlite3_context *context, |
| 756 | int argc, |
| 757 | sqlite3_value **argv |
| 758 | ){ |
| @@ -778,10 +794,23 @@ | |
| 778 | sqlite3_result_int64(context, rid); |
| 779 | } |
| 780 | } |
| 781 | } |
| 782 | |
| 783 | |
| 784 | /* |
| 785 | ** Open a database file. Return a pointer to the new database |
| 786 | ** connection. An error results in process abort. |
| 787 | */ |
| @@ -798,13 +827,12 @@ | |
| 798 | if( rc!=SQLITE_OK ){ |
| 799 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 800 | } |
| 801 | sqlite3_busy_timeout(db, 5000); |
| 802 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 803 | sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, db_now_function, 0, 0); |
| 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | db_checkin_mtime_function, 0, 0); |
| 806 | sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0); |
| 807 | sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 808 | sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 809 | sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0); |
| 810 | sqlite3_create_function( |
| @@ -811,21 +839,14 @@ | |
| 811 | db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 812 | ); |
| 813 | sqlite3_create_function( |
| 814 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 815 | ); |
| 816 | sqlite3_create_function( |
| 817 | db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, db_sym2rid_function, |
| 818 | 0, 0 |
| 819 | ); |
| 820 | sqlite3_create_function( |
| 821 | db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, db_sym2rid_function, |
| 822 | 0, 0 |
| 823 | ); |
| 824 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 825 | re_add_sql_func(db); |
| 826 | foci_register(db); |
| 827 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 828 | return db; |
| 829 | } |
| 830 | |
| 831 | |
| @@ -2636,11 +2657,11 @@ | |
| 2636 | } |
| 2637 | } |
| 2638 | }else{ |
| 2639 | isManifest = 0; |
| 2640 | while( ctrlSettings[i].name |
| 2641 | && strncmp(ctrlSettings[i].name, zName, n)==0 |
| 2642 | ){ |
| 2643 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2644 | i++; |
| 2645 | } |
| 2646 | } |
| 2647 |
| --- 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 |
| @@ -749,10 +757,18 @@ | |
| 757 | if( rc==0 ){ |
| 758 | sqlite3_result_int64(context, mtime); |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | /* |
| 763 | ** SQL wrapper around the symbolic_name_to_rid() C-language API. |
| 764 | ** Examples: |
| 765 | ** |
| 766 | ** symbolic_name_to_rid('trunk'); |
| 767 | ** symbolic_name_to_rid('trunk','w'); |
| 768 | ** |
| 769 | */ |
| 770 | void db_sym2rid_function( |
| 771 | sqlite3_context *context, |
| 772 | int argc, |
| 773 | sqlite3_value **argv |
| 774 | ){ |
| @@ -778,10 +794,23 @@ | |
| 794 | sqlite3_result_int64(context, rid); |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | /* |
| 800 | ** Register the SQL functions that are useful both to the internal |
| 801 | ** representation and to the "fossil sql" command. |
| 802 | */ |
| 803 | void db_add_aux_functions(sqlite3 *db){ |
| 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | db_checkin_mtime_function, 0, 0); |
| 806 | sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, |
| 807 | db_sym2rid_function, 0, 0); |
| 808 | sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, |
| 809 | db_sym2rid_function, 0, 0); |
| 810 | } |
| 811 | |
| 812 | |
| 813 | /* |
| 814 | ** Open a database file. Return a pointer to the new database |
| 815 | ** connection. An error results in process abort. |
| 816 | */ |
| @@ -798,13 +827,12 @@ | |
| 827 | if( rc!=SQLITE_OK ){ |
| 828 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 829 | } |
| 830 | sqlite3_busy_timeout(db, 5000); |
| 831 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 832 | sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, |
| 833 | db_now_function, 0, 0); |
| 834 | sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0); |
| 835 | sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 836 | sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 837 | sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0); |
| 838 | sqlite3_create_function( |
| @@ -811,21 +839,14 @@ | |
| 839 | db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 840 | ); |
| 841 | sqlite3_create_function( |
| 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 843 | ); |
| 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 845 | db_add_aux_functions(db); |
| 846 | re_add_sql_func(db); /* The REGEXP operator */ |
| 847 | foci_register(db); /* The "files_of_checkin" virtual table */ |
| 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 849 | return db; |
| 850 | } |
| 851 | |
| 852 | |
| @@ -2636,11 +2657,11 @@ | |
| 2657 | } |
| 2658 | } |
| 2659 | }else{ |
| 2660 | isManifest = 0; |
| 2661 | while( ctrlSettings[i].name |
| 2662 | && strncmp(ctrlSettings[i].name, zName, n)==0 |
| 2663 | ){ |
| 2664 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2665 | i++; |
| 2666 | } |
| 2667 | } |
| 2668 |
M
src/db.c
+35
-14
| --- 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 |
| @@ -749,10 +757,18 @@ | ||
| 749 | 757 | if( rc==0 ){ |
| 750 | 758 | sqlite3_result_int64(context, mtime); |
| 751 | 759 | } |
| 752 | 760 | } |
| 753 | 761 | |
| 762 | +/* | |
| 763 | +** SQL wrapper around the symbolic_name_to_rid() C-language API. | |
| 764 | +** Examples: | |
| 765 | +** | |
| 766 | +** symbolic_name_to_rid('trunk'); | |
| 767 | +** symbolic_name_to_rid('trunk','w'); | |
| 768 | +** | |
| 769 | +*/ | |
| 754 | 770 | void db_sym2rid_function( |
| 755 | 771 | sqlite3_context *context, |
| 756 | 772 | int argc, |
| 757 | 773 | sqlite3_value **argv |
| 758 | 774 | ){ |
| @@ -778,10 +794,23 @@ | ||
| 778 | 794 | sqlite3_result_int64(context, rid); |
| 779 | 795 | } |
| 780 | 796 | } |
| 781 | 797 | } |
| 782 | 798 | |
| 799 | +/* | |
| 800 | +** Register the SQL functions that are useful both to the internal | |
| 801 | +** representation and to the "fossil sql" command. | |
| 802 | +*/ | |
| 803 | +void db_add_aux_functions(sqlite3 *db){ | |
| 804 | + sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, | |
| 805 | + db_checkin_mtime_function, 0, 0); | |
| 806 | + sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, | |
| 807 | + db_sym2rid_function, 0, 0); | |
| 808 | + sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, | |
| 809 | + db_sym2rid_function, 0, 0); | |
| 810 | +} | |
| 811 | + | |
| 783 | 812 | |
| 784 | 813 | /* |
| 785 | 814 | ** Open a database file. Return a pointer to the new database |
| 786 | 815 | ** connection. An error results in process abort. |
| 787 | 816 | */ |
| @@ -798,13 +827,12 @@ | ||
| 798 | 827 | if( rc!=SQLITE_OK ){ |
| 799 | 828 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 800 | 829 | } |
| 801 | 830 | sqlite3_busy_timeout(db, 5000); |
| 802 | 831 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 803 | - sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, db_now_function, 0, 0); | |
| 804 | - sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, | |
| 805 | - db_checkin_mtime_function, 0, 0); | |
| 832 | + sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, | |
| 833 | + db_now_function, 0, 0); | |
| 806 | 834 | sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0); |
| 807 | 835 | sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 808 | 836 | sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 809 | 837 | sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0); |
| 810 | 838 | sqlite3_create_function( |
| @@ -811,21 +839,14 @@ | ||
| 811 | 839 | db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 812 | 840 | ); |
| 813 | 841 | sqlite3_create_function( |
| 814 | 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 815 | 843 | ); |
| 816 | - sqlite3_create_function( | |
| 817 | - db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, db_sym2rid_function, | |
| 818 | - 0, 0 | |
| 819 | - ); | |
| 820 | - sqlite3_create_function( | |
| 821 | - db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, db_sym2rid_function, | |
| 822 | - 0, 0 | |
| 823 | - ); | |
| 824 | 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 825 | - re_add_sql_func(db); | |
| 826 | - foci_register(db); | |
| 845 | + db_add_aux_functions(db); | |
| 846 | + re_add_sql_func(db); /* The REGEXP operator */ | |
| 847 | + foci_register(db); /* The "files_of_checkin" virtual table */ | |
| 827 | 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 828 | 849 | return db; |
| 829 | 850 | } |
| 830 | 851 | |
| 831 | 852 | |
| @@ -2636,11 +2657,11 @@ | ||
| 2636 | 2657 | } |
| 2637 | 2658 | } |
| 2638 | 2659 | }else{ |
| 2639 | 2660 | isManifest = 0; |
| 2640 | 2661 | while( ctrlSettings[i].name |
| 2641 | - && strncmp(ctrlSettings[i].name, zName, n)==0 | |
| 2662 | + && strncmp(ctrlSettings[i].name, zName, n)==0 | |
| 2642 | 2663 | ){ |
| 2643 | 2664 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2644 | 2665 | i++; |
| 2645 | 2666 | } |
| 2646 | 2667 | } |
| 2647 | 2668 |
| --- 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 |
| @@ -749,10 +757,18 @@ | |
| 749 | if( rc==0 ){ |
| 750 | sqlite3_result_int64(context, mtime); |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | void db_sym2rid_function( |
| 755 | sqlite3_context *context, |
| 756 | int argc, |
| 757 | sqlite3_value **argv |
| 758 | ){ |
| @@ -778,10 +794,23 @@ | |
| 778 | sqlite3_result_int64(context, rid); |
| 779 | } |
| 780 | } |
| 781 | } |
| 782 | |
| 783 | |
| 784 | /* |
| 785 | ** Open a database file. Return a pointer to the new database |
| 786 | ** connection. An error results in process abort. |
| 787 | */ |
| @@ -798,13 +827,12 @@ | |
| 798 | if( rc!=SQLITE_OK ){ |
| 799 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 800 | } |
| 801 | sqlite3_busy_timeout(db, 5000); |
| 802 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 803 | sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, db_now_function, 0, 0); |
| 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | db_checkin_mtime_function, 0, 0); |
| 806 | sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0); |
| 807 | sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 808 | sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 809 | sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0); |
| 810 | sqlite3_create_function( |
| @@ -811,21 +839,14 @@ | |
| 811 | db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 812 | ); |
| 813 | sqlite3_create_function( |
| 814 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 815 | ); |
| 816 | sqlite3_create_function( |
| 817 | db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, db_sym2rid_function, |
| 818 | 0, 0 |
| 819 | ); |
| 820 | sqlite3_create_function( |
| 821 | db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, db_sym2rid_function, |
| 822 | 0, 0 |
| 823 | ); |
| 824 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 825 | re_add_sql_func(db); |
| 826 | foci_register(db); |
| 827 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 828 | return db; |
| 829 | } |
| 830 | |
| 831 | |
| @@ -2636,11 +2657,11 @@ | |
| 2636 | } |
| 2637 | } |
| 2638 | }else{ |
| 2639 | isManifest = 0; |
| 2640 | while( ctrlSettings[i].name |
| 2641 | && strncmp(ctrlSettings[i].name, zName, n)==0 |
| 2642 | ){ |
| 2643 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2644 | i++; |
| 2645 | } |
| 2646 | } |
| 2647 |
| --- 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 |
| @@ -749,10 +757,18 @@ | |
| 757 | if( rc==0 ){ |
| 758 | sqlite3_result_int64(context, mtime); |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | /* |
| 763 | ** SQL wrapper around the symbolic_name_to_rid() C-language API. |
| 764 | ** Examples: |
| 765 | ** |
| 766 | ** symbolic_name_to_rid('trunk'); |
| 767 | ** symbolic_name_to_rid('trunk','w'); |
| 768 | ** |
| 769 | */ |
| 770 | void db_sym2rid_function( |
| 771 | sqlite3_context *context, |
| 772 | int argc, |
| 773 | sqlite3_value **argv |
| 774 | ){ |
| @@ -778,10 +794,23 @@ | |
| 794 | sqlite3_result_int64(context, rid); |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | /* |
| 800 | ** Register the SQL functions that are useful both to the internal |
| 801 | ** representation and to the "fossil sql" command. |
| 802 | */ |
| 803 | void db_add_aux_functions(sqlite3 *db){ |
| 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | db_checkin_mtime_function, 0, 0); |
| 806 | sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, |
| 807 | db_sym2rid_function, 0, 0); |
| 808 | sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, |
| 809 | db_sym2rid_function, 0, 0); |
| 810 | } |
| 811 | |
| 812 | |
| 813 | /* |
| 814 | ** Open a database file. Return a pointer to the new database |
| 815 | ** connection. An error results in process abort. |
| 816 | */ |
| @@ -798,13 +827,12 @@ | |
| 827 | if( rc!=SQLITE_OK ){ |
| 828 | db_err("[%s]: %s", zDbName, sqlite3_errmsg(db)); |
| 829 | } |
| 830 | sqlite3_busy_timeout(db, 5000); |
| 831 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 832 | sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0, |
| 833 | db_now_function, 0, 0); |
| 834 | sqlite3_create_function(db, "user", 0, SQLITE_UTF8, 0, db_sql_user, 0, 0); |
| 835 | sqlite3_create_function(db, "cgi", 1, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 836 | sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0); |
| 837 | sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0); |
| 838 | sqlite3_create_function( |
| @@ -811,21 +839,14 @@ | |
| 839 | db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 840 | ); |
| 841 | sqlite3_create_function( |
| 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 843 | ); |
| 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 845 | db_add_aux_functions(db); |
| 846 | re_add_sql_func(db); /* The REGEXP operator */ |
| 847 | foci_register(db); /* The "files_of_checkin" virtual table */ |
| 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 849 | return db; |
| 850 | } |
| 851 | |
| 852 | |
| @@ -2636,11 +2657,11 @@ | |
| 2657 | } |
| 2658 | } |
| 2659 | }else{ |
| 2660 | isManifest = 0; |
| 2661 | while( ctrlSettings[i].name |
| 2662 | && strncmp(ctrlSettings[i].name, zName, n)==0 |
| 2663 | ){ |
| 2664 | print_setting(&ctrlSettings[i], db_open_local(0)); |
| 2665 | i++; |
| 2666 | } |
| 2667 | } |
| 2668 |
+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 |
+25
-5
| --- src/foci.c | ||
| +++ src/foci.c | ||
| @@ -17,25 +17,45 @@ | ||
| 17 | 17 | ** |
| 18 | 18 | ** This routine implements an SQLite virtual table that gives all of the |
| 19 | 19 | ** files associated with a single checkin. |
| 20 | 20 | ** |
| 21 | 21 | ** The filename "foci" is short for "Files Of CheckIn". |
| 22 | +** | |
| 23 | +** Usage example: | |
| 24 | +** | |
| 25 | +** CREATE VIRTUAL TABLE temp.foci USING files_of_checkin; | |
| 26 | +** -- ^^^^--- important! | |
| 27 | +** SELECT * FROM foci WHERE checkinID=symbolic_name_to_rid('trunk'); | |
| 28 | +** | |
| 29 | +** The symbolic_name_to_rid('trunk') function finds the BLOB.RID value | |
| 30 | +** corresponding to the 'trunk' tag. Then the files_of_checkin virtual table | |
| 31 | +** decodes the manifest defined by that BLOB and returns all files described | |
| 32 | +** by that manifest. The "schema" for the temp.foci table is: | |
| 33 | +** | |
| 34 | +** CREATE TABLE files_of_checkin( | |
| 35 | +** checkinID INTEGER, -- RID for the checkin manifest | |
| 36 | +** filename TEXT, -- Name of a file | |
| 37 | +** uuid TEXT, -- SHA1 hash of the file | |
| 38 | +** previousName TEXT, -- Name of the file in previous checkin | |
| 39 | +** perm TEXT -- Permissions on the file | |
| 40 | +** ); | |
| 41 | +** | |
| 22 | 42 | */ |
| 23 | 43 | #include "config.h" |
| 24 | 44 | #include "foci.h" |
| 25 | 45 | #include <assert.h> |
| 26 | 46 | |
| 27 | 47 | /* |
| 28 | 48 | ** The schema for the virtual table: |
| 29 | 49 | */ |
| 30 | -static const char zFociSchema[] = | |
| 50 | +static const char zFociSchema[] = | |
| 31 | 51 | @ CREATE TABLE files_of_checkin( |
| 32 | 52 | @ checkinID INTEGER, -- RID for the checkin manifest |
| 33 | 53 | @ filename TEXT, -- Name of a file |
| 34 | 54 | @ uuid TEXT, -- SHA1 hash of the file |
| 35 | 55 | @ previousName TEXT, -- Name of the file in previous checkin |
| 36 | -@ prem TEXT -- Permissions on the file | |
| 56 | +@ perm TEXT -- Permissions on the file | |
| 37 | 57 | @ ); |
| 38 | 58 | ; |
| 39 | 59 | |
| 40 | 60 | #if INTERFACE |
| 41 | 61 | /* |
| @@ -139,11 +159,11 @@ | ||
| 139 | 159 | FociCursor *pCsr = (FociCursor *)pCursor; |
| 140 | 160 | return pCsr->pFile==0; |
| 141 | 161 | } |
| 142 | 162 | |
| 143 | 163 | static int fociFilter( |
| 144 | - sqlite3_vtab_cursor *pCursor, | |
| 164 | + sqlite3_vtab_cursor *pCursor, | |
| 145 | 165 | int idxNum, const char *idxStr, |
| 146 | 166 | int argc, sqlite3_value **argv |
| 147 | 167 | ){ |
| 148 | 168 | FociCursor *pCur = (FociCursor *)pCursor; |
| 149 | 169 | manifest_destroy(pCur->pMan); |
| @@ -158,12 +178,12 @@ | ||
| 158 | 178 | } |
| 159 | 179 | return SQLITE_OK; |
| 160 | 180 | } |
| 161 | 181 | |
| 162 | 182 | static int fociColumn( |
| 163 | - sqlite3_vtab_cursor *pCursor, | |
| 164 | - sqlite3_context *ctx, | |
| 183 | + sqlite3_vtab_cursor *pCursor, | |
| 184 | + sqlite3_context *ctx, | |
| 165 | 185 | int i |
| 166 | 186 | ){ |
| 167 | 187 | FociCursor *pCsr = (FociCursor *)pCursor; |
| 168 | 188 | switch( i ){ |
| 169 | 189 | case 0: /* checkinID */ |
| 170 | 190 |
| --- src/foci.c | |
| +++ src/foci.c | |
| @@ -17,25 +17,45 @@ | |
| 17 | ** |
| 18 | ** This routine implements an SQLite virtual table that gives all of the |
| 19 | ** files associated with a single checkin. |
| 20 | ** |
| 21 | ** The filename "foci" is short for "Files Of CheckIn". |
| 22 | */ |
| 23 | #include "config.h" |
| 24 | #include "foci.h" |
| 25 | #include <assert.h> |
| 26 | |
| 27 | /* |
| 28 | ** The schema for the virtual table: |
| 29 | */ |
| 30 | static const char zFociSchema[] = |
| 31 | @ CREATE TABLE files_of_checkin( |
| 32 | @ checkinID INTEGER, -- RID for the checkin manifest |
| 33 | @ filename TEXT, -- Name of a file |
| 34 | @ uuid TEXT, -- SHA1 hash of the file |
| 35 | @ previousName TEXT, -- Name of the file in previous checkin |
| 36 | @ prem TEXT -- Permissions on the file |
| 37 | @ ); |
| 38 | ; |
| 39 | |
| 40 | #if INTERFACE |
| 41 | /* |
| @@ -139,11 +159,11 @@ | |
| 139 | FociCursor *pCsr = (FociCursor *)pCursor; |
| 140 | return pCsr->pFile==0; |
| 141 | } |
| 142 | |
| 143 | static int fociFilter( |
| 144 | sqlite3_vtab_cursor *pCursor, |
| 145 | int idxNum, const char *idxStr, |
| 146 | int argc, sqlite3_value **argv |
| 147 | ){ |
| 148 | FociCursor *pCur = (FociCursor *)pCursor; |
| 149 | manifest_destroy(pCur->pMan); |
| @@ -158,12 +178,12 @@ | |
| 158 | } |
| 159 | return SQLITE_OK; |
| 160 | } |
| 161 | |
| 162 | static int fociColumn( |
| 163 | sqlite3_vtab_cursor *pCursor, |
| 164 | sqlite3_context *ctx, |
| 165 | int i |
| 166 | ){ |
| 167 | FociCursor *pCsr = (FociCursor *)pCursor; |
| 168 | switch( i ){ |
| 169 | case 0: /* checkinID */ |
| 170 |
| --- src/foci.c | |
| +++ src/foci.c | |
| @@ -17,25 +17,45 @@ | |
| 17 | ** |
| 18 | ** This routine implements an SQLite virtual table that gives all of the |
| 19 | ** files associated with a single checkin. |
| 20 | ** |
| 21 | ** The filename "foci" is short for "Files Of CheckIn". |
| 22 | ** |
| 23 | ** Usage example: |
| 24 | ** |
| 25 | ** CREATE VIRTUAL TABLE temp.foci USING files_of_checkin; |
| 26 | ** -- ^^^^--- important! |
| 27 | ** SELECT * FROM foci WHERE checkinID=symbolic_name_to_rid('trunk'); |
| 28 | ** |
| 29 | ** The symbolic_name_to_rid('trunk') function finds the BLOB.RID value |
| 30 | ** corresponding to the 'trunk' tag. Then the files_of_checkin virtual table |
| 31 | ** decodes the manifest defined by that BLOB and returns all files described |
| 32 | ** by that manifest. The "schema" for the temp.foci table is: |
| 33 | ** |
| 34 | ** CREATE TABLE files_of_checkin( |
| 35 | ** checkinID INTEGER, -- RID for the checkin manifest |
| 36 | ** filename TEXT, -- Name of a file |
| 37 | ** uuid TEXT, -- SHA1 hash of the file |
| 38 | ** previousName TEXT, -- Name of the file in previous checkin |
| 39 | ** perm TEXT -- Permissions on the file |
| 40 | ** ); |
| 41 | ** |
| 42 | */ |
| 43 | #include "config.h" |
| 44 | #include "foci.h" |
| 45 | #include <assert.h> |
| 46 | |
| 47 | /* |
| 48 | ** The schema for the virtual table: |
| 49 | */ |
| 50 | static const char zFociSchema[] = |
| 51 | @ CREATE TABLE files_of_checkin( |
| 52 | @ checkinID INTEGER, -- RID for the checkin manifest |
| 53 | @ filename TEXT, -- Name of a file |
| 54 | @ uuid TEXT, -- SHA1 hash of the file |
| 55 | @ previousName TEXT, -- Name of the file in previous checkin |
| 56 | @ perm TEXT -- Permissions on the file |
| 57 | @ ); |
| 58 | ; |
| 59 | |
| 60 | #if INTERFACE |
| 61 | /* |
| @@ -139,11 +159,11 @@ | |
| 159 | FociCursor *pCsr = (FociCursor *)pCursor; |
| 160 | return pCsr->pFile==0; |
| 161 | } |
| 162 | |
| 163 | static int fociFilter( |
| 164 | sqlite3_vtab_cursor *pCursor, |
| 165 | int idxNum, const char *idxStr, |
| 166 | int argc, sqlite3_value **argv |
| 167 | ){ |
| 168 | FociCursor *pCur = (FociCursor *)pCursor; |
| 169 | manifest_destroy(pCur->pMan); |
| @@ -158,12 +178,12 @@ | |
| 178 | } |
| 179 | return SQLITE_OK; |
| 180 | } |
| 181 | |
| 182 | static int fociColumn( |
| 183 | sqlite3_vtab_cursor *pCursor, |
| 184 | sqlite3_context *ctx, |
| 185 | int i |
| 186 | ){ |
| 187 | FociCursor *pCsr = (FociCursor *)pCursor; |
| 188 | switch( i ){ |
| 189 | case 0: /* checkinID */ |
| 190 |
+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 |
-19
| --- src/glob.c | ||
| +++ src/glob.c | ||
| @@ -138,29 +138,10 @@ | ||
| 138 | 138 | z += i+1; |
| 139 | 139 | } |
| 140 | 140 | return p; |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | -/* | |
| 144 | -** Return non-zero if string z matches glob pattern zGlob and zero if the | |
| 145 | -** pattern does not match. | |
| 146 | -** | |
| 147 | -** Globbing rules: | |
| 148 | -** | |
| 149 | -** '*' Matches any sequence of zero or more characters. | |
| 150 | -** | |
| 151 | -** '?' Matches exactly one character. | |
| 152 | -** | |
| 153 | -** [...] Matches one character from the enclosed list of | |
| 154 | -** characters. | |
| 155 | -** | |
| 156 | -** [^...] Matches one character not in the enclosed list. | |
| 157 | -*/ | |
| 158 | -int strglob(const char *zGlob, const char *z){ | |
| 159 | - return sqlite3_strglob(zGlob, z)==0; | |
| 160 | -} | |
| 161 | - | |
| 162 | 143 | /* |
| 163 | 144 | ** Return true (non-zero) if zString matches any of the patterns in |
| 164 | 145 | ** the Glob. The value returned is actually a 1-based index of the pattern |
| 165 | 146 | ** that matched. Return 0 if none of the patterns match zString. |
| 166 | 147 | ** |
| 167 | 148 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -138,29 +138,10 @@ | |
| 138 | z += i+1; |
| 139 | } |
| 140 | return p; |
| 141 | } |
| 142 | |
| 143 | /* |
| 144 | ** Return non-zero if string z matches glob pattern zGlob and zero if the |
| 145 | ** pattern does not match. |
| 146 | ** |
| 147 | ** Globbing rules: |
| 148 | ** |
| 149 | ** '*' Matches any sequence of zero or more characters. |
| 150 | ** |
| 151 | ** '?' Matches exactly one character. |
| 152 | ** |
| 153 | ** [...] Matches one character from the enclosed list of |
| 154 | ** characters. |
| 155 | ** |
| 156 | ** [^...] Matches one character not in the enclosed list. |
| 157 | */ |
| 158 | int strglob(const char *zGlob, const char *z){ |
| 159 | return sqlite3_strglob(zGlob, z)==0; |
| 160 | } |
| 161 | |
| 162 | /* |
| 163 | ** Return true (non-zero) if zString matches any of the patterns in |
| 164 | ** the Glob. The value returned is actually a 1-based index of the pattern |
| 165 | ** that matched. Return 0 if none of the patterns match zString. |
| 166 | ** |
| 167 |
| --- src/glob.c | |
| +++ src/glob.c | |
| @@ -138,29 +138,10 @@ | |
| 138 | z += i+1; |
| 139 | } |
| 140 | return p; |
| 141 | } |
| 142 | |
| 143 | /* |
| 144 | ** Return true (non-zero) if zString matches any of the patterns in |
| 145 | ** the Glob. The value returned is actually a 1-based index of the pattern |
| 146 | ** that matched. Return 0 if none of the patterns match zString. |
| 147 | ** |
| 148 |
+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 |
+1
-1
| --- src/publish.c | ||
| +++ src/publish.c | ||
| @@ -58,11 +58,11 @@ | ||
| 58 | 58 | ** |
| 59 | 59 | ** Cause artifacts identified by TAGS... to be published (made non-private). |
| 60 | 60 | ** This can be used (for example) to convert a private branch into a public |
| 61 | 61 | ** branch, or to publish a bundle that was imported privately. |
| 62 | 62 | ** |
| 63 | -** If any of TAGS names a branch, then all checkins on that most recent | |
| 63 | +** If any of TAGS names a branch, then all checkins on the most recent | |
| 64 | 64 | ** instance of that branch are included, not just the most recent checkin. |
| 65 | 65 | ** |
| 66 | 66 | ** If any of TAGS name checkins then all files and tags associated with |
| 67 | 67 | ** those checkins are also published automatically. Except if the --only |
| 68 | 68 | ** option is used, then only the specific artifacts identified by TAGS |
| 69 | 69 |
| --- src/publish.c | |
| +++ src/publish.c | |
| @@ -58,11 +58,11 @@ | |
| 58 | ** |
| 59 | ** Cause artifacts identified by TAGS... to be published (made non-private). |
| 60 | ** This can be used (for example) to convert a private branch into a public |
| 61 | ** branch, or to publish a bundle that was imported privately. |
| 62 | ** |
| 63 | ** If any of TAGS names a branch, then all checkins on that most recent |
| 64 | ** instance of that branch are included, not just the most recent checkin. |
| 65 | ** |
| 66 | ** If any of TAGS name checkins then all files and tags associated with |
| 67 | ** those checkins are also published automatically. Except if the --only |
| 68 | ** option is used, then only the specific artifacts identified by TAGS |
| 69 |
| --- src/publish.c | |
| +++ src/publish.c | |
| @@ -58,11 +58,11 @@ | |
| 58 | ** |
| 59 | ** Cause artifacts identified by TAGS... to be published (made non-private). |
| 60 | ** This can be used (for example) to convert a private branch into a public |
| 61 | ** branch, or to publish a bundle that was imported privately. |
| 62 | ** |
| 63 | ** If any of TAGS names a branch, then all checkins on the most recent |
| 64 | ** instance of that branch are included, not just the most recent checkin. |
| 65 | ** |
| 66 | ** If any of TAGS name checkins then all files and tags associated with |
| 67 | ** those checkins are also published automatically. Except if the --only |
| 68 | ** option is used, then only the specific artifacts identified by TAGS |
| 69 |
+5
-5
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -126,11 +126,11 @@ | ||
| 126 | 126 | @ info TEXT, -- contact information |
| 127 | 127 | @ mtime DATE, -- last change. seconds since 1970 |
| 128 | 128 | @ photo BLOB -- JPEG image of this user |
| 129 | 129 | @ ); |
| 130 | 130 | @ |
| 131 | -@ -- The VAR table holds miscellanous information about the repository. | |
| 131 | +@ -- The config table holds miscellanous information about the repository. | |
| 132 | 132 | @ -- in the form of name-value pairs. |
| 133 | 133 | @ -- |
| 134 | 134 | @ CREATE TABLE config( |
| 135 | 135 | @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry |
| 136 | 136 | @ value CLOB, -- Content of the named parameter |
| @@ -449,12 +449,12 @@ | ||
| 449 | 449 | #if EXPORT_INTERFACE |
| 450 | 450 | # define MAX_INT_TAG 16 /* The largest pre-assigned tag id */ |
| 451 | 451 | #endif |
| 452 | 452 | |
| 453 | 453 | /* |
| 454 | -** The schema for the locate FOSSIL database file found at the root | |
| 455 | -** of very check-out. This database contains the complete state of | |
| 454 | +** The schema for the local FOSSIL database file found at the root | |
| 455 | +** of every check-out. This database contains the complete state of | |
| 456 | 456 | ** the checkout. |
| 457 | 457 | */ |
| 458 | 458 | const char zLocalSchema[] = |
| 459 | 459 | @ -- The VVAR table holds miscellanous information about the local database |
| 460 | 460 | @ -- in the form of name-value pairs. This is similar to the VAR table |
| @@ -481,12 +481,12 @@ | ||
| 481 | 481 | @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have |
| 482 | 482 | @ -- been edited or which have been subjected to a 3-way merge. |
| 483 | 483 | @ -- Vfile.chnged is 2 if the file has been replaced from a different |
| 484 | 484 | @ -- version by the merge and 3 if the file has been added by a merge. |
| 485 | 485 | @ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been |
| 486 | -@ -- done by an --integrate merge. The difference between vfile.chnged==2|4 | |
| 487 | -@ -- and a regular add is that with vfile.chnged==2|4 we know that the | |
| 486 | +@ -- done by an --integrate merge. The difference between vfile.chnged==3|5 | |
| 487 | +@ -- and a regular add is that with vfile.chnged==3|5 we know that the | |
| 488 | 488 | @ -- current version of the file is already in the repository. |
| 489 | 489 | @ -- |
| 490 | 490 | @ CREATE TABLE vfile( |
| 491 | 491 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 492 | 492 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 493 | 493 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -126,11 +126,11 @@ | |
| 126 | @ info TEXT, -- contact information |
| 127 | @ mtime DATE, -- last change. seconds since 1970 |
| 128 | @ photo BLOB -- JPEG image of this user |
| 129 | @ ); |
| 130 | @ |
| 131 | @ -- The VAR table holds miscellanous information about the repository. |
| 132 | @ -- in the form of name-value pairs. |
| 133 | @ -- |
| 134 | @ CREATE TABLE config( |
| 135 | @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry |
| 136 | @ value CLOB, -- Content of the named parameter |
| @@ -449,12 +449,12 @@ | |
| 449 | #if EXPORT_INTERFACE |
| 450 | # define MAX_INT_TAG 16 /* The largest pre-assigned tag id */ |
| 451 | #endif |
| 452 | |
| 453 | /* |
| 454 | ** The schema for the locate FOSSIL database file found at the root |
| 455 | ** of very check-out. This database contains the complete state of |
| 456 | ** the checkout. |
| 457 | */ |
| 458 | const char zLocalSchema[] = |
| 459 | @ -- The VVAR table holds miscellanous information about the local database |
| 460 | @ -- in the form of name-value pairs. This is similar to the VAR table |
| @@ -481,12 +481,12 @@ | |
| 481 | @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have |
| 482 | @ -- been edited or which have been subjected to a 3-way merge. |
| 483 | @ -- Vfile.chnged is 2 if the file has been replaced from a different |
| 484 | @ -- version by the merge and 3 if the file has been added by a merge. |
| 485 | @ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been |
| 486 | @ -- done by an --integrate merge. The difference between vfile.chnged==2|4 |
| 487 | @ -- and a regular add is that with vfile.chnged==2|4 we know that the |
| 488 | @ -- current version of the file is already in the repository. |
| 489 | @ -- |
| 490 | @ CREATE TABLE vfile( |
| 491 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 492 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 493 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -126,11 +126,11 @@ | |
| 126 | @ info TEXT, -- contact information |
| 127 | @ mtime DATE, -- last change. seconds since 1970 |
| 128 | @ photo BLOB -- JPEG image of this user |
| 129 | @ ); |
| 130 | @ |
| 131 | @ -- The config table holds miscellanous information about the repository. |
| 132 | @ -- in the form of name-value pairs. |
| 133 | @ -- |
| 134 | @ CREATE TABLE config( |
| 135 | @ name TEXT PRIMARY KEY NOT NULL, -- Primary name of the entry |
| 136 | @ value CLOB, -- Content of the named parameter |
| @@ -449,12 +449,12 @@ | |
| 449 | #if EXPORT_INTERFACE |
| 450 | # define MAX_INT_TAG 16 /* The largest pre-assigned tag id */ |
| 451 | #endif |
| 452 | |
| 453 | /* |
| 454 | ** The schema for the local FOSSIL database file found at the root |
| 455 | ** of every check-out. This database contains the complete state of |
| 456 | ** the checkout. |
| 457 | */ |
| 458 | const char zLocalSchema[] = |
| 459 | @ -- The VVAR table holds miscellanous information about the local database |
| 460 | @ -- in the form of name-value pairs. This is similar to the VAR table |
| @@ -481,12 +481,12 @@ | |
| 481 | @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have |
| 482 | @ -- been edited or which have been subjected to a 3-way merge. |
| 483 | @ -- Vfile.chnged is 2 if the file has been replaced from a different |
| 484 | @ -- version by the merge and 3 if the file has been added by a merge. |
| 485 | @ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been |
| 486 | @ -- done by an --integrate merge. The difference between vfile.chnged==3|5 |
| 487 | @ -- and a regular add is that with vfile.chnged==3|5 we know that the |
| 488 | @ -- current version of the file is already in the repository. |
| 489 | @ -- |
| 490 | @ CREATE TABLE vfile( |
| 491 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 492 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 493 |
+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 |
+270
-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 | |
| @@ -1428,10 +1470,21 @@ | ||
| 1428 | 1470 | } |
| 1429 | 1471 | } |
| 1430 | 1472 | sqlite3_finalize(pExplain); |
| 1431 | 1473 | sqlite3_free(zEQP); |
| 1432 | 1474 | } |
| 1475 | + | |
| 1476 | +#if USE_SYSTEM_SQLITE+0==1 | |
| 1477 | + /* Output TESTCTRL_EXPLAIN text of requested */ | |
| 1478 | + if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){ | |
| 1479 | + const char *zExplain = 0; | |
| 1480 | + sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); | |
| 1481 | + if( zExplain && zExplain[0] ){ | |
| 1482 | + fprintf(pArg->out, "%s", zExplain); | |
| 1483 | + } | |
| 1484 | + } | |
| 1485 | +#endif | |
| 1433 | 1486 | |
| 1434 | 1487 | /* If the shell is currently in ".explain" mode, gather the extra |
| 1435 | 1488 | ** data required to add indents to the output.*/ |
| 1436 | 1489 | if( pArg && pArg->mode==MODE_Explain ){ |
| 1437 | 1490 | explain_data_prepare(pArg, pStmt); |
| @@ -1696,16 +1749,17 @@ | ||
| 1696 | 1749 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1697 | 1750 | ".load FILE ?ENTRY? Load an extension library\n" |
| 1698 | 1751 | #endif |
| 1699 | 1752 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" |
| 1700 | 1753 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" |
| 1754 | + " ascii Columns/rows delimited by 0x1F and 0x1E\n" | |
| 1701 | 1755 | " csv Comma-separated values\n" |
| 1702 | 1756 | " column Left-aligned columns. (See .width)\n" |
| 1703 | 1757 | " html HTML <table> code\n" |
| 1704 | 1758 | " insert SQL insert statements for TABLE\n" |
| 1705 | 1759 | " line One value per line\n" |
| 1706 | - " list Values delimited by .separator string\n" | |
| 1760 | + " list Values delimited by .separator strings\n" | |
| 1707 | 1761 | " tabs Tab-separated values\n" |
| 1708 | 1762 | " tcl TCL list elements\n" |
| 1709 | 1763 | ".nullvalue STRING Use STRING in place of NULL values\n" |
| 1710 | 1764 | ".once FILENAME Output for the next SQL command only to FILENAME\n" |
| 1711 | 1765 | ".open ?FILENAME? Close existing database and reopen FILENAME\n" |
| @@ -1718,12 +1772,12 @@ | ||
| 1718 | 1772 | ".save FILE Write in-memory database into FILE\n" |
| 1719 | 1773 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" |
| 1720 | 1774 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1721 | 1775 | " If TABLE specified, only show tables matching\n" |
| 1722 | 1776 | " 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" | |
| 1777 | + ".separator COL ?ROW? Change the column separator and optionally the row\n" | |
| 1778 | + " separator for both the output mode and .import\n" | |
| 1725 | 1779 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1726 | 1780 | ".show Show the current values for various settings\n" |
| 1727 | 1781 | ".stats on|off Turn stats on or off\n" |
| 1728 | 1782 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1729 | 1783 | ".tables ?TABLE? List names of tables\n" |
| @@ -2000,26 +2054,27 @@ | ||
| 2000 | 2054 | static int nCall = 0; |
| 2001 | 2055 | nCall++; |
| 2002 | 2056 | } |
| 2003 | 2057 | |
| 2004 | 2058 | /* |
| 2005 | -** An object used to read a CSV file | |
| 2059 | +** An object used to read a CSV and other files for import. | |
| 2006 | 2060 | */ |
| 2007 | -typedef struct CSVReader CSVReader; | |
| 2008 | -struct CSVReader { | |
| 2061 | +typedef struct ImportCtx ImportCtx; | |
| 2062 | +struct ImportCtx { | |
| 2009 | 2063 | const char *zFile; /* Name of the input file */ |
| 2010 | 2064 | FILE *in; /* Read the CSV text from this input stream */ |
| 2011 | 2065 | char *z; /* Accumulated text for a field */ |
| 2012 | 2066 | int n; /* Number of bytes in z */ |
| 2013 | 2067 | int nAlloc; /* Space allocated for z[] */ |
| 2014 | 2068 | int nLine; /* Current line number */ |
| 2015 | 2069 | int cTerm; /* Character that terminated the most recent field */ |
| 2016 | - int cSeparator; /* The separator character. (Usually ",") */ | |
| 2070 | + int cColSep; /* The column separator character. (Usually ",") */ | |
| 2071 | + int cRowSep; /* The row separator character. (Usually "\n") */ | |
| 2017 | 2072 | }; |
| 2018 | 2073 | |
| 2019 | 2074 | /* Append a single byte to z[] */ |
| 2020 | -static void csv_append_char(CSVReader *p, int c){ | |
| 2075 | +static void import_append_char(ImportCtx *p, int c){ | |
| 2021 | 2076 | if( p->n+1>=p->nAlloc ){ |
| 2022 | 2077 | p->nAlloc += p->nAlloc + 100; |
| 2023 | 2078 | p->z = sqlite3_realloc(p->z, p->nAlloc); |
| 2024 | 2079 | if( p->z==0 ){ |
| 2025 | 2080 | fprintf(stderr, "out of memory\n"); |
| @@ -2033,41 +2088,44 @@ | ||
| 2033 | 2088 | ** with the option of having a separator other than ",". |
| 2034 | 2089 | ** |
| 2035 | 2090 | ** + Input comes from p->in. |
| 2036 | 2091 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2037 | 2092 | ** from sqlite3_malloc(). |
| 2038 | -** + Use p->cSep as the separator. The default is ",". | |
| 2093 | +** + Use p->cSep as the column separator. The default is ",". | |
| 2094 | +** + Use p->rSep as the row separator. The default is "\n". | |
| 2039 | 2095 | ** + Keep track of the line number in p->nLine. |
| 2040 | 2096 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2041 | 2097 | ** EOF on end-of-file. |
| 2042 | 2098 | ** + Report syntax errors on stderr |
| 2043 | 2099 | */ |
| 2044 | -static char *csv_read_one_field(CSVReader *p){ | |
| 2045 | - int c, pc, ppc; | |
| 2046 | - int cSep = p->cSeparator; | |
| 2100 | +static char *csv_read_one_field(ImportCtx *p){ | |
| 2101 | + int c; | |
| 2102 | + int cSep = p->cColSep; | |
| 2103 | + int rSep = p->cRowSep; | |
| 2047 | 2104 | p->n = 0; |
| 2048 | 2105 | c = fgetc(p->in); |
| 2049 | 2106 | if( c==EOF || seenInterrupt ){ |
| 2050 | 2107 | p->cTerm = EOF; |
| 2051 | 2108 | return 0; |
| 2052 | 2109 | } |
| 2053 | 2110 | if( c=='"' ){ |
| 2111 | + int pc, ppc; | |
| 2054 | 2112 | int startLine = p->nLine; |
| 2055 | 2113 | int cQuote = c; |
| 2056 | 2114 | pc = ppc = 0; |
| 2057 | 2115 | while( 1 ){ |
| 2058 | 2116 | c = fgetc(p->in); |
| 2059 | - if( c=='\n' ) p->nLine++; | |
| 2117 | + if( c==rSep ) p->nLine++; | |
| 2060 | 2118 | if( c==cQuote ){ |
| 2061 | 2119 | if( pc==cQuote ){ |
| 2062 | 2120 | pc = 0; |
| 2063 | 2121 | continue; |
| 2064 | 2122 | } |
| 2065 | 2123 | } |
| 2066 | 2124 | if( (c==cSep && pc==cQuote) |
| 2067 | - || (c=='\n' && pc==cQuote) | |
| 2068 | - || (c=='\n' && pc=='\r' && ppc==cQuote) | |
| 2125 | + || (c==rSep && pc==cQuote) | |
| 2126 | + || (c==rSep && pc=='\r' && ppc==cQuote) | |
| 2069 | 2127 | || (c==EOF && pc==cQuote) |
| 2070 | 2128 | ){ |
| 2071 | 2129 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
| 2072 | 2130 | p->cTerm = c; |
| 2073 | 2131 | break; |
| @@ -2077,31 +2135,65 @@ | ||
| 2077 | 2135 | p->zFile, p->nLine, cQuote); |
| 2078 | 2136 | } |
| 2079 | 2137 | if( c==EOF ){ |
| 2080 | 2138 | fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", |
| 2081 | 2139 | p->zFile, startLine, cQuote); |
| 2082 | - p->cTerm = EOF; | |
| 2140 | + p->cTerm = c; | |
| 2083 | 2141 | break; |
| 2084 | 2142 | } |
| 2085 | - csv_append_char(p, c); | |
| 2143 | + import_append_char(p, c); | |
| 2086 | 2144 | ppc = pc; |
| 2087 | 2145 | pc = c; |
| 2088 | 2146 | } |
| 2089 | 2147 | }else{ |
| 2090 | - while( c!=EOF && c!=cSep && c!='\n' ){ | |
| 2091 | - csv_append_char(p, c); | |
| 2148 | + while( c!=EOF && c!=cSep && c!=rSep ){ | |
| 2149 | + import_append_char(p, c); | |
| 2092 | 2150 | c = fgetc(p->in); |
| 2093 | 2151 | } |
| 2094 | - if( c=='\n' ){ | |
| 2152 | + if( c==rSep ){ | |
| 2095 | 2153 | p->nLine++; |
| 2096 | 2154 | if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; |
| 2097 | 2155 | } |
| 2098 | 2156 | p->cTerm = c; |
| 2099 | 2157 | } |
| 2100 | 2158 | if( p->z ) p->z[p->n] = 0; |
| 2101 | 2159 | return p->z; |
| 2102 | 2160 | } |
| 2161 | + | |
| 2162 | +/* Read a single field of ASCII delimited text. | |
| 2163 | +** | |
| 2164 | +** + Input comes from p->in. | |
| 2165 | +** + Store results in p->z of length p->n. Space to hold p->z comes | |
| 2166 | +** from sqlite3_malloc(). | |
| 2167 | +** + Use p->cSep as the column separator. The default is "\x1F". | |
| 2168 | +** + Use p->rSep as the row separator. The default is "\x1E". | |
| 2169 | +** + Keep track of the row number in p->nLine. | |
| 2170 | +** + Store the character that terminates the field in p->cTerm. Store | |
| 2171 | +** EOF on end-of-file. | |
| 2172 | +** + Report syntax errors on stderr | |
| 2173 | +*/ | |
| 2174 | +static char *ascii_read_one_field(ImportCtx *p){ | |
| 2175 | + int c; | |
| 2176 | + int cSep = p->cColSep; | |
| 2177 | + int rSep = p->cRowSep; | |
| 2178 | + p->n = 0; | |
| 2179 | + c = fgetc(p->in); | |
| 2180 | + if( c==EOF || seenInterrupt ){ | |
| 2181 | + p->cTerm = EOF; | |
| 2182 | + return 0; | |
| 2183 | + } | |
| 2184 | + while( c!=EOF && c!=cSep && c!=rSep ){ | |
| 2185 | + import_append_char(p, c); | |
| 2186 | + c = fgetc(p->in); | |
| 2187 | + } | |
| 2188 | + if( c==rSep ){ | |
| 2189 | + p->nLine++; | |
| 2190 | + } | |
| 2191 | + p->cTerm = c; | |
| 2192 | + if( p->z ) p->z[p->n] = 0; | |
| 2193 | + return p->z; | |
| 2194 | +} | |
| 2103 | 2195 | |
| 2104 | 2196 | /* |
| 2105 | 2197 | ** Try to transfer data for table zTable. If an error is seen while |
| 2106 | 2198 | ** moving forward, try to go backwards. The backwards movement won't |
| 2107 | 2199 | ** work for WITHOUT ROWID tables. |
| @@ -2653,100 +2745,125 @@ | ||
| 2653 | 2745 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
| 2654 | 2746 | int nCol; /* Number of columns in the table */ |
| 2655 | 2747 | int nByte; /* Number of bytes in an SQL string */ |
| 2656 | 2748 | int i, j; /* Loop counters */ |
| 2657 | 2749 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
| 2658 | - int nSep; /* Number of bytes in p->separator[] */ | |
| 2750 | + int nSep; /* Number of bytes in p->colSeparator[] */ | |
| 2659 | 2751 | char *zSql; /* An SQL statement */ |
| 2660 | - CSVReader sCsv; /* Reader context */ | |
| 2752 | + ImportCtx sCtx; /* Reader context */ | |
| 2753 | + char *(*xRead)(ImportCtx*); /* Procedure to read one value */ | |
| 2661 | 2754 | int (*xCloser)(FILE*); /* Procedure to close th3 connection */ |
| 2662 | 2755 | |
| 2663 | 2756 | if( nArg!=3 ){ |
| 2664 | 2757 | fprintf(stderr, "Usage: .import FILE TABLE\n"); |
| 2665 | 2758 | goto meta_command_exit; |
| 2666 | 2759 | } |
| 2667 | 2760 | zFile = azArg[1]; |
| 2668 | 2761 | zTable = azArg[2]; |
| 2669 | 2762 | seenInterrupt = 0; |
| 2670 | - memset(&sCsv, 0, sizeof(sCsv)); | |
| 2763 | + memset(&sCtx, 0, sizeof(sCtx)); | |
| 2671 | 2764 | open_db(p, 0); |
| 2672 | - nSep = strlen30(p->separator); | |
| 2765 | + nSep = strlen30(p->colSeparator); | |
| 2766 | + if( nSep==0 ){ | |
| 2767 | + fprintf(stderr, "Error: non-null column separator required for import\n"); | |
| 2768 | + return 1; | |
| 2769 | + } | |
| 2770 | + if( nSep>1 ){ | |
| 2771 | + fprintf(stderr, "Error: multi-character column separators not allowed" | |
| 2772 | + " for import\n"); | |
| 2773 | + return 1; | |
| 2774 | + } | |
| 2775 | + nSep = strlen30(p->rowSeparator); | |
| 2673 | 2776 | if( nSep==0 ){ |
| 2674 | - fprintf(stderr, "Error: non-null separator required for import\n"); | |
| 2777 | + fprintf(stderr, "Error: non-null row separator required for import\n"); | |
| 2675 | 2778 | return 1; |
| 2779 | + } | |
| 2780 | + if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ | |
| 2781 | + /* When importing CSV (only), if the row separator is set to the | |
| 2782 | + ** default output row separator, change it to the default input | |
| 2783 | + ** row separator. This avoids having to maintain different input | |
| 2784 | + ** and output row separators. */ | |
| 2785 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 2786 | + nSep = strlen30(p->rowSeparator); | |
| 2676 | 2787 | } |
| 2677 | 2788 | if( nSep>1 ){ |
| 2678 | - fprintf(stderr, "Error: multi-character separators not allowed" | |
| 2789 | + fprintf(stderr, "Error: multi-character row separators not allowed" | |
| 2679 | 2790 | " for import\n"); |
| 2680 | 2791 | return 1; |
| 2681 | 2792 | } |
| 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>"; | |
| 2793 | + sCtx.zFile = zFile; | |
| 2794 | + sCtx.nLine = 1; | |
| 2795 | + if( sCtx.zFile[0]=='|' ){ | |
| 2796 | + sCtx.in = popen(sCtx.zFile+1, "r"); | |
| 2797 | + sCtx.zFile = "<pipe>"; | |
| 2687 | 2798 | xCloser = pclose; |
| 2688 | 2799 | }else{ |
| 2689 | - sCsv.in = fopen(sCsv.zFile, "rb"); | |
| 2800 | + sCtx.in = fopen(sCtx.zFile, "rb"); | |
| 2690 | 2801 | xCloser = fclose; |
| 2691 | 2802 | } |
| 2692 | - if( sCsv.in==0 ){ | |
| 2803 | + if( p->mode==MODE_Ascii ){ | |
| 2804 | + xRead = ascii_read_one_field; | |
| 2805 | + }else{ | |
| 2806 | + xRead = csv_read_one_field; | |
| 2807 | + } | |
| 2808 | + if( sCtx.in==0 ){ | |
| 2693 | 2809 | fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); |
| 2694 | 2810 | return 1; |
| 2695 | 2811 | } |
| 2696 | - sCsv.cSeparator = p->separator[0]; | |
| 2812 | + sCtx.cColSep = p->colSeparator[0]; | |
| 2813 | + sCtx.cRowSep = p->rowSeparator[0]; | |
| 2697 | 2814 | zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); |
| 2698 | 2815 | if( zSql==0 ){ |
| 2699 | 2816 | fprintf(stderr, "Error: out of memory\n"); |
| 2700 | - xCloser(sCsv.in); | |
| 2817 | + xCloser(sCtx.in); | |
| 2701 | 2818 | return 1; |
| 2702 | 2819 | } |
| 2703 | 2820 | nByte = strlen30(zSql); |
| 2704 | 2821 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2705 | - csv_append_char(&sCsv, 0); /* To ensure sCsv.z is allocated */ | |
| 2822 | + import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ | |
| 2706 | 2823 | if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ |
| 2707 | 2824 | char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
| 2708 | 2825 | char cSep = '('; |
| 2709 | - while( csv_read_one_field(&sCsv) ){ | |
| 2710 | - zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z); | |
| 2826 | + while( xRead(&sCtx) ){ | |
| 2827 | + zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z); | |
| 2711 | 2828 | cSep = ','; |
| 2712 | - if( sCsv.cTerm!=sCsv.cSeparator ) break; | |
| 2829 | + if( sCtx.cTerm!=sCtx.cColSep ) break; | |
| 2713 | 2830 | } |
| 2714 | 2831 | if( cSep=='(' ){ |
| 2715 | 2832 | sqlite3_free(zCreate); |
| 2716 | - sqlite3_free(sCsv.z); | |
| 2717 | - xCloser(sCsv.in); | |
| 2718 | - fprintf(stderr,"%s: empty file\n", sCsv.zFile); | |
| 2833 | + sqlite3_free(sCtx.z); | |
| 2834 | + xCloser(sCtx.in); | |
| 2835 | + fprintf(stderr,"%s: empty file\n", sCtx.zFile); | |
| 2719 | 2836 | return 1; |
| 2720 | 2837 | } |
| 2721 | 2838 | zCreate = sqlite3_mprintf("%z\n)", zCreate); |
| 2722 | 2839 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
| 2723 | 2840 | sqlite3_free(zCreate); |
| 2724 | 2841 | if( rc ){ |
| 2725 | 2842 | fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
| 2726 | 2843 | sqlite3_errmsg(db)); |
| 2727 | - sqlite3_free(sCsv.z); | |
| 2728 | - xCloser(sCsv.in); | |
| 2844 | + sqlite3_free(sCtx.z); | |
| 2845 | + xCloser(sCtx.in); | |
| 2729 | 2846 | return 1; |
| 2730 | 2847 | } |
| 2731 | 2848 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2732 | 2849 | } |
| 2733 | 2850 | sqlite3_free(zSql); |
| 2734 | 2851 | if( rc ){ |
| 2735 | 2852 | if (pStmt) sqlite3_finalize(pStmt); |
| 2736 | 2853 | fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |
| 2737 | - xCloser(sCsv.in); | |
| 2854 | + xCloser(sCtx.in); | |
| 2738 | 2855 | return 1; |
| 2739 | 2856 | } |
| 2740 | 2857 | nCol = sqlite3_column_count(pStmt); |
| 2741 | 2858 | sqlite3_finalize(pStmt); |
| 2742 | 2859 | pStmt = 0; |
| 2743 | 2860 | if( nCol==0 ) return 0; /* no columns, no error */ |
| 2744 | 2861 | zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); |
| 2745 | 2862 | if( zSql==0 ){ |
| 2746 | 2863 | fprintf(stderr, "Error: out of memory\n"); |
| 2747 | - xCloser(sCsv.in); | |
| 2864 | + xCloser(sCtx.in); | |
| 2748 | 2865 | return 1; |
| 2749 | 2866 | } |
| 2750 | 2867 | sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); |
| 2751 | 2868 | j = strlen30(zSql); |
| 2752 | 2869 | for(i=1; i<nCol; i++){ |
| @@ -2758,50 +2875,60 @@ | ||
| 2758 | 2875 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2759 | 2876 | sqlite3_free(zSql); |
| 2760 | 2877 | if( rc ){ |
| 2761 | 2878 | fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |
| 2762 | 2879 | if (pStmt) sqlite3_finalize(pStmt); |
| 2763 | - xCloser(sCsv.in); | |
| 2880 | + xCloser(sCtx.in); | |
| 2764 | 2881 | return 1; |
| 2765 | 2882 | } |
| 2766 | 2883 | needCommit = sqlite3_get_autocommit(db); |
| 2767 | 2884 | if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); |
| 2768 | 2885 | do{ |
| 2769 | - int startLine = sCsv.nLine; | |
| 2886 | + int startLine = sCtx.nLine; | |
| 2770 | 2887 | for(i=0; i<nCol; i++){ |
| 2771 | - char *z = csv_read_one_field(&sCsv); | |
| 2888 | + char *z = xRead(&sCtx); | |
| 2889 | + /* | |
| 2890 | + ** Did we reach end-of-file before finding any columns? | |
| 2891 | + ** If so, stop instead of NULL filling the remaining columns. | |
| 2892 | + */ | |
| 2772 | 2893 | if( z==0 && i==0 ) break; |
| 2894 | + /* | |
| 2895 | + ** Did we reach end-of-file OR end-of-line before finding any | |
| 2896 | + ** columns in ASCII mode? If so, stop instead of NULL filling | |
| 2897 | + ** the remaining columns. | |
| 2898 | + */ | |
| 2899 | + if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; | |
| 2773 | 2900 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2774 | - if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){ | |
| 2901 | + if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ | |
| 2775 | 2902 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2776 | 2903 | "filling the rest with NULL\n", |
| 2777 | - sCsv.zFile, startLine, nCol, i+1); | |
| 2904 | + sCtx.zFile, startLine, nCol, i+1); | |
| 2778 | 2905 | i++; |
| 2779 | 2906 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2780 | 2907 | } |
| 2781 | 2908 | } |
| 2782 | - if( sCsv.cTerm==sCsv.cSeparator ){ | |
| 2909 | + if( sCtx.cTerm==sCtx.cColSep ){ | |
| 2783 | 2910 | do{ |
| 2784 | - csv_read_one_field(&sCsv); | |
| 2911 | + xRead(&sCtx); | |
| 2785 | 2912 | i++; |
| 2786 | - }while( sCsv.cTerm==sCsv.cSeparator ); | |
| 2913 | + }while( sCtx.cTerm==sCtx.cColSep ); | |
| 2787 | 2914 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2788 | 2915 | "extras ignored\n", |
| 2789 | - sCsv.zFile, startLine, nCol, i); | |
| 2916 | + sCtx.zFile, startLine, nCol, i); | |
| 2790 | 2917 | } |
| 2791 | 2918 | if( i>=nCol ){ |
| 2792 | 2919 | sqlite3_step(pStmt); |
| 2793 | 2920 | rc = sqlite3_reset(pStmt); |
| 2794 | 2921 | if( rc!=SQLITE_OK ){ |
| 2795 | - fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine, | |
| 2922 | + fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, | |
| 2796 | 2923 | sqlite3_errmsg(db)); |
| 2797 | 2924 | } |
| 2798 | 2925 | } |
| 2799 | - }while( sCsv.cTerm!=EOF ); | |
| 2926 | + }while( sCtx.cTerm!=EOF ); | |
| 2800 | 2927 | |
| 2801 | - xCloser(sCsv.in); | |
| 2802 | - sqlite3_free(sCsv.z); | |
| 2928 | + xCloser(sCtx.in); | |
| 2929 | + sqlite3_free(sCtx.z); | |
| 2803 | 2930 | sqlite3_finalize(pStmt); |
| 2804 | 2931 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2805 | 2932 | }else |
| 2806 | 2933 | |
| 2807 | 2934 | if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ |
| @@ -2915,32 +3042,36 @@ | ||
| 2915 | 3042 | p->mode = MODE_List; |
| 2916 | 3043 | }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ |
| 2917 | 3044 | p->mode = MODE_Html; |
| 2918 | 3045 | }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ |
| 2919 | 3046 | p->mode = MODE_Tcl; |
| 2920 | - sqlite3_snprintf(sizeof(p->separator), p->separator, " "); | |
| 3047 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); | |
| 2921 | 3048 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 2922 | 3049 | p->mode = MODE_Csv; |
| 2923 | - sqlite3_snprintf(sizeof(p->separator), p->separator, ","); | |
| 2924 | - sqlite3_snprintf(sizeof(p->newline), p->newline, "\r\n"); | |
| 3050 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); | |
| 3051 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); | |
| 2925 | 3052 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 2926 | 3053 | p->mode = MODE_List; |
| 2927 | - sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); | |
| 3054 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); | |
| 2928 | 3055 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 2929 | 3056 | p->mode = MODE_Insert; |
| 2930 | 3057 | set_table_name(p, nArg>=3 ? azArg[2] : "table"); |
| 3058 | + }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ | |
| 3059 | + p->mode = MODE_Ascii; | |
| 3060 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); | |
| 3061 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); | |
| 2931 | 3062 | }else { |
| 2932 | 3063 | fprintf(stderr,"Error: mode should be one of: " |
| 2933 | - "column csv html insert line list tabs tcl\n"); | |
| 3064 | + "ascii column csv html insert line list tabs tcl\n"); | |
| 2934 | 3065 | rc = 1; |
| 2935 | 3066 | } |
| 2936 | 3067 | }else |
| 2937 | 3068 | |
| 2938 | 3069 | if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ |
| 2939 | 3070 | if( nArg==2 ){ |
| 2940 | - sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, | |
| 2941 | - "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); | |
| 3071 | + sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, | |
| 3072 | + "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); | |
| 2942 | 3073 | }else{ |
| 2943 | 3074 | fprintf(stderr, "Usage: .nullvalue STRING\n"); |
| 2944 | 3075 | rc = 1; |
| 2945 | 3076 | } |
| 2946 | 3077 | }else |
| @@ -3221,18 +3352,20 @@ | ||
| 3221 | 3352 | }else |
| 3222 | 3353 | #endif |
| 3223 | 3354 | |
| 3224 | 3355 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3225 | 3356 | if( nArg<2 || nArg>3 ){ |
| 3226 | - fprintf(stderr, "Usage: .separator SEPARATOR ?NEWLINE?\n"); | |
| 3357 | + fprintf(stderr, "Usage: .separator COL ?ROW?\n"); | |
| 3227 | 3358 | rc = 1; |
| 3228 | 3359 | } |
| 3229 | 3360 | if( nArg>=2 ){ |
| 3230 | - sqlite3_snprintf(sizeof(p->separator), p->separator, azArg[1]); | |
| 3361 | + sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, | |
| 3362 | + "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); | |
| 3231 | 3363 | } |
| 3232 | 3364 | if( nArg>=3 ){ |
| 3233 | - sqlite3_snprintf(sizeof(p->newline), p->newline, azArg[2]); | |
| 3365 | + sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, | |
| 3366 | + "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); | |
| 3234 | 3367 | } |
| 3235 | 3368 | }else |
| 3236 | 3369 | |
| 3237 | 3370 | if( c=='s' |
| 3238 | 3371 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| @@ -3259,27 +3392,28 @@ | ||
| 3259 | 3392 | if( nArg!=1 ){ |
| 3260 | 3393 | fprintf(stderr, "Usage: .show\n"); |
| 3261 | 3394 | rc = 1; |
| 3262 | 3395 | goto meta_command_exit; |
| 3263 | 3396 | } |
| 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"); | |
| 3397 | + fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); | |
| 3398 | + fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); | |
| 3266 | 3399 | 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); | |
| 3400 | + fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); | |
| 3401 | + fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]); | |
| 3402 | + fprintf(p->out,"%12.12s: ", "nullvalue"); | |
| 3403 | + output_c_string(p->out, p->nullValue); | |
| 3271 | 3404 | fprintf(p->out, "\n"); |
| 3272 | - fprintf(p->out,"%9.9s: %s\n","output", | |
| 3405 | + fprintf(p->out,"%12.12s: %s\n","output", | |
| 3273 | 3406 | 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); | |
| 3407 | + fprintf(p->out,"%12.12s: ", "colseparator"); | |
| 3408 | + output_c_string(p->out, p->colSeparator); | |
| 3409 | + fprintf(p->out, "\n"); | |
| 3410 | + fprintf(p->out,"%12.12s: ", "rowseparator"); | |
| 3411 | + output_c_string(p->out, p->rowSeparator); | |
| 3278 | 3412 | fprintf(p->out, "\n"); |
| 3279 | - fprintf(p->out,"%9.9s: %s\n","stats", p->statsOn ? "on" : "off"); | |
| 3280 | - fprintf(p->out,"%9.9s: ","width"); | |
| 3413 | + fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); | |
| 3414 | + fprintf(p->out,"%12.12s: ","width"); | |
| 3281 | 3415 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3282 | 3416 | fprintf(p->out,"%d ",p->colWidth[i]); |
| 3283 | 3417 | } |
| 3284 | 3418 | fprintf(p->out,"\n"); |
| 3285 | 3419 | }else |
| @@ -3936,10 +4070,11 @@ | ||
| 3936 | 4070 | |
| 3937 | 4071 | /* |
| 3938 | 4072 | ** Show available command line options |
| 3939 | 4073 | */ |
| 3940 | 4074 | static const char zOptions[] = |
| 4075 | + " -ascii set output mode to 'ascii'\n" | |
| 3941 | 4076 | " -bail stop after hitting an error\n" |
| 3942 | 4077 | " -batch force batch I/O\n" |
| 3943 | 4078 | " -column set output mode to 'column'\n" |
| 3944 | 4079 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
| 3945 | 4080 | " -csv set output mode to 'csv'\n" |
| @@ -3957,15 +4092,15 @@ | ||
| 3957 | 4092 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| 3958 | 4093 | " -mmap N default mmap size set to N\n" |
| 3959 | 4094 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 3960 | 4095 | " -multiplex enable the multiplexor VFS\n" |
| 3961 | 4096 | #endif |
| 3962 | - " -newline SEP set newline character(s) for CSV\n" | |
| 4097 | + " -newline SEP set output row separator. Default: '\\n'\n" | |
| 3963 | 4098 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 3964 | 4099 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
| 3965 | 4100 | " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" |
| 3966 | - " -separator SEP set output field separator. Default: '|'\n" | |
| 4101 | + " -separator SEP set output column separator. Default: '|'\n" | |
| 3967 | 4102 | " -stats print memory stats before each finalize\n" |
| 3968 | 4103 | " -version show SQLite version\n" |
| 3969 | 4104 | " -vfs NAME use NAME as the default VFS\n" |
| 3970 | 4105 | #ifdef SQLITE_ENABLE_VFSTRACE |
| 3971 | 4106 | " -vfstrace enable tracing of all VFS calls\n" |
| @@ -3988,12 +4123,12 @@ | ||
| 3988 | 4123 | ** Initialize the state information in data |
| 3989 | 4124 | */ |
| 3990 | 4125 | static void main_init(ShellState *data) { |
| 3991 | 4126 | memset(data, 0, sizeof(*data)); |
| 3992 | 4127 | data->mode = MODE_List; |
| 3993 | - memcpy(data->separator,"|", 2); | |
| 3994 | - memcpy(data->newline,"\r\n", 3); | |
| 4128 | + memcpy(data->colSeparator,SEP_Column, 2); | |
| 4129 | + memcpy(data->rowSeparator,SEP_Row, 2); | |
| 3995 | 4130 | data->showHeader = 0; |
| 3996 | 4131 | data->shellFlgs = SHFLG_Lookaside; |
| 3997 | 4132 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 3998 | 4133 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 3999 | 4134 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| @@ -4228,19 +4363,25 @@ | ||
| 4228 | 4363 | data.mode = MODE_Line; |
| 4229 | 4364 | }else if( strcmp(z,"-column")==0 ){ |
| 4230 | 4365 | data.mode = MODE_Column; |
| 4231 | 4366 | }else if( strcmp(z,"-csv")==0 ){ |
| 4232 | 4367 | data.mode = MODE_Csv; |
| 4233 | - memcpy(data.separator,",",2); | |
| 4368 | + memcpy(data.colSeparator,",",2); | |
| 4369 | + }else if( strcmp(z,"-ascii")==0 ){ | |
| 4370 | + data.mode = MODE_Ascii; | |
| 4371 | + sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, | |
| 4372 | + SEP_Unit); | |
| 4373 | + sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, | |
| 4374 | + SEP_Record); | |
| 4234 | 4375 | }else if( strcmp(z,"-separator")==0 ){ |
| 4235 | - sqlite3_snprintf(sizeof(data.separator), data.separator, | |
| 4376 | + sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, | |
| 4236 | 4377 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4237 | 4378 | }else if( strcmp(z,"-newline")==0 ){ |
| 4238 | - sqlite3_snprintf(sizeof(data.newline), data.newline, | |
| 4379 | + sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, | |
| 4239 | 4380 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4240 | 4381 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 4241 | - sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, | |
| 4382 | + sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, | |
| 4242 | 4383 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4243 | 4384 | }else if( strcmp(z,"-header")==0 ){ |
| 4244 | 4385 | data.showHeader = 1; |
| 4245 | 4386 | }else if( strcmp(z,"-noheader")==0 ){ |
| 4246 | 4387 | data.showHeader = 0; |
| @@ -4356,11 +4497,11 @@ | ||
| 4356 | 4497 | nHistory = strlen30(zHome) + 20; |
| 4357 | 4498 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 4358 | 4499 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
| 4359 | 4500 | } |
| 4360 | 4501 | } |
| 4361 | -#if defined(HAVE_READLINE) | |
| 4502 | +#if HAVE_READLINE | |
| 4362 | 4503 | if( zHistory ) read_history(zHistory); |
| 4363 | 4504 | #endif |
| 4364 | 4505 | rc = process_input(&data, 0); |
| 4365 | 4506 | if( zHistory ){ |
| 4366 | 4507 | stifle_history(100); |
| 4367 | 4508 |
| --- 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 | |
| @@ -1428,10 +1470,21 @@ | |
| 1428 | } |
| 1429 | } |
| 1430 | sqlite3_finalize(pExplain); |
| 1431 | sqlite3_free(zEQP); |
| 1432 | } |
| 1433 | |
| 1434 | /* If the shell is currently in ".explain" mode, gather the extra |
| 1435 | ** data required to add indents to the output.*/ |
| 1436 | if( pArg && pArg->mode==MODE_Explain ){ |
| 1437 | explain_data_prepare(pArg, pStmt); |
| @@ -1696,16 +1749,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 +1772,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 +2054,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 +2088,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 +2135,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 +2745,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 +2875,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 +3042,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 +3352,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 +3392,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 +4070,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 +4092,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 +4123,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 +4363,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 +4497,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 | |
| @@ -1428,10 +1470,21 @@ | |
| 1470 | } |
| 1471 | } |
| 1472 | sqlite3_finalize(pExplain); |
| 1473 | sqlite3_free(zEQP); |
| 1474 | } |
| 1475 | |
| 1476 | #if USE_SYSTEM_SQLITE+0==1 |
| 1477 | /* Output TESTCTRL_EXPLAIN text of requested */ |
| 1478 | if( pArg && pArg->mode==MODE_Explain && sqlite3_libversion_number()<3008007 ){ |
| 1479 | const char *zExplain = 0; |
| 1480 | sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain); |
| 1481 | if( zExplain && zExplain[0] ){ |
| 1482 | fprintf(pArg->out, "%s", zExplain); |
| 1483 | } |
| 1484 | } |
| 1485 | #endif |
| 1486 | |
| 1487 | /* If the shell is currently in ".explain" mode, gather the extra |
| 1488 | ** data required to add indents to the output.*/ |
| 1489 | if( pArg && pArg->mode==MODE_Explain ){ |
| 1490 | explain_data_prepare(pArg, pStmt); |
| @@ -1696,16 +1749,17 @@ | |
| 1749 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 1750 | ".load FILE ?ENTRY? Load an extension library\n" |
| 1751 | #endif |
| 1752 | ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" |
| 1753 | ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" |
| 1754 | " ascii Columns/rows delimited by 0x1F and 0x1E\n" |
| 1755 | " csv Comma-separated values\n" |
| 1756 | " column Left-aligned columns. (See .width)\n" |
| 1757 | " html HTML <table> code\n" |
| 1758 | " insert SQL insert statements for TABLE\n" |
| 1759 | " line One value per line\n" |
| 1760 | " list Values delimited by .separator strings\n" |
| 1761 | " tabs Tab-separated values\n" |
| 1762 | " tcl TCL list elements\n" |
| 1763 | ".nullvalue STRING Use STRING in place of NULL values\n" |
| 1764 | ".once FILENAME Output for the next SQL command only to FILENAME\n" |
| 1765 | ".open ?FILENAME? Close existing database and reopen FILENAME\n" |
| @@ -1718,12 +1772,12 @@ | |
| 1772 | ".save FILE Write in-memory database into FILE\n" |
| 1773 | ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" |
| 1774 | ".schema ?TABLE? Show the CREATE statements\n" |
| 1775 | " If TABLE specified, only show tables matching\n" |
| 1776 | " LIKE pattern TABLE.\n" |
| 1777 | ".separator COL ?ROW? Change the column separator and optionally the row\n" |
| 1778 | " separator for both the output mode and .import\n" |
| 1779 | ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1780 | ".show Show the current values for various settings\n" |
| 1781 | ".stats on|off Turn stats on or off\n" |
| 1782 | ".system CMD ARGS... Run CMD ARGS... in a system shell\n" |
| 1783 | ".tables ?TABLE? List names of tables\n" |
| @@ -2000,26 +2054,27 @@ | |
| 2054 | static int nCall = 0; |
| 2055 | nCall++; |
| 2056 | } |
| 2057 | |
| 2058 | /* |
| 2059 | ** An object used to read a CSV and other files for import. |
| 2060 | */ |
| 2061 | typedef struct ImportCtx ImportCtx; |
| 2062 | struct ImportCtx { |
| 2063 | const char *zFile; /* Name of the input file */ |
| 2064 | FILE *in; /* Read the CSV text from this input stream */ |
| 2065 | char *z; /* Accumulated text for a field */ |
| 2066 | int n; /* Number of bytes in z */ |
| 2067 | int nAlloc; /* Space allocated for z[] */ |
| 2068 | int nLine; /* Current line number */ |
| 2069 | int cTerm; /* Character that terminated the most recent field */ |
| 2070 | int cColSep; /* The column separator character. (Usually ",") */ |
| 2071 | int cRowSep; /* The row separator character. (Usually "\n") */ |
| 2072 | }; |
| 2073 | |
| 2074 | /* Append a single byte to z[] */ |
| 2075 | static void import_append_char(ImportCtx *p, int c){ |
| 2076 | if( p->n+1>=p->nAlloc ){ |
| 2077 | p->nAlloc += p->nAlloc + 100; |
| 2078 | p->z = sqlite3_realloc(p->z, p->nAlloc); |
| 2079 | if( p->z==0 ){ |
| 2080 | fprintf(stderr, "out of memory\n"); |
| @@ -2033,41 +2088,44 @@ | |
| 2088 | ** with the option of having a separator other than ",". |
| 2089 | ** |
| 2090 | ** + Input comes from p->in. |
| 2091 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2092 | ** from sqlite3_malloc(). |
| 2093 | ** + Use p->cSep as the column separator. The default is ",". |
| 2094 | ** + Use p->rSep as the row separator. The default is "\n". |
| 2095 | ** + Keep track of the line number in p->nLine. |
| 2096 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2097 | ** EOF on end-of-file. |
| 2098 | ** + Report syntax errors on stderr |
| 2099 | */ |
| 2100 | static char *csv_read_one_field(ImportCtx *p){ |
| 2101 | int c; |
| 2102 | int cSep = p->cColSep; |
| 2103 | int rSep = p->cRowSep; |
| 2104 | p->n = 0; |
| 2105 | c = fgetc(p->in); |
| 2106 | if( c==EOF || seenInterrupt ){ |
| 2107 | p->cTerm = EOF; |
| 2108 | return 0; |
| 2109 | } |
| 2110 | if( c=='"' ){ |
| 2111 | int pc, ppc; |
| 2112 | int startLine = p->nLine; |
| 2113 | int cQuote = c; |
| 2114 | pc = ppc = 0; |
| 2115 | while( 1 ){ |
| 2116 | c = fgetc(p->in); |
| 2117 | if( c==rSep ) p->nLine++; |
| 2118 | if( c==cQuote ){ |
| 2119 | if( pc==cQuote ){ |
| 2120 | pc = 0; |
| 2121 | continue; |
| 2122 | } |
| 2123 | } |
| 2124 | if( (c==cSep && pc==cQuote) |
| 2125 | || (c==rSep && pc==cQuote) |
| 2126 | || (c==rSep && pc=='\r' && ppc==cQuote) |
| 2127 | || (c==EOF && pc==cQuote) |
| 2128 | ){ |
| 2129 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
| 2130 | p->cTerm = c; |
| 2131 | break; |
| @@ -2077,31 +2135,65 @@ | |
| 2135 | p->zFile, p->nLine, cQuote); |
| 2136 | } |
| 2137 | if( c==EOF ){ |
| 2138 | fprintf(stderr, "%s:%d: unterminated %c-quoted field\n", |
| 2139 | p->zFile, startLine, cQuote); |
| 2140 | p->cTerm = c; |
| 2141 | break; |
| 2142 | } |
| 2143 | import_append_char(p, c); |
| 2144 | ppc = pc; |
| 2145 | pc = c; |
| 2146 | } |
| 2147 | }else{ |
| 2148 | while( c!=EOF && c!=cSep && c!=rSep ){ |
| 2149 | import_append_char(p, c); |
| 2150 | c = fgetc(p->in); |
| 2151 | } |
| 2152 | if( c==rSep ){ |
| 2153 | p->nLine++; |
| 2154 | if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; |
| 2155 | } |
| 2156 | p->cTerm = c; |
| 2157 | } |
| 2158 | if( p->z ) p->z[p->n] = 0; |
| 2159 | return p->z; |
| 2160 | } |
| 2161 | |
| 2162 | /* Read a single field of ASCII delimited text. |
| 2163 | ** |
| 2164 | ** + Input comes from p->in. |
| 2165 | ** + Store results in p->z of length p->n. Space to hold p->z comes |
| 2166 | ** from sqlite3_malloc(). |
| 2167 | ** + Use p->cSep as the column separator. The default is "\x1F". |
| 2168 | ** + Use p->rSep as the row separator. The default is "\x1E". |
| 2169 | ** + Keep track of the row number in p->nLine. |
| 2170 | ** + Store the character that terminates the field in p->cTerm. Store |
| 2171 | ** EOF on end-of-file. |
| 2172 | ** + Report syntax errors on stderr |
| 2173 | */ |
| 2174 | static char *ascii_read_one_field(ImportCtx *p){ |
| 2175 | int c; |
| 2176 | int cSep = p->cColSep; |
| 2177 | int rSep = p->cRowSep; |
| 2178 | p->n = 0; |
| 2179 | c = fgetc(p->in); |
| 2180 | if( c==EOF || seenInterrupt ){ |
| 2181 | p->cTerm = EOF; |
| 2182 | return 0; |
| 2183 | } |
| 2184 | while( c!=EOF && c!=cSep && c!=rSep ){ |
| 2185 | import_append_char(p, c); |
| 2186 | c = fgetc(p->in); |
| 2187 | } |
| 2188 | if( c==rSep ){ |
| 2189 | p->nLine++; |
| 2190 | } |
| 2191 | p->cTerm = c; |
| 2192 | if( p->z ) p->z[p->n] = 0; |
| 2193 | return p->z; |
| 2194 | } |
| 2195 | |
| 2196 | /* |
| 2197 | ** Try to transfer data for table zTable. If an error is seen while |
| 2198 | ** moving forward, try to go backwards. The backwards movement won't |
| 2199 | ** work for WITHOUT ROWID tables. |
| @@ -2653,100 +2745,125 @@ | |
| 2745 | sqlite3_stmt *pStmt = NULL; /* A statement */ |
| 2746 | int nCol; /* Number of columns in the table */ |
| 2747 | int nByte; /* Number of bytes in an SQL string */ |
| 2748 | int i, j; /* Loop counters */ |
| 2749 | int needCommit; /* True to COMMIT or ROLLBACK at end */ |
| 2750 | int nSep; /* Number of bytes in p->colSeparator[] */ |
| 2751 | char *zSql; /* An SQL statement */ |
| 2752 | ImportCtx sCtx; /* Reader context */ |
| 2753 | char *(*xRead)(ImportCtx*); /* Procedure to read one value */ |
| 2754 | int (*xCloser)(FILE*); /* Procedure to close th3 connection */ |
| 2755 | |
| 2756 | if( nArg!=3 ){ |
| 2757 | fprintf(stderr, "Usage: .import FILE TABLE\n"); |
| 2758 | goto meta_command_exit; |
| 2759 | } |
| 2760 | zFile = azArg[1]; |
| 2761 | zTable = azArg[2]; |
| 2762 | seenInterrupt = 0; |
| 2763 | memset(&sCtx, 0, sizeof(sCtx)); |
| 2764 | open_db(p, 0); |
| 2765 | nSep = strlen30(p->colSeparator); |
| 2766 | if( nSep==0 ){ |
| 2767 | fprintf(stderr, "Error: non-null column separator required for import\n"); |
| 2768 | return 1; |
| 2769 | } |
| 2770 | if( nSep>1 ){ |
| 2771 | fprintf(stderr, "Error: multi-character column separators not allowed" |
| 2772 | " for import\n"); |
| 2773 | return 1; |
| 2774 | } |
| 2775 | nSep = strlen30(p->rowSeparator); |
| 2776 | if( nSep==0 ){ |
| 2777 | fprintf(stderr, "Error: non-null row separator required for import\n"); |
| 2778 | return 1; |
| 2779 | } |
| 2780 | if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ |
| 2781 | /* When importing CSV (only), if the row separator is set to the |
| 2782 | ** default output row separator, change it to the default input |
| 2783 | ** row separator. This avoids having to maintain different input |
| 2784 | ** and output row separators. */ |
| 2785 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); |
| 2786 | nSep = strlen30(p->rowSeparator); |
| 2787 | } |
| 2788 | if( nSep>1 ){ |
| 2789 | fprintf(stderr, "Error: multi-character row separators not allowed" |
| 2790 | " for import\n"); |
| 2791 | return 1; |
| 2792 | } |
| 2793 | sCtx.zFile = zFile; |
| 2794 | sCtx.nLine = 1; |
| 2795 | if( sCtx.zFile[0]=='|' ){ |
| 2796 | sCtx.in = popen(sCtx.zFile+1, "r"); |
| 2797 | sCtx.zFile = "<pipe>"; |
| 2798 | xCloser = pclose; |
| 2799 | }else{ |
| 2800 | sCtx.in = fopen(sCtx.zFile, "rb"); |
| 2801 | xCloser = fclose; |
| 2802 | } |
| 2803 | if( p->mode==MODE_Ascii ){ |
| 2804 | xRead = ascii_read_one_field; |
| 2805 | }else{ |
| 2806 | xRead = csv_read_one_field; |
| 2807 | } |
| 2808 | if( sCtx.in==0 ){ |
| 2809 | fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); |
| 2810 | return 1; |
| 2811 | } |
| 2812 | sCtx.cColSep = p->colSeparator[0]; |
| 2813 | sCtx.cRowSep = p->rowSeparator[0]; |
| 2814 | zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); |
| 2815 | if( zSql==0 ){ |
| 2816 | fprintf(stderr, "Error: out of memory\n"); |
| 2817 | xCloser(sCtx.in); |
| 2818 | return 1; |
| 2819 | } |
| 2820 | nByte = strlen30(zSql); |
| 2821 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2822 | import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ |
| 2823 | if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ |
| 2824 | char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); |
| 2825 | char cSep = '('; |
| 2826 | while( xRead(&sCtx) ){ |
| 2827 | zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z); |
| 2828 | cSep = ','; |
| 2829 | if( sCtx.cTerm!=sCtx.cColSep ) break; |
| 2830 | } |
| 2831 | if( cSep=='(' ){ |
| 2832 | sqlite3_free(zCreate); |
| 2833 | sqlite3_free(sCtx.z); |
| 2834 | xCloser(sCtx.in); |
| 2835 | fprintf(stderr,"%s: empty file\n", sCtx.zFile); |
| 2836 | return 1; |
| 2837 | } |
| 2838 | zCreate = sqlite3_mprintf("%z\n)", zCreate); |
| 2839 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
| 2840 | sqlite3_free(zCreate); |
| 2841 | if( rc ){ |
| 2842 | fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, |
| 2843 | sqlite3_errmsg(db)); |
| 2844 | sqlite3_free(sCtx.z); |
| 2845 | xCloser(sCtx.in); |
| 2846 | return 1; |
| 2847 | } |
| 2848 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2849 | } |
| 2850 | sqlite3_free(zSql); |
| 2851 | if( rc ){ |
| 2852 | if (pStmt) sqlite3_finalize(pStmt); |
| 2853 | fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |
| 2854 | xCloser(sCtx.in); |
| 2855 | return 1; |
| 2856 | } |
| 2857 | nCol = sqlite3_column_count(pStmt); |
| 2858 | sqlite3_finalize(pStmt); |
| 2859 | pStmt = 0; |
| 2860 | if( nCol==0 ) return 0; /* no columns, no error */ |
| 2861 | zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 ); |
| 2862 | if( zSql==0 ){ |
| 2863 | fprintf(stderr, "Error: out of memory\n"); |
| 2864 | xCloser(sCtx.in); |
| 2865 | return 1; |
| 2866 | } |
| 2867 | sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); |
| 2868 | j = strlen30(zSql); |
| 2869 | for(i=1; i<nCol; i++){ |
| @@ -2758,50 +2875,60 @@ | |
| 2875 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 2876 | sqlite3_free(zSql); |
| 2877 | if( rc ){ |
| 2878 | fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |
| 2879 | if (pStmt) sqlite3_finalize(pStmt); |
| 2880 | xCloser(sCtx.in); |
| 2881 | return 1; |
| 2882 | } |
| 2883 | needCommit = sqlite3_get_autocommit(db); |
| 2884 | if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0); |
| 2885 | do{ |
| 2886 | int startLine = sCtx.nLine; |
| 2887 | for(i=0; i<nCol; i++){ |
| 2888 | char *z = xRead(&sCtx); |
| 2889 | /* |
| 2890 | ** Did we reach end-of-file before finding any columns? |
| 2891 | ** If so, stop instead of NULL filling the remaining columns. |
| 2892 | */ |
| 2893 | if( z==0 && i==0 ) break; |
| 2894 | /* |
| 2895 | ** Did we reach end-of-file OR end-of-line before finding any |
| 2896 | ** columns in ASCII mode? If so, stop instead of NULL filling |
| 2897 | ** the remaining columns. |
| 2898 | */ |
| 2899 | if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; |
| 2900 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 2901 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
| 2902 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2903 | "filling the rest with NULL\n", |
| 2904 | sCtx.zFile, startLine, nCol, i+1); |
| 2905 | i++; |
| 2906 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 2907 | } |
| 2908 | } |
| 2909 | if( sCtx.cTerm==sCtx.cColSep ){ |
| 2910 | do{ |
| 2911 | xRead(&sCtx); |
| 2912 | i++; |
| 2913 | }while( sCtx.cTerm==sCtx.cColSep ); |
| 2914 | fprintf(stderr, "%s:%d: expected %d columns but found %d - " |
| 2915 | "extras ignored\n", |
| 2916 | sCtx.zFile, startLine, nCol, i); |
| 2917 | } |
| 2918 | if( i>=nCol ){ |
| 2919 | sqlite3_step(pStmt); |
| 2920 | rc = sqlite3_reset(pStmt); |
| 2921 | if( rc!=SQLITE_OK ){ |
| 2922 | fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine, |
| 2923 | sqlite3_errmsg(db)); |
| 2924 | } |
| 2925 | } |
| 2926 | }while( sCtx.cTerm!=EOF ); |
| 2927 | |
| 2928 | xCloser(sCtx.in); |
| 2929 | sqlite3_free(sCtx.z); |
| 2930 | sqlite3_finalize(pStmt); |
| 2931 | if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0); |
| 2932 | }else |
| 2933 | |
| 2934 | if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){ |
| @@ -2915,32 +3042,36 @@ | |
| 3042 | p->mode = MODE_List; |
| 3043 | }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ |
| 3044 | p->mode = MODE_Html; |
| 3045 | }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ |
| 3046 | p->mode = MODE_Tcl; |
| 3047 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); |
| 3048 | }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ |
| 3049 | p->mode = MODE_Csv; |
| 3050 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
| 3051 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
| 3052 | }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ |
| 3053 | p->mode = MODE_List; |
| 3054 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); |
| 3055 | }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ |
| 3056 | p->mode = MODE_Insert; |
| 3057 | set_table_name(p, nArg>=3 ? azArg[2] : "table"); |
| 3058 | }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ |
| 3059 | p->mode = MODE_Ascii; |
| 3060 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); |
| 3061 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); |
| 3062 | }else { |
| 3063 | fprintf(stderr,"Error: mode should be one of: " |
| 3064 | "ascii column csv html insert line list tabs tcl\n"); |
| 3065 | rc = 1; |
| 3066 | } |
| 3067 | }else |
| 3068 | |
| 3069 | if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ |
| 3070 | if( nArg==2 ){ |
| 3071 | sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, |
| 3072 | "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); |
| 3073 | }else{ |
| 3074 | fprintf(stderr, "Usage: .nullvalue STRING\n"); |
| 3075 | rc = 1; |
| 3076 | } |
| 3077 | }else |
| @@ -3221,18 +3352,20 @@ | |
| 3352 | }else |
| 3353 | #endif |
| 3354 | |
| 3355 | if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ |
| 3356 | if( nArg<2 || nArg>3 ){ |
| 3357 | fprintf(stderr, "Usage: .separator COL ?ROW?\n"); |
| 3358 | rc = 1; |
| 3359 | } |
| 3360 | if( nArg>=2 ){ |
| 3361 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, |
| 3362 | "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); |
| 3363 | } |
| 3364 | if( nArg>=3 ){ |
| 3365 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, |
| 3366 | "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); |
| 3367 | } |
| 3368 | }else |
| 3369 | |
| 3370 | if( c=='s' |
| 3371 | && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) |
| @@ -3259,27 +3392,28 @@ | |
| 3392 | if( nArg!=1 ){ |
| 3393 | fprintf(stderr, "Usage: .show\n"); |
| 3394 | rc = 1; |
| 3395 | goto meta_command_exit; |
| 3396 | } |
| 3397 | fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off"); |
| 3398 | fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off"); |
| 3399 | fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off"); |
| 3400 | fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off"); |
| 3401 | fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]); |
| 3402 | fprintf(p->out,"%12.12s: ", "nullvalue"); |
| 3403 | output_c_string(p->out, p->nullValue); |
| 3404 | fprintf(p->out, "\n"); |
| 3405 | fprintf(p->out,"%12.12s: %s\n","output", |
| 3406 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 3407 | fprintf(p->out,"%12.12s: ", "colseparator"); |
| 3408 | output_c_string(p->out, p->colSeparator); |
| 3409 | fprintf(p->out, "\n"); |
| 3410 | fprintf(p->out,"%12.12s: ", "rowseparator"); |
| 3411 | output_c_string(p->out, p->rowSeparator); |
| 3412 | fprintf(p->out, "\n"); |
| 3413 | fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off"); |
| 3414 | fprintf(p->out,"%12.12s: ","width"); |
| 3415 | for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |
| 3416 | fprintf(p->out,"%d ",p->colWidth[i]); |
| 3417 | } |
| 3418 | fprintf(p->out,"\n"); |
| 3419 | }else |
| @@ -3936,10 +4070,11 @@ | |
| 4070 | |
| 4071 | /* |
| 4072 | ** Show available command line options |
| 4073 | */ |
| 4074 | static const char zOptions[] = |
| 4075 | " -ascii set output mode to 'ascii'\n" |
| 4076 | " -bail stop after hitting an error\n" |
| 4077 | " -batch force batch I/O\n" |
| 4078 | " -column set output mode to 'column'\n" |
| 4079 | " -cmd COMMAND run \"COMMAND\" before reading stdin\n" |
| 4080 | " -csv set output mode to 'csv'\n" |
| @@ -3957,15 +4092,15 @@ | |
| 4092 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| 4093 | " -mmap N default mmap size set to N\n" |
| 4094 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 4095 | " -multiplex enable the multiplexor VFS\n" |
| 4096 | #endif |
| 4097 | " -newline SEP set output row separator. Default: '\\n'\n" |
| 4098 | " -nullvalue TEXT set text string for NULL values. Default ''\n" |
| 4099 | " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" |
| 4100 | " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" |
| 4101 | " -separator SEP set output column separator. Default: '|'\n" |
| 4102 | " -stats print memory stats before each finalize\n" |
| 4103 | " -version show SQLite version\n" |
| 4104 | " -vfs NAME use NAME as the default VFS\n" |
| 4105 | #ifdef SQLITE_ENABLE_VFSTRACE |
| 4106 | " -vfstrace enable tracing of all VFS calls\n" |
| @@ -3988,12 +4123,12 @@ | |
| 4123 | ** Initialize the state information in data |
| 4124 | */ |
| 4125 | static void main_init(ShellState *data) { |
| 4126 | memset(data, 0, sizeof(*data)); |
| 4127 | data->mode = MODE_List; |
| 4128 | memcpy(data->colSeparator,SEP_Column, 2); |
| 4129 | memcpy(data->rowSeparator,SEP_Row, 2); |
| 4130 | data->showHeader = 0; |
| 4131 | data->shellFlgs = SHFLG_Lookaside; |
| 4132 | sqlite3_config(SQLITE_CONFIG_URI, 1); |
| 4133 | sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); |
| 4134 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| @@ -4228,19 +4363,25 @@ | |
| 4363 | data.mode = MODE_Line; |
| 4364 | }else if( strcmp(z,"-column")==0 ){ |
| 4365 | data.mode = MODE_Column; |
| 4366 | }else if( strcmp(z,"-csv")==0 ){ |
| 4367 | data.mode = MODE_Csv; |
| 4368 | memcpy(data.colSeparator,",",2); |
| 4369 | }else if( strcmp(z,"-ascii")==0 ){ |
| 4370 | data.mode = MODE_Ascii; |
| 4371 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, |
| 4372 | SEP_Unit); |
| 4373 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, |
| 4374 | SEP_Record); |
| 4375 | }else if( strcmp(z,"-separator")==0 ){ |
| 4376 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, |
| 4377 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4378 | }else if( strcmp(z,"-newline")==0 ){ |
| 4379 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, |
| 4380 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4381 | }else if( strcmp(z,"-nullvalue")==0 ){ |
| 4382 | sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, |
| 4383 | "%s",cmdline_option_value(argc,argv,++i)); |
| 4384 | }else if( strcmp(z,"-header")==0 ){ |
| 4385 | data.showHeader = 1; |
| 4386 | }else if( strcmp(z,"-noheader")==0 ){ |
| 4387 | data.showHeader = 0; |
| @@ -4356,11 +4497,11 @@ | |
| 4497 | nHistory = strlen30(zHome) + 20; |
| 4498 | if( (zHistory = malloc(nHistory))!=0 ){ |
| 4499 | sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |
| 4500 | } |
| 4501 | } |
| 4502 | #if HAVE_READLINE |
| 4503 | if( zHistory ) read_history(zHistory); |
| 4504 | #endif |
| 4505 | rc = process_input(&data, 0); |
| 4506 | if( zHistory ){ |
| 4507 | stifle_history(100); |
| 4508 |
+30
-1
| --- src/sqlcmd.c | ||
| +++ src/sqlcmd.c | ||
| @@ -132,10 +132,11 @@ | ||
| 132 | 132 | sqlite3 *db, |
| 133 | 133 | const char **pzErrMsg, |
| 134 | 134 | const void *notUsed |
| 135 | 135 | ){ |
| 136 | 136 | add_content_sql_commands(db); |
| 137 | + db_add_aux_functions(db); | |
| 137 | 138 | re_add_sql_func(db); |
| 138 | 139 | g.zMainDbType = "repository"; |
| 139 | 140 | foci_register(db); |
| 140 | 141 | g.repositoryOpen = 1; |
| 141 | 142 | g.db = db; |
| @@ -147,15 +148,43 @@ | ||
| 147 | 148 | ** |
| 148 | 149 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 149 | 150 | ** |
| 150 | 151 | ** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS. |
| 151 | 152 | ** If DATABASE is omitted, then the repository that serves the working |
| 152 | -** directory is opened. | |
| 153 | +** directory is opened. See https://www.sqlite.org/cli.html for additional | |
| 154 | +** information. | |
| 153 | 155 | ** |
| 154 | 156 | ** WARNING: Careless use of this command can corrupt a Fossil repository |
| 155 | 157 | ** in ways that are unrecoverable. Be sure you know what you are doing before |
| 156 | 158 | ** running any SQL commands that modifies the repository database. |
| 159 | +** | |
| 160 | +** The following extensions to the usual SQLite commands are provided: | |
| 161 | +** | |
| 162 | +** content(X) Return the contenxt of artifact X. X can be a | |
| 163 | +** SHA1 hash or prefix or a tag. | |
| 164 | +** | |
| 165 | +** compress(X) Compress text X. | |
| 166 | +** | |
| 167 | +** decompress(X) Decompress text X. Undoes the work of | |
| 168 | +** compress(X). | |
| 169 | +** | |
| 170 | +** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID) | |
| 171 | +** found in check-in X (another BLOB.RID value). | |
| 172 | +** | |
| 173 | +** symbolic_name_to_rid(X) Return a the BLOB.RID corresponding to symbolic | |
| 174 | +** name X. | |
| 175 | +** | |
| 176 | +** REGEXP The REGEXP operator works, unlike in | |
| 177 | +** standard SQLite. | |
| 178 | +** | |
| 179 | +** files_of_checkin The "files_of_check" virtual table is | |
| 180 | +** available for decoding manifests. | |
| 181 | +** | |
| 182 | +** Usage example for files_of_checkin: | |
| 183 | +** | |
| 184 | +** CREATE VIRTUAL TABLE temp.foci USING files_of_checkin; | |
| 185 | +** SELECT * FROM foci WHERE checkinID=symbolic_name_to_rid('trunk'); | |
| 157 | 186 | */ |
| 158 | 187 | void cmd_sqlite3(void){ |
| 159 | 188 | extern int sqlite3_shell(int, char**); |
| 160 | 189 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 161 | 190 | db_close(1); |
| 162 | 191 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -132,10 +132,11 @@ | |
| 132 | sqlite3 *db, |
| 133 | const char **pzErrMsg, |
| 134 | const void *notUsed |
| 135 | ){ |
| 136 | add_content_sql_commands(db); |
| 137 | re_add_sql_func(db); |
| 138 | g.zMainDbType = "repository"; |
| 139 | foci_register(db); |
| 140 | g.repositoryOpen = 1; |
| 141 | g.db = db; |
| @@ -147,15 +148,43 @@ | |
| 147 | ** |
| 148 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 149 | ** |
| 150 | ** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS. |
| 151 | ** If DATABASE is omitted, then the repository that serves the working |
| 152 | ** directory is opened. |
| 153 | ** |
| 154 | ** WARNING: Careless use of this command can corrupt a Fossil repository |
| 155 | ** in ways that are unrecoverable. Be sure you know what you are doing before |
| 156 | ** running any SQL commands that modifies the repository database. |
| 157 | */ |
| 158 | void cmd_sqlite3(void){ |
| 159 | extern int sqlite3_shell(int, char**); |
| 160 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 161 | db_close(1); |
| 162 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -132,10 +132,11 @@ | |
| 132 | sqlite3 *db, |
| 133 | const char **pzErrMsg, |
| 134 | const void *notUsed |
| 135 | ){ |
| 136 | add_content_sql_commands(db); |
| 137 | db_add_aux_functions(db); |
| 138 | re_add_sql_func(db); |
| 139 | g.zMainDbType = "repository"; |
| 140 | foci_register(db); |
| 141 | g.repositoryOpen = 1; |
| 142 | g.db = db; |
| @@ -147,15 +148,43 @@ | |
| 148 | ** |
| 149 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 150 | ** |
| 151 | ** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS. |
| 152 | ** If DATABASE is omitted, then the repository that serves the working |
| 153 | ** directory is opened. See https://www.sqlite.org/cli.html for additional |
| 154 | ** information. |
| 155 | ** |
| 156 | ** WARNING: Careless use of this command can corrupt a Fossil repository |
| 157 | ** in ways that are unrecoverable. Be sure you know what you are doing before |
| 158 | ** running any SQL commands that modifies the repository database. |
| 159 | ** |
| 160 | ** The following extensions to the usual SQLite commands are provided: |
| 161 | ** |
| 162 | ** content(X) Return the contenxt of artifact X. X can be a |
| 163 | ** SHA1 hash or prefix or a tag. |
| 164 | ** |
| 165 | ** compress(X) Compress text X. |
| 166 | ** |
| 167 | ** decompress(X) Decompress text X. Undoes the work of |
| 168 | ** compress(X). |
| 169 | ** |
| 170 | ** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID) |
| 171 | ** found in check-in X (another BLOB.RID value). |
| 172 | ** |
| 173 | ** symbolic_name_to_rid(X) Return a the BLOB.RID corresponding to symbolic |
| 174 | ** name X. |
| 175 | ** |
| 176 | ** REGEXP The REGEXP operator works, unlike in |
| 177 | ** standard SQLite. |
| 178 | ** |
| 179 | ** files_of_checkin The "files_of_check" virtual table is |
| 180 | ** available for decoding manifests. |
| 181 | ** |
| 182 | ** Usage example for files_of_checkin: |
| 183 | ** |
| 184 | ** CREATE VIRTUAL TABLE temp.foci USING files_of_checkin; |
| 185 | ** SELECT * FROM foci WHERE checkinID=symbolic_name_to_rid('trunk'); |
| 186 | */ |
| 187 | void cmd_sqlite3(void){ |
| 188 | extern int sqlite3_shell(int, char**); |
| 189 | db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); |
| 190 | db_close(1); |
| 191 |
+322
-210
| --- 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-16 12:08:06 7d68a42face3ab14ed88407d4331872f5b243fdf" | |
| 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 ){ |
| @@ -149342,17 +149454,16 @@ | ||
| 149342 | 149454 | */ |
| 149343 | 149455 | static int readInt16(u8 *p){ |
| 149344 | 149456 | return (p[0]<<8) + p[1]; |
| 149345 | 149457 | } |
| 149346 | 149458 | static void readCoord(u8 *p, RtreeCoord *pCoord){ |
| 149347 | - u32 i = ( | |
| 149459 | + pCoord->u = ( | |
| 149348 | 149460 | (((u32)p[0]) << 24) + |
| 149349 | 149461 | (((u32)p[1]) << 16) + |
| 149350 | 149462 | (((u32)p[2]) << 8) + |
| 149351 | 149463 | (((u32)p[3]) << 0) |
| 149352 | 149464 | ); |
| 149353 | - *(u32 *)pCoord = i; | |
| 149354 | 149465 | } |
| 149355 | 149466 | static i64 readInt64(u8 *p){ |
| 149356 | 149467 | return ( |
| 149357 | 149468 | (((i64)p[0]) << 56) + |
| 149358 | 149469 | (((i64)p[1]) << 48) + |
| @@ -149377,11 +149488,11 @@ | ||
| 149377 | 149488 | } |
| 149378 | 149489 | static int writeCoord(u8 *p, RtreeCoord *pCoord){ |
| 149379 | 149490 | u32 i; |
| 149380 | 149491 | assert( sizeof(RtreeCoord)==4 ); |
| 149381 | 149492 | assert( sizeof(u32)==4 ); |
| 149382 | - i = *(u32 *)pCoord; | |
| 149493 | + i = pCoord->u; | |
| 149383 | 149494 | p[0] = (i>>24)&0xFF; |
| 149384 | 149495 | p[1] = (i>>16)&0xFF; |
| 149385 | 149496 | p[2] = (i>> 8)&0xFF; |
| 149386 | 149497 | p[3] = (i>> 0)&0xFF; |
| 149387 | 149498 | return 4; |
| @@ -149708,18 +149819,17 @@ | ||
| 149708 | 149819 | RtreeNode *pNode, /* The node containing the cell to be read */ |
| 149709 | 149820 | int iCell, /* Index of the cell within the node */ |
| 149710 | 149821 | RtreeCell *pCell /* OUT: Write the cell contents here */ |
| 149711 | 149822 | ){ |
| 149712 | 149823 | u8 *pData; |
| 149713 | - u8 *pEnd; | |
| 149714 | 149824 | RtreeCoord *pCoord; |
| 149825 | + int ii; | |
| 149715 | 149826 | pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |
| 149716 | 149827 | pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); |
| 149717 | - pEnd = pData + pRtree->nDim*8; | |
| 149718 | 149828 | pCoord = pCell->aCoord; |
| 149719 | - for(; pData<pEnd; pData+=4, pCoord++){ | |
| 149720 | - readCoord(pData, pCoord); | |
| 149829 | + for(ii=0; ii<pRtree->nDim*2; ii++){ | |
| 149830 | + readCoord(&pData[ii*4], &pCoord[ii]); | |
| 149721 | 149831 | } |
| 149722 | 149832 | } |
| 149723 | 149833 | |
| 149724 | 149834 | |
| 149725 | 149835 | /* Forward declaration for the function that does the work of |
| @@ -151778,10 +151888,12 @@ | ||
| 151778 | 151888 | RtreeCell cell; /* New cell to insert if nData>1 */ |
| 151779 | 151889 | int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ |
| 151780 | 151890 | |
| 151781 | 151891 | rtreeReference(pRtree); |
| 151782 | 151892 | assert(nData>=1); |
| 151893 | + | |
| 151894 | + cell.iRowid = 0; /* Used only to suppress a compiler warning */ | |
| 151783 | 151895 | |
| 151784 | 151896 | /* Constraint handling. A write operation on an r-tree table may return |
| 151785 | 151897 | ** SQLITE_CONSTRAINT for two reasons: |
| 151786 | 151898 | ** |
| 151787 | 151899 | ** 1. A duplicate rowid value, or |
| 151788 | 151900 |
| --- 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 ){ |
| @@ -149342,17 +149454,16 @@ | |
| 149342 | */ |
| 149343 | static int readInt16(u8 *p){ |
| 149344 | return (p[0]<<8) + p[1]; |
| 149345 | } |
| 149346 | static void readCoord(u8 *p, RtreeCoord *pCoord){ |
| 149347 | u32 i = ( |
| 149348 | (((u32)p[0]) << 24) + |
| 149349 | (((u32)p[1]) << 16) + |
| 149350 | (((u32)p[2]) << 8) + |
| 149351 | (((u32)p[3]) << 0) |
| 149352 | ); |
| 149353 | *(u32 *)pCoord = i; |
| 149354 | } |
| 149355 | static i64 readInt64(u8 *p){ |
| 149356 | return ( |
| 149357 | (((i64)p[0]) << 56) + |
| 149358 | (((i64)p[1]) << 48) + |
| @@ -149377,11 +149488,11 @@ | |
| 149377 | } |
| 149378 | static int writeCoord(u8 *p, RtreeCoord *pCoord){ |
| 149379 | u32 i; |
| 149380 | assert( sizeof(RtreeCoord)==4 ); |
| 149381 | assert( sizeof(u32)==4 ); |
| 149382 | i = *(u32 *)pCoord; |
| 149383 | p[0] = (i>>24)&0xFF; |
| 149384 | p[1] = (i>>16)&0xFF; |
| 149385 | p[2] = (i>> 8)&0xFF; |
| 149386 | p[3] = (i>> 0)&0xFF; |
| 149387 | return 4; |
| @@ -149708,18 +149819,17 @@ | |
| 149708 | RtreeNode *pNode, /* The node containing the cell to be read */ |
| 149709 | int iCell, /* Index of the cell within the node */ |
| 149710 | RtreeCell *pCell /* OUT: Write the cell contents here */ |
| 149711 | ){ |
| 149712 | u8 *pData; |
| 149713 | u8 *pEnd; |
| 149714 | RtreeCoord *pCoord; |
| 149715 | pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |
| 149716 | pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); |
| 149717 | pEnd = pData + pRtree->nDim*8; |
| 149718 | pCoord = pCell->aCoord; |
| 149719 | for(; pData<pEnd; pData+=4, pCoord++){ |
| 149720 | readCoord(pData, pCoord); |
| 149721 | } |
| 149722 | } |
| 149723 | |
| 149724 | |
| 149725 | /* Forward declaration for the function that does the work of |
| @@ -151778,10 +151888,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-16 12:08:06 7d68a42face3ab14ed88407d4331872f5b243fdf" |
| 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 ){ |
| @@ -149342,17 +149454,16 @@ | |
| 149454 | */ |
| 149455 | static int readInt16(u8 *p){ |
| 149456 | return (p[0]<<8) + p[1]; |
| 149457 | } |
| 149458 | static void readCoord(u8 *p, RtreeCoord *pCoord){ |
| 149459 | pCoord->u = ( |
| 149460 | (((u32)p[0]) << 24) + |
| 149461 | (((u32)p[1]) << 16) + |
| 149462 | (((u32)p[2]) << 8) + |
| 149463 | (((u32)p[3]) << 0) |
| 149464 | ); |
| 149465 | } |
| 149466 | static i64 readInt64(u8 *p){ |
| 149467 | return ( |
| 149468 | (((i64)p[0]) << 56) + |
| 149469 | (((i64)p[1]) << 48) + |
| @@ -149377,11 +149488,11 @@ | |
| 149488 | } |
| 149489 | static int writeCoord(u8 *p, RtreeCoord *pCoord){ |
| 149490 | u32 i; |
| 149491 | assert( sizeof(RtreeCoord)==4 ); |
| 149492 | assert( sizeof(u32)==4 ); |
| 149493 | i = pCoord->u; |
| 149494 | p[0] = (i>>24)&0xFF; |
| 149495 | p[1] = (i>>16)&0xFF; |
| 149496 | p[2] = (i>> 8)&0xFF; |
| 149497 | p[3] = (i>> 0)&0xFF; |
| 149498 | return 4; |
| @@ -149708,18 +149819,17 @@ | |
| 149819 | RtreeNode *pNode, /* The node containing the cell to be read */ |
| 149820 | int iCell, /* Index of the cell within the node */ |
| 149821 | RtreeCell *pCell /* OUT: Write the cell contents here */ |
| 149822 | ){ |
| 149823 | u8 *pData; |
| 149824 | RtreeCoord *pCoord; |
| 149825 | int ii; |
| 149826 | pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); |
| 149827 | pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); |
| 149828 | pCoord = pCell->aCoord; |
| 149829 | for(ii=0; ii<pRtree->nDim*2; ii++){ |
| 149830 | readCoord(&pData[ii*4], &pCoord[ii]); |
| 149831 | } |
| 149832 | } |
| 149833 | |
| 149834 | |
| 149835 | /* Forward declaration for the function that does the work of |
| @@ -151778,10 +151888,12 @@ | |
| 151888 | RtreeCell cell; /* New cell to insert if nData>1 */ |
| 151889 | int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ |
| 151890 | |
| 151891 | rtreeReference(pRtree); |
| 151892 | assert(nData>=1); |
| 151893 | |
| 151894 | cell.iRowid = 0; /* Used only to suppress a compiler warning */ |
| 151895 | |
| 151896 | /* Constraint handling. A write operation on an r-tree table may return |
| 151897 | ** SQLITE_CONSTRAINT for two reasons: |
| 151898 | ** |
| 151899 | ** 1. A duplicate rowid value, or |
| 151900 |
+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-16 12:08:06 7d68a42face3ab14ed88407d4331872f5b243fdf" | |
| 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-16 12:08:06 7d68a42face3ab14ed88407d4331872f5b243fdf" |
| 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 |
+4
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1285,10 +1285,14 @@ | ||
| 1285 | 1285 | { "th.sort:after", |
| 1286 | 1286 | "General styles for sortable column marker", |
| 1287 | 1287 | @ margin-left: .4em; |
| 1288 | 1288 | @ cursor: pointer; |
| 1289 | 1289 | @ text-shadow: 0 0 0 #000; /* Makes arrow darker */ |
| 1290 | + }, | |
| 1291 | + { "th.sort.none:after", | |
| 1292 | + "None sort column marker", | |
| 1293 | + @ content: '\2666'; | |
| 1290 | 1294 | }, |
| 1291 | 1295 | { "th.sort.asc:after", |
| 1292 | 1296 | "Ascending sort column marker", |
| 1293 | 1297 | @ content: '\2193'; |
| 1294 | 1298 | }, |
| 1295 | 1299 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1285,10 +1285,14 @@ | |
| 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.asc:after", |
| 1292 | "Ascending sort column marker", |
| 1293 | @ content: '\2193'; |
| 1294 | }, |
| 1295 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1285,10 +1285,14 @@ | |
| 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 |
+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 |
-1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1035,11 +1035,10 @@ | ||
| 1035 | 1035 | ** nd Suppress "divider" lines |
| 1036 | 1036 | ** v Show details of files changed |
| 1037 | 1037 | ** f=UUID Show family (immediate parents and children) of UUID |
| 1038 | 1038 | ** from=UUID Path from... |
| 1039 | 1039 | ** to=UUID ... to this |
| 1040 | -** nomerge ... avoid merge links on the path | |
| 1041 | 1040 | ** shortest ... show only the shortest path |
| 1042 | 1041 | ** uf=FUUID Show only checkins that use given file version |
| 1043 | 1042 | ** brbg Background color from branch name |
| 1044 | 1043 | ** ubg Background color from user |
| 1045 | 1044 | ** namechng Show only checkins that filename changes |
| 1046 | 1045 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1035,11 +1035,10 @@ | |
| 1035 | ** nd Suppress "divider" lines |
| 1036 | ** v Show details of files changed |
| 1037 | ** f=UUID Show family (immediate parents and children) of UUID |
| 1038 | ** from=UUID Path from... |
| 1039 | ** to=UUID ... to this |
| 1040 | ** nomerge ... avoid merge links on the path |
| 1041 | ** shortest ... show only the shortest path |
| 1042 | ** uf=FUUID Show only checkins that use given file version |
| 1043 | ** brbg Background color from branch name |
| 1044 | ** ubg Background color from user |
| 1045 | ** namechng Show only checkins that filename changes |
| 1046 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1035,11 +1035,10 @@ | |
| 1035 | ** nd Suppress "divider" lines |
| 1036 | ** v Show details of files changed |
| 1037 | ** f=UUID Show family (immediate parents and children) of UUID |
| 1038 | ** from=UUID Path from... |
| 1039 | ** to=UUID ... to this |
| 1040 | ** shortest ... show only the shortest path |
| 1041 | ** uf=FUUID Show only checkins that use given file version |
| 1042 | ** brbg Background color from branch name |
| 1043 | ** ubg Background color from user |
| 1044 | ** namechng Show only checkins that filename changes |
| 1045 |
+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 |
+1
-1
| --- test/diff-test-1.wiki | ||
| +++ test/diff-test-1.wiki | ||
| @@ -17,11 +17,11 @@ | ||
| 17 | 17 | The edit of a line with multibyte characters is the first chunk. |
| 18 | 18 | * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6" |
| 19 | 19 | target="testwindow">Large diff of sqlite3.c</a>. This diff was very |
| 20 | 20 | slow prior to the performance enhancement change [9e15437e97]. |
| 21 | 21 | * <a href="../../../info/bda00cbada#chunk49" target="testwindow"> |
| 22 | - A difficult indentation change. | |
| 22 | + A difficult indentation change.</a> (show-version-diffs must be enabled) | |
| 23 | 23 | * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13" |
| 24 | 24 | target="testwindow">Another tricky indentation.</a> Notice especially |
| 25 | 25 | lines 59398 and 59407 on the left. |
| 26 | 26 | * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13" |
| 27 | 27 | target="testwindow">Inverse of the previous.</a> |
| 28 | 28 |
| --- test/diff-test-1.wiki | |
| +++ test/diff-test-1.wiki | |
| @@ -17,11 +17,11 @@ | |
| 17 | The edit of a line with multibyte characters is the first chunk. |
| 18 | * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6" |
| 19 | target="testwindow">Large diff of sqlite3.c</a>. This diff was very |
| 20 | slow prior to the performance enhancement change [9e15437e97]. |
| 21 | * <a href="../../../info/bda00cbada#chunk49" target="testwindow"> |
| 22 | A difficult indentation change. |
| 23 | * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13" |
| 24 | target="testwindow">Another tricky indentation.</a> Notice especially |
| 25 | lines 59398 and 59407 on the left. |
| 26 | * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13" |
| 27 | target="testwindow">Inverse of the previous.</a> |
| 28 |
| --- test/diff-test-1.wiki | |
| +++ test/diff-test-1.wiki | |
| @@ -17,11 +17,11 @@ | |
| 17 | The edit of a line with multibyte characters is the first chunk. |
| 18 | * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6" |
| 19 | target="testwindow">Large diff of sqlite3.c</a>. This diff was very |
| 20 | slow prior to the performance enhancement change [9e15437e97]. |
| 21 | * <a href="../../../info/bda00cbada#chunk49" target="testwindow"> |
| 22 | A difficult indentation change.</a> (show-version-diffs must be enabled) |
| 23 | * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13" |
| 24 | target="testwindow">Another tricky indentation.</a> Notice especially |
| 25 | lines 59398 and 59407 on the left. |
| 26 | * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13" |
| 27 | target="testwindow">Inverse of the previous.</a> |
| 28 |
+12
-11
| --- test/graph-test-1.wiki | ||
| +++ test/graph-test-1.wiki | ||
| @@ -28,23 +28,21 @@ | ||
| 28 | 28 | multiple branch risers.</a> |
| 29 | 29 | * <a href="../../../timeline?y=ci&a=2010-12-20&n=18" target="testwindow"> |
| 30 | 30 | multiple branch risers, n=18.</a> |
| 31 | 31 | * <a href="../../../timeline?y=ci&a=2010-12-20&n=9" target="testwindow"> |
| 32 | 32 | multiple branch risers, n=9.</a> |
| 33 | - * <a href="../../../timeline?r=experimental" target="testwindow"> | |
| 33 | + * <a href="../../../timeline?r=experimental&n=0" target="testwindow"> | |
| 34 | 34 | Experimental branch with related check-ins.</a> |
| 35 | - * <a href="../../../timeline?r=experimental&mionly" target="testwindow"> | |
| 35 | + * <a href="../../../timeline?r=experimental&mionly&n=0" target="testwindow"> | |
| 36 | 36 | Experimental branch with merge-ins only.</a> |
| 37 | - * <a href="../../../timeline?t=experimental" target="testwindow"> | |
| 37 | + * <a href="../../../timeline?t=experimental&n=0" target="testwindow"> | |
| 38 | 38 | Experimental branch check-ins only.</a> |
| 39 | - * <a href="../../../timeline?r=experimental&n=1000" target="testwindow"> | |
| 40 | - Experimental branch using and related check-ins - 1000 elements.</a> | |
| 41 | - * <a href="../../../timeline?r=release" target="testwindow"> | |
| 39 | + * <a href="../../../timeline?r=release&n=0" target="testwindow"> | |
| 42 | 40 | Check-ins tagged "release" and related check-ins</a> |
| 43 | - * <a href="../../../timeline?r=release&mionly" target="testwindow"> | |
| 41 | + * <a href="../../../timeline?r=release&mionly&n=0" target="testwindow"> | |
| 44 | 42 | Check-ins tagged "release" and merge-ins</a> |
| 45 | - * <a href="../../../timeline?t=release" target="testwindow"> | |
| 43 | + * <a href="../../../timeline?t=release&n=0" target="testwindow"> | |
| 46 | 44 | Only check-ins tagged "release"</a> |
| 47 | 45 | * <a href="../../../finfo?name=Makefile" target="testwindow"> |
| 48 | 46 | History of source file "Makefile".</a> |
| 49 | 47 | * <a href="../../../timeline?a=1970-01-01" target="testwindow"> |
| 50 | 48 | 20 elements after 1970-01-01.</a> |
| @@ -51,22 +49,25 @@ | ||
| 51 | 49 | * <a href="../../../timeline?n=100000000&y=ci" target="testwindow"> |
| 52 | 50 | All check-ins - a huge graph.</a> |
| 53 | 51 | * <a href="../../../timeline?f=8dfed953f7530442" target="testwindow"> |
| 54 | 52 | This malformed commit has a |
| 55 | 53 | merge parent which is not a valid checkin.</a> |
| 56 | - * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9" | |
| 54 | + * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&shortest" | |
| 57 | 55 | target="testwindow"> |
| 58 | 56 | From e663bac6f7 to a298a0e2f9 by shortest path.</a> |
| 59 | - * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&nomerge" | |
| 57 | + * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9" | |
| 60 | 58 | target="testwindow"> |
| 61 | 59 | From e663bac6f7 to a298a0e2f9 without merge links.</a> |
| 62 | 60 | * <a href="../../../timeline?me=e663bac6f7&you=a298a0e2f9" |
| 63 | 61 | target="testwindow"> |
| 64 | 62 | Common ancestor path of e663bac6f7 to a298a0e2f9.</a> |
| 65 | - * <a href="../../../timeline?f=65dd90fb95a2af55"> | |
| 63 | + * <a href="../../../timeline?f=65dd90fb95a2af55" target="testwindow"> | |
| 66 | 64 | Merge on the same branch does not result in a leaf. |
| 67 | 65 | </a> |
| 66 | + * <a href="../../../timeline?c=20015206bc" | |
| 67 | + target="testwindow"> | |
| 68 | + This timeline has a hidden commit.</a> Click Unhide to reveal. | |
| 68 | 69 | |
| 69 | 70 | External: |
| 70 | 71 | |
| 71 | 72 | * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd" |
| 72 | 73 | target="testwindow">Timewarp due to a mis-configured system clock.</a> |
| 73 | 74 |
| --- test/graph-test-1.wiki | |
| +++ test/graph-test-1.wiki | |
| @@ -28,23 +28,21 @@ | |
| 28 | multiple branch risers.</a> |
| 29 | * <a href="../../../timeline?y=ci&a=2010-12-20&n=18" target="testwindow"> |
| 30 | multiple branch risers, n=18.</a> |
| 31 | * <a href="../../../timeline?y=ci&a=2010-12-20&n=9" target="testwindow"> |
| 32 | multiple branch risers, n=9.</a> |
| 33 | * <a href="../../../timeline?r=experimental" target="testwindow"> |
| 34 | Experimental branch with related check-ins.</a> |
| 35 | * <a href="../../../timeline?r=experimental&mionly" target="testwindow"> |
| 36 | Experimental branch with merge-ins only.</a> |
| 37 | * <a href="../../../timeline?t=experimental" target="testwindow"> |
| 38 | Experimental branch check-ins only.</a> |
| 39 | * <a href="../../../timeline?r=experimental&n=1000" target="testwindow"> |
| 40 | Experimental branch using and related check-ins - 1000 elements.</a> |
| 41 | * <a href="../../../timeline?r=release" target="testwindow"> |
| 42 | Check-ins tagged "release" and related check-ins</a> |
| 43 | * <a href="../../../timeline?r=release&mionly" target="testwindow"> |
| 44 | Check-ins tagged "release" and merge-ins</a> |
| 45 | * <a href="../../../timeline?t=release" target="testwindow"> |
| 46 | Only check-ins tagged "release"</a> |
| 47 | * <a href="../../../finfo?name=Makefile" target="testwindow"> |
| 48 | History of source file "Makefile".</a> |
| 49 | * <a href="../../../timeline?a=1970-01-01" target="testwindow"> |
| 50 | 20 elements after 1970-01-01.</a> |
| @@ -51,22 +49,25 @@ | |
| 51 | * <a href="../../../timeline?n=100000000&y=ci" target="testwindow"> |
| 52 | All check-ins - a huge graph.</a> |
| 53 | * <a href="../../../timeline?f=8dfed953f7530442" target="testwindow"> |
| 54 | This malformed commit has a |
| 55 | merge parent which is not a valid checkin.</a> |
| 56 | * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9" |
| 57 | target="testwindow"> |
| 58 | From e663bac6f7 to a298a0e2f9 by shortest path.</a> |
| 59 | * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&nomerge" |
| 60 | target="testwindow"> |
| 61 | From e663bac6f7 to a298a0e2f9 without merge links.</a> |
| 62 | * <a href="../../../timeline?me=e663bac6f7&you=a298a0e2f9" |
| 63 | target="testwindow"> |
| 64 | Common ancestor path of e663bac6f7 to a298a0e2f9.</a> |
| 65 | * <a href="../../../timeline?f=65dd90fb95a2af55"> |
| 66 | Merge on the same branch does not result in a leaf. |
| 67 | </a> |
| 68 | |
| 69 | External: |
| 70 | |
| 71 | * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd" |
| 72 | target="testwindow">Timewarp due to a mis-configured system clock.</a> |
| 73 |
| --- test/graph-test-1.wiki | |
| +++ test/graph-test-1.wiki | |
| @@ -28,23 +28,21 @@ | |
| 28 | multiple branch risers.</a> |
| 29 | * <a href="../../../timeline?y=ci&a=2010-12-20&n=18" target="testwindow"> |
| 30 | multiple branch risers, n=18.</a> |
| 31 | * <a href="../../../timeline?y=ci&a=2010-12-20&n=9" target="testwindow"> |
| 32 | multiple branch risers, n=9.</a> |
| 33 | * <a href="../../../timeline?r=experimental&n=0" target="testwindow"> |
| 34 | Experimental branch with related check-ins.</a> |
| 35 | * <a href="../../../timeline?r=experimental&mionly&n=0" target="testwindow"> |
| 36 | Experimental branch with merge-ins only.</a> |
| 37 | * <a href="../../../timeline?t=experimental&n=0" target="testwindow"> |
| 38 | Experimental branch check-ins only.</a> |
| 39 | * <a href="../../../timeline?r=release&n=0" target="testwindow"> |
| 40 | Check-ins tagged "release" and related check-ins</a> |
| 41 | * <a href="../../../timeline?r=release&mionly&n=0" target="testwindow"> |
| 42 | Check-ins tagged "release" and merge-ins</a> |
| 43 | * <a href="../../../timeline?t=release&n=0" target="testwindow"> |
| 44 | Only check-ins tagged "release"</a> |
| 45 | * <a href="../../../finfo?name=Makefile" target="testwindow"> |
| 46 | History of source file "Makefile".</a> |
| 47 | * <a href="../../../timeline?a=1970-01-01" target="testwindow"> |
| 48 | 20 elements after 1970-01-01.</a> |
| @@ -51,22 +49,25 @@ | |
| 49 | * <a href="../../../timeline?n=100000000&y=ci" target="testwindow"> |
| 50 | All check-ins - a huge graph.</a> |
| 51 | * <a href="../../../timeline?f=8dfed953f7530442" target="testwindow"> |
| 52 | This malformed commit has a |
| 53 | merge parent which is not a valid checkin.</a> |
| 54 | * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&shortest" |
| 55 | target="testwindow"> |
| 56 | From e663bac6f7 to a298a0e2f9 by shortest path.</a> |
| 57 | * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9" |
| 58 | target="testwindow"> |
| 59 | From e663bac6f7 to a298a0e2f9 without merge links.</a> |
| 60 | * <a href="../../../timeline?me=e663bac6f7&you=a298a0e2f9" |
| 61 | target="testwindow"> |
| 62 | Common ancestor path of e663bac6f7 to a298a0e2f9.</a> |
| 63 | * <a href="../../../timeline?f=65dd90fb95a2af55" target="testwindow"> |
| 64 | Merge on the same branch does not result in a leaf. |
| 65 | </a> |
| 66 | * <a href="../../../timeline?c=20015206bc" |
| 67 | target="testwindow"> |
| 68 | This timeline has a hidden commit.</a> Click Unhide to reveal. |
| 69 | |
| 70 | External: |
| 71 | |
| 72 | * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd" |
| 73 | target="testwindow">Timewarp due to a mis-configured system clock.</a> |
| 74 |
+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 |
+55
-13
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -1,34 +1,76 @@ | ||
| 1 | 1 | <title>Change Log</title> |
| 2 | 2 | |
| 3 | -<h2>Changes For Version 1.30 (as yet unreleased)</h2> | |
| 4 | - * Add setting to control the number of times autosync will be tried before | |
| 5 | - returning an error. | |
| 3 | +<h2>Changes For Version 1.30 (2015-01-19)</h2> | |
| 4 | + * Added the [/help?cmd=bundle|fossil bundle] command. | |
| 5 | + * Added the [/help?cmd=purge|fossil purge] command. | |
| 6 | + * Added the [/help?cmd=publish|fossil publish] command. | |
| 7 | + * Added the [/help?cmd=unpublished|fossil unpublished] command. | |
| 8 | + * Enhance the [/tree] webpage to show the age of each file with the option | |
| 9 | + to sort by age. | |
| 10 | + * Enhance the [/brlist] webpage to show additional information about each branch | |
| 11 | + and to be sortable by clicking on column headers. | |
| 12 | + * Add support for Docker. Just install docker and type | |
| 13 | + "sudo docker run -d -p 8080:8080 nijtmans/fossil" to get it running. | |
| 6 | 14 | * Add the [/help/fusefs|fossil fusefs DIRECTORY] command that mounts a |
| 7 | 15 | Fuse Filesystem at the given DIRECTORY and populates it with read-only |
| 8 | 16 | copies of all historical check-ins. This only works on systems that |
| 9 | 17 | support FuseFS. |
| 18 | + * Add the administrative log that records all configuration. | |
| 19 | + * Added the [/sitemap] webpage. | |
| 20 | + * Added the [/bloblist] web page. | |
| 21 | + * Let [/help?cmd=new|fossil new] no longer create an initial empty commit | |
| 22 | + by default. The first commit after checking out an empty repository will | |
| 23 | + become the initial commit. | |
| 24 | + * Added the [/help?cmd=all|fossil all dbstat] and | |
| 25 | + [/help?cmd=all|fossil all info] commands. | |
| 26 | + * Update SQLite to version 3.8.8. | |
| 27 | + * Added the --verily option to the [/help?cmd=clean|fossil clean] command. | |
| 28 | + * Add the "autosync-tries" setting to control the number of autosync attempts | |
| 29 | + before returning an error. | |
| 10 | 30 | * Added a compile-time option (--with-miniz) to build using miniz instead |
| 11 | 31 | of zlib. Disabled by default. |
| 12 | - * Several fixes to the TH1 expression parser. | |
| 13 | 32 | * Support customization of commands and webpages, including the ability to |
| 14 | 33 | add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled |
| 15 | 34 | via a compile-time option. |
| 16 | 35 | * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter], |
| 17 | 36 | [trace], [getParameter], [setParameter], [artifact], and |
| 18 | 37 | [globalState]</nowiki> commands to TH1, primarily for use by TH1 hooks. |
| 19 | - * Bring in the latest version of autosetup from upstream. | |
| 20 | - * When committing a (non-binary) file which contains bytes forming an | |
| 21 | - invalid UTF-8 stream, fossil now adds the possibility to convert it | |
| 22 | - to a valid UTF-8 stream ('c') if you like. | |
| 23 | - * Let [/help?cmd=new|fossil new] no longer create an initial empty commit | |
| 24 | - by default. The first commit after checking out an empty repository will | |
| 25 | - become the initial commit. (NOT PLANNED FOR 1.30, BUT DONE TO EXPOSE | |
| 26 | - [/help?cmd=new|fossil new --empty] TO MORE FIELD TESTING BEFORE | |
| 27 | - MAKING ANY DECISION ON IT!) | |
| 38 | + * Automatically adjust the width of command-line timeline output according to the | |
| 39 | + detected width of the terminal. | |
| 40 | + * Prompt the user to optionally fix invalid UTF-8 at check-in. | |
| 28 | 41 | * Added a line-number toggle option to the [/help?cmd=/info|/info] |
| 29 | 42 | and [/help?cmd=/artifact|/artifact] pages. |
| 43 | + * Most commands now issue errors rather than silently ignoring unrecognized | |
| 44 | + command-line options. | |
| 45 | + * Use full 40-character SHA1 hashes (instead of abbreviations) in most | |
| 46 | + internal URLs. | |
| 47 | + * The "ssh:" sync method on windows now uses "plink.exe" instead of "ssh" as | |
| 48 | + the secure-shell client program. | |
| 49 | + * Prevent a partial clone when the connection is lost. | |
| 50 | + * Make the distinction between 301 and 302 redirects. | |
| 51 | + * Allow commits against a closed check-in as long as the commit goes onto | |
| 52 | + a different branch. | |
| 53 | + * Improved cache control in the web interface reduces unnecessary requests | |
| 54 | + for common resources like the page logo and CSS. | |
| 55 | + * Fix a rare and long-standing sync protocol bug | |
| 56 | + that would silently prevent the sync from running to completion. Before | |
| 57 | + this bug-fix it was sometimes necessary to do "fossil sync --verily" to | |
| 58 | + get two repositories in sync. | |
| 59 | + * Add the [/finfo?name=src/foci.c|files_of_checkin] virtual table - useful | |
| 60 | + for ad hoc queries in the [/help?cmd=sqlite3|fossil sql] interface, | |
| 61 | + and also used internally. | |
| 62 | + * Added the "$secureurl" TH1 variable for use in headers and footers. | |
| 63 | + * (Internal:) Add the ability to include resources as separate files in the | |
| 64 | + source tree that are converted into constant byte arrays in the compiled | |
| 65 | + binary. Use this feature to store the Tk script that implements the --tk | |
| 66 | + diff option in a separate file for easier editing. | |
| 67 | + * (Internal:) Implement a system of compile-time checks to help ensure | |
| 68 | + the correctness of printf-style formatting strings. | |
| 69 | + * Fix CVE-2014-3566, also known as the POODLE SSL 3.0 vulnerability. | |
| 70 | + * Numerous documentation fixes and improvements. | |
| 71 | + * Other obscure and minor bug fixes - see the timeline for details. | |
| 30 | 72 | |
| 31 | 73 | <h2>Changes For Version 1.29 (2014-06-12)</h2> |
| 32 | 74 | * Add the ability to display content, diffs and annotations for UTF16 |
| 33 | 75 | text files in the web interface. |
| 34 | 76 | * Add the "SaveAs..." and "Invert" buttons |
| 35 | 77 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,34 +1,76 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2>Changes For Version 1.30 (as yet unreleased)</h2> |
| 4 | * Add setting to control the number of times autosync will be tried before |
| 5 | returning an error. |
| 6 | * Add the [/help/fusefs|fossil fusefs DIRECTORY] command that mounts a |
| 7 | Fuse Filesystem at the given DIRECTORY and populates it with read-only |
| 8 | copies of all historical check-ins. This only works on systems that |
| 9 | support FuseFS. |
| 10 | * Added a compile-time option (--with-miniz) to build using miniz instead |
| 11 | of zlib. Disabled by default. |
| 12 | * Several fixes to the TH1 expression parser. |
| 13 | * Support customization of commands and webpages, including the ability to |
| 14 | add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled |
| 15 | via a compile-time option. |
| 16 | * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter], |
| 17 | [trace], [getParameter], [setParameter], [artifact], and |
| 18 | [globalState]</nowiki> commands to TH1, primarily for use by TH1 hooks. |
| 19 | * Bring in the latest version of autosetup from upstream. |
| 20 | * When committing a (non-binary) file which contains bytes forming an |
| 21 | invalid UTF-8 stream, fossil now adds the possibility to convert it |
| 22 | to a valid UTF-8 stream ('c') if you like. |
| 23 | * Let [/help?cmd=new|fossil new] no longer create an initial empty commit |
| 24 | by default. The first commit after checking out an empty repository will |
| 25 | become the initial commit. (NOT PLANNED FOR 1.30, BUT DONE TO EXPOSE |
| 26 | [/help?cmd=new|fossil new --empty] TO MORE FIELD TESTING BEFORE |
| 27 | MAKING ANY DECISION ON IT!) |
| 28 | * Added a line-number toggle option to the [/help?cmd=/info|/info] |
| 29 | and [/help?cmd=/artifact|/artifact] pages. |
| 30 | |
| 31 | <h2>Changes For Version 1.29 (2014-06-12)</h2> |
| 32 | * Add the ability to display content, diffs and annotations for UTF16 |
| 33 | text files in the web interface. |
| 34 | * Add the "SaveAs..." and "Invert" buttons |
| 35 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -1,34 +1,76 @@ | |
| 1 | <title>Change Log</title> |
| 2 | |
| 3 | <h2>Changes For Version 1.30 (2015-01-19)</h2> |
| 4 | * Added the [/help?cmd=bundle|fossil bundle] command. |
| 5 | * Added the [/help?cmd=purge|fossil purge] command. |
| 6 | * Added the [/help?cmd=publish|fossil publish] command. |
| 7 | * Added the [/help?cmd=unpublished|fossil unpublished] command. |
| 8 | * Enhance the [/tree] webpage to show the age of each file with the option |
| 9 | to sort by age. |
| 10 | * Enhance the [/brlist] webpage to show additional information about each branch |
| 11 | and to be sortable by clicking on column headers. |
| 12 | * Add support for Docker. Just install docker and type |
| 13 | "sudo docker run -d -p 8080:8080 nijtmans/fossil" to get it running. |
| 14 | * Add the [/help/fusefs|fossil fusefs DIRECTORY] command that mounts a |
| 15 | Fuse Filesystem at the given DIRECTORY and populates it with read-only |
| 16 | copies of all historical check-ins. This only works on systems that |
| 17 | support FuseFS. |
| 18 | * Add the administrative log that records all configuration. |
| 19 | * Added the [/sitemap] webpage. |
| 20 | * Added the [/bloblist] web page. |
| 21 | * Let [/help?cmd=new|fossil new] no longer create an initial empty commit |
| 22 | by default. The first commit after checking out an empty repository will |
| 23 | become the initial commit. |
| 24 | * Added the [/help?cmd=all|fossil all dbstat] and |
| 25 | [/help?cmd=all|fossil all info] commands. |
| 26 | * Update SQLite to version 3.8.8. |
| 27 | * Added the --verily option to the [/help?cmd=clean|fossil clean] command. |
| 28 | * Add the "autosync-tries" setting to control the number of autosync attempts |
| 29 | before returning an error. |
| 30 | * Added a compile-time option (--with-miniz) to build using miniz instead |
| 31 | of zlib. Disabled by default. |
| 32 | * Support customization of commands and webpages, including the ability to |
| 33 | add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled |
| 34 | via a compile-time option. |
| 35 | * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter], |
| 36 | [trace], [getParameter], [setParameter], [artifact], and |
| 37 | [globalState]</nowiki> commands to TH1, primarily for use by TH1 hooks. |
| 38 | * Automatically adjust the width of command-line timeline output according to the |
| 39 | detected width of the terminal. |
| 40 | * Prompt the user to optionally fix invalid UTF-8 at check-in. |
| 41 | * Added a line-number toggle option to the [/help?cmd=/info|/info] |
| 42 | and [/help?cmd=/artifact|/artifact] pages. |
| 43 | * Most commands now issue errors rather than silently ignoring unrecognized |
| 44 | command-line options. |
| 45 | * Use full 40-character SHA1 hashes (instead of abbreviations) in most |
| 46 | internal URLs. |
| 47 | * The "ssh:" sync method on windows now uses "plink.exe" instead of "ssh" as |
| 48 | the secure-shell client program. |
| 49 | * Prevent a partial clone when the connection is lost. |
| 50 | * Make the distinction between 301 and 302 redirects. |
| 51 | * Allow commits against a closed check-in as long as the commit goes onto |
| 52 | a different branch. |
| 53 | * Improved cache control in the web interface reduces unnecessary requests |
| 54 | for common resources like the page logo and CSS. |
| 55 | * Fix a rare and long-standing sync protocol bug |
| 56 | that would silently prevent the sync from running to completion. Before |
| 57 | this bug-fix it was sometimes necessary to do "fossil sync --verily" to |
| 58 | get two repositories in sync. |
| 59 | * Add the [/finfo?name=src/foci.c|files_of_checkin] virtual table - useful |
| 60 | for ad hoc queries in the [/help?cmd=sqlite3|fossil sql] interface, |
| 61 | and also used internally. |
| 62 | * Added the "$secureurl" TH1 variable for use in headers and footers. |
| 63 | * (Internal:) Add the ability to include resources as separate files in the |
| 64 | source tree that are converted into constant byte arrays in the compiled |
| 65 | binary. Use this feature to store the Tk script that implements the --tk |
| 66 | diff option in a separate file for easier editing. |
| 67 | * (Internal:) Implement a system of compile-time checks to help ensure |
| 68 | the correctness of printf-style formatting strings. |
| 69 | * Fix CVE-2014-3566, also known as the POODLE SSL 3.0 vulnerability. |
| 70 | * Numerous documentation fixes and improvements. |
| 71 | * Other obscure and minor bug fixes - see the timeline for details. |
| 72 | |
| 73 | <h2>Changes For Version 1.29 (2014-06-12)</h2> |
| 74 | * Add the ability to display content, diffs and annotations for UTF16 |
| 75 | text files in the web interface. |
| 76 | * Add the "SaveAs..." and "Invert" buttons |
| 77 |
+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 |