Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge updates from trunk. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | skin-xekri |
| Files: | files | file ages | folders |
| SHA1: |
777db01e1d8de0aa0841e2e8f3cc413a |
| User & Date: | zakero 2015-05-16 02:18:29.280 |
Context
|
2015-05-16
| ||
| 02:27 | Added support for the SVG pie charts. check-in: dee9e33bf6 user: zakero tags: skin-xekri | |
| 02:18 | Merge updates from trunk. check-in: 777db01e1d user: zakero tags: skin-xekri | |
|
2015-05-15
| ||
| 16:49 | Remove redundant use of chnged column/variable. The SELECT statement already ensures each row has chnged==1, so there is no need to check it repeatedly. check-in: be25d412f1 user: andygoth tags: trunk | |
|
2015-03-25
| ||
| 22:13 | Updates to the Xekri skin to match the changes in the other skins * [7211414857] Disable font-inflation on all skins. * [72cddddbcc] Change default headers to show menu-bar items that would be available to user "anonymous" even if the current user is not logged in. check-in: 290a1c3363 user: zakero tags: skin-xekri | |
Changes
Deleted .fossil-settings/keep-glob.
|
| < < < < < |
Changes to VERSION.
|
| | | 1 | 1.33 |
Changes to auto.def.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# System autoconfiguration. Try: ./configure --help
use cc cc-lib
options {
with-openssl:path|auto|none
=> {Look for OpenSSL in the given path, or auto or none}
with-miniz=0 => {Use miniz from the source tree}
with-zlib:path => {Look for zlib in the given path}
with-th1-docs=0 => {Enable TH1 for embedded documentation pages}
with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages}
with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism}
with-tcl-private-stubs=0
=> {Enable Tcl integration via private stubs mechanism}
internal-sqlite=1 => {Don't use the internal SQLite, use the system one}
| > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# System autoconfiguration. Try: ./configure --help
use cc cc-lib
options {
with-openssl:path|auto|none
=> {Look for OpenSSL in the given path, or auto or none}
with-miniz=0 => {Use miniz from the source tree}
with-zlib:path => {Look for zlib in the given path}
with-legacy-mv-rm=0 => {Enable legacy behavior for mv/rm (skip checkout files)}
with-th1-docs=0 => {Enable TH1 for embedded documentation pages}
with-th1-hooks=0 => {Enable TH1 hooks for commands and web pages}
with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism}
with-tcl-private-stubs=0
=> {Enable Tcl integration via private stubs mechanism}
internal-sqlite=1 => {Don't use the internal SQLite, use the system one}
|
| ︙ | ︙ | |||
48 49 50 51 52 53 54 |
# Locate the system SQLite by searching for sqlite3_open(). Then check
# if sqlite3_strglob() can be found as well. If we can find open() but
# not strglob(), then the system SQLite is too old to link against
# fossil.
#
if {[cc-check-function-in-lib sqlite3_open sqlite3 $extralibs]} {
| | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# Locate the system SQLite by searching for sqlite3_open(). Then check
# if sqlite3_strglob() can be found as well. If we can find open() but
# not strglob(), then the system SQLite is too old to link against
# fossil.
#
if {[cc-check-function-in-lib sqlite3_open sqlite3 $extralibs]} {
if {![cc-check-function-in-lib sqlite3_malloc64 sqlite3 $extralibs]} {
user-error "system sqlite3 too old (require >= 3.8.7)"
}
# Success. Update symbols and return.
#
define USE_SYSTEM_SQLITE 1
define-append LIBS $extralibs
return
|
| ︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# is required in the CFLAGS because json*.c
# have #ifdef guards around the whole file without
# reading config.h first.
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON
define FOSSIL_ENABLE_JSON
msg-result "JSON support enabled"
}
if {[opt-bool with-th1-docs]} {
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_TH1_DOCS
define FOSSIL_ENABLE_TH1_DOCS
msg-result "TH1 embedded documentation support enabled"
}
| > > > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# is required in the CFLAGS because json*.c
# have #ifdef guards around the whole file without
# reading config.h first.
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON
define FOSSIL_ENABLE_JSON
msg-result "JSON support enabled"
}
if {[opt-bool with-legacy-mv-rm]} {
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_LEGACY_MV_RM
define FOSSIL_ENABLE_LEGACY_MV_RM
msg-result "Legacy mv/rm support enabled"
}
if {[opt-bool with-th1-docs]} {
define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_TH1_DOCS
define FOSSIL_ENABLE_TH1_DOCS
msg-result "TH1 embedded documentation support enabled"
}
|
| ︙ | ︙ | |||
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars
if {![cc-check-functions getpassphrase]} {
# Haiku needs this
cc-check-function-in-lib getpass bsd
}
cc-check-function-in-lib dlopen dl
# Check for the FuseFS library
if {[opt-bool fusefs]} {
if {[cc-check-function-in-lib fuse_mount fuse]} {
define FOSSIL_HAVE_FUSEFS 1
define-append LIBS -lfuse
msg-result "FuseFS support enabled"
}
}
make-template Makefile.in
make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
| > | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars
if {![cc-check-functions getpassphrase]} {
# Haiku needs this
cc-check-function-in-lib getpass bsd
}
cc-check-function-in-lib dlopen dl
cc-check-function-in-lib sin m
# Check for the FuseFS library
if {[opt-bool fusefs]} {
if {[cc-check-function-in-lib fuse_mount fuse]} {
define FOSSIL_HAVE_FUSEFS 1
define-append LIBS -lfuse
msg-result "FuseFS support enabled"
}
}
make-template Makefile.in
make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
|
Changes to setup/fossil.iss.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 |
[Setup]
ArchitecturesAllowed=x86 x64
AlwaysShowComponentsList=false
AppCopyright=Copyright (c) D. Richard Hipp. All rights reserved.
AppID={{f1c25a1f-3954-4e1a-ac36-4314c52f057c}
AppName=Fossil
AppPublisher=Fossil Development Team
| | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
[Setup]
ArchitecturesAllowed=x86 x64
AlwaysShowComponentsList=false
AppCopyright=Copyright (c) D. Richard Hipp. All rights reserved.
AppID={{f1c25a1f-3954-4e1a-ac36-4314c52f057c}
AppName=Fossil
AppPublisher=Fossil Development Team
AppPublisherURL=https://www.fossil-scm.org/
AppSupportURL=https://www.fossil-scm.org/
AppUpdatesURL=https://www.fossil-scm.org/
AppVerName=Fossil v{#AppVersion}
AppVersion={#AppVersion}
AppComments=Simple, high-reliability, distributed software configuration management system.
AppReadmeFile=https://www.fossil-scm.org/index.html/doc/tip/www/quickstart.wiki
DefaultDirName={pf}\Fossil
DefaultGroupName=Fossil
OutputBaseFilename=fossil-win32-{#AppVersion}
OutputManifestFile=fossil-win32-{#AppVersion}-manifest.txt
SetupLogging=true
UninstallFilesDir={app}\uninstall
VersionInfoVersion={#AppVersion}
|
| ︙ | ︙ |
Changes to skins/README.md.
1 2 3 4 | Built-in Skins ============== Each subdirectory under this folder describes a built-in "skin". | | | | > | | | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
Built-in Skins
==============
Each subdirectory under this folder describes a built-in "skin".
There are four files in each subdirectory for the CSS, the "details"
file, the footer, and the header for that skin.
To improve an existing built-in skin, simply edit the appropriate
files and recompile.
To add a new skin:
1. Create a new subdirectory under skins/. (The new directory is
called "skins/newskin" below but you should use a new original
name, of course.)
2. Add files skins/newskin/css.txt, skins/newskin/details.txt,
skins/newskin/footer.txt and skins/newskin/header.txt.
Be sure to "fossil add" these files.
3. Go to the src/ directory and rerun "tclsh makemake.tcl". This
step rebuilds the various makefiles so that they have dependencies
on the skin files you just installed.
4. Edit the BuiltinSkin[] array near the top of the src/skins.c source
file so that it describes and references the "newskin" skin.
5. Type "make" to rebuild.
Development Hints
-----------------
One way to develop a new skin is to copy the baseline files (css.txt,
details.txt, footer.txt, and header.txt) into a working directory $WORKDIR
then launch Fossil with a command-line option "--skin $WORKDIR". Example:
cp -r skins/default newskin
fossil ui --skin ./newskin
When the argument to --skin contains one or more '/' characters, the
appropriate skin files are read from disk from the directory specified.
So after launching fossil as shown above, you can edit the newskin/css.txt,
newskin/details.txt, newskin/footer.txt, and newskin/header.txt files using
your favorite text editor, then press Reload on your browser to see
immediate results.
|
Added skins/aht/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Added skins/black_and_white/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Changes to skins/blitz/css.txt.
| ︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 |
/* Timeline
* Displays chronologically-ordered check-ins with a branch graph.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– */
tr.timelineCurrent {
border-left: 2px solid orange;
background-color: #ffc;
}
tr.timelineSelected {
border-left: 2px solid orange;
background-color: #ffffe8;
}
tr.timelineCurrent td.timelineTableCell {
}
tr.timelineSpacer {
}
div.timelineDate {
| > > > > > > > > | | > > > > > > > > > > > > > > | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
/* Timeline
* Displays chronologically-ordered check-ins with a branch graph.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– */
tr.timelineCurrent {
border-left: 2px solid orange;
background-color: #ffc;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
}
tr.timelineSelected {
border-left: 2px solid orange;
background-color: #ffffe8;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
}
tr.timelineCurrent td.timelineTableCell {
}
tr.timelineSpacer {
}
tr.timelineBottom td {
border-bottom: 0;
}
div.timelineDate {
font-weight: bold;
white-space: nowrap;
}
td.timelineTime {
vertical-align: top;
text-align: right;
white-space: nowrap;
border-bottom: 0;
}
td.timelineGraph {
width: 20px;
text-align: left;
vertical-align: top;
border-bottom: 0;
}
a.timelineHistLink {
text-transform: lowercase;
}
span.timelineComment {
|
| ︙ | ︙ |
Added skins/blitz/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 0 timeline-circle-nodes: 1 timeline-color-graph-lines: 1 white-foreground: 0 |
Changes to skins/blitz_no_logo/css.txt.
| ︙ | ︙ | |||
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 |
/* Timeline
* Displays chronologically-ordered check-ins with a branch graph.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– */
tr.timelineCurrent {
border-left: 2px solid orange;
background-color: #ffc;
}
tr.timelineSelected {
border-left: 2px solid orange;
background-color: #ffffe8;
}
tr.timelineCurrent td.timelineTableCell {
}
tr.timelineSpacer {
}
div.timelineDate {
| > > > > > > > > | | > > > > > > > > > > > > > > | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
/* Timeline
* Displays chronologically-ordered check-ins with a branch graph.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– */
tr.timelineCurrent {
border-left: 2px solid orange;
background-color: #ffc;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
}
tr.timelineSelected {
border-left: 2px solid orange;
background-color: #ffffe8;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
}
tr.timelineCurrent td.timelineTableCell {
}
tr.timelineSpacer {
}
tr.timelineBottom td {
border-bottom: 0;
}
div.timelineDate {
font-weight: bold;
white-space: nowrap;
}
td.timelineTime {
vertical-align: top;
text-align: right;
white-space: nowrap;
border-bottom: 0;
}
td.timelineGraph {
width: 20px;
text-align: left;
vertical-align: top;
border-bottom: 0;
}
a.timelineHistLink {
text-transform: lowercase;
}
span.timelineComment {
|
| ︙ | ︙ |
Added skins/blitz_no_logo/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 0 timeline-circle-nodes: 1 timeline-color-graph-lines: 1 white-foreground: 0 |
Added skins/default/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 1 timeline-color-graph-lines: 1 white-foreground: 0 |
Changes to skins/eagle/css.txt.
| ︙ | ︙ | |||
166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
font-family: "courier new";
border-collapse: collapse;
}
tr.timelineSelected {
background-color: #7EA2D9;
}
/* Side-by-side diff */
table.sbsdiff {
background-color: #485D7B;
font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
font-size: 8pt;
border-collapse:collapse;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
font-family: "courier new";
border-collapse: collapse;
}
tr.timelineSelected {
background-color: #7EA2D9;
}
/* commit node */
.tl-node {
width: 10px;
height: 10px;
border: 1px solid #fff;
background: #485D7B;
cursor: pointer;
}
/* leaf commit marker */
.tl-node.leaf:after {
content: '';
position: absolute;
top: 3px;
left: 3px;
width: 4px;
height: 4px;
background: #fff;
}
/* up arrow */
.tl-arrow.u {
margin-top: -1px;
border-width: 0 3px;
border-bottom: 7px solid #fff;
}
/* small up arrow */
.tl-arrow.u.sm {
border-bottom: 5px solid #fff;
}
/* line */
.tl-line {
background: #fff;
width: 2px;
}
/* left merge arrow */
.tl-arrow.merge.l {
border-right: 3px solid #fff;
}
/* right merge arrow */
.tl-arrow.merge.r {
border-left: 3px solid #fff;
}
/* Side-by-side diff */
table.sbsdiff {
background-color: #485D7B;
font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
font-size: 8pt;
border-collapse:collapse;
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 |
}
/* line numbers in a diff */
span.diffln {
color: white;
}
| < < < < | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
}
/* line numbers in a diff */
span.diffln {
color: white;
}
.fileage tr:hover {
background-color: #7EA2D9;
}
.fileage td {
font-family: "courier new";
}
|
| ︙ | ︙ |
Added skins/eagle/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 1 |
Changes to skins/eagle/header.txt.
| ︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
}
if {[anoncap r]} {
menulink /ticket Tickets
}
if {[anoncap j]} {
menulink /wiki Wiki
}
if {[hascap s]} {
menulink /setup Admin
} elseif {[hascap a]} {
menulink /setup_ulist Users
}
if {[info exists login]} {
menulink /login Logout
| > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
}
if {[anoncap r]} {
menulink /ticket Tickets
}
if {[anoncap j]} {
menulink /wiki Wiki
}
menulink /sitemap More...
if {[hascap s]} {
menulink /setup Admin
} elseif {[hascap a]} {
menulink /setup_ulist Users
}
if {[info exists login]} {
menulink /login Logout
|
| ︙ | ︙ |
Added skins/enhanced1/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Added skins/khaki/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Added skins/original/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Added skins/plain_gray/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Added skins/rounded1/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Added skins/xekri/details.txt.
> > > > | 1 2 3 4 | timeline-arrowheads: 1 timeline-circle-nodes: 0 timeline-color-graph-lines: 0 white-foreground: 0 |
Changes to src/add.c.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | */ #include "config.h" #include "add.h" #include <assert.h> #include <dirent.h> #include "cygsup.h" /* ** This routine returns the names of files in a working checkout that ** are created by Fossil itself, and hence should not be added, deleted, ** or merge, and should be omitted from "clean" and "extras" lists. ** ** Return the N-th name. The first name has N==0. When all names have ** been used, return 0. | > > > > > > > > > > > > > > > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | */ #include "config.h" #include "add.h" #include <assert.h> #include <dirent.h> #include "cygsup.h" /* ** WARNING: For Fossil version 1.x this value was always zero. For Fossil ** 2.x, it will probably always be one. When this value is zero, ** files in the checkout will not be moved by the "mv" command and ** files in the checkout will not be removed by the "rm" command. ** ** If the FOSSIL_ENABLE_LEGACY_MV_RM compile-time option is used, ** the "mv-rm-files" setting will be consulted instead of using ** this value. ** ** To retain the Fossil version 1.x behavior when using Fossil 2.x, ** the FOSSIL_ENABLE_LEGACY_MV_RM compile-time option must be used ** -AND- the "mv-rm-files" setting must be set to zero. */ #ifndef FOSSIL_MV_RM_FILE #define FOSSIL_MV_RM_FILE (0) #endif /* ** This routine returns the names of files in a working checkout that ** are created by Fossil itself, and hence should not be added, deleted, ** or merge, and should be omitted from "clean" and "extras" lists. ** ** Return the N-th name. The first name has N==0. When all names have ** been used, return 0. |
| ︙ | ︙ | |||
297 298 299 300 301 302 303 |
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_wd_isdir(zName);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, scanFlags, pClean, pIgnore);
}else if( isDir==0 ){
fossil_warning("not found: %s", zName);
| < < | 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_wd_isdir(zName);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, scanFlags, pClean, pIgnore);
}else if( isDir==0 ){
fossil_warning("not found: %s", zName);
}else{
char *zTreeName = &zName[nRoot];
if( !forceFlag && glob_match(pIgnore, zTreeName) ){
Blob ans;
char cReply;
char *prompt = mprintf("file \"%s\" matches \"ignore-glob\". "
"Add it (a=all/y/N)? ", zTreeName);
|
| ︙ | ︙ | |||
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | } glob_free(pIgnore); glob_free(pClean); add_files_in_sfile(vid); db_end_transaction(0); } /* ** COMMAND: rm ** COMMAND: delete ** COMMAND: forget* ** ** Usage: %fossil rm|delete|forget FILE1 ?FILE2 ...? ** ** Remove one or more files or directories from the repository. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
}
glob_free(pIgnore);
glob_free(pClean);
add_files_in_sfile(vid);
db_end_transaction(0);
}
/*
** This function adds a file to list of files to delete from disk after
** the other actions required for the parent operation have completed
** successfully. The first time it is called for the current process,
** it creates a temporary table named "fremove", to keep track of these
** files.
*/
static void add_file_to_remove(
const char *zOldName /* The old name of the file on disk. */
){
static int tableCreated = 0;
Blob fullOldName;
if( !tableCreated ){
db_multi_exec("CREATE TEMP TABLE fremove(x TEXT PRIMARY KEY %s)",
filename_collation());
tableCreated = 1;
}
file_canonical_name(zOldName, &fullOldName, 0);
db_multi_exec("INSERT INTO fremove VALUES('%q');", blob_str(&fullOldName));
blob_reset(&fullOldName);
}
/*
** This function deletes files from the checkout, using the file names
** contained in the temporary table "fremove". The temporary table is
** created on demand by the add_file_to_remove() function.
**
** If dryRunFlag is non-zero, no files will be removed; however, their
** names will still be output.
**
** The temporary table "fremove" is dropped after being processed.
*/
static void process_files_to_remove(
int dryRunFlag /* Zero to actually operate on the file-system. */
){
Stmt remove;
db_prepare(&remove, "SELECT x FROM fremove ORDER BY x;");
while( db_step(&remove)==SQLITE_ROW ){
const char *zOldName = db_column_text(&remove, 0);
if( !dryRunFlag ){
file_delete(zOldName);
}
fossil_print("DELETED_FILE %s\n", zOldName);
}
db_finalize(&remove);
db_multi_exec("DROP TABLE fremove;");
}
/*
** COMMAND: rm
** COMMAND: delete
** COMMAND: forget*
**
** Usage: %fossil rm|delete|forget FILE1 ?FILE2 ...?
**
** Remove one or more files or directories from the repository.
**
** The 'rm' and 'delete' commands do NOT normally remove the files from
** disk. They just mark the files as no longer being part of the project.
** In other words, future changes to the named files will not be versioned.
** However, the default behavior of this command may be overridden via the
** command line options listed below and/or the 'mv-rm-files' setting.
**
** The 'forget' command never removes files from disk, even when the command
** line options and/or the 'mv-rm-files' setting would otherwise require it
** to do so.
**
** WARNING: If the "--hard" option is specified -OR- the "mv-rm-files"
** setting is non-zero, files WILL BE removed from disk as well.
** This does NOT apply to the 'forget' command.
**
** Options:
** --soft Skip removing files from the checkout.
** This supersedes the --hard option.
** --hard Remove files from the checkout.
** --case-sensitive <BOOL> Override the case-sensitive setting.
** -n|--dry-run If given, display instead of run actions.
**
** See also: addremove, add
*/
void delete_cmd(void){
int i;
int removeFiles;
int dryRunFlag;
int softFlag;
int hardFlag;
Stmt loop;
dryRunFlag = find_option("dry-run","n",0)!=0;
softFlag = find_option("soft",0,0)!=0;
hardFlag = find_option("hard",0,0)!=0;
/* We should be done with options.. */
verify_all_options();
db_must_be_within_tree();
db_begin_transaction();
if( g.argv[1][0]=='f' ){ /* i.e. "forget" */
removeFiles = 0;
}else if( softFlag ){
removeFiles = 0;
}else if( hardFlag ){
removeFiles = 1;
}else{
#if FOSSIL_ENABLE_LEGACY_MV_RM
removeFiles = db_get_boolean("mv-rm-files",0);
#else
removeFiles = FOSSIL_MV_RM_FILE;
#endif
}
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
filename_collation());
for(i=2; i<g.argc; i++){
Blob treeName;
char *zTreeName;
file_tree_name(g.argv[i], &treeName, 1);
|
| ︙ | ︙ | |||
380 381 382 383 384 385 386 387 388 |
);
blob_reset(&treeName);
}
db_prepare(&loop, "SELECT x FROM sfile");
while( db_step(&loop)==SQLITE_ROW ){
fossil_print("DELETED %s\n", db_column_text(&loop, 0));
}
db_finalize(&loop);
| > > | | | | > > | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
);
blob_reset(&treeName);
}
db_prepare(&loop, "SELECT x FROM sfile");
while( db_step(&loop)==SQLITE_ROW ){
fossil_print("DELETED %s\n", db_column_text(&loop, 0));
if( removeFiles ) add_file_to_remove(db_column_text(&loop, 0));
}
db_finalize(&loop);
if( !dryRunFlag ){
db_multi_exec(
"UPDATE vfile SET deleted=1 WHERE pathname IN sfile;"
"DELETE FROM vfile WHERE rid=0 AND deleted;"
);
}
db_end_transaction(0);
if( removeFiles ) process_files_to_remove(dryRunFlag);
}
/*
** Capture the command-line --case-sensitive option.
*/
static const char *zCaseSensitive = 0;
void capture_case_sensitive_option(void){
|
| ︙ | ︙ | |||
525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
/* We should be done with options.. */
verify_all_options();
db_must_be_within_tree();
if( zCleanFlag==0 ){
zCleanFlag = db_get("clean-glob", 0);
}
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
| > > > > > > > > | 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
/* We should be done with options.. */
verify_all_options();
/* Fail if unprocessed arguments are present, in case user expect the
** addremove command to accept a list of file or directory.
*/
if( g.argc>2 ){
fossil_fatal(
"%s: Can only work on the entire checkout, no arguments supported.",
g.argv[1]);
}
db_must_be_within_tree();
if( zCleanFlag==0 ){
zCleanFlag = db_get("clean-glob", 0);
}
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
|
| ︙ | ︙ | |||
591 592 593 594 595 596 597 | ** Rename a single file. ** ** The original name of the file is zOrig. The new filename is zNew. */ static void mv_one_file( int vid, const char *zOrig, | | > > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 |
** Rename a single file.
**
** The original name of the file is zOrig. The new filename is zNew.
*/
static void mv_one_file(
int vid,
const char *zOrig,
const char *zNew,
int dryRunFlag
){
int x = db_int(-1, "SELECT deleted FROM vfile WHERE pathname=%Q %s",
zNew, filename_collation());
if( x>=0 ){
if( x==0 ){
fossil_fatal("cannot rename '%s' to '%s' since another file named '%s'"
" is currently under management", zOrig, zNew, zNew);
}else{
fossil_fatal("cannot rename '%s' to '%s' since the delete of '%s' has "
"not yet been committed", zOrig, zNew, zNew);
}
}
fossil_print("RENAME %s %s\n", zOrig, zNew);
if( !dryRunFlag ){
db_multi_exec(
"UPDATE vfile SET pathname='%q' WHERE pathname='%q' %s AND vid=%d",
zNew, zOrig, filename_collation(), vid
);
}
}
/*
** This function adds a file to list of files to move on disk after the
** other actions required for the parent operation have completed
** successfully. The first time it is called for the current process,
** it creates a temporary table named "fmove", to keep track of these
** files.
*/
static void add_file_to_move(
const char *zOldName, /* The old name of the file on disk. */
const char *zNewName /* The new name of the file on disk. */
){
static int tableCreated = 0;
Blob fullOldName;
Blob fullNewName;
if( !tableCreated ){
db_multi_exec("CREATE TEMP TABLE fmove(x TEXT PRIMARY KEY %s, y TEXT %s)",
filename_collation(), filename_collation());
tableCreated = 1;
}
file_canonical_name(zOldName, &fullOldName, 0);
file_canonical_name(zNewName, &fullNewName, 0);
db_multi_exec("INSERT INTO fmove VALUES('%q','%q');",
blob_str(&fullOldName), blob_str(&fullNewName));
blob_reset(&fullNewName);
blob_reset(&fullOldName);
}
/*
** This function moves files within the checkout, using the file names
** contained in the temporary table "fmove". The temporary table is
** created on demand by the add_file_to_move() function.
**
** If dryRunFlag is non-zero, no files will be moved; however, their
** names will still be output.
**
** The temporary table "fmove" is dropped after being processed.
*/
static void process_files_to_move(
int dryRunFlag /* Zero to actually operate on the file-system. */
){
Stmt move;
db_prepare(&move, "SELECT x, y FROM fmove ORDER BY x;");
while( db_step(&move)==SQLITE_ROW ){
const char *zOldName = db_column_text(&move, 0);
const char *zNewName = db_column_text(&move, 1);
if( !dryRunFlag ){
if( file_wd_islink(zOldName) ){
symlink_copy(zOldName, zNewName);
}else{
file_copy(zOldName, zNewName);
}
file_delete(zOldName);
}
fossil_print("MOVED_FILE %s\n", zOldName);
}
db_finalize(&move);
db_multi_exec("DROP TABLE fmove;");
}
/*
** COMMAND: mv
** COMMAND: rename*
**
** Usage: %fossil mv|rename OLDNAME NEWNAME
** or: %fossil mv|rename OLDNAME... DIR
**
** Move or rename one or more files or directories within the repository tree.
** You can either rename a file or directory or move it to another subdirectory.
**
** The 'mv' command does NOT normally rename or move the files on disk.
** This command merely records the fact that file names have changed so
** that appropriate notations can be made at the next commit/check-in.
** However, the default behavior of this command may be overridden via
** command line options listed below and/or the 'mv-rm-files' setting.
**
** The 'rename' command never renames or moves files on disk, even when the
** command line options and/or the 'mv-rm-files' setting would otherwise
** require it to do so.
**
** WARNING: If the "--hard" option is specified -OR- the "mv-rm-files"
** setting is non-zero, files WILL BE renamed or moved on disk
** as well. This does NOT apply to the 'rename' command.
**
** Options:
** --soft Skip moving files within the checkout.
** This supersedes the --hard option.
** --hard Move files within the checkout.
** --case-sensitive <BOOL> Override the case-sensitive setting.
** -n|--dry-run If given, display instead of run actions.
**
** See also: changes, status
*/
void mv_cmd(void){
int i;
int vid;
int moveFiles;
int dryRunFlag;
int softFlag;
int hardFlag;
char *zDest;
Blob dest;
Stmt q;
db_must_be_within_tree();
dryRunFlag = find_option("dry-run","n",0)!=0;
softFlag = find_option("soft",0,0)!=0;
hardFlag = find_option("hard",0,0)!=0;
/* We should be done with options.. */
verify_all_options();
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("no checkout rename files in");
}
if( g.argc<4 ){
usage("OLDNAME NEWNAME");
}
zDest = g.argv[g.argc-1];
db_begin_transaction();
if( g.argv[1][0]=='r' ){ /* i.e. "rename" */
moveFiles = 0;
}else if( softFlag ){
moveFiles = 0;
}else if( hardFlag ){
moveFiles = 1;
}else{
#if FOSSIL_ENABLE_LEGACY_MV_RM
moveFiles = db_get_boolean("mv-rm-files",0);
#else
moveFiles = FOSSIL_MV_RM_FILE;
#endif
}
file_tree_name(zDest, &dest, 1);
db_multi_exec(
"UPDATE vfile SET origname=pathname WHERE origname IS NULL;"
);
db_multi_exec(
"CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);"
);
|
| ︙ | ︙ | |||
709 710 711 712 713 714 715 |
db_finalize(&q);
}
}
db_prepare(&q, "SELECT f, t FROM mv ORDER BY f");
while( db_step(&q)==SQLITE_ROW ){
const char *zFrom = db_column_text(&q, 0);
const char *zTo = db_column_text(&q, 1);
| | > > | 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 |
db_finalize(&q);
}
}
db_prepare(&q, "SELECT f, t FROM mv ORDER BY f");
while( db_step(&q)==SQLITE_ROW ){
const char *zFrom = db_column_text(&q, 0);
const char *zTo = db_column_text(&q, 1);
mv_one_file(vid, zFrom, zTo, dryRunFlag);
if( moveFiles ) add_file_to_move(zFrom, zTo);
}
db_finalize(&q);
db_end_transaction(0);
if( moveFiles ) process_files_to_move(dryRunFlag);
}
/*
** Function for stash_apply to be able to restore a file and indicate
** newly ADDED state.
*/
int stash_add_files_in_sfile(int vid){
return add_files_in_sfile(vid);
}
|
Changes to src/allrepo.c.
| ︙ | ︙ | |||
85 86 87 88 89 90 91 | ** that can be useful before or after a period of disconnected operation. ** ** On Win32 systems, the file is named "_fossil" and is located in ** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%. ** ** Available operations are: ** | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | ** that can be useful before or after a period of disconnected operation. ** ** On Win32 systems, the file is named "_fossil" and is located in ** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%. ** ** Available operations are: ** ** changes Shows all local checkouts that have uncommitted changes. ** This operation has no additional options. ** ** clean Delete all "extra" files in all local checkouts. Extreme ** caution should be exercised with this command because its ** effects cannot be undone. Use of the --dry-run option to ** carefully review the local checkouts to be operated upon ** and the --whatif option to carefully review the files to ** be deleted beforehand is highly recommended. The command ** line options supported by the clean command itself, if any ** are present, are passed along verbatim. ** ** dbstat Run the "dbstat" command on all repositories. ** ** extras Shows "extra" files from all local checkouts. The command ** line options supported by the extra command itself, if any ** are present, are passed along verbatim. ** ** fts-config Run the "fts-config" command on all repositories. ** ** info Run the "info" command on all repositories. ** ** pull Run a "pull" operation on all repositories. Only the ** --verbose option is supported. ** ** push Run a "push" on all repositories. Only the --verbose ** option is supported. ** ** rebuild Rebuild on all repositories. The command line options ** supported by the rebuild command itself, if any are ** present, are passed along verbatim. The --force and ** --randomize options are not supported. ** ** sync Run a "sync" on all repositories. Only the --verbose ** option is supported. ** ** setting Run the "setting", "set", or "unset" commands on all ** set repositories. These command are particularly useful in ** unset conjunction with the "max-loadavg" setting which cannot ** otherwise be set globally. ** ** In addition, the following maintenance operations are supported: ** ** add Add all the repositories named to the set of repositories ** tracked by Fossil. Normally Fossil is able to keep up with ** this list by itself, but sometime it can benefit from this ** hint if you rename repositories. ** ** ignore Arguments are repositories that should be ignored by ** subsequent clean, extras, list, pull, push, rebuild, and ** sync operations. The -c|--ckout option causes the listed ** local checkouts to be ignored instead. ** ** list | ls Display the location of all repositories. The -c|--ckout ** option causes all local checkouts to be listed instead. ** ** Repositories are automatically added to the set of known repositories ** when one of the following commands are run against the repository: ** clone, info, pull, push, or sync. Even previously ignored repositories ** are added back to the list of repositories by these commands. ** ** Options: |
| ︙ | ︙ | |||
172 173 174 175 176 177 178 |
dryRunFlag = find_option("dry-run","n",0)!=0;
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
if( g.argc<3 ){
| | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
dryRunFlag = find_option("dry-run","n",0)!=0;
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
if( g.argc<3 ){
usage("SUBCOMMAND ...");
}
n = strlen(g.argv[2]);
db_open_config(1);
blob_zero(&extra);
zCmd = g.argv[2];
if( !login_is_nobody() ) blob_appendf(&extra, " -U %s", g.zLogin);
if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){
|
| ︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
}else if( strncmp(zCmd, "pull", n)==0 ){
zCmd = "pull -autourl -R";
collect_argument(&extra, "verbose","v");
}else if( strncmp(zCmd, "rebuild", n)==0 ){
zCmd = "rebuild";
collect_argument(&extra, "cluster",0);
collect_argument(&extra, "compress",0);
collect_argument(&extra, "noverify",0);
collect_argument_value(&extra, "pagesize");
collect_argument(&extra, "vacuum",0);
collect_argument(&extra, "deanalyze",0);
collect_argument(&extra, "analyze",0);
collect_argument(&extra, "wal",0);
collect_argument(&extra, "stats",0);
| > | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
}else if( strncmp(zCmd, "pull", n)==0 ){
zCmd = "pull -autourl -R";
collect_argument(&extra, "verbose","v");
}else if( strncmp(zCmd, "rebuild", n)==0 ){
zCmd = "rebuild";
collect_argument(&extra, "cluster",0);
collect_argument(&extra, "compress",0);
collect_argument(&extra, "compress-only",0);
collect_argument(&extra, "noverify",0);
collect_argument_value(&extra, "pagesize");
collect_argument(&extra, "vacuum",0);
collect_argument(&extra, "deanalyze",0);
collect_argument(&extra, "analyze",0);
collect_argument(&extra, "wal",0);
collect_argument(&extra, "stats",0);
|
| ︙ | ︙ | |||
271 272 273 274 275 276 277 |
Blob fn = BLOB_INITIALIZER;
Blob sql = BLOB_INITIALIZER;
useCheckouts = find_option("ckout","c",0)!=0;
verify_all_options();
db_begin_transaction();
for(j=3; j<g.argc; j++, blob_reset(&sql), blob_reset(&fn)){
file_canonical_name(g.argv[j], &fn, 0);
| | > > > | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
Blob fn = BLOB_INITIALIZER;
Blob sql = BLOB_INITIALIZER;
useCheckouts = find_option("ckout","c",0)!=0;
verify_all_options();
db_begin_transaction();
for(j=3; j<g.argc; j++, blob_reset(&sql), blob_reset(&fn)){
file_canonical_name(g.argv[j], &fn, 0);
blob_append_sql(&sql,
"DELETE FROM global_config WHERE name GLOB '%s:%q'",
useCheckouts?"ckout":"repo", blob_str(&fn)
);
if( dryRunFlag ){
fossil_print("%s\n", blob_sql_text(&sql));
}else{
db_multi_exec("%s", blob_sql_text(&sql));
}
}
db_end_transaction(0);
blob_reset(&sql);
blob_reset(&fn);
blob_reset(&extra);
return;
}else if( strncmp(zCmd, "add", n)==0 ){
int j;
Blob fn = BLOB_INITIALIZER;
Blob sql = BLOB_INITIALIZER;
verify_all_options();
db_begin_transaction();
|
| ︙ | ︙ | |||
311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
if( dryRunFlag ){
fossil_print("%s\n", blob_sql_text(&sql));
}else{
db_multi_exec("%s", blob_sql_text(&sql));
}
}
db_end_transaction(0);
return;
}else if( strncmp(zCmd, "info", n)==0 ){
zCmd = "info";
showLabel = 1;
quiet = 1;
}else{
fossil_fatal("\"all\" subcommand should be one of: "
| > > > | > | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
if( dryRunFlag ){
fossil_print("%s\n", blob_sql_text(&sql));
}else{
db_multi_exec("%s", blob_sql_text(&sql));
}
}
db_end_transaction(0);
blob_reset(&sql);
blob_reset(&fn);
blob_reset(&extra);
return;
}else if( strncmp(zCmd, "info", n)==0 ){
zCmd = "info";
showLabel = 1;
quiet = 1;
}else{
fossil_fatal("\"all\" subcommand should be one of: "
"add changes clean dbstat extras fts-config ignore "
"info list ls pull push rebuild setting sync unset");
}
verify_all_options();
zFossil = quoteFilename(g.nameOfExe);
db_multi_exec("CREATE TEMP TABLE repolist(name,tag);");
if( useCheckouts ){
db_multi_exec(
"INSERT INTO repolist "
|
| ︙ | ︙ | |||
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
free(zSyscmd);
free(zQFilename);
if( stopOnError && rc ){
break;
}
}
db_finalize(&q);
/* If any repositories whose names appear in the ~/.fossil file could not
** be found, remove those names from the ~/.fossil file.
*/
if( nToDel>0 ){
const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
if( dryRunFlag ){
fossil_print("%s\n", zSql);
}else{
db_multi_exec("%s", zSql /*safe-for-%s*/ );
}
}
}
| > > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
free(zSyscmd);
free(zQFilename);
if( stopOnError && rc ){
break;
}
}
db_finalize(&q);
blob_reset(&extra);
/* If any repositories whose names appear in the ~/.fossil file could not
** be found, remove those names from the ~/.fossil file.
*/
if( nToDel>0 ){
const char *zSql = "DELETE FROM global_config WHERE name IN toDel";
if( dryRunFlag ){
fossil_print("%s\n", zSql);
}else{
db_multi_exec("%s", zSql /*safe-for-%s*/ );
}
}
}
|
Changes to src/attach.c.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 | */ #include "config.h" #include "attach.h" #include <assert.h> /* ** WEBPAGE: attachlist ** ** tkt=TICKETUUID ** page=WIKIPAGE ** | > < | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
*/
#include "config.h"
#include "attach.h"
#include <assert.h>
/*
** WEBPAGE: attachlist
** List attachments.
**
** tkt=TICKETUUID
** page=WIKIPAGE
**
** Either one of tkt= or page= are supplied or neither but not both.
** If neither are given, all attachments are listed. If one is given,
** only attachments for the designated ticket or wiki page are shown.
** TICKETUUID must be complete
*/
void attachlist_page(void){
const char *zPage = P("page");
const char *zTkt = P("tkt");
Blob sql;
Stmt q;
|
| ︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 141 142 143 | } /* ** WEBPAGE: attachdownload ** WEBPAGE: attachimage ** WEBPAGE: attachview ** ** tkt=TICKETUUID ** page=WIKIPAGE ** file=FILENAME ** attachid=ID ** | > > > < | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
}
/*
** WEBPAGE: attachdownload
** WEBPAGE: attachimage
** WEBPAGE: attachview
**
** Download or display an attachment.
** Query parameters:
**
** tkt=TICKETUUID
** page=WIKIPAGE
** file=FILENAME
** attachid=ID
**
*/
void attachview_page(void){
const char *zPage = P("page");
const char *zTkt = P("tkt");
const char *zFile = P("file");
const char *zTarget = 0;
int attachid = atoi(PD("attachid","0"));
|
| ︙ | ︙ | |||
221 222 223 224 225 226 227 228 229 230 231 232 | } manifest_crosslink(rid, pAttach, MC_NONE); } /* ** WEBPAGE: attachadd ** ** tkt=TICKETUUID ** page=WIKIPAGE ** from=URL ** | > < | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
}
manifest_crosslink(rid, pAttach, MC_NONE);
}
/*
** WEBPAGE: attachadd
** Add a new attachment.
**
** tkt=TICKETUUID
** page=WIKIPAGE
** from=URL
**
*/
void attachadd_page(void){
const char *zPage = P("page");
const char *zTkt = P("tkt");
const char *zFrom = P("from");
const char *aContent = P("f");
const char *zName = PD("f:filename","unknown");
|
| ︙ | ︙ |
Changes to src/blob.c.
| ︙ | ︙ | |||
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
int fossil_isalnum(char c){
return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9');
}
/*
** COMMAND: test-isspace
*/
void isspace_cmd(void){
int i;
for(i=0; i<=255; i++){
if( i==' ' || i=='\n' || i=='\t' || i=='\v'
|| i=='\f' || i=='\r' ){
assert( fossil_isspace((char)i) );
| > > > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
int fossil_isalnum(char c){
return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9');
}
/*
** COMMAND: test-isspace
**
** Verify that the fossil_isspace() routine is working correctly but
** testing it on all possible inputs.
*/
void isspace_cmd(void){
int i;
for(i=0; i<=255; i++){
if( i==' ' || i=='\n' || i=='\t' || i=='\v'
|| i=='\f' || i=='\r' ){
assert( fossil_isspace((char)i) );
|
| ︙ | ︙ | |||
882 883 884 885 886 887 888 889 890 891 892 893 894 895 |
assert_blob_is_reset(pOut);
*pOut = temp;
blob_resize(pOut, nOut2+4);
}
/*
** COMMAND: test-compress
*/
void compress_cmd(void){
Blob f;
if( g.argc!=4 ) usage("INPUTFILE OUTPUTFILE");
blob_read_from_file(&f, g.argv[2]);
blob_compress(&f, &f);
blob_write_to_file(&f, g.argv[3]);
| > > > > > > | 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 |
assert_blob_is_reset(pOut);
*pOut = temp;
blob_resize(pOut, nOut2+4);
}
/*
** COMMAND: test-compress
**
** Usage: %fossil test-compress INPUTFILE OUTPUTFILE
**
** Run compression on INPUTFILE and write the result into OUTPUTFILE.
**
** This is used to test and debug the blob_compress() routine.
*/
void compress_cmd(void){
Blob f;
if( g.argc!=4 ) usage("INPUTFILE OUTPUTFILE");
blob_read_from_file(&f, g.argv[2]);
blob_compress(&f, &f);
blob_write_to_file(&f, g.argv[3]);
|
| ︙ | ︙ | |||
934 935 936 937 938 939 940 941 942 943 944 945 946 947 |
if( pOut==pIn2 ) blob_reset(pOut);
assert_blob_is_reset(pOut);
*pOut = temp;
}
/*
** COMMAND: test-compress-2
*/
void compress2_cmd(void){
Blob f1, f2;
if( g.argc!=5 ) usage("INPUTFILE1 INPUTFILE2 OUTPUTFILE");
blob_read_from_file(&f1, g.argv[2]);
blob_read_from_file(&f2, g.argv[3]);
blob_compress2(&f1, &f2, &f1);
| > > > > > > > | 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
if( pOut==pIn2 ) blob_reset(pOut);
assert_blob_is_reset(pOut);
*pOut = temp;
}
/*
** COMMAND: test-compress-2
**
** Usage: %fossil test-compress-2 IN1 IN2 OUT
**
** Read files IN1 and IN2, concatenate the content, compress the
** content, then write results into OUT.
**
** This is used to test and debug the blob_compress2() routine.
*/
void compress2_cmd(void){
Blob f1, f2;
if( g.argc!=5 ) usage("INPUTFILE1 INPUTFILE2 OUTPUTFILE");
blob_read_from_file(&f1, g.argv[2]);
blob_read_from_file(&f2, g.argv[3]);
blob_compress2(&f1, &f2, &f1);
|
| ︙ | ︙ | |||
980 981 982 983 984 985 986 987 988 989 990 991 992 993 |
assert_blob_is_reset(pOut);
*pOut = temp;
return 0;
}
/*
** COMMAND: test-uncompress
*/
void uncompress_cmd(void){
Blob f;
if( g.argc!=4 ) usage("INPUTFILE OUTPUTFILE");
blob_read_from_file(&f, g.argv[2]);
blob_uncompress(&f, &f);
blob_write_to_file(&f, g.argv[3]);
| > > > > > > | 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 |
assert_blob_is_reset(pOut);
*pOut = temp;
return 0;
}
/*
** COMMAND: test-uncompress
**
** Usage: %fossil test-uncompress IN OUT
**
** Read the content of file IN, uncompress that content, and write the
** result into OUT. This command is intended for testing of the the
** blob_compress() function.
*/
void uncompress_cmd(void){
Blob f;
if( g.argc!=4 ) usage("INPUTFILE OUTPUTFILE");
blob_read_from_file(&f, g.argv[2]);
blob_uncompress(&f, &f);
blob_write_to_file(&f, g.argv[3]);
|
| ︙ | ︙ |
Changes to src/branch.c.
| ︙ | ︙ | |||
384 385 386 387 388 389 390 |
db_finalize(&q);
output_table_sorting_javascript("branchlisttable","tkNtt",2);
style_footer();
}
/*
** WEBPAGE: brlist
| | > > > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
db_finalize(&q);
output_table_sorting_javascript("branchlisttable","tkNtt",2);
style_footer();
}
/*
** WEBPAGE: brlist
** Show a list of branches. With no query parameters, a sortable table
** is used to show all branches. If query parameters are present a
** fixed bullet list is shown.
**
** Query parameters:
**
** all Show all branches
** closed Show only closed branches
** open Show only open branches (default behavior)
** colortest Show all branches with automatic color
*/
|
| ︙ | ︙ |
Changes to src/browse.c.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
}
}
/*
** WEBPAGE: dir
**
** Query parameters:
**
** name=PATH Directory to display. Optional. Top-level if missing
** ci=LABEL Show only files in this check-in. Optional.
*/
void page_dir(void){
char *zD = fossil_strdup(P("name"));
int nD = zD ? strlen(zD)+1 : 0;
int mxLen;
int nCol, nRow;
int cnt, i;
| > > > > > > > | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
}
}
/*
** WEBPAGE: dir
**
** Show the files and subdirectories within a single directory of the
** source tree. Only files for a single check-in are shown if the ci=
** query parameter is present. If ci= is missing, the union of files
** across all check-ins is shown.
**
** Query parameters:
**
** name=PATH Directory to display. Optional. Top-level if missing
** ci=LABEL Show only files in this check-in. Optional.
** type=TYPE TYPE=flat: use this display
** TYPE=tree: use the /tree display instead
*/
void page_dir(void){
char *zD = fossil_strdup(P("name"));
int nD = zD ? strlen(zD)+1 : 0;
int mxLen;
int nCol, nRow;
int cnt, i;
|
| ︙ | ︙ | |||
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | } if( pTree->pLast ) pTree->pLast->pNext = 0; } /* ** WEBPAGE: tree ** ** Query parameters: ** ** name=PATH Directory to display. Optional ** ci=LABEL Show only files in this check-in. Optional. ** re=REGEXP Show only files matching REGEXP. Optional. ** expand Begin with the tree fully expanded. ** nofiles Show directories (folders) only. Omit files. ** mtime Order directory elements by decreasing mtime */ | > > > > > > > > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | } if( pTree->pLast ) pTree->pLast->pNext = 0; } /* ** WEBPAGE: tree ** ** Show the files using a tree-view. If the ci= query parameter is present ** then show only the files for the check-in identified. If ci= is omitted, ** then show the union of files over all check-ins. ** ** The type=tree query parameter is required or else the /dir format is ** used. ** ** Query parameters: ** ** type=tree Required to prevent use of /dir format ** name=PATH Directory to display. Optional ** ci=LABEL Show only files in this check-in. Optional. ** re=REGEXP Show only files matching REGEXP. Optional. ** expand Begin with the tree fully expanded. ** nofiles Show directories (folders) only. Omit files. ** mtime Order directory elements by decreasing mtime */ |
| ︙ | ︙ | |||
983 984 985 986 987 988 989 990 991 992 993 994 995 996 |
fossil_free(zAge);
}
db_finalize(&q);
}
/*
** WEBPAGE: fileage
**
** Parameters:
** name=VERSION Selects the check-in version (default=tip).
** glob=STRING Only shows files matching this glob pattern
** (e.g. *.c or *.txt).
** showid Show RID values for debugging
*/
| > > > | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
fossil_free(zAge);
}
db_finalize(&q);
}
/*
** WEBPAGE: fileage
**
** Show all files in a single check-in (identified by the name= query
** parameter) in order of increasing age.
**
** Parameters:
** name=VERSION Selects the check-in version (default=tip).
** glob=STRING Only shows files matching this glob pattern
** (e.g. *.c or *.txt).
** showid Show RID values for debugging
*/
|
| ︙ | ︙ |
Changes to src/cache.c.
| ︙ | ︙ | |||
328 329 330 331 332 333 334 |
" Should be one of: clear init list status", zCmd);
}
}
/*
** WEBPAGE: cachestat
**
| | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
" Should be one of: clear init list status", zCmd);
}
}
/*
** WEBPAGE: cachestat
**
** Show information about the webpage cache. Requires Admin privilege.
*/
void cache_page(void){
sqlite3 *db;
sqlite3_stmt *pStmt;
char zBuf[100];
login_check_credentials();
|
| ︙ | ︙ | |||
378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
/*
** WEBPAGE: cacheget
**
** Usage: /cacheget?key=KEY
**
** Download a single entry for the cache, identified by KEY.
** This page is normally a hyperlink from the /cachestat page.
*/
void cache_getpage(void){
const char *zKey;
Blob content;
login_check_credentials();
if( !g.perm.Setup ){ login_needed(0); return; }
| > | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
/*
** WEBPAGE: cacheget
**
** Usage: /cacheget?key=KEY
**
** Download a single entry for the cache, identified by KEY.
** This page is normally a hyperlink from the /cachestat page.
** Requires Admin privilege.
*/
void cache_getpage(void){
const char *zKey;
Blob content;
login_check_credentials();
if( !g.perm.Setup ){ login_needed(0); return; }
|
| ︙ | ︙ |
Changes to src/captcha.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 | #if INTERFACE #define CAPTCHA 3 /* Which captcha rendering to use */ #endif /* ** Convert a hex digit into a value between 0 and 15 */ | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#if INTERFACE
#define CAPTCHA 3 /* Which captcha rendering to use */
#endif
/*
** Convert a hex digit into a value between 0 and 15
*/
int hex_digit_value(char c){
if( c>='0' && c<='9' ){
return c - '0';
}else if( c>='a' && c<='f' ){
return c - 'a' + 10;
}else if( c>='A' && c<='F' ){
return c - 'A' + 10;
}else{
|
| ︙ | ︙ | |||
73 74 75 76 77 78 79 |
char *captcha_render(const char *zPw){
char *z = fossil_malloc( 9*6*strlen(zPw) + 7 );
int i, j, k, m;
k = 0;
for(i=0; i<6; i++){
for(j=0; zPw[j]; j++){
| | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
char *captcha_render(const char *zPw){
char *z = fossil_malloc( 9*6*strlen(zPw) + 7 );
int i, j, k, m;
k = 0;
for(i=0; i<6; i++){
for(j=0; zPw[j]; j++){
unsigned char v = hex_digit_value(zPw[j]);
v = (aFont1[v] >> ((5-i)*4)) & 0xf;
for(m=8; m>=1; m = m>>1){
if( v & m ){
z[k++] = 'X';
z[k++] = 'X';
}else{
z[k++] = ' ';
|
| ︙ | ︙ | |||
207 208 209 210 211 212 213 |
char *z = fossil_malloc( 7*4*strlen(zPw) + 5 );
int i, j, k, m;
const char *zChar;
k = 0;
for(i=0; i<4; i++){
for(j=0; zPw[j]; j++){
| | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
char *z = fossil_malloc( 7*4*strlen(zPw) + 5 );
int i, j, k, m;
const char *zChar;
k = 0;
for(i=0; i<4; i++){
for(j=0; zPw[j]; j++){
unsigned char v = hex_digit_value(zPw[j]);
zChar = azFont2[4*v + i];
for(m=0; zChar[m]; m++){
z[k++] = zChar[m];
}
}
z[k++] = '\n';
}
|
| ︙ | ︙ | |||
367 368 369 370 371 372 373 |
unsigned char x;
int y;
k = 0;
for(i=0; i<6; i++){
x = 0;
for(j=0; zPw[j]; j++){
| | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
unsigned char x;
int y;
k = 0;
for(i=0; i<6; i++){
x = 0;
for(j=0; zPw[j]; j++){
unsigned char v = hex_digit_value(zPw[j]);
x = (x<<4) + v;
switch( x ){
case 0x7a:
case 0xfa:
y = 3;
break;
case 0x47:
|
| ︙ | ︙ | |||
412 413 414 415 416 417 418 419 420 421 422 423 424 425 |
z[k] = 0;
return z;
}
#endif /* CAPTCHA==3 */
/*
** COMMAND: test-captcha
*/
void test_captcha(void){
int i;
unsigned int v;
char *z;
for(i=2; i<g.argc; i++){
| > > | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
z[k] = 0;
return z;
}
#endif /* CAPTCHA==3 */
/*
** COMMAND: test-captcha
**
** Render an ASCII-art captcha for numbers given on the command line.
*/
void test_captcha(void){
int i;
unsigned int v;
char *z;
for(i=2; i<g.argc; i++){
|
| ︙ | ︙ | |||
549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
@ <input type="submit" value="Submit">
}
@ </td></tr></table></div>
}
/*
** WEBPAGE: test-captcha
*/
void captcha_test(void){
const char *zPw = P("name");
if( zPw==0 || zPw[0]==0 ){
u64 x;
sqlite3_randomness(sizeof(x), &x);
zPw = mprintf("%016llx", x);
| > > > | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
@ <input type="submit" value="Submit">
}
@ </td></tr></table></div>
}
/*
** WEBPAGE: test-captcha
** Test the captcha-generator by rendering the value of the name= query
** parameter using ascii-art. If name= is omitted, show a random 16-digit
** hexadecimal number.
*/
void captcha_test(void){
const char *zPw = P("name");
if( zPw==0 || zPw[0]==0 ){
u64 x;
sqlite3_randomness(sizeof(x), &x);
zPw = mprintf("%016llx", x);
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 | int nErr = 0; Blob rewrittenPathname; Blob where; const char *zName; int i; blob_zero(&where); | | | | > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
int nErr = 0;
Blob rewrittenPathname;
Blob where;
const char *zName;
int i;
blob_zero(&where);
for(i=2; i<g.argc; i++){
Blob fname;
file_tree_name(g.argv[i], &fname, 1);
zName = blob_str(&fname);
if( fossil_strcmp(zName, ".")==0 ){
blob_reset(&where);
break;
}
blob_append_sql(&where,
" %s (pathname=%Q %s) "
"OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
(blob_size(&where)>0) ? "OR" : "AND", zName,
filename_collation(), zName, filename_collation(),
zName, filename_collation()
);
}
db_prepare(&q,
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
" FROM vfile "
" WHERE is_selected(id) %s"
" AND (chnged OR deleted OR rid=0 OR pathname!=origname)"
" ORDER BY 1 /*scan*/",
blob_sql_text(&where)
);
blob_zero(&rewrittenPathname);
while( db_step(&q)==SQLITE_ROW ){
const char *zPathname = db_column_text(&q,0);
const char *zDisplayName = zPathname;
int isDeleted = db_column_int(&q, 1);
|
| ︙ | ︙ | |||
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
}
vid = db_lget_int("checkout", 0);
if( vid ){
show_common_info(vid, "checkout:", 1, 1);
}
db_record_repository_filename(0);
print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative);
}
/*
** Take care of -r version of ls command
*/
static void ls_cmd_rev(
const char *zRev, /* Revision string given */
int verboseFlag, /* Verbose flag given */
| > | | | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
}
vid = db_lget_int("checkout", 0);
if( vid ){
show_common_info(vid, "checkout:", 1, 1);
}
db_record_repository_filename(0);
print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative);
leaf_ambiguity_warning(vid, vid);
}
/*
** Take care of -r version of ls command
*/
static void ls_cmd_rev(
const char *zRev, /* Revision string given */
int verboseFlag, /* Verbose flag given */
int showAge, /* Age flag given */
int timeOrder /* Order by time flag given */
){
Stmt q;
char *zOrderBy = "pathname COLLATE nocase";
char *zName;
Blob where;
int rid;
int i;
/* Handle given file names */
blob_zero(&where);
for(i=2; i<g.argc; i++){
Blob fname;
file_tree_name(g.argv[i], &fname, 1);
zName = blob_str(&fname);
if( fossil_strcmp(zName, ".")==0 ){
blob_reset(&where);
break;
}
blob_append_sql(&where,
" %s (pathname=%Q %s) "
"OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
(blob_size(&where)>0) ? "OR" : "AND (", zName,
filename_collation(), zName, filename_collation(),
zName, filename_collation()
);
}
if( blob_size(&where)>0 ){
blob_append_sql(&where, ")");
}
rid = symbolic_name_to_rid(zRev, "ci");
if( rid==0 ){
fossil_fatal("not a valid check-in: %s", zRev);
}
if( timeOrder ){
zOrderBy = "mtime DESC";
}
compute_fileage(rid,0);
db_prepare(&q,
"SELECT datetime(fileage.mtime, 'localtime'), fileage.pathname,\n"
|
| ︙ | ︙ | |||
331 332 333 334 335 336 337 |
int size = db_column_int(&q,2);
if( verboseFlag ){
fossil_print("%s %7d %s\n", zTime, size, zFile);
}else if( showAge ){
fossil_print("%s %s\n", zTime, zFile);
}else{
fossil_print("%s\n", zFile);
| | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
int size = db_column_int(&q,2);
if( verboseFlag ){
fossil_print("%s %7d %s\n", zTime, size, zFile);
}else if( showAge ){
fossil_print("%s %s\n", zTime, zFile);
}else{
fossil_print("%s\n", zFile);
}
}
db_finalize(&q);
}
/*
** COMMAND: ls
**
|
| ︙ | ︙ | |||
399 400 401 402 403 404 405 |
}
verify_all_options();
blob_zero(&where);
for(i=2; i<g.argc; i++){
Blob fname;
file_tree_name(g.argv[i], &fname, 1);
zName = blob_str(&fname);
| | | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
}
verify_all_options();
blob_zero(&where);
for(i=2; i<g.argc; i++){
Blob fname;
file_tree_name(g.argv[i], &fname, 1);
zName = blob_str(&fname);
if( fossil_strcmp(zName, ".")==0 ){
blob_reset(&where);
break;
}
blob_append_sql(&where,
" %s (pathname=%Q %s) "
"OR (pathname>'%q/' %s AND pathname<'%q0' %s)",
(blob_size(&where)>0) ? "OR" : "WHERE", zName,
|
| ︙ | ︙ | |||
591 592 593 594 595 596 597 |
fossil_all_reserved_names(0)
);
db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
blob_zero(&rewrittenPathname);
g.allowSymlinks = 1; /* Report on symbolic links */
while( db_step(&q)==SQLITE_ROW ){
zDisplayName = zPathname = db_column_text(&q, 0);
| | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 |
fossil_all_reserved_names(0)
);
db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
blob_zero(&rewrittenPathname);
g.allowSymlinks = 1; /* Report on symbolic links */
while( db_step(&q)==SQLITE_ROW ){
zDisplayName = zPathname = db_column_text(&q, 0);
if( cwdRelative ){
char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
file_relative_name(zFullName, &rewrittenPathname, 0);
free(zFullName);
zDisplayName = blob_str(&rewrittenPathname);
if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
zDisplayName += 2; /* no unnecessary ./ prefix */
}
|
| ︙ | ︙ | |||
613 614 615 616 617 618 619 | } blob_reset(&rewrittenPathname); db_finalize(&q); } /* ** COMMAND: clean | | | | > | | | | | < | < < < | | | > > > | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | } blob_reset(&rewrittenPathname); db_finalize(&q); } /* ** COMMAND: clean ** Usage: %fossil clean ?OPTIONS? ?PATH ...? ** ** Delete all "extra" files in the source tree. "Extra" files are ** files that are not officially part of the checkout. This operation ** cannot be undone. If one or more PATH arguments appear, then only ** the files named, or files contained with directories named, will be ** removed. ** ** Prompted are issued to confirm the removal of each file, unless ** the --force flag is used or unless the file matches glob pattern ** specified by the --clean option. No file that matches glob patterns ** specified by --ignore or --keep will ever be deleted. The default ** values for --clean, --ignore, and --keep are determined by the ** (versionable) clean-glob, ignore-glob, and keep-glob settings. ** Files and subdirectories whose names begin with "." are automatically ** ignored unless the --dotfiles option is used. ** ** The --verily option ignores the keep-glob and ignore-glob settings ** and turns on --force, --dotfiles, and --emptydirs. Use the --verily ** option when you really want to clean up everything. ** ** Options: ** --allckouts Check for empty directories within any checkouts ** that may be nested within the current one. This ** option should be used with great care because the ** empty-dirs setting (and other applicable settings) ** belonging to the other repositories, if any, will |
| ︙ | ︙ | |||
654 655 656 657 658 659 660 | ** explicitly exempted via the empty-dirs setting ** or another applicable setting or command line ** argument. Matching files, if any, are removed ** prior to checking for any empty directories; ** therefore, directories that contain only files ** that were removed will be removed as well. ** -f|--force Remove files without prompting. | > | > | > > | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
** explicitly exempted via the empty-dirs setting
** or another applicable setting or command line
** argument. Matching files, if any, are removed
** prior to checking for any empty directories;
** therefore, directories that contain only files
** that were removed will be removed as well.
** -f|--force Remove files without prompting.
** -x|--verily Remove everything that is not a managed file or
** the repository itself. Implies -f --emptydirs
** --dotfiles. Disregard keep-glob and ignore-glob.
** --clean <CSG> Never prompt for files matching this
** comma separated list of glob patterns.
** --ignore <CSG> Ignore files matching patterns from the
** comma separated list of glob patterns.
** --keep <CSG> Keep files matching this comma separated
** list of glob patterns.
** -n|--dry-run Delete nothing, but display what would have been
** deleted.
** --temp Remove only Fossil-generated temporary files.
** -v|--verbose Show all files as they are removed.
**
** See also: addremove, extras, status
*/
void clean_cmd(void){
int allFileFlag, allDirFlag, dryRunFlag, verboseFlag;
int emptyDirsFlag, dirsOnlyFlag;
unsigned scanFlags = 0;
int verilyFlag = 0;
const char *zIgnoreFlag, *zKeepFlag, *zCleanFlag;
Glob *pIgnore, *pKeep, *pClean;
int nRoot;
dryRunFlag = find_option("dry-run","n",0)!=0;
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
|
| ︙ | ︙ | |||
693 694 695 696 697 698 699 |
if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
zIgnoreFlag = find_option("ignore",0,1);
verboseFlag = find_option("verbose","v",0)!=0;
zKeepFlag = find_option("keep",0,1);
zCleanFlag = find_option("clean",0,1);
db_must_be_within_tree();
| | | > | | | | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
zIgnoreFlag = find_option("ignore",0,1);
verboseFlag = find_option("verbose","v",0)!=0;
zKeepFlag = find_option("keep",0,1);
zCleanFlag = find_option("clean",0,1);
db_must_be_within_tree();
if( find_option("verily","x",0)!=0 ){
verilyFlag = allFileFlag = allDirFlag = 1;
emptyDirsFlag = 1;
scanFlags |= SCAN_ALL;
zCleanFlag = 0;
}
if( zIgnoreFlag==0 && !verilyFlag ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
if( zKeepFlag==0 && !verilyFlag ){
zKeepFlag = db_get("keep-glob", 0);
}
if( zCleanFlag==0 && !verilyFlag ){
zCleanFlag = db_get("clean-glob", 0);
}
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
verify_all_options();
pIgnore = glob_create(zIgnoreFlag);
pKeep = glob_create(zKeepFlag);
pClean = glob_create(zCleanFlag);
|
| ︙ | ︙ | |||
752 753 754 755 756 757 758 |
allFileFlag = 1;
}else if( cReply!='y' && cReply!='Y' ){
blob_reset(&ans);
continue;
}
blob_reset(&ans);
}
| | | | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 |
allFileFlag = 1;
}else if( cReply!='y' && cReply!='Y' ){
blob_reset(&ans);
continue;
}
blob_reset(&ans);
}
if( dryRunFlag || file_delete(zName)==0 ){
if( verboseFlag || dryRunFlag ){
fossil_print("Removed unmanaged file: %s\n", zName+nRoot);
}
}else if( verboseFlag ){
fossil_print("Could not remove file: %s\n", zName+nRoot);
}
}
db_finalize(&q);
}
if( emptyDirsFlag ){
Glob *pEmptyDirs = glob_create(db_get("empty-dirs", 0));
Stmt q;
Blob root;
blob_init(&root, g.zLocalRoot, nRoot - 1);
vfile_dir_scan(&root, blob_size(&root), scanFlags, pIgnore,
pEmptyDirs);
blob_reset(&root);
db_prepare(&q,
"SELECT %Q || x FROM dscan_temp"
" WHERE x NOT IN (%s) AND y = 0"
" ORDER BY 1 DESC",
g.zLocalRoot, fossil_all_reserved_names(0)
);
|
| ︙ | ︙ | |||
800 801 802 803 804 805 806 |
allDirFlag = 1;
}else if( cReply!='y' && cReply!='Y' ){
blob_reset(&ans);
continue;
}
blob_reset(&ans);
}
| | | 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 |
allDirFlag = 1;
}else if( cReply!='y' && cReply!='Y' ){
blob_reset(&ans);
continue;
}
blob_reset(&ans);
}
if( dryRunFlag || file_rmdir(zName)==0 ){
if( verboseFlag || dryRunFlag ){
fossil_print("Removed unmanaged directory: %s\n", zName+nRoot);
}
}else if( verboseFlag ){
fossil_print("Could not remove directory: %s\n", zName+nRoot);
}
}
|
| ︙ | ︙ | |||
939 940 941 942 943 944 945 |
int parent_rid
){
Blob prompt;
#if defined(_WIN32) || defined(__CYGWIN__)
int bomSize;
const unsigned char *bom = get_utf8_bom(&bomSize);
blob_init(&prompt, (const char *) bom, bomSize);
| | | > | > | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 |
int parent_rid
){
Blob prompt;
#if defined(_WIN32) || defined(__CYGWIN__)
int bomSize;
const unsigned char *bom = get_utf8_bom(&bomSize);
blob_init(&prompt, (const char *) bom, bomSize);
if( zInit && zInit[0]){
blob_append(&prompt, zInit, -1);
}
#else
blob_init(&prompt, zInit, -1);
#endif
blob_append(&prompt,
"\n"
"# Enter a commit message for this check-in."
" Lines beginning with # are ignored.\n"
"#\n", -1
);
blob_appendf(&prompt, "# user: %s\n",
p->zUserOvrd ? p->zUserOvrd : login_name());
if( p->zBranch && p->zBranch[0] ){
blob_appendf(&prompt, "# tags: %s\n#\n", p->zBranch);
}else{
char *zTags = info_tags_of_checkin(parent_rid, 1);
if( zTags || p->azTag ){
blob_append(&prompt, "# tags: ", 8);
if(zTags){
|
| ︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 |
db_finalize(&q);
if( cnt==0 ){
fossil_warning("fossil knows nothing about: %s", g.argv[ii]);
result = 1;
}
blob_reset(&fname);
}
| | > | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 |
db_finalize(&q);
if( cnt==0 ){
fossil_warning("fossil knows nothing about: %s", g.argv[ii]);
result = 1;
}
blob_reset(&fname);
}
g.aCommitFile = fossil_malloc( (bag_count(&toCommit)+1) *
sizeof(g.aCommitFile[0]) );
for(ii=bag_first(&toCommit); ii>0; ii=bag_next(&toCommit, ii)){
g.aCommitFile[jj++] = ii;
}
g.aCommitFile[jj] = 0;
bag_clear(&toCommit);
}
return result;
|
| ︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 |
blob_appendf(pOut, "P %s", zParentUuid);
if( p->verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
free(zParentUuid);
db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0 OR id<-2");
while( db_step(&q)==SQLITE_ROW ){
char *zMergeUuid;
int mid = db_column_int(&q, 0);
| | > > | 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 |
blob_appendf(pOut, "P %s", zParentUuid);
if( p->verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
free(zParentUuid);
db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0 OR id<-2");
while( db_step(&q)==SQLITE_ROW ){
char *zMergeUuid;
int mid = db_column_int(&q, 0);
if( (!g.markPrivate && content_is_private(mid)) || (mid == vid) ){
continue;
}
zMergeUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
if( zMergeUuid ){
blob_appendf(pOut, " %s", zMergeUuid);
if( p->verifyDate ) checkin_verify_younger(mid, zMergeUuid, zDate);
free(zMergeUuid);
}
}
|
| ︙ | ︙ | |||
1378 1379 1380 1381 1382 1383 1384 | int bReverse; /* UTF-16 byte order is reversed? */ int fUnicode; /* return value of could_be_utf16() */ int fBinary; /* does the blob content appear to be binary? */ int lookFlags; /* output flags from looks_like_utf8/utf16() */ int fHasAnyCr; /* the blob contains one or more CR chars */ int fHasLoneCrOnly; /* all detected line endings are CR only */ int fHasCrLfOnly; /* all detected line endings are CR/LF pairs */ | | | 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 |
int bReverse; /* UTF-16 byte order is reversed? */
int fUnicode; /* return value of could_be_utf16() */
int fBinary; /* does the blob content appear to be binary? */
int lookFlags; /* output flags from looks_like_utf8/utf16() */
int fHasAnyCr; /* the blob contains one or more CR chars */
int fHasLoneCrOnly; /* all detected line endings are CR only */
int fHasCrLfOnly; /* all detected line endings are CR/LF pairs */
int fHasInvalidUtf8 = 0;/* contains invalid UTF-8 */
char *zMsg; /* Warning message */
Blob fname; /* Relative pathname of the file */
static int allOk = 0; /* Set to true to disable this routine */
if( allOk ) return 0;
fUnicode = could_be_utf16(p, &bReverse);
if( fUnicode ){
|
| ︙ | ︙ | |||
1457 1458 1459 1460 1461 1462 1463 |
return 0; /* We don't want encoding warnings for this file. */
}
zWarning = "Unicode";
zDisable = "\"encoding-glob\" setting";
}
file_relative_name(zFilename, &fname, 0);
zMsg = mprintf(
| | > | | 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 |
return 0; /* We don't want encoding warnings for this file. */
}
zWarning = "Unicode";
zDisable = "\"encoding-glob\" setting";
}
file_relative_name(zFilename, &fname, 0);
zMsg = mprintf(
"%s contains %s. Use --no-warnings or the %s to"
" disable this warning.\n"
"Commit anyhow (a=all/%sy/N)? ",
blob_str(&fname), zWarning, zDisable, zConvert);
prompt_user(zMsg, &ans);
fossil_free(zMsg);
cReply = blob_str(&ans)[0];
if( cReply=='a' || cReply=='A' ){
allOk = 1;
}else if( *zConvert && (cReply=='c' || cReply=='C') ){
char *zOrig = file_newname(zFilename, "original", 1);
FILE *f;
blob_write_to_file(p, zOrig);
fossil_free(zOrig);
f = fossil_fopen(zFilename, "wb");
if( f==0 ){
fossil_warning("cannot open %s for writing", zFilename);
}else{
if( fUnicode ){
int bomSize;
const unsigned char *bom = get_utf8_bom(&bomSize);
fwrite(bom, 1, bomSize, f);
blob_to_utf8_no_bom(p, 0);
}else if( fHasInvalidUtf8 ){
blob_cp1252_to_utf8(p);
}
|
| ︙ | ︙ | |||
1657 1658 1659 1660 1661 1662 1663 |
sCiInfo.zColor = find_option("bgcolor",0,1);
sCiInfo.zBrClr = find_option("branchcolor",0,1);
sCiInfo.closeFlag = find_option("close",0,0)!=0;
sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
sCiInfo.zMimetype = find_option("mimetype",0,1);
while( (zTag = find_option("tag",0,1))!=0 ){
if( zTag[0]==0 ) continue;
| | > | 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 |
sCiInfo.zColor = find_option("bgcolor",0,1);
sCiInfo.zBrClr = find_option("branchcolor",0,1);
sCiInfo.closeFlag = find_option("close",0,0)!=0;
sCiInfo.integrateFlag = find_option("integrate",0,0)!=0;
sCiInfo.zMimetype = find_option("mimetype",0,1);
while( (zTag = find_option("tag",0,1))!=0 ){
if( zTag[0]==0 ) continue;
sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag,
sizeof(char*)*(nTag+2));
sCiInfo.azTag[nTag++] = zTag;
sCiInfo.azTag[nTag] = 0;
}
zComFile = find_option("message-file", "M", 1);
if( find_option("private",0,0) ){
g.markPrivate = 1;
if( sCiInfo.zBranch==0 ) sCiInfo.zBranch = "private";
|
| ︙ | ︙ | |||
1838 1839 1840 1841 1842 1843 1844 |
|| db_exists("SELECT 1 FROM tagxref"
" WHERE tagid=%d AND rid=%d AND tagtype>0"
" AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
){
fossil_fatal("cannot commit against a closed leaf");
}
| < | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 |
|| db_exists("SELECT 1 FROM tagxref"
" WHERE tagid=%d AND rid=%d AND tagtype>0"
" AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
){
fossil_fatal("cannot commit against a closed leaf");
}
if( zComment ){
blob_zero(&comment);
blob_append(&comment, zComment, -1);
}else if( zComFile ){
blob_zero(&comment);
blob_read_from_file(&comment, zComFile);
blob_to_utf8_no_bom(&comment, 1);
|
| ︙ | ︙ | |||
1872 1873 1874 1875 1876 1877 1878 |
}
}else{
db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
db_end_transaction(0);
db_begin_transaction();
}
| > > > > > > > > | | | < | | | | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 |
}
}else{
db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
db_end_transaction(0);
db_begin_transaction();
}
/*
** Step 1: Compute an aggregate MD5 checksum over the disk image
** of every file in vid. The file names are part of the checksum.
** The resulting checksum is the same as is expected on the R-card
** of a manifest.
*/
if( useCksum ) vfile_aggregate_checksum_disk(vid, &cksum1);
/* Step 2: Insert records for all modified files into the blob
** table. If there were arguments passed to this command, only
** the identified files are inserted (if they have been modified).
*/
db_prepare(&q,
"SELECT id, %Q || pathname, mrid, %s, %s, %s FROM vfile "
"WHERE chnged==1 AND NOT deleted AND is_selected(id)",
g.zLocalRoot,
glob_expr("pathname", db_get("crnl-glob","")),
glob_expr("pathname", db_get("binary-glob","")),
glob_expr("pathname", db_get("encoding-glob",""))
);
while( db_step(&q)==SQLITE_ROW ){
int id, rid;
const char *zFullname;
Blob content;
int crnlOk, binOk, encodingOk;
id = db_column_int(&q, 0);
zFullname = db_column_text(&q, 1);
rid = db_column_int(&q, 2);
crnlOk = db_column_int(&q, 3);
binOk = db_column_int(&q, 4);
encodingOk = db_column_int(&q, 5);
blob_zero(&content);
if( file_wd_islink(zFullname) ){
/* Instead of file content, put link destination path */
blob_read_link(&content, zFullname);
}else{
blob_read_from_file(&content, zFullname);
}
/* Do not emit any warnings when they are disabled. */
if( !noWarningFlag ){
abortCommit |= commit_warning(&content, crnlOk, binOk,
encodingOk, zFullname);
}
if( contains_merge_marker(&content) ){
Blob fname; /* Relative pathname of the file */
nConflict++;
file_relative_name(zFullname, &fname, 0);
fossil_print("possible unresolved merge conflict in %s\n",
blob_str(&fname));
blob_reset(&fname);
|
| ︙ | ︙ |
Changes to src/clone.c.
| ︙ | ︙ | |||
204 205 206 207 208 209 210 |
db_begin_transaction();
fossil_print("Rebuilding repository meta-data...\n");
rebuild_db(0, 1, 0);
fossil_print("Extra delta compression... "); fflush(stdout);
extra_deltification();
db_end_transaction(0);
fossil_print("\nVacuuming the database... "); fflush(stdout);
| | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
db_begin_transaction();
fossil_print("Rebuilding repository meta-data...\n");
rebuild_db(0, 1, 0);
fossil_print("Extra delta compression... "); fflush(stdout);
extra_deltification();
db_end_transaction(0);
fossil_print("\nVacuuming the database... "); fflush(stdout);
if( db_int(0, "PRAGMA page_count")>1000
&& db_int(0, "PRAGMA page_size")<8192 ){
db_multi_exec("PRAGMA page_size=8192;");
}
db_multi_exec("VACUUM");
fossil_print("\nproject-id: %s\n", db_get("project-code", 0));
fossil_print("server-id: %s\n", db_get("server-code", 0));
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
|
| ︙ | ︙ |
Changes to src/comformat.c.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 | #include "config.h" #include "comformat.h" #include <assert.h> #ifdef _WIN32 # include <windows.h> #else # include <termios.h> | < | < | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include "config.h" #include "comformat.h" #include <assert.h> #ifdef _WIN32 # include <windows.h> #else # include <termios.h> # include <sys/ioctl.h> #endif #if INTERFACE #define COMMENT_PRINT_NONE ((u32)0x00000000) /* No flags. */ #define COMMENT_PRINT_LEGACY ((u32)0x00000001) /* Use legacy algorithm. */ #define COMMENT_PRINT_TRIM_CRLF ((u32)0x00000002) /* Trim leading CR/LF. */ #define COMMENT_PRINT_TRIM_SPACE ((u32)0x00000004) /* Trim leading/trailing. */ |
| ︙ | ︙ |
Changes to src/configure.c.
| ︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
static struct {
const char *zName; /* Name of the configuration parameter */
int groupMask; /* Which config groups is it part of */
} aConfig[] = {
{ "css", CONFIGSET_CSS },
{ "header", CONFIGSET_SKIN },
{ "footer", CONFIGSET_SKIN },
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "timeline-plaintext", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
| > < | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
static struct {
const char *zName; /* Name of the configuration parameter */
int groupMask; /* Which config groups is it part of */
} aConfig[] = {
{ "css", CONFIGSET_CSS },
{ "header", CONFIGSET_SKIN },
{ "footer", CONFIGSET_SKIN },
{ "details", CONFIGSET_SKIN },
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "timeline-plaintext", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
#ifdef FOSSIL_ENABLE_TH1_DOCS
{ "th1-docs", CONFIGSET_TH1 },
#endif
#ifdef FOSSIL_ENABLE_TH1_HOOKS
{ "th1-hooks", CONFIGSET_TH1 },
#endif
|
| ︙ | ︙ | |||
124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
{ "ignore-glob", CONFIGSET_PROJ },
{ "keep-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
{ "dotfiles", CONFIGSET_PROJ },
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
{ "ticket-change", CONFIGSET_TKT },
{ "ticket-newpage", CONFIGSET_TKT },
{ "ticket-viewpage", CONFIGSET_TKT },
{ "ticket-editpage", CONFIGSET_TKT },
| > > > > | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
{ "ignore-glob", CONFIGSET_PROJ },
{ "keep-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
{ "dotfiles", CONFIGSET_PROJ },
#ifdef FOSSIL_ENABLE_LEGACY_MV_RM
{ "mv-rm-files", CONFIGSET_PROJ },
#endif
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
{ "ticket-change", CONFIGSET_TKT },
{ "ticket-newpage", CONFIGSET_TKT },
{ "ticket-viewpage", CONFIGSET_TKT },
{ "ticket-editpage", CONFIGSET_TKT },
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
1644 1645 1646 1647 1648 1649 1650 |
zDefaultUser = find_option("admin-user","A",1);
/* We should be done with options.. */
verify_all_options();
if( g.argc!=3 ){
usage("REPOSITORY-NAME");
}
| | | 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 |
zDefaultUser = find_option("admin-user","A",1);
/* We should be done with options.. */
verify_all_options();
if( g.argc!=3 ){
usage("REPOSITORY-NAME");
}
if( -1 != file_size(g.argv[2]) ){
fossil_fatal("file already exists: %s", g.argv[2]);
}
db_create_repository(g.argv[2]);
db_open_repository(g.argv[2]);
db_open_config(0);
|
| ︙ | ︙ | |||
1885 1886 1887 1888 1889 1890 1891 | /* ** Try to read a versioned setting string from .fossil-settings/<name>. ** ** Return the text of the string if it is found. Return NULL if not ** found. ** ** If the zNonVersionedSetting parameter is not NULL then it holds the | | > | | < > | | > > > > > | > > > > > > > | > > > > > < < | < < | < > > > > > > | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 |
/*
** Try to read a versioned setting string from .fossil-settings/<name>.
**
** Return the text of the string if it is found. Return NULL if not
** found.
**
** If the zNonVersionedSetting parameter is not NULL then it holds the
** non-versioned value for this setting. If both a versioned and a
** non-versioned value exist and are not equal, then a warning message
** might be generated.
*/
char *db_get_versioned(const char *zName, char *zNonVersionedSetting){
char *zVersionedSetting = 0;
int noWarn = 0;
int found = 0;
struct _cacheEntry {
struct _cacheEntry *next;
const char *zName, *zValue;
} *cacheEntry = 0;
static struct _cacheEntry *cache = 0;
if( !g.localOpen && g.zOpenRevision==0 ) return zNonVersionedSetting;
/* Look up name in cache */
cacheEntry = cache;
while( cacheEntry!=0 ){
if( fossil_strcmp(cacheEntry->zName, zName)==0 ){
zVersionedSetting = fossil_strdup(cacheEntry->zValue);
break;
}
cacheEntry = cacheEntry->next;
}
/* Attempt to read value from file in checkout if there wasn't a cache hit. */
if( cacheEntry==0 ){
Blob versionedPathname;
Blob setting;
blob_zero(&versionedPathname);
blob_zero(&setting);
blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
g.zLocalRoot, zName);
if( !g.localOpen ){
/* Repository is in the process of being opened, but files have not been
* written to disk. Load from the database. */
Blob noWarnFile;
if( historical_version_of_file(g.zOpenRevision,
blob_str(&versionedPathname),
&setting, 0, 0, 0, 2)!=2 ){
found = 1;
}
/* See if there's a no-warn flag */
blob_append(&versionedPathname, ".no-warn", -1);
blob_zero(&noWarnFile);
if( historical_version_of_file(g.zOpenRevision,
blob_str(&versionedPathname),
&noWarnFile, 0, 0, 0, 2)!=2 ){
noWarn = 1;
}
blob_reset(&noWarnFile);
}else if( file_size(blob_str(&versionedPathname))>=0 ){
/* File exists, and contains the value for this setting. Load from
** the file. */
if( blob_read_from_file(&setting, blob_str(&versionedPathname))>=0 ){
found = 1;
}
/* See if there's a no-warn flag */
blob_append(&versionedPathname, ".no-warn", -1);
if( file_size(blob_str(&versionedPathname))>=0 ){
noWarn = 1;
}
}
blob_reset(&versionedPathname);
if( found ){
blob_trim(&setting); /* Avoid non-obvious problems with line endings
** on boolean properties */
zVersionedSetting = fossil_strdup(blob_str(&setting));
}
blob_reset(&setting);
/* Store result in cache, which can be the value or 0 if not found */
cacheEntry = (struct _cacheEntry*)fossil_malloc(sizeof(struct _cacheEntry));
cacheEntry->next = cache;
cacheEntry->zName = zName;
cacheEntry->zValue = fossil_strdup(zVersionedSetting);
cache = cacheEntry;
}
|
| ︙ | ︙ | |||
2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 |
if( g.argc!=3 && g.argc!=4 ){
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local(0) ){
fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
}
db_open_repository(g.argv[2]);
#if defined(_WIN32) || defined(__CYGWIN__)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
db_init_database(LOCALDB_NAME, zLocalSchema,
#ifdef FOSSIL_LOCAL_WAL
| > > > > > > > > > > > > > > > > | 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 |
if( g.argc!=3 && g.argc!=4 ){
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local(0) ){
fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
}
db_open_repository(g.argv[2]);
/* Figure out which revision to open. */
if( !emptyFlag ){
if( g.argc==4 ){
g.zOpenRevision = g.argv[3];
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
g.zOpenRevision = db_get("main-branch", "trunk");
}
}
if( g.zOpenRevision ){
/* Since the repository is open and we know the revision now,
** refresh the allow-symlinks flag. */
g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
}
#if defined(_WIN32) || defined(__CYGWIN__)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
db_init_database(LOCALDB_NAME, zLocalSchema,
#ifdef FOSSIL_LOCAL_WAL
|
| ︙ | ︙ | |||
2237 2238 2239 2240 2241 2242 2243 |
db_lset_int("checkout", 0);
oldArgv = g.argv;
oldArgc = g.argc;
azNewArgv[0] = g.argv[0];
g.argv = azNewArgv;
if( !emptyFlag ){
g.argc = 3;
| | | < < | | 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 |
db_lset_int("checkout", 0);
oldArgv = g.argv;
oldArgc = g.argc;
azNewArgv[0] = g.argv[0];
g.argv = azNewArgv;
if( !emptyFlag ){
g.argc = 3;
if( g.zOpenRevision ){
azNewArgv[g.argc-1] = g.zOpenRevision;
}else{
azNewArgv[g.argc-1] = "--latest";
}
if( keepFlag ){
azNewArgv[g.argc++] = "--keep";
}
if( forceMissingFlag ){
azNewArgv[g.argc++] = "--force-missing";
}
|
| ︙ | ︙ | |||
2285 2286 2287 2288 2289 2290 2291 |
}else{
fossil_print("%-20s\n", pSetting->name);
}
if( pSetting->versionable && g.localOpen ){
/* Check to see if this is overridden by a versionable settings file */
Blob versionedPathname;
blob_zero(&versionedPathname);
| | | 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 |
}else{
fossil_print("%-20s\n", pSetting->name);
}
if( pSetting->versionable && g.localOpen ){
/* Check to see if this is overridden by a versionable settings file */
Blob versionedPathname;
blob_zero(&versionedPathname);
blob_appendf(&versionedPathname, "%s.fossil-settings/%s",
g.zLocalRoot, pSetting->name);
if( file_size(blob_str(&versionedPathname))>=0 ){
fossil_print(" (overridden by contents of file .fossil-settings/%s)\n",
pSetting->name);
}
}
db_finalize(&q);
|
| ︙ | ︙ | |||
2343 2344 2345 2346 2347 2348 2349 |
{ "clean-glob", 0, 40, 1, 0, "" },
{ "clearsign", 0, 0, 0, 0, "off" },
{ "crnl-glob", 0, 40, 1, 0, "" },
{ "default-perms", 0, 16, 0, 0, "u" },
{ "diff-binary", 0, 0, 0, 0, "on" },
{ "diff-command", 0, 40, 0, 0, "" },
{ "dont-push", 0, 0, 0, 0, "off" },
| | > > > | 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 |
{ "clean-glob", 0, 40, 1, 0, "" },
{ "clearsign", 0, 0, 0, 0, "off" },
{ "crnl-glob", 0, 40, 1, 0, "" },
{ "default-perms", 0, 16, 0, 0, "u" },
{ "diff-binary", 0, 0, 0, 0, "on" },
{ "diff-command", 0, 40, 0, 0, "" },
{ "dont-push", 0, 0, 0, 0, "off" },
{ "dotfiles", 0, 0, 1, 0, "off" },
{ "editor", 0, 32, 0, 0, "" },
{ "empty-dirs", 0, 40, 1, 0, "" },
{ "encoding-glob", 0, 40, 1, 0, "" },
{ "gdiff-command", 0, 40, 0, 0, "gdiff" },
{ "gmerge-command", 0, 40, 0, 0, "" },
{ "hash-digits", 0, 5, 0, 0, "10" },
{ "http-port", 0, 16, 0, 0, "8080" },
{ "https-login", 0, 0, 0, 0, "off" },
{ "ignore-glob", 0, 40, 1, 0, "" },
{ "keep-glob", 0, 40, 1, 0, "" },
{ "localauth", 0, 0, 0, 0, "off" },
{ "main-branch", 0, 40, 0, 0, "trunk" },
{ "manifest", 0, 0, 1, 0, "off" },
{ "max-loadavg", 0, 25, 0, 0, "0.0" },
{ "max-upload", 0, 25, 0, 0, "250000" },
{ "mtime-changes", 0, 0, 0, 0, "on" },
#if FOSSIL_ENABLE_LEGACY_MV_RM
{ "mv-rm-files", 0, 0, 0, 0, "off" },
#endif
{ "pgp-command", 0, 40, 0, 0, "gpg --clearsign -o " },
{ "proxy", 0, 32, 0, 0, "off" },
{ "relative-paths", 0, 0, 0, 0, "on" },
{ "repo-cksum", 0, 0, 0, 0, "on" },
{ "self-register", 0, 0, 0, 0, "off" },
{ "ssh-command", 0, 40, 0, 0, "" },
{ "ssl-ca-location", 0, 40, 0, 0, "" },
|
| ︙ | ︙ | |||
2381 2382 2383 2384 2385 2386 2387 |
#endif
#ifdef FOSSIL_ENABLE_TH1_HOOKS
{ "th1-hooks", 0, 0, 0, 0, "off" },
#endif
{ "th1-setup", 0, 40, 1, 1, "" },
{ "th1-uri-regexp", 0, 40, 1, 0, "" },
{ "web-browser", 0, 32, 0, 0, "" },
| < | 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 |
#endif
#ifdef FOSSIL_ENABLE_TH1_HOOKS
{ "th1-hooks", 0, 0, 0, 0, "off" },
#endif
{ "th1-setup", 0, 40, 1, 1, "" },
{ "th1-uri-regexp", 0, 40, 1, 0, "" },
{ "web-browser", 0, 32, 0, 0, "" },
{ 0,0,0,0,0,0 }
};
/*
** Look up a control setting by its name. Return a pointer to the Setting
** object, or NULL if there is no such setting.
**
|
| ︙ | ︙ | |||
2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 | ** diff-command External command to run when performing a diff. ** If undefined, the internal text diff will be used. ** ** dont-push Prevent this repository from pushing from client to ** server. Useful when setting up a private branch. ** ** dotfiles Include --dotfiles option for all compatible commands. ** ** editor Text editor command used for check-in comments. ** ** empty-dirs A comma or newline-separated list of pathnames. On ** (versionable) update and checkout commands, if no file or directory ** exists with that name, an empty directory will be ** created. | > | 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 | ** diff-command External command to run when performing a diff. ** If undefined, the internal text diff will be used. ** ** dont-push Prevent this repository from pushing from client to ** server. Useful when setting up a private branch. ** ** dotfiles Include --dotfiles option for all compatible commands. ** (versionable) ** ** editor Text editor command used for check-in comments. ** ** empty-dirs A comma or newline-separated list of pathnames. On ** (versionable) update and checkout commands, if no file or directory ** exists with that name, an empty directory will be ** created. |
| ︙ | ︙ | |||
2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 | ** global configuration database. ** ** max-upload A limit on the size of uplink HTTP requests. The ** default is 250000 bytes. ** ** mtime-changes Use file modification times (mtimes) to detect when ** files have been modified. (Default "on".) ** ** pgp-command Command used to clear-sign manifests at check-in. ** The default is "gpg --clearsign -o ". ** ** proxy URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined | > > > > > > | 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 | ** global configuration database. ** ** max-upload A limit on the size of uplink HTTP requests. The ** default is 250000 bytes. ** ** mtime-changes Use file modification times (mtimes) to detect when ** files have been modified. (Default "on".) ** ** mv-rm-files If enabled (and Fossil was compiled with legacy "mv/rm" ** support), the "mv" and "rename" commands will also move ** the associated files within the checkout -AND- the "rm" ** and "delete" commands will also remove the associated ** files from within the checkout. Default: off. ** ** pgp-command Command used to clear-sign manifests at check-in. ** The default is "gpg --clearsign -o ". ** ** proxy URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined |
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
350 351 352 353 354 355 356 357 | ** The -c|--closed flag shows only closed leaves. ** ** The --recompute flag causes the content of the "leaf" table in the ** repository database to be recomputed. ** ** Options: ** -a|--all show ALL leaves ** -c|--closed show only closed leaves | > | > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
** The -c|--closed flag shows only closed leaves.
**
** The --recompute flag causes the content of the "leaf" table in the
** repository database to be recomputed.
**
** Options:
** -a|--all show ALL leaves
** --bybranch order output by branch name
** -c|--closed show only closed leaves
** -m|--multiple show only cases with multiple leaves on a single branch
** --recompute recompute the "leaf" table in the repository DB
** -W|--width <num> Width of lines (default is to auto-detect). Must be
** >39 or 0 (= no limit, resulting in a single line per
** entry).
**
** See also: descendants, finfo, info, branch
*/
void leaves_cmd(void){
Stmt q;
Blob sql;
int showAll = find_option("all", "a", 0)!=0;
int showClosed = find_option("closed", "c", 0)!=0;
int recomputeFlag = find_option("recompute",0,0)!=0;
int byBranch = find_option("bybranch",0,0)!=0;
int multipleFlag = find_option("multiple","m",0)!=0;
const char *zWidth = find_option("width","W",1);
char *zLastBr = 0;
int n, width;
char zLineNo[10];
if( multipleFlag ) byBranch = 1;
if( zWidth ){
width = atoi(zWidth);
if( (width!=0) && (width<=39) ){
fossil_fatal("-W|--width value must be >39 or 0");
}
}else{
width = -1;
}
db_find_and_open_repository(0,0);
/* We should be done with options.. */
verify_all_options();
if( recomputeFlag ) leaf_rebuild();
blob_zero(&sql);
blob_append(&sql, timeline_query_for_tty(), -1);
if( !multipleFlag ){
/* The usual case - show all leaves */
blob_append_sql(&sql, " AND blob.rid IN leaf");
}else{
/* Show only leaves where two are more occur in the same branch */
db_multi_exec(
"CREATE TEMP TABLE openLeaf(rid INTEGER PRIMARY KEY);"
"INSERT INTO openLeaf(rid)"
" SELECT rid FROM leaf"
" WHERE NOT EXISTS("
" SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND rid=leaf.rid);",
TAG_CLOSED
);
db_multi_exec(
"CREATE TEMP TABLE ambiguousBranch(brname TEXT);"
"INSERT INTO ambiguousBranch(brname)"
" SELECT (SELECT value FROM tagxref WHERE tagid=%d AND rid=openLeaf.rid)"
" FROM openLeaf"
" GROUP BY 1 HAVING count(*)>1;",
TAG_BRANCH
);
db_multi_exec(
"CREATE TEMP TABLE ambiguousLeaf(rid INTEGER PRIMARY KEY);\n"
"INSERT INTO ambiguousLeaf(rid)\n"
" SELECT rid FROM openLeaf\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=openLeaf.rid)"
" IN (SELECT brname FROM ambiguousBranch);",
TAG_BRANCH
);
blob_append_sql(&sql, " AND blob.rid IN ambiguousLeaf");
}
if( showClosed ){
blob_append_sql(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
}else if( !showAll ){
blob_append_sql(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
}
if( byBranch ){
db_prepare(&q, "%s ORDER BY nullif(branch,'trunk') COLLATE nocase,"
|
| ︙ | ︙ | |||
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
const char *zBr = db_column_text(&q, 7);
char *z;
if( byBranch && fossil_strcmp(zBr, zLastBr)!=0 ){
fossil_print("*** %s ***\n", zBr);
fossil_free(zLastBr);
zLastBr = fossil_strdup(zBr);
}
n++;
sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n);
fossil_print("%6s ", zLineNo);
z = mprintf("%s [%S] %s", zDate, zId, zCom);
comment_print(z, zCom, 7, width, g.comFmtFlags);
fossil_free(z);
}
fossil_free(zLastBr);
db_finalize(&q);
}
/*
** WEBPAGE: leaves
**
| > > > > > > > > > > | > | 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
const char *zBr = db_column_text(&q, 7);
char *z;
if( byBranch && fossil_strcmp(zBr, zLastBr)!=0 ){
fossil_print("*** %s ***\n", zBr);
fossil_free(zLastBr);
zLastBr = fossil_strdup(zBr);
if( multipleFlag ) n = 0;
}
n++;
sqlite3_snprintf(sizeof(zLineNo), zLineNo, "(%d)", n);
fossil_print("%6s ", zLineNo);
z = mprintf("%s [%S] %s", zDate, zId, zCom);
comment_print(z, zCom, 7, width, g.comFmtFlags);
fossil_free(z);
}
fossil_free(zLastBr);
db_finalize(&q);
}
/*
** WEBPAGE: leaves
**
** Show leaf check-ins in a timeline. By default only open leaves
** are listed.
**
** A "leaf" is a check-in with no children in the same branch. A
** "closed leaf" is a leaf that has a "closed" tag. An "open leaf"
** is a leaf without a "closed" tag.
**
** Query parameters:
**
** all Show all leaves
** closed Show only closed leaves
*/
void leaves_page(void){
Blob sql;
Stmt q;
int showAll = P("all")!=0;
int showClosed = P("closed")!=0;
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 |
if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
return diffFlags;
}
/*
** COMMAND: test-rawdiff
*/
void test_rawdiff_cmd(void){
Blob a, b;
int r;
int i;
int *R;
u64 diffFlags = diff_options();
| > > > > > > | 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 |
if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
return diffFlags;
}
/*
** COMMAND: test-rawdiff
**
** Usage: %fossil test-rawdiff FILE1 FILE2
**
** Show a minimal sequence of Copy/Delete/Insert operations needed to convert
** FILE1 into FILE2. This command is intended for use in testing and debugging
** the built-in difference engine of Fossil.
*/
void test_rawdiff_cmd(void){
Blob a, b;
int r;
int i;
int *R;
u64 diffFlags = diff_options();
|
| ︙ | ︙ | |||
2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 | } /* ** WEBPAGE: annotate ** WEBPAGE: blame ** WEBPAGE: praise ** ** Query parameters: ** ** checkin=ID The manifest ID at which to start the annotation ** filename=FILENAME The filename. ** filevers Show file versions rather than check-in versions ** log=BOOLEAN Show a log of versions analyzed | > > > > > > > > > | > | 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 |
}
/*
** WEBPAGE: annotate
** WEBPAGE: blame
** WEBPAGE: praise
**
** URL: /annotate?checkin=ID&filename=FILENAME
** URL: /blame?checkin=ID&filename=FILENAME
** URL: /praise?checkin=ID&filename=FILENAME
**
** Show the most recent change to each line of a text file. /annotate shows
** the date of the changes and the check-in SHA1 hash (with a link to the
** check-in). /blame and /praise also show the user who made the check-in.
**
** Query parameters:
**
** checkin=ID The manifest ID at which to start the annotation
** filename=FILENAME The filename.
** filevers Show file versions rather than check-in versions
** limit=N Limit the search depth to N ancestors
** log=BOOLEAN Show a log of versions analyzed
** w Ignore whitespace
**
*/
void annotation_page(void){
int mid;
int fnid;
int i;
int iLimit; /* Depth limit */
u64 annFlags = (ANN_FILE_ANCEST|DIFF_STRIP_EOLCR);
|
| ︙ | ︙ | |||
2292 2293 2294 2295 2296 2297 2298 |
z2 = sqlite3_mprintf("%d", iLimit+20);
style_submenu_element(z1, z1, "%s", url_render(&url, "limit", z2, 0, 0));
}
if( iLimit>20 ){
style_submenu_element("20 Ancestors", "20 Ancestors",
"%s", url_render(&url, "limit", "20", 0, 0));
}
| | | 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 |
z2 = sqlite3_mprintf("%d", iLimit+20);
style_submenu_element(z1, z1, "%s", url_render(&url, "limit", z2, 0, 0));
}
if( iLimit>20 ){
style_submenu_element("20 Ancestors", "20 Ancestors",
"%s", url_render(&url, "limit", "20", 0, 0));
}
if( skin_detail_boolean("white-foreground") ){
clr1 = 0xa04040;
clr2 = 0x4059a0;
}else{
clr1 = 0xffb5b5; /* Recent changes: red (hot) */
clr2 = 0xb5e0ff; /* Older changes: blue (cold) */
}
for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
833 834 835 836 837 838 839 |
diffFlags);
}
}
}
/*
** WEBPAGE: vpatch
| | > > | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 |
diffFlags);
}
}
}
/*
** WEBPAGE: vpatch
** URL: /vpatch?from=FROM&to=TO
**
** Show a patch that goes from check-in FROM to check-in TO.
*/
void vpatch_page(void){
const char *zFrom = P("from");
const char *zTo = P("to");
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
|
| ︙ | ︙ |
Changes to src/doc.c.
| ︙ | ︙ | |||
772 773 774 775 776 777 778 | 179, 62, 5, 0, 59, }; /* ** WEBPAGE: background ** | | > | | > > > > > > | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 |
179, 62, 5, 0, 59,
};
/*
** WEBPAGE: background
**
** Return the background image. If no background image is defined, a
** built-in 16x16 pixel white GIF is returned.
*/
void background_page(void){
Blob bgimg;
char *zMime;
zMime = db_get("background-mimetype", "image/gif");
blob_zero(&bgimg);
db_blob(&bgimg, "SELECT value FROM config WHERE name='background-image'");
if( blob_size(&bgimg)==0 ){
blob_init(&bgimg, (char*)aBackground, sizeof(aBackground));
}
cgi_set_content_type(zMime);
cgi_set_content(&bgimg);
g.isConst = 1;
}
/*
** WEBPAGE: docsrch
**
** Search for documents that match a user-supplied full-text search pattern.
** If no pattern is specified (by the s= query parameter) then the user
** is prompted to enter a search string.
**
** Query parameters:
**
** s=PATTERN Search for PATTERN
*/
void doc_search_page(void){
login_check_credentials();
style_header("Document Search");
search_screen(SRCH_DOC, 0);
style_footer();
}
|
Changes to src/encode.c.
| ︙ | ︙ | |||
604 605 606 607 608 609 610 611 612 613 614 615 616 617 |
}
/*
** Command to test obscure() and unobscure(). These commands are also useful
** utilities for decoding passwords found in the database.
**
** COMMAND: test-obscure
*/
void test_obscure_cmd(void){
int i;
char *z, *z2;
for(i=2; i<g.argc; i++){
z = obscure(g.argv[i]);
z2 = unobscure(z);
| > > > > | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
}
/*
** Command to test obscure() and unobscure(). These commands are also useful
** utilities for decoding passwords found in the database.
**
** COMMAND: test-obscure
**
** For each command-line argument X, run both obscure(X) and
** unobscure(obscure(X)) and print the results. This is used for testing
** and debugging of the obscure() and unobscure() functions.
*/
void test_obscure_cmd(void){
int i;
char *z, *z2;
for(i=2; i<g.argc; i++){
z = obscure(g.argv[i]);
z2 = unobscure(z);
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
180 181 182 183 184 185 186 |
rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
&fname, filename_collation());
if( rid==0 ){
fossil_fatal("no history for file: %b", &fname);
}
zFilename = blob_str(&fname);
db_prepare(&q,
| | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
&fname, filename_collation());
if( rid==0 ){
fossil_fatal("no history for file: %b", &fname);
}
zFilename = blob_str(&fname);
db_prepare(&q,
"SELECT DISTINCT b.uuid, ci.uuid, date(event.mtime%s),"
" coalesce(event.ecomment, event.comment),"
" coalesce(event.euser, event.user),"
" (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0"
" AND tagxref.rid=mlink.mid)" /* Tags */
" FROM mlink, blob b, event, blob ci, filename"
" WHERE filename.name=%Q %s"
" AND mlink.fnid=filename.fnid"
|
| ︙ | ︙ | |||
259 260 261 262 263 264 265 |
/* We should be done with options.. */
verify_all_options();
for(i=2; i<g.argc; i++){
file_tree_name(g.argv[i], &fname, 1);
blob_zero(&content);
| | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
/* We should be done with options.. */
verify_all_options();
for(i=2; i<g.argc; i++){
file_tree_name(g.argv[i], &fname, 1);
blob_zero(&content);
rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
if( rc==2 ){
fossil_fatal("no such file: %s", g.argv[i]);
}
blob_write_to_file(&content, "-");
blob_reset(&fname);
blob_reset(&content);
}
}
|
| ︙ | ︙ | |||
286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
**
** a=DATE Only show changes after DATE
** b=DATE Only show changes before DATE
** n=NUM Show the first NUM changes only
** brbg Background color by branch name
** ubg Background color by user name
** ci=UUID Ancestors of a particular check-in
*/
void finfo_page(void){
Stmt q;
const char *zFilename;
char zPrevDate[20];
const char *zA;
const char *zB;
| > | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
**
** a=DATE Only show changes after DATE
** b=DATE Only show changes before DATE
** n=NUM Show the first NUM changes only
** brbg Background color by branch name
** ubg Background color by user name
** ci=UUID Ancestors of a particular check-in
** showid Show RID values for debugging
*/
void finfo_page(void){
Stmt q;
const char *zFilename;
char zPrevDate[20];
const char *zA;
const char *zB;
|
| ︙ | ︙ | |||
400 401 402 403 404 405 406 |
blob_appendf(&title, "History of files named ");
hyperlinked_path(zFilename, &title, 0, "tree", "");
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
}
@ <h2>%b(&title)</h2>
blob_reset(&title);
pGraph = graph_init();
| < < | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
blob_appendf(&title, "History of files named ");
hyperlinked_path(zFilename, &title, 0, "tree", "");
if( fShowId ) blob_appendf(&title, " (%d)", fnid);
}
@ <h2>%b(&title)</h2>
blob_reset(&title);
pGraph = graph_init();
@ <table id="timelineTable" class="timelineTable">
while( db_step(&q)==SQLITE_ROW ){
const char *zDate = db_column_text(&q, 0);
const char *zCom = db_column_text(&q, 1);
const char *zUser = db_column_text(&q, 2);
int fpid = db_column_int(&q, 3);
int frid = db_column_int(&q, 4);
|
| ︙ | ︙ | |||
456 457 458 459 460 461 462 |
@ <div class="divider timelineDate">%s(zPrevDate)</div>
@ </td><td></td><td></td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
@ <tr><td class="timelineTime">
@ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td>
| | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
@ <div class="divider timelineDate">%s(zPrevDate)</div>
@ </td><td></td><td></td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
@ <tr><td class="timelineTime">
@ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td>
@ <td class="timelineGraph"><div id="m%d(gidx)" class="tl-nodemark"></div></td>
if( zBgClr && zBgClr[0] ){
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
}else{
@ <td class="timelineTableCell">
}
if( zUuid ){
if( nParent==0 ){
|
| ︙ | ︙ | |||
506 507 508 509 510 511 512 |
if( g.perm.Hyperlink && zUuid ){
const char *z = zFilename;
@ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
@ [annotate]</a>
@ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
@ [blame]</a>
@ %z(href("%R/timeline?n=200&uf=%!S",zUuid))[check-ins using]</a>
| | | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 |
if( g.perm.Hyperlink && zUuid ){
const char *z = zFilename;
@ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
@ [annotate]</a>
@ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin))
@ [blame]</a>
@ %z(href("%R/timeline?n=200&uf=%!S",zUuid))[check-ins using]</a>
if( fpid>0 ){
@ %z(href("%R/fdiff?sbs=1&v1=%!S&v2=%!S",zPUuid,zUuid))[diff]</a>
}
}
if( fDebug & FINFO_DEBUG_MLINK ){
int ii;
char *zAncLink;
@ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid)
|
| ︙ | ︙ | |||
533 534 535 536 537 538 539 |
db_finalize(&q);
if( pGraph ){
graph_finish(pGraph, 1);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
| < < < | | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
db_finalize(&q);
if( pGraph ){
graph_finish(pGraph, 1);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
@ <tr class="timelineBottom"><td></td><td></td><td></td></tr>
}
}
@ </table>
timeline_output_graph_javascript(pGraph, 0, 1);
style_footer();
}
|
Changes to src/graph.c.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | int idxTop; /* Direct descendent highest up on the graph */ GraphRow *pChild; /* Child immediately above this node */ u8 isDup; /* True if this is duplicate of a prior entry */ u8 isLeaf; /* True if this is a leaf node */ u8 timeWarp; /* Child is earlier in time */ u8 bDescender; /* True if riser from bottom of graph to here. */ i8 iRail; /* Which rail this check-in appears on. 0-based.*/ | | < | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
int idxTop; /* Direct descendent highest up on the graph */
GraphRow *pChild; /* Child immediately above this node */
u8 isDup; /* True if this is duplicate of a prior entry */
u8 isLeaf; /* True if this is a leaf node */
u8 timeWarp; /* Child is earlier in time */
u8 bDescender; /* True if riser from bottom of graph to here. */
i8 iRail; /* Which rail this check-in appears on. 0-based.*/
i8 mergeOut; /* Merge out to this rail. -1 if no merge-out */
u8 mergeIn[GR_MAX_RAIL]; /* Merge in from non-zero rails */
int aiRiser[GR_MAX_RAIL]; /* Risers from this node to a higher row. */
int mergeUpto; /* Draw the mergeOut rail up to this level */
u64 mergeDown; /* Draw merge lines up from bottom of graph */
u64 railInUse; /* Mask of occupied rails at this row */
};
/* Context while building a graph
*/
struct GraphContext {
int nErr; /* Number of errors encountered */
int mxRail; /* Number of rails required to render the graph */
GraphRow *pFirst; /* First row in the list */
GraphRow *pLast; /* Last row in the list */
int nBranch; /* Number of distinct branches */
char **azBranch; /* Names of the branches */
int nRow; /* Number of rows */
int nHash; /* Number of slots in apHash[] */
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
|
| ︙ | ︙ | |||
292 293 294 295 296 297 298 |
if( pParent->mergeOut<0 ){
u = pParent->aiRiser[pParent->iRail];
if( u>=0 && u<pChild->idx ){
/* The thick arrow up to the next primary child of pDesc goes
** further up than the thin merge arrow riser, so draw them both
** on the same rail. */
| | < | | | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
if( pParent->mergeOut<0 ){
u = pParent->aiRiser[pParent->iRail];
if( u>=0 && u<pChild->idx ){
/* The thick arrow up to the next primary child of pDesc goes
** further up than the thin merge arrow riser, so draw them both
** on the same rail. */
pParent->mergeOut = pParent->iRail;
pParent->mergeUpto = pChild->idx;
}else{
/* The thin merge arrow riser is taller than the thick primary
** child riser, so use separate rails. */
int iTarget = pParent->iRail;
pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
0, iTarget);
pParent->mergeUpto = pChild->idx;
mask = BIT(pParent->mergeOut);
for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
pLoop=pLoop->pNext){
pLoop->railInUse |= mask;
}
}
}
pChild->mergeIn[pParent->mergeOut] = 1;
}
/*
** Compute the maximum rail number.
*/
static void find_max_rail(GraphContext *p){
GraphRow *pRow;
p->mxRail = 0;
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( pRow->iRail>p->mxRail ) p->mxRail = pRow->iRail;
if( pRow->mergeOut>p->mxRail ) p->mxRail = pRow->mergeOut;
while( p->mxRail<GR_MAX_RAIL && pRow->mergeDown>(BIT(p->mxRail+1)-1) ){
p->mxRail++;
}
}
}
|
| ︙ | ︙ | |||
538 539 540 541 542 543 544 |
int parentRid = pRow->aParent[i];
pDesc = hashFind(p, parentRid);
if( pDesc==0 ){
/* Merge from a node that is off-screen */
int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0, 0);
if( p->mxRail>=GR_MAX_RAIL ) return;
mask = BIT(iMrail);
| | | 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
int parentRid = pRow->aParent[i];
pDesc = hashFind(p, parentRid);
if( pDesc==0 ){
/* Merge from a node that is off-screen */
int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0, 0);
if( p->mxRail>=GR_MAX_RAIL ) return;
mask = BIT(iMrail);
pRow->mergeIn[iMrail] = 1;
pRow->mergeDown |= mask;
for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
pLoop->railInUse |= mask;
}
}else{
/* Merge from an on-screen node */
createMergeRiser(p, pDesc, pRow);
|
| ︙ | ︙ | |||
567 568 569 570 571 572 573 |
if( p->mxRail>=GR_MAX_RAIL ) return;
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( !pRow->isDup ) continue;
pRow->iRail = dupRail;
pDesc = hashFind(p, pRow->rid);
assert( pDesc!=0 && pDesc!=pRow );
createMergeRiser(p, pDesc, pRow);
| | < < < < < | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
if( p->mxRail>=GR_MAX_RAIL ) return;
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( !pRow->isDup ) continue;
pRow->iRail = dupRail;
pDesc = hashFind(p, pRow->rid);
assert( pDesc!=0 && pDesc!=pRow );
createMergeRiser(p, pDesc, pRow);
if( pDesc->mergeOut>mxRail ) mxRail = pDesc->mergeOut;
}
if( dupRail<=mxRail ){
dupRail = mxRail+1;
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( pRow->isDup ) pRow->iRail = dupRail;
}
}
if( mxRail>=GR_MAX_RAIL ) return;
}
/*
** Find the maximum rail number.
*/
find_max_rail(p);
p->nErr = 0;
}
|
Changes to src/http.c.
| ︙ | ︙ | |||
336 337 338 339 340 341 342 |
goto write_err;
}
j = strlen(zLine) - 1;
while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
j -= 4;
zLine[j] = 0;
}
| < < > > | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
goto write_err;
}
j = strlen(zLine) - 1;
while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
j -= 4;
zLine[j] = 0;
}
fossil_print("redirect with status %d to %s\n", rc, &zLine[i]);
url_parse(&zLine[i], 0);
transport_close(&g.url);
transport_global_shutdown(&g.url);
fSeenHttpAuth = 0;
if( g.zHttpAuth ) free(g.zHttpAuth);
g.zHttpAuth = get_httpauth();
return http_exchange(pSend, pReply, useLogin, maxRedirect);
}else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
isCompressed = 0;
|
| ︙ | ︙ |
Changes to src/http_socket.c.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** at a time. State information is stored in static variables. The identity ** of the server is held in global variables that are set by url_parse(). ** ** Low-level sockets are abstracted out into this module because they ** are handled different on Unix and windows. */ #include "config.h" #include "http_socket.h" #if defined(_WIN32) # if !defined(_WIN32_WINNT) # define _WIN32_WINNT 0x0501 # endif # include <winsock2.h> | > > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | ** at a time. State information is stored in static variables. The identity ** of the server is held in global variables that are set by url_parse(). ** ** Low-level sockets are abstracted out into this module because they ** are handled different on Unix and windows. */ #ifndef __EXTENSIONS__ # define __EXTENSIONS__ 1 /* IPv6 won't compile on Solaris without this */ #endif #include "config.h" #include "http_socket.h" #if defined(_WIN32) # if !defined(_WIN32_WINNT) # define _WIN32_WINNT 0x0501 # endif # include <winsock2.h> |
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
/*
** Print common information about a particular record.
**
** * The UUID
** * The record ID
** * mtime and ctime
** * who signed it
*/
void show_common_info(
int rid, /* The rid for the check-in to display info for */
const char *zUuidName, /* Name of the UUID */
int showComment, /* True to show the check-in comment */
int showFamily /* True to show parents and children */
){
| > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
/*
** Print common information about a particular record.
**
** * The UUID
** * The record ID
** * mtime and ctime
** * who signed it
**
*/
void show_common_info(
int rid, /* The rid for the check-in to display info for */
const char *zUuidName, /* Name of the UUID */
int showComment, /* True to show the check-in comment */
int showFamily /* True to show parents and children */
){
|
| ︙ | ︙ | |||
107 108 109 110 111 112 113 |
db_column_int(&q, 1)
);
fossil_print("%-13s %s %s\n", zType, zUuid, zDate);
free(zDate);
}
db_finalize(&q);
}
| < < < < < < < < < < < < < < < < | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
db_column_int(&q, 1)
);
fossil_print("%-13s %s %s\n", zType, zUuid, zDate);
free(zDate);
}
db_finalize(&q);
}
zTags = info_tags_of_checkin(rid, 0);
if( zTags && zTags[0] ){
fossil_print("tags: %s\n", zTags);
}
free(zTags);
if( zComment ){
fossil_print("comment: ");
|
| ︙ | ︙ | |||
496 497 498 499 500 501 502 | } return diffFlags; } /* ** WEBPAGE: vinfo ** WEBPAGE: ci | | > | | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | } return diffFlags; } /* ** WEBPAGE: vinfo ** WEBPAGE: ci ** URL: /ci?name=ARTIFACTID ** URL: /vinfo?name=ARTIFACTID ** ** Display information about a particular check-in. ** ** We also jump here from /info if the name is a check-in ** ** If the /ci page is used (instead of /vinfo or /info) then the ** default behavior is to show unified diffs of all file changes. ** With /vinfo and /info, only a list of the changed files are ** shown, without diffs. This behavior is inverted if the ** "show-version-diffs" setting is turned on. */ |
| ︙ | ︙ | |||
759 760 761 762 763 764 765 | style_footer(); } /* ** WEBPAGE: winfo ** URL: /winfo?name=UUID ** | | | 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
style_footer();
}
/*
** WEBPAGE: winfo
** URL: /winfo?name=UUID
**
** Display information about a wiki page.
*/
void winfo_page(void){
int rid;
Manifest *pWiki;
char *zUuid;
char *zDate;
Blob wiki;
|
| ︙ | ︙ | |||
962 963 964 965 966 967 968 | } db_finalize(&q); } /* ** WEBPAGE: vdiff | | > > > > > | 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 |
}
db_finalize(&q);
}
/*
** WEBPAGE: vdiff
** URL: /vdiff?from=TAG&to=TAG
**
** Show the difference between two check-ins identified by the from= and
** to= query parameters.
**
** Query parameters:
**
** from=TAG Left side of the comparison
** to=TAG Right side of the comparison
** branch=TAG Show all changes on a particular branch
** v=BOOLEAN Default true. If false, only list files that have changed
** sbs=BOOLEAN Side-by-side diff if true. Unified diff if false
** glob=STRING only diff files matching this glob
** dc=N show N lines of context around each diff
** w ignore whitespace when computing diffs
**
**
** Show all differences between two check-ins.
*/
void vdiff_page(void){
int ridFrom, ridTo;
int verboseFlag = 0;
|
| ︙ | ︙ | |||
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 |
** Two arguments, v1 and v2, identify the files to be diffed. Show the
** difference between the two artifacts. Show diff side by side unless sbs
** is 0. Generate plaintext if "patch" is present.
**
** Additional parameters:
**
** verbose Show more detail when describing artifacts
*/
void diff_page(void){
int v1, v2;
int isPatch;
int sideBySide;
char *zV1;
char *zV2;
| > > | 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 |
** Two arguments, v1 and v2, identify the files to be diffed. Show the
** difference between the two artifacts. Show diff side by side unless sbs
** is 0. Generate plaintext if "patch" is present.
**
** Additional parameters:
**
** verbose Show more detail when describing artifacts
** dc=N Show N lines of context around each diff
** w Ignore whitespace
*/
void diff_page(void){
int v1, v2;
int isPatch;
int sideBySide;
char *zV1;
char *zV2;
|
| ︙ | ︙ | |||
2035 2036 2037 2038 2039 2040 2041 | } /* ** WEBPAGE: info ** URL: info/ARTIFACTID ** | | | | 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 |
}
/*
** WEBPAGE: info
** URL: info/ARTIFACTID
**
** The argument is a artifact ID which might be a check-in or a file or
** a ticket changes or a wiki edit or something else.
**
** Figure out what the artifact ID is and display it appropriately.
*/
void info_page(void){
const char *zName;
Blob uuid;
int rid;
int rc;
int nLen;
|
| ︙ | ︙ | |||
2270 2271 2272 2273 2274 2275 2276 | while( fossil_isspace(zB[0]) ) zB++; while( fossil_isspace(zA[0]) ) zA++; return zA[0]==0 && zB[0]==0; } /* ** WEBPAGE: ci_edit | | | > > | 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 |
while( fossil_isspace(zB[0]) ) zB++;
while( fossil_isspace(zA[0]) ) zA++;
return zA[0]==0 && zB[0]==0;
}
/*
** WEBPAGE: ci_edit
** URL: /ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
**
** Present a dialog for updating properties of a check-in.
**
** * The check-in user
** * The check-in comment
** * The check-in time and date
** * The background color.
** * Add and remove tags
*/
void ci_edit_page(void){
int rid;
const char *zComment; /* Current comment on the check-in */
const char *zNewComment; /* Revised check-in comment */
const char *zUser; /* Current user for the check-in */
const char *zNewUser; /* Revised user */
|
| ︙ | ︙ |
Changes to src/json.c.
| ︙ | ︙ | |||
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 | INT(g, thTrace); INT(g, isHome); INT(g, nAux); INT(g, allowSymlinks); CSTR(g, zMainDbType); CSTR(g, zConfigDbType); CSTR(g, zLocalRoot); CSTR(g, zPath); CSTR(g, zExtra); CSTR(g, zBaseURL); CSTR(g, zTop); CSTR(g, zContentType); CSTR(g, zErrMsg); | > | 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 | INT(g, thTrace); INT(g, isHome); INT(g, nAux); INT(g, allowSymlinks); CSTR(g, zMainDbType); CSTR(g, zConfigDbType); CSTR(g, zOpenRevision); CSTR(g, zLocalRoot); CSTR(g, zPath); CSTR(g, zExtra); CSTR(g, zBaseURL); CSTR(g, zTop); CSTR(g, zContentType); CSTR(g, zErrMsg); |
| ︙ | ︙ |
Changes to src/json_config.c.
| ︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
static const struct JsonConfigProperty {
char const * name;
int groupMask;
} JsonConfigProperties[] = {
{ "css", CONFIGSET_CSS },
{ "header", CONFIGSET_SKIN },
{ "footer", CONFIGSET_SKIN },
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "timeline-plaintext", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
| > < | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
static const struct JsonConfigProperty {
char const * name;
int groupMask;
} JsonConfigProperties[] = {
{ "css", CONFIGSET_CSS },
{ "header", CONFIGSET_SKIN },
{ "footer", CONFIGSET_SKIN },
{ "details", CONFIGSET_SKIN },
{ "logo-mimetype", CONFIGSET_SKIN },
{ "logo-image", CONFIGSET_SKIN },
{ "background-mimetype", CONFIGSET_SKIN },
{ "background-image", CONFIGSET_SKIN },
{ "timeline-block-markup", CONFIGSET_SKIN },
{ "timeline-max-comment", CONFIGSET_SKIN },
{ "timeline-plaintext", CONFIGSET_SKIN },
{ "adunit", CONFIGSET_SKIN },
{ "adunit-omit-if-admin", CONFIGSET_SKIN },
{ "adunit-omit-if-user", CONFIGSET_SKIN },
{ "project-name", CONFIGSET_PROJ },
{ "short-project-name", CONFIGSET_PROJ },
{ "project-description", CONFIGSET_PROJ },
{ "index-page", CONFIGSET_PROJ },
{ "manifest", CONFIGSET_PROJ },
{ "binary-glob", CONFIGSET_PROJ },
|
| ︙ | ︙ |
Changes to src/leaf.c.
| ︙ | ︙ | |||
178 179 180 181 182 183 184 |
void leaf_do_pending_checks(void){
int rid;
for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){
leaf_check(rid);
}
bag_clear(&needToCheck);
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
void leaf_do_pending_checks(void){
int rid;
for(rid=bag_first(&needToCheck); rid; rid=bag_next(&needToCheck,rid)){
leaf_check(rid);
}
bag_clear(&needToCheck);
}
/*
** If check-in rid is an open-leaf and there exists another
** open leaf on the same branch, then return 1.
**
** If check-in rid is not an open leaf, or if it is the only open leaf
** on its branch, then return 0.
*/
int leaf_ambiguity(int rid){
int rc; /* Result */
char zVal[30];
if( !is_a_leaf(rid) ) return 0;
sqlite3_snprintf(sizeof(zVal), zVal, "%d", rid);
rc = db_exists(
"SELECT 1 FROM leaf"
" WHERE NOT %z"
" AND rid<>%d"
" AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)="
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=%d)"
" AND NOT %z",
leaf_is_closed_sql(zVal), rid, TAG_BRANCH, TAG_BRANCH, rid,
leaf_is_closed_sql("leaf.rid"));
return rc;
}
/*
** If check-in rid is an open-leaf and there exists another open leaf
** on the same branch, then print a detailed warning showing all open
** leaves on that branch.
*/
int leaf_ambiguity_warning(int rid, int currentCkout){
char *zBr;
Stmt q;
int n = 0;
Blob msg;
if( leaf_ambiguity(rid)==0 ) return 0;
zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_BRANCH, rid);
if( zBr==0 ) zBr = fossil_strdup("trunk");
blob_init(&msg, 0, 0);
blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr);
db_prepare(&q,
"SELECT"
" (SELECT uuid FROM blob WHERE rid=leaf.rid),"
" (SELECT datetime(mtime%s) FROM event WHERE objid=leaf.rid),"
" leaf.rid"
" FROM leaf"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=leaf.rid)=%Q"
" AND NOT %z"
" ORDER BY 2 DESC",
timeline_utc(), TAG_BRANCH, zBr, leaf_is_closed_sql("leaf.rid")
);
while( db_step(&q)==SQLITE_ROW ){
blob_appendf(&msg, "\n (%d) %s [%S]%s",
++n, db_column_text(&q,1), db_column_text(&q,0),
db_column_int(&q,2)==currentCkout ? " (current)" : "");
}
db_finalize(&q);
fossil_warning("%s",blob_str(&msg));
blob_reset(&msg);
return 1;
}
/*
** COMMAND: test-leaf-ambiguity
**
** Usage: %fossil NAME ...
**
** Resolve each name on the command line and call leaf_ambiguity_warning()
** for each resulting RID.
*/
void leaf_ambiguity_warning_test(void){
int i;
int rid;
int rc;
db_find_and_open_repository(0,0);
verify_all_options();
for(i=2; i<g.argc; i++){
char *zUuid;
rid = name_to_typed_rid(g.argv[i], "ci");
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
fossil_print("%s (rid=%d) %S ", g.argv[i], rid, zUuid ? zUuid : "(none)");
fossil_free(zUuid);
rc = leaf_ambiguity_warning(rid, rid);
if( rc==0 ) fossil_print(" ok\n");
}
}
|
Changes to src/login.c.
| ︙ | ︙ | |||
1300 1301 1302 1303 1304 1305 1306 |
}
fossil_fatal("Cross-site request forgery attempt");
}
/*
** WEBPAGE: register
**
| | | | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 |
}
fossil_fatal("Cross-site request forgery attempt");
}
/*
** WEBPAGE: register
**
** Page to allow users to self-register. The "self-register" setting
** must be enabled for this page to operate.
*/
void register_page(void){
const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap;
unsigned int uSeed;
const char *zDecoded;
char *zCaptcha;
if( !db_get_boolean("self-register", 0) ){
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
133 134 135 136 137 138 139 140 141 142 143 144 145 146 | sqlite3_int64 now; /* Seconds since 1970 */ int repositoryOpen; /* True if the main repository database is open */ char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database */ char *zLocalDbName; /* Name of the local database */ const char *zMainDbType;/* "configdb", "localdb", or "repository" */ const char *zConfigDbType; /* "configdb", "localdb", or "repository" */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ | > | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | sqlite3_int64 now; /* Seconds since 1970 */ int repositoryOpen; /* True if the main repository database is open */ char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database */ char *zLocalDbName; /* Name of the local database */ const char *zMainDbType;/* "configdb", "localdb", or "repository" */ const char *zConfigDbType; /* "configdb", "localdb", or "repository" */ char *zOpenRevision; /* Check-in version to use during database open */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ |
| ︙ | ︙ | |||
588 589 590 591 592 593 594 |
#endif
int main(int argc, char **argv)
#endif
{
const char *zCmdName = "unknown";
int idx;
int rc;
| | | | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
#endif
int main(int argc, char **argv)
#endif
{
const char *zCmdName = "unknown";
int idx;
int rc;
if( sqlite3_libversion_number()<3008007 ){
fossil_fatal("Unsuitable SQLite version %s, must be at least 3.8.7",
sqlite3_libversion());
}
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
memset(&g, 0, sizeof(g));
g.now = time(0);
g.httpHeader = empty_blob;
|
| ︙ | ︙ | |||
654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
"with '-' and contains a space, in which case it is assumed to be\n"
"another flag and is treated as such. --args FILENAME may be used\n"
"in conjunction with any other flags.\n");
fossil_exit(1);
}else{
const char *zChdir = find_option("chdir",0,1);
g.isHTTP = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
g.fSshClient = 0;
g.zSshCmd = 0;
| > | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
"with '-' and contains a space, in which case it is assumed to be\n"
"another flag and is treated as such. --args FILENAME may be used\n"
"in conjunction with any other flags.\n");
fossil_exit(1);
}else{
const char *zChdir = find_option("chdir",0,1);
g.isHTTP = 0;
g.rcvid = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
g.fSshClient = 0;
g.zSshCmd = 0;
|
| ︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 |
fossil_print("miniz %s, loaded %s\n", MZ_VERSION, mz_version());
#else
fossil_print("zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion());
#endif
#if defined(FOSSIL_ENABLE_SSL)
fossil_print("SSL (%s)\n", SSLeay_version(SSLEAY_VERSION));
#endif
#if defined(FOSSIL_ENABLE_TH1_DOCS)
fossil_print("TH1_DOCS\n");
#endif
#if defined(FOSSIL_ENABLE_TH1_HOOKS)
fossil_print("TH1_HOOKS\n");
#endif
#if defined(FOSSIL_ENABLE_TCL)
| > > > | 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 |
fossil_print("miniz %s, loaded %s\n", MZ_VERSION, mz_version());
#else
fossil_print("zlib %s, loaded %s\n", ZLIB_VERSION, zlibVersion());
#endif
#if defined(FOSSIL_ENABLE_SSL)
fossil_print("SSL (%s)\n", SSLeay_version(SSLEAY_VERSION));
#endif
#if defined(FOSSIL_ENABLE_LEGACY_MV_RM)
fossil_print("LEGACY_MV_RM\n");
#endif
#if defined(FOSSIL_ENABLE_TH1_DOCS)
fossil_print("TH1_DOCS\n");
#endif
#if defined(FOSSIL_ENABLE_TH1_HOOKS)
fossil_print("TH1_HOOKS\n");
#endif
#if defined(FOSSIL_ENABLE_TCL)
|
| ︙ | ︙ | |||
1126 1127 1128 1129 1130 1131 1132 |
}
}
putchar('\n');
}
/*
** WEBPAGE: help
| | > > > | 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 |
}
}
putchar('\n');
}
/*
** WEBPAGE: help
** URL: /help?name=CMD
**
** Show the built-in help text for CMD. CMD can be a command-line interface
** command or a page name from the web interface.
*/
void help_page(void){
const char *zCmd = P("cmd");
if( zCmd==0 ) zCmd = P("name");
style_header("Command-line Help");
if( zCmd ){
|
| ︙ | ︙ | |||
1194 1195 1196 1197 1198 1199 1200 |
}
if( j>0 ){
@ </ul></td>
}
@ </tr></table>
@ <h1>Available web UI pages:</h1>
| < | 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 |
}
if( j>0 ){
@ </ul></td>
}
@ </tr></table>
@ <h1>Available web UI pages:</h1>
@ <table border="0"><tr>
for(i=j=0; i<count(aCommand); i++){
const char *z = aCommand[i].zName;
if( '/'!=*z ) continue;
j++;
}
n = (j+4)/5;
|
| ︙ | ︙ | |||
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 |
db_multi_exec("CREATE TABLE sfile(x TEXT);");
db_multi_exec("CREATE TABLE vfile(pathname);");
vfile_scan(&base, blob_size(&base), 0, 0, 0);
db_multi_exec("DELETE FROM sfile WHERE x NOT GLOB '*.fossil'");
n = db_int(0, "SELECT count(*) FROM sfile");
if( n>0 ){
Stmt q;
@ <h1>Available Repositories:</h1>
@ <ol>
db_prepare(&q, "SELECT x, substr(x,-7,-100000)||'/home'"
" FROM sfile ORDER BY x COLLATE nocase;");
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zUrl = db_column_text(&q, 1);
| > > > > > | > > | 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 |
db_multi_exec("CREATE TABLE sfile(x TEXT);");
db_multi_exec("CREATE TABLE vfile(pathname);");
vfile_scan(&base, blob_size(&base), 0, 0, 0);
db_multi_exec("DELETE FROM sfile WHERE x NOT GLOB '*.fossil'");
n = db_int(0, "SELECT count(*) FROM sfile");
if( n>0 ){
Stmt q;
@ <html>
@ <head>
@ <title>Repository List</title>
@ </head>
@ <body>
@ <h1>Available Repositories:</h1>
@ <ol>
db_prepare(&q, "SELECT x, substr(x,-7,-100000)||'/home'"
" FROM sfile ORDER BY x COLLATE nocase;");
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zUrl = db_column_text(&q, 1);
@ <li><a href="%h(zUrl)" target="_blank">%h(zName)</a></li>
}
@ </ol>
@ </body>
@ </html>
cgi_reply();
}
sqlite3_close(g.db);
g.db = 0;
return n;
}
|
| ︙ | ︙ | |||
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 |
}
szFile = 1;
break;
}
if( szFile==0 ){
if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; }
szFile = file_size(zRepo);
}
if( szFile<0 && i>0 ){
const char *zMimetype;
assert( fossil_strcmp(&zRepo[j], ".fossil")==0 );
zRepo[j] = 0;
if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
fossil_free(zToFree);
| > > > > > > | 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 |
}
szFile = 1;
break;
}
if( szFile==0 ){
if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; }
szFile = file_size(zRepo);
/* this should only be set from the --baseurl option, not CGI */
if( g.zBaseURL && g.zBaseURL[0]!=0 && g.zTop && g.zTop[0]!=0 &&
file_isdir(g.zRepositoryName)==1 ){
g.zBaseURL = mprintf("%s%.*s", g.zBaseURL, i, zPathInfo);
g.zTop = mprintf("%s%.*s", g.zTop, i, zPathInfo);
}
}
if( szFile<0 && i>0 ){
const char *zMimetype;
assert( fossil_strcmp(&zRepo[j], ".fossil")==0 );
zRepo[j] = 0;
if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){
fossil_free(zToFree);
|
| ︙ | ︙ | |||
1549 1550 1551 1552 1553 1554 1555 |
return;
}
zRepo[j] = '.';
}
if( szFile<1024 ){
set_base_url(0);
| < < | > > | 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 |
return;
}
zRepo[j] = '.';
}
if( szFile<1024 ){
set_base_url(0);
if( strcmp(zPathInfo,"/")==0
&& allowRepoList
&& repo_list_page() ){
/* Will return a list of repositories */
}else if( zNotFound ){
cgi_redirect(zNotFound);
}else{
#ifdef FOSSIL_ENABLE_JSON
if(g.json.isJsonMode){
json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
return;
}
#endif
|
| ︙ | ︙ | |||
2155 2156 2157 2158 2159 2160 2161 |
if( zAltBase ) set_base_url(zAltBase);
if( find_option("https",0,0)!=0 ){
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
cgi_replace_parameter("HTTPS","on");
}
zHost = find_option("host", 0, 1);
if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
| < > | 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 |
if( zAltBase ) set_base_url(zAltBase);
if( find_option("https",0,0)!=0 ){
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
cgi_replace_parameter("HTTPS","on");
}
zHost = find_option("host", 0, 1);
if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
/* We should be done with options.. */
verify_all_options();
if( g.argc!=2 && g.argc!=3 && g.argc!=5 && g.argc!=6 ){
fossil_fatal("no repository specified");
}
g.cgiOutput = 1;
g.fullHttpReply = 1;
if( g.argc>=5 ){
g.httpIn = fossil_fopen(g.argv[2], "rb");
g.httpOut = fossil_fopen(g.argv[3], "wb");
zIpAddr = g.argv[4];
find_server_repository(5, 0);
}else{
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 93 94 95 | $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/path.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/publish.c \ $(SRCDIR)/purge.c \ $(SRCDIR)/rebuild.c \ | > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/path.c \ $(SRCDIR)/piechart.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/publish.c \ $(SRCDIR)/purge.c \ $(SRCDIR)/rebuild.c \ |
| ︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | $(SRCDIR)/winhttp.c \ $(SRCDIR)/wysiwyg.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../skins/black_and_white/css.txt \ $(SRCDIR)/../skins/black_and_white/footer.txt \ $(SRCDIR)/../skins/black_and_white/header.txt \ $(SRCDIR)/../skins/blitz/css.txt \ $(SRCDIR)/../skins/blitz/footer.txt \ $(SRCDIR)/../skins/blitz/header.txt \ $(SRCDIR)/../skins/blitz/ticket.txt \ $(SRCDIR)/../skins/blitz_no_logo/css.txt \ $(SRCDIR)/../skins/blitz_no_logo/footer.txt \ $(SRCDIR)/../skins/blitz_no_logo/header.txt \ $(SRCDIR)/../skins/blitz_no_logo/ticket.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ $(SRCDIR)/../skins/enhanced1/header.txt \ $(SRCDIR)/../skins/khaki/css.txt \ $(SRCDIR)/../skins/khaki/footer.txt \ $(SRCDIR)/../skins/khaki/header.txt \ $(SRCDIR)/../skins/original/css.txt \ $(SRCDIR)/../skins/original/footer.txt \ $(SRCDIR)/../skins/original/header.txt \ $(SRCDIR)/../skins/plain_gray/css.txt \ $(SRCDIR)/../skins/plain_gray/footer.txt \ $(SRCDIR)/../skins/plain_gray/header.txt \ $(SRCDIR)/../skins/rounded1/css.txt \ $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ | > > > > > > > > > > > > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | $(SRCDIR)/winhttp.c \ $(SRCDIR)/wysiwyg.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../skins/aht/details.txt \ $(SRCDIR)/../skins/black_and_white/css.txt \ $(SRCDIR)/../skins/black_and_white/details.txt \ $(SRCDIR)/../skins/black_and_white/footer.txt \ $(SRCDIR)/../skins/black_and_white/header.txt \ $(SRCDIR)/../skins/blitz/css.txt \ $(SRCDIR)/../skins/blitz/details.txt \ $(SRCDIR)/../skins/blitz/footer.txt \ $(SRCDIR)/../skins/blitz/header.txt \ $(SRCDIR)/../skins/blitz/ticket.txt \ $(SRCDIR)/../skins/blitz_no_logo/css.txt \ $(SRCDIR)/../skins/blitz_no_logo/details.txt \ $(SRCDIR)/../skins/blitz_no_logo/footer.txt \ $(SRCDIR)/../skins/blitz_no_logo/header.txt \ $(SRCDIR)/../skins/blitz_no_logo/ticket.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ $(SRCDIR)/../skins/enhanced1/header.txt \ $(SRCDIR)/../skins/khaki/css.txt \ $(SRCDIR)/../skins/khaki/details.txt \ $(SRCDIR)/../skins/khaki/footer.txt \ $(SRCDIR)/../skins/khaki/header.txt \ $(SRCDIR)/../skins/original/css.txt \ $(SRCDIR)/../skins/original/details.txt \ $(SRCDIR)/../skins/original/footer.txt \ $(SRCDIR)/../skins/original/header.txt \ $(SRCDIR)/../skins/plain_gray/css.txt \ $(SRCDIR)/../skins/plain_gray/details.txt \ $(SRCDIR)/../skins/plain_gray/footer.txt \ $(SRCDIR)/../skins/plain_gray/header.txt \ $(SRCDIR)/../skins/rounded1/css.txt \ $(SRCDIR)/../skins/rounded1/details.txt \ $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ |
| ︙ | ︙ | |||
241 242 243 244 245 246 247 248 249 250 251 252 253 254 | $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/path_.c \ $(OBJDIR)/pivot_.c \ $(OBJDIR)/popen_.c \ $(OBJDIR)/pqueue_.c \ $(OBJDIR)/printf_.c \ $(OBJDIR)/publish_.c \ $(OBJDIR)/purge_.c \ $(OBJDIR)/rebuild_.c \ | > | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/path_.c \ $(OBJDIR)/piechart_.c \ $(OBJDIR)/pivot_.c \ $(OBJDIR)/popen_.c \ $(OBJDIR)/pqueue_.c \ $(OBJDIR)/printf_.c \ $(OBJDIR)/publish_.c \ $(OBJDIR)/purge_.c \ $(OBJDIR)/rebuild_.c \ |
| ︙ | ︙ | |||
361 362 363 364 365 366 367 368 369 370 371 372 373 374 | $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/path.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/publish.o \ $(OBJDIR)/purge.o \ $(OBJDIR)/rebuild.o \ | > | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/path.o \ $(OBJDIR)/piechart.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/publish.o \ $(OBJDIR)/purge.o \ $(OBJDIR)/rebuild.o \ |
| ︙ | ︙ | |||
460 461 462 463 464 465 466 |
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| | > | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_DBSTAT_VTAB
# Setup the options used to compile the included SQLite shell.
SHELL_OPTIONS = -Dmain=sqlite3_shell \
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
-DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
-DSQLITE_SHELL_DBNAME_PROC=fossil_open
|
| ︙ | ︙ | |||
592 593 594 595 596 597 598 599 600 601 602 603 604 605 | $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ | > | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ $(OBJDIR)/piechart_.c:$(OBJDIR)/piechart.h \ $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| ︙ | ︙ | |||
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 | $(OBJDIR)/path_.c: $(SRCDIR)/path.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/path.c >$@ $(OBJDIR)/path.o: $(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c $(OBJDIR)/path.h: $(OBJDIR)/headers $(OBJDIR)/pivot_.c: $(SRCDIR)/pivot.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/pivot.c >$@ $(OBJDIR)/pivot.o: $(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c | > > > > > > > > | 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 | $(OBJDIR)/path_.c: $(SRCDIR)/path.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/path.c >$@ $(OBJDIR)/path.o: $(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c $(OBJDIR)/path.h: $(OBJDIR)/headers $(OBJDIR)/piechart_.c: $(SRCDIR)/piechart.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/piechart.c >$@ $(OBJDIR)/piechart.o: $(OBJDIR)/piechart_.c $(OBJDIR)/piechart.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/piechart.o -c $(OBJDIR)/piechart_.c $(OBJDIR)/piechart.h: $(OBJDIR)/headers $(OBJDIR)/pivot_.c: $(SRCDIR)/pivot.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/pivot.c >$@ $(OBJDIR)/pivot.o: $(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c |
| ︙ | ︙ |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 100 101 | markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild | > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild |
| ︙ | ︙ | |||
157 158 159 160 161 162 163 164 165 166 167 168 169 170 | -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS } #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4 #lappend SQLITE_OPTIONS -DSQLITE_WIN32_NO_ANSI #lappend SQLITE_OPTIONS -DSQLITE_WINNT_MAX_PATH_CHARS=4096 # Options used to compile the included SQLite shell. | > | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB } #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4 #lappend SQLITE_OPTIONS -DSQLITE_WIN32_NO_ANSI #lappend SQLITE_OPTIONS -DSQLITE_WINNT_MAX_PATH_CHARS=4096 # Options used to compile the included SQLite shell. |
| ︙ | ︙ | |||
491 492 493 494 495 496 497 498 499 500 501 502 503 504 | # # FOSSIL_ENABLE_SSL = 1 #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 #### Enable TH1 scripts in embedded documentation files # # FOSSIL_ENABLE_TH1_DOCS = 1 #### Enable hooks for commands and web pages via TH1 # | > > > > | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | # # FOSSIL_ENABLE_SSL = 1 #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 #### Enable legacy treatment of mv/rm (skip checkout files) # # FOSSIL_ENABLE_LEGACY_MV_RM = 1 #### Enable TH1 scripts in embedded documentation files # # FOSSIL_ENABLE_TH1_DOCS = 1 #### Enable hooks for commands and web pages via TH1 # |
| ︙ | ︙ | |||
690 691 692 693 694 695 696 697 698 699 700 701 702 703 | endif # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif # With TH1 embedded docs support ifdef FOSSIL_ENABLE_TH1_DOCS TCC += -DFOSSIL_ENABLE_TH1_DOCS=1 RCC += -DFOSSIL_ENABLE_TH1_DOCS=1 endif | > > > > > > | 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 | endif # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif # With legacy treatment of mv/rm ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 endif # With TH1 embedded docs support ifdef FOSSIL_ENABLE_TH1_DOCS TCC += -DFOSSIL_ENABLE_TH1_DOCS=1 RCC += -DFOSSIL_ENABLE_TH1_DOCS=1 endif |
| ︙ | ︙ | |||
1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 | # FOSSIL_ENABLE_MINIZ = 1 # Uncomment to enable SSL support # FOSSIL_ENABLE_SSL = 1 # Uncomment to build SSL libraries # FOSSIL_BUILD_SSL = 1 # Uncomment to enable TH1 scripts in embedded documentation files # FOSSIL_ENABLE_TH1_DOCS = 1 # Uncomment to enable TH1 hooks # FOSSIL_ENABLE_TH1_HOOKS = 1 | > > > | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 | # FOSSIL_ENABLE_MINIZ = 1 # Uncomment to enable SSL support # FOSSIL_ENABLE_SSL = 1 # Uncomment to build SSL libraries # FOSSIL_BUILD_SSL = 1 # Uncomment to enable legacy treatment of mv/rm # FOSSIL_ENABLE_LEGACY_MV_RM = 1 # Uncomment to enable TH1 scripts in embedded documentation files # FOSSIL_ENABLE_TH1_DOCS = 1 # Uncomment to enable TH1 hooks # FOSSIL_ENABLE_TH1_HOOKS = 1 |
| ︙ | ︙ | |||
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 | !ifdef FOSSIL_ENABLE_SSL TCC = $(TCC) /DFOSSIL_ENABLE_SSL=1 RCC = $(RCC) /DFOSSIL_ENABLE_SSL=1 LIBS = $(LIBS) $(SSLLIB) LIBDIR = $(LIBDIR) /LIBPATH:$(SSLLIBDIR) !endif !ifdef FOSSIL_ENABLE_TH1_DOCS TCC = $(TCC) /DFOSSIL_ENABLE_TH1_DOCS=1 RCC = $(RCC) /DFOSSIL_ENABLE_TH1_DOCS=1 !endif !ifdef FOSSIL_ENABLE_TH1_HOOKS | > > > > > | 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | !ifdef FOSSIL_ENABLE_SSL TCC = $(TCC) /DFOSSIL_ENABLE_SSL=1 RCC = $(RCC) /DFOSSIL_ENABLE_SSL=1 LIBS = $(LIBS) $(SSLLIB) LIBDIR = $(LIBDIR) /LIBPATH:$(SSLLIBDIR) !endif !ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC = $(TCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC = $(RCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 !endif !ifdef FOSSIL_ENABLE_TH1_DOCS TCC = $(TCC) /DFOSSIL_ENABLE_TH1_DOCS=1 RCC = $(RCC) /DFOSSIL_ENABLE_TH1_DOCS=1 !endif !ifdef FOSSIL_ENABLE_TH1_HOOKS |
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 |
** will be NULL and it will be computed based on cid/pid.
**
** A single mlink entry is added for every file that changed content,
** name, and/or permissions going from pid to cid.
**
** Deleted files have mlink.fid=0.
** Added files have mlink.pid=0.
** Edited files have both mlink.pid!=0 and mlink.fid!=0
*/
static void add_mlink(
int pmid, Manifest *pParent, /* Parent check-in */
int mid, Manifest *pChild, /* The child check-in */
int isPrim /* TRUE if pmid is the primary parent of mid */
){
| > | 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 |
** will be NULL and it will be computed based on cid/pid.
**
** A single mlink entry is added for every file that changed content,
** name, and/or permissions going from pid to cid.
**
** Deleted files have mlink.fid=0.
** Added files have mlink.pid=0.
** File added by merge have mlink.pid=-1
** Edited files have both mlink.pid!=0 and mlink.fid!=0
*/
static void add_mlink(
int pmid, Manifest *pParent, /* Parent check-in */
int mid, Manifest *pChild, /* The child check-in */
int isPrim /* TRUE if pmid is the primary parent of mid */
){
|
| ︙ | ︙ | |||
1799 1800 1801 1802 1803 1804 1805 |
"INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
"VALUES(%d, %d, %d, %.17g, %s)",
pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
add_mlink(pid, 0, rid, p, i==0);
if( i==0 ) parentid = pid;
}
if( p->nParent>1 ){
| < | | | 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 |
"INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)"
"VALUES(%d, %d, %d, %.17g, %s)",
pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/);
add_mlink(pid, 0, rid, p, i==0);
if( i==0 ) parentid = pid;
}
if( p->nParent>1 ){
/* Change MLINK.PID from 0 to -1 for files that are added by merge. */
db_multi_exec(
"UPDATE mlink SET pid=-1"
" WHERE mid=%d"
" AND pid=0"
" AND fnid IN "
" (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid"
" HAVING count(*)<%d)",
rid, rid, p->nParent
);
|
| ︙ | ︙ |
Changes to src/merge.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
indent, "");
comment_print(zCom, db_column_text(&q,2), indent, -1, g.comFmtFlags);
fossil_free(zCom);
}
db_finalize(&q);
}
/*
** COMMAND: merge
**
** Usage: %fossil merge ?OPTIONS? ?VERSION?
**
** The argument VERSION is a version that should be merged into the
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
indent, "");
comment_print(zCom, db_column_text(&q,2), indent, -1, g.comFmtFlags);
fossil_free(zCom);
}
db_finalize(&q);
}
/* Pick the most recent leaf that is (1) not equal to vid and (2)
** has not already been merged into vid and (3) the leaf is not
** closed and (4) the leaf is in the same branch as vid.
**
** Set vmergeFlag to control whether the vmerge table is checked.
*/
int fossil_find_nearest_fork(int vid, int vmergeFlag){
Blob sql;
Stmt q;
int rid = 0;
blob_zero(&sql);
blob_append_sql(&sql,
"SELECT leaf.rid"
" FROM leaf, event"
" WHERE leaf.rid=event.objid"
" AND leaf.rid!=%d", /* Constraint (1) */
vid
);
if( vmergeFlag ){
blob_append_sql(&sql,
" AND leaf.rid NOT IN (SELECT merge FROM vmerge)" /* Constraint (2) */
);
}
blob_append_sql(&sql,
" AND NOT EXISTS(SELECT 1 FROM tagxref" /* Constraint (3) */
" WHERE rid=leaf.rid"
" AND tagid=%d"
" AND tagtype>0)"
" AND (SELECT value FROM tagxref" /* Constraint (4) */
" WHERE tagid=%d AND rid=%d AND tagtype>0) ="
" (SELECT value FROM tagxref"
" WHERE tagid=%d AND rid=leaf.rid AND tagtype>0)"
" ORDER BY event.mtime DESC LIMIT 1",
TAG_CLOSED, TAG_BRANCH, vid, TAG_BRANCH
);
db_prepare(&q, "%s", blob_sql_text(&sql));
blob_reset(&sql);
if( db_step(&q)==SQLITE_ROW ){
rid = db_column_int(&q, 0);
}
db_finalize(&q);
return rid;
}
/*
** Check content that was received with rcvid and return true if any
** fork was created.
*/
int fossil_any_has_fork(int rcvid){
static Stmt q;
int fForkSeen = 0;
if( rcvid==0 ) return 0;
db_static_prepare(&q,
" SELECT pid FROM plink WHERE pid>0 AND isprim"
" AND cid IN (SELECT blob.rid FROM blob"
" WHERE rcvid=:rcvid)");
db_bind_int(&q, ":rcvid", rcvid);
while( !fForkSeen && db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q, 0);
if( count_nonbranch_children(pid)>1 ){
compute_leaves(pid,1);
if( db_int(0, "SELECT count(*) FROM leaves")>1 ){
int rid = db_int(0, "SELECT rid FROM leaves, event"
" WHERE event.objid=leaves.rid"
" ORDER BY event.mtime DESC LIMIT 1");
fForkSeen = fossil_find_nearest_fork(rid, db_open_local(0))!=0;
}
}
}
db_finalize(&q);
return fForkSeen;
}
/*
** COMMAND: merge
**
** Usage: %fossil merge ?OPTIONS? ?VERSION?
**
** The argument VERSION is a version that should be merged into the
|
| ︙ | ︙ | |||
170 171 172 173 174 175 176 |
** the leaf is not closed and (4) the leaf is in the same branch
** as the current checkout.
*/
Stmt q;
if( pickFlag || backoutFlag || integrateFlag){
fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge");
}
| | < < < < < < < < < < < < < < < < | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
** the leaf is not closed and (4) the leaf is in the same branch
** as the current checkout.
*/
Stmt q;
if( pickFlag || backoutFlag || integrateFlag){
fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge");
}
mid = fossil_find_nearest_fork(vid, db_open_local(0));
if( mid==0 ){
fossil_fatal("no unmerged forks of branch \"%s\"",
db_text(0, "SELECT value FROM tagxref"
" WHERE tagid=%d AND rid=%d AND tagtype>0",
TAG_BRANCH, vid)
);
}
|
| ︙ | ︙ |
Changes to src/merge3.c.
| ︙ | ︙ | |||
258 259 260 261 262 263 264 |
blob_copy_lines(0, pV2, nIns);
i1 += 3;
i2 += 3;
}else
{
/* We have found a region where different edits to V1 and V2 overlap.
** This is a merge conflict. Find the size of the conflict, then
| | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
blob_copy_lines(0, pV2, nIns);
i1 += 3;
i2 += 3;
}else
{
/* We have found a region where different edits to V1 and V2 overlap.
** This is a merge conflict. Find the size of the conflict, then
** output both possible edits separated by distinctive marks.
*/
int sz = 1; /* Size of the conflict in lines */
nConflict++;
while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
sz++;
}
DEBUG( printf("CONFLICT %d\n", sz); )
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
1066 1067 1068 1069 1070 1071 1072 |
describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0);
}
/* Maximum number of collision examples to remember */
#define MAX_COLLIDE 25
/*
| | | < | < < | < < < | 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 |
describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0);
}
/* Maximum number of collision examples to remember */
#define MAX_COLLIDE 25
/*
** Generate a report on the number of collisions in SHA1 hashes
** generated by the SQL given in the argument.
*/
static void collision_report(const char *zSql){
int i, j, kk;
int nHash = 0;
Stmt q;
char zPrev[UUID_SIZE+1];
struct {
int cnt;
char *azHit[MAX_COLLIDE];
char z[UUID_SIZE+1];
} aCollide[UUID_SIZE+1];
memset(aCollide, 0, sizeof(aCollide));
memset(zPrev, 0, sizeof(zPrev));
db_prepare(&q,"%s",zSql/*safe-for-%s*/);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q,0);
int n = db_column_bytes(&q,0);
int i;
nHash++;
for(i=0; zPrev[i] && zPrev[i]==zUuid[i]; i++){}
if( i>0 && i<=UUID_SIZE ){
if( i>=4 && aCollide[i].cnt<MAX_COLLIDE ){
aCollide[i].azHit[aCollide[i].cnt] = mprintf("%.*s", i, zPrev);
}
aCollide[i].cnt++;
if( aCollide[i].z[0]==0 ) memcpy(aCollide[i].z, zPrev, n+1);
}
memcpy(zPrev, zUuid, n+1);
}
db_finalize(&q);
@ <table border=1><thead>
@ <tr><th>Length<th>Instances<th>First Instance</tr>
@ </thead><tbody>
for(i=1; i<=UUID_SIZE; i++){
if( aCollide[i].cnt==0 ) continue;
@ <tr><td>%d(i)<td>%d(aCollide[i].cnt)<td>%h(aCollide[i].z)</tr>
}
|
| ︙ | ︙ | |||
1129 1130 1131 1132 1133 1134 1135 1136 1137 |
}
for(j=0; j<aCollide[i].cnt && j<MAX_COLLIDE; j++){
char *zId = aCollide[i].azHit[j];
if( zId==0 ) continue;
@ %z(href("%R/whatis/%s",zId))%h(zId)</a>
}
}
style_footer();
}
| > > > > > > > > > > > > > > > > > > > > > > > > | 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 |
}
for(j=0; j<aCollide[i].cnt && j<MAX_COLLIDE; j++){
char *zId = aCollide[i].azHit[j];
if( zId==0 ) continue;
@ %z(href("%R/whatis/%s",zId))%h(zId)</a>
}
}
for(i=4; i<ArraySize(aCollide); i++){
for(j=0; j<aCollide[i].cnt && j<MAX_COLLIDE; j++){
fossil_free(aCollide[i].azHit[j]);
}
}
}
/*
** WEBPAGE: hash-collisions
**
** Show the number of hash collisions for hash prefixes of various lengths.
*/
void hash_collisions_webpage(void){
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("SHA1 Prefix Collisions");
style_submenu_element("Activity Reports", 0, "reports");
style_submenu_element("Stats", 0, "stat");
@ <h1>Hash Prefix Collisions on Check-ins</h1>
collision_report("SELECT (SELECT uuid FROM blob WHERE rid=objid)"
" FROM event WHERE event.type='ci'"
" ORDER BY 1");
@ <h1>Hash Prefix Collisions on All Artifacts</h1>
collision_report("SELECT uuid FROM blob ORDER BY 1");
style_footer();
}
|
Added src/piechart.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
/*
** Copyright (c) 2015 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code for generating pie charts on web pages.
**
*/
#include "config.h"
#include "piechart.h"
#include <math.h>
#ifndef M_PI
# define M_PI 3.1415926535897932385
#endif
/*
** Return an RGB color name given HSV values. The HSV values
** must each be between between 0 and 255. The string
** returned is held in a static buffer and is overwritten
** on each call.
*/
const char *rgbName(unsigned char h, unsigned char s, unsigned char v){
static char zColor[8];
unsigned char A, B, C, r, g, b;
unsigned int i, m;
if( s==0 ){
r = g = b = v;
}else{
i = (h*6)/256;
m = (h*6)&0xff;
A = v*(256-s)/256;
B = v*(65536-s*m)/65536;
C = v*(65536-s*(256-m))/65536;
@ <!-- hsv=%d(h),%d(s),%d(v) i=%d(i) m=%d(m) ABC=%d(A),%d(B),%d(C) -->
switch( i ){
case 0: r=v; g=C; b=A; break;
case 1: r=B; g=v; b=A; break;
case 2: r=A; g=v; b=C; break;
case 3: r=A; g=B; b=v; break;
case 4: r=C; g=A; b=v; break;
default: r=v; g=A; b=B; break;
}
}
sqlite3_snprintf(sizeof(zColor),zColor,"#%02x%02x%02x",r,g,b);
return zColor;
}
/*
** Flags that can be passed into the pie-chart generator
*/
#if INTERFACE
#define PIE_OTHER 0x0001 /* No wedge less than 1/60th of the circle */
#define PIE_CHROMATIC 0x0002 /* Wedge colors are in chromatic order */
#define PIE_PERCENT 0x0004 /* Add "(XX%)" marks on each label */
#endif
/*
** A pie-chart wedge label
*/
struct WedgeLabel {
double rCos, rSin; /* Sine and Cosine of center angle of wedge */
char *z; /* Label to draw on this wedge */
};
typedef struct WedgeLabel WedgeLabel;
/*
** Comparison callback for qsort() to sort labels in order of increasing
** distance above and below the horizontal centerline.
*/
static int wedgeCompare(const void *a, const void *b){
const WedgeLabel *pA = (const WedgeLabel*)a;
const WedgeLabel *pB = (const WedgeLabel*)b;
double rA = fabs(pA->rCos);
double rB = fabs(pB->rCos);
if( rA<rB ) return -1;
if( rA>rB ) return +1;
return 0;
}
/*
** Output HTML that will render a pie chart using data from
** the PIECHART temporary table.
**
** The schema for the PIECHART table should be:
**
** CREATE TEMP TABLE piechart(amt REAL, label TEXT);
*/
void piechart_render(int width, int height, unsigned int pieFlags){
Stmt q;
double cx, cy; /* center of the pie */
double r, r2; /* Radius of the pie */
double x1,y1; /* Start of the slice */
double x2,y2; /* End of the slice */
double x3,y3; /* Middle point of the slice */
double x4,y4; /* End of line extending from x3,y3 */
double x5,y5; /* Text anchor */
double d1; /* radius to x4,y4 */
const char *zAnc; /* Anchor point for text */
double a1 = 0.0; /* Angle for first edge of slice */
double a2; /* Angle for second edge */
double a3; /* Angle at middle of slice */
unsigned char h; /* Hue */
const char *zClr; /* Color */
int l; /* Large arc flag */
int j; /* Wedge number */
double rTotal; /* Total piechart.amt */
double rTooSmall; /* Sum of pieChart.amt entries less than 1/60th */
int nTotal; /* Total number of entries in piechart */
int nTooSmall; /* Number of pieChart.amt entries less than 1/60th */
const char *zFg; /* foreground color for lines and text */
int nWedgeAlloc = 0; /* Slots allocated for aWedge[] */
int nWedge = 0; /* Slots used for aWedge[] */
WedgeLabel *aWedge = 0; /* Labels */
double rUprRight; /* Floor for next label in the upper right quadrant */
double rUprLeft; /* Floor for next label in the upper left quadrant */
double rLwrRight; /* Ceiling for label in the lower right quadrant */
double rLwrLeft; /* Ceiling for label in the lower left quadrant */
int i; /* Loop counter looping over wedge labels */
# define SATURATION 128
# define VALUE 192
# define OTHER_CUTOFF 90.0
# define TEXT_HEIGHT 15.0
cx = 0.5*width;
cy = 0.5*height;
r2 = cx<cy ? cx : cy;
r = r2 - 80.0;
if( r<0.33333*r2 ) r = 0.33333*r2;
h = 0;
zFg = skin_detail_boolean("white-foreground") ? "white" : "black";
db_prepare(&q, "SELECT sum(amt), count(*) FROM piechart");
if( db_step(&q)!=SQLITE_ROW ) return;
rTotal = db_column_double(&q, 0);
nTotal = db_column_int(&q, 1);
db_finalize(&q);
rTooSmall = 0.0;
nTooSmall = 0;
if( (pieFlags & PIE_OTHER)!=0 && nTotal>1 ){
db_prepare(&q, "SELECT sum(amt), count(*) FROM piechart WHERE amt<:amt");
db_bind_double(&q, ":amt", rTotal/OTHER_CUTOFF);
if( db_step(&q)==SQLITE_ROW ){
rTooSmall = db_column_double(&q, 0);
nTooSmall = db_column_double(&q, 1);
}
db_finalize(&q);
}
if( nTooSmall>1 ){
db_prepare(&q, "SELECT amt, label FROM piechart WHERE amt>=:limit"
" UNION ALL SELECT %.17g, '%d others';",
rTooSmall, nTooSmall);
db_bind_double(&q, ":limit", rTotal/OTHER_CUTOFF);
nTotal += 1 - nTooSmall;
}else{
db_prepare(&q, "SELECT amt, label FROM piechart");
}
if( nTotal<=10 ) pieFlags |= PIE_CHROMATIC;
for(j=0; db_step(&q)==SQLITE_ROW; j++){
double x = db_column_double(&q,0)/rTotal;
const char *zLbl = db_column_text(&q,1);
/* @ <!-- x=%g(x) zLbl="%h(zLbl)" h=%d(h) --> */
if( x<=0.0 ) continue;
x1 = cx + sin(a1)*r;
y1 = cy - cos(a1)*r;
a2 = a1 + x*2.0*M_PI;
x2 = cx + sin(a2)*r;
y2 = cy - cos(a2)*r;
a3 = 0.5*(a1+a2);
if( nWedge+1>nWedgeAlloc ){
nWedgeAlloc = nWedgeAlloc*2 + 40;
aWedge = fossil_realloc(aWedge, sizeof(aWedge[0])*nWedgeAlloc);
}
if( pieFlags & PIE_PERCENT ){
int pct = (int)(x*100.0 + 0.5);
aWedge[nWedge].z = mprintf("%s (%d%%)", zLbl, pct);
}else{
aWedge[nWedge].z = fossil_strdup(zLbl);
}
aWedge[nWedge].rSin = sin(a3);
aWedge[nWedge].rCos = cos(a3);
nWedge++;
if( (j&1)==0 || (pieFlags & PIE_CHROMATIC)!=0 ){
h = 256*j/nTotal;
}else if( j+2<nTotal ){
h = 256*(j+2)/nTotal;
}else{
h = 256*((j+2+(nTotal&1))%nTotal)/nTotal;
}
zClr = rgbName(h,SATURATION,VALUE);
l = x>=0.5;
a1 = a2;
@ <path stroke="%s(zFg)" stroke-width="1" fill="%s(zClr)"
@ d='M%g(cx),%g(cy)L%g(x1),%g(y1)A%g(r),%g(r) 0 %d(l),1 %g(x2),%g(y2)z'/>
}
qsort(aWedge, nWedge, sizeof(aWedge[0]), wedgeCompare);
rUprLeft = height;
rLwrLeft = 0;
rUprRight = height;
rLwrRight = 0;
d1 = r*1.1;
for(i=0; i<nWedge; i++){
WedgeLabel *p = &aWedge[i];
x3 = cx + p->rSin*r;
y3 = cy - p->rCos*r;
x4 = cx + p->rSin*d1;
y4 = cy - p->rCos*d1;
if( y4<=cy ){
if( x4>=cx ){
if( y4>rUprRight ){
y4 = rUprRight;
}
rUprRight = y4 - TEXT_HEIGHT;
}else{
if( y4>rUprLeft ){
y4 = rUprLeft;
}
rUprLeft = y4 - TEXT_HEIGHT;
}
}else{
if( x4>=cx ){
if( y4<rLwrRight ){
y4 = rLwrRight;
}
rLwrRight = y4 + TEXT_HEIGHT;
}else{
if( y4<rLwrLeft ){
y4 = rLwrLeft;
}
rLwrLeft = y4 + TEXT_HEIGHT;
}
}
if( x4<=cx ){
x5 = x4 - 1.0;
zAnc = "end";
}else{
x5 = x4 + 1.0;
zAnc = "start";
}
y5 = y4 - 3.0 + 6.0*(1.0 - p->rCos);
@ <line stroke='%s(zFg)' stroke-width='1'
@ x1='%g(x3)' y1='%g(y3)' x2='%g(x4)' y2='%g(y4)''/>
@ <text text-anchor="%s(zAnc)"
@ x='%g(x5)' y='%g(y5)' fill='%s(zFg)'>%h(p->z)</text>
fossil_free(p->z);
}
db_finalize(&q);
fossil_free(aWedge);
}
/*
** WEBPAGE: test-piechart
**
** Generate a pie-chart based on data input from a form.
*/
void piechart_test_page(void){
const char *zData;
Stmt ins, q;
Blob all, line, token1, token2;
int n = 0;
int width;
int height;
login_check_credentials();
style_header("Pie Chart Test");
db_multi_exec("CREATE TEMP TABLE piechart(amt REAL, label TEXT);");
db_prepare(&ins, "INSERT INTO piechart(amt,label) VALUES(:amt,:label)");
zData = PD("data","");
width = atoi(PD("width","800"));
height = atoi(PD("height","400"));
blob_init(&all, zData, -1);
while( blob_line(&all, &line) ){
double rAmt;
if( blob_token(&line, &token1)==0 ) continue;
rAmt = atof(blob_str(&token1));
if( rAmt<=0.0 ) continue;
blob_tail(&line, &token2);
db_bind_double(&ins, ":amt", rAmt);
db_bind_text(&ins, ":label", blob_str(&token2));
db_step(&ins);
db_reset(&ins);
n++;
}
db_finalize(&ins);
blob_reset(&all);
if( n>0 ){
@ <svg width=%d(width) height=%d(height) style="border:1px solid #d3d3d3;">
piechart_render(width,height, PIE_OTHER);
@ </svg>
@ <hr>
}
@ <form method="post" action='%R/test-piechart'>
@ <p>One slice per line. Value and then Label.<p>
@ <textarea name='data' rows='20' cols='80'>%h(zData)</textarea><br/>
@ Width: <input type='text' size='8' name='width' value='%d(width)'/>
@ Height: <input type='text' size='8' name='height' value='%d(height)'/><br/>
@ <input type='hidden' name='width' value='%d(width)'/>
@ <input type='hidden' name='height' value='%d(height)'/>
@ <input type='submit' value='Draw The Pie Chart'/>
@ </form>
@ <hr><p>Previous Data:</p>
@ <table border="1">
db_prepare(&q, "SELECT rowid, amt, label FROM piechart");
while( db_step(&q)==SQLITE_ROW ){
@ <tr><td>%d(db_column_int(&q,0))</td>
@ <td>%g(db_column_double(&q,1))</td>
@ <td>%h(db_column_text(&q,2))</td></tr>
}
db_finalize(&q);
@ </table>
style_footer();
}
|
Changes to src/pivot.c.
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
" src BOOLEAN" /* 1 for primary. 0 for others */
");"
"DELETE FROM aqueue;"
"CREATE INDEX IF NOT EXISTS aqueue_idx1 ON aqueue(pending, mtime);"
);
/* Insert the primary record */
| | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
" src BOOLEAN" /* 1 for primary. 0 for others */
");"
"DELETE FROM aqueue;"
"CREATE INDEX IF NOT EXISTS aqueue_idx1 ON aqueue(pending, mtime);"
);
/* Insert the primary record */
db_multi_exec(
"INSERT INTO aqueue(rid, mtime, pending, src)"
" SELECT %d, mtime, 1, 1 FROM event WHERE objid=%d AND type='ci' LIMIT 1",
rid, rid
);
}
/*
** Set a secondary file. The primary file must be set first. There
** must be at least one secondary but there can be more than one if
** desired.
*/
void pivot_set_secondary(int rid){
/* Insert the primary record */
db_multi_exec(
"INSERT OR IGNORE INTO aqueue(rid, mtime, pending, src)"
" SELECT %d, mtime, 1, 0 FROM event WHERE objid=%d AND type='ci'",
rid, rid
);
}
/*
** Find the most recent common ancestor of the primary and one of
** the secondaries. Return its rid. Return 0 if no common ancestor
** can be found.
*/
int pivot_find(void){
Stmt q1, q2, u1, i1;
int rid = 0;
/* aqueue must contain at least one primary and one other. Otherwise
** we abort early
*/
if( db_int(0, "SELECT count(distinct src) FROM aqueue")<2 ){
fossil_fatal("lack both primary and secondary files");
}
|
| ︙ | ︙ |
Changes to src/popen.c.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 | /* ** The following macros are used to cast pointers to integers and ** integers to pointers. The way you do this varies from one compiler ** to the next, so we have developed the following set of #if statements ** to generate appropriate macros for a wide range of compilers. ** | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* ** The following macros are used to cast pointers to integers and ** integers to pointers. The way you do this varies from one compiler ** to the next, so we have developed the following set of #if statements ** to generate appropriate macros for a wide range of compilers. ** ** The correct "ANSI" way to do this is to use the intptr_t type. ** Unfortunately, that typedef is not available on all compilers, or ** if it is available, it requires an #include of specific headers ** that vary from one machine to the next. ** ** This code is copied out of SQLite. */ #if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ |
| ︙ | ︙ | |||
110 111 112 113 114 115 116 | } return rc!=0; } #endif /* ** Create a child process running shell command "zCmd". *ppOut is | | | | | | | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
}
return rc!=0;
}
#endif
/*
** Create a child process running shell command "zCmd". *ppOut is
** a FILE that becomes the standard input of the child process.
** (The caller writes to *ppOut in order to send text to the child.)
** *ppIn is stdout from the child process. (The caller
** reads from *ppIn in order to receive input from the child.)
** Note that *ppIn is an unbuffered file descriptor, not a FILE.
** The process ID of the child is written into *pChildPid.
**
** Return the number of errors.
*/
int popen2(const char *zCmd, int *pfdIn, FILE **ppOut, int *pChildPid){
#ifdef _WIN32
HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr, hStderr;
SECURITY_ATTRIBUTES saAttr;
DWORD childPid = 0;
int fd;
saAttr.nLength = sizeof(saAttr);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
hStderr = GetStdHandle(STD_ERROR_HANDLE);
if( !CreatePipe(&hStdoutRd, &hStdoutWr, &saAttr, 4096) ){
win32_fatal_error("cannot create pipe for stdout");
}
SetHandleInformation( hStdoutRd, HANDLE_FLAG_INHERIT, FALSE);
if( !CreatePipe(&hStdinRd, &hStdinWr, &saAttr, 4096) ){
win32_fatal_error("cannot create pipe for stdin");
}
SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
win32_create_child_process(fossil_utf8_to_unicode(zCmd),
hStdinRd, hStdoutWr, hStderr,&childPid);
*pChildPid = childPid;
*pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
*ppOut = _fdopen(fd, "w");
CloseHandle(hStdinRd);
CloseHandle(hStdoutWr);
return 0;
#else
int pin[2], pout[2];
*pfdIn = 0;
*ppOut = 0;
*pChildPid = 0;
|
| ︙ | ︙ |
Changes to src/rebuild.c.
| ︙ | ︙ | |||
520 521 522 523 524 525 526 | ** Usage: %fossil rebuild ?REPOSITORY? ?OPTIONS? ** ** Reconstruct the named repository database from the core ** records. Run this command after updating the fossil ** executable in a way that changes the database schema. ** ** Options: | | | | > | | | | | | | | | | | | > > > | > | | | | > | 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 |
** Usage: %fossil rebuild ?REPOSITORY? ?OPTIONS?
**
** Reconstruct the named repository database from the core
** records. Run this command after updating the fossil
** executable in a way that changes the database schema.
**
** Options:
** --analyze Run ANALYZE on the database after rebuilding
** --cluster Compute clusters for unclustered artifacts
** --compress Strive to make the database as small as possible
** --compress-only Skip the rebuilding step. Do --compress only
** --deanalyze Remove ANALYZE tables from the database
** --force Force the rebuild to complete even if errors are seen
** --ifneeded Only do the rebuild if it would change the schema version
** --index Always add in the full-text search index
** --noverify Skip the verification of changes to the BLOB table
** --noindex Always omit the full-text search index
** --pagesize N Set the database pagesize to N. (512..65536 and power of 2)
** --randomize Scan artifacts in a random order
** --stats Show artifact statistics after rebuilding
** --vacuum Run VACUUM on the database after rebuilding
** --wal Set Write-Ahead-Log journalling mode on the database
**
** See also: deconstruct, reconstruct
*/
void rebuild_database(void){
int forceFlag;
int randomizeFlag;
int errCnt = 0;
int omitVerify;
int doClustering;
const char *zPagesize;
int newPagesize = 0;
int activateWal;
int runVacuum;
int runDeanalyze;
int runAnalyze;
int runCompress;
int showStats;
int runReindex;
int optNoIndex;
int optIndex;
int optIfNeeded;
int compressOnlyFlag;
omitVerify = find_option("noverify",0,0)!=0;
forceFlag = find_option("force","f",0)!=0;
randomizeFlag = find_option("randomize", 0, 0)!=0;
doClustering = find_option("cluster", 0, 0)!=0;
runVacuum = find_option("vacuum",0,0)!=0;
runDeanalyze = find_option("deanalyze",0,0)!=0;
runAnalyze = find_option("analyze",0,0)!=0;
runCompress = find_option("compress",0,0)!=0;
zPagesize = find_option("pagesize",0,1);
showStats = find_option("stats",0,0)!=0;
optIndex = find_option("index",0,0)!=0;
optNoIndex = find_option("noindex",0,0)!=0;
optIfNeeded = find_option("ifneeded",0,0)!=0;
compressOnlyFlag = find_option("compress-only",0,0)!=0;
if( compressOnlyFlag ) runCompress = runVacuum = 1;
if( zPagesize ){
newPagesize = atoi(zPagesize);
if( newPagesize<512 || newPagesize>65536
|| (newPagesize&(newPagesize-1))!=0
){
fossil_fatal("page size must be a power of two between 512 and 65536");
}
}
activateWal = find_option("wal",0,0)!=0;
if( g.argc==3 ){
db_open_repository(g.argv[2]);
}else{
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
if( g.argc!=2 ){
usage("?REPOSITORY-FILENAME?");
}
db_close(1);
db_open_repository(g.zRepositoryName);
}
runReindex = search_index_exists() && !compressOnlyFlag;
if( optIndex ) runReindex = 1;
if( optNoIndex ) runReindex = 0;
if( optIfNeeded && fossil_strcmp(db_get("aux-schema",""),AUX_SCHEMA_MAX)==0 ){
return;
}
/* We should be done with options.. */
verify_all_options();
db_begin_transaction();
if( !compressOnlyFlag ){
search_drop_index();
ttyOutput = 1;
errCnt = rebuild_db(randomizeFlag, 1, doClustering);
reconstruct_private_table();
}
db_multi_exec(
"REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
"REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
"REPLACE INTO config(name,value,mtime) VALUES('rebuilt',%Q,now());",
CONTENT_SCHEMA, AUX_SCHEMA_MAX, get_version()
);
if( errCnt && !forceFlag ){
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 | static void report_format_hints(void); #ifndef SQLITE_RECURSIVE # define SQLITE_RECURSIVE 33 #endif /* | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
static void report_format_hints(void);
#ifndef SQLITE_RECURSIVE
# define SQLITE_RECURSIVE 33
#endif
/*
** WEBPAGE: reportlist
**
** Main menu for Tickets.
*/
void view_list(void){
const char *zScript;
Blob ril; /* Report Item List */
Stmt q;
|
| ︙ | ︙ | |||
282 283 284 285 286 287 288 |
sqlite3_finalize(pStmt);
}
report_unrestrict_sql();
return zErr;
}
/*
| | > > > > | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
sqlite3_finalize(pStmt);
}
report_unrestrict_sql();
return zErr;
}
/*
** WEBPAGE: rptsql
** URL: /rptsql?rn=N
**
** Display the SQL query used to generate a ticket report. The rn=N
** query parameter identifies the specific report number to be displayed.
*/
void view_see_sql(void){
int rn;
const char *zTitle;
const char *zSQL;
const char *zOwner;
const char *zClrKey;
|
| ︙ | ︙ | |||
330 331 332 333 334 335 336 | @ </tr></table> report_format_hints(); style_footer(); db_finalize(&q); } /* | | | > > > > > > > > > | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
@ </tr></table>
report_format_hints();
style_footer();
db_finalize(&q);
}
/*
** WEBPAGE: rptnew
** WEBPAGE: rptedit
**
** Create (/rptnew) or edit (/rptedit) a ticket report format.
** Query parameters:
**
** rn=N Ticket report number. (required)
** t=TITLE Title of the report format
** w=USER Owner of the report format
** s=SQL SQL text used to implement the report
** k=KEY Color key
*/
void view_edit(void){
int rn;
const char *zTitle;
const char *z;
const char *zOwner;
const char *zClrKey;
|
| ︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 |
@ }
@ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)",%d(iInitSort));
@ </script>
}
/*
| | | < < < < < < | > > | > | > > > > > > > | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 |
@ }
@ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)",%d(iInitSort));
@ </script>
}
/*
** WEBPAGE: rptview
**
** Generate a report. The rn query parameter is the report number
** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
** then the output consists of lines of tab-separated fields instead of
** an HTML table.
*/
void rptview_page(void){
int count = 0;
int rn, rc;
char *zSql;
char *zTitle;
char *zOwner;
char *zClrKey;
int tabs;
Stmt q;
char *zErr1 = 0;
char *zErr2 = 0;
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
tabs = P("tablist")!=0;
db_prepare(&q,
"SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE rn=%d",
atoi(PD("rn","0")));
rc = db_step(&q);
if( rc!=SQLITE_ROW ){
db_finalize(&q);
db_prepare(&q,
"SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE title GLOB %Q",
P("title"));
rc = db_step(&q);
}
if( rc!=SQLITE_ROW ){
db_finalize(&q);
cgi_redirect("reportlist");
return;
}
zTitle = db_column_malloc(&q, 0);
zSql = db_column_malloc(&q, 1);
zOwner = db_column_malloc(&q, 2);
zClrKey = db_column_malloc(&q, 3);
rn = db_column_int(&q,4);
db_finalize(&q);
if( P("order_by") ){
/*
** If the user wants to do a column sort, wrap the query into a sub
** query and then sort the results. This is a whole lot easier than
** trying to insert an ORDER BY into the query itself, especially
|
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
247 248 249 250 251 252 253 | @ -- fid = File ID. @ -- pmid = Parent Manifest ID. @ -- pid = Parent file ID. @ -- fnid = File Name ID. @ -- pfnid = Parent File Name ID. @ -- isaux = pmid IS AUXiliary parent, not primary parent @ -- | | > > | | | | | | | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | @ -- fid = File ID. @ -- pmid = Parent Manifest ID. @ -- pid = Parent file ID. @ -- fnid = File Name ID. @ -- pfnid = Parent File Name ID. @ -- isaux = pmid IS AUXiliary parent, not primary parent @ -- @ -- pid==0 if the file is added by check-in mid. @ -- pid==(-1) if the file exists in a merge parents but not in the primary @ -- parent. In other words, if the file file was added by merge. @ -- fid==0 if the file is removed by check-in mid. @ -- @ CREATE TABLE mlink( @ mid INTEGER, -- Check-in that contains fid @ fid INTEGER, -- New file content. 0 if deleted @ pmid INTEGER, -- Check-in that contains pid @ pid INTEGER, -- Prev file content. 0 if new. -1 merge @ fnid INTEGER REFERENCES filename, -- Name of the file @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged @ mperm INTEGER, -- File permissions. 1==exec @ isaux BOOLEAN DEFAULT 0 -- TRUE if pmid is the primary @ ); @ CREATE INDEX mlink_i1 ON mlink(mid); @ CREATE INDEX mlink_i2 ON mlink(fnid); @ CREATE INDEX mlink_i3 ON mlink(fid); @ CREATE INDEX mlink_i4 ON mlink(pid); @ @ -- Parent/child linkages between check-ins |
| ︙ | ︙ | |||
365 366 367 368 369 370 371 372 373 374 375 376 377 378 | @ INSERT INTO tag VALUES(4, 'date'); -- TAG_DATE @ INSERT INTO tag VALUES(5, 'hidden'); -- TAG_HIDDEN @ INSERT INTO tag VALUES(6, 'private'); -- TAG_PRIVATE @ INSERT INTO tag VALUES(7, 'cluster'); -- TAG_CLUSTER @ INSERT INTO tag VALUES(8, 'branch'); -- TAG_BRANCH @ INSERT INTO tag VALUES(9, 'closed'); -- TAG_CLOSED @ INSERT INTO tag VALUES(10,'parent'); -- TAG_PARENT @ @ -- Assignments of tags to baselines. Note that we allow tags to @ -- have values assigned to them. So we are not really dealing with @ -- tags here. These are really properties. But we are going to @ -- keep calling them tags because in many cases the value is ignored. @ -- @ CREATE TABLE tagxref( | > | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | @ INSERT INTO tag VALUES(4, 'date'); -- TAG_DATE @ INSERT INTO tag VALUES(5, 'hidden'); -- TAG_HIDDEN @ INSERT INTO tag VALUES(6, 'private'); -- TAG_PRIVATE @ INSERT INTO tag VALUES(7, 'cluster'); -- TAG_CLUSTER @ INSERT INTO tag VALUES(8, 'branch'); -- TAG_BRANCH @ INSERT INTO tag VALUES(9, 'closed'); -- TAG_CLOSED @ INSERT INTO tag VALUES(10,'parent'); -- TAG_PARENT @ INSERT INTO tag VALUES(11,'note'); -- TAG_NOTE @ @ -- Assignments of tags to baselines. Note that we allow tags to @ -- have values assigned to them. So we are not really dealing with @ -- tags here. These are really properties. But we are going to @ -- keep calling them tags because in many cases the value is ignored. @ -- @ CREATE TABLE tagxref( |
| ︙ | ︙ | |||
464 465 466 467 468 469 470 | # define TAG_DATE 4 /* The date of a check-in */ # define TAG_HIDDEN 5 /* Do not display in timeline */ # define TAG_PRIVATE 6 /* Do not sync */ # define TAG_CLUSTER 7 /* A cluster */ # define TAG_BRANCH 8 /* Value is name of the current branch */ # define TAG_CLOSED 9 /* Do not display this check-in as a leaf */ # define TAG_PARENT 10 /* Change to parentage on a check-in */ | < < | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | # define TAG_DATE 4 /* The date of a check-in */ # define TAG_HIDDEN 5 /* Do not display in timeline */ # define TAG_PRIVATE 6 /* Do not sync */ # define TAG_CLUSTER 7 /* A cluster */ # define TAG_BRANCH 8 /* Value is name of the current branch */ # define TAG_CLOSED 9 /* Do not display this check-in as a leaf */ # define TAG_PARENT 10 /* Change to parentage on a check-in */ # define TAG_NOTE 11 /* Extra text appended to a check-in comment */ #endif /* ** The schema for the local FOSSIL database file found at the root ** of every check-out. This database contains the complete state of ** the checkout. */ |
| ︙ | ︙ |
Changes to src/search.c.
| ︙ | ︙ | |||
100 101 102 103 104 105 106 |
if( p!=&gSearch ) fossil_free(p);
}
}
/*
** Compile a search pattern
*/
| | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
if( p!=&gSearch ) fossil_free(p);
}
}
/*
** Compile a search pattern
*/
static Search *search_init(
const char *zPattern, /* The search pattern */
const char *zMarkBegin, /* Start of a match */
const char *zMarkEnd, /* End of a match */
const char *zMarkGap, /* A gap between two matches */
unsigned fSrchFlg /* Flags */
){
Search *p;
|
| ︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 |
@ <p class='searchEmpty'>No matches for: <span>%h(zPattern)</span></p>
}
@ </div>
}
}
/*
| | > > > > > > > > | 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 |
@ <p class='searchEmpty'>No matches for: <span>%h(zPattern)</span></p>
}
@ </div>
}
}
/*
** WEBPAGE: search
**
** Search for check-in comments, documents, tickets, or wiki that
** match a user-supplied pattern.
**
** s=PATTERN Specify the full-text pattern to search for
** y=TYPE What to search.
** c -> check-ins
** d -> documentation
** t -> tickets
** w -> wiki
** all -> everything
*/
void search_page(void){
login_check_credentials();
style_header("Search");
search_screen(SRCH_ALL, 1);
style_footer();
}
|
| ︙ | ︙ | |||
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 |
html_to_plaintext(blob_str(&html), pOut);
}else if( fossil_strcmp(zMimetype,"text/html")==0 ){
if( doc_is_embedded_html(pIn, &title) ){
blob_appendf(pOut, "%s\n", blob_str(&title));
}
html_to_plaintext(blob_str(pIn), pOut);
}else{
blob_append(pOut, blob_buffer(pIn), blob_size(pIn));
}
blob_reset(&html);
blob_reset(&title);
}
/*
| > | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 |
html_to_plaintext(blob_str(&html), pOut);
}else if( fossil_strcmp(zMimetype,"text/html")==0 ){
if( doc_is_embedded_html(pIn, &title) ){
blob_appendf(pOut, "%s\n", blob_str(&title));
}
html_to_plaintext(blob_str(pIn), pOut);
}else{
blob_append(pOut, "\n", 1);
blob_append(pOut, blob_buffer(pIn), blob_size(pIn));
}
blob_reset(&html);
blob_reset(&title);
}
/*
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
52 53 54 55 56 57 58 | } @ </td><td width="5"></td><td valign="top">%h(zDesc)</td></tr> } /* | | > > | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
}
@ </td><td width="5"></td><td valign="top">%h(zDesc)</td></tr>
}
/*
** WEBPAGE: setup
**
** Main menu for the administrative pages. Requires Admin privileges.
*/
void setup_page(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
}
style_header("Server Administration");
/* Make sure the header contains <base href="...">. Issue a warning
** if it does not. */
if( !cgi_header_contains("<base href=") ){
@ <p class="generalError"><b>Configuration Error:</b> Please add
@ <tt><base href="$secureurl/$current_page"></tt> after
@ <tt><head></tt> in the <a href="setup_skinedit?w=2">HTML header</a>!</p>
}
#if !defined(_WIN32)
/* Check for /dev/null and /dev/urandom. We want both devices to be present,
** but they are sometimes omitted (by mistake) from chroot jails. */
if( access("/dev/null", R_OK|W_OK) ){
@ <p class="generalError">WARNING: Device "/dev/null" is not available
|
| ︙ | ︙ | |||
105 106 107 108 109 110 111 |
setup_menu_entry("Tickets", "tktsetup",
"Configure the trouble-ticketing system for this repository");
setup_menu_entry("Search","srchsetup",
"Configure the built-in search engine");
setup_menu_entry("Transfers", "xfersetup",
"Configure the transfer system for this repository");
setup_menu_entry("Skins", "setup_skin",
| | < < < < < < | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
setup_menu_entry("Tickets", "tktsetup",
"Configure the trouble-ticketing system for this repository");
setup_menu_entry("Search","srchsetup",
"Configure the built-in search engine");
setup_menu_entry("Transfers", "xfersetup",
"Configure the transfer system for this repository");
setup_menu_entry("Skins", "setup_skin",
"Select and/or modify the web interface \"skins\"");
setup_menu_entry("Moderation", "setup_modreq",
"Enable/Disable requiring moderator approval of Wiki and/or Ticket"
" changes and attachments.");
setup_menu_entry("Ad-Unit", "setup_adunit",
"Edit HTML text for an ad unit inserted after the menu bar");
setup_menu_entry("Logo", "setup_logo",
"Change the logo and background images for the server");
setup_menu_entry("Shunned", "shun",
"Show artifacts that are shunned by this repository");
setup_menu_entry("Artifact Receipts Log", "rcvfromlist",
"A record of received artifacts and their sources");
setup_menu_entry("User Log", "access_log",
"A record of login attempts");
setup_menu_entry("Administrative Log", "admin_log",
"View the admin_log entries");
setup_menu_entry("Sitemap", "sitemap",
"Links to miscellaneous pages");
setup_menu_entry("SQL", "admin_sql",
"Enter raw SQL commands");
setup_menu_entry("TH1", "admin_th1",
"Enter raw TH1 commands");
@ </table>
style_footer();
}
/*
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user. Requires Admin privileges.
*/
void setup_ulist(void){
Stmt s;
int prevLevel = 0;
login_check_credentials();
if( !g.perm.Admin ){
|
| ︙ | ︙ | |||
317 318 319 320 321 322 323 |
if( zPw==0 ) return 0;
if( zPw[0]==0 ) return 1;
while( zPw[0]=='*' ){ zPw++; }
return zPw[0]!=0;
}
/*
| | > > > | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
if( zPw==0 ) return 0;
if( zPw[0]==0 ) return 1;
while( zPw[0]=='*' ){ zPw++; }
return zPw[0]!=0;
}
/*
** WEBPAGE: setup_uedit
**
** Edit information about a user or create a new user.
** Requires Admin privileges.
*/
void user_edit(void){
const char *zId, *zLogin, *zInfo, *zCap, *zPw;
const char *zGroup;
const char *zOldLogin;
int doWrite;
int uid, i;
|
| ︙ | ︙ | |||
928 929 930 931 932 933 934 | } @ /> <b>%s(zLabel)</b> } /* ** Generate a text box for an attribute. */ | | | 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 | } @ /> <b>%s(zLabel)</b> } /* ** Generate a text box for an attribute. */ const char *textarea_attribute( const char *zLabel, /* The text label on the textarea */ int rows, /* Rows in the textarea */ int cols, /* Columns in the textarea */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQP, /* The query parameter */ const char *zDflt, /* Default value if VAR table entry does not exist */ int disabled /* 1 if the textarea should not be editable */ |
| ︙ | ︙ | |||
957 958 959 960 961 962 963 964 965 966 967 968 969 970 |
@ disabled="disabled"
}
@ cols="%d(cols)">%h(z)</textarea>
if( zLabel && *zLabel ){
@ <span class="textareaLabel">%s(zLabel)</span>
}
}
}
/*
** Generate a text box for an attribute.
*/
static void multiple_choice_attribute(
const char *zLabel, /* The text label on the menu */
| > | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 |
@ disabled="disabled"
}
@ cols="%d(cols)">%h(z)</textarea>
if( zLabel && *zLabel ){
@ <span class="textareaLabel">%s(zLabel)</span>
}
}
return z;
}
/*
** Generate a text box for an attribute.
*/
static void multiple_choice_attribute(
const char *zLabel, /* The text label on the menu */
|
| ︙ | ︙ | |||
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 |
}
@ </select> <b>%h(zLabel)</b>
}
/*
** WEBPAGE: setup_access
*/
void setup_access(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
| > > | 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 |
}
@ </select> <b>%h(zLabel)</b>
}
/*
** WEBPAGE: setup_access
**
** The access-control settings page. Requires Admin privileges.
*/
void setup_access(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ | |||
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 |
@ </div></form>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_login_group
*/
void setup_login_group(void){
const char *zGroup;
char *zErrMsg = 0;
Blob fullName;
char *zSelfRepo;
const char *zRepo = PD("repo", "");
| > > > | 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 |
@ </div></form>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_login_group
**
** Change how the current repository participates in a login
** group.
*/
void setup_login_group(void){
const char *zGroup;
char *zErrMsg = 0;
Blob fullName;
char *zSelfRepo;
const char *zRepo = PD("repo", "");
|
| ︙ | ︙ | |||
1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 |
output_table_sorting_javascript("configTab","ttt",1);
}
style_footer();
}
/*
** WEBPAGE: setup_timeline
*/
void setup_timeline(void){
double tmDiff;
char zTmDiff[20];
static const char *const azTimeFormats[] = {
"0", "HH:MM",
"1", "HH:MM:SS",
| > > > | 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 |
output_table_sorting_javascript("configTab","ttt",1);
}
style_footer();
}
/*
** WEBPAGE: setup_timeline
**
** Edit administrative settings controlling the display of
** timelines.
*/
void setup_timeline(void){
double tmDiff;
char zTmDiff[20];
static const char *const azTimeFormats[] = {
"0", "HH:MM",
"1", "HH:MM:SS",
|
| ︙ | ︙ | |||
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 |
@ </div></form>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_settings
*/
void setup_settings(void){
Setting const *pSet;
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
| > > > | 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 |
@ </div></form>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_settings
**
** Change or view miscellanous settings. Part of the
** Admin pages requiring Admin privileges.
*/
void setup_settings(void){
Setting const *pSet;
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
|
| ︙ | ︙ | |||
1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 |
@ </p><pre>%s(zHelp_setting_cmd)</pre>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_config
*/
void setup_config(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
| > > | 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 |
@ </p><pre>%s(zHelp_setting_cmd)</pre>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_config
**
** The "Admin/Configuration" page. Requires Admin privilege.
*/
void setup_config(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ | |||
1548 1549 1550 1551 1552 1553 1554 1555 | @ <hr /> @ <p><input type="submit" name="submit" value="Apply Changes" /></p> @ </div></form> db_end_transaction(0); style_footer(); } /* | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 |
@ <hr />
@ <p><input type="submit" name="submit" value="Apply Changes" /></p>
@ </div></form>
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_modreq
**
** Admin page for setting up moderation of tickets and wiki.
*/
void setup_modreq(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ | |||
1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 |
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_adunit
*/
void setup_adunit(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
| > > > | 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 |
db_end_transaction(0);
style_footer();
}
/*
** WEBPAGE: setup_adunit
**
** Administrative page for configuring and controlling ad units
** and how they are displayed.
*/
void setup_adunit(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ | |||
1781 1782 1783 1784 1785 1786 1787 | @ </div></form> @ <hr /> @ <b>Ad-Unit Notes:</b><ul> @ <li>Leave both Ad-Units blank to disable all advertising. @ <li>The "Banner Ad-Unit" is used for wide pages. @ <li>The "Right-Column Ad-Unit" is used on pages with tall, narrow content. @ <li>If the "Right-Column Ad-Unit" is blank, the "Banner Ad-Unit" is used on all pages. | | | 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 |
@ </div></form>
@ <hr />
@ <b>Ad-Unit Notes:</b><ul>
@ <li>Leave both Ad-Units blank to disable all advertising.
@ <li>The "Banner Ad-Unit" is used for wide pages.
@ <li>The "Right-Column Ad-Unit" is used on pages with tall, narrow content.
@ <li>If the "Right-Column Ad-Unit" is blank, the "Banner Ad-Unit" is used on all pages.
@ <li>Suggested <a href="setup_skinedit?w=0">CSS</a> changes:
@ <blockquote><pre>
@ div.adunit_banner {
@ margin: auto;
@ width: 100%;
@ }
@ div.adunit_right {
@ float: right;
|
| ︙ | ︙ | |||
1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 |
@ </li>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: setup_logo
*/
void setup_logo(void){
const char *zLogoMtime = db_get_mtime("logo-image", 0, 0);
const char *zLogoMime = db_get("logo-mimetype","image/gif");
const char *aLogoImg = P("logoim");
int szLogoImg = atoi(PD("logoim:bytes","0"));
const char *zBgMtime = db_get_mtime("background-image", 0, 0);
| > > | 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 |
@ </li>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: setup_logo
**
** Administrative page for changing the logo image.
*/
void setup_logo(void){
const char *zLogoMtime = db_get_mtime("logo-image", 0, 0);
const char *zLogoMime = db_get("logo-mimetype","image/gif");
const char *aLogoImg = P("logoim");
int szLogoImg = atoi(PD("logoim:bytes","0"));
const char *zBgMtime = db_get_mtime("background-image", 0, 0);
|
| ︙ | ︙ | |||
1895 1896 1897 1898 1899 1900 1901 | @ </p></blockquote> @ @ <form action="%s(g.zTop)/setup_logo" method="post" @ enctype="multipart/form-data"><div> @ <p>The logo is accessible to all users at this URL: @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>. @ The logo may or may not appear on each | | | | | | 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 | @ </p></blockquote> @ @ <form action="%s(g.zTop)/setup_logo" method="post" @ enctype="multipart/form-data"><div> @ <p>The logo is accessible to all users at this URL: @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>. @ The logo may or may not appear on each @ page depending on the <a href="setup_skinedit?w=0">CSS</a> and @ <a href="setup_skinedit?w=2">header setup</a>. @ To change the logo image, use the following form:</p> login_insert_csrf_secret(); @ Logo Image file: @ <input type="file" name="logoim" size="60" accept="image/*" /> @ <p align="center"> @ <input type="submit" name="setlogo" value="Change Logo" /> @ <input type="submit" name="clrlogo" value="Revert To Default" /></p> @ </div></form> @ <hr /> @ @ <p>The current background image has a MIME-Type of <b>%h(zBgMime)</b> @ and looks like this:</p> @ <blockquote><p><img src="%s(g.zTop)/background/%z(zBgMtime)" alt="background" border=1 /> @ </p></blockquote> @ @ <form action="%s(g.zTop)/setup_logo" method="post" @ enctype="multipart/form-data"><div> @ <p>The background image is accessible to all users at this URL: @ <a href="%s(g.zBaseURL)/background">%s(g.zBaseURL)/background</a>. @ The background image may or may not appear on each @ page depending on the <a href="setup_skinedit?w=0">CSS</a> and @ <a href="setup_skinedit?w=2">header setup</a>. @ To change the background image, use the following form:</p> login_insert_csrf_secret(); @ Background image file: @ <input type="file" name="bgim" size="60" accept="image/*" /> @ <p align="center"> @ <input type="submit" name="setbg" value="Change Background" /> @ <input type="submit" name="clrbg" value="Revert To Default" /></p> |
| ︙ | ︙ | |||
1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 |
}
/*
** WEBPAGE: admin_sql
**
** Run raw SQL commands against the database file using the web interface.
*/
void sql_page(void){
const char *zQ = P("q");
int go = P("go")!=0;
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
| > | 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 |
}
/*
** WEBPAGE: admin_sql
**
** Run raw SQL commands against the database file using the web interface.
** Requires Admin privileges.
*/
void sql_page(void){
const char *zQ = P("q");
int go = P("go")!=0;
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
|
| ︙ | ︙ | |||
2085 2086 2087 2088 2089 2090 2091 | /* ** WEBPAGE: admin_th1 ** ** Run raw TH1 commands using the web interface. If Tcl integration was ** enabled at compile-time and the "tcl" setting is enabled, Tcl commands | | | 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 |
/*
** WEBPAGE: admin_th1
**
** Run raw TH1 commands using the web interface. If Tcl integration was
** enabled at compile-time and the "tcl" setting is enabled, Tcl commands
** may be run as well. Requires Admin privilege.
*/
void th1_page(void){
const char *zQ = P("q");
int go = P("go")!=0;
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
|
| ︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | } style_footer(); } /* ** WEBPAGE: srchsetup ** | | | 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 |
}
style_footer();
}
/*
** WEBPAGE: srchsetup
**
** Configure the search engine. Requires Admin privilege.
*/
void page_srchsetup(){
login_check_credentials();
if( !g.perm.Setup && !g.perm.Admin ){
login_needed(0);
return;
}
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
332 333 334 335 336 337 338 | static int stdin_is_interactive = 1; /* ** The following is the open SQLite database. We make a pointer ** to this database a static variable so that it can be accessed ** by the SIGINT handler to interrupt database processing. */ | | | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | static int stdin_is_interactive = 1; /* ** The following is the open SQLite database. We make a pointer ** to this database a static variable so that it can be accessed ** by the SIGINT handler to interrupt database processing. */ static sqlite3 *globalDb = 0; /* ** True if an interrupt (Control-C) has been received. */ static volatile int seenInterrupt = 0; /* |
| ︙ | ︙ | |||
366 367 368 369 370 371 372 | /* ** This routine works like printf in that its first argument is a ** format string and subsequent arguments are values to be substituted ** in place of % fields. The result of formatting this string ** is written to iotrace. */ #ifdef SQLITE_ENABLE_IOTRACE | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
/*
** This routine works like printf in that its first argument is a
** format string and subsequent arguments are values to be substituted
** in place of % fields. The result of formatting this string
** is written to iotrace.
*/
#ifdef SQLITE_ENABLE_IOTRACE
static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
va_list ap;
char *z;
if( iotrace==0 ) return;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
fprintf(iotrace, "%s", z);
|
| ︙ | ︙ | |||
523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
typedef struct ShellState ShellState;
struct ShellState {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
int statsOn; /* True to display memory stats before each finalize */
int scanstatsOn; /* True to display scan stats before each finalize */
int outCount; /* Revert to stdout when reaching zero */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
FILE *traceOut; /* Output for sqlite3_trace() */
int nErr; /* Number of errors seen */
int mode; /* An output mode setting */
int writableSchema; /* True if PRAGMA writable_schema=ON */
| > | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 |
typedef struct ShellState ShellState;
struct ShellState {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
int statsOn; /* True to display memory stats before each finalize */
int scanstatsOn; /* True to display scan stats before each finalize */
int backslashOn; /* Resolve C-style \x escapes in SQL input text */
int outCount; /* Revert to stdout when reaching zero */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
FILE *traceOut; /* Output for sqlite3_trace() */
int nErr; /* Number of errors seen */
int mode; /* An output mode setting */
int writableSchema; /* True if PRAGMA writable_schema=ON */
|
| ︙ | ︙ | |||
800 801 802 803 804 805 806 |
/*
** This routine runs when the user presses Ctrl-C
*/
static void interrupt_handler(int NotUsed){
UNUSED_PARAMETER(NotUsed);
seenInterrupt++;
if( seenInterrupt>2 ) exit(1);
| | | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 |
/*
** This routine runs when the user presses Ctrl-C
*/
static void interrupt_handler(int NotUsed){
UNUSED_PARAMETER(NotUsed);
seenInterrupt++;
if( seenInterrupt>2 ) exit(1);
if( globalDb ) sqlite3_interrupt(globalDb);
}
#endif
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
|
| ︙ | ︙ | |||
985 986 987 988 989 990 991 |
}
setTextMode(p->out);
break;
}
case MODE_Insert: {
p->cnt++;
if( azArg==0 ) break;
| | > > > > > > > > > | 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 |
}
setTextMode(p->out);
break;
}
case MODE_Insert: {
p->cnt++;
if( azArg==0 ) break;
fprintf(p->out,"INSERT INTO %s",p->zDestTable);
if( p->showHeader ){
fprintf(p->out,"(");
for(i=0; i<nArg; i++){
char *zSep = i>0 ? ",": "";
fprintf(p->out, "%s%s", zSep, azCol[i]);
}
fprintf(p->out,")");
}
fprintf(p->out," VALUES(");
for(i=0; i<nArg; i++){
char *zSep = i>0 ? ",": "";
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
fprintf(p->out,"%sNULL",zSep);
}else if( aiType && aiType[i]==SQLITE_TEXT ){
if( zSep[0] ) fprintf(p->out,"%s",zSep);
output_quoted_string(p->out, azArg[i]);
|
| ︙ | ︙ | |||
1186 1187 1188 1189 1190 1191 1192 |
/*
** Allocate space and save off current error string.
*/
static char *save_err_msg(
sqlite3 *db /* Database to query */
){
int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
| | | 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 |
/*
** Allocate space and save off current error string.
*/
static char *save_err_msg(
sqlite3 *db /* Database to query */
){
int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
char *zErrMsg = sqlite3_malloc64(nErrMsg);
if( zErrMsg ){
memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
}
return zErrMsg;
}
/*
|
| ︙ | ︙ | |||
1423 1424 1425 1426 1427 1428 1429 |
** SQL trigger or foreign key. */
int p2 = sqlite3_column_int(pSql, 3);
int p2op = (p2 + (iOp-iAddr));
/* Grow the p->aiIndent array as required */
if( iOp>=nAlloc ){
nAlloc += 100;
| | | | 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 |
** SQL trigger or foreign key. */
int p2 = sqlite3_column_int(pSql, 3);
int p2op = (p2 + (iOp-iAddr));
/* Grow the p->aiIndent array as required */
if( iOp>=nAlloc ){
nAlloc += 100;
p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
}
abYield[iOp] = str_in_array(zOp, azYield);
p->aiIndent[iOp] = 0;
p->nIndent = iOp+1;
if( str_in_array(zOp, azNext) ){
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
|
| ︙ | ︙ | |||
1541 1542 1543 1544 1545 1546 1547 |
rc = sqlite3_step(pStmt);
/* if we have a result set... */
if( SQLITE_ROW == rc ){
/* if we have a callback... */
if( xCallback ){
/* allocate space for col name ptr, value ptr, and type */
int nCol = sqlite3_column_count(pStmt);
| | | 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 |
rc = sqlite3_step(pStmt);
/* if we have a result set... */
if( SQLITE_ROW == rc ){
/* if we have a callback... */
if( xCallback ){
/* allocate space for col name ptr, value ptr, and type */
int nCol = sqlite3_column_count(pStmt);
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
if( !pData ){
rc = SQLITE_NOMEM;
}else{
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i, x;
|
| ︙ | ︙ | |||
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | /* ** Text of a help message */ static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".bail on|off Stop after hitting an error. Default OFF\n" ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\n" ".dbinfo ?DB? Show status information about the database\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" " LIKE pattern TABLE.\n" ".echo on|off Turn command echo on or off\n" | > | 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 | /* ** Text of a help message */ static char zHelp[] = ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".bail on|off Stop after hitting an error. Default OFF\n" ".binary on|off Turn binary output on or off. Default OFF\n" ".clone NEWDB Clone data into NEWDB from the existing database\n" ".databases List names and files of attached databases\n" ".dbinfo ?DB? Show status information about the database\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" " If TABLE specified, only dump tables matching\n" " LIKE pattern TABLE.\n" ".echo on|off Turn command echo on or off\n" |
| ︙ | ︙ | |||
1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 | ".import FILE TABLE Import data from FILE into TABLE\n" ".indexes ?TABLE? Show names of all indexes\n" " If TABLE specified, only show indexes for tables\n" " matching LIKE pattern TABLE.\n" #ifdef SQLITE_ENABLE_IOTRACE ".iotrace FILE Enable I/O diagnostic logging to FILE\n" #endif #ifndef SQLITE_OMIT_LOAD_EXTENSION ".load FILE ?ENTRY? Load an extension library\n" #endif ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " ascii Columns/rows delimited by 0x1F and 0x1E\n" " csv Comma-separated values\n" | > | 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 | ".import FILE TABLE Import data from FILE into TABLE\n" ".indexes ?TABLE? Show names of all indexes\n" " If TABLE specified, only show indexes for tables\n" " matching LIKE pattern TABLE.\n" #ifdef SQLITE_ENABLE_IOTRACE ".iotrace FILE Enable I/O diagnostic logging to FILE\n" #endif ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" #ifndef SQLITE_OMIT_LOAD_EXTENSION ".load FILE ?ENTRY? Load an extension library\n" #endif ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " ascii Columns/rows delimited by 0x1F and 0x1E\n" " csv Comma-separated values\n" |
| ︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 | zName = (const char*)sqlite3_value_text(argv[0]); if( zName==0 ) return; in = fopen(zName, "rb"); if( in==0 ) return; fseek(in, 0, SEEK_END); nIn = ftell(in); rewind(in); | | | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 |
zName = (const char*)sqlite3_value_text(argv[0]);
if( zName==0 ) return;
in = fopen(zName, "rb");
if( in==0 ) return;
fseek(in, 0, SEEK_END);
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc64( nIn );
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
}else{
sqlite3_free(pBuf);
}
fclose(in);
}
|
| ︙ | ︙ | |||
1904 1905 1906 1907 1908 1909 1910 |
** Make sure the database is open. If it is not, then open it. If
** the database fails to open, print an error message and exit.
*/
static void open_db(ShellState *p, int keepAlive){
if( p->db==0 ){
sqlite3_initialize();
sqlite3_open(p->zDbFilename, &p->db);
| | | | | | | | > > > > > | > | | | > > > > > > > > > > > > | 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 |
** Make sure the database is open. If it is not, then open it. If
** the database fails to open, print an error message and exit.
*/
static void open_db(ShellState *p, int keepAlive){
if( p->db==0 ){
sqlite3_initialize();
sqlite3_open(p->zDbFilename, &p->db);
globalDb = p->db;
if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
shellstaticFunc, 0, 0);
}
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
p->zDbFilename, sqlite3_errmsg(p->db));
if( keepAlive ) return;
exit(1);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
sqlite3_enable_load_extension(p->db, 1);
#endif
sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
readfileFunc, 0, 0);
sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
writefileFunc, 0, 0);
}
}
/*
** Do C-language style dequoting.
**
** \a -> alarm
** \b -> backspace
** \t -> tab
** \n -> newline
** \v -> vertical tab
** \f -> form feed
** \r -> carriage return
** \s -> space
** \" -> "
** \' -> '
** \\ -> backslash
** \NNN -> ascii character NNN in octal
*/
static void resolve_backslashes(char *z){
int i, j;
char c;
while( *z && *z!='\\' ) z++;
for(i=j=0; (c = z[i])!=0; i++, j++){
if( c=='\\' && z[i+1]!=0 ){
c = z[++i];
if( c=='a' ){
c = '\a';
}else if( c=='b' ){
c = '\b';
}else if( c=='t' ){
c = '\t';
}else if( c=='n' ){
c = '\n';
}else if( c=='v' ){
c = '\v';
}else if( c=='f' ){
c = '\f';
}else if( c=='r' ){
c = '\r';
}else if( c=='"' ){
c = '"';
}else if( c=='\'' ){
c = '\'';
}else if( c=='\\' ){
c = '\\';
}else if( c>='0' && c<='7' ){
c -= '0';
if( z[i+1]>='0' && z[i+1]<='7' ){
i++;
c = (c<<3) + z[i] - '0';
|
| ︙ | ︙ | |||
2117 2118 2119 2120 2121 2122 2123 |
int cRowSep; /* The row separator character. (Usually "\n") */
};
/* Append a single byte to z[] */
static void import_append_char(ImportCtx *p, int c){
if( p->n+1>=p->nAlloc ){
p->nAlloc += p->nAlloc + 100;
| | | | 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 |
int cRowSep; /* The row separator character. (Usually "\n") */
};
/* Append a single byte to z[] */
static void import_append_char(ImportCtx *p, int c){
if( p->n+1>=p->nAlloc ){
p->nAlloc += p->nAlloc + 100;
p->z = sqlite3_realloc64(p->z, p->nAlloc);
if( p->z==0 ){
fprintf(stderr, "out of memory\n");
exit(1);
}
}
p->z[p->n++] = (char)c;
}
/* Read a single field of CSV text. Compatible with rfc4180 and extended
** with the option of having a separator other than ",".
**
** + Input comes from p->in.
** + Store results in p->z of length p->n. Space to hold p->z comes
** from sqlite3_malloc64().
** + Use p->cSep as the column separator. The default is ",".
** + Use p->rSep as the row separator. The default is "\n".
** + Keep track of the line number in p->nLine.
** + Store the character that terminates the field in p->cTerm. Store
** EOF on end-of-file.
** + Report syntax errors on stderr
*/
|
| ︙ | ︙ | |||
2205 2206 2207 2208 2209 2210 2211 | return p->z; } /* Read a single field of ASCII delimited text. ** ** + Input comes from p->in. ** + Store results in p->z of length p->n. Space to hold p->z comes | | | 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 | return p->z; } /* Read a single field of ASCII delimited text. ** ** + Input comes from p->in. ** + Store results in p->z of length p->n. Space to hold p->z comes ** from sqlite3_malloc64(). ** + Use p->cSep as the column separator. The default is "\x1F". ** + Use p->rSep as the row separator. The default is "\x1E". ** + Keep track of the row number in p->nLine. ** + Store the character that terminates the field in p->cTerm. Store ** EOF on end-of-file. ** + Report syntax errors on stderr */ |
| ︙ | ︙ | |||
2265 2266 2267 2268 2269 2270 2271 |
if( rc ){
fprintf(stderr, "Error %d: %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_data_xfer;
}
n = sqlite3_column_count(pQuery);
| | | 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 |
if( rc ){
fprintf(stderr, "Error %d: %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_data_xfer;
}
n = sqlite3_column_count(pQuery);
zInsert = sqlite3_malloc64(200 + nTable + n*3);
if( zInsert==0 ){
fprintf(stderr, "out of memory\n");
goto end_data_xfer;
}
sqlite3_snprintf(200+nTable,zInsert,
"INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
i = (int)strlen(zInsert);
|
| ︙ | ︙ | |||
2581 2582 2583 2584 2585 2586 2587 |
/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int do_meta_command(char *zLine, ShellState *p){
| | | | | | | | | | | | | | | | | 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 |
/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int do_meta_command(char *zLine, ShellState *p){
int h = 1;
int nArg = 0;
int n, c;
int rc = 0;
char *azArg[50];
/* Parse the input line into tokens.
*/
while( zLine[h] && nArg<ArraySize(azArg) ){
while( IsSpace(zLine[h]) ){ h++; }
if( zLine[h]==0 ) break;
if( zLine[h]=='\'' || zLine[h]=='"' ){
int delim = zLine[h++];
azArg[nArg++] = &zLine[h];
while( zLine[h] && zLine[h]!=delim ){
if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
h++;
}
if( zLine[h]==delim ){
zLine[h++] = 0;
}
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
}else{
azArg[nArg++] = &zLine[h];
while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
if( zLine[h] ) zLine[h++] = 0;
resolve_backslashes(azArg[nArg-1]);
}
}
/* Process the input line.
*/
if( nArg==0 ) return 0; /* no tokens, no error */
|
| ︙ | ︙ | |||
2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 |
if( nArg==2 ){
bail_on_error = booleanValue(azArg[1]);
}else{
fprintf(stderr, "Usage: .bail on|off\n");
rc = 1;
}
}else
/* The undocumented ".breakpoint" command causes a call to the no-op
** routine named test_breakpoint().
*/
if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
test_breakpoint();
}else
| > > > > > > > > > > > > > | 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 |
if( nArg==2 ){
bail_on_error = booleanValue(azArg[1]);
}else{
fprintf(stderr, "Usage: .bail on|off\n");
rc = 1;
}
}else
if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
if( nArg==2 ){
if( booleanValue(azArg[1]) ){
setBinaryMode(p->out);
}else{
setTextMode(p->out);
}
}else{
fprintf(stderr, "Usage: .binary on|off\n");
rc = 1;
}
}else
/* The undocumented ".breakpoint" command causes a call to the no-op
** routine named test_breakpoint().
*/
if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
test_breakpoint();
}else
|
| ︙ | ︙ | |||
2982 2983 2984 2985 2986 2987 2988 |
fprintf(stderr, "Error: out of memory\n");
xCloser(sCtx.in);
return 1;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
| | | | | | | | | 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 |
fprintf(stderr, "Error: out of memory\n");
xCloser(sCtx.in);
return 1;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
while( xRead(&sCtx) ){
zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
cSep = ',';
if( sCtx.cTerm!=sCtx.cColSep ) break;
}
if( cSep=='(' ){
sqlite3_free(zCreate);
sqlite3_free(sCtx.z);
xCloser(sCtx.in);
fprintf(stderr,"%s: empty file\n", sCtx.zFile);
return 1;
}
zCreate = sqlite3_mprintf("%z\n)", zCreate);
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
if( rc ){
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
sqlite3_errmsg(p->db));
sqlite3_free(sCtx.z);
xCloser(sCtx.in);
return 1;
}
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql);
if( rc ){
if (pStmt) sqlite3_finalize(pStmt);
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
xCloser(sCtx.in);
return 1;
}
nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nCol==0 ) return 0; /* no columns, no error */
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n");
xCloser(sCtx.in);
return 1;
}
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
j = strlen30(zSql);
for(i=1; i<nCol; i++){
zSql[j++] = ',';
zSql[j++] = '?';
}
zSql[j++] = ')';
zSql[j] = 0;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
if (pStmt) sqlite3_finalize(pStmt);
xCloser(sCtx.in);
return 1;
}
needCommit = sqlite3_get_autocommit(p->db);
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
do{
int startLine = sCtx.nLine;
for(i=0; i<nCol; i++){
char *z = xRead(&sCtx);
/*
** Did we reach end-of-file before finding any columns?
** If so, stop instead of NULL filling the remaining columns.
|
| ︙ | ︙ | |||
3082 3083 3084 3085 3086 3087 3088 |
sCtx.zFile, startLine, nCol, i);
}
if( i>=nCol ){
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
| | | | 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 |
sCtx.zFile, startLine, nCol, i);
}
if( i>=nCol ){
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
sqlite3_errmsg(p->db));
}
}
}while( sCtx.cTerm!=EOF );
xCloser(sCtx.in);
sqlite3_free(sCtx.z);
sqlite3_finalize(pStmt);
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
}else
if( c=='i' && (strncmp(azArg[0], "indices", n)==0
|| strncmp(azArg[0], "indexes", n)==0) ){
ShellState data;
char *zErrMsg = 0;
open_db(p, 0);
|
| ︙ | ︙ | |||
3140 3141 3142 3143 3144 3145 3146 |
fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
rc = 1;
}
}else
#ifdef SQLITE_ENABLE_IOTRACE
if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 |
fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
rc = 1;
}
}else
#ifdef SQLITE_ENABLE_IOTRACE
if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
if( iotrace && iotrace!=stdout ) fclose(iotrace);
iotrace = 0;
if( nArg<2 ){
sqlite3IoTrace = 0;
}else if( strcmp(azArg[1], "-")==0 ){
sqlite3IoTrace = iotracePrintf;
iotrace = stdout;
}else{
iotrace = fopen(azArg[1], "w");
if( iotrace==0 ){
fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
sqlite3IoTrace = 0;
rc = 1;
}else{
sqlite3IoTrace = iotracePrintf;
}
}
}else
#endif
if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
static const struct {
const char *zLimitName; /* Name of a limit */
int limitCode; /* Integer code for that limit */
} aLimit[] = {
{ "length", SQLITE_LIMIT_LENGTH },
{ "sql_length", SQLITE_LIMIT_SQL_LENGTH },
{ "column", SQLITE_LIMIT_COLUMN },
{ "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
{ "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
{ "vdbe_op", SQLITE_LIMIT_VDBE_OP },
{ "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
{ "attached", SQLITE_LIMIT_ATTACHED },
{ "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
{ "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
};
int i, n2;
open_db(p, 0);
if( nArg==1 ){
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
printf("%20s %d\n", aLimit[i].zLimitName,
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
}
}else if( nArg>3 ){
fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
rc = 1;
goto meta_command_exit;
}else{
int iLimit = -1;
n2 = strlen30(azArg[1]);
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
if( iLimit<0 ){
iLimit = i;
}else{
fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
rc = 1;
goto meta_command_exit;
}
}
}
if( iLimit<0 ){
fprintf(stderr, "unknown limit: \"%s\"\n"
"enter \".limits\" with no arguments for a list.\n",
azArg[1]);
rc = 1;
goto meta_command_exit;
}
if( nArg==3 ){
sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
}
printf("%20s %d\n", aLimit[iLimit].zLimitName,
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
}
}else
#ifndef SQLITE_OMIT_LOAD_EXTENSION
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
const char *zFile, *zProc;
char *zErrMsg = 0;
if( nArg<2 ){
fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
|
| ︙ | ︙ | |||
3644 3645 3646 3647 3648 3649 3650 |
sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
}else{
sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
if( nRow>=nAlloc ){
char **azNew;
| | | | | 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 |
sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
}else{
sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
if( nRow>=nAlloc ){
char **azNew;
int n2 = nAlloc*2 + 10;
azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
if( azNew==0 ){
fprintf(stderr, "Error: out of memory\n");
break;
}
nAlloc = n2;
azResult = azNew;
}
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
if( azResult[nRow] ) nRow++;
}
sqlite3_finalize(pStmt);
if( nRow>0 ){
|
| ︙ | ︙ | |||
3703 3704 3705 3706 3707 3708 3709 |
{ "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
{ "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER },
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
{ "imposter", SQLITE_TESTCTRL_IMPOSTER },
};
int testctrl = -1;
| | | | | | | | | | | | | | | | > | < | 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 |
{ "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
{ "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER },
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
{ "imposter", SQLITE_TESTCTRL_IMPOSTER },
};
int testctrl = -1;
int rc2 = 0;
int i, n2;
open_db(p, 0);
/* convert testctrl text option to value. allow any unique prefix
** of the option name, or a numerical value. */
n2 = strlen30(azArg[1]);
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
if( testctrl<0 ){
testctrl = aCtrl[i].ctrlCode;
}else{
fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
testctrl = -1;
break;
}
}
}
if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
}else{
switch(testctrl){
/* sqlite3_test_control(int, db, int) */
case SQLITE_TESTCTRL_OPTIMIZATIONS:
case SQLITE_TESTCTRL_RESERVE:
if( nArg==3 ){
int opt = (int)strtol(azArg[2], 0, 0);
rc2 = sqlite3_test_control(testctrl, p->db, opt);
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
fprintf(stderr,"Error: testctrl %s takes a single int option\n",
azArg[1]);
}
break;
/* sqlite3_test_control(int) */
case SQLITE_TESTCTRL_PRNG_SAVE:
case SQLITE_TESTCTRL_PRNG_RESTORE:
case SQLITE_TESTCTRL_PRNG_RESET:
case SQLITE_TESTCTRL_BYTEORDER:
if( nArg==2 ){
rc2 = sqlite3_test_control(testctrl);
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
}
break;
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
fprintf(stderr,"Error: testctrl %s takes a single unsigned"
" int option\n", azArg[1]);
}
break;
/* sqlite3_test_control(int, int) */
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
case SQLITE_TESTCTRL_NEVER_CORRUPT:
if( nArg==3 ){
int opt = booleanValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
fprintf(stderr,"Error: testctrl %s takes a single int option\n",
azArg[1]);
}
break;
/* sqlite3_test_control(int, char *) */
#ifdef SQLITE_N_KEYWORD
case SQLITE_TESTCTRL_ISKEYWORD:
if( nArg==3 ){
const char *opt = azArg[2];
rc2 = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
} else {
fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
azArg[1]);
}
break;
#endif
case SQLITE_TESTCTRL_IMPOSTER:
if( nArg==5 ){
rc2 = sqlite3_test_control(testctrl, p->db,
azArg[2],
integerValue(azArg[3]),
integerValue(azArg[4]));
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
}else{
fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
}
break;
case SQLITE_TESTCTRL_BITVEC_TEST:
case SQLITE_TESTCTRL_FAULT_INSTALL:
case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
case SQLITE_TESTCTRL_SCRATCHMALLOC:
|
| ︙ | ︙ | |||
4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 |
memcpy(zSql+nSql, zLine, nLine+1);
nSql += nLine;
}
if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
&& sqlite3_complete(zSql) ){
p->cnt = 0;
open_db(p, 0);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
if( rc || zErrMsg ){
char zPrefix[100];
if( in!=0 || !stdin_is_interactive ){
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
| > | 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 |
memcpy(zSql+nSql, zLine, nLine+1);
nSql += nLine;
}
if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
&& sqlite3_complete(zSql) ){
p->cnt = 0;
open_db(p, 0);
if( p->backslashOn ) resolve_backslashes(zSql);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
if( rc || zErrMsg ){
char zPrefix[100];
if( in!=0 || !stdin_is_interactive ){
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
|
| ︙ | ︙ | |||
4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 |
data.echoOn = 1;
}else if( strcmp(z,"-eqp")==0 ){
data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-scanstats")==0 ){
data.scanstatsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
bail_on_error = 1;
}else if( strcmp(z,"-version")==0 ){
printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
return 0;
}else if( strcmp(z,"-interactive")==0 ){
stdin_is_interactive = 1;
| > > > > > > > | 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 |
data.echoOn = 1;
}else if( strcmp(z,"-eqp")==0 ){
data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-scanstats")==0 ){
data.scanstatsOn = 1;
}else if( strcmp(z,"-backslash")==0 ){
/* Undocumented command-line option: -backslash
** Causes C-style backslash escapes to be evaluated in SQL statements
** prior to sending the SQL into SQLite. Useful for injecting
** crazy bytes in the middle of SQL statements for testing and debugging.
*/
data.backslashOn = 1;
}else if( strcmp(z,"-bail")==0 ){
bail_on_error = 1;
}else if( strcmp(z,"-version")==0 ){
printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
return 0;
}else if( strcmp(z,"-interactive")==0 ){
stdin_is_interactive = 1;
|
| ︙ | ︙ |
Changes to src/shun.c.
| ︙ | ︙ | |||
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
rc = db_step(&q);
db_reset(&q);
return rc==SQLITE_ROW;
}
/*
** WEBPAGE: shun
*/
void shun_page(void){
Stmt q;
int cnt = 0;
const char *zUuid = P("uuid");
const char *zShun = P("shun");
const char *zAccept = P("accept");
| > > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
rc = db_step(&q);
db_reset(&q);
return rc==SQLITE_ROW;
}
/*
** WEBPAGE: shun
**
** View the SHA1 hashes of all shunned artifacts. Add new hashes
** to the shun set. Requires Admin privilege.
*/
void shun_page(void){
Stmt q;
int cnt = 0;
const char *zUuid = P("uuid");
const char *zShun = P("shun");
const char *zAccept = P("accept");
|
| ︙ | ︙ | |||
291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
);
}
/*
** WEBPAGE: rcvfromlist
**
** Show a listing of RCVFROM table entries.
*/
void rcvfromlist_page(void){
int ofst = atoi(PD("ofst","0"));
int showAll = P("all")!=0;
int cnt;
Stmt q;
| > > > > > | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
);
}
/*
** WEBPAGE: rcvfromlist
**
** Show a listing of RCVFROM table entries.
**
** The RCVFROM table records where this repository received each
** artifact, including the time of receipt, user, and IP address.
**
** Access requires Admin privilege.
*/
void rcvfromlist_page(void){
int ofst = atoi(PD("ofst","0"));
int showAll = P("all")!=0;
int cnt;
Stmt q;
|
| ︙ | ︙ | |||
373 374 375 376 377 378 379 | @ </table> style_footer(); } /* ** WEBPAGE: rcvfrom ** | | > | 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
@ </table>
style_footer();
}
/*
** WEBPAGE: rcvfrom
**
** Show a single RCVFROM table entry identified by the rcvid= query
** parameters. Requires Admin privilege.
*/
void rcvfrom_page(void){
int rcvid = atoi(PD("rcvid","0"));
Stmt q;
login_check_credentials();
if( !g.perm.Admin ){
|
| ︙ | ︙ |
Changes to src/sitemap.c.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 | #include "config.h" #include "sitemap.h" #include <assert.h> /* ** WEBPAGE: sitemap ** | | > > > > > > > > | | | > > > | | | | | | | > > | | > > > | | < < < | > > | | | | | | > > | | > | > | | | | | | | | > > | | > | > | | | | > > | > > | | | | > | | > | | > > > | | | | | | > > | > > | > > | > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
#include "config.h"
#include "sitemap.h"
#include <assert.h>
/*
** WEBPAGE: sitemap
**
** List some of the web pages offered by the Fossil web engine. This
** page is intended as a suppliment to the menu bar on the main screen.
** That is, this page is designed to hold links that are omitted from
** the main menu due to lack of space.
*/
void sitemap_page(void){
int srchFlags;
login_check_credentials();
srchFlags = search_restrict(SRCH_ALL);
style_header("Site Map");
style_adunit_config(ADUNIT_RIGHT_OK);
#if 0
@ <p>
@ The following links are just a few of the many web-pages available for
@ this Fossil repository:
@ </p>
@
#endif
@ <ul>
@ <li>%z(href("%R/home"))Home Page</a>
if( srchFlags & SRCH_DOC ){
@ <ul>
@ <li>%z(href("%R/docsrch"))Search Project Documentation</a></li>
@ </ul>
}
@ </li>
if( g.perm.Read ){
@ <li>%z(href("%R/tree"))File Browser</a></li>
@ <ul>
@ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view,
@ Trunk Check-in</a></li>
@ <li>%z(href("%R/tree?type=flat"))Flat-view</a></li>
@ <li>%z(href("%R/fileage?name=trunk"))File ages for Trunk</a></li>
@ </ul>
}
if( g.perm.Read ){
@ <li>%z(href("%R/timeline?n=200"))Project Timeline</a></li>
@ <ul>
@ <li>%z(href("%R/reports"))Activity Reports</a></li>
@ <li>%z(href("%R/timeline?n=all&namechng"))File name changes</a></li>
@ <li>%z(href("%R/timeline?n=all&forks"))Forks</a></li>
@ <li>%z(href("%R/timeline?a=1970-01-01&y=ci&n=10"))First 10
@ check-ins</a></li>
@ </ul>
}
if( g.perm.Read ){
@ <li>%z(href("%R/brlist"))Branches</a></li>
@ <ul>
@ <li>%z(href("%R/leaves"))Leaf Check-ins</a></li>
@ <li>%z(href("%R/taglist"))List of Tags</a></li>
@ </ul>
@ </li>
}
if( g.perm.RdWiki ){
@ <li>%z(href("%R/wikihelp"))Wiki</a>
@ <ul>
if( srchFlags & SRCH_WIKI ){
@ <li>%z(href("%R/wikisrch"))Wiki Search</a></li>
}
@ <li>%z(href("%R/wcontent"))List of Wiki Pages</a></li>
@ <li>%z(href("%R/timeline?y=w"))Recent activity</a></li>
@ <li>%z(href("%R/wiki_rules"))Wiki Formatting Rules</a></li>
@ <li>%z(href("%R/md_rules"))Markdown Formatting Rules</a></li>
@ <li>%z(href("%R/wiki?name=Sandbox"))Sandbox</a></li>
@ <li>%z(href("%R/attachlist"))List of Attachments</a></li>
@ </ul>
@ </li>
}
if( g.perm.RdTkt ){
@ <li>%z(href("%R/reportlist"))Tickets</a>
@ <ul>
if( srchFlags & SRCH_TKT ){
@ <li>%z(href("%R/tktsrch"))Ticket Search</a></li>
}
@ <li>%z(href("%R/timeline?y=t"))Recent activity</a></li>
@ <li>%z(href("%R/attachlist"))List of Attachments</a></li>
@ </ul>
@ </li>
}
if( srchFlags ){
@ <li>%z(href("%R/search"))Full-Text Search</a></li>
}
@ <li>%z(href("%R/login"))Login/Logout/Change Password</a></li>
if( g.perm.Read ){
@ <li>%z(href("%R/stat"))Repository Status</a>
@ <ul>
@ <li>%z(href("%R/hash-collisions"))Collisions on SHA1 hash
@ prefixes</a></li>
if( g.perm.Admin ){
@ <li>%z(href("%R/urllist"))List of URLs used to access
@ this repository</a></li>
}
@ <li>%z(href("%R/bloblist"))List of Artifacts</a></li>
@ </ul>
@ </li>
}
@ <li>On-line Documentation
@ <ul>
@ <li>%z(href("%R/help"))List of All Commands and Web Pages</a></li>
@ <li>%z(href("%R/test-all-help"))All "help" text on a single page</a></li>
@ <li>%z(href("%R/mimetype_list"))Filename suffix to mimetype map</a></li>
@ </ul></li>
if( g.perm.Admin ){
@ <li>%z(href("%R/setup"))Administration Pages</a>
@ <ul>
@ <li>%z(href("%R/modreq"))Pending Moderation Requests</a></li>
@ <li>%z(href("%R/admin_log"))Admin log</a></li>
@ <li>%z(href("%R/cachestat"))Status of the web-page cache</a></li>
@ </ul></li>
}
@ <li>Test Pages
@ <ul>
if( g.perm.Admin || db_get_boolean("test_env_enable",0) ){
@ <li>%z(href("%R/test_env"))CGI Environment Test</a></li>
}
if( g.perm.Read && g.perm.Hyperlink ){
@ <li>%z(href("%R/test_timewarps"))List of "Timewarp" Check-ins</a></li>
}
if( g.perm.Read ){
@ <li>%z(href("%R/test-rename-list"))List of file renames</a></li>
}
@ <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic
@ colors assigned to branch names</a>
@ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</li>
@ </ul></li>
@ </ul></li>
style_footer();
}
|
Changes to src/skins.c.
| ︙ | ︙ | |||
35 36 37 38 39 40 41 |
** rebuild the makefiles to reference the new CSS, headers, and footers.
**
** 4. Make an entry in the following array for the new skin.
*/
static struct BuiltinSkin {
const char *zDesc; /* Description of this skin */
const char *zLabel; /* The directory under skins/ holding this skin */
| < | | | | | | | | | | | > > > > > > > > > > > > > > > > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
** rebuild the makefiles to reference the new CSS, headers, and footers.
**
** 4. Make an entry in the following array for the new skin.
*/
static struct BuiltinSkin {
const char *zDesc; /* Description of this skin */
const char *zLabel; /* The directory under skins/ holding this skin */
char *zSQL; /* Filled in at run-time with SQL to insert this skin */
} aBuiltinSkin[] = {
{ "Default", "default", 0 },
{ "Blitz", "blitz", 0 },
{ "Blitz, No Logo", "blitz_no_logo", 0 },
{ "Xekri", "xekri", 0 },
{ "Original", "original", 0 },
{ "Enhanced Original", "enhanced1", 0 },
{ "Shadow boxes & Rounded Corners", "rounded1", 0 },
{ "Eagle", "eagle", 0 },
{ "Black & White, Menu on Left", "black_and_white", 0 },
{ "Plain Gray, No Logo", "plain_gray", 0 },
{ "Khaki, No Logo", "khaki", 0 },
};
/*
** Alternative skins can be specified in the CGI script or by options
** on the "http", "ui", and "server" commands. The alternative skin
** name must be one of the aBuiltinSkin[].zLabel names. If there is
** a match, that alternative is used.
**
** The following static variable holds the name of the alternative skin,
** or NULL if the skin should be as configured.
*/
static struct BuiltinSkin *pAltSkin = 0;
static char *zAltSkinDir = 0;
/*
** Skin details are a set of key/value pairs that define display
** attributes of the skin that cannot be easily specified using CSS
** or that need to be known on the server-side.
**
** The following array holds the value for all known skin details.
*/
static struct SkinDetail {
const char *zName; /* Name of the detail */
char *zValue; /* Value of the detail */
} aSkinDetail[] = {
{ "timeline-arrowheads", "1" },
{ "timeline-circle-nodes", "0" },
{ "timeline-color-graph-lines", "0" },
{ "white-foreground", "0" },
};
/*
** Invoke this routine to set the alternative skin. Return NULL if the
** alternative was successfully installed. Return a string listing all
** available skins if zName does not match an available skin. Memory
** for the returned string comes from fossil_malloc() and should be freed
** by the caller.
|
| ︙ | ︙ | |||
139 140 141 142 143 144 145 |
z = mprintf("skins/default/%s.txt", zWhat);
zOut = builtin_text(z);
fossil_free(z);
}
}
return zOut;
}
| | > > > > | > > > > > | | | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
z = mprintf("skins/default/%s.txt", zWhat);
zOut = builtin_text(z);
fossil_free(z);
}
}
return zOut;
}
/*
** Return a pointer to a SkinDetail element. Return 0 if not found.
*/
static struct SkinDetail *skin_detail_find(const char *zName){
int lwr = 0;
int upr = ArraySize(aSkinDetail);
while( upr>=lwr ){
int mid = (upr+lwr)/2;
int c = fossil_strcmp(aSkinDetail[mid].zName, zName);
if( c==0 ) return &aSkinDetail[mid];
if( c<0 ){
lwr = mid+1;
}else{
upr = mid-1;
}
}
return 0;
}
/* Initialize the aSkinDetail array using the text in the details.txt
** file.
*/
static void skin_detail_initialize(void){
static int isInit = 0;
char *zDetail;
Blob detail, line, key, value;
if( isInit ) return;
isInit = 1;
zDetail = (char*)skin_get("details");
if( zDetail==0 ) return;
zDetail = fossil_strdup(zDetail);
blob_init(&detail, zDetail, -1);
while( blob_line(&detail, &line) ){
char *zKey;
int nKey;
struct SkinDetail *pDetail;
if( !blob_token(&line, &key) ) continue;
zKey = blob_buffer(&key);
if( zKey[0]=='#' ) continue;
nKey = blob_size(&key);
if( nKey<2 ) continue;
if( zKey[nKey-1]!=':' ) continue;
zKey[nKey-1] = 0;
pDetail = skin_detail_find(zKey);
if( pDetail==0 ) continue;
if( !blob_token(&line, &value) ) continue;
pDetail->zValue = fossil_strdup(blob_str(&value));
}
blob_reset(&detail);
fossil_free(zDetail);
}
/*
** Return a skin detail setting
*/
const char *skin_detail(const char *zName){
struct SkinDetail *pDetail;
skin_detail_initialize();
pDetail = skin_detail_find(zName);
if( pDetail==0 ) fossil_fatal("no such skin detail: %s", zName);
return pDetail->zValue;
}
int skin_detail_boolean(const char *zName){
return !is_false(skin_detail(zName));
}
/*
** Hash function for computing a skin id.
*/
static unsigned int skin_hash(unsigned int h, const char *z){
if( z==0 ) return h;
|
| ︙ | ︙ | |||
225 226 227 228 229 230 231 |
** by zName.
**
** Memory to hold the returned string is obtained from malloc.
*/
static char *getSkin(const char *zName){
const char *z;
char *zLabel;
| | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
** by zName.
**
** Memory to hold the returned string is obtained from malloc.
*/
static char *getSkin(const char *zName){
const char *z;
char *zLabel;
static const char *azType[] = { "css", "header", "footer", "details" };
int i;
Blob val;
blob_zero(&val);
for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
if( zName ){
zLabel = mprintf("skins/%s/%s.txt", zName, azType[i]);
z = builtin_text(zLabel);
|
| ︙ | ︙ | |||
332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
zNewName, zCurrent
);
return 0;
}
/*
** WEBPAGE: setup_skin
*/
void setup_skin(void){
const char *z;
char *zName;
char *zErr = 0;
const char *zCurrent = 0; /* Current skin */
int i; /* Loop counter */
| > > > | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
zNewName, zCurrent
);
return 0;
}
/*
** WEBPAGE: setup_skin
**
** Show a list of available skins with buttons for selecting which
** skin to use. Requires Admin privilege.
*/
void setup_skin(void){
const char *z;
char *zName;
char *zErr = 0;
const char *zCurrent = 0; /* Current skin */
int i; /* Loop counter */
|
| ︙ | ︙ | |||
418 419 420 421 422 423 424 |
}
style_header("Skins");
if( zErr ){
@ <p><font color="red">%h(zErr)</font></p>
}
@ <p>A "skin" is a combination of
| | | > > | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
}
style_header("Skins");
if( zErr ){
@ <p><font color="red">%h(zErr)</font></p>
}
@ <p>A "skin" is a combination of
@ <a href="setup_skinedit?w=0">CSS</a>,
@ <a href="setup_skinedit?w=2">Header</a>,
@ <a href="setup_skinedit?w=1">Footer</a>, and
@ <a href="setup_skinedit?w=3">Details</a>
@ that determines the look and feel
@ of the web interface.</p>
@
if( pAltSkin ){
@ <p class="generalError">
@ This page is generated using an skin override named
@ "%h(pAltSkin->zLabel)". You can change the skin configuration
@ below, but the changes will not take effect until the Fossil server
|
| ︙ | ︙ | |||
481 482 483 484 485 486 487 488 489 490 |
i++;
@ <tr><td>%d(i).<td><i>Current Configuration</i><td> <td>
@ <form action="%s(g.zTop)/setup_skin" method="post">
@ <input type="submit" name="save" value="Save">
@ </form>
}
@ </table>
style_footer();
db_end_transaction(0);
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 |
i++;
@ <tr><td>%d(i).<td><i>Current Configuration</i><td> <td>
@ <form action="%s(g.zTop)/setup_skin" method="post">
@ <input type="submit" name="save" value="Save">
@ </form>
}
@ </table>
style_footer();
db_end_transaction(0);
}
/*
** WEBPAGE: setup_skinedit
**
** Edit aspects of a skin determined by the w= query parameter.
** Requires Admin privileges.
**
** w=N -- 0=CSS, 1=footer, 2=header, 3=details
*/
void setup_skinedit(void){
static const struct sSkinAddr {
const char *zFile;
const char *zTitle;
const char *zSubmenu;
} aSkinAttr[] = {
/* 0 */ { "css", "CSS", "CSS", },
/* 1 */ { "footer", "Page Footer", "Footer", },
/* 2 */ { "header", "Page Header", "Header", },
/* 3 */ { "details", "Display Details", "Details", },
};
const char *zBasis;
const char *zContent;
char *zDflt;
int ii;
int j;
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
ii = atoi(PD("w","0"));
if( ii<0 || ii>ArraySize(aSkinAttr) ) ii = 0;
zBasis = PD("basis","default");
zDflt = mprintf("skins/%s/%s.txt", zBasis, aSkinAttr[ii].zFile);
db_begin_transaction();
if( P("revert")!=0 ){
db_multi_exec("DELETE FROM config WHERE name=%Q", aSkinAttr[ii].zFile);
cgi_replace_parameter(aSkinAttr[ii].zFile, builtin_text(zDflt));
}
style_header("%s", aSkinAttr[ii].zTitle);
for(j=0; j<ArraySize(aSkinAttr); j++){
if( j==ii ) continue;
style_submenu_element(aSkinAttr[j].zSubmenu, 0,
"%R/setup_skinedit?w=%d&basis=%h",j,zBasis);
}
style_submenu_element("Skins", 0, "%R/setup_skin");
@ <form action="%s(g.zTop)/setup_skinedit" method="post"><div>
login_insert_csrf_secret();
@ <input type='hidden' name='w' value='%d(ii)'>
@ <h2>Edit %s(aSkinAttr[ii].zTitle):</h2>
zContent = textarea_attribute("", 10, 80, aSkinAttr[ii].zFile,
aSkinAttr[ii].zFile, builtin_text(zDflt), 0);
@ <br />
@ <input type="submit" name="submit" value="Apply Changes" />
@ <hr />
@ Baseline: <select size='1' name='basis'>
for(j=0; j<ArraySize(aBuiltinSkin); j++){
cgi_printf("<option value='%h'%s>%h</option>\n",
aBuiltinSkin[j].zLabel,
fossil_strcmp(zBasis,aBuiltinSkin[j].zLabel)==0 ? " selected" : "",
aBuiltinSkin[j].zDesc
);
}
@ </select>
@ <input type="submit" name="diff" value="Diff" />
if( P("diff")!=0 ){
u64 diffFlags = construct_diff_flags(0,0) |
DIFF_STRIP_EOLCR;
Blob from, to, out;
blob_init(&to, zContent, -1);
blob_init(&from, builtin_text(zDflt), -1);
blob_zero(&out);
@ <input type="submit" name="revert" value="Revert" /><p>
if( diffFlags & DIFF_SIDEBYSIDE ){
text_diff(&from, &to, &out, 0, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
@ %s(blob_str(&out))
}else{
text_diff(&from, &to, &out, 0,
diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
@ <pre class="udiff">
@ %s(blob_str(&out))
@ </pre>
}
blob_reset(&from);
blob_reset(&to);
blob_reset(&out);
}
@ </div></form>
style_footer();
db_end_transaction(0);
}
|
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
int argc,
sqlite3_value **argv
){
const unsigned char *pIn;
unsigned char *pOut;
unsigned int nIn;
unsigned long int nOut;
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
nOut = 13 + nIn + (nIn+999)/1000;
pOut = sqlite3_malloc( nOut+4 );
pOut[0] = nIn>>24 & 0xff;
pOut[1] = nIn>>16 & 0xff;
pOut[2] = nIn>>8 & 0xff;
pOut[3] = nIn & 0xff;
| > | > | > > > > | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
int argc,
sqlite3_value **argv
){
const unsigned char *pIn;
unsigned char *pOut;
unsigned int nIn;
unsigned long int nOut;
int rc;
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
nOut = 13 + nIn + (nIn+999)/1000;
pOut = sqlite3_malloc( nOut+4 );
pOut[0] = nIn>>24 & 0xff;
pOut[1] = nIn>>16 & 0xff;
pOut[2] = nIn>>8 & 0xff;
pOut[3] = nIn & 0xff;
rc = compress(&pOut[4], &nOut, pIn, nIn);
if( rc==Z_OK ){
sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free);
}else{
sqlite3_free(pOut);
sqlite3_result_error(context, "input cannot be zlib compressed", -1);
}
}
/*
** Implementation of the "decompress(X)" SQL function. The argument X
** is a blob which was obtained from compress(Y). The output will be
** the value Y.
*/
|
| ︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
nIn = sqlite3_value_bytes(argv[0]);
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
pOut = sqlite3_malloc( nOut+1 );
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
if( rc==Z_OK ){
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
}else{
sqlite3_result_error(context, "input is not zlib compressed", -1);
}
}
/*
** Add the content(), compress(), and decompress() SQL functions to
** database connection db.
| > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
nIn = sqlite3_value_bytes(argv[0]);
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
pOut = sqlite3_malloc( nOut+1 );
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
if( rc==Z_OK ){
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
}else{
sqlite3_free(pOut);
sqlite3_result_error(context, "input is not zlib compressed", -1);
}
}
/*
** Add the content(), compress(), and decompress() SQL functions to
** database connection db.
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | 1 2 3 4 5 6 7 8 9 10 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.8.10.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other |
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | ** separate file. This file contains only code for the core SQLite library. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif | < < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** separate file. This file contains only code for the core SQLite library. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif /************** Begin file sqliteInt.h ***************************************/ /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** |
| ︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #define _MSVC_H_ #if defined(_MSC_VER) #pragma warning(disable : 4054) #pragma warning(disable : 4055) #pragma warning(disable : 4100) #pragma warning(disable : 4127) #pragma warning(disable : 4152) #pragma warning(disable : 4189) #pragma warning(disable : 4206) #pragma warning(disable : 4210) #pragma warning(disable : 4232) #pragma warning(disable : 4244) #pragma warning(disable : 4305) | > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #define _MSVC_H_ #if defined(_MSC_VER) #pragma warning(disable : 4054) #pragma warning(disable : 4055) #pragma warning(disable : 4100) #pragma warning(disable : 4127) #pragma warning(disable : 4130) #pragma warning(disable : 4152) #pragma warning(disable : 4189) #pragma warning(disable : 4206) #pragma warning(disable : 4210) #pragma warning(disable : 4232) #pragma warning(disable : 4244) #pragma warning(disable : 4305) |
| ︙ | ︙ | |||
248 249 250 251 252 253 254 |
*/
#if 0
extern "C" {
#endif
/*
| | < < < < < < > > > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
*/
#if 0
extern "C" {
#endif
/*
** Provide the ability to override linkage features of the interface.
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
#ifndef SQLITE_STDCALL
# define SQLITE_STDCALL
#endif
/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental. New applications
** should not use deprecated interfaces - they are supported for backwards
** compatibility only. Application writers should be aware that
** experimental interfaces are subject to change in point releases.
|
| ︙ | ︙ | |||
319 320 321 322 323 324 325 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.10.1" #define SQLITE_VERSION_NUMBER 3008010 #define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
354 355 356 357 358 359 360 | ** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; | | | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | ** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void); SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void); SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** ** ^The sqlite3_compileoption_used() function returns 0 or 1 ** indicating whether the specified option was defined at ** compile time. ^The SQLITE_ prefix may be omitted from the |
| ︙ | ︙ | |||
381 382 383 384 385 386 387 | ** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS | | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | ** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName); SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N); #endif /* ** CAPI3REF: Test To See If The Library Is Threadsafe ** ** ^The sqlite3_threadsafe() function returns zero if and only if ** SQLite was compiled with mutexing code omitted due to the |
| ︙ | ︙ | |||
421 422 423 424 425 426 427 | ** sqlite3_threadsafe() function shows only the compile-time setting of ** thread safety, not any run-time changes to that setting made by ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() ** is unchanged by calls to sqlite3_config().)^ ** ** See the [threading mode] documentation for additional information. */ | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
** sqlite3_threadsafe() function shows only the compile-time setting of
** thread safety, not any run-time changes to that setting made by
** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
** is unchanged by calls to sqlite3_config().)^
**
** See the [threading mode] documentation for additional information.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
|
| ︙ | ︙ | |||
478 479 480 481 482 483 484 485 486 487 488 489 490 491 | */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** | > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** DESTRUCTOR: sqlite3 ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** |
| ︙ | ︙ | |||
517 518 519 520 521 522 523 | ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ | | | > | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*); SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface ** METHOD: sqlite3 ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, |
| ︙ | ︙ | |||
588 589 590 591 592 593 594 | ** is a valid and open [database connection]. ** <li> The application must not close the [database connection] specified by ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. ** <li> The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. ** </ul> */ | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | ** is a valid and open [database connection]. ** <li> The application must not close the [database connection] specified by ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. ** <li> The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. ** </ul> */ SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ ); |
| ︙ | ︙ | |||
1548 1549 1550 1551 1552 1553 1554 | ** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for ** sqlite3_os_init() and sqlite3_os_end(). An application-supplied ** implementation of sqlite3_os_init() or sqlite3_os_end() ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ | | | | | | 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 | ** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for ** sqlite3_os_init() and sqlite3_os_end(). An application-supplied ** implementation of sqlite3_os_init() or sqlite3_os_end() ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void); SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void); SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void); SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void); /* ** CAPI3REF: Configuring The SQLite Library ** ** The sqlite3_config() interface is used to make global configuration ** changes to SQLite in order to tune SQLite to the specific needs of ** the application. The default configuration is recommended for most |
| ︙ | ︙ | |||
1582 1583 1584 1585 1586 1587 1588 | ** vary depending on the [configuration option] ** in the first argument. ** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ | | > | | 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 | ** vary depending on the [configuration option] ** in the first argument. ** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections ** METHOD: sqlite3 ** ** The sqlite3_db_config() interface is used to make configuration ** changes to a [database connection]. The interface is similar to ** [sqlite3_config()] except that the changes apply to a single ** [database connection] (specified in the first argument). ** ** The second argument to sqlite3_db_config(D,V,...) is the ** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if ** the call is considered successful. */ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines ** ** An instance of this object defines the interface between SQLite ** and low-level memory allocation routines. ** |
| ︙ | ︙ | |||
2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 | #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ | > | > | 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 | #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff); /* ** CAPI3REF: Last Insert Rowid ** METHOD: sqlite3 ** ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) ** has a unique 64-bit signed ** integer key called the [ROWID | "rowid"]. ^The rowid is always available ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those ** names are not also used by explicitly declared columns. ^If ** the table has a column of type [INTEGER PRIMARY KEY] then that column |
| ︙ | ︙ | |||
2139 2140 2141 2142 2143 2144 2145 | ** If a separate thread performs a new [INSERT] on the same ** database connection while the [sqlite3_last_insert_rowid()] ** function is running and thus changes the last insert [rowid], ** then the value returned by [sqlite3_last_insert_rowid()] is ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ | | > | 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 | ** If a separate thread performs a new [INSERT] on the same ** database connection while the [sqlite3_last_insert_rowid()] ** function is running and thus changes the last insert [rowid], ** then the value returned by [sqlite3_last_insert_rowid()] is ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*); /* ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 ** ** ^This function returns the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** ^Executing any other type of SQL statement does not modify the value ** returned by this function. ** |
| ︙ | ︙ | |||
2191 2192 2193 2194 2195 2196 2197 | ** See also the [sqlite3_total_changes()] interface, the ** [count_changes pragma], and the [changes() SQL function]. ** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ | | > | > | 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 | ** See also the [sqlite3_total_changes()] interface, the ** [count_changes pragma], and the [changes() SQL function]. ** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified ** METHOD: sqlite3 ** ** ^This function returns the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as ** part of trigger programs. ^Executing any other type of SQL statement ** does not affect the value returned by sqlite3_total_changes(). ** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. ** ** See also the [sqlite3_changes()] interface, the ** [count_changes pragma], and the [total_changes() SQL function]. ** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. */ SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query ** METHOD: sqlite3 ** ** ^This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically ** called in response to a user action such as pressing "Cancel" ** or Ctrl-C where the user wants a long query operation to halt ** immediately. ** |
| ︙ | ︙ | |||
2253 2254 2255 2256 2257 2258 2259 | ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. ** ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ | | | 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 | ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. ** ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete ** ** These routines are useful during command-line input to determine if the ** currently entered text seems to form a complete SQL statement or ** if additional input is needed before sending the text into |
| ︙ | ︙ | |||
2288 2289 2290 2291 2292 2293 2294 | ** ** The input to [sqlite3_complete()] must be a zero-terminated ** UTF-8 string. ** ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ | | | > | 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 |
**
** The input to [sqlite3_complete()] must be a zero-terminated
** UTF-8 string.
**
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
** KEYWORDS: {busy-handler callback} {busy handler}
** METHOD: sqlite3
**
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
** that might be invoked with argument P whenever
** an attempt is made to access a database table associated with
** [database connection] D when another thread
** or process has the table locked.
** The sqlite3_busy_handler() interface is used to implement
|
| ︙ | ︙ | |||
2349 2350 2351 2352 2353 2354 2355 | ** database connection that invoked the busy handler. In other words, ** the busy handler is not reentrant. Any such actions ** result in undefined behavior. ** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ | | > | > | 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 | ** database connection that invoked the busy handler. In other words, ** the busy handler is not reentrant. Any such actions ** result in undefined behavior. ** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout ** METHOD: sqlite3 ** ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps ** for a specified amount of time when a table is locked. ^The handler ** will sleep multiple times until at least "ms" milliseconds of sleeping ** have accumulated. ^After at least "ms" milliseconds of sleeping, ** the handler returns 0 which causes [sqlite3_step()] to return ** [SQLITE_BUSY]. ** ** ^Calling this routine with an argument less than or equal to zero ** turns off all busy handlers. ** ** ^(There can only be a single busy handler for a particular ** [database connection] at any given moment. If another busy handler ** was defined (using [sqlite3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ ** ** See also: [PRAGMA busy_timeout] */ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** ** Definition: A <b>result table</b> is memory data structure created by the ** [sqlite3_get_table()] interface. A result table records the ** complete query results from one or more queries. |
| ︙ | ︙ | |||
2445 2446 2447 2448 2449 2450 2451 | ** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access ** to any internal data structures of SQLite. It uses only the public ** interface defined here. As a consequence, errors that occur in the ** wrapper layer outside of the internal [sqlite3_exec()] call are not ** reflected in subsequent calls to [sqlite3_errcode()] or ** [sqlite3_errmsg()]. */ | | | | 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 | ** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access ** to any internal data structures of SQLite. It uses only the public ** interface defined here. As a consequence, errors that occur in the ** wrapper layer outside of the internal [sqlite3_exec()] call are not ** reflected in subsequent calls to [sqlite3_errcode()] or ** [sqlite3_errmsg()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** These routines understand most of the common K&R formatting options, |
| ︙ | ︙ | |||
2559 2560 2561 2562 2563 2564 2565 | ** character.)^ The "%w" formatting option is intended for safely inserting ** table and column names into a constructed SQL statement. ** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ | | | | | | 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 | ** character.)^ The "%w" formatting option is intended for safely inserting ** table and column names into a constructed SQL statement. ** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...); SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list); SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...); SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list); /* ** CAPI3REF: Memory Allocation Subsystem ** ** The SQLite core uses these three routines for all of its own ** internal memory allocation needs. "Core" in the previous sentence ** does not include operating-system specific VFS implementation. The |
| ︙ | ︙ | |||
2652 2653 2654 2655 2656 2657 2658 | ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** ** The application must not read or write any part of ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ | | | | | | | | 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 | ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** ** The application must not read or write any part of ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int); SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64); SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int); SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64); SQLITE_API void SQLITE_STDCALL sqlite3_free(void*); SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*); /* ** CAPI3REF: Memory Allocator Statistics ** ** SQLite provides these two interfaces for reporting on the status ** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] ** routines, which form the built-in memory allocation subsystem. |
| ︙ | ︙ | |||
2682 2683 2684 2685 2686 2687 2688 | ** ** ^The memory high-water mark is reset to the current value of ** [sqlite3_memory_used()] if and only if the parameter to ** [sqlite3_memory_highwater()] is true. ^The value returned ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ | | | | 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 | ** ** ^The memory high-water mark is reset to the current value of ** [sqlite3_memory_used()] if and only if the parameter to ** [sqlite3_memory_highwater()] is true. ^The value returned ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Pseudo-Random Number Generator ** ** SQLite contains a high-quality pseudo-random number generator (PRNG) used to ** select random [ROWID | ROWIDs] when inserting new records into a table that ** already uses the largest possible [ROWID]. The PRNG is also used for |
| ︙ | ︙ | |||
2706 2707 2708 2709 2710 2711 2712 | ** seeded using randomness obtained from the xRandomness method of ** the default [sqlite3_vfs] object. ** ^If the previous call to this routine had an N of 1 or more and a ** non-NULL P then the pseudo-randomness is generated ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ | | > | 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 | ** seeded using randomness obtained from the xRandomness method of ** the default [sqlite3_vfs] object. ** ^If the previous call to this routine had an N of 1 or more and a ** non-NULL P then the pseudo-randomness is generated ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** METHOD: sqlite3 ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], ** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various ** points during the compilation process, as logic is being created |
| ︙ | ︙ | |||
2788 2789 2790 2791 2792 2793 2794 | ** ** ^Note that the authorizer callback is invoked only during ** [sqlite3_prepare()] or its variants. Authorization is not ** performed during statement evaluation in [sqlite3_step()], unless ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ | | | 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 | ** ** ^Note that the authorizer callback is invoked only during ** [sqlite3_prepare()] or its variants. Authorization is not ** performed during statement evaluation in [sqlite3_step()], unless ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData ); /* ** CAPI3REF: Authorizer Return Codes |
| ︙ | ︙ | |||
2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 | #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ #define SQLITE_COPY 0 /* No longer used */ #define SQLITE_RECURSIVE 33 /* NULL NULL */ /* ** CAPI3REF: Tracing And Profiling Functions ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. ** ** ^The callback function registered by sqlite3_trace() is invoked at ** various times when an SQL statement is being run by [sqlite3_step()]. ** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the | > | 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 | #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ #define SQLITE_COPY 0 /* No longer used */ #define SQLITE_RECURSIVE 33 /* NULL NULL */ /* ** CAPI3REF: Tracing And Profiling Functions ** METHOD: sqlite3 ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. ** ** ^The callback function registered by sqlite3_trace() is invoked at ** various times when an SQL statement is being run by [sqlite3_step()]. ** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the |
| ︙ | ︙ | |||
2892 2893 2894 2895 2896 2897 2898 | ** time is in units of nanoseconds, however the current implementation ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite ** might provide greater resolution on the profiler callback. The ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ | | | > | 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 | ** time is in units of nanoseconds, however the current implementation ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite ** might provide greater resolution on the profiler callback. The ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** |
| ︙ | ︙ | |||
2927 2928 2929 2930 2931 2932 2933 | ** ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** */ | | > | 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 | ** ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** */ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection ** CONSTRUCTOR: sqlite3 ** ** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for ** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte ** order for sqlite3_open16(). ^(A [database connection] handle is usually ** returned in *ppDb, even if an error occurs. The only exception is that ** if SQLite is unable to allocate memory to hold the [sqlite3] object, |
| ︙ | ︙ | |||
3155 3156 3157 3158 3159 3160 3161 | ** ** <b>Note to Windows Runtime users:</b> The temporary directory must be set ** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various ** features that require the use of temporary files may fail. ** ** See also: [sqlite3_temp_directory] */ | | | | | 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 | ** ** <b>Note to Windows Runtime users:</b> The temporary directory must be set ** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various ** features that require the use of temporary files may fail. ** ** See also: [sqlite3_temp_directory] */ SQLITE_API int SQLITE_STDCALL sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); SQLITE_API int SQLITE_STDCALL sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ); /* |
| ︙ | ︙ | |||
3209 3210 3211 3212 3213 3214 3215 | ** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that SQLite passed into the xOpen ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. */ | | | | > | 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 | ** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that SQLite passed into the xOpen ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam); SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** ** ^If the most recent sqlite3_* API call associated with ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. ** If the most recent API call was successful, ** then the return value from sqlite3_errcode() is undefined. |
| ︙ | ︙ | |||
3254 3255 3256 3257 3258 3259 3260 | ** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after ** all calls to the interfaces listed here are completed. ** ** If an interface fails with SQLITE_MISUSE, that means the interface ** was invoked incorrectly by the application. In that case, the ** error code and message may or may not be set. */ | | | | | | | | > > > | > | | | < | | < < < > | 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 |
** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
** all calls to the interfaces listed here are completed.
**
** If an interface fails with SQLITE_MISUSE, that means the interface
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
/*
** CAPI3REF: Prepared Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
** An instance of this object represents a single SQL statement that
** has been compiled into binary form and is ready to be evaluated.
**
** Think of each SQL statement as a separate computer program. The
** original SQL text is source code. A prepared statement object
** is the compiled object code. All SQL must be converted into a
** prepared statement before it can be run.
**
** The life-cycle of a prepared statement object usually goes like this:
**
** <ol>
** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
** <li> Bind values to [parameters] using the sqlite3_bind_*()
** interfaces.
** <li> Run the SQL by calling [sqlite3_step()] one or more times.
** <li> Reset the prepared statement using [sqlite3_reset()] then go back
** to step 2. Do this zero or more times.
** <li> Destroy the object using [sqlite3_finalize()].
** </ol>
*/
typedef struct sqlite3_stmt sqlite3_stmt;
/*
** CAPI3REF: Run-time Limits
** METHOD: sqlite3
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
** [database connection] whose limit is to be set or queried. The
** second parameter is one of the [limit categories] that define a
** class of constructs to be size limited. The third parameter is the
** new limit for that construct.)^
|
| ︙ | ︙ | |||
3325 3326 3327 3328 3329 3330 3331 | ** attack. Developers might also want to use the [sqlite3_set_authorizer()] ** interface to further control untrusted SQL. The size of the database ** created by an untrusted script can be contained using the ** [max_page_count] [PRAGMA]. ** ** New run-time limit categories may be added in future releases. */ | | | 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 |
** attack. Developers might also want to use the [sqlite3_set_authorizer()]
** interface to further control untrusted SQL. The size of the database
** created by an untrusted script can be contained using the
** [max_page_count] [PRAGMA].
**
** New run-time limit categories may be added in future releases.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
|
| ︙ | ︙ | |||
3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 |
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()]. The database connection must not have been closed.
| > > | 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 |
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()]. The database connection must not have been closed.
|
| ︙ | ︙ | |||
3475 3476 3477 3478 3479 3480 3481 | ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** </li> ** </ol> */ | | | | | > | > | 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 | ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** </li> ** </ol> */ SQLITE_API int SQLITE_STDCALL sqlite3_prepare( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); /* ** CAPI3REF: Retrieving Statement SQL ** METHOD: sqlite3_stmt ** ** ^This interface can be used to retrieve a saved copy of the original ** SQL text used to create a [prepared statement] if that statement was ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database ** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** and only if the [prepared statement] X makes no direct changes to ** the content of the database file. ** ** Note that [application-defined SQL functions] or ** [virtual tables] might change the database indirectly as a side effect. |
| ︙ | ︙ | |||
3542 3543 3544 3545 3546 3547 3548 | ** since the statements themselves do not actually modify the database but ** rather they control the timing of when other statements modify the ** database. ^The [ATTACH] and [DETACH] statements also cause ** sqlite3_stmt_readonly() to return true since, while those statements ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. */ | | > | | 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 |
** since the statements themselves do not actually modify the database but
** rather they control the timing of when other statements modify the
** database. ^The [ATTACH] and [DETACH] statements also cause
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
** [sqlite3_step(S)] but has not run to completion and/or has not
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
** interface returns false if S is a NULL pointer. If S is not a
** NULL pointer and is not a pointer to a valid [prepared statement]
** object, then the behavior is undefined and probably undesirable.
**
** This interface can be used in combination [sqlite3_next_stmt()]
** to locate all prepared statements associated with a database
** connection that are in need of being reset. This can be used,
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
** that can be stored in a database table. SQLite uses dynamic typing
|
| ︙ | ︙ | |||
3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 |
*/
typedef struct sqlite3_context sqlite3_context;
/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li> ?
| > | 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 |
*/
typedef struct sqlite3_context sqlite3_context;
/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
** METHOD: sqlite3_stmt
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li> ?
|
| ︙ | ︙ | |||
3722 3723 3724 3725 3726 3727 3728 | ** [SQLITE_MAX_LENGTH]. ** ^[SQLITE_RANGE] is returned if the parameter ** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. ** ** See also: [sqlite3_bind_parameter_count()], ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ | | | | | | | | | | | | > | > | 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 |
** [SQLITE_MAX_LENGTH].
** ^[SQLITE_RANGE] is returned if the parameter
** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails.
**
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
/*
** CAPI3REF: Number Of SQL Parameters
** METHOD: sqlite3_stmt
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
** placeholders for values that are [sqlite3_bind_blob | bound]
** to the parameters at a later time.
**
** ^(This routine actually returns the index of the largest (rightmost)
** parameter. For all forms except ?NNN, this will correspond to the
** number of unique parameters. If parameters of the ?NNN form are used,
** there may be gaps in the list.)^
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
** METHOD: sqlite3_stmt
**
** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
** respectively.
** In other words, the initial ":" or "$" or "@" or "?"
|
| ︙ | ︙ | |||
3781 3782 3783 3784 3785 3786 3787 | ** originally specified as UTF-16 in [sqlite3_prepare16()] or ** [sqlite3_prepare16_v2()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ | | > | > | > | > | 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 | ** originally specified as UTF-16 in [sqlite3_prepare16()] or ** [sqlite3_prepare16_v2()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int); /* ** CAPI3REF: Index Of A Parameter With A Given Name ** METHOD: sqlite3_stmt ** ** ^Return the index of an SQL parameter given its name. ^The ** index value returned is suitable for use as the second ** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero ** is returned if no matching parameter is found. ^The parameter ** name must be given in UTF-8 even if the original statement ** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement ** METHOD: sqlite3_stmt ** ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset ** the [sqlite3_bind_blob | bindings] on a [prepared statement]. ** ^Use this routine to reset all host parameters to NULL. */ SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*); /* ** CAPI3REF: Number Of Columns In A Result Set ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL ** statement that does not return data (for example an [UPDATE]). ** ** See also: [sqlite3_data_count()] */ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Column Names In A Result Set ** METHOD: sqlite3_stmt ** ** ^These routines return the name assigned to a particular column ** in the result set of a [SELECT] statement. ^The sqlite3_column_name() ** interface returns a pointer to a zero-terminated UTF-8 string ** and sqlite3_column_name16() returns a pointer to a zero-terminated ** UTF-16 string. ^The first parameter is the [prepared statement] ** that implements the [SELECT] statement. ^The second parameter is the |
| ︙ | ︙ | |||
3845 3846 3847 3848 3849 3850 3851 | ** NULL pointer is returned. ** ** ^The name of a result column is the value of the "AS" clause for ** that column, if there is an AS clause. If there is no AS clause ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ | | | > | 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 | ** NULL pointer is returned. ** ** ^The name of a result column is the value of the "AS" clause for ** that column, if there is an AS clause. If there is no AS clause ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return ** the database name, the _table_ routines return the table name, and |
| ︙ | ︙ | |||
3893 3894 3895 3896 3897 3898 3899 | ** undefined. ** ** If two or more threads call one or more ** [sqlite3_column_database_name | column metadata interfaces] ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ | | | | | | | > | 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 | ** undefined. ** ** If two or more threads call one or more ** [sqlite3_column_database_name | column metadata interfaces] ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int); SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int); SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int); /* ** CAPI3REF: Declared Datatype Of A Query Result ** METHOD: sqlite3_stmt ** ** ^(The first parameter is a [prepared statement]. ** If this statement is a [SELECT] statement and the Nth column of the ** returned result set of that [SELECT] is a table column (not an ** expression or subquery) then the declared type of the table ** column is returned.)^ ^If the Nth column of the result set is an ** expression or subquery, then a NULL pointer is returned. |
| ︙ | ︙ | |||
3929 3930 3931 3932 3933 3934 3935 | ** ^SQLite uses dynamic run-time typing. ^So just because a column ** is declared to contain a particular type does not mean that the ** data stored in that column is of the declared type. SQLite is ** strongly typed, but the typing is dynamic not static. ^Type ** is associated with individual values, not with the containers ** used to hold those values. */ | | | > | 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 | ** ^SQLite uses dynamic run-time typing. ^So just because a column ** is declared to contain a particular type does not mean that the ** data stored in that column is of the declared type. SQLite is ** strongly typed, but the typing is dynamic not static. ^Type ** is associated with individual values, not with the containers ** used to hold those values. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int); /* ** CAPI3REF: Evaluate An SQL Statement ** METHOD: sqlite3_stmt ** ** After a [prepared statement] has been prepared using either ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy ** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function ** must be called one or more times to evaluate the statement. ** ** The details of the behavior of the sqlite3_step() interface depend |
| ︙ | ︙ | |||
4009 4010 4011 4012 4013 4014 4015 | ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly ** by sqlite3_step(). The use of the "v2" interface is recommended. */ | | > | | 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 | ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly ** by sqlite3_step(). The use of the "v2" interface is recommended. */ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set ** METHOD: sqlite3_stmt ** ** ^The sqlite3_data_count(P) interface returns the number of columns in the ** current row of the result set of [prepared statement] P. ** ^If prepared statement P does not have results ready to return ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of ** interfaces) then sqlite3_data_count(P) returns 0. ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. ** ^The sqlite3_data_count(P) routine returns 0 if the previous call to ** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) ** will return non-zero if previous call to [sqlite3_step](P) returned ** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] ** where it always returns zero since each step of that multi-step ** pragma returns 0 columns of data. ** ** See also: [sqlite3_column_count()] */ SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Fundamental Datatypes ** KEYWORDS: SQLITE_TEXT ** ** ^(Every value in SQLite has one of five fundamental datatypes: ** |
| ︙ | ︙ | |||
4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 |
# define SQLITE_TEXT 3
#endif
#define SQLITE3_TEXT 3
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
| > | 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 |
# define SQLITE_TEXT 3
#endif
#define SQLITE3_TEXT 3
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
** METHOD: sqlite3_stmt
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
|
| ︙ | ︙ | |||
4225 4226 4227 4228 4229 4230 4231 | ** ** ^(If a memory allocation error occurs during the evaluation of any ** of these routines, a default value is returned. The default value ** is either the integer 0, the floating point number 0.0, or a NULL ** pointer. Subsequent calls to [sqlite3_errcode()] will return ** [SQLITE_NOMEM].)^ */ | | | | | | | | | | | > | 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 | ** ** ^(If a memory allocation error occurs during the evaluation of any ** of these routines, a default value is returned. The default value ** is either the integer 0, the floating point number 0.0, or a NULL ** pointer. Subsequent calls to [sqlite3_errcode()] will return ** [SQLITE_NOMEM].)^ */ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol); SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol); SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object ** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors ** or if the statement is never been evaluated, then sqlite3_finalize() returns ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then ** sqlite3_finalize(S) returns the appropriate [error code] or ** [extended error code]. |
| ︙ | ︙ | |||
4261 4262 4263 4264 4265 4266 4267 | ** ** The application must finalize every [prepared statement] in order to avoid ** resource leaks. It is a grievous error for the application to try to use ** a prepared statement after it has been finalized. Any use of a prepared ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ | | > | 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 | ** ** The application must finalize every [prepared statement] in order to avoid ** resource leaks. It is a grievous error for the application to try to use ** a prepared statement after it has been finalized. Any use of a prepared ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt); /* ** CAPI3REF: Reset A Prepared Statement Object ** METHOD: sqlite3_stmt ** ** The sqlite3_reset() function is called to reset a [prepared statement] ** object back to its initial state, ready to be re-executed. ** ^Any SQL statement variables that had values bound to them using ** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. ** Use [sqlite3_clear_bindings()] to reset the bindings. ** |
| ︙ | ︙ | |||
4287 4288 4289 4290 4291 4292 4293 | ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code]. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ | | > | 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 |
** ^If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite3_reset(S)] returns an appropriate [error code].
**
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates. The only differences between
** these routines are the text encoding expected for
** the second parameter (the name of the function being created)
** and the presence or absence of a destructor callback for
|
| ︙ | ︙ | |||
4386 4387 4388 4389 4390 4391 4392 | ** ^Built-in functions may be overloaded by new application-defined functions. ** ** ^An application-defined function is permitted to call other ** SQLite interfaces. However, such calls must not ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ | | | | | 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 | ** ^Built-in functions may be overloaded by new application-defined functions. ** ** ^An application-defined function is permitted to call other ** SQLite interfaces. However, such calls must not ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ SQLITE_API int SQLITE_STDCALL sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), |
| ︙ | ︙ | |||
4452 4453 4454 4455 4456 4457 4458 | ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid ** the use of these functions. To encourage programmers to avoid ** these functions, we will not explain what they do. */ #ifndef SQLITE_OMIT_DEPRECATED | | | | | | | > | 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 |
** These functions are [deprecated]. In order to maintain
** backwards compatibility with older code, these functions continue
** to be supported. However, new applications should avoid
** the use of these functions. To encourage programmers to avoid
** these functions, we will not explain what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
/*
** CAPI3REF: Obtaining SQL Function Parameter Values
** METHOD: sqlite3_value
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
** the function or aggregate.
**
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
|
| ︙ | ︙ | |||
4506 4507 4508 4509 4510 4511 4512 | ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ | | | | | | | | | | | | | > | 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 | ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*); SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*); SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*); SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context ** METHOD: sqlite3_context ** ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** ** ^The first time the sqlite3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite ** allocates N of memory, zeroes out that memory, and returns a pointer |
| ︙ | ︙ | |||
4561 4562 4563 4564 4565 4566 4567 | ** [sqlite3_context | SQL function context] that is the first parameter ** to the xStep or xFinal callback routine that implements the aggregate ** function. ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ | | > | > | > | 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 | ** [sqlite3_context | SQL function context] that is the first parameter ** to the xStep or xFinal callback routine that implements the aggregate ** function. ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions ** METHOD: sqlite3_context ** ** ^The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) ** of the [sqlite3_create_function()] ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. ** ** This routine must be called from the same thread in which ** the application-defined function is running. */ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*); /* ** CAPI3REF: Database Connection For Functions ** METHOD: sqlite3_context ** ** ^The sqlite3_context_db_handle() interface returns a copy of ** the pointer to the [database connection] (the 1st parameter) ** of the [sqlite3_create_function()] ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. */ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to ** multiple invocations of the same SQL function during query execution, under ** some circumstances the associated metadata may be preserved. An example ** of where this might be useful is in a regular-expression matching ** function. The compiled version of the regular expression can be stored as |
| ︙ | ︙ | |||
4638 4639 4640 4641 4642 4643 4644 | ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. */ | | | | 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 | ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. */ SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior ** ** These are special values for the destructor that is passed in as the ** final argument to routines like [sqlite3_result_blob()]. ^If the destructor |
| ︙ | ︙ | |||
4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 | */ typedef void (*sqlite3_destructor_type)(void*); #define SQLITE_STATIC ((sqlite3_destructor_type)0) #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) /* ** CAPI3REF: Setting The Result Of An SQL Function ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See ** [sqlite3_create_function()] and [sqlite3_create_function16()] ** for additional information. ** ** These functions work very much like the [parameter binding] family of | > | 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 | */ typedef void (*sqlite3_destructor_type)(void*); #define SQLITE_STATIC ((sqlite3_destructor_type)0) #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) /* ** CAPI3REF: Setting The Result Of An SQL Function ** METHOD: sqlite3_context ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See ** [sqlite3_create_function()] and [sqlite3_create_function16()] ** for additional information. ** ** These functions work very much like the [parameter binding] family of |
| ︙ | ︙ | |||
4774 4775 4776 4777 4778 4779 4780 | ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ | | | | | | | | | | | | | | | | | | | > | 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 |
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
/*
** CAPI3REF: Define New Collating Sequences
** METHOD: sqlite3
**
** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument.
**
** ^The name of the collation is a UTF-8 string
** for sqlite3_create_collation() and sqlite3_create_collation_v2()
** and a UTF-16 string in native byte order for sqlite3_create_collation16().
|
| ︙ | ︙ | |||
4874 4875 4876 4877 4878 4879 4880 | ** themselves rather than expecting SQLite to deal with it for them. ** This is different from every other SQLite interface. The inconsistency ** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ | | | | > | 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 | ** themselves rather than expecting SQLite to deal with it for them. ** This is different from every other SQLite interface. The inconsistency ** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); /* ** CAPI3REF: Collation Needed Callbacks ** METHOD: sqlite3 ** ** ^To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the ** [database connection] to be invoked whenever an undefined collation ** sequence is required. ** ** ^If the function is registered using the sqlite3_collation_needed() API, |
| ︙ | ︙ | |||
4923 4924 4925 4926 4927 4928 4929 | ** sequence function required. The fourth parameter is the name of the ** required collation sequence.)^ ** ** The callback function should register the desired collation using ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. */ | | | | | | | | | | 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 | ** sequence function required. The fourth parameter is the name of the ** required collation sequence.)^ ** ** The callback function should register the desired collation using ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef SQLITE_HAS_CODEC /* ** Specify the key for an encrypted database. This routine should be ** called right after sqlite3_open(). ** ** The code to implement this API is not available in the public release ** of SQLite. */ SQLITE_API int SQLITE_STDCALL sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); SQLITE_API int SQLITE_STDCALL sqlite3_key_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The key */ ); /* ** Change the key on an open database. If the current database is not ** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the ** database is decrypted. ** ** The code to implement this API is not available in the public release ** of SQLite. */ SQLITE_API int SQLITE_STDCALL sqlite3_rekey( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The new key */ ); /* ** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ SQLITE_API void SQLITE_STDCALL sqlite3_activate_see( const char *zPassPhrase /* Activation phrase */ ); #endif #ifdef SQLITE_ENABLE_CEROD /* ** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod( const char *zPassPhrase /* Activation phrase */ ); #endif /* ** CAPI3REF: Suspend Execution For A Short Time ** |
| ︙ | ︙ | |||
5006 5007 5008 5009 5010 5011 5012 | ** ** ^SQLite implements this interface by calling the xSleep() ** method of the default [sqlite3_vfs] object. If the xSleep() method ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ | | | 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 | ** ** ^SQLite implements this interface by calling the xSleep() ** method of the default [sqlite3_vfs] object. If the xSleep() method ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int); /* ** CAPI3REF: Name Of The Folder Holding Temporary Files ** ** ^(If this global variable is made to point to a string which is ** the name of a folder (a.k.a. directory), then all temporary files ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| ︙ | ︙ | |||
5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 |
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
**
** If certain kinds of errors occur on a statement within a multi-statement
** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
** transaction might be rolled back automatically. The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
| > | > | > | > | > | > | 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 |
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
** METHOD: sqlite3
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
**
** If certain kinds of errors occur on a statement within a multi-statement
** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
** transaction might be rolled back automatically. The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
** METHOD: sqlite3_stmt
**
** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection]
** returned by sqlite3_db_handle is the same [database connection]
** that was the first argument
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
**
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file
** has the name "main". If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
** a NULL pointer is returned.
**
** ^The filename returned by this function is the output of the
** xFullPathname method of the [VFS]. ^In other words, the filename
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
** METHOD: sqlite3
**
** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
** METHOD: sqlite3
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb. ^If no prepared statement
** satisfies the conditions of this routine, it returns NULL.
**
** The [database connection] pointer D in a call to
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
** METHOD: sqlite3
**
** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed].
** ^Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** ^The sqlite3_rollback_hook() interface registers a callback
** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
|
| ︙ | ︙ | |||
5224 5225 5226 5227 5228 5229 5230 | ** rolled back if an explicit "ROLLBACK" statement is executed, or ** an error or constraint causes an implicit rollback to occur. ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** ** See also the [sqlite3_update_hook()] interface. */ | | | > | 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 | ** rolled back if an explicit "ROLLBACK" statement is executed, or ** an error or constraint causes an implicit rollback to occur. ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** ** See also the [sqlite3_update_hook()] interface. */ SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument ** to be invoked whenever a row is updated, inserted or deleted in ** a rowid table. ** ^Any callback set by a previous call to this function ** for the same database connection is overridden. |
| ︙ | ︙ | |||
5275 5276 5277 5278 5279 5280 5281 | ** returns the P argument from the previous call ** on the same [database connection] D, or NULL for ** the first call on D. ** ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] ** interfaces. */ | | | 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 | ** returns the P argument from the previous call ** on the same [database connection] D, or NULL for ** the first call on D. ** ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] ** interfaces. */ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache |
| ︙ | ︙ | |||
5315 5316 5317 5318 5319 5320 5321 | ** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ | | | > | | 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 | ** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory ** ** ^The sqlite3_release_memory() interface attempts to free N bytes ** of heap memory by deallocating non-essential memory allocations ** held by the database library. Memory used to cache database ** pages to improve performance is an example of non-essential memory. ** ^sqlite3_release_memory() returns the number of bytes actually freed, ** which might be more or less than the amount requested. ** ^The sqlite3_release_memory() routine is a no-op returning zero ** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** ** See also: [sqlite3_db_release_memory()] */ SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int); /* ** CAPI3REF: Free Memory Used By A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the ** [sqlite3_release_memory()] interface, this interface is in effect even ** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is ** omitted. ** ** See also: [sqlite3_release_memory()] */ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. ** ^SQLite strives to keep heap memory utilization below the soft heap |
| ︙ | ︙ | |||
5396 5397 5398 5399 5400 5401 5402 | ** the page cache is the predominate memory user in SQLite, most ** applications will achieve adequate soft heap limit enforcement without ** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** ** The circumstances under which SQLite will enforce the soft heap limit may ** changes in future releases of SQLite. */ | | | > | 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 | ** the page cache is the predominate memory user in SQLite, most ** applications will achieve adequate soft heap limit enforcement without ** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** ** The circumstances under which SQLite will enforce the soft heap limit may ** changes in future releases of SQLite. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface ** DEPRECATED ** ** This is a deprecated version of the [sqlite3_soft_heap_limit64()] ** interface. This routine is provided for historical compatibility ** only. All new applications should use the ** [sqlite3_soft_heap_limit64()] interface rather than this one. */ SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N); /* ** CAPI3REF: Extract Metadata About A Column Of A Table ** METHOD: sqlite3 ** ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns ** information about column C of table T in database D ** on [database connection] X.)^ ^The sqlite3_table_column_metadata() ** interface returns SQLITE_OK and fills in the non-NULL pointers in ** the final five arguments with appropriate values if the specified ** column exists. ^The sqlite3_table_column_metadata() interface returns |
| ︙ | ︙ | |||
5476 5477 5478 5479 5480 5481 5482 | ** auto increment: 0 ** </pre>)^ ** ** ^This function causes all database schemas to be read from disk and ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ | | > | 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 | ** auto increment: 0 ** </pre>)^ ** ** ^This function causes all database schemas to be read from disk and ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ const char *zColumnName, /* Column name */ char const **pzDataType, /* OUTPUT: Declared data type */ char const **pzCollSeq, /* OUTPUT: Collation sequence name */ int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ int *pPrimaryKey, /* OUTPUT: True if column part of PK */ int *pAutoinc /* OUTPUT: True if column is auto-increment */ ); /* ** CAPI3REF: Load An Extension ** METHOD: sqlite3 ** ** ^This interface loads an SQLite extension library from the named file. ** ** ^The sqlite3_load_extension() interface attempts to load an ** [SQLite extension] library contained in the file zFile. If ** the file cannot be loaded directly, attempts are made to load ** with various operating-system specific extensions added. |
| ︙ | ︙ | |||
5522 5523 5524 5525 5526 5527 5528 | ** ** ^Extension loading must be enabled using ** [sqlite3_enable_load_extension()] prior to calling this API, ** otherwise an error will be returned. ** ** See also the [load_extension() SQL function]. */ | | > | | 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 | ** ** ^Extension loading must be enabled using ** [sqlite3_enable_load_extension()] prior to calling this API, ** otherwise an error will be returned. ** ** See also the [load_extension() SQL function]. */ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ); /* ** CAPI3REF: Enable Or Disable Extension Loading ** METHOD: sqlite3 ** ** ^So as not to open security holes in older applications that are ** unprepared to deal with [extension loading], and as a means of disabling ** [extension loading] while evaluating user-entered SQL, the following API ** is provided to turn the [sqlite3_load_extension()] mechanism on and off. ** ** ^Extension loading is off by default. ** ^Call the sqlite3_enable_load_extension() routine with onoff==1 ** to turn extension loading on and call it with onoff==0 to turn ** it back off again. */ SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ** CAPI3REF: Automatically Load Statically Linked Extensions ** ** ^This interface causes the xEntryPoint() function to be invoked for ** each new [database connection] that is created. The idea here is that ** xEntryPoint() is the entry point for a statically linked [SQLite extension] |
| ︙ | ︙ | |||
5580 5581 5582 5583 5584 5585 5586 | ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already ** on the list of automatic extensions is a harmless no-op. ^No entry point ** will be called more than once for each database connection that is opened. ** ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ | | | | | 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 | ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already ** on the list of automatic extensions is a harmless no-op. ^No entry point ** will be called more than once for each database connection that is opened. ** ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading ** ** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the ** initialization routine X that was registered using a prior call to ** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] ** routine returns 1 if initialization routine X was successfully ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading ** ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void); /* ** The interface to the virtual-table mechanism is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** ** When the virtual-table mechanism stabilizes, we will declare the |
| ︙ | ︙ | |||
5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 | #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 #define SQLITE_INDEX_CONSTRAINT_GE 32 #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* ** CAPI3REF: Register A Virtual Table Implementation ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before ** creating a new [virtual table] using the module and before using a ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified | > | 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 | #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 #define SQLITE_INDEX_CONSTRAINT_GE 32 #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* ** CAPI3REF: Register A Virtual Table Implementation ** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before ** creating a new [virtual table] using the module and before using a ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified |
| ︙ | ︙ | |||
5803 5804 5805 5806 5807 5808 5809 | ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ | | | | 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 | ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ SQLITE_API int SQLITE_STDCALL sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ void(*xDestroy)(void*) /* Module destructor function */ ); |
| ︙ | ︙ | |||
5872 5873 5874 5875 5876 5877 5878 | ** CAPI3REF: Declare The Schema Of A Virtual Table ** ** ^The [xCreate] and [xConnect] methods of a ** [virtual table module] call this interface ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ | | > | | 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 | ** CAPI3REF: Declare The Schema Of A Virtual Table ** ** ^The [xCreate] and [xConnect] methods of a ** [virtual table module] call this interface ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table ** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions ** using the [xFindFunction] method of the [virtual table module]. ** But global versions of those functions ** must exist in order to be overloaded.)^ ** ** ^(This API makes sure a global version of a function with a particular ** name and number of parameters exists. If no such function exists ** before this API is called, a new function is created.)^ ^The implementation ** of the new function always causes an exception to be thrown. So ** the new function is not good for anything by itself. Its only ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up ** to a comment remarkably similar to this one) is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** |
| ︙ | ︙ | |||
5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 | ** can be used to read or write small subsections of the BLOB. ** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. */ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; ** in other words, the same BLOB that would be selected by: ** ** <pre> ** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; | > > | 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 | ** can be used to read or write small subsections of the BLOB. ** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. */ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O ** METHOD: sqlite3 ** CONSTRUCTOR: sqlite3_blob ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; ** in other words, the same BLOB that would be selected by: ** ** <pre> ** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; |
| ︙ | ︙ | |||
5987 5988 5989 5990 5991 5992 5993 | ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces ** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. */ | | > | > | > | > | 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 | ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces ** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, const char *zColumn, sqlite3_int64 iRow, int flags, sqlite3_blob **ppBlob ); /* ** CAPI3REF: Move a BLOB Handle to a New Row ** METHOD: sqlite3_blob ** ** ^This function is used to move an existing blob handle so that it points ** to a different row of the same database table. ^The new row is identified ** by the rowid value passed as the second argument. Only the row can be ** changed. ^The database, table and column on which the blob handle is open ** remain the same. Moving an existing blob handle to a new row can be ** faster than closing the existing handle and opening a new one. ** ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - ** it must exist and there must be either a blob or text value stored in ** the nominated column.)^ ^If the new row is not present in the table, or if ** it does not contain a blob or text value, or if another error occurs, an ** SQLite error code is returned and the blob handle is considered aborted. ** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or ** [sqlite3_blob_reopen()] on an aborted blob handle immediately return ** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle ** always returns zero. ** ** ^This function sets the database handle error code and message. */ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); /* ** CAPI3REF: Close A BLOB Handle ** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed ** unconditionally. Even if this routine returns an error code, the ** handle is still closed.)^ ** ** ^If the blob handle being closed was opened for read-write access, and if ** the database is in auto-commit mode and there are no other open read-write ** blob handles or active write statements, the current transaction is ** committed. ^If an error occurs while committing the transaction, an error ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an ** open blob handle results in undefined behaviour. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *); /* ** CAPI3REF: Read Data From A BLOB Incrementally ** METHOD: sqlite3_blob ** ** ^(This function is used to read data from an open [BLOB handle] into a ** caller-supplied buffer. N bytes of data are copied into buffer Z ** from the open BLOB, starting at offset iOffset.)^ ** ** ^If offset iOffset is less than N bytes from the end of the BLOB, ** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is |
| ︙ | ︙ | |||
6084 6085 6086 6087 6088 6089 6090 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_write()]. */ | | > | 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_write()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally ** METHOD: sqlite3_blob ** ** ^(This function is used to write data into an open [BLOB handle] from a ** caller-supplied buffer. N bytes of data are copied from the buffer Z ** into the open BLOB, starting at offset iOffset.)^ ** ** ^(On success, sqlite3_blob_write() returns SQLITE_OK. ** Otherwise, an [error code] or an [extended error code] is returned.)^ |
| ︙ | ︙ | |||
6125 6126 6127 6128 6129 6130 6131 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_read()]. */ | | | 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_read()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** CAPI3REF: Virtual File System Objects ** ** A virtual filesystem (VFS) is an [sqlite3_vfs] object ** that SQLite uses to interact ** with the underlying operating system. Most SQLite builds come with a |
| ︙ | ︙ | |||
6156 6157 6158 6159 6160 6161 6162 | ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** ** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ | | | | | 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 | ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** ** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName); SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*); /* ** CAPI3REF: Mutexes ** ** The SQLite core uses these routines for thread ** synchronization. Though they are intended for internal ** use by SQLite, code that links against SQLite is |
| ︙ | ︙ | |||
6271 6272 6273 6274 6275 6276 6277 | ** ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or ** sqlite3_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ | | | | | | | 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 | ** ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or ** sqlite3_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int); SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*); SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*); SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*); SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object ** ** An instance of this structure defines the low-level routines ** used to allocate and use mutexes. ** |
| ︙ | ︙ | |||
6385 6386 6387 6388 6389 6390 6391 | ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the ** call to sqlite3_mutex_held() to fail, so a non-zero return is ** the appropriate thing to do. The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG | | | | 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 | ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the ** call to sqlite3_mutex_held() to fail, so a non-zero return is ** the appropriate thing to do. The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*); SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*); #endif /* ** CAPI3REF: Mutex Types ** ** The [sqlite3_mutex_alloc()] interface takes a single argument ** which is one of these integer constants. |
| ︙ | ︙ | |||
6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ /* ** CAPI3REF: Retrieve the mutex for a database connection ** ** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ | > | > | 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** ** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files ** METHOD: sqlite3 ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated ** with a particular database identified by the second argument. ^The ** name of the database is "main" for the main database or "temp" for the ** TEMP database, or the name that appears after the AS keyword for ** databases that are added using the [ATTACH] SQL command. |
| ︙ | ︙ | |||
6456 6457 6458 6459 6460 6461 6462 | ** or [sqlite3_errmsg()]. The underlying xFileControl method might ** also return SQLITE_ERROR. There is no way to distinguish between ** an incorrect zDbName and an SQLITE_ERROR return from the underlying ** xFileControl method. ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ | | | | 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 | ** or [sqlite3_errmsg()]. The underlying xFileControl method might ** also return SQLITE_ERROR. There is no way to distinguish between ** an incorrect zDbName and an SQLITE_ERROR return from the underlying ** xFileControl method. ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); /* ** CAPI3REF: Testing Interface ** ** ^The sqlite3_test_control() interface is used to read out internal ** state of SQLite and to inject faults into SQLite for testing ** purposes. ^The first parameter is an operation code that determines ** the number, meaning, and operation of all subsequent parameters. ** ** This interface is not for use by applications. It exists solely ** for verifying the correct operation of the SQLite library. Depending ** on how the SQLite library is compiled, this interface might not exist. ** ** The details of the operation codes, their meanings, the parameters ** they take, and what they do are all subject to change without notice. ** Unlike most of the SQLite API, this function is not guaranteed to ** operate consistently from one release to the next. */ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...); /* ** CAPI3REF: Testing Interface Operation Codes ** ** These constants are the valid operation code parameters used ** as the first argument to [sqlite3_test_control()]. ** |
| ︙ | ︙ | |||
6538 6539 6540 6541 6542 6543 6544 | ** ** If either the current value or the highwater mark is too large to ** be represented by a 32-bit integer, then the values returned by ** sqlite3_status() are undefined. ** ** See also: [sqlite3_db_status()] */ | | | | 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 | ** ** If either the current value or the highwater mark is too large to ** be represented by a 32-bit integer, then the values returned by ** sqlite3_status() are undefined. ** ** See also: [sqlite3_db_status()] */ SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); SQLITE_API int SQLITE_STDCALL sqlite3_status64( int op, sqlite3_int64 *pCurrent, sqlite3_int64 *pHighwater, int resetFlag ); |
| ︙ | ︙ | |||
6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 | #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 #define SQLITE_STATUS_SCRATCH_SIZE 8 #define SQLITE_STATUS_MALLOC_COUNT 9 /* ** CAPI3REF: Database Connection Status ** ** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the ** database connection object to be interrogated. ^The second argument ** is an integer constant, taken from the set of ** [SQLITE_DBSTATUS options], that ** determines the parameter to interrogate. The set of ** [SQLITE_DBSTATUS options] is likely ** to grow in future releases of SQLite. ** ** ^The current value of the requested parameter is written into *pCur ** and the highest instantaneous value is written into *pHiwtr. ^If ** the resetFlg is true, then the highest instantaneous value is ** reset back down to the current value. ** ** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a ** non-zero [error code] on failure. ** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ | > | | 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 |
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
#define SQLITE_STATUS_SCRATCH_SIZE 8
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
** CAPI3REF: Database Connection Status
** METHOD: sqlite3
**
** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the
** database connection object to be interrogated. ^The second argument
** is an integer constant, taken from the set of
** [SQLITE_DBSTATUS options], that
** determines the parameter to interrogate. The set of
** [SQLITE_DBSTATUS options] is likely
** to grow in future releases of SQLite.
**
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
|
| ︙ | ︙ | |||
6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 | #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number ** of times it has performed specific operations.)^ These counters can ** be used to monitor the performance characteristics of the prepared ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate | > | 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 | #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number ** of times it has performed specific operations.)^ These counters can ** be used to monitor the performance characteristics of the prepared ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate |
| ︙ | ︙ | |||
6791 6792 6793 6794 6795 6796 6797 | ** to be interrogated.)^ ** ^The current value of the requested counter is returned. ** ^If the resetFlg is true, then the counter is reset to zero after this ** interface call returns. ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ | | | 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 |
** to be interrogated.)^
** ^The current value of the requested counter is returned.
** ^If the resetFlg is true, then the counter is reset to zero after this
** interface call returns.
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
**
** These preprocessor macros define integer codes that name counter
** values associated with the [sqlite3_stmt_status()] interface.
|
| ︙ | ︙ | |||
7260 7261 7262 7263 7264 7265 7266 | ** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ | | | | | | > | 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 | ** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ const char *zDestName, /* Destination database name */ sqlite3 *pSource, /* Source database handle */ const char *zSourceName /* Source database name */ ); SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage); SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p); SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p); SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification ** METHOD: sqlite3 ** ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or ** individual tables within the shared-cache cannot be obtained. See ** [SQLite Shared-Cache Mode] for a description of shared-cache locking. ** ^This API may be used to register a callback that SQLite will invoke ** when the connection currently holding the required lock relinquishes it. |
| ︙ | ︙ | |||
7385 7386 7387 7388 7389 7390 7391 | ** ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ | | | | | | 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 | ** ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ ); /* ** CAPI3REF: String Comparison ** ** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications ** and extensions to compare the contents of two buffers containing UTF-8 ** strings in a case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *); SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: String Globbing * ** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches ** the glob pattern P, and it returns non-zero if string X does not match ** the glob pattern P. ^The definition of glob pattern matching used in ** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the ** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case ** sensitive. ** ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr); /* ** CAPI3REF: Error Logging Interface ** ** ^The [sqlite3_log()] interface writes a message into the [error log] ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. ** ^If logging is enabled, the zFormat string and subsequent arguments are |
| ︙ | ︙ | |||
7439 7440 7441 7442 7443 7444 7445 | ** ** To avoid deadlocks and other threading problems, the sqlite3_log() routine ** will not use dynamically allocated memory. The log message is stored in ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ | | > | 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 | ** ** To avoid deadlocks and other threading problems, the sqlite3_log() routine ** will not use dynamically allocated memory. The log message is stored in ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook ** METHOD: sqlite3 ** ** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. ** ** ^(The callback is invoked by SQLite after the commit has taken place and ** the associated write-lock on the database released)^, so the implementation ** may read, write or [checkpoint] the database as required. |
| ︙ | ︙ | |||
7474 7475 7476 7477 7478 7479 7480 | ** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^Note that the ** [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** those overwrite any prior [sqlite3_wal_hook()] settings. */ | | > | 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 | ** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^Note that the ** [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** those overwrite any prior [sqlite3_wal_hook()] settings. */ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* ); /* ** CAPI3REF: Configure an auto-checkpoint ** METHOD: sqlite3 ** ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around ** [sqlite3_wal_hook()] that causes any database on [database connection] D ** to automatically [checkpoint] ** after committing a transaction if there are N or ** more frames in the [write-ahead log] file. ^Passing zero or ** a negative value as the nFrame parameter disables automatic |
| ︙ | ︙ | |||
7508 7509 7510 7511 7512 7513 7514 | ** ** ^Every new [database connection] defaults to having the auto-checkpoint ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] ** pages. The use of this interface ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ | | > | > | 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 | ** ** ^Every new [database connection] defaults to having the auto-checkpoint ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] ** pages. The use of this interface ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N); /* ** CAPI3REF: Checkpoint a database ** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ ** ** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the ** [write-ahead log] for database X on [database connection] D to be ** transferred into the database file and for the write-ahead log to ** be reset. See the [checkpointing] documentation for addition ** information. ** ** This interface used to be the only way to cause a checkpoint to ** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] ** interface was added. This interface is retained for backwards ** compatibility and as a convenience for applications that need to manually ** start a callback but which do not need the full power (and corresponding ** complication) of [sqlite3_wal_checkpoint_v2()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Checkpoint a database ** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint ** operation on database X of [database connection] D in mode M. Status ** information is written back into integers pointed to by L and C.)^ ** ^(The M parameter must be a valid [checkpoint mode]:)^ ** ** <dl> |
| ︙ | ︙ | |||
7622 7623 7624 7625 7626 7627 7628 | ** the sqlite3_wal_checkpoint_v2() interface ** sets the error information that is queried by ** [sqlite3_errcode()] and [sqlite3_errmsg()]. ** ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ | | | 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 | ** the sqlite3_wal_checkpoint_v2() interface ** sets the error information that is queried by ** [sqlite3_errcode()] and [sqlite3_errmsg()]. ** ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ int *pnLog, /* OUT: Size of WAL log in frames */ int *pnCkpt /* OUT: Total number of frames checkpointed */ ); |
| ︙ | ︙ | |||
7658 7659 7660 7661 7662 7663 7664 | ** If this interface is invoked outside the context of an xConnect or ** xCreate virtual table method then the behavior is undefined. ** ** At present, there is only one option that may be configured using ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ | | | 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 | ** If this interface is invoked outside the context of an xConnect or ** xCreate virtual table method then the behavior is undefined. ** ** At present, there is only one option that may be configured using ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options ** ** These macros define the various options to the ** [sqlite3_vtab_config()] interface that [virtual table] implementations ** can use to customize and optimize their behavior. |
| ︙ | ︙ | |||
7711 7712 7713 7714 7715 7716 7717 | ** This function may only be called from within a call to the [xUpdate] method ** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The ** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], ** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode ** of the SQL statement that triggered the call to the [xUpdate] method of the ** [virtual table]. */ | | | 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 |
** This function may only be called from within a call to the [xUpdate] method
** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation what the [ON CONFLICT] mode
|
| ︙ | ︙ | |||
7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 | #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 /* ** CAPI3REF: Prepared Statement Scan Status ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only | > | 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 | #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only |
| ︙ | ︙ | |||
7815 7816 7817 7818 7819 7820 7821 | ** ^Statistics might not be available for all loops in all statements. ^In cases ** where there exist loops with no available statistics, this function behaves ** as if the loop did not exist - it returns non-zero and leave the variable ** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ | | > | | 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 | ** ^Statistics might not be available for all loops in all statements. ^In cases ** where there exist loops with no available statistics, this function behaves ** as if the loop did not exist - it returns non-zero and leave the variable ** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); /* ** CAPI3REF: Zero Scan-Status Counters ** METHOD: sqlite3_stmt ** ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. ** ** This API is only available if the library is built with pre-processor ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. */ SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT |
| ︙ | ︙ | |||
7885 7886 7887 7888 7889 7890 7891 | /* ** Register a geometry callback named zGeom that can be used as part of an ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ | | | 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 | /* ** Register a geometry callback named zGeom that can be used as part of an ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), void *pContext ); |
| ︙ | ︙ | |||
7911 7912 7913 7914 7915 7916 7917 | /* ** Register a 2nd-generation geometry callback named zScore that can be ** used as part of an R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) */ | | | 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 | /* ** Register a 2nd-generation geometry callback named zScore that can be ** used as part of an R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) */ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( sqlite3 *db, const char *zQueryFunc, int (*xQueryFunc)(sqlite3_rtree_query_info*), void *pContext, void (*xDestructor)(void*) ); |
| ︙ | ︙ | |||
8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 | # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif /* ** Return true (non-zero) if the input is an integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() ** macros to verify that we have tested SQLite for large-file support. */ #define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) | > > > > > > > > > > > > > > > > > > > > > > > > > > | 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 |
# define ALWAYS(X) ((X)?1:(assert(0),0))
# define NEVER(X) ((X)?(assert(0),1):0)
#else
# define ALWAYS(X) (X)
# define NEVER(X) (X)
#endif
/*
** Declarations used for tracing the operating system interfaces.
*/
#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
(defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
extern int sqlite3OSTrace;
# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
# define SQLITE_HAVE_OS_TRACE
#else
# define OSTRACE(X)
# undef SQLITE_HAVE_OS_TRACE
#endif
/*
** Is the sqlite3ErrName() function needed in the build? Currently,
** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when
** OSTRACE is enabled), and by several "test*.c" files (which are
** compiled using SQLITE_TEST).
*/
#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \
(defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
# define SQLITE_NEED_ERR_NAME
#else
# undef SQLITE_NEED_ERR_NAME
#endif
/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits. This macro is used inside of various testcase()
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
|
| ︙ | ︙ | |||
9155 9156 9157 9158 9159 9160 9161 | ** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL ** macros become no-ops and have zero performance impact. */ #ifdef SQLITE_OMIT_WSD #define SQLITE_WSD const #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) | | | | 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 | ** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL ** macros become no-ops and have zero performance impact. */ #ifdef SQLITE_OMIT_WSD #define SQLITE_WSD const #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J); SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L); #else #define SQLITE_WSD #define GLOBAL(t,v) v #define sqlite3GlobalConfig sqlite3Config #endif /* |
| ︙ | ︙ | |||
9845 9846 9847 9848 9849 9850 9851 | /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c ** are encoded into bitvectors as follows: */ #define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */ | < | | | | | | | | | | | | | | | | | | | | | | | | 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 |
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
#define OPFLG_IN1 0x0002 /* in1: P1 is an input */
#define OPFLG_IN2 0x0004 /* in2: P2 is an input */
#define OPFLG_IN3 0x0008 /* in3: P3 is an input */
#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */
#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
/* 16 */ 0x01, 0x01, 0x02, 0x12, 0x01, 0x02, 0x03, 0x08,\
/* 24 */ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\
/* 32 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x02,\
/* 40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\
/* 48 */ 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,\
/* 56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09,\
/* 64 */ 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x26,\
/* 72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\
/* 80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\
/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
/* 96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\
/* 112 */ 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x00,\
/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 128 */ 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00, 0x01,\
/* 136 */ 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01,\
/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\
/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
|
| ︙ | ︙ | |||
9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 | #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); | > | 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 | #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); |
| ︙ | ︙ | |||
11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 11080 | #define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ #define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ #define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ | > | 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 | #define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ #define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ #define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ #define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ |
| ︙ | ︙ | |||
11397 11398 11399 11400 11401 11402 11403 | int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ }; /* | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > | 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 |
int nRef; /* Number of pointers to this structure */
u8 bConstraint; /* True if constraints are supported */
int iSavepoint; /* Depth of the SAVEPOINT stack */
VTable *pNext; /* Next in linked list (see above) */
};
/*
** The schema for each SQL table and view is represented in memory
** by an instance of the following structure.
*/
struct Table {
char *zName; /* Name of the table or view */
Column *aCol; /* Information about each column */
Index *pIndex; /* List of SQL indexes on this table. */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
int tnum; /* Root BTree page for this table */
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
LogEst szTabRow; /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
LogEst costMult; /* Cost multiplier for using this table */
#endif
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
|
| ︙ | ︙ | |||
11462 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474 11475 11476 11477 11478 11479 11480 11481 11482 | Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* ** Allowed values for Table.tabFlags. */ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ /* ** Test to see whether or not a table is a virtual table. This is ** done as a macro so that it will be optimized out when virtual ** table support is omitted from the build. */ | > > > > > > > | 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 | Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* ** Allowed values for Table.tabFlags. ** ** TF_OOOHidden applies to virtual tables that have hidden columns that are ** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING ** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, ** the TF_OOOHidden attribute would apply in this case. Such tables require ** special handling during INSERT processing. */ #define TF_Readonly 0x01 /* Read-only system table */ #define TF_Ephemeral 0x02 /* An ephemeral table */ #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ #define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */ /* ** Test to see whether or not a table is a virtual table. This is ** done as a macro so that it will be optimized out when virtual ** table support is omitted from the build. */ |
| ︙ | ︙ | |||
12225 12226 12227 12228 12229 12230 12231 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ #define SF_Aggregate 0x0004 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0040 /* Part of a compound query */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ | | > | 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 | #define SF_Resolved 0x0002 /* Identifiers have been resolved */ #define SF_Aggregate 0x0004 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0040 /* Part of a compound query */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ #define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */ #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ #define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */ /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** |
| ︙ | ︙ | |||
12608 12609 12610 12611 12612 12613 12614 | * "SELECT" statement. The meanings of the other members is determined by the * value of "op" as follows: * * (op == TK_INSERT) * orconf -> stores the ON CONFLICT algorithm * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then * this stores a pointer to the SELECT statement. Otherwise NULL. | | | | | | | 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 |
* "SELECT" statement. The meanings of the other members is determined by the
* value of "op" as follows:
*
* (op == TK_INSERT)
* orconf -> stores the ON CONFLICT algorithm
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
* this stores a pointer to the SELECT statement. Otherwise NULL.
* zTarget -> Dequoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
* statement, then this stores the column-names to be
* inserted into.
*
* (op == TK_DELETE)
* zTarget -> Dequoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
* zTarget -> Dequoted name of the table to update.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
* Otherwise NULL.
* pExprList -> A list of the columns to update and the expressions to update
* them to. See sqlite3Update() documentation of "pChanges"
* argument.
*
*/
struct TriggerStep {
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
u8 orconf; /* OE_Rollback etc. */
Trigger *pTrig; /* The trigger that this step is a part of */
Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
ExprList *pExprList; /* SET clause for UPDATE. */
IdList *pIdList; /* Column names for INSERT */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
};
|
| ︙ | ︙ | |||
12667 12668 12669 12670 12671 12672 12673 |
*/
struct StrAccum {
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
char *zBase; /* A base allocation. Not from malloc. */
char *zText; /* The string collected so far */
int nChar; /* Length of the string so far */
int nAlloc; /* Amount of space allocated in zText */
| | < | 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 |
*/
struct StrAccum {
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
char *zBase; /* A base allocation. Not from malloc. */
char *zText; /* The string collected so far */
int nChar; /* Length of the string so far */
int nAlloc; /* Amount of space allocated in zText */
int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
};
#define STRACCUM_NOMEM 1
#define STRACCUM_TOOBIG 2
/*
** A pointer to this structure is used to communicate information
|
| ︙ | ︙ | |||
12985 12986 12987 12988 12989 12990 12991 | #define SQLITE_PRINTF_INTERNAL 0x01 #define SQLITE_PRINTF_SQLFUNC 0x02 SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list); SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...); SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...); | | | 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 | #define SQLITE_PRINTF_INTERNAL 0x01 #define SQLITE_PRINTF_SQLFUNC 0x02 SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list); SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...); SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); #endif #if defined(SQLITE_TEST) SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); #endif #if defined(SQLITE_DEBUG) |
| ︙ | ︙ | |||
13332 13333 13334 13335 13336 13337 13338 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); SQLITE_PRIVATE u8 sqlite3HexToInt(int h); SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); | | | 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 13421 13422 13423 13424 13425 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); SQLITE_PRIVATE u8 sqlite3HexToInt(int h); SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); #if defined(SQLITE_NEED_ERR_NAME) SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| ︙ | ︙ | |||
13426 13427 13428 13429 13430 13431 13432 | void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), FuncDestructor *pDestructor ); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); | | | 13505 13506 13507 13508 13509 13510 13511 13512 13513 13514 13515 13516 13517 13518 13519 | void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), FuncDestructor *pDestructor ); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*); SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| ︙ | ︙ | |||
13644 13645 13646 13647 13648 13649 13650 |
** If the SQLITE_ENABLE IOTRACE exists then the global variable
** sqlite3IoTrace is a pointer to a printf-like routine used to
** print I/O tracing messages.
*/
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
| | | 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 |
** If the SQLITE_ENABLE IOTRACE exists then the global variable
** sqlite3IoTrace is a pointer to a printf-like routine used to
** print I/O tracing messages.
*/
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
#else
# define IOTRACE(A)
# define sqlite3VdbeIOTraceSql(X)
#endif
/*
** These routines are available for the mem2.c debugging memory allocator
|
| ︙ | ︙ | |||
14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 | "ENABLE_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_CEROD "ENABLE_CEROD", #endif #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif #if SQLITE_ENABLE_EXPENSIVE_ASSERT "ENABLE_EXPENSIVE_ASSERT", #endif #if SQLITE_ENABLE_FTS1 "ENABLE_FTS1", #endif | > > > | 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 | "ENABLE_ATOMIC_WRITE", #endif #if SQLITE_ENABLE_CEROD "ENABLE_CEROD", #endif #if SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif #if SQLITE_ENABLE_DBSTAT_VTAB "ENABLE_DBSTAT_VTAB", #endif #if SQLITE_ENABLE_EXPENSIVE_ASSERT "ENABLE_EXPENSIVE_ASSERT", #endif #if SQLITE_ENABLE_FTS1 "ENABLE_FTS1", #endif |
| ︙ | ︙ | |||
14357 14358 14359 14360 14361 14362 14363 | /* ** Given the name of a compile-time option, return true if that option ** was used and false if not. ** ** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix ** is not required for a match. */ | | | 14439 14440 14441 14442 14443 14444 14445 14446 14447 14448 14449 14450 14451 14452 14453 |
/*
** Given the name of a compile-time option, return true if that option
** was used and false if not.
**
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
** is not required for a match.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
int i, n;
#if SQLITE_ENABLE_API_ARMOR
if( zOptName==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
|
| ︙ | ︙ | |||
14385 14386 14387 14388 14389 14390 14391 | return 0; } /* ** Return the N-th compile-time option string. If N is out of range, ** return a NULL pointer. */ | | | 14467 14468 14469 14470 14471 14472 14473 14474 14475 14476 14477 14478 14479 14480 14481 |
return 0;
}
/*
** Return the N-th compile-time option string. If N is out of range,
** return a NULL pointer.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
if( N>=0 && N<ArraySize(azCompileOpt) ){
return azCompileOpt[N];
}
return 0;
}
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
| ︙ | ︙ | |||
15022 15023 15024 15025 15026 15027 15028 |
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
}
/*
** Query status information.
*/
| | | 15104 15105 15106 15107 15108 15109 15110 15111 15112 15113 15114 15115 15116 15117 15118 |
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
}
/*
** Query status information.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
int resetFlag
){
sqlite3_mutex *pMutex;
wsdStatInit;
|
| ︙ | ︙ | |||
15047 15048 15049 15050 15051 15052 15053 |
if( resetFlag ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
sqlite3_mutex_leave(pMutex);
(void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
return SQLITE_OK;
}
| | | | 15129 15130 15131 15132 15133 15134 15135 15136 15137 15138 15139 15140 15141 15142 15143 15144 15145 15146 15147 15148 15149 15150 15151 15152 15153 15154 15155 15156 15157 15158 15159 15160 |
if( resetFlag ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
}
sqlite3_mutex_leave(pMutex);
(void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
return SQLITE_OK;
}
SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
sqlite3_int64 iCur, iHwtr;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
#endif
rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
if( rc==0 ){
*pCurrent = (int)iCur;
*pHighwater = (int)iHwtr;
}
return rc;
}
/*
** Query status information for a single database connection
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
int *pHighwater, /* Write high-water mark here */
int resetFlag /* Reset high-water mark if true */
){
int rc = SQLITE_OK; /* Return code */
|
| ︙ | ︙ | |||
16688 16689 16690 16691 16692 16693 16694 | static sqlite3_vfs * SQLITE_WSD vfsList = 0; #define vfsList GLOBAL(sqlite3_vfs *, vfsList) /* ** Locate a VFS by name. If no name is given, simply return the ** first VFS on the list. */ | | | 16770 16771 16772 16773 16774 16775 16776 16777 16778 16779 16780 16781 16782 16783 16784 |
static sqlite3_vfs * SQLITE_WSD vfsList = 0;
#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
/*
** Locate a VFS by name. If no name is given, simply return the
** first VFS on the list.
*/
SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){
sqlite3_vfs *pVfs = 0;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
#endif
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return 0;
|
| ︙ | ︙ | |||
16734 16735 16736 16737 16738 16739 16740 | } /* ** Register a VFS with the system. It is harmless to register the same ** VFS multiple times. The new VFS becomes the default if makeDflt is ** true. */ | | | 16816 16817 16818 16819 16820 16821 16822 16823 16824 16825 16826 16827 16828 16829 16830 |
}
/*
** Register a VFS with the system. It is harmless to register the same
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return rc;
#endif
#ifdef SQLITE_ENABLE_API_ARMOR
if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
|
| ︙ | ︙ | |||
16762 16763 16764 16765 16766 16767 16768 | sqlite3_mutex_leave(mutex); return SQLITE_OK; } /* ** Unregister a VFS so that it is no longer accessible. */ | | | 16844 16845 16846 16847 16848 16849 16850 16851 16852 16853 16854 16855 16856 16857 16858 |
sqlite3_mutex_leave(mutex);
return SQLITE_OK;
}
/*
** Unregister a VFS so that it is no longer accessible.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
sqlite3_mutex_enter(mutex);
vfsUnlink(pVfs);
sqlite3_mutex_leave(mutex);
return SQLITE_OK;
|
| ︙ | ︙ | |||
19098 19099 19100 19101 19102 19103 19104 | return rc; } /* ** Retrieve a pointer to a static mutex or allocate a new dynamic one. */ | | | | | | | | | 19180 19181 19182 19183 19184 19185 19186 19187 19188 19189 19190 19191 19192 19193 19194 19195 19196 19197 19198 19199 19200 19201 19202 19203 19204 19205 19206 19207 19208 19209 19210 19211 19212 19213 19214 19215 19216 19217 19218 19219 19220 19221 19222 19223 19224 19225 19226 19227 19228 19229 19230 19231 19232 19233 19234 19235 19236 19237 19238 19239 19240 19241 19242 19243 19244 19245 19246 19247 19248 19249 19250 19251 19252 19253 19254 19255 19256 19257 19258 19259 19260 19261 |
return rc;
}
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
#endif
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
if( !sqlite3GlobalConfig.bCoreMutex ){
return 0;
}
assert( GLOBAL(int, mutexIsInit) );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
/*
** Free a dynamic mutex.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
if( p ){
sqlite3GlobalConfig.mutex.xMutexFree(p);
}
}
/*
** Obtain the mutex p. If some other thread already has the mutex, block
** until it can be obtained.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
if( p ){
sqlite3GlobalConfig.mutex.xMutexEnter(p);
}
}
/*
** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
int rc = SQLITE_OK;
if( p ){
return sqlite3GlobalConfig.mutex.xMutexTry(p);
}
return rc;
}
/*
** The sqlite3_mutex_leave() routine exits a mutex that was previously
** entered by the same thread. The behavior is undefined if the mutex
** is not currently entered. If a NULL pointer is passed as an argument
** this function is a no-op.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
if( p ){
sqlite3GlobalConfig.mutex.xMutexLeave(p);
}
}
#ifndef NDEBUG
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
#endif
#endif /* !defined(SQLITE_MUTEX_OMIT) */
/************** End of mutex.c ***********************************************/
|
| ︙ | ︙ | |||
19810 19811 19812 19813 19814 19815 19816 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the ** switch. The following code should catch this problem at compile-time. */ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif | < < < < < < < < < < | 19892 19893 19894 19895 19896 19897 19898 19899 19900 19901 19902 19903 19904 19905 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the ** switch. The following code should catch this problem at compile-time. */ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif /* ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. */ #ifdef SQLITE_PERFORMANCE_TRACE /* |
| ︙ | ︙ | |||
20161 20162 20163 20164 20165 20166 20167 | /* As the winMutexInit() and winMutexEnd() functions are called as part ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the ** "interlocked" magic used here is probably not strictly necessary. */ static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; | | | | 20233 20234 20235 20236 20237 20238 20239 20240 20241 20242 20243 20244 20245 20246 20247 20248 |
/* As the winMutexInit() and winMutexEnd() functions are called as part
** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
** "interlocked" magic used here is probably not strictly necessary.
*/
static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */
SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
#if SQLITE_OS_WINRT
|
| ︙ | ︙ | |||
20458 20459 20460 20461 20462 20463 20464 | /* #include <stdarg.h> */ /* ** Attempt to release up to n bytes of non-essential memory currently ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ | | | 20530 20531 20532 20533 20534 20535 20536 20537 20538 20539 20540 20541 20542 20543 20544 |
/* #include <stdarg.h> */
/*
** Attempt to release up to n bytes of non-essential memory currently
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
return sqlite3PcacheReleaseMemory(n);
#else
/* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine
** is a no-op returning zero if SQLite is not compiled with
** SQLITE_ENABLE_MEMORY_MANAGEMENT. */
UNUSED_PARAMETER(n);
|
| ︙ | ︙ | |||
20558 20559 20560 20561 20562 20563 20564 | } #ifndef SQLITE_OMIT_DEPRECATED /* ** Deprecated external interface. Internal/core SQLite code ** should call sqlite3MemoryAlarm. */ | | | | > | 20630 20631 20632 20633 20634 20635 20636 20637 20638 20639 20640 20641 20642 20643 20644 20645 20646 20647 20648 20649 20650 20651 20652 20653 20654 20655 20656 20657 20658 20659 20660 20661 20662 20663 20664 20665 20666 20667 20668 20669 20670 20671 20672 20673 20674 20675 20676 20677 20678 20679 20680 20681 20682 20683 20684 20685 20686 |
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
** Deprecated external interface. Internal/core SQLite code
** should call sqlite3MemoryAlarm.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
){
return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
}
#endif
/*
** Set the soft heap-size limit for the library. Passing a zero or
** negative value indicates no limit.
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return -1;
#endif
sqlite3_mutex_enter(mem0.mutex);
priorLimit = mem0.alarmThreshold;
sqlite3_mutex_leave(mem0.mutex);
if( n<0 ) return priorLimit;
if( n>0 ){
sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
}else{
sqlite3MemoryAlarm(0, 0, 0);
}
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
}
/*
** Initialize the memory allocation subsystem.
*/
SQLITE_PRIVATE int sqlite3MallocInit(void){
int rc;
if( sqlite3GlobalConfig.m.xMalloc==0 ){
sqlite3MemSetDefault();
}
memset(&mem0, 0, sizeof(mem0));
if( sqlite3GlobalConfig.bCoreMutex ){
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
}
|
| ︙ | ︙ | |||
20635 20636 20637 20638 20639 20640 20641 |
}
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
|| sqlite3GlobalConfig.nPage<1 ){
sqlite3GlobalConfig.pPage = 0;
sqlite3GlobalConfig.szPage = 0;
sqlite3GlobalConfig.nPage = 0;
}
| | > > | 20708 20709 20710 20711 20712 20713 20714 20715 20716 20717 20718 20719 20720 20721 20722 20723 20724 |
}
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
|| sqlite3GlobalConfig.nPage<1 ){
sqlite3GlobalConfig.pPage = 0;
sqlite3GlobalConfig.szPage = 0;
sqlite3GlobalConfig.nPage = 0;
}
rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));
return rc;
}
/*
** Return true if the heap is currently under memory pressure - in other
** words if the amount of heap used is close to the limit set by
** sqlite3_soft_heap_limit().
*/
|
| ︙ | ︙ | |||
20660 20661 20662 20663 20664 20665 20666 | } memset(&mem0, 0, sizeof(mem0)); } /* ** Return the amount of memory currently checked out. */ | | | | 20735 20736 20737 20738 20739 20740 20741 20742 20743 20744 20745 20746 20747 20748 20749 20750 20751 20752 20753 20754 20755 20756 20757 20758 20759 20760 20761 20762 |
}
memset(&mem0, 0, sizeof(mem0));
}
/*
** Return the amount of memory currently checked out.
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
int n, mx;
sqlite3_int64 res;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
return res;
}
/*
** Return the maximum amount of memory that has ever been
** checked out since either the beginning of this process
** or since the most recent reset.
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
int n, mx;
sqlite3_int64 res;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
return res;
}
|
| ︙ | ︙ | |||
20764 20765 20766 20767 20768 20769 20770 | } /* ** This version of the memory allocation is for use by the application. ** First make sure the memory subsystem is initialized, then do the ** allocation. */ | | | | 20839 20840 20841 20842 20843 20844 20845 20846 20847 20848 20849 20850 20851 20852 20853 20854 20855 20856 20857 20858 20859 |
}
/*
** This version of the memory allocation is for use by the application.
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return n<=0 ? 0 : sqlite3Malloc(n);
}
SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return sqlite3Malloc(n);
}
/*
|
| ︙ | ︙ | |||
20911 20912 20913 20914 20915 20916 20917 |
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
return sqlite3GlobalConfig.m.xSize(p);
}
}
}
| | | | 20986 20987 20988 20989 20990 20991 20992 20993 20994 20995 20996 20997 20998 20999 21000 21001 21002 21003 21004 21005 21006 21007 21008 21009 |
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
return sqlite3GlobalConfig.m.xSize(p);
}
}
}
SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
}
/*
** Free memory previously obtained from sqlite3Malloc().
*/
SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
|
| ︙ | ︙ | |||
21029 21030 21031 21032 21033 21034 21035 | return pNew; } /* ** The public interface to sqlite3Realloc. Make sure that the memory ** subsystem is initialized prior to invoking sqliteRealloc. */ | | | | 21104 21105 21106 21107 21108 21109 21110 21111 21112 21113 21114 21115 21116 21117 21118 21119 21120 21121 21122 21123 21124 21125 |
return pNew;
}
/*
** The public interface to sqlite3Realloc. Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
if( n<0 ) n = 0; /* IMP: R-26507-47431 */
return sqlite3Realloc(pOld, n);
}
SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return sqlite3Realloc(pOld, n);
}
|
| ︙ | ︙ | |||
21401 21402 21403 21404 21405 21406 21407 21408 21409 21410 21411 21412 21413 21414 |
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** Set the StrAccum object to an error mode.
*/
static void setStrAccumError(StrAccum *p, u8 eError){
p->accError = eError;
p->nAlloc = 0;
}
/*
** Extra argument values from a PrintfArguments object
*/
| > | 21476 21477 21478 21479 21480 21481 21482 21483 21484 21485 21486 21487 21488 21489 21490 |
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** Set the StrAccum object to an error mode.
*/
static void setStrAccumError(StrAccum *p, u8 eError){
assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
p->accError = eError;
p->nAlloc = 0;
}
/*
** Extra argument values from a PrintfArguments object
*/
|
| ︙ | ︙ | |||
21515 21516 21517 21518 21519 21520 21521 |
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
/* Get the field width */
| < | > | > > > < < > > > > | > > | 21591 21592 21593 21594 21595 21596 21597 21598 21599 21600 21601 21602 21603 21604 21605 21606 21607 21608 21609 21610 21611 21612 21613 21614 21615 21616 21617 21618 21619 21620 21621 21622 21623 21624 21625 21626 21627 21628 21629 21630 21631 21632 21633 21634 21635 21636 21637 21638 21639 21640 21641 21642 21643 21644 21645 21646 |
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
/* Get the field width */
if( c=='*' ){
if( bArgList ){
width = (int)getIntArg(pArgList);
}else{
width = va_arg(ap,int);
}
if( width<0 ){
flag_leftjustify = 1;
width = width >= -2147483647 ? -width : 0;
}
c = *++fmt;
}else{
unsigned wx = 0;
while( c>='0' && c<='9' ){
wx = wx*10 + c - '0';
c = *++fmt;
}
testcase( wx>0x7fffffff );
width = wx & 0x7fffffff;
}
/* Get the precision */
if( c=='.' ){
c = *++fmt;
if( c=='*' ){
if( bArgList ){
precision = (int)getIntArg(pArgList);
}else{
precision = va_arg(ap,int);
}
c = *++fmt;
if( precision<0 ){
precision = precision >= -2147483647 ? -precision : -1;
}
}else{
unsigned px = 0;
while( c>='0' && c<='9' ){
px = px*10 + c - '0';
c = *++fmt;
}
testcase( px>0x7fffffff );
precision = px & 0x7fffffff;
}
}else{
precision = -1;
}
/* Get the conversion type modifier */
if( c=='l' ){
flag_long = 1;
|
| ︙ | ︙ | |||
21713 21714 21715 21716 21717 21718 21719 |
prefix = '-';
}else{
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
| > | | 21796 21797 21798 21799 21800 21801 21802 21803 21804 21805 21806 21807 21808 21809 21810 21811 |
prefix = '-';
}else{
if( flag_plussign ) prefix = '+';
else if( flag_blanksign ) prefix = ' ';
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
bufpt = "NaN";
length = 3;
break;
|
| ︙ | ︙ | |||
21768 21769 21770 21771 21772 21773 21774 |
flag_rtz = flag_altform2;
}
if( xtype==etEXP ){
e2 = 0;
}else{
e2 = exp;
}
| | | > | 21852 21853 21854 21855 21856 21857 21858 21859 21860 21861 21862 21863 21864 21865 21866 21867 21868 |
flag_rtz = flag_altform2;
}
if( xtype==etEXP ){
e2 = 0;
}else{
e2 = exp;
}
if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
bufpt = zExtra
= sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
if( bufpt==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}
zOut = bufpt;
nsd = 16 + flag_altform2*10;
|
| ︙ | ︙ | |||
22001 22002 22003 22004 22005 22006 22007 |
** able to accept at least N more bytes of text.
**
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero.
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
| | | | | > | > > | 22086 22087 22088 22089 22090 22091 22092 22093 22094 22095 22096 22097 22098 22099 22100 22101 22102 22103 22104 22105 22106 22107 22108 22109 22110 22111 22112 22113 22114 22115 22116 22117 22118 22119 22120 22121 22122 22123 22124 22125 22126 22127 22128 22129 22130 22131 22132 22133 22134 22135 22136 22137 22138 22139 22140 22141 22142 22143 22144 22145 22146 22147 22148 22149 22150 22151 22152 |
** able to accept at least N more bytes of text.
**
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero.
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return 0;
}
if( p->mxAlloc==0 ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
** to avoid having to call this routine too often */
szNew += p->nChar;
}
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_TOOBIG);
return 0;
}else{
p->nAlloc = (int)szNew;
}
if( p->db ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc64(zOld, p->nAlloc);
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
return 0;
}
}
return N;
}
/*
** Append N copies of character c to the given string buffer.
*/
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
testcase( p->nChar + (i64)N > 0x7fffffff );
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return;
}
while( (N--)>0 ) p->zText[p->nChar++] = c;
}
/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
|
| ︙ | ︙ | |||
22075 22076 22077 22078 22079 22080 22081 |
}
/*
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
| | | 22163 22164 22165 22166 22167 22168 22169 22170 22171 22172 22173 22174 22175 22176 22177 |
}
/*
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 || N==0 );
assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
}else{
assert( p->zText );
|
| ︙ | ︙ | |||
22104 22105 22106 22107 22108 22109 22110 |
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
p->zText[p->nChar] = 0;
| | < | < < < < | < < < | > > > > > > > > > > > | | < | < | 22192 22193 22194 22195 22196 22197 22198 22199 22200 22201 22202 22203 22204 22205 22206 22207 22208 22209 22210 22211 22212 22213 22214 22215 22216 22217 22218 22219 22220 22221 22222 22223 22224 22225 22226 22227 22228 22229 22230 22231 22232 22233 22234 22235 22236 22237 22238 22239 22240 22241 22242 22243 22244 22245 22246 22247 22248 22249 22250 22251 22252 22253 22254 22255 22256 22257 22258 22259 22260 22261 |
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
p->zText[p->nChar] = 0;
if( p->mxAlloc>0 && p->zText==p->zBase ){
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
setStrAccumError(p, STRACCUM_NOMEM);
}
}
}
return p->zText;
}
/*
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
if( p->zText!=p->zBase ){
sqlite3DbFree(p->db, p->zText);
}
p->zText = 0;
}
/*
** Initialize a string accumulator.
**
** p: The accumulator to be initialized.
** db: Pointer to a database connection. May be NULL. Lookaside
** memory is used if not NULL. db->mallocFailed is set appropriately
** when not NULL.
** zBase: An initial buffer. May be NULL in which case the initial buffer
** is malloced.
** n: Size of zBase in bytes. If total space requirements never exceed
** n then no memory allocations ever occur.
** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
** allocations will ever occur.
*/
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
p->zText = p->zBase = zBase;
p->db = db;
p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
p->accError = 0;
}
/*
** Print into memory obtained from sqliteMalloc(). Use the internal
** %-conversion extensions.
*/
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
assert( db!=0 );
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
}
return z;
}
|
| ︙ | ︙ | |||
22202 22203 22204 22205 22206 22207 22208 | return z; } /* ** Print into memory obtained from sqlite3_malloc(). Omit the internal ** %-conversion extensions. */ | | | < | | 22291 22292 22293 22294 22295 22296 22297 22298 22299 22300 22301 22302 22303 22304 22305 22306 22307 22308 22309 22310 22311 22312 22313 22314 22315 22316 22317 22318 22319 22320 22321 22322 22323 22324 22325 22326 22327 22328 22329 |
return z;
}
/*
** Print into memory obtained from sqlite3_malloc(). Omit the internal
** %-conversion extensions.
*/
SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( zFormat==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
return z;
}
/*
** Print into memory obtained from sqlite3_malloc()(). Omit the internal
** %-conversion extensions.
*/
SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
va_list ap;
char *z;
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
|
| ︙ | ︙ | |||
22252 22253 22254 22255 22256 22257 22258 | ** Oops: The first two arguments of sqlite3_snprintf() are backwards ** from the snprintf() standard. Unfortunately, it is too late to change ** this without breaking compatibility, so we just have to live with the ** mistake. ** ** sqlite3_vsnprintf() is the varargs version. */ | | | < | | 22340 22341 22342 22343 22344 22345 22346 22347 22348 22349 22350 22351 22352 22353 22354 22355 22356 22357 22358 22359 22360 22361 22362 22363 22364 22365 22366 22367 22368 |
** Oops: The first two arguments of sqlite3_snprintf() are backwards
** from the snprintf() standard. Unfortunately, it is too late to change
** this without breaking compatibility, so we just have to live with the
** mistake.
**
** sqlite3_vsnprintf() is the varargs version.
*/
SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
StrAccum acc;
if( n<=0 ) return zBuf;
#ifdef SQLITE_ENABLE_API_ARMOR
if( zBuf==0 || zFormat==0 ) {
(void)SQLITE_MISUSE_BKPT;
if( zBuf ) zBuf[0] = 0;
return zBuf;
}
#endif
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
return sqlite3StrAccumFinish(&acc);
}
SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
char *z;
va_list ap;
va_start(ap,zFormat);
z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
va_end(ap);
return z;
}
|
| ︙ | ︙ | |||
22289 22290 22291 22292 22293 22294 22295 |
** allocate memory because it might be called while the memory allocator
** mutex is held.
*/
static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
StrAccum acc; /* String accumulator */
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
| | < | | | < | 22376 22377 22378 22379 22380 22381 22382 22383 22384 22385 22386 22387 22388 22389 22390 22391 22392 22393 22394 22395 22396 22397 22398 22399 22400 22401 22402 22403 22404 22405 22406 22407 22408 22409 22410 22411 22412 22413 22414 22415 22416 22417 22418 |
** allocate memory because it might be called while the memory allocator
** mutex is held.
*/
static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
StrAccum acc; /* String accumulator */
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
}
/*
** Format and write a message to the log if logging is enabled.
*/
SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
renderLogMsg(iErrCode, zFormat, ap);
va_end(ap);
}
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
/*
** A version of printf() that understands %lld. Used for debugging.
** The printf() built into some versions of windows does not understand %lld
** and segfaults if you give it a long long int.
*/
SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
char zBuf[500];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3VXPrintf(&acc, 0, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf);
fflush(stdout);
}
|
| ︙ | ︙ | |||
22346 22347 22348 22349 22350 22351 22352 |
** a diagram of Expr, ExprList, and Select objects.
**
*/
/* Add a new subitem to the tree. The moreToFollow flag indicates that this
** is not the last item in the tree. */
SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
if( p==0 ){
| | | 22431 22432 22433 22434 22435 22436 22437 22438 22439 22440 22441 22442 22443 22444 22445 |
** a diagram of Expr, ExprList, and Select objects.
**
*/
/* Add a new subitem to the tree. The moreToFollow flag indicates that this
** is not the last item in the tree. */
SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
if( p==0 ){
p = sqlite3_malloc64( sizeof(*p) );
if( p==0 ) return 0;
memset(p, 0, sizeof(*p));
}else{
p->iLevel++;
}
assert( moreToFollow==0 || moreToFollow==1 );
if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
|
| ︙ | ︙ | |||
22369 22370 22371 22372 22373 22374 22375 |
/* Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines */
SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
va_list ap;
int i;
StrAccum acc;
char zBuf[500];
| | < | 22454 22455 22456 22457 22458 22459 22460 22461 22462 22463 22464 22465 22466 22467 22468 |
/* Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines */
SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
va_list ap;
int i;
StrAccum acc;
char zBuf[500];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
if( p ){
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
}
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
}
va_start(ap, zFormat);
|
| ︙ | ︙ | |||
22435 22436 22437 22438 22439 22440 22441 | unsigned char i, j; /* State variables */ unsigned char s[256]; /* State variables */ } sqlite3Prng; /* ** Return N random bytes. */ | | | 22519 22520 22521 22522 22523 22524 22525 22526 22527 22528 22529 22530 22531 22532 22533 |
unsigned char i, j; /* State variables */
unsigned char s[256]; /* State variables */
} sqlite3Prng;
/*
** Return N random bytes.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
unsigned char t;
unsigned char *zBuf = pBuf;
/* The "wsdPrng" macro will resolve to the pseudo-random number generator
** state vector. If writable static data is unsupported on the target,
** we have to locate the state vector at run-time. In the more common
** case where writable static data is supported, wsdPrng can refer directly
|
| ︙ | ︙ | |||
23587 23588 23589 23590 23591 23592 23593 | ** ** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and ** sqlite3_strnicmp() APIs allow applications and extensions to compare ** the contents of two buffers containing UTF-8 strings in a ** case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ | | | | 23671 23672 23673 23674 23675 23676 23677 23678 23679 23680 23681 23682 23683 23684 23685 23686 23687 23688 23689 23690 23691 23692 23693 23694 23695 23696 23697 |
**
** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and
** sqlite3_strnicmp() APIs allow applications and extensions to compare
** the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
return UpperToLower[*a] - UpperToLower[*b];
}
SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
a = (unsigned char *)zLeft;
|
| ︙ | ︙ | |||
23993 23994 23995 23996 23997 23998 23999 24000 24001 24002 24003 24004 24005 24006 |
memcpy(pValue, &u, 4);
return 1;
}else{
return 0;
}
}
#endif
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
/* The longest decimal representation of a 32 bit integer is 10 digits:
**
** 1234567890
| > | 24077 24078 24079 24080 24081 24082 24083 24084 24085 24086 24087 24088 24089 24090 24091 |
memcpy(pValue, &u, 4);
return 1;
}else{
return 0;
}
}
#endif
while( zNum[0]=='0' ) zNum++;
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
v = v*10 + c;
}
/* The longest decimal representation of a 32 bit integer is 10 digits:
**
** 1234567890
|
| ︙ | ︙ | |||
25247 25248 25249 25250 25251 25252 25253 25254 25255 25256 25257 25258 25259 25260 | #endif #if SQLITE_ENABLE_LOCKING_STYLE # include <sys/ioctl.h> # include <sys/file.h> # include <sys/param.h> #endif /* SQLITE_ENABLE_LOCKING_STYLE */ #if OS_VXWORKS /* # include <sys/ioctl.h> */ # include <semaphore.h> # include <limits.h> #endif /* OS_VXWORKS */ | > > > > > > > > > > > | 25332 25333 25334 25335 25336 25337 25338 25339 25340 25341 25342 25343 25344 25345 25346 25347 25348 25349 25350 25351 25352 25353 25354 25355 25356 |
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
# include <sys/ioctl.h>
# include <sys/file.h>
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
# define HAVE_GETHOSTUUID 1
# else
# warning "gethostuuid() is disabled."
# endif
#endif
#if OS_VXWORKS
/* # include <sys/ioctl.h> */
# include <semaphore.h>
# include <limits.h>
#endif /* OS_VXWORKS */
|
| ︙ | ︙ | |||
25443 25444 25445 25446 25447 25448 25449 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the ** switch. The following code should catch this problem at compile-time. */ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif | < < < < < < < < < < | 25539 25540 25541 25542 25543 25544 25545 25546 25547 25548 25549 25550 25551 25552 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the ** switch. The following code should catch this problem at compile-time. */ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif /* ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. */ #ifdef SQLITE_PERFORMANCE_TRACE /* |
| ︙ | ︙ | |||
25995 25996 25997 25998 25999 26000 26001 |
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif
| | | 26081 26082 26083 26084 26085 26086 26087 26088 26089 26090 26091 26092 26093 26094 26095 |
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif
#ifdef SQLITE_HAVE_OS_TRACE
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string representation of the supplied
** integer lock-type.
*/
static const char *azFileLock(int eFileLock){
switch( eFileLock ){
|
| ︙ | ︙ | |||
26258 26259 26260 26261 26262 26263 26264 |
static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
struct vxworksFileId *pNew; /* search key and new file ID */
struct vxworksFileId *pCandidate; /* For looping over existing file IDs */
int n; /* Length of zAbsoluteName string */
assert( zAbsoluteName[0]=='/' );
n = (int)strlen(zAbsoluteName);
| | | 26344 26345 26346 26347 26348 26349 26350 26351 26352 26353 26354 26355 26356 26357 26358 |
static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
struct vxworksFileId *pNew; /* search key and new file ID */
struct vxworksFileId *pCandidate; /* For looping over existing file IDs */
int n; /* Length of zAbsoluteName string */
assert( zAbsoluteName[0]=='/' );
n = (int)strlen(zAbsoluteName);
pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
if( pNew==0 ) return 0;
pNew->zCanonicalName = (char*)&pNew[1];
memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
n = vxworksSimplifyName(pNew->zCanonicalName, n);
/* Search for an existing entry that matching the canonical name.
** If found, increment the reference count and return a pointer to
|
| ︙ | ︙ | |||
26662 26663 26664 26665 26666 26667 26668 |
fileId.ino = statbuf.st_ino;
#endif
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
}
if( pInode==0 ){
| | | 26748 26749 26750 26751 26752 26753 26754 26755 26756 26757 26758 26759 26760 26761 26762 |
fileId.ino = statbuf.st_ino;
#endif
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
}
if( pInode==0 ){
pInode = sqlite3_malloc64( sizeof(*pInode) );
if( pInode==0 ){
return SQLITE_NOMEM;
}
memset(pInode, 0, sizeof(*pInode));
memcpy(&pInode->fileId, &fileId, sizeof(fileId));
pInode->nRef = 1;
pInode->pNext = inodeList;
|
| ︙ | ︙ | |||
29148 29149 29150 29151 29152 29153 29154 |
/*
** Information and control of an open file handle.
*/
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
case SQLITE_FCNTL_WAL_BLOCK: {
| | | 29234 29235 29236 29237 29238 29239 29240 29241 29242 29243 29244 29245 29246 29247 29248 |
/*
** Information and control of an open file handle.
*/
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
case SQLITE_FCNTL_WAL_BLOCK: {
/* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */
return SQLITE_OK;
}
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
}
case SQLITE_FCNTL_LAST_ERRNO: {
|
| ︙ | ︙ | |||
29183 29184 29185 29186 29187 29188 29189 |
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
| | | 29269 29270 29271 29272 29273 29274 29275 29276 29277 29278 29279 29280 29281 29282 29283 |
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
if( zTFile ){
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
}
case SQLITE_FCNTL_HAS_MOVED: {
|
| ︙ | ︙ | |||
29624 29625 29626 29627 29628 29629 29630 | struct unixShmNode *pShmNode; /* The underlying mmapped file */ int rc; /* Result code */ unixInodeInfo *pInode; /* The inode of fd */ char *zShmFilename; /* Name of the file used for SHM */ int nShmFilename; /* Size of the SHM filename in bytes */ /* Allocate space for the new unixShm object. */ | | | 29710 29711 29712 29713 29714 29715 29716 29717 29718 29719 29720 29721 29722 29723 29724 | struct unixShmNode *pShmNode; /* The underlying mmapped file */ int rc; /* Result code */ unixInodeInfo *pInode; /* The inode of fd */ char *zShmFilename; /* Name of the file used for SHM */ int nShmFilename; /* Size of the SHM filename in bytes */ /* Allocate space for the new unixShm object. */ p = sqlite3_malloc64( sizeof(*p) ); if( p==0 ) return SQLITE_NOMEM; memset(p, 0, sizeof(*p)); assert( pDbFd->pShm==0 ); /* Check to see if a unixShmNode object already exists. Reuse an existing ** one if present. Create a new one if necessary. */ |
| ︙ | ︙ | |||
29655 29656 29657 29658 29659 29660 29661 |
}
#ifdef SQLITE_SHM_DIRECTORY
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
#else
nShmFilename = 6 + (int)strlen(zBasePath);
#endif
| | | 29741 29742 29743 29744 29745 29746 29747 29748 29749 29750 29751 29752 29753 29754 29755 |
}
#ifdef SQLITE_SHM_DIRECTORY
nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
#else
nShmFilename = 6 + (int)strlen(zBasePath);
#endif
pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
rc = SQLITE_NOMEM;
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
#ifdef SQLITE_SHM_DIRECTORY
|
| ︙ | ︙ | |||
29865 29866 29867 29868 29869 29870 29871 |
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
| | | 29951 29952 29953 29954 29955 29956 29957 29958 29959 29960 29961 29962 29963 29964 29965 |
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
pMem = sqlite3_malloc64(szRegion);
if( pMem==0 ){
rc = SQLITE_NOMEM;
goto shmpage_out;
}
memset(pMem, 0, szRegion);
}
|
| ︙ | ︙ | |||
30702 30703 30704 30705 30706 30707 30708 |
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
else if( pLockingStyle == &afpIoMethods ){
/* AFP locking uses the file path so it needs to be included in
** the afpLockingContext.
*/
afpLockingContext *pCtx;
| | | 30788 30789 30790 30791 30792 30793 30794 30795 30796 30797 30798 30799 30800 30801 30802 |
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
else if( pLockingStyle == &afpIoMethods ){
/* AFP locking uses the file path so it needs to be included in
** the afpLockingContext.
*/
afpLockingContext *pCtx;
pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
rc = SQLITE_NOMEM;
}else{
/* NB: zFilename exists and remains valid until the file is closed
** according to requirement F11141. So we do not need to make a
** copy of the filename. */
pCtx->dbPath = zFilename;
|
| ︙ | ︙ | |||
30732 30733 30734 30735 30736 30737 30738 |
/* Dotfile locking uses the file path so it needs to be included in
** the dotlockLockingContext
*/
char *zLockFile;
int nFilename;
assert( zFilename!=0 );
nFilename = (int)strlen(zFilename) + 6;
| | | 30818 30819 30820 30821 30822 30823 30824 30825 30826 30827 30828 30829 30830 30831 30832 |
/* Dotfile locking uses the file path so it needs to be included in
** the dotlockLockingContext
*/
char *zLockFile;
int nFilename;
assert( zFilename!=0 );
nFilename = (int)strlen(zFilename) + 6;
zLockFile = (char *)sqlite3_malloc64(nFilename);
if( zLockFile==0 ){
rc = SQLITE_NOMEM;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
pNew->lockingContext = zLockFile;
}
|
| ︙ | ︙ | |||
31109 31110 31111 31112 31113 31114 31115 |
if( eType==SQLITE_OPEN_MAIN_DB ){
UnixUnusedFd *pUnused;
pUnused = findReusableFd(zName, flags);
if( pUnused ){
fd = pUnused->fd;
}else{
| | | 31195 31196 31197 31198 31199 31200 31201 31202 31203 31204 31205 31206 31207 31208 31209 |
if( eType==SQLITE_OPEN_MAIN_DB ){
UnixUnusedFd *pUnused;
pUnused = findReusableFd(zName, flags);
if( pUnused ){
fd = pUnused->fd;
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
}
p->pUnused = pUnused;
/* Database filenames are double-zero terminated if they are not
|
| ︙ | ︙ | |||
31489 31490 31491 31492 31493 31494 31495 | ** ** When testing, initializing zBuf[] to zero is all we do. That means ** that we always use the same random number sequence. This makes the ** tests repeatable. */ memset(zBuf, 0, nBuf); randomnessPid = osGetpid(0); | | | 31575 31576 31577 31578 31579 31580 31581 31582 31583 31584 31585 31586 31587 31588 31589 |
**
** When testing, initializing zBuf[] to zero is all we do. That means
** that we always use the same random number sequence. This makes the
** tests repeatable.
*/
memset(zBuf, 0, nBuf);
randomnessPid = osGetpid(0);
#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
{
int fd, got;
fd = robust_open("/dev/urandom", O_RDONLY, 0);
if( fd<0 ){
time_t t;
time(&t);
memcpy(zBuf, &t, sizeof(t));
|
| ︙ | ︙ | |||
31901 31902 31903 31904 31905 31906 31907 |
** 3. if that fails, try to open the file read-only
** otherwise return BUSY (if lock file) or CANTOPEN for the conch file
*/
pUnused = findReusableFd(path, openFlags);
if( pUnused ){
fd = pUnused->fd;
}else{
| | | 31987 31988 31989 31990 31991 31992 31993 31994 31995 31996 31997 31998 31999 32000 32001 |
** 3. if that fails, try to open the file read-only
** otherwise return BUSY (if lock file) or CANTOPEN for the conch file
*/
pUnused = findReusableFd(path, openFlags);
if( pUnused ){
fd = pUnused->fd;
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
return SQLITE_NOMEM;
}
}
if( fd<0 ){
fd = robust_open(path, openFlags, 0);
terrno = errno;
|
| ︙ | ︙ | |||
31934 31935 31936 31937 31938 31939 31940 |
case EIO:
return SQLITE_IOERR_LOCK; /* even though it is the conch */
default:
return SQLITE_CANTOPEN_BKPT;
}
}
| | | 32020 32021 32022 32023 32024 32025 32026 32027 32028 32029 32030 32031 32032 32033 32034 |
case EIO:
return SQLITE_IOERR_LOCK; /* even though it is the conch */
default:
return SQLITE_CANTOPEN_BKPT;
}
}
pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
if( pNew==NULL ){
rc = SQLITE_NOMEM;
goto end_create_proxy;
}
memset(pNew, 0, sizeof(unixFile));
pNew->openFlags = openFlags;
memset(&dummyVfs, 0, sizeof(dummyVfs));
|
| ︙ | ︙ | |||
31967 31968 31969 31970 31971 31972 31973 31974 31975 31976 31977 31978 31979 31980 31981 31982 |
#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
SQLITE_API int sqlite3_hostid_num = 0;
#endif
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
** bytes of writable memory.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN);
| > > | < | 32053 32054 32055 32056 32057 32058 32059 32060 32061 32062 32063 32064 32065 32066 32067 32068 32069 32070 32071 32072 32073 32074 32075 32076 32077 32078 |
#ifdef SQLITE_TEST
/* simulate multiple hosts by creating unique hostid file paths */
SQLITE_API int sqlite3_hostid_num = 0;
#endif
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
#ifdef HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif
/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
** bytes of writable memory.
*/
static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN);
#ifdef HAVE_GETHOSTUUID
{
struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){
int err = errno;
if( pError ){
*pError = err;
}
|
| ︙ | ︙ | |||
32395 32396 32397 32398 32399 32400 32401 |
OSTRACE(("RELEASECONCH %d %s\n", conchFile->h,
(rc==SQLITE_OK ? "ok" : "failed")));
return rc;
}
/*
** Given the name of a database file, compute the name of its conch file.
| | | | 32482 32483 32484 32485 32486 32487 32488 32489 32490 32491 32492 32493 32494 32495 32496 32497 32498 32499 32500 32501 32502 32503 32504 32505 32506 32507 32508 32509 32510 32511 32512 |
OSTRACE(("RELEASECONCH %d %s\n", conchFile->h,
(rc==SQLITE_OK ? "ok" : "failed")));
return rc;
}
/*
** Given the name of a database file, compute the name of its conch file.
** Store the conch filename in memory obtained from sqlite3_malloc64().
** Make *pConchPath point to the new name. Return SQLITE_OK on success
** or SQLITE_NOMEM if unable to obtain memory.
**
** The caller is responsible for ensuring that the allocated memory
** space is eventually freed.
**
** *pConchPath is set to NULL if a memory allocation error occurs.
*/
static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
int i; /* Loop counter */
int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
char *conchPath; /* buffer in which to construct conch name */
/* Allocate space for the conch filename and initialize the name to
** the name of the original database file. */
*pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
if( conchPath==0 ){
return SQLITE_NOMEM;
}
memcpy(conchPath, dbPath, len+1);
/* now insert a "." before the last / character */
for( i=(len-1); i>=0; i-- ){
|
| ︙ | ︙ | |||
32527 32528 32529 32530 32531 32532 32533 |
}else{
lockPath=(char *)path;
}
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
(lockPath ? lockPath : ":auto:"), osGetpid(0)));
| | | 32614 32615 32616 32617 32618 32619 32620 32621 32622 32623 32624 32625 32626 32627 32628 |
}else{
lockPath=(char *)path;
}
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
(lockPath ? lockPath : ":auto:"), osGetpid(0)));
pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
return SQLITE_NOMEM;
}
memset(pCtx, 0, sizeof(*pCtx));
rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
32812 32813 32814 32815 32816 32817 32818 | ** files. ** ** This routine is called once during SQLite initialization and by a ** single thread. The memory allocation and mutex subsystems have not ** necessarily been initialized when this routine is called, and so they ** should not be used. */ | | | 32899 32900 32901 32902 32903 32904 32905 32906 32907 32908 32909 32910 32911 32912 32913 |
** files.
**
** This routine is called once during SQLite initialization and by a
** single thread. The memory allocation and mutex subsystems have not
** necessarily been initialized when this routine is called, and so they
** should not be used.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
/*
** The following macro defines an initializer for an sqlite3_vfs object.
** The name of the VFS is NAME. The pAppData is a pointer to a pointer
** to the "finder" function. (pAppData is a pointer to a pointer because
** silly C90 rules prohibit a void* from being cast to a function pointer
** and so we have to go through the intermediate pointer to avoid problems
** when compiling with -pedantic-errors on GCC.)
|
| ︙ | ︙ | |||
32911 32912 32913 32914 32915 32916 32917 | /* ** Shutdown the operating system interface. ** ** Some operating systems might need to do some cleanup in this routine, ** to release dynamically allocated objects. But not on unix. ** This routine is a no-op for unix. */ | | | 32998 32999 33000 33001 33002 33003 33004 33005 33006 33007 33008 33009 33010 33011 33012 |
/*
** Shutdown the operating system interface.
**
** Some operating systems might need to do some cleanup in this routine,
** to release dynamically allocated objects. But not on unix.
** This routine is a no-op for unix.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
return SQLITE_OK;
}
#endif /* SQLITE_OS_UNIX */
/************** End of os_unix.c *********************************************/
/************** Begin file os_win.c ******************************************/
|
| ︙ | ︙ | |||
32971 32972 32973 32974 32975 32976 32977 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the ** switch. The following code should catch this problem at compile-time. */ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif | < < < < < < < < < < | 33058 33059 33060 33061 33062 33063 33064 33065 33066 33067 33068 33069 33070 33071 | ** macro to SQLITE_DEBUG and some older makefiles have not yet made the ** switch. The following code should catch this problem at compile-time. */ #ifdef MEMORY_DEBUG # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." #endif /* ** Macros for performance tracing. Normally turned off. Only works ** on i486 hardware. */ #ifdef SQLITE_PERFORMANCE_TRACE /* |
| ︙ | ︙ | |||
33324 33325 33326 33327 33328 33329 33330 |
DWORD, DWORD, DWORD, LPCWSTR);
#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */
/*
| | > > | 33401 33402 33403 33404 33405 33406 33407 33408 33409 33410 33411 33412 33413 33414 33415 33416 33417 33418 |
DWORD, DWORD, DWORD, LPCWSTR);
#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */
/*
** These file mapping APIs are common to both Win32 and WinRT.
*/
WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T);
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API */
/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_FILE_ATTRIBUTES
|
| ︙ | ︙ | |||
34210 34211 34212 34213 34214 34215 34216 34217 34218 34219 34220 34221 34222 34223 |
#else
{ "UuidCreateSequential", (SYSCALL)0, 0 },
#endif
#define osUuidCreateSequential \
((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
}; /* End of the overrideable system calls */
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes. Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
** system call named zName.
| > > > > > > > > > | 34289 34290 34291 34292 34293 34294 34295 34296 34297 34298 34299 34300 34301 34302 34303 34304 34305 34306 34307 34308 34309 34310 34311 |
#else
{ "UuidCreateSequential", (SYSCALL)0, 0 },
#endif
#define osUuidCreateSequential \
((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
{ "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 },
#else
{ "FlushViewOfFile", (SYSCALL)0, 0 },
#endif
#define osFlushViewOfFile \
((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
}; /* End of the overrideable system calls */
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes. Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
** system call named zName.
|
| ︙ | ︙ | |||
34303 34304 34305 34306 34307 34308 34309 | /* ** If a Win32 native heap has been configured, this function will attempt to ** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one ** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The ** "pnLargest" argument, if non-zero, will be used to return the size of the ** largest committed free block in the heap, in bytes. */ | | | 34391 34392 34393 34394 34395 34396 34397 34398 34399 34400 34401 34402 34403 34404 34405 |
/*
** If a Win32 native heap has been configured, this function will attempt to
** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one
** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The
** "pnLargest" argument, if non-zero, will be used to return the size of the
** largest committed free block in the heap, in bytes.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
int rc = SQLITE_OK;
UINT nLargest = 0;
HANDLE hHeap;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
|
| ︙ | ︙ | |||
34343 34344 34345 34346 34347 34348 34349 | /* ** If a Win32 native heap has been configured, this function will attempt to ** destroy and recreate it. If the Win32 native heap is not isolated and/or ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will ** be returned and no changes will be made to the Win32 native heap. */ | | | 34431 34432 34433 34434 34435 34436 34437 34438 34439 34440 34441 34442 34443 34444 34445 |
/*
** If a Win32 native heap has been configured, this function will attempt to
** destroy and recreate it. If the Win32 native heap is not isolated and/or
** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
** be returned and no changes will be made to the Win32 native heap.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
int rc;
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
sqlite3_mutex_enter(pMaster);
sqlite3_mutex_enter(pMem);
|
| ︙ | ︙ | |||
34388 34389 34390 34391 34392 34393 34394 | #endif /* SQLITE_WIN32_MALLOC */ /* ** This function outputs the specified (ANSI) string to the Win32 debugger ** (if available). */ | | | 34476 34477 34478 34479 34480 34481 34482 34483 34484 34485 34486 34487 34488 34489 34490 |
#endif /* SQLITE_WIN32_MALLOC */
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
*/
SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
#if defined(SQLITE_WIN32_HAS_ANSI)
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
|
| ︙ | ︙ | |||
34428 34429 34430 34431 34432 34433 34434 | ** The following routine suspends the current thread for at least ms ** milliseconds. This is equivalent to the Win32 Sleep() interface. */ #if SQLITE_OS_WINRT static HANDLE sleepObj = NULL; #endif | | | 34516 34517 34518 34519 34520 34521 34522 34523 34524 34525 34526 34527 34528 34529 34530 |
** The following routine suspends the current thread for at least ms
** milliseconds. This is equivalent to the Win32 Sleep() interface.
*/
#if SQLITE_OS_WINRT
static HANDLE sleepObj = NULL;
#endif
SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
SYNCHRONIZE);
}
assert( sleepObj!=NULL );
osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
|
| ︙ | ︙ | |||
34477 34478 34479 34480 34481 34482 34483 | # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ | | | 34565 34566 34567 34568 34569 34570 34571 34572 34573 34574 34575 34576 34577 34578 34579 |
# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
#endif
/*
** This function determines if the machine is running a version of Windows
** based on the NT kernel.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
#if SQLITE_OS_WINRT
/*
** NOTE: The WinRT sub-platform is always assumed to be based on the NT
** kernel.
*/
return 1;
#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
|
| ︙ | ︙ | |||
34831 34832 34833 34834 34835 34836 34837 | return zFilename; } /* ** Convert multibyte character string to UTF-8. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ | | | | | 34919 34920 34921 34922 34923 34924 34925 34926 34927 34928 34929 34930 34931 34932 34933 34934 34935 34936 34937 34938 34939 34940 34941 34942 34943 34944 34945 34946 34947 34948 34949 34950 34951 34952 34953 34954 34955 34956 34957 34958 34959 34960 34961 34962 34963 34964 34965 34966 34967 34968 34969 34970 |
return zFilename;
}
/*
** Convert multibyte character string to UTF-8. Space to hold the
** returned string is obtained from sqlite3_malloc().
*/
SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
char *zFilenameUtf8;
LPWSTR zTmpWide;
zTmpWide = winMbcsToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameUtf8;
}
/*
** Convert UTF-8 to multibyte character string. Space to hold the
** returned string is obtained from sqlite3_malloc().
*/
SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
char *zFilenameMbcs;
LPWSTR zTmpWide;
zTmpWide = winUtf8ToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameMbcs;
}
/*
** This function sets the data directory or the temporary directory based on
** the provided arguments. The type argument must be 1 in order to set the
** data directory or 2 in order to set the temporary directory. The zValue
** argument is the name of the directory to use. The return value will be
** SQLITE_OK if successful.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
char **ppDirectory = 0;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return rc;
#endif
if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
ppDirectory = &sqlite3_data_directory;
|
| ︙ | ︙ | |||
35093 35094 35095 35096 35097 35098 35099 | } return 0; } /* ** Log a I/O error retry episode. */ | | | | | | 35181 35182 35183 35184 35185 35186 35187 35188 35189 35190 35191 35192 35193 35194 35195 35196 35197 35198 35199 |
}
return 0;
}
/*
** Log a I/O error retry episode.
*/
static void winLogIoerr(int nRetry, int lineno){
if( nRetry ){
sqlite3_log(SQLITE_NOTICE,
"delayed %dms for lock/sharing conflict at line %d",
winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
);
}
}
#if SQLITE_OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.
|
| ︙ | ︙ | |||
35577 35578 35579 35580 35581 35582 35583 | winFile *pFile = (winFile*)id; assert( id!=0 ); #ifndef SQLITE_OMIT_WAL assert( pFile->pShm==0 ); #endif assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); | | > | 35665 35666 35667 35668 35669 35670 35671 35672 35673 35674 35675 35676 35677 35678 35679 35680 |
winFile *pFile = (winFile*)id;
assert( id!=0 );
#ifndef SQLITE_OMIT_WAL
assert( pFile->pShm==0 );
#endif
assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
osGetCurrentProcessId(), pFile, pFile->h));
#if SQLITE_MAX_MMAP_SIZE>0
winUnmapfile(pFile);
#endif
do{
rc = osCloseHandle(pFile->h);
|
| ︙ | ︙ | |||
35606 35607 35608 35609 35610 35611 35612 |
sqlite3_free(pFile->zDeleteOnClose);
}
#endif
if( rc ){
pFile->h = NULL;
}
OpenCounter(-1);
| > | | 35695 35696 35697 35698 35699 35700 35701 35702 35703 35704 35705 35706 35707 35708 35709 35710 |
sqlite3_free(pFile->zDeleteOnClose);
}
#endif
if( rc ){
pFile->h = NULL;
}
OpenCounter(-1);
OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
return rc ? SQLITE_OK
: winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
"winClose", pFile->zPath);
}
/*
** Read data from a file into a buffer. Return SQLITE_OK if all
|
| ︙ | ︙ | |||
35634 35635 35636 35637 35638 35639 35640 | DWORD nRead; /* Number of bytes actually read from file */ int nRetry = 0; /* Number of retrys */ assert( id!=0 ); assert( amt>0 ); assert( offset>=0 ); SimulateIOError(return SQLITE_IOERR_READ); | | > | > | > | > | | > | > | 35724 35725 35726 35727 35728 35729 35730 35731 35732 35733 35734 35735 35736 35737 35738 35739 35740 35741 35742 35743 35744 35745 35746 35747 35748 35749 35750 35751 35752 35753 35754 35755 35756 35757 35758 35759 35760 35761 35762 35763 35764 35765 35766 35767 35768 35769 35770 35771 35772 35773 35774 35775 35776 35777 35778 35779 35780 35781 35782 35783 35784 35785 35786 35787 35788 35789 35790 35791 35792 35793 |
DWORD nRead; /* Number of bytes actually read from file */
int nRetry = 0; /* Number of retrys */
assert( id!=0 );
assert( amt>0 );
assert( offset>=0 );
SimulateIOError(return SQLITE_IOERR_READ);
OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
"offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
pFile->h, pBuf, amt, offset, pFile->locktype));
#if SQLITE_MAX_MMAP_SIZE>0
/* Deal with as much of this read request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}else{
int nCopy = (int)(pFile->mmapSize - offset);
memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
pBuf = &((u8 *)pBuf)[nCopy];
amt -= nCopy;
offset += nCopy;
}
}
#endif
#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
if( winSeekFile(pFile, offset) ){
OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_FULL;
}
while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
#else
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.Offset = (LONG)(offset & 0xffffffff);
overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
osGetLastError()!=ERROR_HANDLE_EOF ){
#endif
DWORD lastErrno;
if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
pFile->lastErrno = lastErrno;
OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
"winRead", pFile->zPath);
}
winLogIoerr(nRetry, __LINE__);
if( nRead<(DWORD)amt ){
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[nRead], 0, amt-nRead);
OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_IOERR_SHORT_READ;
}
OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}
/*
** Write data from a buffer into a file. Return SQLITE_OK on success
** or some other error code on failure.
*/
|
| ︙ | ︙ | |||
35706 35707 35708 35709 35710 35711 35712 | int nRetry = 0; /* Number of retries */ assert( amt>0 ); assert( pFile ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); | | > | > | 35802 35803 35804 35805 35806 35807 35808 35809 35810 35811 35812 35813 35814 35815 35816 35817 35818 35819 35820 35821 35822 35823 35824 35825 35826 35827 |
int nRetry = 0; /* Number of retries */
assert( amt>0 );
assert( pFile );
SimulateIOError(return SQLITE_IOERR_WRITE);
SimulateDiskfullError(return SQLITE_FULL);
OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
"offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
pFile->h, pBuf, amt, offset, pFile->locktype));
#if SQLITE_MAX_MMAP_SIZE>0
/* Deal with as much of this write request as possible by transfering
** data from the memory mapping using memcpy(). */
if( offset<pFile->mmapSize ){
if( offset+amt <= pFile->mmapSize ){
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}else{
int nCopy = (int)(pFile->mmapSize - offset);
memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
pBuf = &((u8 *)pBuf)[nCopy];
amt -= nCopy;
offset += nCopy;
|
| ︙ | ︙ | |||
35778 35779 35780 35781 35782 35783 35784 |
rc = 1;
}
}
if( rc ){
if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
|| ( pFile->lastErrno==ERROR_DISK_FULL )){
| | > | > | | > | | | 35876 35877 35878 35879 35880 35881 35882 35883 35884 35885 35886 35887 35888 35889 35890 35891 35892 35893 35894 35895 35896 35897 35898 35899 35900 35901 35902 35903 35904 35905 35906 35907 35908 35909 35910 35911 35912 35913 35914 35915 35916 35917 35918 |
rc = 1;
}
}
if( rc ){
if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
|| ( pFile->lastErrno==ERROR_DISK_FULL )){
OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_FULL, pFile->lastErrno,
"winWrite1", pFile->zPath);
}
OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
"winWrite2", pFile->zPath);
}else{
winLogIoerr(nRetry, __LINE__);
}
OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}
/*
** Truncate an open file to a specified size
*/
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
winFile *pFile = (winFile*)id; /* File handle object */
int rc = SQLITE_OK; /* Return code for this function */
DWORD lastErrno;
assert( pFile );
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
/* If the user has configured a chunk-size for this file, truncate the
** file so that it consists of an integer number of chunks (i.e. the
** actual file size after the operation may be larger than the requested
** size).
*/
if( pFile->szChunk>0 ){
|
| ︙ | ︙ | |||
35835 35836 35837 35838 35839 35840 35841 |
** use read() and write() to access data beyond this point from now on.
*/
if( pFile->pMapRegion && nByte<pFile->mmapSize ){
pFile->mmapSize = nByte;
}
#endif
| > | | 35936 35937 35938 35939 35940 35941 35942 35943 35944 35945 35946 35947 35948 35949 35950 35951 |
** use read() and write() to access data beyond this point from now on.
*/
if( pFile->pMapRegion && nByte<pFile->mmapSize ){
pFile->mmapSize = nByte;
}
#endif
OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
return rc;
}
#ifdef SQLITE_TEST
/*
** Count the number of fullsyncs and normal syncs. This is used to test
** that syncs and fullsyncs are occuring at the right times.
|
| ︙ | ︙ | |||
35859 35860 35861 35862 35863 35864 35865 | #ifndef SQLITE_NO_SYNC /* ** Used only when SQLITE_NO_SYNC is not defined. */ BOOL rc; #endif #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ | | | > | | > > > > > > > > > > > > > > > > > | > | > | | 35961 35962 35963 35964 35965 35966 35967 35968 35969 35970 35971 35972 35973 35974 35975 35976 35977 35978 35979 35980 35981 35982 35983 35984 35985 35986 35987 35988 35989 35990 35991 35992 35993 35994 35995 35996 35997 35998 35999 36000 36001 36002 36003 36004 36005 36006 36007 36008 36009 36010 36011 36012 36013 36014 36015 36016 36017 36018 36019 36020 36021 36022 36023 36024 36025 36026 36027 36028 36029 36030 36031 36032 36033 36034 36035 36036 36037 36038 36039 36040 36041 36042 36043 36044 |
#ifndef SQLITE_NO_SYNC
/*
** Used only when SQLITE_NO_SYNC is not defined.
*/
BOOL rc;
#endif
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
defined(SQLITE_HAVE_OS_TRACE)
/*
** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
** OSTRACE() macros.
*/
winFile *pFile = (winFile*)id;
#else
UNUSED_PARAMETER(id);
#endif
assert( pFile );
/* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
assert((flags&0x0F)==SQLITE_SYNC_NORMAL
|| (flags&0x0F)==SQLITE_SYNC_FULL
);
/* Unix cannot, but some systems may return SQLITE_FULL from here. This
** line is to test that doing so does not cause any problems.
*/
SimulateDiskfullError( return SQLITE_FULL );
OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
osGetCurrentProcessId(), pFile, pFile->h, flags,
pFile->locktype));
#ifndef SQLITE_TEST
UNUSED_PARAMETER(flags);
#else
if( (flags&0x0F)==SQLITE_SYNC_FULL ){
sqlite3_fullsync_count++;
}
sqlite3_sync_count++;
#endif
/* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
** no-op
*/
#ifdef SQLITE_NO_SYNC
OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
#else
#if SQLITE_MAX_MMAP_SIZE>0
if( pFile->pMapRegion ){
if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
"rc=SQLITE_OK\n", osGetCurrentProcessId(),
pFile, pFile->pMapRegion));
}else{
pFile->lastErrno = osGetLastError();
OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
"rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
pFile, pFile->pMapRegion));
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
"winSync1", pFile->zPath);
}
}
#endif
rc = osFlushFileBuffers(pFile->h);
SimulateIOError( rc=FALSE );
if( rc ){
OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}else{
pFile->lastErrno = osGetLastError();
OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
osGetCurrentProcessId(), pFile, pFile->h));
return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
"winSync2", pFile->zPath);
}
#endif
}
/*
** Determine the current size of a file in bytes
*/
|
| ︙ | ︙ | |||
36516 36517 36518 36519 36520 36521 36522 |
void *pMap;
} *aRegion;
DWORD lastErrno; /* The Windows errno from the last I/O error */
int nRef; /* Number of winShm objects pointing to this */
winShm *pFirst; /* All winShm objects pointing to this */
winShmNode *pNext; /* Next in list of all winShmNode objects */
| | | 36638 36639 36640 36641 36642 36643 36644 36645 36646 36647 36648 36649 36650 36651 36652 |
void *pMap;
} *aRegion;
DWORD lastErrno; /* The Windows errno from the last I/O error */
int nRef; /* Number of winShm objects pointing to this */
winShm *pFirst; /* All winShm objects pointing to this */
winShmNode *pNext; /* Next in list of all winShmNode objects */
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
u8 nextShmId; /* Next available winShm.id value */
#endif
};
/*
** A global array of all winShmNode objects.
**
|
| ︙ | ︙ | |||
36547 36548 36549 36550 36551 36552 36553 |
*/
struct winShm {
winShmNode *pShmNode; /* The underlying winShmNode object */
winShm *pNext; /* Next winShm with the same winShmNode */
u8 hasMutex; /* True if holding the winShmNode mutex */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
| | | 36669 36670 36671 36672 36673 36674 36675 36676 36677 36678 36679 36680 36681 36682 36683 |
*/
struct winShm {
winShmNode *pShmNode; /* The underlying winShmNode object */
winShm *pNext; /* Next winShm with the same winShmNode */
u8 hasMutex; /* True if holding the winShmNode mutex */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
u8 id; /* Id of this connection with its winShmNode */
#endif
};
/*
** Constants used for locking
*/
|
| ︙ | ︙ | |||
36738 36739 36740 36741 36742 36743 36744 |
rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
}
if( rc ) goto shm_open_err;
}
/* Make the new connection a child of the winShmNode */
p->pShmNode = pShmNode;
| | | 36860 36861 36862 36863 36864 36865 36866 36867 36868 36869 36870 36871 36872 36873 36874 |
rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
}
if( rc ) goto shm_open_err;
}
/* Make the new connection a child of the winShmNode */
p->pShmNode = pShmNode;
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
p->id = pShmNode->nextShmId++;
#endif
pShmNode->nRef++;
pDbFd->pShm = p;
winShmLeaveMutex();
/* The reference count on pShmNode has already been incremented under
|
| ︙ | ︙ | |||
37007 37008 37009 37010 37011 37012 37013 |
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
"winShmMap2", pDbFd->zPath);
goto shmpage_out;
}
}
/* Map the requested memory region into this processes address space. */
| | | 37129 37130 37131 37132 37133 37134 37135 37136 37137 37138 37139 37140 37141 37142 37143 |
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
"winShmMap2", pDbFd->zPath);
goto shmpage_out;
}
}
/* Map the requested memory region into this processes address space. */
apNew = (struct ShmRegion *)sqlite3_realloc64(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
rc = SQLITE_IOERR_NOMEM;
goto shmpage_out;
}
pShmNode->aRegion = apNew;
|
| ︙ | ︙ | |||
37879 37880 37881 37882 37883 37884 37885 |
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
| | | 38001 38002 38003 38004 38005 38006 38007 38008 38009 38010 38011 38012 38013 38014 38015 |
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
winLogIoerr(cnt, __LINE__);
OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
if( h==INVALID_HANDLE_VALUE ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
|
| ︙ | ︙ | |||
38063 38064 38065 38066 38067 38068 38069 |
}
} while(1);
}
#endif
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
| | | 38185 38186 38187 38188 38189 38190 38191 38192 38193 38194 38195 38196 38197 38198 38199 |
}
} while(1);
}
#endif
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
winLogIoerr(cnt, __LINE__);
}
sqlite3_free(zConverted);
OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
return rc;
}
/*
|
| ︙ | ︙ | |||
38113 38114 38115 38116 38117 38118 38119 |
&& sAttrData.nFileSizeHigh==0
&& sAttrData.nFileSizeLow==0 ){
attr = INVALID_FILE_ATTRIBUTES;
}else{
attr = sAttrData.dwFileAttributes;
}
}else{
| | | 38235 38236 38237 38238 38239 38240 38241 38242 38243 38244 38245 38246 38247 38248 38249 |
&& sAttrData.nFileSizeHigh==0
&& sAttrData.nFileSizeLow==0 ){
attr = INVALID_FILE_ATTRIBUTES;
}else{
attr = sAttrData.dwFileAttributes;
}
}else{
winLogIoerr(cnt, __LINE__);
if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
sqlite3_free(zConverted);
return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
zFilename);
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
|
| ︙ | ︙ | |||
38454 38455 38456 38457 38458 38459 38460 |
/*
** Write up to nBuf bytes of randomness into zBuf.
*/
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
int n = 0;
UNUSED_PARAMETER(pVfs);
| | | 38576 38577 38578 38579 38580 38581 38582 38583 38584 38585 38586 38587 38588 38589 38590 |
/*
** Write up to nBuf bytes of randomness into zBuf.
*/
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
int n = 0;
UNUSED_PARAMETER(pVfs);
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
n = nBuf;
memset(zBuf, 0, nBuf);
#else
if( sizeof(SYSTEMTIME)<=nBuf-n ){
SYSTEMTIME x;
osGetSystemTime(&x);
memcpy(&zBuf[n], &x, sizeof(x));
|
| ︙ | ︙ | |||
38488 38489 38490 38491 38492 38493 38494 |
#endif
if( sizeof(LARGE_INTEGER)<=nBuf-n ){
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
| < > | 38610 38611 38612 38613 38614 38615 38616 38617 38618 38619 38620 38621 38622 38623 38624 38625 38626 38627 38628 38629 38630 38631 38632 38633 38634 38635 38636 38637 38638 38639 38640 |
#endif
if( sizeof(LARGE_INTEGER)<=nBuf-n ){
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
if( sizeof(UUID)<=nBuf-n ){
UUID id;
memset(&id, 0, sizeof(UUID));
osUuidCreate(&id);
memcpy(zBuf, &id, sizeof(UUID));
n += sizeof(UUID);
}
if( sizeof(UUID)<=nBuf-n ){
UUID id;
memset(&id, 0, sizeof(UUID));
osUuidCreateSequential(&id);
memcpy(zBuf, &id, sizeof(UUID));
n += sizeof(UUID);
}
#endif
#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
return n;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
|
| ︙ | ︙ | |||
38628 38629 38630 38631 38632 38633 38634 | UNUSED_PARAMETER(pVfs); return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); } /* ** Initialize and deinitialize the operating system interface. */ | | | 38750 38751 38752 38753 38754 38755 38756 38757 38758 38759 38760 38761 38762 38763 38764 |
UNUSED_PARAMETER(pVfs);
return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
}
/*
** Initialize and deinitialize the operating system interface.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
0, /* pNext */
"win32", /* zName */
0, /* pAppData */
|
| ︙ | ︙ | |||
38682 38683 38684 38685 38686 38687 38688 |
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
| | | | 38804 38805 38806 38807 38808 38809 38810 38811 38812 38813 38814 38815 38816 38817 38818 38819 38820 38821 38822 38823 38824 38825 38826 38827 38828 38829 38830 38831 38832 38833 38834 38835 38836 38837 38838 38839 |
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==80 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
osGetNativeSystemInfo(&winSysInfo);
#else
osGetSystemInfo(&winSysInfo);
#endif
assert( winSysInfo.dwAllocationGranularity>0 );
assert( winSysInfo.dwPageSize>0 );
sqlite3_vfs_register(&winVfs, 1);
#if defined(SQLITE_WIN32_HAS_WIDE)
sqlite3_vfs_register(&winLongPathVfs, 0);
#endif
return SQLITE_OK;
}
SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
sleepObj = NULL;
}
#endif
return SQLITE_OK;
|
| ︙ | ︙ | |||
39059 39060 39061 39062 39063 39064 39065 | int i, nx, pc, op; void *pTmpSpace; /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); pV = sqlite3MallocZero( (sz+7)/8 + 1 ); | | | 39181 39182 39183 39184 39185 39186 39187 39188 39189 39190 39191 39192 39193 39194 39195 | int i, nx, pc, op; void *pTmpSpace; /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); pV = sqlite3MallocZero( (sz+7)/8 + 1 ); pTmpSpace = sqlite3_malloc64(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; /* NULL pBitvec tests */ sqlite3BitvecSet(0, 1); sqlite3BitvecClear(0, 1, pTmpSpace); /* Run the program */ |
| ︙ | ︙ | |||
44548 44549 44550 44551 44552 44553 44554 |
Pager *pPager, /* Pager object */
PgHdr *pList, /* List of frames to log */
Pgno nTruncate, /* Database size after this commit */
int isCommit /* True if this is a commit */
){
int rc; /* Return code */
int nList; /* Number of pages in pList */
| < < < < | 44670 44671 44672 44673 44674 44675 44676 44677 44678 44679 44680 44681 44682 44683 44684 44685 44686 44687 44688 44689 44690 44691 44692 44693 44694 44695 44696 44697 44698 44699 44700 44701 44702 44703 44704 44705 44706 44707 44708 44709 44710 44711 44712 44713 44714 44715 44716 44717 44718 44719 |
Pager *pPager, /* Pager object */
PgHdr *pList, /* List of frames to log */
Pgno nTruncate, /* Database size after this commit */
int isCommit /* True if this is a commit */
){
int rc; /* Return code */
int nList; /* Number of pages in pList */
PgHdr *p; /* For looping over pages */
assert( pPager->pWal );
assert( pList );
#ifdef SQLITE_DEBUG
/* Verify that the page list is in accending order */
for(p=pList; p && p->pDirty; p=p->pDirty){
assert( p->pgno < p->pDirty->pgno );
}
#endif
assert( pList->pDirty==0 || isCommit );
if( isCommit ){
/* If a WAL transaction is being committed, there is no point in writing
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
PgHdr **ppNext = &pList;
nList = 0;
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
if( p->pgno<=nTruncate ){
ppNext = &p->pDirty;
nList++;
}
}
assert( pList );
}else{
nList = 1;
}
pPager->aStat[PAGER_STAT_WRITE] += nList;
if( pList->pgno==1 ) pager_write_changecounter(pList);
rc = sqlite3WalFrames(pPager->pWal,
pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
);
if( rc==SQLITE_OK && pPager->pBackup ){
for(p=pList; p; p=p->pDirty){
sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
}
}
#ifdef SQLITE_CHECK_PAGES
pList = sqlite3PcacheDirtyList(pPager->pPCache);
|
| ︙ | ︙ | |||
48518 48519 48520 48521 48522 48523 48524 48525 48526 48527 48528 48529 48530 48531 |
if( rc==SQLITE_OK && state==PAGER_READER ){
pagerUnlockDb(pPager, SHARED_LOCK);
}else if( state==PAGER_OPEN ){
pager_unlock(pPager);
}
assert( state==pPager->eState );
}
}
}
/* Return the new journal mode */
return (int)pPager->journalMode;
}
| > > | 48636 48637 48638 48639 48640 48641 48642 48643 48644 48645 48646 48647 48648 48649 48650 48651 |
if( rc==SQLITE_OK && state==PAGER_READER ){
pagerUnlockDb(pPager, SHARED_LOCK);
}else if( state==PAGER_OPEN ){
pager_unlock(pPager);
}
assert( state==pPager->eState );
}
}else if( eMode==PAGER_JOURNALMODE_OFF ){
sqlite3OsClose(pPager->jfd);
}
}
/* Return the new journal mode */
return (int)pPager->journalMode;
}
|
| ︙ | ︙ | |||
49300 49301 49302 49303 49304 49305 49306 |
static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
int rc = SQLITE_OK;
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
int nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
| | | 49420 49421 49422 49423 49424 49425 49426 49427 49428 49429 49430 49431 49432 49433 49434 |
static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
int rc = SQLITE_OK;
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
int nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM;
}
memset((void*)&apNew[pWal->nWiData], 0,
sizeof(u32*)*(iPage+1-pWal->nWiData));
pWal->apWiData = apNew;
|
| ︙ | ︙ | |||
49925 49926 49927 49928 49929 49930 49931 |
if( version!=WAL_MAX_VERSION ){
rc = SQLITE_CANTOPEN_BKPT;
goto finished;
}
/* Malloc a buffer to read frames into. */
szFrame = szPage + WAL_FRAME_HDRSIZE;
| | | 50045 50046 50047 50048 50049 50050 50051 50052 50053 50054 50055 50056 50057 50058 50059 |
if( version!=WAL_MAX_VERSION ){
rc = SQLITE_CANTOPEN_BKPT;
goto finished;
}
/* Malloc a buffer to read frames into. */
szFrame = szPage + WAL_FRAME_HDRSIZE;
aFrame = (u8 *)sqlite3_malloc64(szFrame);
if( !aFrame ){
rc = SQLITE_NOMEM;
goto recovery_error;
}
aData = &aFrame[WAL_FRAME_HDRSIZE];
/* Read all frames from the log file. */
|
| ︙ | ︙ | |||
50318 50319 50320 50321 50322 50323 50324 |
iLast = pWal->hdr.mxFrame;
/* Allocate space for the WalIterator object. */
nSegment = walFramePage(iLast) + 1;
nByte = sizeof(WalIterator)
+ (nSegment-1)*sizeof(struct WalSegment)
+ iLast*sizeof(ht_slot);
| | | | 50438 50439 50440 50441 50442 50443 50444 50445 50446 50447 50448 50449 50450 50451 50452 50453 50454 50455 50456 50457 50458 50459 50460 50461 50462 |
iLast = pWal->hdr.mxFrame;
/* Allocate space for the WalIterator object. */
nSegment = walFramePage(iLast) + 1;
nByte = sizeof(WalIterator)
+ (nSegment-1)*sizeof(struct WalSegment)
+ iLast*sizeof(ht_slot);
p = (WalIterator *)sqlite3_malloc64(nByte);
if( !p ){
return SQLITE_NOMEM;
}
memset(p, 0, nByte);
p->nSegment = nSegment;
/* Allocate temporary space used by the merge-sort routine. This block
** of memory will be freed before this function returns.
*/
aTmp = (ht_slot *)sqlite3_malloc64(
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
rc = SQLITE_NOMEM;
}
for(i=0; rc==SQLITE_OK && i<nSegment; i++){
|
| ︙ | ︙ | |||
50508 50509 50510 50511 50512 50513 50514 50515 50516 50517 50518 50519 50520 50521 |
** safe to write into the database. Frames beyond mxSafeFrame might
** overwrite database pages that are in use by active readers and thus
** cannot be backfilled from the WAL.
*/
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; i<WAL_NREADER; i++){
u32 y = pInfo->aReadMark[i];
if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
| > > > > > > > > | 50628 50629 50630 50631 50632 50633 50634 50635 50636 50637 50638 50639 50640 50641 50642 50643 50644 50645 50646 50647 50648 50649 |
** safe to write into the database. Frames beyond mxSafeFrame might
** overwrite database pages that are in use by active readers and thus
** cannot be backfilled from the WAL.
*/
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; i<WAL_NREADER; i++){
/* Thread-sanitizer reports that the following is an unsafe read,
** as some other thread may be in the process of updating the value
** of the aReadMark[] slot. The assumption here is that if that is
** happening, the other client may only be increasing the value,
** not decreasing it. So assuming either that either the "old" or
** "new" version of the value is read, and not some arbitrary value
** that would never be written by a real client, things are still
** safe. */
u32 y = pInfo->aReadMark[i];
if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
| ︙ | ︙ | |||
52229 52230 52231 52232 52233 52234 52235 52236 52237 52238 52239 52240 52241 52242 | u8 intKey; /* True if table b-trees. False for index b-trees */ u8 intKeyLeaf; /* True if the leaf of an intKey table */ u8 noPayload; /* True if internal intKey page (thus w/o data) */ u8 leaf; /* True if a leaf page */ u8 hdrOffset; /* 100 for page 1. 0 otherwise */ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ u8 max1bytePayload; /* min(maxLocal,127) */ u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ u16 cellOffset; /* Index in aData of first cell pointer */ u16 nFree; /* Number of free bytes on the page */ u16 nCell; /* Number of cells on this page, local and ovfl */ u16 maskPage; /* Mask for page offset */ u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th | > | 52357 52358 52359 52360 52361 52362 52363 52364 52365 52366 52367 52368 52369 52370 52371 | u8 intKey; /* True if table b-trees. False for index b-trees */ u8 intKeyLeaf; /* True if the leaf of an intKey table */ u8 noPayload; /* True if internal intKey page (thus w/o data) */ u8 leaf; /* True if a leaf page */ u8 hdrOffset; /* 100 for page 1. 0 otherwise */ u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ u8 max1bytePayload; /* min(maxLocal,127) */ u8 bBusy; /* Prevent endless loops on corrupt database files */ u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ u16 cellOffset; /* Index in aData of first cell pointer */ u16 nFree; /* Number of free bytes on the page */ u16 nCell; /* Number of cells on this page, local and ovfl */ u16 maskPage; /* Mask for page offset */ u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th |
| ︙ | ︙ | |||
53004 53005 53006 53007 53008 53009 53010 | /* ** Enable or disable the shared pager and schema features. ** ** This routine has no effect on existing database connections. ** The shared cache setting effects only future calls to ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). */ | | | 53133 53134 53135 53136 53137 53138 53139 53140 53141 53142 53143 53144 53145 53146 53147 |
/*
** Enable or disable the shared pager and schema features.
**
** This routine has no effect on existing database connections.
** The shared cache setting effects only future calls to
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){
sqlite3GlobalConfig.sharedCacheEnabled = enable;
return SQLITE_OK;
}
#endif
|
| ︙ | ︙ | |||
53518 53519 53520 53521 53522 53523 53524 |
**
** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
** prior to calling this routine.
*/
static int saveCursorPosition(BtCursor *pCur){
int rc;
| | > > > > > | 53647 53648 53649 53650 53651 53652 53653 53654 53655 53656 53657 53658 53659 53660 53661 53662 53663 53664 53665 53666 53667 53668 53669 |
**
** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
** prior to calling this routine.
*/
static int saveCursorPosition(BtCursor *pCur){
int rc;
assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState );
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
if( pCur->eState==CURSOR_SKIPNEXT ){
pCur->eState = CURSOR_VALID;
}else{
pCur->skipNext = 0;
}
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
/* If this is an intKey table, then the above call to BtreeKeySize()
** stores the integer key in pCur->nKey. In this case this value is
** all that is required. Otherwise, if pCur is not open on an intKey
** table, then malloc space for and store the pCur->nKey bytes of key
|
| ︙ | ︙ | |||
53592 53593 53594 53595 53596 53597 53598 |
static int SQLITE_NOINLINE saveCursorsOnList(
BtCursor *p, /* The first cursor that needs saving */
Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
BtCursor *pExcept /* Do not save this cursor */
){
do{
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
| | | 53726 53727 53728 53729 53730 53731 53732 53733 53734 53735 53736 53737 53738 53739 53740 |
static int SQLITE_NOINLINE saveCursorsOnList(
BtCursor *p, /* The first cursor that needs saving */
Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */
BtCursor *pExcept /* Do not save this cursor */
){
do{
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
int rc = saveCursorPosition(p);
if( SQLITE_OK!=rc ){
return rc;
}
}else{
testcase( p->iPage>0 );
btreeReleaseAllCursorPages(p);
|
| ︙ | ︙ | |||
53664 53665 53666 53667 53668 53669 53670 53671 53672 53673 53674 53675 53676 |
** when saveCursorPosition() was called. Note that this call deletes the
** saved position info stored by saveCursorPosition(), so there can be
** at most one effective restoreCursorPosition() call after each
** saveCursorPosition().
*/
static int btreeRestoreCursorPosition(BtCursor *pCur){
int rc;
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState>=CURSOR_REQUIRESEEK );
if( pCur->eState==CURSOR_FAULT ){
return pCur->skipNext;
}
pCur->eState = CURSOR_INVALID;
| > | > | 53798 53799 53800 53801 53802 53803 53804 53805 53806 53807 53808 53809 53810 53811 53812 53813 53814 53815 53816 53817 53818 53819 53820 53821 53822 53823 53824 |
** when saveCursorPosition() was called. Note that this call deletes the
** saved position info stored by saveCursorPosition(), so there can be
** at most one effective restoreCursorPosition() call after each
** saveCursorPosition().
*/
static int btreeRestoreCursorPosition(BtCursor *pCur){
int rc;
int skipNext;
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState>=CURSOR_REQUIRESEEK );
if( pCur->eState==CURSOR_FAULT ){
return pCur->skipNext;
}
pCur->eState = CURSOR_INVALID;
rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
if( rc==SQLITE_OK ){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
pCur->skipNext |= skipNext;
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
pCur->eState = CURSOR_SKIPNEXT;
}
}
return rc;
}
|
| ︙ | ︙ | |||
53726 53727 53728 53729 53730 53731 53732 |
assert( pCur!=0 );
assert( pCur->eState!=CURSOR_VALID );
rc = restoreCursorPosition(pCur);
if( rc ){
*pDifferentRow = 1;
return rc;
}
| | > | 53862 53863 53864 53865 53866 53867 53868 53869 53870 53871 53872 53873 53874 53875 53876 53877 53878 53879 |
assert( pCur!=0 );
assert( pCur->eState!=CURSOR_VALID );
rc = restoreCursorPosition(pCur);
if( rc ){
*pDifferentRow = 1;
return rc;
}
if( pCur->eState!=CURSOR_VALID ){
*pDifferentRow = 1;
}else{
assert( pCur->skipNext==0 );
*pDifferentRow = 0;
}
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
|
| ︙ | ︙ | |||
54869 54870 54871 54872 54873 54874 54875 54876 |
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/*
** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with
*/
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
int nFullPathname = pVfs->mxPathname+1;
| > | > | | 55006 55007 55008 55009 55010 55011 55012 55013 55014 55015 55016 55017 55018 55019 55020 55021 55022 55023 55024 55025 55026 55027 55028 55029 55030 55031 |
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/*
** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with
*/
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
int nFilename = sqlite3Strlen30(zFilename)+1;
int nFullPathname = pVfs->mxPathname+1;
char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename));
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
return SQLITE_NOMEM;
}
if( isMemdb ){
memcpy(zFullPathname, zFilename, nFilename);
}else{
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
if( rc ){
sqlite3_free(zFullPathname);
sqlite3_free(p);
return rc;
|
| ︙ | ︙ | |||
55337 55338 55339 55340 55341 55342 55343 |
if( nReserve<0 ){
nReserve = pBt->pageSize - pBt->usableSize;
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
| | | 55476 55477 55478 55479 55480 55481 55482 55483 55484 55485 55486 55487 55488 55489 55490 |
if( nReserve<0 ){
nReserve = pBt->pageSize - pBt->usableSize;
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
assert( (pageSize & 7)==0 );
assert( !pBt->pCursor );
pBt->pageSize = (u32)pageSize;
freeTempSpace(pBt);
}
rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
pBt->usableSize = pBt->pageSize - (u16)nReserve;
if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED;
sqlite3BtreeLeave(p);
|
| ︙ | ︙ | |||
56543 56544 56545 56546 56547 56548 56549 |
assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
if( pBtree ){
sqlite3BtreeEnter(pBtree);
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
int i;
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
| | | 56682 56683 56684 56685 56686 56687 56688 56689 56690 56691 56692 56693 56694 56695 56696 |
assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
if( pBtree ){
sqlite3BtreeEnter(pBtree);
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
int i;
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
rc = saveCursorPosition(p);
if( rc!=SQLITE_OK ){
(void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
break;
}
}
}else{
|
| ︙ | ︙ | |||
56949 56950 56951 56952 56953 56954 56955 56956 56957 56958 56959 56960 56961 56962 |
** Failure is not possible. This function always returns SQLITE_OK.
** It might just as well be a procedure (returning void) but we continue
** to return an integer result code for historical reasons.
*/
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
getCellInfo(pCur);
*pSize = pCur->info.nPayload;
return SQLITE_OK;
}
/*
| > > | 57088 57089 57090 57091 57092 57093 57094 57095 57096 57097 57098 57099 57100 57101 57102 57103 |
** Failure is not possible. This function always returns SQLITE_OK.
** It might just as well be a procedure (returning void) but we continue
** to return an integer result code for historical reasons.
*/
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>=0 );
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
getCellInfo(pCur);
*pSize = pCur->info.nPayload;
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
57357 57358 57359 57360 57361 57362 57363 57364 57365 57366 57367 57368 57369 |
** page of the database. The data might change or move the next time
** any btree routine is called.
*/
static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
| > > > > > | | 57498 57499 57500 57501 57502 57503 57504 57505 57506 57507 57508 57509 57510 57511 57512 57513 57514 57515 57516 57517 57518 57519 57520 57521 57522 57523 |
** page of the database. The data might change or move the next time
** any btree routine is called.
*/
static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
u32 amt;
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
assert( pCur->info.nSize>0 );
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
*pAmt = amt;
return (void*)pCur->info.pPayload;
}
/*
** For the entry that cursor pCur is point to, return as
** many bytes of the key or data as are available on the local
|
| ︙ | ︙ | |||
57427 57428 57429 57430 57431 57432 57433 |
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
return SQLITE_CORRUPT_BKPT;
}
return SQLITE_OK;
}
| | > > | 57573 57574 57575 57576 57577 57578 57579 57580 57581 57582 57583 57584 57585 57586 57587 57588 57589 57590 57591 57592 57593 57594 57595 57596 57597 |
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
return SQLITE_CORRUPT_BKPT;
}
return SQLITE_OK;
}
#if SQLITE_DEBUG
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
** cell in page pParent. Or, if iIdx is equal to the total number of
** cells in pParent, that page number iChild is the right-child of
** the page.
*/
static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
if( CORRUPT_DB ) return; /* The conditions tested below might not be true
** in a corrupt database */
assert( iIdx<=pParent->nCell );
if( iIdx==pParent->nCell ){
assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild );
}else{
assert( get4byte(findCell(pParent, iIdx))==iChild );
}
}
|
| ︙ | ︙ | |||
57460 57461 57462 57463 57464 57465 57466 |
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>0 );
assert( pCur->apPage[pCur->iPage] );
| < < < < < < < < | 57608 57609 57610 57611 57612 57613 57614 57615 57616 57617 57618 57619 57620 57621 57622 57623 57624 57625 57626 |
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>0 );
assert( pCur->apPage[pCur->iPage] );
assertParentIndex(
pCur->apPage[pCur->iPage-1],
pCur->aiIdx[pCur->iPage-1],
pCur->apPage[pCur->iPage]->pgno
);
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
releasePage(pCur->apPage[pCur->iPage]);
pCur->iPage--;
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
}
|
| ︙ | ︙ | |||
59647 59648 59649 59650 59651 59652 59653 |
}else{
assert( bBulk==0 || bBulk==1 );
if( iParentIdx==0 ){
nxDiv = 0;
}else if( iParentIdx==i ){
nxDiv = i-2+bBulk;
}else{
| < | 59787 59788 59789 59790 59791 59792 59793 59794 59795 59796 59797 59798 59799 59800 |
}else{
assert( bBulk==0 || bBulk==1 );
if( iParentIdx==0 ){
nxDiv = 0;
}else if( iParentIdx==i ){
nxDiv = i-2+bBulk;
}else{
nxDiv = iParentIdx-1;
}
i = 2-bBulk;
}
nOld = i+1;
if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
pRight = &pParent->aData[pParent->hdrOffset+8];
|
| ︙ | ︙ | |||
60420 60421 60422 60423 60424 60425 60426 60427 60428 60429 60430 60431 60432 60433 |
}
pPage->nOverflow = 0;
/* The next iteration of the do-loop balances the parent page. */
releasePage(pPage);
pCur->iPage--;
}
}while( rc==SQLITE_OK );
if( pFree ){
sqlite3PageFree(pFree);
}
return rc;
| > | 60559 60560 60561 60562 60563 60564 60565 60566 60567 60568 60569 60570 60571 60572 60573 |
}
pPage->nOverflow = 0;
/* The next iteration of the do-loop balances the parent page. */
releasePage(pPage);
pCur->iPage--;
assert( pCur->iPage>=0 );
}
}while( rc==SQLITE_OK );
if( pFree ){
sqlite3PageFree(pFree);
}
return rc;
|
| ︙ | ︙ | |||
60896 60897 60898 60899 60900 60901 60902 |
int hdr;
u16 szCell;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
| < > > > > > | 61036 61037 61038 61039 61040 61041 61042 61043 61044 61045 61046 61047 61048 61049 61050 61051 61052 61053 61054 61055 61056 |
int hdr;
u16 szCell;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
return SQLITE_CORRUPT_BKPT;
}
rc = getAndInitPage(pBt, pgno, &pPage, 0);
if( rc ) return rc;
if( pPage->bBusy ){
rc = SQLITE_CORRUPT_BKPT;
goto cleardatabasepage_out;
}
pPage->bBusy = 1;
hdr = pPage->hdrOffset;
for(i=0; i<pPage->nCell; i++){
pCell = findCell(pPage, i);
if( !pPage->leaf ){
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}
|
| ︙ | ︙ | |||
60923 60924 60925 60926 60927 60928 60929 60930 60931 60932 60933 60934 60935 60936 |
if( freePageFlag ){
freePage(pPage, &rc);
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
}
cleardatabasepage_out:
releasePage(pPage);
return rc;
}
/*
** Delete all information from a single table in the database. iTable is
** the page number of the root of the table. After this routine returns,
| > | 61067 61068 61069 61070 61071 61072 61073 61074 61075 61076 61077 61078 61079 61080 61081 |
if( freePageFlag ){
freePage(pPage, &rc);
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
}
cleardatabasepage_out:
pPage->bBusy = 0;
releasePage(pPage);
return rc;
}
/*
** Delete all information from a single table in the database. iTable is
** the page number of the root of the table. After this routine returns,
|
| ︙ | ︙ | |||
61429 61430 61431 61432 61433 61434 61435 61436 61437 61438 61439 61440 61441 61442 |
}
#endif
iPage = get4byte(pOvflData);
sqlite3PagerUnref(pOvflPage);
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Do various sanity checks on a single page of a tree. Return
** the tree depth. Root pages return 0. Parents of root pages
** return 1, and so forth.
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 61574 61575 61576 61577 61578 61579 61580 61581 61582 61583 61584 61585 61586 61587 61588 61589 61590 61591 61592 61593 61594 61595 61596 61597 61598 61599 61600 61601 61602 61603 61604 61605 61606 61607 61608 61609 61610 61611 61612 61613 61614 61615 61616 61617 61618 61619 61620 61621 61622 61623 61624 61625 61626 61627 61628 61629 61630 61631 61632 61633 61634 61635 61636 61637 61638 |
}
#endif
iPage = get4byte(pOvflData);
sqlite3PagerUnref(pOvflPage);
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/*
** An implementation of a min-heap.
**
** aHeap[0] is the number of elements on the heap. aHeap[1] is the
** root element. The daughter nodes of aHeap[N] are aHeap[N*2]
** and aHeap[N*2+1].
**
** The heap property is this: Every node is less than or equal to both
** of its daughter nodes. A consequence of the heap property is that the
** root node aHeap[1] is always the minimum value currently in the heap.
**
** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
** the heap, preserving the heap property. The btreeHeapPull() routine
** removes the root element from the heap (the minimum value in the heap)
** and then moves other nodes around as necessary to preserve the heap
** property.
**
** This heap is used for cell overlap and coverage testing. Each u32
** entry represents the span of a cell or freeblock on a btree page.
** The upper 16 bits are the index of the first byte of a range and the
** lower 16 bits are the index of the last byte of that range.
*/
static void btreeHeapInsert(u32 *aHeap, u32 x){
u32 j, i = ++aHeap[0];
aHeap[i] = x;
while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
x = aHeap[j];
aHeap[j] = aHeap[i];
aHeap[i] = x;
i = j;
}
}
static int btreeHeapPull(u32 *aHeap, u32 *pOut){
u32 j, i, x;
if( (x = aHeap[0])==0 ) return 0;
*pOut = aHeap[1];
aHeap[1] = aHeap[x];
aHeap[x] = 0xffffffff;
aHeap[0]--;
i = 1;
while( (j = i*2)<=aHeap[0] ){
if( aHeap[j]>aHeap[j+1] ) j++;
if( aHeap[i]<aHeap[j] ) break;
x = aHeap[i];
aHeap[i] = aHeap[j];
aHeap[j] = x;
i = j;
}
return 1;
}
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Do various sanity checks on a single page of a tree. Return
** the tree depth. Root pages return 0. Parents of root pages
** return 1, and so forth.
**
|
| ︙ | ︙ | |||
61462 61463 61464 61465 61466 61467 61468 | MemPage *pPage; int i, rc, depth, d2, pgno, cnt; int hdr, cellStart; int nCell; u8 *data; BtShared *pBt; int usableSize; | > | | 61658 61659 61660 61661 61662 61663 61664 61665 61666 61667 61668 61669 61670 61671 61672 61673 | MemPage *pPage; int i, rc, depth, d2, pgno, cnt; int hdr, cellStart; int nCell; u8 *data; BtShared *pBt; int usableSize; u32 *heap = 0; u32 x, prev = 0; i64 nMinKey = 0; i64 nMaxKey = 0; const char *saved_zPfx = pCheck->zPfx; int saved_v1 = pCheck->v1; int saved_v2 = pCheck->v2; /* Check that the page exists |
| ︙ | ︙ | |||
61607 61608 61609 61610 61611 61612 61613 |
}
}
/* Check for complete coverage of the page
*/
data = pPage->aData;
hdr = pPage->hdrOffset;
| | | | | < | | < < | > > > > | | > > > > | | | 61804 61805 61806 61807 61808 61809 61810 61811 61812 61813 61814 61815 61816 61817 61818 61819 61820 61821 61822 61823 61824 61825 61826 61827 61828 61829 61830 61831 61832 61833 61834 61835 61836 61837 61838 61839 61840 61841 61842 61843 61844 61845 61846 61847 61848 61849 61850 61851 61852 61853 61854 61855 61856 61857 61858 61859 61860 61861 61862 61863 61864 61865 61866 61867 61868 61869 61870 61871 61872 61873 61874 61875 61876 61877 61878 61879 61880 61881 61882 61883 61884 61885 61886 61887 61888 61889 61890 61891 61892 61893 61894 61895 61896 |
}
}
/* Check for complete coverage of the page
*/
data = pPage->aData;
hdr = pPage->hdrOffset;
heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
pCheck->zPfx = 0;
if( heap==0 ){
pCheck->mallocFailed = 1;
}else{
int contentOffset = get2byteNotZero(&data[hdr+5]);
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
heap[0] = 0;
btreeHeapInsert(heap, contentOffset-1);
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
** number of cells on the page. */
nCell = get2byte(&data[hdr+3]);
/* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
** immediately follows the b-tree page header. */
cellStart = hdr + 12 - 4*pPage->leaf;
/* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
** integer offsets to the cell contents. */
for(i=0; i<nCell; i++){
int pc = get2byte(&data[cellStart+i*2]);
u32 size = 65536;
if( pc<=usableSize-4 ){
size = cellSizePtr(pPage, &data[pc]);
}
if( (int)(pc+size-1)>=usableSize ){
pCheck->zPfx = 0;
checkAppendMsg(pCheck,
"Corruption detected in cell %d on page %d",i,iPage);
}else{
btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
}
}
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
** is the offset of the first freeblock, or zero if there are no
** freeblocks on the page. */
i = get2byte(&data[hdr+1]);
while( i>0 ){
int size, j;
assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
size = get2byte(&data[i+2]);
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
btreeHeapInsert(heap, (i<<16)|(i+size-1));
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
** big-endian integer which is the offset in the b-tree page of the next
** freeblock in the chain, or zero if the freeblock is the last on the
** chain. */
j = get2byte(&data[i]);
/* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
** increasing offset. */
assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
i = j;
}
cnt = 0;
assert( heap[0]>0 );
assert( (heap[1]>>16)==0 );
btreeHeapPull(heap,&prev);
while( btreeHeapPull(heap,&x) ){
if( (prev&0xffff)+1>(x>>16) ){
checkAppendMsg(pCheck,
"Multiple uses for byte %u of page %d", x>>16, iPage);
break;
}else{
cnt += (x>>16) - (prev&0xffff) - 1;
prev = x;
}
}
cnt += usableSize - (prev&0xffff) - 1;
/* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
** is stored in the fifth field of the b-tree page header.
** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
** number of fragmented free bytes within the cell content area.
*/
if( heap[0]==0 && cnt!=data[hdr+7] ){
checkAppendMsg(pCheck,
"Fragmentation of %d bytes reported as %d on page %d",
cnt, data[hdr+7], iPage);
}
}
sqlite3PageFree(heap);
releasePage(pPage);
end_of_check:
pCheck->zPfx = saved_zPfx;
pCheck->v1 = saved_v1;
pCheck->v2 = saved_v2;
return depth+1;
|
| ︙ | ︙ | |||
61744 61745 61746 61747 61748 61749 61750 |
if( !sCheck.aPgRef ){
*pnErr = 1;
sqlite3BtreeLeave(p);
return 0;
}
i = PENDING_BYTE_PAGE(pBt);
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
| | < | 61946 61947 61948 61949 61950 61951 61952 61953 61954 61955 61956 61957 61958 61959 61960 |
if( !sCheck.aPgRef ){
*pnErr = 1;
sqlite3BtreeLeave(p);
return 0;
}
i = PENDING_BYTE_PAGE(pBt);
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
/* Check the integrity of the freelist
*/
sCheck.zPfx = "Main freelist: ";
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
get4byte(&pBt->pPage1->aData[36]));
sCheck.zPfx = 0;
|
| ︙ | ︙ | |||
62237 62238 62239 62240 62241 62242 62243 | ** Create an sqlite3_backup process to copy the contents of zSrcDb from ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return ** a pointer to the new sqlite3_backup object. ** ** If an error occurs, NULL is returned and an error code and error message ** stored in database handle pDestDb. */ | | | 62438 62439 62440 62441 62442 62443 62444 62445 62446 62447 62448 62449 62450 62451 62452 |
** Create an sqlite3_backup process to copy the contents of zSrcDb from
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
** a pointer to the new sqlite3_backup object.
**
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
sqlite3* pDestDb, /* Database to write to */
const char *zDestDb, /* Name of database within pDestDb */
sqlite3* pSrcDb, /* Database connection to read from */
const char *zSrcDb /* Name of database within pSrcDb */
){
sqlite3_backup *p; /* Value to return */
|
| ︙ | ︙ | |||
62445 62446 62447 62448 62449 62450 62451 | *pp = p; p->isAttached = 1; } /* ** Copy nPage pages from the source b-tree to the destination. */ | | | 62646 62647 62648 62649 62650 62651 62652 62653 62654 62655 62656 62657 62658 62659 62660 |
*pp = p;
p->isAttached = 1;
}
/*
** Copy nPage pages from the source b-tree to the destination.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
int rc;
int destMode; /* Destination journal mode */
int pgszSrc = 0; /* Source page size */
int pgszDest = 0; /* Destination page size */
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return SQLITE_MISUSE_BKPT;
|
| ︙ | ︙ | |||
62690 62691 62692 62693 62694 62695 62696 | sqlite3_mutex_leave(p->pSrcDb->mutex); return rc; } /* ** Release all resources associated with an sqlite3_backup* handle. */ | | | 62891 62892 62893 62894 62895 62896 62897 62898 62899 62900 62901 62902 62903 62904 62905 |
sqlite3_mutex_leave(p->pSrcDb->mutex);
return rc;
}
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
/* Enter the mutexes */
if( p==0 ) return SQLITE_OK;
pSrcDb = p->pSrcDb;
|
| ︙ | ︙ | |||
62742 62743 62744 62745 62746 62747 62748 | return rc; } /* ** Return the number of pages still to be backed up as of the most recent ** call to sqlite3_backup_step(). */ | | | | 62943 62944 62945 62946 62947 62948 62949 62950 62951 62952 62953 62954 62955 62956 62957 62958 62959 62960 62961 62962 62963 62964 62965 62966 62967 62968 62969 62970 62971 |
return rc;
}
/*
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return p->nRemaining;
}
/*
** Return the total number of pages in the source database as of the most
** recent call to sqlite3_backup_step().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return p->nPagecount;
|
| ︙ | ︙ | |||
63081 63082 63083 63084 63085 63086 63087 63088 |
if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
return SQLITE_NOMEM;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->flags |= MEM_Term;
#ifdef SQLITE_DEBUG
| > > | < | 63282 63283 63284 63285 63286 63287 63288 63289 63290 63291 63292 63293 63294 63295 63296 63297 63298 63299 63300 |
if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
return SQLITE_NOMEM;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
pMem->flags |= MEM_Term;
}
pMem->flags &= ~MEM_Ephem;
#ifdef SQLITE_DEBUG
pMem->pScopyFrom = 0;
#endif
return SQLITE_OK;
}
/*
** If the given Mem* has a zero-filled tail, turn it into an ordinary
** blob stored in dynamically allocated space.
|
| ︙ | ︙ | |||
64528 64529 64530 64531 64532 64533 64534 |
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
if( pRec ){
int i;
int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; i<nCol; i++){
| | | 64730 64731 64732 64733 64734 64735 64736 64737 64738 64739 64740 64741 64742 64743 64744 |
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
if( pRec ){
int i;
int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; i<nCol; i++){
sqlite3VdbeMemRelease(&aMem[i]);
}
sqlite3KeyInfoUnref(pRec->pKeyInfo);
sqlite3DbFree(db, pRec);
}
}
#endif /* ifdef SQLITE_ENABLE_STAT4 */
|
| ︙ | ︙ | |||
64631 64632 64633 64634 64635 64636 64637 | p->zSql = sqlite3DbStrNDup(p->db, z, n); p->isPrepareV2 = (u8)isPrepareV2; } /* ** Return the SQL associated with a prepared statement */ | | | 64833 64834 64835 64836 64837 64838 64839 64840 64841 64842 64843 64844 64845 64846 64847 |
p->zSql = sqlite3DbStrNDup(p->db, z, n);
p->isPrepareV2 = (u8)isPrepareV2;
}
/*
** Return the SQL associated with a prepared statement
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return (p && p->isPrepareV2) ? p->zSql : 0;
}
/*
** Swap all content between two VDBE structures.
*/
|
| ︙ | ︙ | |||
66364 66365 66366 66367 66368 66369 66370 66371 66372 66373 66374 66375 66376 66377 66378 66379 66380 66381 66382 66383 66384 66385 |
const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
assert( pVtabCursor->pVtab->nRef>0 );
pVtabCursor->pVtab->nRef--;
pModule->xClose(pVtabCursor);
}
#endif
}
/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
v->aOnceFlag = pFrame->aOnceFlag;
v->nOnceFlag = pFrame->nOnceFlag;
v->aOp = pFrame->aOp;
v->nOp = pFrame->nOp;
| > > > > > > > > > > > > > > > > > | 66566 66567 66568 66569 66570 66571 66572 66573 66574 66575 66576 66577 66578 66579 66580 66581 66582 66583 66584 66585 66586 66587 66588 66589 66590 66591 66592 66593 66594 66595 66596 66597 66598 66599 66600 66601 66602 66603 66604 |
const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
assert( pVtabCursor->pVtab->nRef>0 );
pVtabCursor->pVtab->nRef--;
pModule->xClose(pVtabCursor);
}
#endif
}
/*
** Close all cursors in the current frame.
*/
static void closeCursorsInFrame(Vdbe *p){
if( p->apCsr ){
int i;
for(i=0; i<p->nCursor; i++){
VdbeCursor *pC = p->apCsr[i];
if( pC ){
sqlite3VdbeFreeCursor(p, pC);
p->apCsr[i] = 0;
}
}
}
}
/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
** control to the main program.
*/
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
closeCursorsInFrame(v);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
v->aOnceFlag = pFrame->aOnceFlag;
v->nOnceFlag = pFrame->nOnceFlag;
v->aOp = pFrame->aOp;
v->nOp = pFrame->nOp;
|
| ︙ | ︙ | |||
66406 66407 66408 66409 66410 66411 66412 |
VdbeFrame *pFrame;
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
sqlite3VdbeFrameRestore(pFrame);
p->pFrame = 0;
p->nFrame = 0;
}
assert( p->nFrame==0 );
| | < < < < < < < < < < | 66625 66626 66627 66628 66629 66630 66631 66632 66633 66634 66635 66636 66637 66638 66639 |
VdbeFrame *pFrame;
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
sqlite3VdbeFrameRestore(pFrame);
p->pFrame = 0;
p->nFrame = 0;
}
assert( p->nFrame==0 );
closeCursorsInFrame(p);
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}
while( p->pDelFrame ){
VdbeFrame *pDel = p->pDelFrame;
p->pDelFrame = pDel->pParent;
sqlite3VdbeFrameDelete(pDel);
|
| ︙ | ︙ | |||
68161 68162 68163 68164 68165 68166 68167 | ** returned. ** ** If database corruption is discovered, set pPKey2->errCode to ** SQLITE_CORRUPT and return 0. If an OOM error is encountered, ** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the ** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). */ | | | 68370 68371 68372 68373 68374 68375 68376 68377 68378 68379 68380 68381 68382 68383 68384 |
** returned.
**
** If database corruption is discovered, set pPKey2->errCode to
** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */
){
u32 d1; /* Offset into aKey[] of next data element */
int i; /* Index of next field to compare */
u32 szHdr1; /* Size of record header in bytes */
|
| ︙ | ︙ | |||
68347 68348 68349 68350 68351 68352 68353 |
);
return pPKey2->default_rc;
}
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
| | | 68556 68557 68558 68559 68560 68561 68562 68563 68564 68565 68566 68567 68568 68569 68570 |
);
return pPKey2->default_rc;
}
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
}
/*
** This function is an optimized version of sqlite3VdbeRecordCompare()
** that (a) the first field of pPKey2 is an integer, and (b) the
** size-of-header varint at the start of (pKey1/nKey1) fits in a single
|
| ︙ | ︙ | |||
68435 68436 68437 68438 68439 68440 68441 |
if( v>lhs ){
res = pPKey2->r1;
}else if( v<lhs ){
res = pPKey2->r2;
}else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing
** fields. */
| | | 68644 68645 68646 68647 68648 68649 68650 68651 68652 68653 68654 68655 68656 68657 68658 |
if( v>lhs ){
res = pPKey2->r1;
}else if( v<lhs ){
res = pPKey2->r2;
}else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing
** fields. */
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
res = pPKey2->default_rc;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
|
| ︙ | ︙ | |||
68483 68484 68485 68486 68487 68488 68489 |
nCmp = MIN( pPKey2->aMem[0].n, nStr );
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
if( res==0 ){
res = nStr - pPKey2->aMem[0].n;
if( res==0 ){
if( pPKey2->nField>1 ){
| | | 68692 68693 68694 68695 68696 68697 68698 68699 68700 68701 68702 68703 68704 68705 68706 |
nCmp = MIN( pPKey2->aMem[0].n, nStr );
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
if( res==0 ){
res = nStr - pPKey2->aMem[0].n;
if( res==0 ){
if( pPKey2->nField>1 ){
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
}
}else if( res>0 ){
res = pPKey2->r2;
}else{
res = pPKey2->r1;
|
| ︙ | ︙ | |||
68787 68788 68789 68790 68791 68792 68793 | ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is ** added or changed. */ | | | 68996 68997 68998 68999 69000 69001 69002 69003 69004 69005 69006 69007 69008 69009 69010 |
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled. A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates. For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p==0 || p->expired;
}
#endif
/*
** Check on a Vdbe to make sure it has not been finalized. Log
|
| ︙ | ︙ | |||
68824 68825 68826 68827 68828 68829 68830 | ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ | | | 69033 69034 69035 69036 69037 69038 69039 69040 69041 69042 69043 69044 69045 69046 69047 |
** the sqlite3_compile() routine. The integer returned is an SQLITE_
** success/failure code that describes the result of executing the virtual
** machine.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
** pointer is a harmless no-op. */
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
|
| ︙ | ︙ | |||
68850 68851 68852 68853 68854 68855 68856 | ** Terminate the current execution of an SQL statement and reset it ** back to its starting state so that it can be reused. A success code from ** the prior execution is returned. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ | | | | 69059 69060 69061 69062 69063 69064 69065 69066 69067 69068 69069 69070 69071 69072 69073 69074 69075 69076 69077 69078 69079 69080 69081 69082 69083 69084 69085 69086 69087 69088 69089 69090 69091 69092 |
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from
** the prior execution is returned.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
rc = sqlite3VdbeReset(v);
sqlite3VdbeRewind(v);
assert( (rc & (v->db->errMask))==rc );
rc = sqlite3ApiExit(v->db, rc);
sqlite3_mutex_leave(v->db->mutex);
}
return rc;
}
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
#endif
sqlite3_mutex_enter(mutex);
|
| ︙ | ︙ | |||
68893 68894 68895 68896 68897 68898 68899 | } /**************************** sqlite3_value_ ******************************* ** The following routines extract information from a Mem or sqlite3_value ** structure. */ | | | | | | | | | | | | | 69102 69103 69104 69105 69106 69107 69108 69109 69110 69111 69112 69113 69114 69115 69116 69117 69118 69119 69120 69121 69122 69123 69124 69125 69126 69127 69128 69129 69130 69131 69132 69133 69134 69135 69136 69137 69138 69139 69140 69141 69142 69143 69144 69145 69146 69147 69148 69149 69150 69151 69152 69153 69154 69155 69156 69157 69158 69159 |
}
/**************************** sqlite3_value_ *******************************
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite3VdbeMemExpandBlob(p);
p->flags |= MEM_Blob;
return p->n ? p->z : 0;
}else{
return sqlite3_value_text(pVal);
}
}
SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){
return sqlite3VdbeRealValue((Mem*)pVal);
}
SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){
return (int)sqlite3VdbeIntValue((Mem*)pVal);
}
SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){
return sqlite3VdbeIntValue((Mem*)pVal);
}
SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){
return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16BE);
}
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16LE);
}
#endif /* SQLITE_OMIT_UTF16 */
/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
** point number string BLOB NULL
*/
SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 */
SQLITE_NULL, /* 0x01 */
SQLITE_TEXT, /* 0x02 */
SQLITE_NULL, /* 0x03 */
SQLITE_INTEGER, /* 0x04 */
SQLITE_NULL, /* 0x05 */
|
| ︙ | ︙ | |||
69012 69013 69014 69015 69016 69017 69018 |
/* noop */
}else{
xDel((void*)p);
}
if( pCtx ) sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
| | | | | | | | | | | | | | | | | | | | 69221 69222 69223 69224 69225 69226 69227 69228 69229 69230 69231 69232 69233 69234 69235 69236 69237 69238 69239 69240 69241 69242 69243 69244 69245 69246 69247 69248 69249 69250 69251 69252 69253 69254 69255 69256 69257 69258 69259 69260 69261 69262 69263 69264 69265 69266 69267 69268 69269 69270 69271 69272 69273 69274 69275 69276 69277 69278 69279 69280 69281 69282 69283 69284 69285 69286 69287 69288 69289 69290 69291 69292 69293 69294 69295 69296 69297 69298 69299 69300 69301 69302 69303 69304 69305 69306 69307 69308 69309 69310 69311 69312 69313 69314 69315 69316 69317 69318 69319 69320 69321 69322 69323 69324 69325 69326 69327 69328 69329 69330 69331 69332 69333 69334 69335 69336 69337 69338 69339 69340 69341 69342 69343 69344 69345 69346 69347 69348 69349 69350 69351 69352 69353 69354 69355 69356 69357 69358 69359 69360 69361 69362 69363 69364 69365 69366 69367 69368 69369 69370 69371 69372 69373 |
/* noop */
}else{
xDel((void*)p);
}
if( pCtx ) sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( n>=0 );
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
sqlite3_context *pCtx,
const void *z,
sqlite3_uint64 n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
assert( xDel!=SQLITE_DYNAMIC );
if( n>0x7fffffff ){
(void)invokeValueDestructor(z, xDel, pCtx);
}else{
setResultStrOrError(pCtx, z, (int)n, 0, xDel);
}
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
sqlite3_context *pCtx,
const char *z,
sqlite3_uint64 n,
void (*xDel)(void *),
unsigned char enc
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
assert( xDel!=SQLITE_DYNAMIC );
if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
if( n>0x7fffffff ){
(void)invokeValueDestructor(z, xDel, pCtx);
}else{
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
}
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pCtx->pOut, pValue);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
}
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
#ifdef SQLITE_DEBUG
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
#endif
if( pCtx->pOut->flags & MEM_Null ){
sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
}
}
/* Force an SQLITE_TOOBIG error. */
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
/* An SQLITE_NOMEM error. */
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM;
pCtx->fErrorOrAux = 1;
pCtx->pOut->db->mallocFailed = 1;
}
|
| ︙ | ︙ | |||
69323 69324 69325 69326 69327 69328 69329 | } /* ** This is the top-level implementation of sqlite3_step(). Call ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. */ | | | 69532 69533 69534 69535 69536 69537 69538 69539 69540 69541 69542 69543 69544 69545 69546 |
}
/*
** This is the top-level implementation of sqlite3_step(). Call
** sqlite3Step() to do most of the work. If a schema error occurs,
** call sqlite3Reprepare() and try again.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
int rc = SQLITE_OK; /* Result from sqlite3Step() */
int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */
Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
int cnt = 0; /* Counter to prevent infinite loop of reprepares */
sqlite3 *db; /* The database connection */
if( vdbeSafetyNotNull(v) ){
|
| ︙ | ︙ | |||
69374 69375 69376 69377 69378 69379 69380 | } /* ** Extract the user data from a sqlite3_context structure and return a ** pointer to it. */ | | | | 69583 69584 69585 69586 69587 69588 69589 69590 69591 69592 69593 69594 69595 69596 69597 69598 69599 69600 69601 69602 69603 69604 69605 69606 69607 69608 69609 69610 69611 69612 |
}
/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
assert( p && p->pFunc );
return p->pFunc->pUserData;
}
/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
**
** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface
** returns a copy of the pointer to the database connection (the 1st
** parameter) of the sqlite3_create_function() and
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
assert( p && p->pFunc );
return p->pOut->db;
}
/*
** Return the current time for a statement. If the current time
** is requested more than once within the same run of a single prepared
|
| ︙ | ︙ | |||
69465 69466 69467 69468 69469 69470 69471 | } /* ** Allocate or return the aggregate context for a user function. A new ** context is allocated on the first call. Subsequent calls return the ** same context that was returned on prior calls. */ | | | | | 69674 69675 69676 69677 69678 69679 69680 69681 69682 69683 69684 69685 69686 69687 69688 69689 69690 69691 69692 69693 69694 69695 69696 69697 69698 69699 69700 69701 69702 69703 69704 69705 69706 69707 69708 69709 69710 69711 69712 69713 69714 69715 69716 69717 69718 69719 69720 69721 69722 69723 69724 |
}
/*
** Allocate or return the aggregate context for a user function. A new
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
assert( sqlite3_mutex_held(p->pOut->db->mutex) );
testcase( nByte<0 );
if( (p->pMem->flags & MEM_Agg)==0 ){
return createAggContext(p, nByte);
}else{
return (void*)p->pMem->z;
}
}
/*
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#if SQLITE_ENABLE_STAT3_OR_STAT4
if( pCtx->pVdbe==0 ) return 0;
#else
assert( pCtx->pVdbe!=0 );
#endif
for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
return (pAuxData ? pAuxData->pAux : 0);
}
/*
** Set the auxiliary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
void (*xDelete)(void*)
){
AuxData *pAuxData;
Vdbe *pVdbe = pCtx->pVdbe;
|
| ︙ | ︙ | |||
69556 69557 69558 69559 69560 69561 69562 | ** called. ** ** This function is deprecated. Do not use it for new code. It is ** provide only to avoid breaking legacy code. New aggregate function ** implementations should keep their own counts within their aggregate ** context. */ | | | | | 69765 69766 69767 69768 69769 69770 69771 69772 69773 69774 69775 69776 69777 69778 69779 69780 69781 69782 69783 69784 69785 69786 69787 69788 69789 69790 69791 69792 69793 69794 69795 69796 69797 |
** called.
**
** This function is deprecated. Do not use it for new code. It is
** provide only to avoid breaking legacy code. New aggregate function
** implementations should keep their own counts within their aggregate
** context.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
return p->pMem->n;
}
#endif
/*
** Return the number of columns in the result set for the statement pStmt.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm ? pVm->nResColumn : 0;
}
/*
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( pVm==0 || pVm->pResultSet==0 ) return 0;
return pVm->nResColumn;
}
/*
** Return a pointer to static memory containing an SQL NULL value.
|
| ︙ | ︙ | |||
69676 69677 69678 69679 69680 69681 69682 | } } /**************************** sqlite3_column_ ******************************* ** The following routines are used to access elements of the current row ** in the result set. */ | | | | | | | | | | | | 69885 69886 69887 69888 69889 69890 69891 69892 69893 69894 69895 69896 69897 69898 69899 69900 69901 69902 69903 69904 69905 69906 69907 69908 69909 69910 69911 69912 69913 69914 69915 69916 69917 69918 69919 69920 69921 69922 69923 69924 69925 69926 69927 69928 69929 69930 69931 69932 69933 69934 69935 69936 69937 69938 69939 69940 69941 69942 69943 69944 69945 69946 69947 69948 69949 69950 69951 69952 69953 69954 69955 |
}
}
/**************************** sqlite3_column_ *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
const void *val;
val = sqlite3_value_blob( columnMem(pStmt,i) );
/* Even though there is no encoding conversion, value_blob() might
** need to call malloc() to expand the result of a zeroblob()
** expression.
*/
columnMallocFailure(pStmt);
return val;
}
SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){
double val = sqlite3_value_double( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_int( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){
const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i);
if( pOut->flags&MEM_Static ){
pOut->flags &= ~MEM_Static;
pOut->flags |= MEM_Ephem;
}
columnMallocFailure(pStmt);
return (sqlite3_value *)pOut;
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){
int iType = sqlite3_value_type( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return iType;
}
/*
** Convert the N-th element of pStmt->pColName[] into a string using
|
| ︙ | ︙ | |||
69796 69797 69798 69799 69800 69801 69802 | return ret; } /* ** Return the name of the Nth column of the result set returned by SQL ** statement pStmt. */ | | | | | | | | | | | | 70005 70006 70007 70008 70009 70010 70011 70012 70013 70014 70015 70016 70017 70018 70019 70020 70021 70022 70023 70024 70025 70026 70027 70028 70029 70030 70031 70032 70033 70034 70035 70036 70037 70038 70039 70040 70041 70042 70043 70044 70045 70046 70047 70048 70049 70050 70051 70052 70053 70054 70055 70056 70057 70058 70059 70060 70061 70062 70063 70064 70065 70066 70067 70068 70069 70070 70071 70072 70073 70074 70075 70076 70077 70078 70079 70080 70081 70082 70083 70084 70085 70086 70087 70088 70089 70090 70091 70092 70093 70094 70095 70096 70097 70098 70099 |
return ret;
}
/*
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
}
#endif
/*
** Constraint: If you have ENABLE_COLUMN_METADATA then you must
** not define OMIT_DECLTYPE.
*/
#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA)
# error "Must not define both SQLITE_OMIT_DECLTYPE \
and SQLITE_ENABLE_COLUMN_METADATA"
#endif
#ifndef SQLITE_OMIT_DECLTYPE
/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_DECLTYPE */
#ifdef SQLITE_ENABLE_COLUMN_METADATA
/*
** Return the name of the database from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Return the name of the table from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Return the name of the table column from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_ENABLE_COLUMN_METADATA */
|
| ︙ | ︙ | |||
69977 69978 69979 69980 69981 69982 69983 | return rc; } /* ** Bind a blob value to an SQL statement variable. */ | | | | | | | | | | | | 70186 70187 70188 70189 70190 70191 70192 70193 70194 70195 70196 70197 70198 70199 70200 70201 70202 70203 70204 70205 70206 70207 70208 70209 70210 70211 70212 70213 70214 70215 70216 70217 70218 70219 70220 70221 70222 70223 70224 70225 70226 70227 70228 70229 70230 70231 70232 70233 70234 70235 70236 70237 70238 70239 70240 70241 70242 70243 70244 70245 70246 70247 70248 70249 70250 70251 70252 70253 70254 70255 70256 70257 70258 70259 70260 70261 70262 70263 70264 70265 70266 70267 70268 70269 70270 70271 70272 70273 70274 70275 70276 70277 70278 70279 70280 70281 70282 70283 70284 70285 70286 70287 70288 70289 70290 70291 |
return rc;
}
/*
** Bind a blob value to an SQL statement variable.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
sqlite3_stmt *pStmt,
int i,
const void *zData,
int nData,
void (*xDel)(void*)
){
return bindText(pStmt, i, zData, nData, xDel, 0);
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
sqlite3_stmt *pStmt,
int i,
const void *zData,
sqlite3_uint64 nData,
void (*xDel)(void*)
){
assert( xDel!=SQLITE_DYNAMIC );
if( nData>0x7fffffff ){
return invokeValueDestructor(zData, xDel, 0);
}else{
return bindText(pStmt, i, zData, (int)nData, xDel, 0);
}
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (i64)iValue);
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(
sqlite3_stmt *pStmt,
int i,
const char *zData,
int nData,
void (*xDel)(void*)
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(
sqlite3_stmt *pStmt,
int i,
const char *zData,
sqlite3_uint64 nData,
void (*xDel)(void*),
unsigned char enc
){
assert( xDel!=SQLITE_DYNAMIC );
if( nData>0x7fffffff ){
return invokeValueDestructor(zData, xDel, 0);
}else{
if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
return bindText(pStmt, i, zData, (int)nData, xDel, enc);
}
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
int nData,
void (*xDel)(void*)
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
switch( sqlite3_value_type((sqlite3_value*)pValue) ){
case SQLITE_INTEGER: {
rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
break;
}
case SQLITE_FLOAT: {
|
| ︙ | ︙ | |||
70099 70100 70101 70102 70103 70104 70105 |
default: {
rc = sqlite3_bind_null(pStmt, i);
break;
}
}
return rc;
}
| | | | | 70308 70309 70310 70311 70312 70313 70314 70315 70316 70317 70318 70319 70320 70321 70322 70323 70324 70325 70326 70327 70328 70329 70330 70331 70332 70333 70334 70335 70336 70337 70338 70339 70340 70341 70342 70343 70344 70345 70346 70347 70348 |
default: {
rc = sqlite3_bind_null(pStmt, i);
break;
}
}
return rc;
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
}
/*
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p ? p->nVar : 0;
}
/*
** Return the name of a wildcard parameter. Return NULL if the index
** is out of range or if the wildcard is unnamed.
**
** The result is always UTF-8.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
if( p==0 || i<1 || i>p->nzVar ){
return 0;
}
return p->azVar[i-1];
}
|
| ︙ | ︙ | |||
70153 70154 70155 70156 70157 70158 70159 |
if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
return i+1;
}
}
}
return 0;
}
| | | 70362 70363 70364 70365 70366 70367 70368 70369 70370 70371 70372 70373 70374 70375 70376 |
if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
return i+1;
}
}
}
return 0;
}
SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
}
/*
** Transfer all bindings from the first statement over to the second.
*/
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
|
| ︙ | ︙ | |||
70187 70188 70189 70190 70191 70192 70193 | ** database connections. But as this is a deprecated interface, we ** will not bother to check for that condition. ** ** If the two statements contain a different number of bindings, then ** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise ** SQLITE_OK is returned. */ | | | 70396 70397 70398 70399 70400 70401 70402 70403 70404 70405 70406 70407 70408 70409 70410 |
** database connections. But as this is a deprecated interface, we
** will not bother to check for that condition.
**
** If the two statements contain a different number of bindings, then
** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
** SQLITE_OK is returned.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
if( pTo->isPrepareV2 && pTo->expmask ){
pTo->expired = 1;
|
| ︙ | ︙ | |||
70209 70210 70211 70212 70213 70214 70215 | /* ** Return the sqlite3* database handle to which the prepared statement given ** in the argument belongs. This is the same database handle that was ** the first argument to the sqlite3_prepare() that was used to create ** the statement in the first place. */ | | | | | | | | 70418 70419 70420 70421 70422 70423 70424 70425 70426 70427 70428 70429 70430 70431 70432 70433 70434 70435 70436 70437 70438 70439 70440 70441 70442 70443 70444 70445 70446 70447 70448 70449 70450 70451 70452 70453 70454 70455 70456 70457 70458 70459 70460 70461 70462 70463 70464 70465 70466 70467 70468 70469 70470 70471 70472 70473 70474 70475 70476 70477 70478 70479 70480 70481 70482 70483 70484 70485 70486 70487 70488 70489 70490 70491 70492 70493 70494 70495 70496 70497 |
/*
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs. This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}
/*
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}
/*
** Return true if the prepared statement is in need of being reset.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
}
/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb. If pStmt is NULL, return the first
** prepared statement for the database connection. Return NULL if there
** are no more.
*/
SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
sqlite3_stmt *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pDb) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
sqlite3_mutex_enter(pDb->mutex);
if( pStmt==0 ){
pNext = (sqlite3_stmt*)pDb->pVdbe;
}else{
pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
}
sqlite3_mutex_leave(pDb->mutex);
return pNext;
}
/*
** Return the value of a status counter for a prepared statement
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !pStmt ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
v = pVdbe->aCounter[op];
if( resetFlag ) pVdbe->aCounter[op] = 0;
return (int)v;
}
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
/*
** Return status data for a single loop within query pStmt.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement being queried */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Which metric to return */
void *pOut /* OUT: Write the answer here */
){
Vdbe *p = (Vdbe*)pStmt;
ScanStatus *pScan;
|
| ︙ | ︙ | |||
70333 70334 70335 70336 70337 70338 70339 | } return 0; } /* ** Zero all counters associated with the sqlite3_stmt_scanstatus() data. */ | | | 70542 70543 70544 70545 70546 70547 70548 70549 70550 70551 70552 70553 70554 70555 70556 |
}
return 0;
}
/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
memset(p->anExec, 0, p->nOp * sizeof(i64));
}
#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbetrace.c ***************************************/
|
| ︙ | ︙ | |||
70425 70426 70427 70428 70429 70430 70431 | int nToken; /* Length of the parameter token */ int i; /* Loop counter */ Mem *pVar; /* Value of a host parameter */ StrAccum out; /* Accumulate the output here */ char zBase[100]; /* Initial working space */ db = p->db; | | < > > | > > | 70634 70635 70636 70637 70638 70639 70640 70641 70642 70643 70644 70645 70646 70647 70648 70649 70650 70651 70652 70653 70654 70655 70656 70657 70658 70659 70660 70661 70662 70663 70664 70665 70666 70667 70668 70669 70670 70671 70672 70673 70674 70675 70676 70677 70678 70679 70680 70681 |
int nToken; /* Length of the parameter token */
int i; /* Loop counter */
Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */
char zBase[100]; /* Initial working space */
db = p->db;
sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
if( db->nVdbeExec>1 ){
while( *zRawSql ){
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
sqlite3StrAccumAppend(&out, "-- ", 3);
assert( (zRawSql - zStart) > 0 );
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
}
}else if( p->nVar==0 ){
sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
}else{
while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken);
assert( n>0 );
sqlite3StrAccumAppend(&out, zRawSql, n);
zRawSql += n;
assert( zRawSql[0] || nToken==0 );
if( nToken==0 ) break;
if( zRawSql[0]=='?' ){
if( nToken>1 ){
assert( sqlite3Isdigit(zRawSql[1]) );
sqlite3GetInt32(&zRawSql[1], &idx);
}else{
idx = nextIndex;
}
}else{
assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
zRawSql[0]=='@' || zRawSql[0]=='#' );
testcase( zRawSql[0]==':' );
testcase( zRawSql[0]=='$' );
testcase( zRawSql[0]=='@' );
testcase( zRawSql[0]=='#' );
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
assert( idx>0 );
}
zRawSql += nToken;
nextIndex = idx + 1;
assert( idx>0 && idx<=p->nVar );
pVar = &p->aVar[idx-1];
|
| ︙ | ︙ | |||
70832 70833 70834 70835 70836 70837 70838 | /* ** Try to convert the type of a function argument or a result column ** into a numeric representation. Use either INTEGER or REAL whichever ** is appropriate. But only do the conversion if it is possible without ** loss of information and return the revised type of the argument. */ | | | 71044 71045 71046 71047 71048 71049 71050 71051 71052 71053 71054 71055 71056 71057 71058 |
/*
** Try to convert the type of a function argument or a result column
** into a numeric representation. Use either INTEGER or REAL whichever
** is appropriate. But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){
int eType = sqlite3_value_type(pVal);
if( eType==SQLITE_TEXT ){
Mem *pMem = (Mem*)pVal;
applyNumericAffinity(pMem, 0);
eType = sqlite3_value_type(pVal);
}
return eType;
|
| ︙ | ︙ | |||
71130 71131 71132 71133 71134 71135 71136 71137 71138 71139 71140 71141 71142 71143 71144 |
Savepoint *p;
for(p=db->pSavepoint; p; p=p->pNext) n++;
assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
return 1;
}
#endif
/*
** Execute as much of a VDBE program as we can.
** This is the core of sqlite3_step().
*/
SQLITE_PRIVATE int sqlite3VdbeExec(
Vdbe *p /* The VDBE */
){
| > > > > > > > > > > > > > > > < | > > > | 71342 71343 71344 71345 71346 71347 71348 71349 71350 71351 71352 71353 71354 71355 71356 71357 71358 71359 71360 71361 71362 71363 71364 71365 71366 71367 71368 71369 71370 71371 71372 71373 71374 71375 71376 71377 71378 71379 71380 71381 71382 71383 |
Savepoint *p;
for(p=db->pSavepoint; p; p=p->pNext) n++;
assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
return 1;
}
#endif
/*
** Return the register of pOp->p2 after first preparing it to be
** overwritten with an integer value.
*/
static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
Mem *pOut;
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &p->aMem[pOp->p2];
memAboutToChange(p, pOut);
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
pOut->flags = MEM_Int;
return pOut;
}
/*
** Execute as much of a VDBE program as we can.
** This is the core of sqlite3_step().
*/
SQLITE_PRIVATE int sqlite3VdbeExec(
Vdbe *p /* The VDBE */
){
Op *aOp = p->aOp; /* Copy of p->aOp */
Op *pOp = aOp; /* Current operation */
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
Op *pOrigOp; /* Value of pOp at the top of the loop */
#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
u8 encoding = ENC(db); /* The database encoding */
int iCompare = 0; /* Result of last OP_Compare operation */
unsigned nVmStep = 0; /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
| ︙ | ︙ | |||
71216 71217 71218 71219 71220 71221 71222 |
}
}
}
if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n");
}
sqlite3EndBenignMalloc();
#endif
| | | < | | < < < < < < < < < < < < < < < > | 71445 71446 71447 71448 71449 71450 71451 71452 71453 71454 71455 71456 71457 71458 71459 71460 71461 71462 71463 71464 71465 71466 71467 71468 71469 71470 71471 71472 71473 71474 71475 71476 71477 71478 71479 71480 71481 71482 71483 71484 71485 71486 71487 71488 71489 71490 71491 71492 71493 |
}
}
}
if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n");
}
sqlite3EndBenignMalloc();
#endif
for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
#endif
nVmStep++;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
#endif
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
}
#endif
/* Check to see if we need to simulate an interrupt. This only happens
** if we have a special test build.
*/
#ifdef SQLITE_TEST
if( sqlite3_interrupt_count>0 ){
sqlite3_interrupt_count--;
if( sqlite3_interrupt_count==0 ){
sqlite3_interrupt(db);
}
}
#endif
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
|
| ︙ | ︙ | |||
71298 71299 71300 71301 71302 71303 71304 71305 71306 71307 71308 71309 71310 71311 |
}
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
switch( pOp->opcode ){
/*****************************************************************************
** What follows is a massive switch statement where each case implements a
** separate instruction in the virtual machine. If we follow the usual
** indentation conventions, each case should be indented by 6 spaces. But
| > > > | 71512 71513 71514 71515 71516 71517 71518 71519 71520 71521 71522 71523 71524 71525 71526 71527 71528 |
}
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
pOrigOp = pOp;
#endif
switch( pOp->opcode ){
/*****************************************************************************
** What follows is a massive switch statement where each case implements a
** separate instruction in the virtual machine. If we follow the usual
** indentation conventions, each case should be indented by 6 spaces. But
|
| ︙ | ︙ | |||
71321 71322 71323 71324 71325 71326 71327 | ** opcode and the opcodes.c file is filled with an array of strings where ** each string is the symbolic name for the corresponding opcode. If the ** case statement is followed by a comment of the form "/# same as ... #/" ** that comment is used to determine the particular value of the opcode. ** ** Other keywords in the comment that follows each case are used to ** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. | | | 71538 71539 71540 71541 71542 71543 71544 71545 71546 71547 71548 71549 71550 71551 71552 | ** opcode and the opcodes.c file is filled with an array of strings where ** each string is the symbolic name for the corresponding opcode. If the ** case statement is followed by a comment of the form "/# same as ... #/" ** that comment is used to determine the particular value of the opcode. ** ** Other keywords in the comment that follows each case are used to ** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. ** Keywords include: in1, in2, in3, out2, out3. See ** the mkopcodeh.awk script for additional information. ** ** Documentation about VDBE opcodes is generated by scanning this file ** for lines of that contain "Opcode:". That line and all subsequent ** comment lines are used in the generation of the opcode.html documentation ** file. ** |
| ︙ | ︙ | |||
71349 71350 71351 71352 71353 71354 71355 |
**
** The P1 parameter is not actually used by this opcode. However, it
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
| > | | 71566 71567 71568 71569 71570 71571 71572 71573 71574 71575 71576 71577 71578 71579 71580 71581 |
**
** The P1 parameter is not actually used by this opcode. However, it
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];
/* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
** completion. Check to see if sqlite3_interrupt() has been called
** or if the progress callback needs to be invoked.
**
** This code uses unstructured "goto" statements and does not look clean.
|
| ︙ | ︙ | |||
71394 71395 71396 71397 71398 71399 71400 |
*/
case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
| | > > > > | | | 71612 71613 71614 71615 71616 71617 71618 71619 71620 71621 71622 71623 71624 71625 71626 71627 71628 71629 71630 71631 71632 71633 71634 71635 71636 71637 71638 71639 71640 71641 71642 71643 71644 |
*/
case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
pIn1->u.i = (int)(pOp-aOp);
REGISTER_TRACE(pOp->p1, pIn1);
/* Most jump operations do a goto to this spot in order to update
** the pOp pointer. */
jump_to_p2:
pOp = &aOp[pOp->p2 - 1];
break;
}
/* Opcode: Return P1 * * * *
**
** Jump to the next instruction after the address in register P1. After
** the jump, register P1 becomes undefined.
*/
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags==MEM_Int );
pOp = &aOp[pIn1->u.i];
pIn1->flags = MEM_Undefined;
break;
}
/* Opcode: InitCoroutine P1 P2 P3 * *
**
** Set up register P1 so that it will Yield to the coroutine
|
| ︙ | ︙ | |||
71432 71433 71434 71435 71436 71437 71438 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); assert( pOp->p2>=0 && pOp->p2<p->nOp ); assert( pOp->p3>=0 && pOp->p3<p->nOp ); pOut = &aMem[pOp->p1]; assert( !VdbeMemDynamic(pOut) ); pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; | | | | 71654 71655 71656 71657 71658 71659 71660 71661 71662 71663 71664 71665 71666 71667 71668 71669 71670 71671 71672 71673 71674 71675 71676 71677 71678 71679 71680 71681 71682 71683 71684 71685 71686 71687 71688 |
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
assert( pOp->p2>=0 && pOp->p2<p->nOp );
assert( pOp->p3>=0 && pOp->p3<p->nOp );
pOut = &aMem[pOp->p1];
assert( !VdbeMemDynamic(pOut) );
pOut->u.i = pOp->p3 - 1;
pOut->flags = MEM_Int;
if( pOp->p2 ) goto jump_to_p2;
break;
}
/* Opcode: EndCoroutine P1 * * * *
**
** The instruction at the address in register P1 is a Yield.
** Jump to the P2 parameter of that Yield.
** After the jump, register P1 becomes undefined.
**
** See also: InitCoroutine
*/
case OP_EndCoroutine: { /* in1 */
VdbeOp *pCaller;
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags==MEM_Int );
assert( pIn1->u.i>=0 && pIn1->u.i<p->nOp );
pCaller = &aOp[pIn1->u.i];
assert( pCaller->opcode==OP_Yield );
assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
pOp = &aOp[pCaller->p2 - 1];
pIn1->flags = MEM_Undefined;
break;
}
/* Opcode: Yield P1 P2 * * *
**
** Swap the program counter with the value in register P1. This
|
| ︙ | ︙ | |||
71476 71477 71478 71479 71480 71481 71482 |
*/
case OP_Yield: { /* in1, jump */
int pcDest;
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i;
| | | | 71698 71699 71700 71701 71702 71703 71704 71705 71706 71707 71708 71709 71710 71711 71712 71713 71714 |
*/
case OP_Yield: { /* in1, jump */
int pcDest;
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i;
pIn1->u.i = (int)(pOp - aOp);
REGISTER_TRACE(pOp->p1, pIn1);
pOp = &aOp[pcDest];
break;
}
/* Opcode: HaltIfNull P1 P2 P3 P4 P5
** Synopsis: if r[P3]=null halt
**
** Check the value in register P3. If it is NULL then Halt using
|
| ︙ | ︙ | |||
71529 71530 71531 71532 71533 71534 71535 71536 71537 71538 |
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program. So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
const char *zType;
const char *zLogFmt;
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
| > > > | | | | > | | 71751 71752 71753 71754 71755 71756 71757 71758 71759 71760 71761 71762 71763 71764 71765 71766 71767 71768 71769 71770 71771 71772 71773 71774 71775 71776 71777 71778 71779 71780 71781 71782 71783 71784 71785 71786 71787 71788 71789 71790 71791 71792 |
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program. So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
const char *zType;
const char *zLogFmt;
VdbeFrame *pFrame;
int pcx;
pcx = (int)(pOp - aOp);
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
pcx = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
/* Instruction pcx is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
** as the p2 of the calling OP_Program. */
pcx = p->aOp[pcx].p2-1;
}
aOp = p->aOp;
aMem = p->aMem;
pOp = &aOp[pcx];
break;
}
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
p->pc = pcx;
if( p->rc ){
if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
"FOREIGN KEY" };
assert( pOp->p5>=1 && pOp->p5<=4 );
testcase( pOp->p5==1 );
testcase( pOp->p5==2 );
|
| ︙ | ︙ | |||
71576 71577 71578 71579 71580 71581 71582 |
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
zType, pOp->p4.z);
}else if( pOp->p4.z ){
sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
}else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
}
| | | > | > | > | > | 71802 71803 71804 71805 71806 71807 71808 71809 71810 71811 71812 71813 71814 71815 71816 71817 71818 71819 71820 71821 71822 71823 71824 71825 71826 71827 71828 71829 71830 71831 71832 71833 71834 71835 71836 71837 71838 71839 71840 71841 71842 71843 71844 71845 71846 71847 71848 71849 71850 71851 71852 71853 71854 71855 71856 71857 71858 71859 71860 71861 71862 71863 71864 71865 71866 71867 71868 71869 71870 71871 71872 71873 71874 71875 71876 71877 71878 71879 71880 |
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
zType, pOp->p4.z);
}else if( pOp->p4.z ){
sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
}else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
}
sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
if( rc==SQLITE_BUSY ){
p->rc = rc = SQLITE_BUSY;
}else{
assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
}
goto vdbe_return;
}
/* Opcode: Integer P1 P2 * * *
** Synopsis: r[P2]=P1
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_Integer: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1;
break;
}
/* Opcode: Int64 * P2 * P4 *
** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
case OP_Int64: { /* out2 */
pOut = out2Prerelease(p, pOp);
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: Real * P2 * P4 *
** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
case OP_Real: { /* same as TK_FLOAT, out2 */
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal;
break;
}
#endif
/* Opcode: String8 * P2 * P4 *
** Synopsis: r[P2]='P4'
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
** into a String opcode before it is executed for the first time. During
** this transformation, the length of string P4 is computed and stored
** as the P1 parameter.
*/
case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
if( rc==SQLITE_TOOBIG ) goto too_big;
|
| ︙ | ︙ | |||
71673 71674 71675 71676 71677 71678 71679 | ** The string value P4 of length P1 (bytes) is stored in register P2. ** ** If P5!=0 and the content of register P3 is greater than zero, then ** the datatype of the register P2 is converted to BLOB. The content is ** the same sequence of bytes, it is merely interpreted as a BLOB instead ** of a string, as if it had been CAST. */ | | > | 71903 71904 71905 71906 71907 71908 71909 71910 71911 71912 71913 71914 71915 71916 71917 71918 71919 |
** The string value P4 of length P1 (bytes) is stored in register P2.
**
** If P5!=0 and the content of register P3 is greater than zero, then
** the datatype of the register P2 is converted to BLOB. The content is
** the same sequence of bytes, it is merely interpreted as a BLOB instead
** of a string, as if it had been CAST.
*/
case OP_String: { /* out2 */
assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z;
pOut->n = pOp->p1;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
if( pOp->p5 ){
assert( pOp->p3>0 );
|
| ︙ | ︙ | |||
71702 71703 71704 71705 71706 71707 71708 | ** is less than P2 (typically P3 is zero) then only register P2 is ** set to NULL. ** ** If the P1 value is non-zero, then also set the MEM_Cleared flag so that ** NULL values will not compare equal even if SQLITE_NULLEQ is set on ** OP_Ne or OP_Eq. */ | | > | 71933 71934 71935 71936 71937 71938 71939 71940 71941 71942 71943 71944 71945 71946 71947 71948 71949 71950 |
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL.
**
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2 */
int cnt;
u16 nullFlag;
pOut = out2Prerelease(p, pOp);
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
sqlite3VdbeMemSetNull(pOut);
|
| ︙ | ︙ | |||
71739 71740 71741 71742 71743 71744 71745 | /* Opcode: Blob P1 P2 * P4 * ** Synopsis: r[P2]=P4 (len=P1) ** ** P4 points to a blob of data P1 bytes long. Store this ** blob in register P2. */ | | > | > | 71971 71972 71973 71974 71975 71976 71977 71978 71979 71980 71981 71982 71983 71984 71985 71986 71987 71988 71989 71990 71991 71992 71993 71994 71995 71996 71997 71998 71999 72000 72001 72002 72003 72004 72005 72006 72007 72008 72009 72010 72011 |
/* Opcode: Blob P1 P2 * P4 *
** Synopsis: r[P2]=P4 (len=P1)
**
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
case OP_Blob: { /* out2 */
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Variable P1 P2 * P4 *
** Synopsis: r[P2]=parameter(P1,P4)
**
** Transfer the values of bound parameter P1 into register P2
**
** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
** Synopsis: r[P2@P3]=r[P1@P3]
|
| ︙ | ︙ | |||
71798 71799 71800 71801 71802 71803 71804 |
do{
assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
| | | > | 72032 72033 72034 72035 72036 72037 72038 72039 72040 72041 72042 72043 72044 72045 72046 72047 72048 72049 72050 |
do{
assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
pOut->pScopyFrom += pOp->p2 - p1;
}
#endif
Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
}while( --n );
break;
}
|
| ︙ | ︙ | |||
71940 71941 71942 71943 71944 71945 71946 |
sqlite3VdbeMemNulTerminate(&pMem[i]);
REGISTER_TRACE(pOp->p1+i, &pMem[i]);
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
| | | 72175 72176 72177 72178 72179 72180 72181 72182 72183 72184 72185 72186 72187 72188 72189 |
sqlite3VdbeMemNulTerminate(&pMem[i]);
REGISTER_TRACE(pOp->p1+i, &pMem[i]);
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
p->pc = (int)(pOp - aOp) + 1;
rc = SQLITE_ROW;
goto vdbe_return;
}
/* Opcode: Concat P1 P2 P3 * *
** Synopsis: r[P3]=r[P2]+r[P1]
**
|
| ︙ | ︙ | |||
72186 72187 72188 72189 72190 72191 72192 |
apVal[i] = pArg;
Deephemeralize(pArg);
REGISTER_TRACE(pOp->p2+i, pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
| | | | 72421 72422 72423 72424 72425 72426 72427 72428 72429 72430 72431 72432 72433 72434 72435 72436 72437 72438 72439 72440 72441 72442 72443 72444 72445 72446 72447 72448 72449 |
apVal[i] = pArg;
Deephemeralize(pArg);
REGISTER_TRACE(pOp->p2+i, pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
ctx.iOp = (int)(pOp - aOp);
ctx.pVdbe = p;
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
db->lastRowid = lastRowid;
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
/* If the function returned an error, throw an exception */
if( ctx.fErrorOrAux ){
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
rc = ctx.isError;
}
sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
}
/* Copy the result of the function into register P3 */
sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
if( sqlite3VdbeMemTooBig(ctx.pOut) ){
goto too_big;
}
|
| ︙ | ︙ | |||
72329 72330 72331 72332 72333 72334 72335 |
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
if( (pIn1->flags & MEM_Int)==0 ){
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
| | < | 72564 72565 72566 72567 72568 72569 72570 72571 72572 72573 72574 72575 72576 72577 72578 |
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
if( (pIn1->flags & MEM_Int)==0 ){
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
goto jump_to_p2;
}
}
}
MemSetTypeFlag(pIn1, MEM_Int);
break;
}
|
| ︙ | ︙ | |||
72516 72517 72518 72519 72520 72521 72522 |
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){
| | > > > > | 72750 72751 72752 72753 72754 72755 72756 72757 72758 72759 72760 72761 72762 72763 72764 72765 72766 72767 72768 72769 72770 72771 72772 72773 72774 72775 72776 72777 72778 72779 72780 72781 72782 72783 72784 72785 72786 72787 72788 72789 72790 72791 72792 |
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){
goto jump_to_p2;
}
}
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
}
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
}
if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
sqlite3VdbeMemStringify(pIn3, encoding, 1);
testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
}
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
if( pIn1->flags & MEM_Zero ){
sqlite3VdbeMemExpandBlob(pIn1);
flags1 &= ~MEM_Zero;
}
|
| ︙ | ︙ | |||
72563 72564 72565 72566 72567 72568 72569 72570 72571 72572 72573 72574 72575 72576 72577 72578 72579 |
case OP_Eq: res = res==0; break;
case OP_Ne: res = res!=0; break;
case OP_Lt: res = res<0; break;
case OP_Le: res = res<=0; break;
case OP_Gt: res = res>0; break;
default: res = res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = res;
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){
| > > > > > > | < < < | 72801 72802 72803 72804 72805 72806 72807 72808 72809 72810 72811 72812 72813 72814 72815 72816 72817 72818 72819 72820 72821 72822 72823 72824 72825 72826 72827 72828 72829 72830 72831 72832 72833 |
case OP_Eq: res = res==0; break;
case OP_Ne: res = res!=0; break;
case OP_Lt: res = res<0; break;
case OP_Le: res = res<=0; break;
case OP_Gt: res = res>0; break;
default: res = res>=0; break;
}
/* Undo any changes made by applyAffinity() to the input registers. */
assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
pIn1->flags = flags1;
assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
pIn3->flags = flags3;
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = res;
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){
goto jump_to_p2;
}
}
break;
}
/* Opcode: Permutation * * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.
|
| ︙ | ︙ | |||
72673 72674 72675 72676 72677 72678 72679 |
**
** Jump to the instruction at address P1, P2, or P3 depending on whether
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
| | | | | 72914 72915 72916 72917 72918 72919 72920 72921 72922 72923 72924 72925 72926 72927 72928 72929 72930 72931 72932 |
**
** Jump to the instruction at address P1, P2, or P3 depending on whether
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){
VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
}else{
VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
}
break;
}
/* Opcode: And P1 P2 P3 * *
** Synopsis: r[P3]=(r[P1] && r[P2])
**
|
| ︙ | ︙ | |||
72787 72788 72789 72790 72791 72792 72793 |
** All "once" flags are initially cleared whenever a prepared statement
** first begins to run.
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
| | | 73028 73029 73030 73031 73032 73033 73034 73035 73036 73037 73038 73039 73040 73041 73042 |
** All "once" flags are initially cleared whenever a prepared statement
** first begins to run.
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
goto jump_to_p2;
}else{
p->aOnceFlag[pOp->p1] = 1;
}
break;
}
/* Opcode: If P1 P2 P3 * *
|
| ︙ | ︙ | |||
72822 72823 72824 72825 72826 72827 72828 |
#else
c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
if( pOp->opcode==OP_IfNot ) c = !c;
}
VdbeBranchTaken(c!=0, 2);
if( c ){
| | | | | 73063 73064 73065 73066 73067 73068 73069 73070 73071 73072 73073 73074 73075 73076 73077 73078 73079 73080 73081 73082 73083 73084 73085 73086 73087 73088 73089 73090 73091 73092 73093 73094 73095 73096 73097 73098 73099 73100 73101 73102 73103 73104 73105 |
#else
c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
if( pOp->opcode==OP_IfNot ) c = !c;
}
VdbeBranchTaken(c!=0, 2);
if( c ){
goto jump_to_p2;
}
break;
}
/* Opcode: IsNull P1 P2 * * *
** Synopsis: if r[P1]==NULL goto P2
**
** Jump to P2 if the value in register P1 is NULL.
*/
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
if( (pIn1->flags & MEM_Null)!=0 ){
goto jump_to_p2;
}
break;
}
/* Opcode: NotNull P1 P2 * * *
** Synopsis: if r[P1]!=NULL goto P2
**
** Jump to P2 if the value in register P1 is not NULL.
*/
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
if( (pIn1->flags & MEM_Null)==0 ){
goto jump_to_p2;
}
break;
}
/* Opcode: Column P1 P2 P3 P4 P5
** Synopsis: r[P3]=PX
**
|
| ︙ | ︙ | |||
73064 73065 73066 73067 73068 73069 73070 |
|| (offset > pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
}
| | | 73305 73306 73307 73308 73309 73310 73311 73312 73313 73314 73315 73316 73317 73318 73319 |
|| (offset > pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
}
/* If after trying to extract new entries from the header, nHdrParsed is
** still not up to p2, that means that the record has fewer than p2
** columns. So the result will be either the default value or a NULL.
*/
if( pC->nHdrParsed<=p2 ){
if( pOp->p4type==P4_MEM ){
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
}else{
|
| ︙ | ︙ | |||
73188 73189 73190 73191 73192 73193 73194 |
*/
case OP_MakeRecord: {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */
| | | 73429 73430 73431 73432 73433 73434 73435 73436 73437 73438 73439 73440 73441 73442 73443 |
*/
case OP_MakeRecord: {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */
i64 nZero; /* Number of zero bytes at the end of the record */
int nVarint; /* Number of bytes in a varint */
u32 serial_type; /* Type field */
Mem *pData0; /* First field to be combined into the record */
Mem *pLast; /* Last field of the record */
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
|
| ︙ | ︙ | |||
73280 73281 73282 73283 73284 73285 73286 |
}else{
/* Rare case of a really large header */
nVarint = sqlite3VarintLen(nHdr);
nHdr += nVarint;
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
}
nByte = nHdr+nData;
| | | 73521 73522 73523 73524 73525 73526 73527 73528 73529 73530 73531 73532 73533 73534 73535 |
}else{
/* Rare case of a really large header */
nVarint = sqlite3VarintLen(nHdr);
nHdr += nVarint;
if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
}
nByte = nHdr+nData;
if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
/* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
** be one of the input registers (because the following call to
** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
|
| ︙ | ︙ | |||
73331 73332 73333 73334 73335 73336 73337 | /* Opcode: Count P1 P2 * * * ** Synopsis: r[P2]=count() ** ** Store the number of entries (an integer value) in the table or index ** opened by cursor P1 in register P2 */ #ifndef SQLITE_OMIT_BTREECOUNT | | > | 73572 73573 73574 73575 73576 73577 73578 73579 73580 73581 73582 73583 73584 73585 73586 73587 73588 73589 73590 73591 73592 73593 73594 |
/* Opcode: Count P1 P2 * * *
** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
pCrsr = p->apCsr[pOp->p1]->pCursor;
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
}
#endif
/* Opcode: Savepoint P1 * * P4 *
**
|
| ︙ | ︙ | |||
73452 73453 73454 73455 73456 73457 73458 |
int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
if( isTransaction && p1==SAVEPOINT_RELEASE ){
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
| | | 73694 73695 73696 73697 73698 73699 73700 73701 73702 73703 73704 73705 73706 73707 73708 |
int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
if( isTransaction && p1==SAVEPOINT_RELEASE ){
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = (int)(pOp - aOp);
db->autoCommit = 0;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
|
| ︙ | ︙ | |||
73511 73512 73513 73514 73515 73516 73517 |
db->nSavepoint--;
}
}else{
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
| | | 73753 73754 73755 73756 73757 73758 73759 73760 73761 73762 73763 73764 73765 73766 73767 |
db->nSavepoint--;
}
}else{
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
}
break;
|
| ︙ | ︙ | |||
73571 73572 73573 73574 73575 73576 73577 |
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
| | | 73813 73814 73815 73816 73817 73818 73819 73820 73821 73822 73823 73824 73825 73826 73827 |
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = (int)(pOp - aOp);
db->autoCommit = (u8)(1-desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
}
assert( db->nStatement==0 );
sqlite3CloseSavepoints(db);
|
| ︙ | ︙ | |||
73648 73649 73650 73651 73652 73653 73654 |
goto abort_due_to_error;
}
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
| | | 73890 73891 73892 73893 73894 73895 73896 73897 73898 73899 73900 73901 73902 73903 73904 |
goto abort_due_to_error;
}
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
p->pc = (int)(pOp - aOp);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
|
| ︙ | ︙ | |||
73727 73728 73729 73730 73731 73732 73733 | ** the main database file and P1==1 is the database file used to store ** temporary tables. ** ** There must be a read-lock on the database (either a transaction ** must be started or there must be an open cursor) before ** executing this instruction. */ | | > | 73969 73970 73971 73972 73973 73974 73975 73976 73977 73978 73979 73980 73981 73982 73983 73984 73985 73986 73987 73988 73989 73990 73991 73992 73993 73994 73995 73996 73997 |
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: { /* out2 */
int iMeta;
int iDb;
int iCookie;
assert( p->bIsReader );
iDb = pOp->p1;
iCookie = pOp->p3;
assert( pOp->p3<SQLITE_N_BTREE_META );
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 );
assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
pOut = out2Prerelease(p, pOp);
pOut->u.i = iMeta;
break;
}
/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
|
| ︙ | ︙ | |||
74062 74063 74064 74065 74066 74067 74068 |
*/
case OP_SequenceTest: {
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
| | | 74305 74306 74307 74308 74309 74310 74311 74312 74313 74314 74315 74316 74317 74318 74319 |
*/
case OP_SequenceTest: {
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC->pSorter );
if( (pC->seqCount++)==0 ){
goto jump_to_p2;
}
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * *
** Synopsis: P3 columns in r[P2]
**
|
| ︙ | ︙ | |||
74239 74240 74241 74242 74243 74244 74245 |
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
if( (pIn3->flags & MEM_Int)==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
| | | 74482 74483 74484 74485 74486 74487 74488 74489 74490 74491 74492 74493 74494 74495 74496 |
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
if( (pIn3->flags & MEM_Int)==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
VdbeBranchTaken(1,2); goto jump_to_p2;
break;
}
/* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
** is 4.9 and the integer approximation 5:
**
|
| ︙ | ︙ | |||
74330 74331 74332 74333 74334 74335 74336 |
*/
res = sqlite3BtreeEof(pC->pCursor);
}
}
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
| | | 74573 74574 74575 74576 74577 74578 74579 74580 74581 74582 74583 74584 74585 74586 74587 |
*/
res = sqlite3BtreeEof(pC->pCursor);
}
}
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
goto jump_to_p2;
}
break;
}
/* Opcode: Seek P1 P2 * * *
** Synopsis: intkey=r[P2]
**
|
| ︙ | ︙ | |||
74424 74425 74426 74427 74428 74429 74430 74431 74432 74433 74434 74435 74436 74437 |
**
** See also: NotFound, Found, NotExists
*/
case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
int alreadyExists;
int ii;
VdbeCursor *pC;
int res;
char *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
| > | 74667 74668 74669 74670 74671 74672 74673 74674 74675 74676 74677 74678 74679 74680 74681 |
**
** See also: NotFound, Found, NotExists
*/
case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
int alreadyExists;
int takeJump;
int ii;
VdbeCursor *pC;
int res;
char *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
|
| ︙ | ︙ | |||
74446 74447 74448 74449 74450 74451 74452 | assert( pC!=0 ); #ifdef SQLITE_DEBUG pC->seekOp = pOp->opcode; #endif pIn3 = &aMem[pOp->p3]; assert( pC->pCursor!=0 ); assert( pC->isTable==0 ); | | | 74690 74691 74692 74693 74694 74695 74696 74697 74698 74699 74700 74701 74702 74703 74704 |
assert( pC!=0 );
#ifdef SQLITE_DEBUG
pC->seekOp = pOp->opcode;
#endif
pIn3 = &aMem[pOp->p3];
assert( pC->pCursor!=0 );
assert( pC->isTable==0 );
pFree = 0;
if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
r.aMem = pIn3;
for(ii=0; ii<r.nField; ii++){
assert( memIsValid(&r.aMem[ii]) );
ExpandBlob(&r.aMem[ii]);
|
| ︙ | ︙ | |||
74469 74470 74471 74472 74473 74474 74475 74476 74477 74478 74479 74480 74481 |
);
if( pIdxKey==0 ) goto no_mem;
assert( pIn3->flags & MEM_Blob );
ExpandBlob(pIn3);
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not
** conflict */
for(ii=0; ii<pIdxKey->nField; ii++){
if( pIdxKey->aMem[ii].flags & MEM_Null ){
| > | < | < | | | | 74713 74714 74715 74716 74717 74718 74719 74720 74721 74722 74723 74724 74725 74726 74727 74728 74729 74730 74731 74732 74733 74734 74735 74736 74737 74738 74739 74740 74741 74742 74743 74744 74745 74746 74747 74748 74749 74750 74751 74752 74753 74754 |
);
if( pIdxKey==0 ) goto no_mem;
assert( pIn3->flags & MEM_Blob );
ExpandBlob(pIn3);
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
takeJump = 0;
if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not
** conflict */
for(ii=0; ii<pIdxKey->nField; ii++){
if( pIdxKey->aMem[ii].flags & MEM_Null ){
takeJump = 1;
break;
}
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
break;
}
pC->seekResult = res;
alreadyExists = (res==0);
pC->nullRow = 1-alreadyExists;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){
VdbeBranchTaken(alreadyExists!=0,2);
if( alreadyExists ) goto jump_to_p2;
}else{
VdbeBranchTaken(takeJump||alreadyExists==0,2);
if( takeJump || !alreadyExists ) goto jump_to_p2;
}
break;
}
/* Opcode: NotExists P1 P2 P3 * *
** Synopsis: intkey=r[P3]
**
|
| ︙ | ︙ | |||
74546 74547 74548 74549 74550 74551 74552 | iKey = pIn3->u.i; rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); pC->movetoTarget = iKey; /* Used by OP_Delete */ pC->nullRow = 0; pC->cacheStatus = CACHE_STALE; pC->deferredMoveto = 0; VdbeBranchTaken(res!=0,2); | < < < > | > | > | 74789 74790 74791 74792 74793 74794 74795 74796 74797 74798 74799 74800 74801 74802 74803 74804 74805 74806 74807 74808 74809 74810 74811 74812 74813 74814 74815 74816 74817 74818 74819 74820 74821 74822 74823 74824 74825 74826 74827 74828 74829 74830 74831 74832 74833 74834 74835 74836 74837 74838 74839 74840 74841 74842 74843 74844 74845 74846 74847 74848 74849 74850 |
iKey = pIn3->u.i;
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
VdbeBranchTaken(res!=0,2);
pC->seekResult = res;
if( res!=0 ) goto jump_to_p2;
break;
}
/* Opcode: Sequence P1 P2 * * *
** Synopsis: r[P2]=cursor[P1].ctr++
**
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
** The sequence number on the cursor is incremented after this
** instruction.
*/
case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
/* Opcode: NewRowid P1 P2 P3 * *
** Synopsis: r[P2]=rowid
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to. The new record number is written
** written to register P2.
**
** If P3>0 then P3 is a register in the root frame of this VDBE that holds
** the largest previously generated record number. No new record numbers are
** allowed to be less than this value. When this value reaches its maximum,
** an SQLITE_FULL error is generated. The P3 register is updated with the '
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRowid: { /* out2 */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */
int cnt; /* Counter to limit the number of searches */
Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
VdbeFrame *pFrame; /* Root frame of VDBE */
v = 0;
res = 0;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
if( NEVER(pC->pCursor==0) ){
/* The zero initialization above is all that is needed */
}else{
/* The next rowid or record number (different terms for the same
|
| ︙ | ︙ | |||
74907 74908 74909 74910 74911 74912 74913 | assert( isSorter(pC) ); assert( pOp->p4type==P4_INT32 ); pIn3 = &aMem[pOp->p3]; nKeyCol = pOp->p4.i; res = 0; rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); VdbeBranchTaken(res!=0,2); | | < < | 75150 75151 75152 75153 75154 75155 75156 75157 75158 75159 75160 75161 75162 75163 75164 | assert( isSorter(pC) ); assert( pOp->p4type==P4_INT32 ); pIn3 = &aMem[pOp->p3]; nKeyCol = pOp->p4.i; res = 0; rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; break; }; /* Opcode: SorterData P1 P2 P3 * * ** Synopsis: r[P2]=data ** ** Write into register P2 the current sorter data for sorter cursor P1. |
| ︙ | ︙ | |||
75038 75039 75040 75041 75042 75043 75044 | ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. ** ** P1 can be either an ordinary table or a virtual table. There used to ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ | | > | 75279 75280 75281 75282 75283 75284 75285 75286 75287 75288 75289 75290 75291 75292 75293 75294 75295 75296 75297 75298 75299 |
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
**
** P1 can be either an ordinary table or a virtual table. There used to
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
case OP_Rowid: { /* out2 */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->pseudoTableReg==0 || pC->nullRow );
if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
|
| ︙ | ︙ | |||
75096 75097 75098 75099 75100 75101 75102 |
pC->cacheStatus = CACHE_STALE;
if( pC->pCursor ){
sqlite3BtreeClearCursor(pC->pCursor);
}
break;
}
| | | 75338 75339 75340 75341 75342 75343 75344 75345 75346 75347 75348 75349 75350 75351 75352 |
pC->cacheStatus = CACHE_STALE;
if( pC->pCursor ){
sqlite3BtreeClearCursor(pC->pCursor);
}
break;
}
/* Opcode: Last P1 P2 P3 * *
**
** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
**
|
| ︙ | ︙ | |||
75123 75124 75125 75126 75127 75128 75129 75130 75131 75132 75133 75134 |
pCrsr = pC->pCursor;
res = 0;
assert( pCrsr!=0 );
rc = sqlite3BtreeLast(pCrsr, &res);
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
| > | | 75365 75366 75367 75368 75369 75370 75371 75372 75373 75374 75375 75376 75377 75378 75379 75380 75381 75382 75383 75384 75385 |
pCrsr = pC->pCursor;
res = 0;
assert( pCrsr!=0 );
rc = sqlite3BtreeLast(pCrsr, &res);
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
}
break;
}
/* Opcode: Sort P1 P2 * * *
**
|
| ︙ | ︙ | |||
75192 75193 75194 75195 75196 75197 75198 |
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
| | < < | 75435 75436 75437 75438 75439 75440 75441 75442 75443 75444 75445 75446 75447 75448 75449 |
rc = sqlite3BtreeFirst(pCrsr, &res);
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break;
}
/* Opcode: Next P1 P2 P3 P4 P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
|
| ︙ | ︙ | |||
75305 75306 75307 75308 75309 75310 75311 |
rc = pOp->p4.xAdvance(pC->pCursor, &res);
next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
if( res==0 ){
pC->nullRow = 0;
| < > | 75546 75547 75548 75549 75550 75551 75552 75553 75554 75555 75556 75557 75558 75559 75560 75561 75562 75563 75564 |
rc = pOp->p4.xAdvance(pC->pCursor, &res);
next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
if( res==0 ){
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
goto jump_to_p2_and_check_for_interrupt;
}else{
pC->nullRow = 1;
}
goto check_for_interrupt;
}
/* Opcode: IdxInsert P1 P2 P3 * P5
|
| ︙ | ︙ | |||
75417 75418 75419 75420 75421 75422 75423 | ** ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ | | > | 75658 75659 75660 75661 75662 75663 75664 75665 75666 75667 75668 75669 75670 75671 75672 75673 75674 75675 75676 75677 |
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1. This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
pCrsr = pC->pCursor;
assert( pCrsr!=0 );
pOut->flags = MEM_Null;
assert( pC->isTable==0 );
|
| ︙ | ︙ | |||
75534 75535 75536 75537 75538 75539 75540 |
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
res = -res;
}else{
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
res++;
}
VdbeBranchTaken(res>0,2);
| | < < | 75776 75777 75778 75779 75780 75781 75782 75783 75784 75785 75786 75787 75788 75789 75790 |
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
res = -res;
}else{
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
res++;
}
VdbeBranchTaken(res>0,2);
if( res>0 ) goto jump_to_p2;
break;
}
/* Opcode: Destroy P1 P2 P3 * *
**
** Delete an entire database table or index whose root page in the database
** file is given by P1.
|
| ︙ | ︙ | |||
75560 75561 75562 75563 75564 75565 75566 | ** is stored in register P2. If no page ** movement was required (because the table being dropped was already ** the last one in the database) then a zero is stored in register P2. ** If AUTOVACUUM is disabled then a zero is stored in register P2. ** ** See also: Clear */ | | > | 75800 75801 75802 75803 75804 75805 75806 75807 75808 75809 75810 75811 75812 75813 75814 75815 75816 75817 75818 75819 |
** is stored in register P2. If no page
** movement was required (because the table being dropped was already
** the last one in the database) then a zero is stored in register P2.
** If AUTOVACUUM is disabled then a zero is stored in register P2.
**
** See also: Clear
*/
case OP_Destroy: { /* out2 */
int iMoved;
int iDb;
assert( p->readOnly==0 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null;
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
}else{
iDb = pOp->p3;
assert( DbMaskTest(p->btreeMask, iDb) );
|
| ︙ | ︙ | |||
75673 75674 75675 75676 75677 75678 75679 | ** Allocate a new index in the main database file if P1==0 or in the ** auxiliary database file if P1==1 or in an attached database if ** P1>1. Write the root page number of the new table into ** register P2. ** ** See documentation on OP_CreateTable for additional information. */ | | | > | 75914 75915 75916 75917 75918 75919 75920 75921 75922 75923 75924 75925 75926 75927 75928 75929 75930 75931 75932 75933 75934 |
** Allocate a new index in the main database file if P1==0 or in the
** auxiliary database file if P1==1 or in an attached database if
** P1>1. Write the root page number of the new table into
** register P2.
**
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex: /* out2 */
case OP_CreateTable: { /* out2 */
int pgno;
int flags;
Db *pDb;
pOut = out2Prerelease(p, pOp);
pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){
|
| ︙ | ︙ | |||
75904 75905 75906 75907 75908 75909 75910 |
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_RowSet)==0
|| sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
| < > < > | 76146 76147 76148 76149 76150 76151 76152 76153 76154 76155 76156 76157 76158 76159 76160 76161 76162 76163 76164 76165 |
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_RowSet)==0
|| sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
VdbeBranchTaken(1,2);
goto jump_to_p2_and_check_for_interrupt;
}else{
/* A value was pulled from the index */
VdbeBranchTaken(0,2);
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
}
goto check_for_interrupt;
}
/* Opcode: RowSetTest P1 P2 P3 P4
** Synopsis: if r[P3] in rowset(P1) goto P2
**
|
| ︙ | ︙ | |||
75960 75961 75962 75963 75964 75965 75966 |
}
assert( pOp->p4type==P4_INT32 );
assert( iSet==-1 || iSet>=0 );
if( iSet ){
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2);
| | < < < | 76202 76203 76204 76205 76206 76207 76208 76209 76210 76211 76212 76213 76214 76215 76216 |
}
assert( pOp->p4type==P4_INT32 );
assert( iSet==-1 || iSet>=0 );
if( iSet ){
exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2);
if( exists ) goto jump_to_p2;
}
if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
}
break;
}
|
| ︙ | ︙ | |||
76052 76053 76054 76055 76056 76057 76058 |
sqlite3VdbeMemRelease(pRt);
pRt->flags = MEM_Frame;
pRt->u.pFrame = pFrame;
pFrame->v = p;
pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr;
| | | 76291 76292 76293 76294 76295 76296 76297 76298 76299 76300 76301 76302 76303 76304 76305 |
sqlite3VdbeMemRelease(pRt);
pRt->flags = MEM_Frame;
pRt->u.pFrame = pFrame;
pFrame->v = p;
pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr;
pFrame->pc = (int)(pOp - aOp);
pFrame->aMem = p->aMem;
pFrame->nMem = p->nMem;
pFrame->apCsr = p->apCsr;
pFrame->nCursor = p->nCursor;
pFrame->aOp = p->aOp;
pFrame->nOp = p->nOp;
pFrame->token = pProgram->token;
|
| ︙ | ︙ | |||
76075 76076 76077 76078 76079 76080 76081 |
pMem->flags = MEM_Undefined;
pMem->db = db;
}
}else{
pFrame = pRt->u.pFrame;
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
assert( pProgram->nCsr==pFrame->nChildCsr );
| | | | > | 76314 76315 76316 76317 76318 76319 76320 76321 76322 76323 76324 76325 76326 76327 76328 76329 76330 76331 76332 76333 76334 76335 76336 76337 76338 76339 76340 76341 76342 76343 76344 76345 76346 76347 76348 76349 76350 76351 76352 76353 76354 76355 76356 76357 76358 76359 76360 76361 76362 76363 76364 76365 76366 76367 76368 76369 76370 |
pMem->flags = MEM_Undefined;
pMem->db = db;
}
}else{
pFrame = pRt->u.pFrame;
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
assert( pProgram->nCsr==pFrame->nChildCsr );
assert( (int)(pOp - aOp)==pFrame->pc );
}
p->nFrame++;
pFrame->pParent = p->pFrame;
pFrame->lastRowid = lastRowid;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
p->nChange = 0;
p->pFrame = pFrame;
p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
p->nMem = pFrame->nChildMem;
p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
p->aOp = aOp = pProgram->aOp;
p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = pProgram->nOnce;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
pOp = &aOp[-1];
memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
}
/* Opcode: Param P1 P2 * * *
**
** This opcode is only ever present in sub-programs called via the
** OP_Program instruction. Copy a value currently stored in a memory
** cell of the calling (parent) frame to cell P2 in the current frames
** address space. This is used by trigger programs to access the new.*
** and old.* values.
**
** The address of the cell in the parent frame is determined by adding
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
case OP_Param: { /* out2 */
VdbeFrame *pFrame;
Mem *pIn;
pOut = out2Prerelease(p, pOp);
pFrame = p->pFrame;
pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
| ︙ | ︙ | |||
76160 76161 76162 76163 76164 76165 76166 |
** is zero (the one that counts deferred constraint violations). If P1 is
** zero, the jump is taken if the statement constraint-counter is zero
** (immediate foreign key constraint violations).
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
| | | | 76400 76401 76402 76403 76404 76405 76406 76407 76408 76409 76410 76411 76412 76413 76414 76415 76416 76417 |
** is zero (the one that counts deferred constraint violations). If P1 is
** zero, the jump is taken if the statement constraint-counter is zero
** (immediate foreign key constraint violations).
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}else{
VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
}
break;
}
#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 P2 * * *
|
| ︙ | ︙ | |||
76214 76215 76216 76217 76218 76219 76220 |
** If the initial value of register P1 is less than 1, then the
** value is unchanged and control passes through to the next instruction.
*/
case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken( pIn1->u.i>0, 2);
| | < < | < < | | < < | < < | 76454 76455 76456 76457 76458 76459 76460 76461 76462 76463 76464 76465 76466 76467 76468 76469 76470 76471 76472 76473 76474 76475 76476 76477 76478 76479 76480 76481 76482 76483 76484 76485 76486 76487 76488 76489 76490 76491 76492 76493 76494 76495 76496 76497 76498 76499 76500 76501 76502 76503 76504 76505 76506 76507 76508 76509 76510 76511 76512 76513 76514 76515 76516 76517 76518 76519 76520 76521 76522 76523 76524 76525 76526 76527 76528 76529 76530 76531 76532 |
** If the initial value of register P1 is less than 1, then the
** value is unchanged and control passes through to the next instruction.
*/
case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken( pIn1->u.i>0, 2);
if( pIn1->u.i>0 ) goto jump_to_p2;
break;
}
/* Opcode: IfNeg P1 P2 P3 * *
** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2
**
** Register P1 must contain an integer. Add literal P3 to the value in
** register P1 then if the value of register P1 is less than zero, jump to P2.
*/
case OP_IfNeg: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
pIn1->u.i += pOp->p3;
VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i<0 ) goto jump_to_p2;
break;
}
/* Opcode: IfNotZero P1 P2 P3 * *
** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2
**
** Register P1 must contain an integer. If the content of register P1 is
** initially nonzero, then add P3 to P1 and jump to P2. If register P1 is
** initially zero, leave it unchanged and fall through.
*/
case OP_IfNotZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i ){
pIn1->u.i += pOp->p3;
goto jump_to_p2;
}
break;
}
/* Opcode: DecrJumpZero P1 P2 * * *
** Synopsis: if (--r[P1])==0 goto P2
**
** Register P1 must hold an integer. Decrement the value in register P1
** then jump to P2 if the new value is exactly zero.
*/
case OP_DecrJumpZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
pIn1->u.i--;
VdbeBranchTaken(pIn1->u.i==0, 2);
if( pIn1->u.i==0 ) goto jump_to_p2;
break;
}
/* Opcode: JumpZeroIncr P1 P2 * * *
** Synopsis: if (r[P1]++)==0 ) goto P2
**
** The register P1 must contain an integer. If register P1 is initially
** zero, then jump to P2. Increment register P1 regardless of whether or
** not the jump is taken.
*/
case OP_JumpZeroIncr: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i==0, 2);
if( (pIn1->u.i++)==0 ) goto jump_to_p2;
break;
}
/* Opcode: AggStep * P2 P3 P4 P5
** Synopsis: accum=r[P3] step(r[P2@P5])
**
** Execute the step function for an aggregate. The
|
| ︙ | ︙ | |||
76328 76329 76330 76331 76332 76333 76334 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); ctx.pMem = pMem = &aMem[pOp->p3]; pMem->n++; sqlite3VdbeMemInit(&t, db, MEM_Null); ctx.pOut = &t; ctx.isError = 0; ctx.pVdbe = p; | | | 76560 76561 76562 76563 76564 76565 76566 76567 76568 76569 76570 76571 76572 76573 76574 |
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pMem = pMem = &aMem[pOp->p3];
pMem->n++;
sqlite3VdbeMemInit(&t, db, MEM_Null);
ctx.pOut = &t;
ctx.isError = 0;
ctx.pVdbe = p;
ctx.iOp = (int)(pOp - aOp);
ctx.skipFlag = 0;
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
rc = ctx.isError;
}
if( ctx.skipFlag ){
|
| ︙ | ︙ | |||
76423 76424 76425 76426 76427 76428 76429 | ** modes (delete, truncate, persist, off and memory), this is a simple ** operation. No IO is required. ** ** If changing into or out of WAL mode the procedure is more complicated. ** ** Write a string containing the final journal-mode to register P2. */ | | > | 76655 76656 76657 76658 76659 76660 76661 76662 76663 76664 76665 76666 76667 76668 76669 76670 76671 76672 76673 76674 76675 76676 76677 76678 |
** modes (delete, truncate, persist, off and memory), this is a simple
** operation. No IO is required.
**
** If changing into or out of WAL mode the procedure is more complicated.
**
** Write a string containing the final journal-mode to register P2.
*/
case OP_JournalMode: { /* out2 */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
int eOld; /* The old journal mode */
#ifndef SQLITE_OMIT_WAL
const char *zFilename; /* Name of database file for pPager */
#endif
pOut = out2Prerelease(p, pOp);
eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE
|| eNew==PAGER_JOURNALMODE_TRUNCATE
|| eNew==PAGER_JOURNALMODE_PERSIST
|| eNew==PAGER_JOURNALMODE_OFF
|| eNew==PAGER_JOURNALMODE_MEMORY
|| eNew==PAGER_JOURNALMODE_WAL
|
| ︙ | ︙ | |||
76507 76508 76509 76510 76511 76512 76513 |
#endif /* ifndef SQLITE_OMIT_WAL */
if( rc ){
eNew = eOld;
}
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
| < | 76740 76741 76742 76743 76744 76745 76746 76747 76748 76749 76750 76751 76752 76753 |
#endif /* ifndef SQLITE_OMIT_WAL */
if( rc ){
eNew = eOld;
}
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = (char *)sqlite3JournalModename(eNew);
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
break;
};
|
| ︙ | ︙ | |||
76548 76549 76550 76551 76552 76553 76554 |
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
| < > | 76780 76781 76782 76783 76784 76785 76786 76787 76788 76789 76790 76791 76792 76793 76794 76795 |
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
goto jump_to_p2;
}
break;
}
#endif
/* Opcode: Expire P1 * * * *
**
|
| ︙ | ︙ | |||
76702 76703 76704 76705 76706 76707 76708 |
/* Initialize vdbe cursor object */
pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( pCur ){
pCur->pVtabCursor = pVtabCursor;
pVtab->nRef++;
}else{
| | > | 76934 76935 76936 76937 76938 76939 76940 76941 76942 76943 76944 76945 76946 76947 76948 76949 76950 |
/* Initialize vdbe cursor object */
pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( pCur ){
pCur->pVtabCursor = pVtabCursor;
pVtab->nRef++;
}else{
assert( db->mallocFailed );
pModule->xClose(pVtabCursor);
goto no_mem;
}
}
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
| ︙ | ︙ | |||
76759 76760 76761 76762 76763 76764 76765 | /* Grab the index number and argc parameters */ assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); nArg = (int)pArgc->u.i; iQuery = (int)pQuery->u.i; /* Invoke the xFilter method */ | < | | | | | < | | | | | > | | < < < < < | 76992 76993 76994 76995 76996 76997 76998 76999 77000 77001 77002 77003 77004 77005 77006 77007 77008 77009 77010 77011 77012 77013 77014 77015 77016 77017 77018 |
/* Grab the index number and argc parameters */
assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
nArg = (int)pArgc->u.i;
iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
res = 0;
apArg = p->apArg;
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
}
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pVtabCursor);
}
pCur->nullRow = 0;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
** Synopsis: r[P3]=vcolumn(P2)
|
| ︙ | ︙ | |||
76864 76865 76866 76867 76868 76869 76870 |
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pCur->pVtabCursor);
}
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
| | | 77091 77092 77093 77094 77095 77096 77097 77098 77099 77100 77101 77102 77103 77104 77105 |
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pCur->pVtabCursor);
}
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
goto jump_to_p2_and_check_for_interrupt;
}
goto check_for_interrupt;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRename P1 * * P4 *
|
| ︙ | ︙ | |||
76987 76988 76989 76990 76991 76992 76993 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* Opcode: Pagecount P1 P2 * * * ** ** Write the current number of pages in database P1 to memory cell P2. */ | | > | > | 77214 77215 77216 77217 77218 77219 77220 77221 77222 77223 77224 77225 77226 77227 77228 77229 77230 77231 77232 77233 77234 77235 77236 77237 77238 77239 77240 77241 77242 77243 77244 77245 77246 77247 77248 77249 |
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/* Opcode: Pagecount P1 P2 * * *
**
** Write the current number of pages in database P1 to memory cell P2.
*/
case OP_Pagecount: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break;
}
#endif
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/* Opcode: MaxPgcnt P1 P2 P3 * *
**
** Try to set the maximum page count for database P1 to the value in P3.
** Do not let the maximum page count fall below the current page count and
** do not change the maximum page count value if P3==0.
**
** Store the maximum page count after the change in register P2.
*/
case OP_MaxPgcnt: { /* out2 */
unsigned int newMax;
Btree *pBt;
pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt;
newMax = 0;
if( pOp->p3 ){
newMax = sqlite3BtreeLastPage(pBt);
if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3;
}
pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax);
|
| ︙ | ︙ | |||
77035 77036 77037 77038 77039 77040 77041 |
**
** If P2 is not zero, jump to instruction P2.
*/
case OP_Init: { /* jump */
char *zTrace;
char *z;
| < < < | 77264 77265 77266 77267 77268 77269 77270 77271 77272 77273 77274 77275 77276 77277 |
**
** If P2 is not zero, jump to instruction P2.
*/
case OP_Init: { /* jump */
char *zTrace;
char *z;
#ifndef SQLITE_OMIT_TRACE
if( db->xTrace
&& !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
z = sqlite3VdbeExpandSql(p, zTrace);
db->xTrace(db->pTraceArg, z);
|
| ︙ | ︙ | |||
77065 77066 77067 77068 77069 77070 77071 77072 77073 77074 77075 77076 77077 77078 |
if( (db->flags & SQLITE_SqlTrace)!=0
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
break;
}
/* Opcode: Noop * * * * *
**
** Do nothing. This instruction is often useful as a jump
| > | 77291 77292 77293 77294 77295 77296 77297 77298 77299 77300 77301 77302 77303 77304 77305 |
if( (db->flags & SQLITE_SqlTrace)!=0
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
if( pOp->p2 ) goto jump_to_p2;
break;
}
/* Opcode: Noop * * * * *
**
** Do nothing. This instruction is often useful as a jump
|
| ︙ | ︙ | |||
77096 77097 77098 77099 77100 77101 77102 |
** restored.
*****************************************************************************/
}
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
| | | | | | | | | | 77323 77324 77325 77326 77327 77328 77329 77330 77331 77332 77333 77334 77335 77336 77337 77338 77339 77340 77341 77342 77343 77344 77345 77346 77347 77348 77349 77350 77351 77352 77353 77354 77355 77356 77357 77358 77359 77360 77361 77362 77363 77364 77365 77366 77367 77368 77369 77370 77371 77372 |
** restored.
*****************************************************************************/
}
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
if( endTime>start ) pOrigOp->cycles += endTime - start;
pOrigOp->cnt++;
}
#endif
/* The following code adds nothing to the actual functionality
** of the program. It is only here for testing and debugging.
** On the other hand, it does burn CPU cycles every time through
** the evaluator loop. So we can leave it out when NDEBUG is defined.
*/
#ifndef NDEBUG
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
if( pOrigOp->opflags & (OPFLG_OUT2) ){
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
if( pOrigOp->opflags & OPFLG_OUT3 ){
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
#endif /* NDEBUG */
} /* The end of the for(;;) loop the loops through opcodes */
/* If we reach this point, it means that execution is finished with
** an error of some kind.
*/
vdbe_error_halt:
assert( rc );
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
(int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
}
|
| ︙ | ︙ | |||
77294 77295 77296 77297 77298 77299 77300 | *pzErr = zErr; return rc; } /* ** Open a blob handle. */ | | | 77521 77522 77523 77524 77525 77526 77527 77528 77529 77530 77531 77532 77533 77534 77535 | *pzErr = zErr; return rc; } /* ** Open a blob handle. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( sqlite3* db, /* The database connection */ const char *zDb, /* The attached database containing the blob */ const char *zTable, /* The table containing the blob */ const char *zColumn, /* The column containing the blob */ sqlite_int64 iRow, /* The row containing the glob */ int flags, /* True -> read/write access, false -> read-only */ sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ |
| ︙ | ︙ | |||
77531 77532 77533 77534 77535 77536 77537 | return rc; } /* ** Close a blob handle that was previously created using ** sqlite3_blob_open(). */ | | | 77758 77759 77760 77761 77762 77763 77764 77765 77766 77767 77768 77769 77770 77771 77772 |
return rc;
}
/*
** Close a blob handle that was previously created using
** sqlite3_blob_open().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
int rc;
sqlite3 *db;
if( p ){
db = p->db;
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
77600 77601 77602 77603 77604 77605 77606 | sqlite3_mutex_leave(db->mutex); return rc; } /* ** Read data from a blob handle. */ | | | | | | 77827 77828 77829 77830 77831 77832 77833 77834 77835 77836 77837 77838 77839 77840 77841 77842 77843 77844 77845 77846 77847 77848 77849 77850 77851 77852 77853 77854 77855 77856 77857 77858 77859 77860 77861 77862 77863 77864 77865 77866 77867 77868 77869 77870 77871 77872 77873 |
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** Read data from a blob handle.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
}
/*
** Write data to a blob handle.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
}
/*
** Query a blob handle for the size of the data.
**
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
return (p && p->pStmt) ? p->nByte : 0;
}
/*
** Move an existing blob handle to point to a different row of the same
** database table.
**
** If an error occurs, or if the specified row does not exist or does not
** contain a blob or text value, then an error code is returned and the
** database handle error code and message set. If this happens, then all
** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
** immediately return SQLITE_ABORT.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
int rc;
Incrblob *p = (Incrblob *)pBlob;
sqlite3 *db;
if( p==0 ) return SQLITE_MISUSE_BKPT;
db = p->db;
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
77957 77958 77959 77960 77961 77962 77963 77964 77965 77966 77967 77968 77969 77970 77971 77972 77973 77974 77975 77976 77977 77978 77979 77980 |
** to sqlite3ThreadJoin() is likely to block. Cases that are likely to
** block provoke debugging output.
**
** In both cases, the effects of the main thread seeing (bDone==0) even
** after the thread has finished are not dire. So we don't worry about
** memory barriers and such here.
*/
struct SortSubtask {
SQLiteThread *pThread; /* Background thread, if any */
int bDone; /* Set if thread is finished but not joined */
VdbeSorter *pSorter; /* Sorter that owns this sub-task */
UnpackedRecord *pUnpacked; /* Space to unpack a record */
SorterList list; /* List for thread to write to a PMA */
int nPMA; /* Number of PMAs currently in file */
SorterFile file; /* Temp file for level-0 PMAs */
SorterFile file2; /* Space for other PMAs */
};
/*
** Main sorter structure. A single instance of this is allocated for each
** sorter cursor created by the VDBE.
**
** mxKeysize:
** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(),
| > > > | 78184 78185 78186 78187 78188 78189 78190 78191 78192 78193 78194 78195 78196 78197 78198 78199 78200 78201 78202 78203 78204 78205 78206 78207 78208 78209 78210 |
** to sqlite3ThreadJoin() is likely to block. Cases that are likely to
** block provoke debugging output.
**
** In both cases, the effects of the main thread seeing (bDone==0) even
** after the thread has finished are not dire. So we don't worry about
** memory barriers and such here.
*/
typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
struct SortSubtask {
SQLiteThread *pThread; /* Background thread, if any */
int bDone; /* Set if thread is finished but not joined */
VdbeSorter *pSorter; /* Sorter that owns this sub-task */
UnpackedRecord *pUnpacked; /* Space to unpack a record */
SorterList list; /* List for thread to write to a PMA */
int nPMA; /* Number of PMAs currently in file */
SorterCompare xCompare; /* Compare function to use */
SorterFile file; /* Temp file for level-0 PMAs */
SorterFile file2; /* Space for other PMAs */
};
/*
** Main sorter structure. A single instance of this is allocated for each
** sorter cursor created by the VDBE.
**
** mxKeysize:
** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(),
|
| ︙ | ︙ | |||
77994 77995 77996 77997 77998 77999 78000 78001 78002 78003 78004 78005 78006 78007 78008 78009 | SorterList list; /* List of in-memory records */ int iMemory; /* Offset of free space in list.aMemory */ int nMemory; /* Size of list.aMemory allocation in bytes */ u8 bUsePMA; /* True if one or more PMAs created */ u8 bUseThreads; /* True to use background threads */ u8 iPrev; /* Previous thread used to flush PMA */ u8 nTask; /* Size of aTask[] array */ SortSubtask aTask[1]; /* One or more subtasks */ }; /* ** An instance of the following object is used to read records out of a ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. ** aKey might point into aMap or into aBuffer. If neither of those locations ** contain a contiguous representation of the key, then aAlloc is allocated ** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. | > > > > | 78224 78225 78226 78227 78228 78229 78230 78231 78232 78233 78234 78235 78236 78237 78238 78239 78240 78241 78242 78243 | SorterList list; /* List of in-memory records */ int iMemory; /* Offset of free space in list.aMemory */ int nMemory; /* Size of list.aMemory allocation in bytes */ u8 bUsePMA; /* True if one or more PMAs created */ u8 bUseThreads; /* True to use background threads */ u8 iPrev; /* Previous thread used to flush PMA */ u8 nTask; /* Size of aTask[] array */ u8 typeMask; SortSubtask aTask[1]; /* One or more subtasks */ }; #define SORTER_TYPE_INTEGER 0x01 #define SORTER_TYPE_TEXT 0x02 /* ** An instance of the following object is used to read records out of a ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. ** aKey might point into aMap or into aBuffer. If neither of those locations ** contain a contiguous representation of the key, then aAlloc is allocated ** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. |
| ︙ | ︙ | |||
78408 78409 78410 78411 78412 78413 78414 78415 78416 78417 78418 78419 78420 |
if( rc==SQLITE_OK ){
rc = vdbePmaReaderNext(pReadr);
}
return rc;
}
/*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
** used by the comparison. Return the result of the comparison.
**
| > > > > > > > > > > > > > > > > > > > > | | < < > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 78642 78643 78644 78645 78646 78647 78648 78649 78650 78651 78652 78653 78654 78655 78656 78657 78658 78659 78660 78661 78662 78663 78664 78665 78666 78667 78668 78669 78670 78671 78672 78673 78674 78675 78676 78677 78678 78679 78680 78681 78682 78683 78684 78685 78686 78687 78688 78689 78690 78691 78692 78693 78694 78695 78696 78697 78698 78699 78700 78701 78702 78703 78704 78705 78706 78707 78708 78709 78710 78711 78712 78713 78714 78715 78716 78717 78718 78719 78720 78721 78722 78723 78724 78725 78726 78727 78728 78729 78730 78731 78732 78733 78734 78735 78736 78737 78738 78739 78740 78741 78742 78743 78744 78745 78746 78747 78748 78749 78750 78751 78752 78753 78754 78755 78756 78757 78758 78759 78760 78761 78762 78763 78764 78765 78766 78767 78768 78769 78770 78771 78772 78773 78774 78775 78776 78777 78778 78779 78780 78781 78782 78783 78784 78785 78786 78787 78788 78789 78790 78791 78792 78793 78794 78795 78796 78797 78798 78799 78800 78801 78802 78803 78804 78805 78806 78807 78808 78809 78810 |
if( rc==SQLITE_OK ){
rc = vdbePmaReaderNext(pReadr);
}
return rc;
}
/*
** A version of vdbeSorterCompare() that assumes that it has already been
** determined that the first field of key1 is equal to the first field of
** key2.
*/
static int vdbeSorterCompareTail(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( *pbKey2Cached==0 ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
*pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
}
/*
** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
** used by the comparison. Return the result of the comparison.
**
** If IN/OUT parameter *pbKey2Cached is true when this function is called,
** it is assumed that (pTask->pUnpacked) contains the unpacked version
** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
** version of key2 and *pbKey2Cached set to true before returning.
**
** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
** to SQLITE_NOMEM.
*/
static int vdbeSorterCompare(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
UnpackedRecord *r2 = pTask->pUnpacked;
if( !*pbKey2Cached ){
sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
*pbKey2Cached = 1;
}
return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
}
/*
** A specially optimized version of vdbeSorterCompare() that assumes that
** the first field of each key is a TEXT value and that the collation
** sequence to compare them with is BINARY.
*/
static int vdbeSorterCompareText(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
const u8 * const p1 = (const u8 * const)pKey1;
const u8 * const p2 = (const u8 * const)pKey2;
const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
int n1;
int n2;
int res;
getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
res = memcmp(v1, v2, MIN(n1, n2));
if( res==0 ){
res = n1 - n2;
}
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else{
if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
res = res * -1;
}
}
return res;
}
/*
** A specially optimized version of vdbeSorterCompare() that assumes that
** the first field of each key is an INTEGER value.
*/
static int vdbeSorterCompareInt(
SortSubtask *pTask, /* Subtask context (for pKeyInfo) */
int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2 /* Right side of comparison */
){
const u8 * const p1 = (const u8 * const)pKey1;
const u8 * const p2 = (const u8 * const)pKey2;
const int s1 = p1[1]; /* Left hand serial type */
const int s2 = p2[1]; /* Right hand serial type */
const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */
const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */
int res; /* Return value */
assert( (s1>0 && s1<7) || s1==8 || s1==9 );
assert( (s2>0 && s2<7) || s2==8 || s2==9 );
if( s1>7 && s2>7 ){
res = s1 - s2;
}else{
if( s1==s2 ){
if( (*v1 ^ *v2) & 0x80 ){
/* The two values have different signs */
res = (*v1 & 0x80) ? -1 : +1;
}else{
/* The two values have the same sign. Compare using memcmp(). */
static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
int i;
res = 0;
for(i=0; i<aLen[s1]; i++){
if( (res = v1[i] - v2[i]) ) break;
}
}
}else{
if( s2>7 ){
res = +1;
}else if( s1>7 ){
res = -1;
}else{
res = s1 - s2;
}
assert( res!=0 );
if( res>0 ){
if( *v1 & 0x80 ) res = -1;
}else{
if( *v2 & 0x80 ) res = +1;
}
}
}
if( res==0 ){
if( pTask->pSorter->pKeyInfo->nField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
}
}else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
res = res * -1;
}
return res;
}
/*
** Initialize the temporary index cursor just opened as a sorter cursor.
**
** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
** to determine the number of fields that should be compared from the
** records being sorted. However, if the value passed as argument nField
|
| ︙ | ︙ | |||
78501 78502 78503 78504 78505 78506 78507 |
pCsr->pSorter = pSorter;
if( pSorter==0 ){
rc = SQLITE_NOMEM;
}else{
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
| | > > > > | 78865 78866 78867 78868 78869 78870 78871 78872 78873 78874 78875 78876 78877 78878 78879 78880 78881 78882 78883 78884 78885 |
pCsr->pSorter = pSorter;
if( pSorter==0 ){
rc = SQLITE_NOMEM;
}else{
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
if( nField && nWorker==0 ){
pKeyInfo->nXField += (pKeyInfo->nField - nField);
pKeyInfo->nField = nField;
}
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
pSorter->nTask = nWorker + 1;
pSorter->iPrev = nWorker-1;
pSorter->bUseThreads = (pSorter->nTask>1);
pSorter->db = db;
for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
pTask->pSorter = pSorter;
}
|
| ︙ | ︙ | |||
78529 78530 78531 78532 78533 78534 78535 78536 78537 78538 78539 78540 78541 78542 |
if( sqlite3GlobalConfig.pScratch==0 ){
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
}
}
}
return rc;
}
#undef nWorker /* Defined at the top of this function */
/*
| > > > > > > | 78897 78898 78899 78900 78901 78902 78903 78904 78905 78906 78907 78908 78909 78910 78911 78912 78913 78914 78915 78916 |
if( sqlite3GlobalConfig.pScratch==0 ){
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
}
}
if( (pKeyInfo->nField+pKeyInfo->nXField)<13
&& (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
){
pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
}
}
return rc;
}
#undef nWorker /* Defined at the top of this function */
/*
|
| ︙ | ︙ | |||
78553 78554 78555 78556 78557 78558 78559 |
/*
** Free all resources owned by the object indicated by argument pTask. All
** fields of *pTask are zeroed before returning.
*/
static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
sqlite3DbFree(db, pTask->pUnpacked);
| < < < < < < < > | 78927 78928 78929 78930 78931 78932 78933 78934 78935 78936 78937 78938 78939 78940 78941 78942 78943 78944 78945 78946 78947 78948 78949 78950 78951 78952 78953 78954 78955 78956 78957 78958 |
/*
** Free all resources owned by the object indicated by argument pTask. All
** fields of *pTask are zeroed before returning.
*/
static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
sqlite3DbFree(db, pTask->pUnpacked);
#if SQLITE_MAX_WORKER_THREADS>0
/* pTask->list.aMemory can only be non-zero if it was handed memory
** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */
if( pTask->list.aMemory ){
sqlite3_free(pTask->list.aMemory);
}else
#endif
{
assert( pTask->list.aMemory==0 );
vdbeSorterRecordFree(0, pTask->list.pList);
}
if( pTask->file.pFd ){
sqlite3OsCloseFree(pTask->file.pFd);
}
if( pTask->file2.pFd ){
sqlite3OsCloseFree(pTask->file2.pFd);
}
memset(pTask, 0, sizeof(SortSubtask));
}
#ifdef SQLITE_DEBUG_SORTER_THREADS
static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
i64 t;
int iTask = (pTask - pTask->pSorter->aTask);
sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
|
| ︙ | ︙ | |||
78756 78757 78758 78759 78760 78761 78762 78763 78764 78765 78766 78767 78768 78769 |
}
#endif
vdbeMergeEngineFree(pSorter->pMerger);
pSorter->pMerger = 0;
for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
vdbeSortSubtaskCleanup(db, pTask);
}
if( pSorter->list.aMemory==0 ){
vdbeSorterRecordFree(0, pSorter->list.pList);
}
pSorter->list.pList = 0;
pSorter->list.szPMA = 0;
pSorter->bUsePMA = 0;
| > | 79124 79125 79126 79127 79128 79129 79130 79131 79132 79133 79134 79135 79136 79137 79138 |
}
#endif
vdbeMergeEngineFree(pSorter->pMerger);
pSorter->pMerger = 0;
for(i=0; i<pSorter->nTask; i++){
SortSubtask *pTask = &pSorter->aTask[i];
vdbeSortSubtaskCleanup(db, pTask);
pTask->pSorter = pSorter;
}
if( pSorter->list.aMemory==0 ){
vdbeSorterRecordFree(0, pSorter->list.pList);
}
pSorter->list.pList = 0;
pSorter->list.szPMA = 0;
pSorter->bUsePMA = 0;
|
| ︙ | ︙ | |||
78865 78866 78867 78868 78869 78870 78871 |
SortSubtask *pTask, /* Calling thread context */
SorterRecord *p1, /* First list to merge */
SorterRecord *p2, /* Second list to merge */
SorterRecord **ppOut /* OUT: Head of merged list */
){
SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal;
| | > | > > < | < | > > > > > > > > > > > > > > > > < | 79234 79235 79236 79237 79238 79239 79240 79241 79242 79243 79244 79245 79246 79247 79248 79249 79250 79251 79252 79253 79254 79255 79256 79257 79258 79259 79260 79261 79262 79263 79264 79265 79266 79267 79268 79269 79270 79271 79272 79273 79274 79275 79276 79277 79278 79279 79280 79281 79282 79283 79284 79285 79286 79287 79288 79289 79290 79291 79292 79293 79294 79295 79296 79297 79298 79299 79300 79301 79302 79303 79304 79305 |
SortSubtask *pTask, /* Calling thread context */
SorterRecord *p1, /* First list to merge */
SorterRecord *p2, /* Second list to merge */
SorterRecord **ppOut /* OUT: Head of merged list */
){
SorterRecord *pFinal = 0;
SorterRecord **pp = &pFinal;
int bCached = 0;
while( p1 && p2 ){
int res;
res = pTask->xCompare(
pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
);
if( res<=0 ){
*pp = p1;
pp = &p1->u.pNext;
p1 = p1->u.pNext;
}else{
*pp = p2;
pp = &p2->u.pNext;
p2 = p2->u.pNext;
bCached = 0;
}
}
*pp = p1 ? p1 : p2;
*ppOut = pFinal;
}
/*
** Return the SorterCompare function to compare values collected by the
** sorter object passed as the only argument.
*/
static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
if( p->typeMask==SORTER_TYPE_INTEGER ){
return vdbeSorterCompareInt;
}else if( p->typeMask==SORTER_TYPE_TEXT ){
return vdbeSorterCompareText;
}
return vdbeSorterCompare;
}
/*
** Sort the linked list of records headed at pTask->pList. Return
** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if
** an error occurs.
*/
static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
int i;
SorterRecord **aSlot;
SorterRecord *p;
int rc;
rc = vdbeSortAllocUnpacked(pTask);
if( rc!=SQLITE_OK ) return rc;
p = pList->pList;
pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){
return SQLITE_NOMEM;
}
while( p ){
SorterRecord *pNext;
if( pList->aMemory ){
if( (u8*)p==pList->aMemory ){
pNext = 0;
}else{
assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) );
|
| ︙ | ︙ | |||
79120 79121 79122 79123 79124 79125 79126 |
rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]);
/* Update contents of aTree[] */
if( rc==SQLITE_OK ){
int i; /* Index of aTree[] to recalculate */
PmaReader *pReadr1; /* First PmaReader to compare */
PmaReader *pReadr2; /* Second PmaReader to compare */
| | < | | | 79505 79506 79507 79508 79509 79510 79511 79512 79513 79514 79515 79516 79517 79518 79519 79520 79521 79522 79523 79524 79525 79526 79527 79528 79529 79530 79531 79532 79533 79534 79535 |
rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]);
/* Update contents of aTree[] */
if( rc==SQLITE_OK ){
int i; /* Index of aTree[] to recalculate */
PmaReader *pReadr1; /* First PmaReader to compare */
PmaReader *pReadr2; /* Second PmaReader to compare */
int bCached = 0;
/* Find the first two PmaReaders to compare. The one that was just
** advanced (iPrev) and the one next to it in the array. */
pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
/* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
int iRes;
if( pReadr1->pFd==0 ){
iRes = +1;
}else if( pReadr2->pFd==0 ){
iRes = -1;
}else{
iRes = pTask->xCompare(pTask, &bCached,
pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
);
}
/* If pReadr1 contained the smaller value, set aTree[i] to its index.
** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
** case there is no cache of pReadr2 in pTask->pUnpacked, so set
** pKey2 to point to the record belonging to pReadr2.
|
| ︙ | ︙ | |||
79159 79160 79161 79162 79163 79164 79165 |
** If the two values were equal, then the value from the oldest
** PMA should be considered smaller. The VdbeSorter.aReadr[] array
** is sorted from oldest to newest, so pReadr1 contains older values
** than pReadr2 iff (pReadr1<pReadr2). */
if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
| | | | 79543 79544 79545 79546 79547 79548 79549 79550 79551 79552 79553 79554 79555 79556 79557 79558 79559 |
** If the two values were equal, then the value from the oldest
** PMA should be considered smaller. The VdbeSorter.aReadr[] array
** is sorted from oldest to newest, so pReadr1 contains older values
** than pReadr2 iff (pReadr1<pReadr2). */
if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
bCached = 0;
}else{
if( pReadr1->pFd ) bCached = 0;
pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
}
}
*pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0);
}
|
| ︙ | ︙ | |||
79268 79269 79270 79271 79272 79273 79274 79275 79276 79277 79278 79279 79280 79281 | VdbeSorter *pSorter = pCsr->pSorter; int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ int bFlush; /* True to flush contents of memory to PMA */ int nReq; /* Bytes of memory required */ int nPMA; /* Bytes of PMA space required */ assert( pSorter ); /* Figure out whether or not the current contents of memory should be ** flushed to a PMA before continuing. If so, do so. ** ** If using the single large allocation mode (pSorter->aMemory!=0), then | > > > > > > > > > > | 79652 79653 79654 79655 79656 79657 79658 79659 79660 79661 79662 79663 79664 79665 79666 79667 79668 79669 79670 79671 79672 79673 79674 79675 |
VdbeSorter *pSorter = pCsr->pSorter;
int rc = SQLITE_OK; /* Return Code */
SorterRecord *pNew; /* New list element */
int bFlush; /* True to flush contents of memory to PMA */
int nReq; /* Bytes of memory required */
int nPMA; /* Bytes of PMA space required */
int t; /* serial type of first record field */
getVarint32((const u8*)&pVal->z[1], t);
if( t>0 && t<10 && t!=7 ){
pSorter->typeMask &= SORTER_TYPE_INTEGER;
}else if( t>10 && (t & 0x01) ){
pSorter->typeMask &= SORTER_TYPE_TEXT;
}else{
pSorter->typeMask = 0;
}
assert( pSorter );
/* Figure out whether or not the current contents of memory should be
** flushed to a PMA before continuing. If so, do so.
**
** If using the single large allocation mode (pSorter->aMemory!=0), then
|
| ︙ | ︙ | |||
79533 79534 79535 79536 79537 79538 79539 79540 |
p2 = &pMerger->aReadr[i2];
if( p1->pFd==0 ){
iRes = i2;
}else if( p2->pFd==0 ){
iRes = i1;
}else{
int res;
| > > | | | | 79927 79928 79929 79930 79931 79932 79933 79934 79935 79936 79937 79938 79939 79940 79941 79942 79943 79944 79945 79946 |
p2 = &pMerger->aReadr[i2];
if( p1->pFd==0 ){
iRes = i2;
}else if( p2->pFd==0 ){
iRes = i1;
}else{
SortSubtask *pTask = pMerger->pTask;
int bCached = 0;
int res;
assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */
res = pTask->xCompare(
pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
);
if( res<=0 ){
iRes = i1;
}else{
iRes = i2;
}
}
|
| ︙ | ︙ | |||
79560 79561 79562 79563 79564 79565 79566 | ** SQLITE_MAX_WORKER_THREADS==0). The other values are only used ** when there exists one or more separate worker threads. */ #define INCRINIT_NORMAL 0 #define INCRINIT_TASK 1 #define INCRINIT_ROOT 2 | > | | | | | 79956 79957 79958 79959 79960 79961 79962 79963 79964 79965 79966 79967 79968 79969 79970 79971 79972 79973 79974 79975 | ** SQLITE_MAX_WORKER_THREADS==0). The other values are only used ** when there exists one or more separate worker threads. */ #define INCRINIT_NORMAL 0 #define INCRINIT_TASK 1 #define INCRINIT_ROOT 2 /* ** Forward reference required as the vdbeIncrMergeInit() and ** vdbePmaReaderIncrInit() routines are called mutually recursively when ** building a merge tree. */ static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode); /* ** Initialize the MergeEngine object passed as the second argument. Once this ** function returns, the first key of merged data may be read from the ** MergeEngine object in the usual fashion. ** ** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge |
| ︙ | ︙ | |||
79611 79612 79613 79614 79615 79616 79617 |
** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
** in use it will block the vdbePmaReaderNext() call while it uses
** the main thread to fill its buffer. So calling PmaReaderNext()
** on this PmaReader before any of the multi-threaded PmaReaders takes
** better advantage of multi-processor hardware. */
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
}else{
| | < < | | | | | | | 80008 80009 80010 80011 80012 80013 80014 80015 80016 80017 80018 80019 80020 80021 80022 80023 80024 80025 80026 80027 80028 80029 80030 80031 80032 80033 80034 80035 80036 80037 80038 80039 80040 80041 80042 |
** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
** in use it will block the vdbePmaReaderNext() call while it uses
** the main thread to fill its buffer. So calling PmaReaderNext()
** on this PmaReader before any of the multi-threaded PmaReaders takes
** better advantage of multi-processor hardware. */
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
}else{
rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
}
if( rc!=SQLITE_OK ) return rc;
}
for(i=pMerger->nTree-1; i>0; i--){
vdbeMergeEngineCompare(pMerger, i);
}
return pTask->pUnpacked->errCode;
}
/*
** The PmaReader passed as the first argument is guaranteed to be an
** incremental-reader (pReadr->pIncr!=0). This function serves to open
** and/or initialize the temp file related fields of the IncrMerge
** object at (pReadr->pIncr).
**
** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
** in the sub-tree headed by pReadr are also initialized. Data is then
** loaded into the buffers belonging to pReadr and it is set to point to
** the first key in its range.
**
** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
** to be a multi-threaded PmaReader and this function is being called in a
** background thread. In this case all PmaReaders in the sub-tree are
** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
** pReadr is populated. However, pReadr itself is not set up to point
** to its first key. A call to vdbePmaReaderNext() is still required to do
|
| ︙ | ︙ | |||
79660 79661 79662 79663 79664 79665 79666 79667 79668 79669 79670 |
** the current PmaReader set to point to the first key in its range.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
int rc = SQLITE_OK;
IncrMerger *pIncr = pReadr->pIncr;
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
| > > < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > | | | < | < | | | | > < | > > > | < | | > > | > > > > > > | | | > > > > > > | 80055 80056 80057 80058 80059 80060 80061 80062 80063 80064 80065 80066 80067 80068 80069 80070 80071 80072 80073 80074 80075 80076 80077 80078 80079 80080 80081 80082 80083 80084 80085 80086 80087 80088 80089 80090 80091 80092 80093 80094 80095 80096 80097 80098 80099 80100 80101 80102 80103 80104 80105 80106 80107 80108 80109 80110 80111 80112 80113 80114 80115 80116 80117 80118 80119 80120 80121 80122 80123 80124 80125 80126 80127 80128 80129 80130 80131 80132 80133 80134 80135 80136 80137 80138 80139 80140 80141 80142 80143 80144 80145 80146 80147 80148 80149 80150 80151 80152 80153 80154 80155 80156 80157 80158 80159 80160 80161 80162 80163 80164 80165 80166 80167 80168 80169 80170 |
** the current PmaReader set to point to the first key in its range.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
int rc = SQLITE_OK;
IncrMerger *pIncr = pReadr->pIncr;
SortSubtask *pTask = pIncr->pTask;
sqlite3 *db = pTask->pSorter->db;
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
/* Set up the required files for pIncr. A multi-theaded IncrMerge object
** requires two temp files to itself, whereas a single-threaded object
** only requires a region of pTask->file2. */
if( rc==SQLITE_OK ){
int mxSz = pIncr->mxSz;
#if SQLITE_MAX_WORKER_THREADS>0
if( pIncr->bUseThread ){
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
if( rc==SQLITE_OK ){
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
}
}else
#endif
/*if( !pIncr->bUseThread )*/{
if( pTask->file2.pFd==0 ){
assert( pTask->file2.iEof>0 );
rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
pTask->file2.iEof = 0;
}
if( rc==SQLITE_OK ){
pIncr->aFile[1].pFd = pTask->file2.pFd;
pIncr->iStartOff = pTask->file2.iEof;
pTask->file2.iEof += mxSz;
}
}
}
#if SQLITE_MAX_WORKER_THREADS>0
if( rc==SQLITE_OK && pIncr->bUseThread ){
/* Use the current thread to populate aFile[1], even though this
** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
** then this function is already running in background thread
** pIncr->pTask->thread.
**
** If this is the INCRINIT_ROOT object, then it is running in the
** main VDBE thread. But that is Ok, as that thread cannot return
** control to the VDBE or proceed with anything useful until the
** first results are ready from this merger object anyway.
*/
assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
rc = vdbeIncrPopulate(pIncr);
}
#endif
if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
rc = vdbePmaReaderNext(pReadr);
}
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** The main routine for vdbePmaReaderIncrMergeInit() operations run in
** background threads.
*/
static void *vdbePmaReaderBgIncrInit(void *pCtx){
PmaReader *pReader = (PmaReader*)pCtx;
void *pRet = SQLITE_INT_TO_PTR(
vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
);
pReader->pIncr->pTask->bDone = 1;
return pRet;
}
#endif
/*
** If the PmaReader passed as the first argument is not an incremental-reader
** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
** this routine to initialize the incremental merge.
**
** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1),
** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
** Or, if the IncrMerger is single threaded, the same function is called
** using the current thread.
*/
static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */
int rc = SQLITE_OK; /* Return code */
if( pIncr ){
#if SQLITE_MAX_WORKER_THREADS>0
assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
if( pIncr->bUseThread ){
void *pCtx = (void*)pReadr;
rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
}else
#endif
{
rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
}
}
return rc;
}
/*
** Allocate a new MergeEngine object to merge the contents of nPMA level-0
** PMAs from pTask->file. If no error occurs, set *ppOut to point to
** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
** to NULL and return an SQLite error code.
**
|
| ︙ | ︙ | |||
79954 79955 79956 79957 79958 79959 79960 79961 79962 79963 79964 79965 79966 79967 |
*/
static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
int rc; /* Return code */
SortSubtask *pTask0 = &pSorter->aTask[0];
MergeEngine *pMain = 0;
#if SQLITE_MAX_WORKER_THREADS
sqlite3 *db = pTask0->pSorter->db;
#endif
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS
assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
if( pSorter->bUseThreads ){
| > > > > > | 80368 80369 80370 80371 80372 80373 80374 80375 80376 80377 80378 80379 80380 80381 80382 80383 80384 80385 80386 |
*/
static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
int rc; /* Return code */
SortSubtask *pTask0 = &pSorter->aTask[0];
MergeEngine *pMain = 0;
#if SQLITE_MAX_WORKER_THREADS
sqlite3 *db = pTask0->pSorter->db;
int i;
SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
for(i=0; i<pSorter->nTask; i++){
pSorter->aTask[i].xCompare = xCompare;
}
#endif
rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
if( rc==SQLITE_OK ){
#if SQLITE_MAX_WORKER_THREADS
assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
if( pSorter->bUseThreads ){
|
| ︙ | ︙ | |||
79982 79983 79984 79985 79986 79987 79988 79989 |
IncrMerger *pIncr;
if( (pIncr = pMain->aReadr[iTask].pIncr) ){
vdbeIncrMergerSetThreads(pIncr);
assert( pIncr->pTask!=pLast );
}
}
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
PmaReader *p = &pMain->aReadr[iTask];
| > > > > > > > > > | | | < < > | < < | 80401 80402 80403 80404 80405 80406 80407 80408 80409 80410 80411 80412 80413 80414 80415 80416 80417 80418 80419 80420 80421 80422 80423 80424 80425 80426 80427 80428 80429 |
IncrMerger *pIncr;
if( (pIncr = pMain->aReadr[iTask].pIncr) ){
vdbeIncrMergerSetThreads(pIncr);
assert( pIncr->pTask!=pLast );
}
}
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
/* Check that:
**
** a) The incremental merge object is configured to use the
** right task, and
** b) If it is using task (nTask-1), it is configured to run
** in single-threaded mode. This is important, as the
** root merge (INCRINIT_ROOT) will be using the same task
** object.
*/
PmaReader *p = &pMain->aReadr[iTask];
assert( p->pIncr==0 || (
(p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */
&& (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */
));
rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
}
}
pMain = 0;
}
if( rc==SQLITE_OK ){
rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT);
}
|
| ︙ | ︙ | |||
80945 80946 80947 80948 80949 80950 80951 | ** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase; ** ** Should be transformed into: ** ** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; ** ** The nSubquery parameter specifies how many levels of subquery the | | < | 81370 81371 81372 81373 81374 81375 81376 81377 81378 81379 81380 81381 81382 81383 81384 81385 81386 81387 81388 81389 81390 81391 81392 81393 81394 81395 81396 81397 81398 81399 81400 81401 81402 81403 |
** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
** Should be transformed into:
**
** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
**
** The nSubquery parameter specifies how many levels of subquery the
** alias is removed from the original expression. The usual value is
** zero but it might be more if the alias is contained within a subquery
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
** structures must be increased by the nSubquery amount.
*/
static void resolveAlias(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* A result set */
int iCol, /* A column in the result set. 0..pEList->nExpr-1 */
Expr *pExpr, /* Transform this into an alias to the result set */
const char *zType, /* "GROUP" or "ORDER" or "" */
int nSubquery /* Number of subqueries that the label is moving */
){
Expr *pOrig; /* The iCol-th column of the result set */
Expr *pDup; /* Copy of pOrig */
sqlite3 *db; /* The database connection */
assert( iCol>=0 && iCol<pEList->nExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
incrAggFunctionDepth(pDup, nSubquery);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
|
| ︙ | ︙ | |||
81859 81860 81861 81862 81863 81864 81865 |
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return 1;
pNew->flags |= EP_IntValue;
pNew->u.iValue = iCol;
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
| > | > | | | 82283 82284 82285 82286 82287 82288 82289 82290 82291 82292 82293 82294 82295 82296 82297 82298 82299 82300 82301 |
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return 1;
pNew->flags |= EP_IntValue;
pNew->u.iValue = iCol;
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
Expr *pParent = pItem->pExpr;
assert( pParent->op==TK_COLLATE );
while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
assert( pParent->pLeft==pE );
pParent->pLeft = pNew;
}
sqlite3ExprDelete(db, pE);
pItem->u.x.iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
}
|
| ︙ | ︙ | |||
82052 82053 82054 82055 82056 82057 82058 82059 82060 82061 82062 82063 82064 82065 |
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* Recursively resolve names in all subqueries
*/
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
if( pItem->pSelect ){
NameContext *pNC; /* Used to iterate name contexts */
| > > > > > > > > > > > > > > | 82478 82479 82480 82481 82482 82483 82484 82485 82486 82487 82488 82489 82490 82491 82492 82493 82494 82495 82496 82497 82498 82499 82500 82501 82502 82503 82504 82505 |
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* If the SF_Converted flags is set, then this Select object was
** was created by the convertCompoundSelectToSubquery() function.
** In this case the ORDER BY clause (p->pOrderBy) should be resolved
** as if it were part of the sub-query, not the parent. This block
** moves the pOrderBy down to the sub-query. It will be moved back
** after the names have been resolved. */
if( p->selFlags & SF_Converted ){
Select *pSub = p->pSrc->a[0].pSelect;
assert( p->pSrc->nSrc==1 && p->pOrderBy );
assert( pSub->pPrior && pSub->pOrderBy==0 );
pSub->pOrderBy = p->pOrderBy;
p->pOrderBy = 0;
}
/* Recursively resolve names in all subqueries
*/
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
if( pItem->pSelect ){
NameContext *pNC; /* Used to iterate name contexts */
|
| ︙ | ︙ | |||
82133 82134 82135 82136 82137 82138 82139 82140 82141 82142 82143 82144 82145 |
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
sNC.ncFlags |= NC_AllowAgg;
/* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
*/
| > > > > > > > > > > > > > > > > > | > | 82573 82574 82575 82576 82577 82578 82579 82580 82581 82582 82583 82584 82585 82586 82587 82588 82589 82590 82591 82592 82593 82594 82595 82596 82597 82598 82599 82600 82601 82602 82603 82604 82605 82606 82607 82608 82609 82610 82611 |
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
sNC.ncFlags |= NC_AllowAgg;
/* If this is a converted compound query, move the ORDER BY clause from
** the sub-query back to the parent query. At this point each term
** within the ORDER BY clause has been transformed to an integer value.
** These integers will be replaced by copies of the corresponding result
** set expressions by the call to resolveOrderGroupBy() below. */
if( p->selFlags & SF_Converted ){
Select *pSub = p->pSrc->a[0].pSelect;
p->pOrderBy = pSub->pOrderBy;
pSub->pOrderBy = 0;
}
/* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
**
** If there is an ORDER BY clause on a term of a compound-select other
** than the right-most term, then that is a syntax error. But the error
** is not detected until much later, and so we need to go ahead and
** resolve those symbols on the incorrect ORDER BY for consistency.
*/
if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
&& resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
){
return WRC_Abort;
}
if( db->mallocFailed ){
return WRC_Abort;
}
/* Resolve the GROUP BY clause. At the same time, make sure
|
| ︙ | ︙ | |||
83591 83592 83593 83594 83595 83596 83597 |
** ExprList.
*/
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
int i;
u32 m = 0;
if( pList ){
for(i=0; i<pList->nExpr; i++){
| | > | 84049 84050 84051 84052 84053 84054 84055 84056 84057 84058 84059 84060 84061 84062 84063 84064 |
** ExprList.
*/
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
int i;
u32 m = 0;
if( pList ){
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
if( ALWAYS(pExpr) ) m |= pExpr->flags;
}
}
return m;
}
/*
** These routines are Walker callbacks used to check expressions to
|
| ︙ | ︙ | |||
84031 84032 84033 84034 84035 84036 84037 | mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; /* Check to see if an existing table or index can be used to ** satisfy the query. This is preferable to generating a new ** ephemeral table. */ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); | | | 84490 84491 84492 84493 84494 84495 84496 84497 84498 84499 84500 84501 84502 84503 84504 |
mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( pParse->nErr==0 && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */
i16 iCol; /* Index of column <column> */
i16 iDb; /* Database idx for pTab */
assert( p ); /* Because of isCandidateForInOpt(p) */
|
| ︙ | ︙ | |||
84356 84357 84358 84359 84360 84361 84362 84363 84364 84365 84366 84367 84368 84369 |
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
sqlite3ExprDelete(pParse->db, pSel->pLimit);
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]);
pSel->iLimit = 0;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
rReg = dest.iSDParm;
ExprSetVVAProperty(pExpr, EP_NoReduce);
break;
}
| > | 84815 84816 84817 84818 84819 84820 84821 84822 84823 84824 84825 84826 84827 84828 84829 |
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
sqlite3ExprDelete(pParse->db, pSel->pLimit);
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
&sqlite3IntTokens[1]);
pSel->iLimit = 0;
pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
rReg = dest.iSDParm;
ExprSetVVAProperty(pExpr, EP_NoReduce);
break;
}
|
| ︙ | ︙ | |||
85721 85722 85723 85724 85725 85726 85727 |
}
case TK_AS: {
sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
case TK_ID: {
| | | 86181 86182 86183 86184 86185 86186 86187 86188 86189 86190 86191 86192 86193 86194 86195 |
}
case TK_AS: {
sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
case TK_ID: {
sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
| ︙ | ︙ | |||
86356 86357 86358 86359 86360 86361 86362 |
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
| | | 86816 86817 86818 86819 86820 86821 86822 86823 86824 86825 86826 86827 86828 86829 86830 |
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
}
return 0;
}
|
| ︙ | ︙ | |||
86888 86889 86890 86891 86892 86893 86894 86895 86896 86897 86898 86899 86900 86901 |
if( token==TK_REFERENCES ){
char *zParent;
do {
z += n;
n = sqlite3GetToken(z, &token);
}while( token==TK_SPACE );
zParent = sqlite3DbStrNDup(db, (const char *)z, n);
if( zParent==0 ) break;
sqlite3Dequote(zParent);
if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
(zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
);
| > | 87348 87349 87350 87351 87352 87353 87354 87355 87356 87357 87358 87359 87360 87361 87362 |
if( token==TK_REFERENCES ){
char *zParent;
do {
z += n;
n = sqlite3GetToken(z, &token);
}while( token==TK_SPACE );
if( token==TK_ILLEGAL ) break;
zParent = sqlite3DbStrNDup(db, (const char *)z, n);
if( zParent==0 ) break;
sqlite3Dequote(zParent);
if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
(zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
);
|
| ︙ | ︙ | |||
89114 89115 89116 89117 89118 89119 89120 89121 89122 |
pIndex = sqlite3PrimaryKeyIndex(pTable);
}else{
pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
}
z = argv[2];
if( pIndex ){
int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
| > > > > | | < | < > | | 89575 89576 89577 89578 89579 89580 89581 89582 89583 89584 89585 89586 89587 89588 89589 89590 89591 89592 89593 89594 89595 89596 89597 89598 89599 |
pIndex = sqlite3PrimaryKeyIndex(pTable);
}else{
pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
}
z = argv[2];
if( pIndex ){
tRowcnt *aiRowEst = 0;
int nCol = pIndex->nKeyCol+1;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* Index.aiRowEst may already be set here if there are duplicate
** sqlite_stat1 entries for this index. In that case just clobber
** the old data with the new instead of allocating a new array. */
if( pIndex->aiRowEst==0 ){
pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
}
aiRowEst = pIndex->aiRowEst;
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
|
| ︙ | ︙ | |||
89784 89785 89786 89787 89788 89789 89790 |
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
| | | 90248 90249 90250 90251 90252 90253 90254 90255 90256 90257 90258 90259 90260 90261 90262 |
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
sqlite3CollapseDatabaseArray(db);
return;
detach_error:
sqlite3_result_error(context, zErr, -1);
}
/*
|
| ︙ | ︙ | |||
89818 89819 89820 89821 89822 89823 89824 |
sName.pParse = pParse;
if(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
| < | 90282 90283 90284 90285 90286 90287 90288 90289 90290 90291 90292 90293 90294 90295 |
sName.pParse = pParse;
if(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
goto attach_end;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pAuthArg ){
char *zAuthArg;
if( pAuthArg->op==TK_STRING ){
|
| ︙ | ︙ | |||
90140 90141 90142 90143 90144 90145 90146 | ** will return with an error. SQLITE_IGNORE means that the SQL statement ** should run but attempts to read the specified column will return NULL ** and attempts to write the column will be ignored. ** ** Setting the auth function to NULL disables this hook. The default ** setting of the auth function is NULL. */ | | | 90603 90604 90605 90606 90607 90608 90609 90610 90611 90612 90613 90614 90615 90616 90617 |
** will return with an error. SQLITE_IGNORE means that the SQL statement
** should run but attempts to read the specified column will return NULL
** and attempts to write the column will be ignored.
**
** Setting the auth function to NULL disables this hook. The default
** setting of the auth function is NULL.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
sqlite3 *db,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
|
| ︙ | ︙ | |||
90477 90478 90479 90480 90481 90482 90483 |
*/
SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db;
Vdbe *v;
assert( pParse->pToplevel==0 );
db = pParse->db;
| > | | | > | 90940 90941 90942 90943 90944 90945 90946 90947 90948 90949 90950 90951 90952 90953 90954 90955 90956 90957 90958 |
*/
SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db;
Vdbe *v;
assert( pParse->pToplevel==0 );
db = pParse->db;
if( pParse->nested ) return;
if( db->mallocFailed || pParse->nErr ){
if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
return;
}
/* Begin by generating some termination code at the end of the
** vdbe program
*/
v = sqlite3GetVdbe(pParse);
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
|
| ︙ | ︙ | |||
90561 90562 90563 90564 90565 90566 90567 |
sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
}
}
/* Get the VDBE program ready for execution
*/
| | | 91026 91027 91028 91029 91030 91031 91032 91033 91034 91035 91036 91037 91038 91039 91040 |
sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
}
}
/* Get the VDBE program ready for execution
*/
if( v && pParse->nErr==0 && !db->mallocFailed ){
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
sqlite3VdbeMakeReady(v, pParse);
pParse->rc = SQLITE_DONE;
pParse->colNamesSet = 0;
|
| ︙ | ︙ | |||
91096 91097 91098 91099 91100 91101 91102 |
){
int iDb; /* Database holding the object */
sqlite3 *db = pParse->db;
if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
| < < | 91561 91562 91563 91564 91565 91566 91567 91568 91569 91570 91571 91572 91573 91574 91575 91576 91577 91578 91579 91580 |
){
int iDb; /* Database holding the object */
sqlite3 *db = pParse->db;
if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
return -1;
}
*pUnqual = pName2;
iDb = sqlite3FindDb(db, pName1);
if( iDb<0 ){
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
return -1;
}
}else{
assert( db->init.iDb==0 || db->init.busy );
iDb = db->init.iDb;
*pUnqual = pName1;
}
|
| ︙ | ︙ | |||
91262 91263 91264 91265 91266 91267 91268 |
goto begin_table_error;
}
pTable = sqlite3FindTable(db, zName, zDb);
if( pTable ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
}else{
| | | 91725 91726 91727 91728 91729 91730 91731 91732 91733 91734 91735 91736 91737 91738 91739 |
goto begin_table_error;
}
pTable = sqlite3FindTable(db, zName, zDb);
if( pTable ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
}else{
assert( !db->init.busy || CORRUPT_DB );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto begin_table_error;
}
if( sqlite3FindIndex(db, zName, zDb)!=0 ){
sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
goto begin_table_error;
|
| ︙ | ︙ | |||
91551 91552 91553 91554 91555 91556 91557 |
SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
Table *p;
Column *pCol;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
| | > | 92014 92015 92016 92017 92018 92019 92020 92021 92022 92023 92024 92025 92026 92027 92028 92029 |
SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
Table *p;
Column *pCol;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
pCol = &p->aCol[p->nCol-1];
assert( pCol->zType==0 || CORRUPT_DB );
sqlite3DbFree(pParse->db, pCol->zType);
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
}
/*
** The expression is the default value for the most recently added column
** of the table currently under construction.
|
| ︙ | ︙ | |||
92785 92786 92787 92788 92789 92790 92791 92792 92793 92794 92795 92796 92797 92798 |
int iDb;
if( db->mallocFailed ){
goto exit_drop_table;
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
goto exit_drop_table;
| > | 93249 93250 93251 93252 93253 93254 93255 93256 93257 93258 93259 93260 93261 93262 93263 |
int iDb;
if( db->mallocFailed ){
goto exit_drop_table;
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
goto exit_drop_table;
|
| ︙ | ︙ | |||
93098 93099 93100 93101 93102 93103 93104 |
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
| > | | 93563 93564 93565 93566 93567 93568 93569 93570 93571 93572 93573 93574 93575 93576 93577 93578 |
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_Close, iTab);
sqlite3VdbeAddOp1(v, OP_Close, iIdx);
|
| ︙ | ︙ | |||
93191 93192 93193 93194 93195 93196 93197 | struct ExprList_item *pListItem; /* For looping over pList */ const Column *pTabCol; /* A column in the table */ int nExtra = 0; /* Space allocated for zExtra[] */ int nExtraCol; /* Number of extra columns needed */ char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ | < | | 93657 93658 93659 93660 93661 93662 93663 93664 93665 93666 93667 93668 93669 93670 93671 |
struct ExprList_item *pListItem; /* For looping over pList */
const Column *pTabCol; /* A column in the table */
int nExtra = 0; /* Space allocated for zExtra[] */
int nExtraCol; /* Number of extra columns needed */
char *zExtra = 0; /* Extra space after the Index object */
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
/*
|
| ︙ | ︙ | |||
94111 94112 94113 94114 94115 94116 94117 |
** The operator is "natural cross join". The A and B operands are stored
** in p->a[0] and p->a[1], respectively. The parser initially stores the
** operator with A. This routine shifts that operator over to B.
*/
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
if( p ){
int i;
| < | 94576 94577 94578 94579 94580 94581 94582 94583 94584 94585 94586 94587 94588 94589 |
** The operator is "natural cross join". The A and B operands are stored
** in p->a[0] and p->a[1], respectively. The parser initially stores the
** operator with A. This routine shifts that operator over to B.
*/
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
if( p ){
int i;
for(i=p->nSrc-1; i>0; i--){
p->a[i].jointype = p->a[i-1].jointype;
}
p->a[0].jointype = 0;
}
}
|
| ︙ | ︙ | |||
94358 94359 94360 94361 94362 94363 94364 |
Index *pIdx /* The index that triggers the constraint */
){
char *zErr;
int j;
StrAccum errMsg;
Table *pTab = pIdx->pTable;
| | < | 94822 94823 94824 94825 94826 94827 94828 94829 94830 94831 94832 94833 94834 94835 94836 |
Index *pIdx /* The index that triggers the constraint */
){
char *zErr;
int j;
StrAccum errMsg;
Table *pTab = pIdx->pTable;
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
for(j=0; j<pIdx->nKeyCol; j++){
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
sqlite3StrAccumAppend(&errMsg, ".", 1);
sqlite3StrAccumAppendAll(&errMsg, zCol);
}
|
| ︙ | ︙ | |||
96188 96189 96190 96191 96192 96193 96194 96195 96196 96197 96198 96199 |
int argc,
sqlite3_value **argv
){
PrintfArguments x;
StrAccum str;
const char *zFormat;
int n;
if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
x.nArg = argc-1;
x.nUsed = 0;
x.apArg = argv+1;
| > | < | 96651 96652 96653 96654 96655 96656 96657 96658 96659 96660 96661 96662 96663 96664 96665 96666 96667 96668 96669 96670 96671 |
int argc,
sqlite3_value **argv
){
PrintfArguments x;
StrAccum str;
const char *zFormat;
int n;
sqlite3 *db = sqlite3_context_db_handle(context);
if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
x.nArg = argc-1;
x.nUsed = 0;
x.apArg = argv+1;
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
SQLITE_DYNAMIC);
}
}
|
| ︙ | ︙ | |||
96344 96345 96346 96347 96348 96349 96350 |
sqlite3_free(zBuf);
}
sqlite3_result_double(context, r);
}
#endif
/*
| | | 96807 96808 96809 96810 96811 96812 96813 96814 96815 96816 96817 96818 96819 96820 96821 |
sqlite3_free(zBuf);
}
sqlite3_result_double(context, r);
}
#endif
/*
** Allocate nByte bytes of space using sqlite3Malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify
** the database handle that malloc() has failed and return NULL.
** If nByte is larger than the maximum string or blob length, then
** raise an SQLITE_TOOBIG exception and return NULL.
*/
static void *contextMalloc(sqlite3_context *context, i64 nByte){
char *z;
|
| ︙ | ︙ | |||
96718 96719 96720 96721 96722 96723 96724 | } return *zString==0; } /* ** The sqlite3_strglob() interface. */ | | | 97181 97182 97183 97184 97185 97186 97187 97188 97189 97190 97191 97192 97193 97194 97195 |
}
return *zString==0;
}
/*
** The sqlite3_strglob() interface.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
}
/*
** Count the number of times that the LIKE operator (or GLOB which is
** just a variation of LIKE) gets called. This is used for testing
** only.
|
| ︙ | ︙ | |||
97013 97014 97015 97016 97017 97018 97019 |
static void charFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
unsigned char *z, *zOut;
int i;
| | | 97476 97477 97478 97479 97480 97481 97482 97483 97484 97485 97486 97487 97488 97489 97490 |
static void charFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
unsigned char *z, *zOut;
int i;
zOut = z = sqlite3_malloc64( argc*4+1 );
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
}
for(i=0; i<argc; i++){
sqlite3_int64 x;
unsigned c;
|
| ︙ | ︙ | |||
97161 97162 97163 97164 97165 97166 97167 |
testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
sqlite3_free(zOut);
return;
}
zOld = zOut;
| | | 97624 97625 97626 97627 97628 97629 97630 97631 97632 97633 97634 97635 97636 97637 97638 |
testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
sqlite3_free(zOut);
return;
}
zOld = zOut;
zOut = sqlite3_realloc64(zOut, (int)nOut);
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
return;
}
memcpy(&zOut[j], zRep, nRep);
j += nRep;
|
| ︙ | ︙ | |||
97523 97524 97525 97526 97527 97528 97529 |
int nVal, nSep;
assert( argc==1 || argc==2 );
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
if( pAccum ){
sqlite3 *db = sqlite3_context_db_handle(context);
| | < | 97986 97987 97988 97989 97990 97991 97992 97993 97994 97995 97996 97997 97998 97999 98000 |
int nVal, nSep;
assert( argc==1 || argc==2 );
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
if( pAccum ){
sqlite3 *db = sqlite3_context_db_handle(context);
int firstTerm = pAccum->mxAlloc==0;
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
if( !firstTerm ){
if( argc==2 ){
zSep = (char*)sqlite3_value_text(argv[1]);
nSep = sqlite3_value_bytes(argv[1]);
}else{
zSep = ",";
|
| ︙ | ︙ | |||
98944 98945 98946 98947 98948 98949 98950 |
Token tFromCol; /* Name of column in child table */
Token tToCol; /* Name of column in parent table */
int iFromCol; /* Idx of column in child table */
Expr *pEq; /* tFromCol = OLD.tToCol */
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
| > | | | | | | | | | | | 99406 99407 99408 99409 99410 99411 99412 99413 99414 99415 99416 99417 99418 99419 99420 99421 99422 99423 99424 99425 99426 99427 99428 99429 99430 99431 99432 99433 99434 99435 99436 99437 99438 99439 99440 99441 99442 99443 99444 99445 99446 99447 99448 99449 99450 99451 99452 99453 99454 99455 99456 99457 99458 99459 99460 99461 99462 99463 99464 |
Token tFromCol; /* Name of column in child table */
Token tToCol; /* Name of column in parent table */
int iFromCol; /* Idx of column in child table */
Expr *pEq; /* tFromCol = OLD.tToCol */
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
tToCol.n = sqlite3Strlen30(tToCol.z);
tFromCol.n = sqlite3Strlen30(tFromCol.z);
/* Create the expression "OLD.zToCol = zFromCol". It is important
** that the "OLD.zToCol" term is on the LHS of the = operator, so
** that the affinity and collation sequence associated with the
** parent table are used for the comparison. */
pEq = sqlite3PExpr(pParse, TK_EQ,
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
, 0);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
**
** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
*/
if( pChanges ){
pEq = sqlite3PExpr(pParse, TK_IS,
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
0);
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
Expr *pNew;
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0);
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
if( pDflt ){
pNew = sqlite3ExprDup(db, pDflt, 0);
}else{
pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
|
| ︙ | ︙ | |||
99034 99035 99036 99037 99038 99039 99040 |
/* Disable lookaside memory allocation */
enableLookaside = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
| | | < | | 99497 99498 99499 99500 99501 99502 99503 99504 99505 99506 99507 99508 99509 99510 99511 99512 99513 99514 99515 99516 |
/* Disable lookaside memory allocation */
enableLookaside = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
nFrom + 1 /* Space for pStep->zTarget */
);
if( pTrigger ){
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
pStep->zTarget = (char *)&pStep[1];
memcpy((char *)pStep->zTarget, zFrom, nFrom);
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
if( pWhen ){
pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
|
| ︙ | ︙ | |||
99505 99506 99507 99508 99509 99510 99511 | int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */ ); /* ** This routine is called to handle SQL of the following forms: ** | | > | | > | > | | | | | 99967 99968 99969 99970 99971 99972 99973 99974 99975 99976 99977 99978 99979 99980 99981 99982 99983 99984 99985 99986 99987 99988 99989 99990 99991 99992 99993 99994 99995 99996 99997 | int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */ ); /* ** This routine is called to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... ** insert into TABLE (IDLIST) select ** insert into TABLE (IDLIST) default values ** ** The IDLIST following the table name is always optional. If omitted, ** then a list of all (non-hidden) columns for the table is substituted. ** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST ** is omitted. ** ** For the pSelect parameter holds the values to be inserted for the ** first two forms shown above. A VALUES clause is really just short-hand ** for a SELECT statement that omits the FROM clause and everything else ** that follows. If the pSelect parameter is NULL, that means that the ** DEFAULT VALUES form of the INSERT statement is intended. ** ** The code generated follows one of four templates. For a simple ** insert with data coming from a single-row VALUES clause, the code executes ** once straight down through. Pseudo-code follows (we call this ** the "1st template"): ** ** open write cursor to <table> and its indices ** put VALUES clause expressions into registers ** write the resulting record into <table> ** cleanup |
| ︙ | ︙ | |||
99625 99626 99627 99628 99629 99630 99631 | int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ u8 useTempTable = 0; /* Store SELECT results in intermediate table */ u8 appendFlag = 0; /* True if the insert is likely to be an append */ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ | | | 100090 100091 100092 100093 100094 100095 100096 100097 100098 100099 100100 100101 100102 100103 100104 | int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ u8 useTempTable = 0; /* Store SELECT results in intermediate table */ u8 appendFlag = 0; /* True if the insert is likely to be an append */ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ u8 bIdListInOrder; /* True if IDLIST is in table order */ ExprList *pList = 0; /* List of VALUES() to be inserted */ /* Register allocations */ int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ |
| ︙ | ︙ | |||
99650 99651 99652 99653 99654 99655 99656 |
db = pParse->db;
memset(&dest, 0, sizeof(dest));
if( pParse->nErr || db->mallocFailed ){
goto insert_cleanup;
}
/* If the Select object is really just a simple VALUES() list with a
| | | | 100115 100116 100117 100118 100119 100120 100121 100122 100123 100124 100125 100126 100127 100128 100129 100130 |
db = pParse->db;
memset(&dest, 0, sizeof(dest));
if( pParse->nErr || db->mallocFailed ){
goto insert_cleanup;
}
/* If the Select object is really just a simple VALUES() list with a
** single row (the common case) then keep that one row of values
** and discard the other (unused) parts of the pSelect object
*/
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
pList = pSelect->pEList;
pSelect->pEList = 0;
sqlite3SelectDelete(db, pSelect);
pSelect = 0;
}
|
| ︙ | ︙ | |||
99759 99760 99761 99762 99763 99764 99765 99766 99767 99768 99769 99770 99771 99772 |
** If the table has an INTEGER PRIMARY KEY column and that column
** is named in the IDLIST, then record in the ipkColumn variable
** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
** is appears in the original table. (The index of the INTEGER
** PRIMARY KEY in the original table is pTab->iPKey.)
*/
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; i<pColumn->nId; i++){
for(j=0; j<pTab->nCol; j++){
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
| > | 100224 100225 100226 100227 100228 100229 100230 100231 100232 100233 100234 100235 100236 100237 100238 |
** If the table has an INTEGER PRIMARY KEY column and that column
** is named in the IDLIST, then record in the ipkColumn variable
** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
** is appears in the original table. (The index of the INTEGER
** PRIMARY KEY in the original table is pTab->iPKey.)
*/
bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
pColumn->a[i].idx = -1;
}
for(i=0; i<pColumn->nId; i++){
for(j=0; j<pTab->nCol; j++){
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
|
| ︙ | ︙ | |||
99794 99795 99796 99797 99798 99799 99800 |
/* Figure out how many columns of data are supplied. If the data
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
| > | < | | 100260 100261 100262 100263 100264 100265 100266 100267 100268 100269 100270 100271 100272 100273 100274 100275 100276 100277 100278 100279 100280 100281 100282 100283 100284 100285 100286 100287 100288 |
/* Figure out how many columns of data are supplied. If the data
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
/* Data is coming from a SELECT or from a multi-row VALUES clause.
** Generate a co-routine to run the SELECT. */
int regYield; /* Register holding co-routine entry-point */
int addrTop; /* Top of the co-routine */
int rc; /* Result code */
regYield = ++pParse->nMem;
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
dest.iSdst = bIdListInOrder ? regData : 0;
dest.nSdst = pTab->nCol;
rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
|
| ︙ | ︙ | |||
99856 99857 99858 99859 99860 99861 99862 |
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
| | | | 100322 100323 100324 100325 100326 100327 100328 100329 100330 100331 100332 100333 100334 100335 100336 100337 |
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
}else{
/* This is the case if the data for the INSERT is coming from a
** single-row VALUES clause
*/
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
srcTab = -1;
assert( useTempTable==0 );
nColumn = pList ? pList->nExpr : 0;
|
| ︙ | ︙ | |||
100928 100929 100930 100931 100932 100933 100934 100935 100936 100937 100938 100939 100940 100941 |
static int xferOptimization(
Parse *pParse, /* Parser context */
Table *pDest, /* The table we are inserting into */
Select *pSelect, /* A SELECT statement to use as the data source */
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
){
ExprList *pEList; /* The result set of the SELECT */
Table *pSrc; /* The table in the FROM clause of SELECT */
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
struct SrcList_item *pItem; /* An element of pSelect->pSrc */
int i; /* Loop counter */
int iDbSrc; /* The database of pSrc */
int iSrc, iDest; /* Cursors from source and destination */
| > | 101394 101395 101396 101397 101398 101399 101400 101401 101402 101403 101404 101405 101406 101407 101408 |
static int xferOptimization(
Parse *pParse, /* Parser context */
Table *pDest, /* The table we are inserting into */
Select *pSelect, /* A SELECT statement to use as the data source */
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
){
sqlite3 *db = pParse->db;
ExprList *pEList; /* The result set of the SELECT */
Table *pSrc; /* The table in the FROM clause of SELECT */
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
struct SrcList_item *pItem; /* An element of pSelect->pSrc */
int i; /* Loop counter */
int iDbSrc; /* The database of pSrc */
int iSrc, iDest; /* Cursors from source and destination */
|
| ︙ | ︙ | |||
101075 101076 101077 101078 101079 101080 101081 | /* Disallow the transfer optimization if the destination table constains ** any foreign key constraints. This is more restrictive than necessary. ** But the main beneficiary of the transfer optimization is the VACUUM ** command, and the VACUUM command disables foreign key constraints. So ** the extra complication to make this rule less restrictive is probably ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] */ | | | | > | | | > > > > | < | 101542 101543 101544 101545 101546 101547 101548 101549 101550 101551 101552 101553 101554 101555 101556 101557 101558 101559 101560 101561 101562 101563 101564 101565 101566 101567 101568 101569 101570 101571 101572 101573 101574 101575 101576 101577 101578 101579 101580 101581 101582 101583 101584 101585 101586 101587 101588 101589 101590 101591 101592 |
/* Disallow the transfer optimization if the destination table constains
** any foreign key constraints. This is more restrictive than necessary.
** But the main beneficiary of the transfer optimization is the VACUUM
** command, and the VACUUM command disables foreign key constraints. So
** the extra complication to make this rule less restrictive is probably
** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
*/
if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
return 0;
}
#endif
if( (db->flags & SQLITE_CountRows)!=0 ){
return 0; /* xfer opt does not play well with PRAGMA count_changes */
}
/* If we get this far, it means that the xfer optimization is at
** least a possibility, though it might only work if the destination
** table (tab1) is initially empty.
*/
#ifdef SQLITE_TEST
sqlite3_xferopt_count++;
#endif
iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
v = sqlite3GetVdbe(pParse);
sqlite3CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
regData = sqlite3GetTempReg(pParse);
regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx );
if( (db->flags & SQLITE_Vacuum)==0 && (
(pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
)){
/* In some circumstances, we are able to run the xfer optimization
** only if the destination table is initially empty. Unless the
** SQLITE_Vacuum flag is set, this block generates code to make
** that determination. If SQLITE_Vacuum is set, then the destination
** table is always empty.
**
** Conditions under which the destination must be empty:
**
** (1) There is no INTEGER PRIMARY KEY but there are indices.
** (If the destination is not initially empty, the rowid fields
** of index entries might need to change.)
**
** (2) The destination has a unique index. (The xfer optimization
** is unable to test uniqueness.)
|
| ︙ | ︙ | |||
101150 101151 101152 101153 101154 101155 101156 101157 101158 101159 101160 101161 101162 101163 101164 101165 101166 101167 101168 101169 101170 101171 101172 101173 101174 101175 101176 101177 |
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}else{
sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
assert( pSrcIdx );
sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
VdbeComment((v, "%s", pSrcIdx->zName));
sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3ReleaseTempReg(pParse, regRowid);
| > > > > > > > > > > > > > > > > > > > > > > > > > > > | 101621 101622 101623 101624 101625 101626 101627 101628 101629 101630 101631 101632 101633 101634 101635 101636 101637 101638 101639 101640 101641 101642 101643 101644 101645 101646 101647 101648 101649 101650 101651 101652 101653 101654 101655 101656 101657 101658 101659 101660 101661 101662 101663 101664 101665 101666 101667 101668 101669 101670 101671 101672 101673 101674 101675 |
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}else{
sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
}
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
u8 useSeekResult = 0;
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
assert( pSrcIdx );
sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
VdbeComment((v, "%s", pSrcIdx->zName));
sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
if( db->flags & SQLITE_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
** collation sequence BINARY, then it can also be assumed that the
** index will be populated by inserting keys in strictly sorted
** order. In this case, instead of seeking within the b-tree as part
** of every OP_IdxInsert opcode, an OP_Last is added before the
** OP_IdxInsert to seek to the point within the b-tree where each key
** should be inserted. This is faster.
**
** If any of the indexed columns use a collation sequence other than
** BINARY, this optimization is disabled. This is because the user
** might change the definition of a collation sequence and then run
** a VACUUM command. In that case keys may not be written in strictly
** sorted order. */
for(i=0; i<pSrcIdx->nColumn; i++){
char *zColl = pSrcIdx->azColl[i];
assert( zColl!=0 );
if( sqlite3_stricmp("BINARY", zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
useSeekResult = OPFLAG_USESEEKRESULT;
sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
}
}
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
sqlite3VdbeChangeP5(v, useSeekResult);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3ReleaseTempReg(pParse, regRowid);
|
| ︙ | ︙ | |||
101213 101214 101215 101216 101217 101218 101219 | ** malloc() and make *pzErrMsg point to that message. ** ** If the SQL is a query, then for each row in the query result ** the xCallback() function is called. pArg becomes the first ** argument to xCallback(). If xCallback=NULL then no callback ** is invoked, even for queries. */ | | | 101711 101712 101713 101714 101715 101716 101717 101718 101719 101720 101721 101722 101723 101724 101725 |
** malloc() and make *pzErrMsg point to that message.
**
** If the SQL is a query, then for each row in the query result
** the xCallback() function is called. pArg becomes the first
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback routine */
void *pArg, /* First argument to xCallback() */
char **pzErrMsg /* Write error messages here */
){
int rc = SQLITE_OK; /* Return code */
|
| ︙ | ︙ | |||
102282 102283 102284 102285 102286 102287 102288 | sqlite3_vfs *pVfs = db->pVfs; void *handle; int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); char *zErrmsg = 0; const char *zEntry; char *zAltEntry = 0; void **aHandle; | | | 102780 102781 102782 102783 102784 102785 102786 102787 102788 102789 102790 102791 102792 102793 102794 |
sqlite3_vfs *pVfs = db->pVfs;
void *handle;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
const char *zEntry;
char *zAltEntry = 0;
void **aHandle;
u64 nMsg = 300 + sqlite3Strlen30(zFile);
int ii;
/* Shared library endings to try if zFile cannot be loaded as written */
static const char *azEndings[] = {
#if SQLITE_OS_WIN
"dll"
#elif defined(__APPLE__)
|
| ︙ | ︙ | |||
102325 102326 102327 102328 102329 102330 102331 |
if( zAltFile==0 ) return SQLITE_NOMEM;
handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
#endif
if( handle==0 ){
if( pzErrMsg ){
| | | 102823 102824 102825 102826 102827 102828 102829 102830 102831 102832 102833 102834 102835 102836 102837 |
if( zAltFile==0 ) return SQLITE_NOMEM;
handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
#endif
if( handle==0 ){
if( pzErrMsg ){
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"unable to open shared library [%s]", zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
}
return SQLITE_ERROR;
|
| ︙ | ︙ | |||
102351 102352 102353 102354 102355 102356 102357 |
**
** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init
** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init
*/
if( xInit==0 && zProc==0 ){
int iFile, iEntry, c;
int ncFile = sqlite3Strlen30(zFile);
| | | 102849 102850 102851 102852 102853 102854 102855 102856 102857 102858 102859 102860 102861 102862 102863 |
**
** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init
** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init
*/
if( xInit==0 && zProc==0 ){
int iFile, iEntry, c;
int ncFile = sqlite3Strlen30(zFile);
zAltEntry = sqlite3_malloc64(ncFile+30);
if( zAltEntry==0 ){
sqlite3OsDlClose(pVfs, handle);
return SQLITE_NOMEM;
}
memcpy(zAltEntry, "sqlite3_", 8);
for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
iFile++;
|
| ︙ | ︙ | |||
102373 102374 102375 102376 102377 102378 102379 |
zEntry = zAltEntry;
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
sqlite3OsDlSym(pVfs, handle, zEntry);
}
if( xInit==0 ){
if( pzErrMsg ){
nMsg += sqlite3Strlen30(zEntry);
| | | 102871 102872 102873 102874 102875 102876 102877 102878 102879 102880 102881 102882 102883 102884 102885 |
zEntry = zAltEntry;
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
sqlite3OsDlSym(pVfs, handle, zEntry);
}
if( xInit==0 ){
if( pzErrMsg ){
nMsg += sqlite3Strlen30(zEntry);
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"no entry point [%s] in shared library [%s]", zEntry, zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
}
sqlite3OsDlClose(pVfs, handle);
|
| ︙ | ︙ | |||
102408 102409 102410 102411 102412 102413 102414 | } sqlite3DbFree(db, db->aExtension); db->aExtension = aHandle; db->aExtension[db->nExtension++] = handle; return SQLITE_OK; } | | | 102906 102907 102908 102909 102910 102911 102912 102913 102914 102915 102916 102917 102918 102919 102920 |
}
sqlite3DbFree(db, db->aExtension);
db->aExtension = aHandle;
db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
}
SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
char **pzErrMsg /* Put error message here if not 0 */
){
int rc;
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
102439 102440 102441 102442 102443 102444 102445 | sqlite3DbFree(db, db->aExtension); } /* ** Enable or disable extension loading. Extension loading is disabled by ** default so as not to open security holes in older applications. */ | | | 102937 102938 102939 102940 102941 102942 102943 102944 102945 102946 102947 102948 102949 102950 102951 |
sqlite3DbFree(db, db->aExtension);
}
/*
** Enable or disable extension loading. Extension loading is disabled by
** default so as not to open security holes in older applications.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){
db->flags |= SQLITE_LoadExtension;
}else{
db->flags &= ~SQLITE_LoadExtension;
}
sqlite3_mutex_leave(db->mutex);
|
| ︙ | ︙ | |||
102472 102473 102474 102475 102476 102477 102478 |
** extensions.
**
** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER
** mutex must be held while accessing this list.
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
| | | 102970 102971 102972 102973 102974 102975 102976 102977 102978 102979 102980 102981 102982 102983 102984 |
** extensions.
**
** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER
** mutex must be held while accessing this list.
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
u32 nExt; /* Number of entries in aExt[] */
void (**aExt)(void); /* Pointers to the extension init functions */
} sqlite3Autoext = { 0, 0 };
/* The "wsdAutoext" macro will resolve to the autoextension
** state vector. If writable static data is unsupported on the target,
** we have to locate the state vector at run-time. In the more common
** case where writable static data is supported, wsdStat can refer directly
|
| ︙ | ︙ | |||
102496 102497 102498 102499 102500 102501 102502 | #endif /* ** Register a statically linked extension that is automatically ** loaded by every new database connection. */ | | | | | | 102994 102995 102996 102997 102998 102999 103000 103001 103002 103003 103004 103005 103006 103007 103008 103009 103010 103011 103012 103013 103014 103015 103016 103017 103018 103019 103020 103021 103022 103023 103024 103025 103026 103027 103028 103029 |
#endif
/*
** Register a statically linked extension that is automatically
** loaded by every new database connection.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if( rc ){
return rc;
}else
#endif
{
u32 i;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
wsdAutoextInit;
sqlite3_mutex_enter(mutex);
for(i=0; i<wsdAutoext.nExt; i++){
if( wsdAutoext.aExt[i]==xInit ) break;
}
if( i==wsdAutoext.nExt ){
u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
void (**aNew)(void);
aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
if( aNew==0 ){
rc = SQLITE_NOMEM;
}else{
wsdAutoext.aExt = aNew;
wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
wsdAutoext.nExt++;
}
|
| ︙ | ︙ | |||
102541 102542 102543 102544 102545 102546 102547 | ** set of routines that is invoked for each new database connection, if it ** is currently on the list. If xInit is not on the list, then this ** routine is a no-op. ** ** Return 1 if xInit was found on the list and removed. Return 0 if xInit ** was not on the list. */ | | | | | 103039 103040 103041 103042 103043 103044 103045 103046 103047 103048 103049 103050 103051 103052 103053 103054 103055 103056 103057 103058 103059 103060 103061 103062 103063 103064 103065 103066 103067 103068 103069 103070 103071 103072 103073 103074 103075 103076 |
** set of routines that is invoked for each new database connection, if it
** is currently on the list. If xInit is not on the list, then this
** routine is a no-op.
**
** Return 1 if xInit was found on the list and removed. Return 0 if xInit
** was not on the list.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void)){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
int i;
int n = 0;
wsdAutoextInit;
sqlite3_mutex_enter(mutex);
for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
if( wsdAutoext.aExt[i]==xInit ){
wsdAutoext.nExt--;
wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
n++;
break;
}
}
sqlite3_mutex_leave(mutex);
return n;
}
/*
** Reset the automatic extension loading mechanism.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize()==SQLITE_OK )
#endif
{
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
|
| ︙ | ︙ | |||
102587 102588 102589 102590 102591 102592 102593 |
/*
** Load all automatic extensions.
**
** If anything goes wrong, set an error in the database connection.
*/
SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
| | | 103085 103086 103087 103088 103089 103090 103091 103092 103093 103094 103095 103096 103097 103098 103099 |
/*
** Load all automatic extensions.
**
** If anything goes wrong, set an error in the database connection.
*/
SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
u32 i;
int go = 1;
int rc;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
wsdAutoextInit;
if( wsdAutoext.nExt==0 ){
/* Common case: early out without every having to acquire a mutex */
|
| ︙ | ︙ | |||
103251 103252 103253 103254 103255 103256 103257 |
#endif /* SQLITE_PAGER_PRAGMAS */
/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
Vdbe *v = sqlite3GetVdbe(pParse);
| | | | | 103749 103750 103751 103752 103753 103754 103755 103756 103757 103758 103759 103760 103761 103762 103763 103764 103765 103766 103767 103768 103769 103770 103771 |
#endif /* SQLITE_PAGER_PRAGMAS */
/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
Vdbe *v = sqlite3GetVdbe(pParse);
int nMem = ++pParse->nMem;
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
if( pI64 ){
memcpy(pI64, &value, sizeof(value));
}
sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
}
/*
** Set the safety_level and pager flags for pager iDb. Or if iDb<0
** set these values for all pagers.
*/
|
| ︙ | ︙ | |||
103424 103425 103426 103427 103428 103429 103430 |
aFcntl[1] = zLeft;
aFcntl[2] = zRight;
aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
if( aFcntl[0] ){
| | | | | 103922 103923 103924 103925 103926 103927 103928 103929 103930 103931 103932 103933 103934 103935 103936 103937 103938 103939 103940 |
aFcntl[1] = zLeft;
aFcntl[2] = zRight;
aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
if( aFcntl[0] ){
int nMem = ++pParse->nMem;
sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
sqlite3_free(aFcntl[0]);
}
goto pragma_out;
}
if( rc!=SQLITE_NOTFOUND ){
if( aFcntl[0] ){
sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
|
| ︙ | ︙ | |||
104033 104034 104035 104036 104037 104038 104039 |
if( !zRight ){
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
}else{
| > > | | 104531 104532 104533 104534 104535 104536 104537 104538 104539 104540 104541 104542 104543 104544 104545 104546 104547 |
if( !zRight ){
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
}else{
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
if( iLevel==0 ) iLevel = 1;
pDb->safety_level = iLevel;
setAllPagerFlags(db);
}
}
break;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
| ︙ | ︙ | |||
104128 104129 104130 104131 104132 104133 104134 |
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
k = 0;
}else if( pPk==0 ){
k = 1;
}else{
| | | 104628 104629 104630 104631 104632 104633 104634 104635 104636 104637 104638 104639 104640 104641 104642 |
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
k = 0;
}else if( pPk==0 ){
k = 1;
}else{
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
}
break;
|
| ︙ | ︙ | |||
105134 105135 105136 105137 105138 105139 105140 |
return 1;
}
assert( iDb>=0 && iDb<db->nDb );
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
if( argv[1]==0 ){
corruptSchema(pData, argv[0], 0);
| | | 105634 105635 105636 105637 105638 105639 105640 105641 105642 105643 105644 105645 105646 105647 105648 |
return 1;
}
assert( iDb>=0 && iDb<db->nDb );
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
if( argv[1]==0 ){
corruptSchema(pData, argv[0], 0);
}else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
** structures that describe the table, index, or view.
*/
int rc;
sqlite3_stmt *pStmt;
|
| ︙ | ︙ | |||
105165 105166 105167 105168 105169 105170 105171 |
db->mallocFailed = 1;
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
corruptSchema(pData, argv[0], sqlite3_errmsg(db));
}
}
}
sqlite3_finalize(pStmt);
| | | | 105665 105666 105667 105668 105669 105670 105671 105672 105673 105674 105675 105676 105677 105678 105679 105680 |
db->mallocFailed = 1;
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
corruptSchema(pData, argv[0], sqlite3_errmsg(db));
}
}
}
sqlite3_finalize(pStmt);
}else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
corruptSchema(pData, argv[0], 0);
}else{
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
** constraint for a CREATE TABLE. The index should have already
** been created when we processed the CREATE TABLE. All we have
** to do here is record the root page number for that index.
*/
|
| ︙ | ︙ | |||
105844 105845 105846 105847 105848 105849 105850 | ** Two versions of the official API. Legacy and new use. In the legacy ** version, the original SQL text is not saved in the prepared statement ** and so if a schema change occurs, SQLITE_SCHEMA is returned by ** sqlite3_step(). In the new version, the original SQL text is retained ** and the statement is automatically recompiled if an schema change ** occurs. */ | | | | 106344 106345 106346 106347 106348 106349 106350 106351 106352 106353 106354 106355 106356 106357 106358 106359 106360 106361 106362 106363 106364 106365 106366 106367 106368 106369 106370 |
** Two versions of the official API. Legacy and new use. In the legacy
** version, the original SQL text is not saved in the prepared statement
** and so if a schema change occurs, SQLITE_SCHEMA is returned by
** sqlite3_step(). In the new version, the original SQL text is retained
** and the statement is automatically recompiled if an schema change
** occurs.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
int rc;
rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
int rc;
|
| ︙ | ︙ | |||
105932 105933 105934 105935 105936 105937 105938 | ** Two versions of the official API. Legacy and new use. In the legacy ** version, the original SQL text is not saved in the prepared statement ** and so if a schema change occurs, SQLITE_SCHEMA is returned by ** sqlite3_step(). In the new version, the original SQL text is retained ** and the statement is automatically recompiled if an schema change ** occurs. */ | | | | 106432 106433 106434 106435 106436 106437 106438 106439 106440 106441 106442 106443 106444 106445 106446 106447 106448 106449 106450 106451 106452 106453 106454 106455 106456 106457 106458 |
** Two versions of the official API. Legacy and new use. In the legacy
** version, the original SQL text is not saved in the prepared statement
** and so if a schema change occurs, SQLITE_SCHEMA is returned by
** sqlite3_step(). In the new version, the original SQL text is retained
** and the statement is automatically recompiled if an schema change
** occurs.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const void **pzTail /* OUT: End of parsed string */
){
int rc;
rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const void **pzTail /* OUT: End of parsed string */
){
int rc;
|
| ︙ | ︙ | |||
106073 106074 106075 106076 106077 106078 106079 |
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
Select *pNew;
Select standin;
sqlite3 *db = pParse->db;
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
| < | | 106573 106574 106575 106576 106577 106578 106579 106580 106581 106582 106583 106584 106585 106586 106587 106588 106589 106590 106591 106592 106593 106594 106595 106596 106597 106598 106599 106600 106601 106602 106603 106604 106605 106606 |
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
Select *pNew;
Select standin;
sqlite3 *db = pParse->db;
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
if( pNew==0 ){
assert( db->mallocFailed );
pNew = &standin;
memset(pNew, 0, sizeof(*pNew));
}
if( pEList==0 ){
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
}
pNew->pEList = pEList;
if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
pNew->pSrc = pSrc;
pNew->pWhere = pWhere;
pNew->pGroupBy = pGroupBy;
pNew->pHaving = pHaving;
pNew->pOrderBy = pOrderBy;
pNew->selFlags = selFlags;
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
if( db->mallocFailed ) {
clearSelect(db, pNew, pNew!=&standin);
pNew = 0;
}else{
assert( pNew->pSrc!=0 || pParse->nErr>0 );
|
| ︙ | ︙ | |||
107343 107344 107345 107346 107347 107348 107349 |
assert( pTab && pExpr->pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
| | | 107842 107843 107844 107845 107846 107847 107848 107849 107850 107851 107852 107853 107854 107855 107856 |
assert( pTab && pExpr->pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
if( iCol>=0 && iCol<pS->pEList->nExpr ){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
*/
NameContext sNC;
Expr *p = pS->pEList->a[iCol].pExpr;
sNC.pSrcList = pS->pSrc;
|
| ︙ | ︙ | |||
107663 107664 107665 107666 107667 107668 107669 |
assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
if( db->mallocFailed ) return;
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
p = a[i].pExpr;
| > | > | | 108162 108163 108164 108165 108166 108167 108168 108169 108170 108171 108172 108173 108174 108175 108176 108177 108178 108179 108180 108181 108182 108183 |
assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
if( db->mallocFailed ) return;
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
p = a[i].pExpr;
if( pCol->zType==0 ){
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
}
szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p);
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl && pCol->zColl==0 ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
pTab->szTabRow = sqlite3LogEst(szAll*4);
}
/*
|
| ︙ | ︙ | |||
108070 108071 108072 108073 108074 108075 108076 |
Select *p, /* The right-most of SELECTs to be coded */
SelectDest *pDest /* What to do with query results */
){
Select *pPrior;
int nExpr = p->pEList->nExpr;
int nRow = 1;
int rc = 0;
| < | | 108571 108572 108573 108574 108575 108576 108577 108578 108579 108580 108581 108582 108583 108584 108585 |
Select *p, /* The right-most of SELECTs to be coded */
SelectDest *pDest /* What to do with query results */
){
Select *pPrior;
int nExpr = p->pEList->nExpr;
int nRow = 1;
int rc = 0;
assert( p->selFlags & SF_MultiValue );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
assert( p->pLimit==0 );
assert( p->pOffset==0 );
if( p->pEList->nExpr!=nExpr ){
selectWrongNumTermsError(pParse, p);
|
| ︙ | ︙ | |||
108180 108181 108182 108183 108184 108185 108186 |
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
dest.eDest = SRT_Table;
}
/* Special handling for a compound-select that originates as a VALUES clause.
*/
| | | 108680 108681 108682 108683 108684 108685 108686 108687 108688 108689 108690 108691 108692 108693 108694 |
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
dest.eDest = SRT_Table;
}
/* Special handling for a compound-select that originates as a VALUES clause.
*/
if( p->selFlags & SF_MultiValue ){
rc = multiSelectValues(pParse, p, &dest);
goto multi_select_end;
}
/* Make sure all SELECTs in the statement have the same number of elements
** in their result sets.
*/
|
| ︙ | ︙ | |||
108565 108566 108567 108568 108569 108570 108571 |
#ifndef SQLITE_OMIT_SUBQUERY
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
** then there should be a single item on the stack. Write this
** item into the set table with bogus data.
*/
case SRT_Set: {
int r1;
| | | 109065 109066 109067 109068 109069 109070 109071 109072 109073 109074 109075 109076 109077 109078 109079 |
#ifndef SQLITE_OMIT_SUBQUERY
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
** then there should be a single item on the stack. Write this
** item into the set table with bogus data.
*/
case SRT_Set: {
int r1;
assert( pIn->nSdst==1 || pParse->nErr>0 );
pDest->affSdst =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
|
| ︙ | ︙ | |||
108591 108592 108593 108594 108595 108596 108597 |
#endif
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
| | | | 109091 109092 109093 109094 109095 109096 109097 109098 109099 109100 109101 109102 109103 109104 109105 109106 109107 109108 109109 109110 109111 109112 109113 109114 109115 109116 109117 109118 109119 109120 |
#endif
/* If this is a scalar select that is part of an expression, then
** store the results in the appropriate memory cell and break out
** of the scan loop.
*/
case SRT_Mem: {
assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
/* The LIMIT clause will jump out of the loop for us */
break;
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
/* The results are stored in a sequence of registers
** starting at pDest->iSdst. Then the co-routine yields.
*/
case SRT_Coroutine: {
if( pDest->iSdst==0 ){
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
pDest->nSdst = pIn->nSdst;
}
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
break;
}
/* If none of the above, then the result destination must be
** SRT_Output. This routine is never called with any other
** destination other than the ones handled above or SRT_Output.
|
| ︙ | ︙ | |||
108822 108823 108824 108825 108826 108827 108828 |
** to the right and the left are evaluated, they use the correct
** collation.
*/
aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
| | | > > | 109322 109323 109324 109325 109326 109327 109328 109329 109330 109331 109332 109333 109334 109335 109336 109337 109338 109339 |
** to the right and the left are evaluated, they use the correct
** collation.
*/
aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
assert( pItem->u.x.iOrderByCol>0 );
/* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
** but only for well-formed SELECT statements. */
testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
}else{
pKeyMerge = 0;
}
|
| ︙ | ︙ | |||
109033 109034 109035 109036 109037 109038 109039 | } p->pPrior = pPrior; pPrior->pNext = p; /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ explainComposite(pParse, p->op, iSub1, iSub2, 0); | | | 109535 109536 109537 109538 109539 109540 109541 109542 109543 109544 109545 109546 109547 109548 109549 | } p->pPrior = pPrior; pPrior->pNext = p; /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ explainComposite(pParse, p->op, iSub1, iSub2, 0); return pParse->nErr!=0; } #endif #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Forward Declarations */ static void substExprList(sqlite3*, ExprList*, int, ExprList*); static void substSelect(sqlite3*, Select *, int, ExprList *); |
| ︙ | ︙ | |||
109845 109846 109847 109848 109849 109850 109851 109852 109853 109854 109855 109856 109857 109858 109859 | p->op = TK_SELECT; p->pWhere = 0; pNew->pGroupBy = 0; pNew->pHaving = 0; pNew->pOrderBy = 0; p->pPrior = 0; p->pNext = 0; p->selFlags &= ~SF_Compound; assert( pNew->pPrior!=0 ); pNew->pPrior->pNext = pNew; pNew->pLimit = 0; pNew->pOffset = 0; return WRC_Continue; } | > > > | 110347 110348 110349 110350 110351 110352 110353 110354 110355 110356 110357 110358 110359 110360 110361 110362 110363 110364 | p->op = TK_SELECT; p->pWhere = 0; pNew->pGroupBy = 0; pNew->pHaving = 0; pNew->pOrderBy = 0; p->pPrior = 0; p->pNext = 0; p->pWith = 0; p->selFlags &= ~SF_Compound; assert( (p->selFlags & SF_Converted)==0 ); p->selFlags |= SF_Converted; assert( pNew->pPrior!=0 ); pNew->pPrior->pNext = pNew; pNew->pLimit = 0; pNew->pOffset = 0; return WRC_Continue; } |
| ︙ | ︙ | |||
110381 110382 110383 110384 110385 110386 110387 |
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
if( pParse->hasCompound ){
w.xSelectCallback = convertCompoundSelectToSubquery;
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
| | | 110886 110887 110888 110889 110890 110891 110892 110893 110894 110895 110896 110897 110898 110899 110900 |
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
if( pParse->hasCompound ){
w.xSelectCallback = convertCompoundSelectToSubquery;
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
if( (pSelect->selFlags & SF_MultiValue)==0 ){
w.xSelectCallback2 = selectPopWith;
}
sqlite3WalkSelect(&w, pSelect);
}
#ifndef SQLITE_OMIT_SUBQUERY
|
| ︙ | ︙ | |||
110567 110568 110569 110570 110571 110572 110573 |
sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP);
}else{
nArg = 0;
regAgg = 0;
}
if( pF->iDistinct>=0 ){
addrNext = sqlite3VdbeMakeLabel(v);
| | > | 111072 111073 111074 111075 111076 111077 111078 111079 111080 111081 111082 111083 111084 111085 111086 111087 |
sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP);
}else{
nArg = 0;
regAgg = 0;
}
if( pF->iDistinct>=0 ){
addrNext = sqlite3VdbeMakeLabel(v);
testcase( nArg==0 ); /* Error condition */
testcase( nArg>1 ); /* Also an error */
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
}
if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl = 0;
struct ExprList_item *pItem;
int j;
assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */
|
| ︙ | ︙ | |||
111442 111443 111444 111445 111446 111447 111448 |
generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
}
/* Jump here to skip this query
*/
sqlite3VdbeResolveLabel(v, iEnd);
| > | < < | | 111948 111949 111950 111951 111952 111953 111954 111955 111956 111957 111958 111959 111960 111961 111962 111963 111964 |
generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
}
/* Jump here to skip this query
*/
sqlite3VdbeResolveLabel(v, iEnd);
/* The SELECT has been coded. If there is an error in the Parse structure,
** set the return code to 1. Otherwise 0. */
rc = (pParse->nErr>0);
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
*/
select_end:
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
|
| ︙ | ︙ | |||
111496 111497 111498 111499 111500 111501 111502 |
int i;
pView = sqlite3TreeViewPush(pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
StrAccum x;
char zLine[100];
| | | 112001 112002 112003 112004 112005 112006 112007 112008 112009 112010 112011 112012 112013 112014 112015 |
int i;
pView = sqlite3TreeViewPush(pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
for(i=0; i<p->pSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3XPrintf(&x, 0, " %s", pItem->zName);
}
if( pItem->pTab ){
|
| ︙ | ︙ | |||
111655 111656 111657 111658 111659 111660 111661 |
*/
if( argv!=0 ){
for(i=0; i<nCol; i++){
if( argv[i]==0 ){
z = 0;
}else{
int n = sqlite3Strlen30(argv[i])+1;
| | | 112160 112161 112162 112163 112164 112165 112166 112167 112168 112169 112170 112171 112172 112173 112174 |
*/
if( argv!=0 ){
for(i=0; i<nCol; i++){
if( argv[i]==0 ){
z = 0;
}else{
int n = sqlite3Strlen30(argv[i])+1;
z = sqlite3_malloc64( n );
if( z==0 ) goto malloc_failed;
memcpy(z, argv[i], n);
}
p->azResult[p->nData++] = z;
}
p->nRow++;
}
|
| ︙ | ︙ | |||
111680 111681 111682 111683 111684 111685 111686 | ** at the conclusion of the call. ** ** The result that is written to ***pazResult is held in memory obtained ** from malloc(). But the caller cannot free this memory directly. ** Instead, the entire table should be passed to sqlite3_free_table() when ** the calling procedure is finished using it. */ | | | 112185 112186 112187 112188 112189 112190 112191 112192 112193 112194 112195 112196 112197 112198 112199 |
** at the conclusion of the call.
**
** The result that is written to ***pazResult is held in memory obtained
** from malloc(). But the caller cannot free this memory directly.
** Instead, the entire table should be passed to sqlite3_free_table() when
** the calling procedure is finished using it.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
char ***pazResult, /* Write the result table here */
int *pnRow, /* Write the number of rows in the result here */
int *pnColumn, /* Write the number of columns of result here */
char **pzErrMsg /* Write error messages here */
){
|
| ︙ | ︙ | |||
111704 111705 111706 111707 111708 111709 111710 | if( pzErrMsg ) *pzErrMsg = 0; res.zErrMsg = 0; res.nRow = 0; res.nColumn = 0; res.nData = 1; res.nAlloc = 20; res.rc = SQLITE_OK; | | | 112209 112210 112211 112212 112213 112214 112215 112216 112217 112218 112219 112220 112221 112222 112223 |
if( pzErrMsg ) *pzErrMsg = 0;
res.zErrMsg = 0;
res.nRow = 0;
res.nColumn = 0;
res.nData = 1;
res.nAlloc = 20;
res.rc = SQLITE_OK;
res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM;
}
res.azResult[0] = 0;
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
|
| ︙ | ︙ | |||
111732 111733 111734 111735 111736 111737 111738 |
sqlite3_free(res.zErrMsg);
if( rc!=SQLITE_OK ){
sqlite3_free_table(&res.azResult[1]);
return rc;
}
if( res.nAlloc>res.nData ){
char **azNew;
| | | | 112237 112238 112239 112240 112241 112242 112243 112244 112245 112246 112247 112248 112249 112250 112251 112252 112253 112254 112255 112256 112257 112258 112259 112260 112261 112262 112263 112264 112265 112266 112267 112268 |
sqlite3_free(res.zErrMsg);
if( rc!=SQLITE_OK ){
sqlite3_free_table(&res.azResult[1]);
return rc;
}
if( res.nAlloc>res.nData ){
char **azNew;
azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
return SQLITE_NOMEM;
}
res.azResult = azNew;
}
*pazResult = &res.azResult[1];
if( pnColumn ) *pnColumn = res.nColumn;
if( pnRow ) *pnRow = res.nRow;
return rc;
}
/*
** This routine frees the space the sqlite3_get_table() malloced.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_free_table(
char **azResult /* Result returned from sqlite3_get_table() */
){
if( azResult ){
int i, n;
azResult--;
assert( azResult!=0 );
n = SQLITE_PTR_TO_INT(azResult[0]);
|
| ︙ | ︙ | |||
111960 111961 111962 111963 111964 111965 111966 |
}
goto trigger_cleanup;
}
/* Do not create a trigger on a system table */
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
| < | 112465 112466 112467 112468 112469 112470 112471 112472 112473 112474 112475 112476 112477 112478 |
}
goto trigger_cleanup;
}
/* Do not create a trigger on a system table */
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
goto trigger_cleanup;
}
/* INSTEAD of triggers are only for views and views only support INSTEAD
** of triggers.
*/
if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
|
| ︙ | ︙ | |||
112140 112141 112142 112143 112144 112145 112146 |
static TriggerStep *triggerStepAllocate(
sqlite3 *db, /* Database connection */
u8 op, /* Trigger opcode */
Token *pName /* The target name */
){
TriggerStep *pTriggerStep;
| | > | < | 112644 112645 112646 112647 112648 112649 112650 112651 112652 112653 112654 112655 112656 112657 112658 112659 112660 112661 112662 112663 |
static TriggerStep *triggerStepAllocate(
sqlite3 *db, /* Database connection */
u8 op, /* Trigger opcode */
Token *pName /* The target name */
){
TriggerStep *pTriggerStep;
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
if( pTriggerStep ){
char *z = (char*)&pTriggerStep[1];
memcpy(z, pName->z, pName->n);
sqlite3Dequote(z);
pTriggerStep->zTarget = z;
pTriggerStep->op = op;
}
return pTriggerStep;
}
/*
** Build a trigger step out of an INSERT statement. Return a pointer
|
| ︙ | ︙ | |||
112428 112429 112430 112431 112432 112433 112434 |
if( pMask ){
*pMask = mask;
}
return (mask ? pList : 0);
}
/*
| | > | | | < | | 112932 112933 112934 112935 112936 112937 112938 112939 112940 112941 112942 112943 112944 112945 112946 112947 112948 112949 112950 112951 112952 112953 112954 112955 112956 112957 112958 112959 112960 112961 112962 112963 112964 112965 112966 112967 112968 112969 |
if( pMask ){
*pMask = mask;
}
return (mask ? pList : 0);
}
/*
** Convert the pStep->zTarget string into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
** forming the SrcList. This prevents a trigger in one database from
** referring to a target in another database. An exception is when the
** trigger is in TEMP in which case it can refer to any other database it
** wants.
*/
static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
sqlite3 *db = pParse->db;
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
assert( iDb<db->nDb );
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
}
}
return pSrc;
}
/*
|
| ︙ | ︙ | |||
112563 112564 112565 112566 112567 112568 112569 112570 112571 112572 112573 112574 112575 112576 |
*/
static void transferParseError(Parse *pTo, Parse *pFrom){
assert( pFrom->zErrMsg==0 || pFrom->nErr );
assert( pTo->zErrMsg==0 || pTo->nErr );
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
}else{
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
}
}
/*
** Create and populate a new TriggerPrg object with a sub-program
| > | 113067 113068 113069 113070 113071 113072 113073 113074 113075 113076 113077 113078 113079 113080 113081 |
*/
static void transferParseError(Parse *pTo, Parse *pFrom){
assert( pFrom->zErrMsg==0 || pFrom->nErr );
assert( pTo->zErrMsg==0 || pTo->nErr );
if( pTo->nErr==0 ){
pTo->zErrMsg = pFrom->zErrMsg;
pTo->nErr = pFrom->nErr;
pTo->rc = pFrom->rc;
}else{
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
}
}
/*
** Create and populate a new TriggerPrg object with a sub-program
|
| ︙ | ︙ | |||
113913 113914 113915 113916 113917 113918 113919 113920 113921 113922 113923 113924 113925 113926 113927 113928 113929 113930 113931 113932 113933 |
" FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
rc = execExecSql(db, pzErrMsg,
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
"|| ' SELECT * FROM main.' || quote(name) || ';'"
"FROM main.sqlite_master "
"WHERE type = 'table' AND name!='sqlite_sequence' "
" AND coalesce(rootpage,1)>0"
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy over the sequence table
*/
rc = execExecSql(db, pzErrMsg,
"SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
"FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
| > > > > | 114418 114419 114420 114421 114422 114423 114424 114425 114426 114427 114428 114429 114430 114431 114432 114433 114434 114435 114436 114437 114438 114439 114440 114441 114442 |
" FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
assert( (db->flags & SQLITE_Vacuum)==0 );
db->flags |= SQLITE_Vacuum;
rc = execExecSql(db, pzErrMsg,
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
"|| ' SELECT * FROM main.' || quote(name) || ';'"
"FROM main.sqlite_master "
"WHERE type = 'table' AND name!='sqlite_sequence' "
" AND coalesce(rootpage,1)>0"
);
assert( (db->flags & SQLITE_Vacuum)!=0 );
db->flags &= ~SQLITE_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy over the sequence table
*/
rc = execExecSql(db, pzErrMsg,
"SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
"FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
|
| ︙ | ︙ | |||
114058 114059 114060 114061 114062 114063 114064 114065 114066 114067 114068 114069 114070 114071 |
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */
};
/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
| > > | 114567 114568 114569 114570 114571 114572 114573 114574 114575 114576 114577 114578 114579 114580 114581 114582 |
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */
VtabCtx *pPrior; /* Parent context (if any) */
int bDeclared; /* True after sqlite3_declare_vtab() is called */
};
/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
|
| ︙ | ︙ | |||
114109 114110 114111 114112 114113 114114 114115 | return rc; } /* ** External API function used to create a new virtual-table module. */ | | | | 114620 114621 114622 114623 114624 114625 114626 114627 114628 114629 114630 114631 114632 114633 114634 114635 114636 114637 114638 114639 114640 114641 114642 114643 114644 114645 114646 114647 114648 114649 |
return rc;
}
/*
** External API function used to create a new virtual-table module.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
void *pAux /* Context pointer for xCreate/xConnect */
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
#endif
return createModule(db, zName, pModule, pAux, 0);
}
/*
** External API function used to create a new virtual-table module.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
void *pAux, /* Context pointer for xCreate/xConnect */
void (*xDestroy)(void *) /* Module destructor function */
){
#ifdef SQLITE_ENABLE_API_ARMOR
|
| ︙ | ︙ | |||
114504 114505 114506 114507 114508 114509 114510 |
*/
SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
Token *pArg = &pParse->sArg;
if( pArg->z==0 ){
pArg->z = p->z;
pArg->n = p->n;
}else{
| | | | > > > > > > > > > > > > | > | > | > | > > > | 115015 115016 115017 115018 115019 115020 115021 115022 115023 115024 115025 115026 115027 115028 115029 115030 115031 115032 115033 115034 115035 115036 115037 115038 115039 115040 115041 115042 115043 115044 115045 115046 115047 115048 115049 115050 115051 115052 115053 115054 115055 115056 115057 115058 115059 115060 115061 115062 115063 115064 115065 115066 115067 115068 115069 115070 115071 115072 115073 115074 115075 115076 115077 115078 115079 115080 115081 115082 115083 115084 115085 115086 115087 115088 115089 115090 115091 115092 115093 115094 115095 115096 115097 115098 115099 115100 115101 115102 115103 115104 115105 115106 115107 115108 115109 115110 115111 115112 115113 115114 115115 115116 115117 115118 115119 115120 115121 115122 115123 115124 115125 115126 115127 115128 115129 115130 115131 115132 |
*/
SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
Token *pArg = &pParse->sArg;
if( pArg->z==0 ){
pArg->z = p->z;
pArg->n = p->n;
}else{
assert(pArg->z <= p->z);
pArg->n = (int)(&p->z[p->n] - pArg->z);
}
}
/*
** Invoke a virtual table constructor (either xCreate or xConnect). The
** pointer to the function to invoke is passed as the fourth parameter
** to this procedure.
*/
static int vtabCallConstructor(
sqlite3 *db,
Table *pTab,
Module *pMod,
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
VtabCtx sCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
char *zErr = 0;
char *zModuleName;
int iDb;
VtabCtx *pCtx;
/* Check that the virtual-table is not already being initialized */
for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
if( pCtx->pTab==pTab ){
*pzErr = sqlite3MPrintf(db,
"vtable constructor called recursively: %s", pTab->zName
);
return SQLITE_LOCKED;
}
}
zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
if( !zModuleName ){
return SQLITE_NOMEM;
}
pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
if( !pVTable ){
sqlite3DbFree(db, zModuleName);
return SQLITE_NOMEM;
}
pVTable->db = db;
pVTable->pMod = pMod;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pTab->azModuleArg[1] = db->aDb[iDb].zName;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
sCtx.pPrior = db->pVtabCtx;
sCtx.bDeclared = 0;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = sCtx.pPrior;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
assert( sCtx.pTab==pTab );
if( SQLITE_OK!=rc ){
if( zErr==0 ){
*pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
}else {
*pzErr = sqlite3MPrintf(db, "%s", zErr);
sqlite3_free(zErr);
}
sqlite3DbFree(db, pVTable);
}else if( ALWAYS(pVTable->pVtab) ){
/* Justification of ALWAYS(): A correct vtab constructor must allocate
** the sqlite3_vtab object if successful. */
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1;
if( sCtx.bDeclared==0 ){
const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
sqlite3VtabUnlock(pVTable);
rc = SQLITE_ERROR;
}else{
int iCol;
u8 oooHidden = 0;
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->pVTable. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
** the type string. */
pVTable->pNext = pTab->pVTable;
pTab->pVTable = pVTable;
for(iCol=0; iCol<pTab->nCol; iCol++){
char *zType = pTab->aCol[iCol].zType;
int nType;
int i = 0;
if( !zType ){
pTab->tabFlags |= oooHidden;
continue;
}
nType = sqlite3Strlen30(zType);
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
for(i=0; i<nType; i++){
if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
&& (zType[i+7]=='\0' || zType[i+7]==' ')
){
i++;
|
| ︙ | ︙ | |||
114612 114613 114614 114615 114616 114617 114618 114619 114620 114621 114622 114623 114624 114625 |
zType[j] = zType[j+nDel];
}
if( zType[i]=='\0' && i>0 ){
assert(zType[i-1]==' ');
zType[i-1] = '\0';
}
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
}
}
}
}
sqlite3DbFree(db, zModuleName);
return rc;
| > > > | 115141 115142 115143 115144 115145 115146 115147 115148 115149 115150 115151 115152 115153 115154 115155 115156 115157 |
zType[j] = zType[j+nDel];
}
if( zType[i]=='\0' && i>0 ){
assert(zType[i-1]==' ');
zType[i-1] = '\0';
}
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
oooHidden = TF_OOOHidden;
}else{
pTab->tabFlags |= oooHidden;
}
}
}
}
sqlite3DbFree(db, zModuleName);
return rc;
|
| ︙ | ︙ | |||
114739 114740 114741 114742 114743 114744 114745 | } /* ** This function is used to set the schema of a virtual table. It is only ** valid to call this function from within the xCreate() or xConnect() of a ** virtual table module. */ | | > < | > > | 115271 115272 115273 115274 115275 115276 115277 115278 115279 115280 115281 115282 115283 115284 115285 115286 115287 115288 115289 115290 115291 115292 115293 115294 115295 115296 115297 115298 115299 115300 115301 115302 115303 115304 |
}
/*
** This function is used to set the schema of a virtual table. It is only
** valid to call this function from within the xCreate() or xConnect() of a
** virtual table module.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
VtabCtx *pCtx;
Parse *pParse;
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
pCtx = db->pVtabCtx;
if( !pCtx || pCtx->bDeclared ){
sqlite3Error(db, SQLITE_MISUSE);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT;
}
pTab = pCtx->pTab;
assert( (pTab->tabFlags & TF_Virtual)!=0 );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
rc = SQLITE_NOMEM;
}else{
pParse->declareVtab = 1;
|
| ︙ | ︙ | |||
114779 114780 114781 114782 114783 114784 114785 |
){
if( !pTab->aCol ){
pTab->aCol = pParse->pNewTable->aCol;
pTab->nCol = pParse->pNewTable->nCol;
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
| | | 115313 115314 115315 115316 115317 115318 115319 115320 115321 115322 115323 115324 115325 115326 115327 |
){
if( !pTab->aCol ){
pTab->aCol = pParse->pNewTable->aCol;
pTab->nCol = pParse->pNewTable->nCol;
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
pCtx->bDeclared = 1;
}else{
sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
rc = SQLITE_ERROR;
}
pParse->declareVtab = 0;
|
| ︙ | ︙ | |||
114973 114974 114975 114976 114977 114978 114979 |
** function immediately. If all calls to virtual table methods are successful,
** SQLITE_OK is returned.
*/
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
| | | 115507 115508 115509 115510 115511 115512 115513 115514 115515 115516 115517 115518 115519 115520 115521 |
** function immediately. If all calls to virtual table methods are successful,
** SQLITE_OK is returned.
*/
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
int rc = SQLITE_OK;
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
assert( iSavepoint>=-1 );
if( db->aVTrans ){
int i;
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
VTable *pVTab = db->aVTrans[i];
const sqlite3_module *pMod = pVTab->pMod->pModule;
if( pVTab->pVtab && pMod->iVersion>=2 ){
int (*xMethod)(sqlite3_vtab *, int);
|
| ︙ | ︙ | |||
115091 115092 115093 115094 115095 115096 115097 |
Table **apVtabLock;
assert( IsVirtual(pTab) );
for(i=0; i<pToplevel->nVtabLock; i++){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
| | | | | 115625 115626 115627 115628 115629 115630 115631 115632 115633 115634 115635 115636 115637 115638 115639 115640 115641 115642 115643 115644 115645 115646 115647 115648 115649 115650 115651 115652 115653 115654 115655 115656 115657 115658 115659 115660 115661 115662 115663 115664 115665 115666 115667 115668 115669 115670 115671 115672 115673 |
Table **apVtabLock;
assert( IsVirtual(pTab) );
for(i=0; i<pToplevel->nVtabLock; i++){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
if( apVtabLock ){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
}else{
pToplevel->db->mallocFailed = 1;
}
}
/*
** Return the ON CONFLICT resolution mode in effect for the virtual
** table update operation currently in progress.
**
** The results of this routine are undefined unless it is called from
** within an xUpdate method.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
static const unsigned char aMap[] = {
SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
};
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
assert( OE_Ignore==4 && OE_Replace==5 );
assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
return (int)aMap[db->vtabOnConflict-1];
}
/*
** Call from within the xCreate() or xConnect() methods to provide
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
115890 115891 115892 115893 115894 115895 115896 115897 |
** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array. The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
pWC->op = op;
| > | | | | | 116424 116425 116426 116427 116428 116429 116430 116431 116432 116433 116434 116435 116436 116437 116438 116439 116440 116441 116442 116443 116444 116445 |
** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array. The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
pWC->op = op;
if( pE2==0 ) return;
if( pE2->op!=op ){
whereClauseInsert(pWC, pExpr, 0);
}else{
whereSplit(pWC, pE2->pLeft, op);
whereSplit(pWC, pE2->pRight, op);
}
}
/*
** Initialize a WhereMaskSet object
*/
#define initMaskSet(P) (P)->n=0
|
| ︙ | ︙ | |||
117167 117168 117169 117170 117171 117172 117173 |
for(i=0; i<pList->nExpr; i++){
Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
if( p->op==TK_COLUMN
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
| | | 117702 117703 117704 117705 117706 117707 117708 117709 117710 117711 117712 117713 117714 117715 117716 |
for(i=0; i<pList->nExpr; i++){
Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
if( p->op==TK_COLUMN
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
}
return -1;
}
|
| ︙ | ︙ | |||
117441 117442 117443 117444 117445 117446 117447 |
testcase( iCol==BMS-1 );
testcase( iCol==BMS );
if( (idxCols & cMask)==0 ){
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
| | | 117976 117977 117978 117979 117980 117981 117982 117983 117984 117985 117986 117987 117988 117989 117990 |
testcase( iCol==BMS-1 );
testcase( iCol==BMS );
if( (idxCols & cMask)==0 ){
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
n++;
}
}
}
assert( (u32)n==pLoop->u.btree.nEq );
/* Add additional columns needed to make the automatic index into
|
| ︙ | ︙ | |||
118737 118738 118739 118740 118741 118742 118743 |
flags = pLoop->wsFlags;
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
| | < | 119272 119273 119274 119275 119276 119277 119278 119279 119280 119281 119282 119283 119284 119285 119286 |
flags = pLoop->wsFlags;
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;
isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
if( pItem->pSelect ){
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
}else{
sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
}
|
| ︙ | ︙ | |||
119937 119938 119939 119940 119941 119942 119943 119944 119945 119946 119947 119948 119949 119950 |
}
/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
if( ALWAYS(pWInfo) ){
whereClauseClear(&pWInfo->sWC);
while( pWInfo->pLoops ){
WhereLoop *p = pWInfo->pLoops;
pWInfo->pLoops = p->pNextLoop;
whereLoopDelete(db, p);
}
sqlite3DbFree(db, pWInfo);
| > > > > > > > | 120471 120472 120473 120474 120475 120476 120477 120478 120479 120480 120481 120482 120483 120484 120485 120486 120487 120488 120489 120490 120491 |
}
/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
if( ALWAYS(pWInfo) ){
int i;
for(i=0; i<pWInfo->nLevel; i++){
WhereLevel *pLevel = &pWInfo->a[i];
if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
}
whereClauseClear(&pWInfo->sWC);
while( pWInfo->pLoops ){
WhereLoop *p = pWInfo->pLoops;
pWInfo->pLoops = p->pNextLoop;
whereLoopDelete(db, p);
}
sqlite3DbFree(db, pWInfo);
|
| ︙ | ︙ | |||
120416 120417 120418 120419 120420 120421 120422 |
}
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
** changes "x IN (?)" into "x=?". */
}else if( eOp & (WO_EQ) ){
pNew->wsFlags |= WHERE_COLUMN_EQ;
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
| | | 120957 120958 120959 120960 120961 120962 120963 120964 120965 120966 120967 120968 120969 120970 120971 |
}
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
** changes "x IN (?)" into "x=?". */
}else if( eOp & (WO_EQ) ){
pNew->wsFlags |= WHERE_COLUMN_EQ;
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
if( iCol>=0 && pProbe->uniqNotNull==0 ){
pNew->wsFlags |= WHERE_UNQ_WANTED;
}else{
pNew->wsFlags |= WHERE_ONEROW;
}
}
}else if( eOp & WO_ISNULL ){
pNew->wsFlags |= WHERE_COLUMN_NULL;
|
| ︙ | ︙ | |||
121876 121877 121878 121879 121880 121881 121882 |
}
}else{
pWInfo->nOBSat = pFrom->isOrdered;
if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
pWInfo->revMask = pFrom->revLoop;
}
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
| | | 122417 122418 122419 122420 122421 122422 122423 122424 122425 122426 122427 122428 122429 122430 122431 |
}
}else{
pWInfo->nOBSat = pFrom->isOrdered;
if( pWInfo->nOBSat<0 ) pWInfo->nOBSat = 0;
pWInfo->revMask = pFrom->revLoop;
}
if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
&& pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
){
Bitmask revMask = 0;
int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy,
pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
);
assert( pWInfo->sorted==0 );
if( nOrder==pWInfo->pOrderBy->nExpr ){
|
| ︙ | ︙ | |||
122281 122282 122283 122284 122285 122286 122287 |
pWInfo->revMask = (Bitmask)(-1);
}
if( pParse->nErr || NEVER(db->mallocFailed) ){
goto whereBeginError;
}
#ifdef WHERETRACE_ENABLED /* !=0 */
if( sqlite3WhereTrace ){
| < | 122822 122823 122824 122825 122826 122827 122828 122829 122830 122831 122832 122833 122834 122835 |
pWInfo->revMask = (Bitmask)(-1);
}
if( pParse->nErr || NEVER(db->mallocFailed) ){
goto whereBeginError;
}
#ifdef WHERETRACE_ENABLED /* !=0 */
if( sqlite3WhereTrace ){
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
if( pWInfo->nOBSat>0 ){
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
}
switch( pWInfo->eDistinct ){
case WHERE_DISTINCT_UNIQUE: {
sqlite3DebugPrintf(" DISTINCT=unique");
|
| ︙ | ︙ | |||
122534 122535 122536 122537 122538 122539 122540 |
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
VdbeCoverage(v);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
| < | 123074 123075 123076 123077 123078 123079 123080 123081 123082 123083 123084 123085 123086 123087 |
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
VdbeCoverage(v);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
if( pLevel->addrSkip ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
|
| ︙ | ︙ | |||
122745 122746 122747 122748 122749 122750 122751 122752 122753 122754 122755 122756 122757 122758 |
struct TrigEvent { int a; IdList * b; };
/*
** An instance of this structure holds the ATTACH key and the key type.
*/
struct AttachKey { int type; Token key; };
/* This is a utility routine used to set the ExprSpan.zStart and
** ExprSpan.zEnd values of pOut so that the span covers the complete
** range of text beginning with pStart and going to the end of pEnd.
*/
static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
pOut->zStart = pStart->z;
| > > > > > > > > > > > > > > > > > > > > > > | 123284 123285 123286 123287 123288 123289 123290 123291 123292 123293 123294 123295 123296 123297 123298 123299 123300 123301 123302 123303 123304 123305 123306 123307 123308 123309 123310 123311 123312 123313 123314 123315 123316 123317 123318 123319 |
struct TrigEvent { int a; IdList * b; };
/*
** An instance of this structure holds the ATTACH key and the key type.
*/
struct AttachKey { int type; Token key; };
/*
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
** all elements in the list. And make sure list length does not exceed
** SQLITE_LIMIT_COMPOUND_SELECT.
*/
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
if( p->pPrior ){
Select *pNext = 0, *pLoop;
int mxSelect, cnt = 0;
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
pLoop->pNext = pNext;
pLoop->selFlags |= SF_Compound;
}
if( (p->selFlags & SF_MultiValue)==0 &&
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
}
}
/* This is a utility routine used to set the ExprSpan.zStart and
** ExprSpan.zEnd values of pOut so that the span covers the complete
** range of text beginning with pStart and going to the end of pEnd.
*/
static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
pOut->zStart = pStart->z;
|
| ︙ | ︙ | |||
125062 125063 125064 125065 125066 125067 125068 |
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
}
break;
case 112: /* select ::= with selectnowith */
{
| | < < < < < < < < < < < < < | < < < < > > | 125623 125624 125625 125626 125627 125628 125629 125630 125631 125632 125633 125634 125635 125636 125637 125638 125639 125640 125641 125642 125643 125644 125645 125646 125647 125648 125649 125650 125651 125652 125653 125654 125655 125656 125657 125658 125659 125660 125661 125662 125663 125664 125665 |
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
}
break;
case 112: /* select ::= with selectnowith */
{
Select *p = yymsp[0].minor.yy3;
if( p ){
p->pWith = yymsp[-1].minor.yy59;
parserDoubleLinkSelect(pParse, p);
}else{
sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
}
yygotominor.yy3 = p;
}
break;
case 113: /* selectnowith ::= oneselect */
case 119: /* oneselect ::= values */ yytestcase(yyruleno==119);
{yygotominor.yy3 = yymsp[0].minor.yy3;}
break;
case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
Select *pRhs = yymsp[0].minor.yy3;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
x.n = 0;
parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)yymsp[-1].minor.yy328;
pRhs->pPrior = yymsp[-2].minor.yy3;
pRhs->selFlags &= ~SF_MultiValue;
if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
}
yygotominor.yy3 = pRhs;
}
break;
|
| ︙ | ︙ | |||
125152 125153 125154 125155 125156 125157 125158 |
case 120: /* values ::= VALUES LP nexprlist RP */
{
yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
}
break;
case 121: /* values ::= values COMMA LP exprlist RP */
{
| > | > > | | | 125698 125699 125700 125701 125702 125703 125704 125705 125706 125707 125708 125709 125710 125711 125712 125713 125714 125715 125716 125717 125718 125719 125720 125721 |
case 120: /* values ::= VALUES LP nexprlist RP */
{
yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
}
break;
case 121: /* values ::= values COMMA LP exprlist RP */
{
Select *pRight, *pLeft = yymsp[-4].minor.yy3;
pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
pLeft = yymsp[-4].minor.yy3;
pRight->pPrior = pLeft;
yygotominor.yy3 = pRight;
}else{
yygotominor.yy3 = pLeft;
}
}
break;
case 122: /* distinct ::= DISTINCT */
{yygotominor.yy381 = SF_Distinct;}
break;
case 123: /* distinct ::= ALL */
|
| ︙ | ︙ | |||
126962 126963 126964 126965 126966 126967 126968 |
sqlite3ErrorMsg(pParse, "interrupt");
pParse->rc = SQLITE_INTERRUPT;
goto abort_parse;
}
break;
}
case TK_ILLEGAL: {
| < | < > | > | > | 127511 127512 127513 127514 127515 127516 127517 127518 127519 127520 127521 127522 127523 127524 127525 127526 127527 127528 127529 127530 127531 127532 127533 127534 127535 127536 127537 127538 127539 127540 127541 127542 127543 127544 127545 127546 127547 127548 127549 127550 127551 127552 |
sqlite3ErrorMsg(pParse, "interrupt");
pParse->rc = SQLITE_INTERRUPT;
goto abort_parse;
}
break;
}
case TK_ILLEGAL: {
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
&pParse->sLastToken);
goto abort_parse;
}
case TK_SEMI: {
pParse->zTail = &zSql[i];
/* Fall thru into the default case */
}
default: {
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
if( pParse->rc!=SQLITE_OK ){
goto abort_parse;
}
break;
}
}
}
abort_parse:
assert( nErr==0 );
if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
pParse->zTail = &zSql[i];
}
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
}
}
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
);
sqlite3_mutex_leave(sqlite3MallocMutex());
|
| ︙ | ︙ | |||
127049 127050 127051 127052 127053 127054 127055 |
sqlite3DbFree(db, p);
}
while( pParse->pZombieTab ){
Table *p = pParse->pZombieTab;
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
| < | < | 127599 127600 127601 127602 127603 127604 127605 127606 127607 127608 127609 127610 127611 127612 127613 |
sqlite3DbFree(db, p);
}
while( pParse->pZombieTab ){
Table *p = pParse->pZombieTab;
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
}
/************** End of tokenize.c ********************************************/
/************** Begin file complete.c ****************************************/
/*
** 2001 September 15
|
| ︙ | ︙ | |||
127159 127160 127161 127162 127163 127164 127165 | ** Whitespace never causes a state transition and is always ignored. ** This means that a SQL string of all whitespace is invalid. ** ** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed ** to recognize the end of a trigger can be omitted. All we have to do ** is look for a semicolon that is not part of an string or comment. */ | | | 127707 127708 127709 127710 127711 127712 127713 127714 127715 127716 127717 127718 127719 127720 127721 |
** Whitespace never causes a state transition and is always ignored.
** This means that a SQL string of all whitespace is invalid.
**
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** to recognize the end of a trigger can be omitted. All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
#ifndef SQLITE_OMIT_TRIGGER
/* A complex statement machine used to detect the end of a CREATE TRIGGER
** statement. This is the normal case.
*/
|
| ︙ | ︙ | |||
127324 127325 127326 127327 127328 127329 127330 | #ifndef SQLITE_OMIT_UTF16 /* ** This routine is the same as the sqlite3_complete() routine described ** above, except that the parameter is required to be UTF-16 encoded, not ** UTF-8. */ | | | | 127872 127873 127874 127875 127876 127877 127878 127879 127880 127881 127882 127883 127884 127885 127886 127887 127888 127889 |
#ifndef SQLITE_OMIT_UTF16
/*
** This routine is the same as the sqlite3_complete() routine described
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
sqlite3_value *pVal;
char const *zSql8;
int rc;
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if( rc ) return rc;
#endif
pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
| ︙ | ︙ | |||
127474 127475 127476 127477 127478 127479 127480 | */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; #endif /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns ** a pointer to the to the sqlite3_version[] string constant. */ | | | | | > > > > > > > > > > > > | | 128022 128023 128024 128025 128026 128027 128028 128029 128030 128031 128032 128033 128034 128035 128036 128037 128038 128039 128040 128041 128042 128043 128044 128045 128046 128047 128048 128049 128050 128051 128052 128053 128054 128055 128056 128057 128058 128059 128060 128061 128062 128063 128064 128065 128066 128067 128068 128069 128070 128071 128072 128073 128074 |
*/
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
#endif
/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
** a pointer to the to the sqlite3_version[] string constant.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; }
/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
** pointer to a string constant whose value is the same as the
** SQLITE_SOURCE_ID C preprocessor macro.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
** returns an integer equal to SQLITE_VERSION_NUMBER.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
** zero if and only if SQLite was compiled with mutexing code omitted due to
** the SQLITE_THREADSAFE compile-time option being set to 0.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
/*
** When compiling the test fixture or with debugging enabled (on Win32),
** this variable being set to non-zero will cause OSTRACE macros to emit
** extra diagnostic information.
*/
#ifdef SQLITE_HAVE_OS_TRACE
# ifndef SQLITE_DEBUG_OS_TRACE
# define SQLITE_DEBUG_OS_TRACE 0
# endif
int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
#endif
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
/*
** If the following function pointer is not NULL and if
** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
** I/O active are written using this function. These messages
** are intended for debugging activity only.
*/
SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0;
#endif
/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
**
|
| ︙ | ︙ | |||
127552 127553 127554 127555 127556 127557 127558 | ** ** * Calls to this routine from Y must block until the outer-most ** call by X completes. ** ** * Recursive calls to this routine from thread X return immediately ** without blocking. */ | | | 128112 128113 128114 128115 128116 128117 128118 128119 128120 128121 128122 128123 128124 128125 128126 |
**
** * Calls to this routine from Y must block until the outer-most
** call by X completes.
**
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
#ifdef SQLITE_EXTRA_INIT
int bRunExtraInit = 0; /* Extra initialization needed */
#endif
#ifdef SQLITE_OMIT_WSD
|
| ︙ | ︙ | |||
127713 127714 127715 127716 127717 127718 127719 | ** Undo the effects of sqlite3_initialize(). Must not be called while ** there are outstanding database connections or memory allocations or ** while any part of SQLite is otherwise in use in any thread. This ** routine is not threadsafe. But it is safe to invoke this routine ** on when SQLite is already shut down. If SQLite is already shut down ** when this routine is invoked, then this routine is a harmless no-op. */ | | | 128273 128274 128275 128276 128277 128278 128279 128280 128281 128282 128283 128284 128285 128286 128287 |
** Undo the effects of sqlite3_initialize(). Must not be called while
** there are outstanding database connections or memory allocations or
** while any part of SQLite is otherwise in use in any thread. This
** routine is not threadsafe. But it is safe to invoke this routine
** on when SQLite is already shut down. If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
#ifdef SQLITE_OMIT_WSD
int rc = sqlite3_wsd_init(4096, 24);
if( rc!=SQLITE_OK ){
return rc;
}
#endif
|
| ︙ | ︙ | |||
127767 127768 127769 127770 127771 127772 127773 | ** the SQLite library at run-time. ** ** This routine should only be called when there are no outstanding ** database connections or memory allocations. This routine is not ** threadsafe. Failure to heed these warnings can lead to unpredictable ** behavior. */ | | | 128327 128328 128329 128330 128331 128332 128333 128334 128335 128336 128337 128338 128339 128340 128341 |
** the SQLite library at run-time.
**
** This routine should only be called when there are no outstanding
** database connections or memory allocations. This routine is not
** threadsafe. Failure to heed these warnings can lead to unpredictable
** behavior.
*/
SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
va_list ap;
int rc = SQLITE_OK;
/* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
** the SQLite library is in use. */
if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;
|
| ︙ | ︙ | |||
128124 128125 128126 128127 128128 128129 128130 | } return SQLITE_OK; } /* ** Return the mutex associated with a database connection. */ | | | | 128684 128685 128686 128687 128688 128689 128690 128691 128692 128693 128694 128695 128696 128697 128698 128699 128700 128701 128702 128703 128704 128705 128706 128707 128708 128709 128710 128711 128712 |
}
return SQLITE_OK;
}
/*
** Return the mutex associated with a database connection.
*/
SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->mutex;
}
/*
** Free up as much memory as we can from the given database
** connection.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
int i;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
|
| ︙ | ︙ | |||
128161 128162 128163 128164 128165 128166 128167 | sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } /* ** Configuration settings for an individual database connection */ | | | 128721 128722 128723 128724 128725 128726 128727 128728 128729 128730 128731 128732 128733 128734 128735 |
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
/*
** Configuration settings for an individual database connection
*/
SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
switch( op ){
case SQLITE_DBCONFIG_LOOKASIDE: {
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
|
| ︙ | ︙ | |||
128280 128281 128282 128283 128284 128285 128286 | } return r; } /* ** Return the ROWID of the most recent insert */ | | | | | 128840 128841 128842 128843 128844 128845 128846 128847 128848 128849 128850 128851 128852 128853 128854 128855 128856 128857 128858 128859 128860 128861 128862 128863 128864 128865 128866 128867 128868 128869 128870 128871 128872 128873 128874 128875 128876 128877 128878 128879 128880 |
}
return r;
}
/*
** Return the ROWID of the most recent insert
*/
SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->lastRowid;
}
/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->nChange;
}
/*
** Return the number of changes since the database handle was opened.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->nTotalChange;
|
| ︙ | ︙ | |||
128448 128449 128450 128451 128452 128453 128454 | ** connection. The sqlite3_close() version returns SQLITE_BUSY and ** leaves the connection option if there are unfinalized prepared ** statements or unfinished sqlite3_backups. The sqlite3_close_v2() ** version forces the connection to become a zombie if there are ** unclosed resources, and arranges for deallocation when the last ** prepare statement or sqlite3_backup closes. */ | | | | 129008 129009 129010 129011 129012 129013 129014 129015 129016 129017 129018 129019 129020 129021 129022 129023 |
** connection. The sqlite3_close() version returns SQLITE_BUSY and
** leaves the connection option if there are unfinalized prepared
** statements or unfinished sqlite3_backups. The sqlite3_close_v2()
** version forces the connection to become a zombie if there are
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
** Close the mutex on database connection db.
**
** Furthermore, if database connection db is a zombie (meaning that there
** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
|
| ︙ | ︙ | |||
128632 128633 128634 128635 128636 128637 128638 | } } /* ** Return a static string containing the name corresponding to the error code ** specified in the argument. */ | | | 129192 129193 129194 129195 129196 129197 129198 129199 129200 129201 129202 129203 129204 129205 129206 |
}
}
/*
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
#if defined(SQLITE_NEED_ERR_NAME)
SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
for(i=0; i<2 && zName==0; i++, rc &= 0xff){
switch( rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
|
| ︙ | ︙ | |||
128856 128857 128858 128859 128860 128861 128862 | return rc; } /* ** This routine sets the busy callback for an Sqlite database to the ** given callback function with the given argument. */ | | | 129416 129417 129418 129419 129420 129421 129422 129423 129424 129425 129426 129427 129428 129429 129430 |
return rc;
}
/*
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
sqlite3 *db,
int (*xBusy)(void*,int),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
|
| ︙ | ︙ | |||
128879 128880 128881 128882 128883 128884 128885 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* ** This routine sets the progress callback for an Sqlite database to the ** given callback function with the given argument. The progress callback will ** be invoked every nOps opcodes. */ | | | 129439 129440 129441 129442 129443 129444 129445 129446 129447 129448 129449 129450 129451 129452 129453 |
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
sqlite3 *db,
int nOps,
int (*xProgress)(void*),
void *pArg
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
|
| ︙ | ︙ | |||
128910 128911 128912 128913 128914 128915 128916 | #endif /* ** This routine installs a default busy handler that waits for the ** specified number of milliseconds before returning 0. */ | | | | 129470 129471 129472 129473 129474 129475 129476 129477 129478 129479 129480 129481 129482 129483 129484 129485 129486 129487 129488 129489 129490 129491 129492 129493 129494 129495 129496 129497 129498 129499 129500 |
#endif
/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms>0 ){
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
db->busyTimeout = ms;
}else{
sqlite3_busy_handler(db, 0, 0);
}
return SQLITE_OK;
}
/*
** Cause any pending operation to stop at its earliest opportunity.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return;
}
#endif
db->u1.isInterrupted = 1;
|
| ︙ | ︙ | |||
129043 129044 129045 129046 129047 129048 129049 | p->nArg = (u16)nArg; return SQLITE_OK; } /* ** Create new user functions. */ | | | | 129603 129604 129605 129606 129607 129608 129609 129610 129611 129612 129613 129614 129615 129616 129617 129618 129619 129620 129621 129622 129623 129624 129625 129626 129627 129628 129629 129630 129631 |
p->nArg = (u16)nArg;
return SQLITE_OK;
}
/*
** Create new user functions.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
sqlite3 *db,
const char *zFunc,
int nArg,
int enc,
void *p,
void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
void (*xStep)(sqlite3_context*,int,sqlite3_value **),
void (*xFinal)(sqlite3_context*)
){
return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
xFinal, 0);
}
SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunc,
int nArg,
int enc,
void *p,
void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
void (*xStep)(sqlite3_context*,int,sqlite3_value **),
|
| ︙ | ︙ | |||
129100 129101 129102 129103 129104 129105 129106 | out: rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; } #ifndef SQLITE_OMIT_UTF16 | | | 129660 129661 129662 129663 129664 129665 129666 129667 129668 129669 129670 129671 129672 129673 129674 | out: rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; } #ifndef SQLITE_OMIT_UTF16 SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *p, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), |
| ︙ | ︙ | |||
129140 129141 129142 129143 129144 129145 129146 | ** a new one that always throws a run-time error. ** ** When virtual tables intend to provide an overloaded function, they ** should call this routine to make sure the global function exists. ** A global function must exist in order for name resolution to work ** properly. */ | | | 129700 129701 129702 129703 129704 129705 129706 129707 129708 129709 129710 129711 129712 129713 129714 |
** a new one that always throws a run-time error.
**
** When virtual tables intend to provide an overloaded function, they
** should call this routine to make sure the global function exists.
** A global function must exist in order for name resolution to work
** properly.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
){
int nName = sqlite3Strlen30(zName);
int rc = SQLITE_OK;
|
| ︙ | ︙ | |||
129172 129173 129174 129175 129176 129177 129178 | ** Register a trace function. The pArg from the previously registered trace ** is returned. ** ** A NULL trace function means that no tracing is executes. A non-NULL ** trace is a pointer to a function that is invoked at the start of each ** SQL statement. */ | | | 129732 129733 129734 129735 129736 129737 129738 129739 129740 129741 129742 129743 129744 129745 129746 |
** Register a trace function. The pArg from the previously registered trace
** is returned.
**
** A NULL trace function means that no tracing is executes. A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
|
| ︙ | ︙ | |||
129196 129197 129198 129199 129200 129201 129202 | ** Register a profile function. The pArg from the previously registered ** profile function is returned. ** ** A NULL profile function means that no profiling is executes. A non-NULL ** profile is a pointer to a function that is invoked at the conclusion of ** each SQL statement that is run. */ | | | 129756 129757 129758 129759 129760 129761 129762 129763 129764 129765 129766 129767 129768 129769 129770 |
** Register a profile function. The pArg from the previously registered
** profile function is returned.
**
** A NULL profile function means that no profiling is executes. A non-NULL
** profile is a pointer to a function that is invoked at the conclusion of
** each SQL statement that is run.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
sqlite3 *db,
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
|
| ︙ | ︙ | |||
129223 129224 129225 129226 129227 129228 129229 | #endif /* SQLITE_OMIT_TRACE */ /* ** Register a function to be invoked when a transaction commits. ** If the invoked function returns non-zero, then the commit becomes a ** rollback. */ | | | 129783 129784 129785 129786 129787 129788 129789 129790 129791 129792 129793 129794 129795 129796 129797 |
#endif /* SQLITE_OMIT_TRACE */
/*
** Register a function to be invoked when a transaction commits.
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
sqlite3 *db, /* Attach the hook to this database */
int (*xCallback)(void*), /* Function to invoke on each commit */
void *pArg /* Argument to the function */
){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
|
| ︙ | ︙ | |||
129248 129249 129250 129251 129252 129253 129254 | return pOld; } /* ** Register a callback to be invoked each time a row is updated, ** inserted or deleted using this database connection. */ | | | 129808 129809 129810 129811 129812 129813 129814 129815 129816 129817 129818 129819 129820 129821 129822 |
return pOld;
}
/*
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
void *pArg /* Argument to the function */
){
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
|
| ︙ | ︙ | |||
129273 129274 129275 129276 129277 129278 129279 | return pRet; } /* ** Register a callback to be invoked each time a transaction is rolled ** back by this database connection. */ | | | 129833 129834 129835 129836 129837 129838 129839 129840 129841 129842 129843 129844 129845 129846 129847 |
return pRet;
}
/*
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*), /* Callback function */
void *pArg /* Argument to the function */
){
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
|
| ︙ | ︙ | |||
129327 129328 129329 129330 129331 129332 129333 | ** nFrame parameter disables automatic checkpoints entirely. ** ** The callback registered by this function replaces any existing callback ** registered using sqlite3_wal_hook(). Likewise, registering a callback ** using sqlite3_wal_hook() disables the automatic checkpoint mechanism ** configured by this function. */ | | | | 129887 129888 129889 129890 129891 129892 129893 129894 129895 129896 129897 129898 129899 129900 129901 129902 129903 129904 129905 129906 129907 129908 129909 129910 129911 129912 129913 129914 129915 129916 129917 129918 129919 129920 129921 129922 |
** nFrame parameter disables automatic checkpoints entirely.
**
** The callback registered by this function replaces any existing callback
** registered using sqlite3_wal_hook(). Likewise, registering a callback
** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
** configured by this function.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(nFrame);
#else
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( nFrame>0 ){
sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
}else{
sqlite3_wal_hook(db, 0, 0);
}
#endif
return SQLITE_OK;
}
/*
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
*/
SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
sqlite3 *db, /* Attach the hook to this db handle */
int(*xCallback)(void *, sqlite3*, const char*, int),
void *pArg /* First argument passed to xCallback() */
){
#ifndef SQLITE_OMIT_WAL
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
|
| ︙ | ︙ | |||
129375 129376 129377 129378 129379 129380 129381 | return 0; #endif } /* ** Checkpoint database zDb. */ | | | 129935 129936 129937 129938 129939 129940 129941 129942 129943 129944 129945 129946 129947 129948 129949 |
return 0;
#endif
}
/*
** Checkpoint database zDb.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
int *pnLog, /* OUT: Size of WAL log in frames */
int *pnCkpt /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
|
| ︙ | ︙ | |||
129430 129431 129432 129433 129434 129435 129436 | /* ** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points ** to contains a zero-length string, all attached databases are ** checkpointed. */ | | | 129990 129991 129992 129993 129994 129995 129996 129997 129998 129999 130000 130001 130002 130003 130004 |
/*
** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
** to contains a zero-length string, all attached databases are
** checkpointed.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
/* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
}
#ifndef SQLITE_OMIT_WAL
/*
|
| ︙ | ︙ | |||
129519 129520 129521 129522 129523 129524 129525 | #endif } /* ** Return UTF-8 encoded English language explanation of the most recent ** error. */ | | | 130079 130080 130081 130082 130083 130084 130085 130086 130087 130088 130089 130090 130091 130092 130093 |
#endif
}
/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
return sqlite3ErrStr(SQLITE_NOMEM);
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
}
|
| ︙ | ︙ | |||
129547 129548 129549 129550 129551 129552 129553 | } #ifndef SQLITE_OMIT_UTF16 /* ** Return UTF-16 encoded English language explanation of the most recent ** error. */ | | | 130107 130108 130109 130110 130111 130112 130113 130114 130115 130116 130117 130118 130119 130120 130121 |
}
#ifndef SQLITE_OMIT_UTF16
/*
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
static const u16 outOfMem[] = {
'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
static const u16 misuse[] = {
'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ',
'r', 'o', 'u', 't', 'i', 'n', 'e', ' ',
'c', 'a', 'l', 'l', 'e', 'd', ' ',
|
| ︙ | ︙ | |||
129592 129593 129594 129595 129596 129597 129598 | } #endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). */ | | | | | 130152 130153 130154 130155 130156 130157 130158 130159 130160 130161 130162 130163 130164 130165 130166 130167 130168 130169 130170 130171 130172 130173 130174 130175 130176 130177 130178 130179 130180 130181 130182 130183 130184 130185 130186 130187 130188 130189 130190 |
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
return SQLITE_NOMEM;
}
return db->errCode & db->errMask;
}
SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
return SQLITE_NOMEM;
}
return db->errCode;
}
/*
** Return a string that describes the kind of error specified in the
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
*/
|
| ︙ | ︙ | |||
129764 129765 129766 129767 129768 129769 129770 | ** Make no changes but still report the old value if the ** new limit is negative. ** ** A new lower limit does not shrink existing constructs. ** It merely prevents new constructs that exceed the limit ** from forming. */ | | | 130324 130325 130326 130327 130328 130329 130330 130331 130332 130333 130334 130335 130336 130337 130338 |
** Make no changes but still report the old value if the
** new limit is negative.
**
** A new lower limit does not shrink existing constructs.
** It merely prevents new constructs that exceed the limit
** from forming.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return -1;
}
|
| ︙ | ︙ | |||
129857 129858 129859 129860 129861 129862 129863 |
|| sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
&& nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
){
char *zOpt;
int eState; /* Parser state when parsing URI */
int iIn; /* Input character index */
int iOut = 0; /* Output character index */
| | | | 130417 130418 130419 130420 130421 130422 130423 130424 130425 130426 130427 130428 130429 130430 130431 130432 130433 130434 130435 130436 130437 130438 |
|| sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
&& nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
){
char *zOpt;
int eState; /* Parser state when parsing URI */
int iIn; /* Input character index */
int iOut = 0; /* Output character index */
u64 nByte = nUri+2; /* Bytes of space to allocate */
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
** method that there may be extra parameters following the file-name. */
flags |= SQLITE_OPEN_URI;
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
zFile = sqlite3_malloc64(nByte);
if( !zFile ) return SQLITE_NOMEM;
iIn = 5;
#ifdef SQLITE_ALLOW_URI_AUTHORITY
if( strncmp(zUri+5, "///", 3)==0 ){
iIn = 7;
/* The following condition causes URIs with five leading / characters
|
| ︙ | ︙ | |||
130030 130031 130032 130033 130034 130035 130036 |
}
}
zOpt = &zVal[nVal+1];
}
}else{
| | | 130590 130591 130592 130593 130594 130595 130596 130597 130598 130599 130600 130601 130602 130603 130604 |
}
}
zOpt = &zVal[nVal+1];
}
}else{
zFile = sqlite3_malloc64(nUri+2);
if( !zFile ) return SQLITE_NOMEM;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
zFile[nUri+1] = '\0';
flags &= ~SQLITE_OPEN_URI;
}
|
| ︙ | ︙ | |||
130301 130302 130303 130304 130305 130306 130307 130308 130309 130310 130311 130312 130313 130314 |
#endif
#ifdef SQLITE_ENABLE_RTREE
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3RtreeInit(db);
}
#endif
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
*/
#ifdef SQLITE_DEFAULT_LOCKING_MODE
db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
| > > > > > > > | 130861 130862 130863 130864 130865 130866 130867 130868 130869 130870 130871 130872 130873 130874 130875 130876 130877 130878 130879 130880 130881 |
#endif
#ifdef SQLITE_ENABLE_RTREE
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3RtreeInit(db);
}
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
if( !db->mallocFailed && rc==SQLITE_OK){
int sqlite3_dbstat_register(sqlite3*);
rc = sqlite3_dbstat_register(db);
}
#endif
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
*/
#ifdef SQLITE_DEFAULT_LOCKING_MODE
db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
|
| ︙ | ︙ | |||
130349 130350 130351 130352 130353 130354 130355 | #endif return sqlite3ApiExit(0, rc); } /* ** Open a new database handle. */ | | | | | 130916 130917 130918 130919 130920 130921 130922 130923 130924 130925 130926 130927 130928 130929 130930 130931 130932 130933 130934 130935 130936 130937 130938 130939 130940 130941 130942 130943 130944 130945 130946 130947 130948 130949 130950 |
#endif
return sqlite3ApiExit(0, rc);
}
/*
** Open a new database handle.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_open(
const char *zFilename,
sqlite3 **ppDb
){
return openDatabase(zFilename, ppDb,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
}
SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
){
return openDatabase(filename, ppDb, (unsigned int)flags, zVfs);
}
#ifndef SQLITE_OMIT_UTF16
/*
** Open a new database handle.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_open16(
const void *zFilename,
sqlite3 **ppDb
){
char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */
sqlite3_value *pVal;
int rc;
|
| ︙ | ︙ | |||
130408 130409 130410 130411 130412 130413 130414 | return sqlite3ApiExit(0, rc); } #endif /* SQLITE_OMIT_UTF16 */ /* ** Register a new collation sequence with the database handle db. */ | | | | 130975 130976 130977 130978 130979 130980 130981 130982 130983 130984 130985 130986 130987 130988 130989 130990 130991 130992 130993 130994 130995 130996 130997 130998 130999 131000 131001 131002 |
return sqlite3ApiExit(0, rc);
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Register a new collation sequence with the database handle db.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
sqlite3* db,
const char *zName,
int enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*)
){
return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0);
}
/*
** Register a new collation sequence with the database handle db.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
sqlite3* db,
const char *zName,
int enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDel)(void*)
){
|
| ︙ | ︙ | |||
130446 130447 130448 130449 130450 130451 130452 | return rc; } #ifndef SQLITE_OMIT_UTF16 /* ** Register a new collation sequence with the database handle db. */ | | | 131013 131014 131015 131016 131017 131018 131019 131020 131021 131022 131023 131024 131025 131026 131027 |
return rc;
}
#ifndef SQLITE_OMIT_UTF16
/*
** Register a new collation sequence with the database handle db.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
sqlite3* db,
const void *zName,
int enc,
void* pCtx,
int(*xCompare)(void*,int,const void*,int,const void*)
){
int rc = SQLITE_OK;
|
| ︙ | ︙ | |||
130476 130477 130478 130479 130480 130481 130482 | } #endif /* SQLITE_OMIT_UTF16 */ /* ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. */ | | | | 131043 131044 131045 131046 131047 131048 131049 131050 131051 131052 131053 131054 131055 131056 131057 131058 131059 131060 131061 131062 131063 131064 131065 131066 131067 131068 131069 131070 131071 131072 131073 131074 131075 131076 131077 131078 |
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = xCollNeeded;
db->xCollNeeded16 = 0;
db->pCollNeededArg = pCollNeededArg;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_UTF16
/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
|
| ︙ | ︙ | |||
130519 130520 130521 130522 130523 130524 130525 | #endif /* SQLITE_OMIT_UTF16 */ #ifndef SQLITE_OMIT_DEPRECATED /* ** This function is now an anachronism. It used to be used to recover from a ** malloc() failure, but SQLite now does this automatically. */ | | | | 131086 131087 131088 131089 131090 131091 131092 131093 131094 131095 131096 131097 131098 131099 131100 131101 131102 131103 131104 131105 131106 131107 131108 131109 131110 131111 |
#endif /* SQLITE_OMIT_UTF16 */
#ifndef SQLITE_OMIT_DEPRECATED
/*
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
return SQLITE_OK;
}
#endif
/*
** Test to see whether or not the database connection is in autocommit
** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return db->autoCommit;
|
| ︙ | ︙ | |||
130582 130583 130584 130585 130586 130587 130588 | /* ** This is a convenience routine that makes sure that all thread-specific ** data for this thread has been deallocated. ** ** SQLite no longer uses thread-specific data so this routine is now a ** no-op. It is retained for historical compatibility. */ | | | | 131149 131150 131151 131152 131153 131154 131155 131156 131157 131158 131159 131160 131161 131162 131163 131164 131165 131166 131167 131168 131169 131170 131171 |
/*
** This is a convenience routine that makes sure that all thread-specific
** data for this thread has been deallocated.
**
** SQLite no longer uses thread-specific data so this routine is now a
** no-op. It is retained for historical compatibility.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
}
#endif
/*
** Return meta information about a specific column of a database table.
** See comment in sqlite3.h (sqlite.h.in) for details.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
const char *zColumnName, /* Column name */
char const **pzDataType, /* OUTPUT: Declared data type */
char const **pzCollSeq, /* OUTPUT: Collation sequence name */
int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
|
| ︙ | ︙ | |||
130708 130709 130710 130711 130712 130713 130714 | sqlite3_mutex_leave(db->mutex); return rc; } /* ** Sleep for a little while. Return the amount of time slept. */ | | | | | 131275 131276 131277 131278 131279 131280 131281 131282 131283 131284 131285 131286 131287 131288 131289 131290 131291 131292 131293 131294 131295 131296 131297 131298 131299 131300 131301 131302 131303 131304 131305 131306 131307 131308 131309 131310 131311 131312 131313 131314 131315 131316 131317 131318 |
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
sqlite3_vfs *pVfs;
int rc;
pVfs = sqlite3_vfs_find(0);
if( pVfs==0 ) return 0;
/* This function works in milliseconds, but the underlying OsSleep()
** API uses microseconds. Hence the 1000's.
*/
rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000);
return rc;
}
/*
** Enable or disable the extended result codes.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
db->errMask = onoff ? 0xffffffff : 0xff;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
/*
** Invoke the xFileControl method on a particular database.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
int rc = SQLITE_ERROR;
Btree *pBtree;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
130771 130772 130773 130774 130775 130776 130777 | sqlite3_mutex_leave(db->mutex); return rc; } /* ** Interface to the testing logic. */ | | | 131338 131339 131340 131341 131342 131343 131344 131345 131346 131347 131348 131349 131350 131351 131352 |
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** Interface to the testing logic.
*/
SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
va_list ap;
va_start(ap, op);
switch( op ){
/*
|
| ︙ | ︙ | |||
131114 131115 131116 131117 131118 131119 131120 | ** ** The zFilename argument is the filename pointer passed into the xOpen() ** method of a VFS implementation. The zParam argument is the name of the ** query parameter we seek. This routine returns the value of the zParam ** parameter if it exists. If the parameter does not exist, this routine ** returns a NULL pointer. */ | | | | | 131681 131682 131683 131684 131685 131686 131687 131688 131689 131690 131691 131692 131693 131694 131695 131696 131697 131698 131699 131700 131701 131702 131703 131704 131705 131706 131707 131708 131709 131710 131711 131712 131713 131714 131715 131716 131717 131718 131719 |
**
** The zFilename argument is the filename pointer passed into the xOpen()
** method of a VFS implementation. The zParam argument is the name of the
** query parameter we seek. This routine returns the value of the zParam
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 || zParam==0 ) return 0;
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
int x = strcmp(zFilename, zParam);
zFilename += sqlite3Strlen30(zFilename) + 1;
if( x==0 ) return zFilename;
zFilename += sqlite3Strlen30(zFilename) + 1;
}
return 0;
}
/*
** Return a boolean value for a query parameter.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
bDflt = bDflt!=0;
return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
}
/*
** Return a 64-bit integer value for a query parameter.
*/
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(
const char *zFilename, /* Filename as passed to xOpen */
const char *zParam, /* URI parameter sought */
sqlite3_int64 bDflt /* return if parameter is missing */
){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
sqlite3_int64 v;
if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){
|
| ︙ | ︙ | |||
131170 131171 131172 131173 131174 131175 131176 | return 0; } /* ** Return the filename of the database associated with a database ** connection. */ | | | | 131737 131738 131739 131740 131741 131742 131743 131744 131745 131746 131747 131748 131749 131750 131751 131752 131753 131754 131755 131756 131757 131758 131759 131760 131761 131762 131763 131764 131765 131766 131767 |
return 0;
}
/*
** Return the filename of the database associated with a database
** connection.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
pBt = sqlite3DbNameToBtree(db, zDbName);
return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
}
/*
** Return 1 if database is read-only or 0 if read/write. Return -1 if
** no such database exists.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return -1;
}
#endif
|
| ︙ | ︙ | |||
131345 131346 131347 131348 131349 131350 131351 | ** Otherwise, make arrangements to invoke xNotify when pOther drops ** its locks. ** ** Each call to this routine overrides any prior callbacks registered ** on the same "db". If xNotify==0 then any prior callbacks are immediately ** cancelled. */ | | | 131912 131913 131914 131915 131916 131917 131918 131919 131920 131921 131922 131923 131924 131925 131926 |
** Otherwise, make arrangements to invoke xNotify when pOther drops
** its locks.
**
** Each call to this routine overrides any prior callbacks registered
** on the same "db". If xNotify==0 then any prior callbacks are immediately
** cancelled.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
sqlite3 *db,
void (*xNotify)(void **, int),
void *pArg
){
int rc = SQLITE_OK;
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
132239 132240 132241 132242 132243 132244 132245 132246 132247 132248 132249 132250 132251 132252 | /* ** Macros indicating that conditional expressions are always true or ** false. */ #ifdef SQLITE_COVERAGE_TEST # define ALWAYS(x) (1) # define NEVER(X) (0) #else # define ALWAYS(x) (x) # define NEVER(x) (x) #endif /* ** Internal types used by SQLite. | > > > > > | 132806 132807 132808 132809 132810 132811 132812 132813 132814 132815 132816 132817 132818 132819 132820 132821 132822 132823 132824 | /* ** Macros indicating that conditional expressions are always true or ** false. */ #ifdef SQLITE_COVERAGE_TEST # define ALWAYS(x) (1) # define NEVER(X) (0) #elif defined(SQLITE_DEBUG) # define ALWAYS(x) sqlite3Fts3Always((x)!=0) # define NEVER(x) sqlite3Fts3Never((x)!=0) SQLITE_PRIVATE int sqlite3Fts3Always(int b); SQLITE_PRIVATE int sqlite3Fts3Never(int b); #else # define ALWAYS(x) (x) # define NEVER(x) (x) #endif /* ** Internal types used by SQLite. |
| ︙ | ︙ | |||
132639 132640 132641 132642 132643 132644 132645 132646 132647 132648 132649 132650 132651 132652 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); #define fts3GetVarint32(p, piVal) ( \ (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ ) /* fts3.c */ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); | > | 133211 133212 133213 133214 133215 133216 133217 133218 133219 133220 133221 133222 133223 133224 133225 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); #define fts3GetVarint32(p, piVal) ( \ (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ ) /* fts3.c */ SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); |
| ︙ | ︙ | |||
132727 132728 132729 132730 132731 132732 132733 132734 132735 132736 132737 132738 132739 132740 |
SQLITE_EXTENSION_INIT1
#endif
static int fts3EvalNext(Fts3Cursor *pCsr);
static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
** The number of bytes written is returned.
*/
SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
| > > > > > > > | 133300 133301 133302 133303 133304 133305 133306 133307 133308 133309 133310 133311 133312 133313 133314 133315 133316 133317 133318 133319 133320 |
SQLITE_EXTENSION_INIT1
#endif
static int fts3EvalNext(Fts3Cursor *pCsr);
static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
#ifndef SQLITE_AMALGAMATION
# if defined(SQLITE_DEBUG)
SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; }
SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; }
# endif
#endif
/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
** The number of bytes written is returned.
*/
SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
|
| ︙ | ︙ | |||
132837 132838 132839 132840 132841 132842 132843 |
if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
int iIn = 1; /* Index of next byte to read from input */
int iOut = 0; /* Index of next byte to write to output */
/* If the first byte was a '[', then the close-quote character is a ']' */
if( quote=='[' ) quote = ']';
| | | 133417 133418 133419 133420 133421 133422 133423 133424 133425 133426 133427 133428 133429 133430 133431 |
if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
int iIn = 1; /* Index of next byte to read from input */
int iOut = 0; /* Index of next byte to write to output */
/* If the first byte was a '[', then the close-quote character is a ']' */
if( quote=='[' ) quote = ']';
while( z[iIn] ){
if( z[iIn]==quote ){
if( z[iIn+1]!=quote ) break;
z[iOut++] = quote;
iIn += 2;
}else{
z[iOut++] = z[iIn++];
}
|
| ︙ | ︙ | |||
132915 132916 132917 132918 132919 132920 132921 132922 132923 132924 132925 132926 132927 132928 | /* Invoke the tokenizer destructor to free the tokenizer. */ p->pTokenizer->pModule->xDestroy(p->pTokenizer); sqlite3_free(p); return SQLITE_OK; } /* ** Construct one or more SQL statements from the format string given ** and then evaluate those statements. The success code is written ** into *pRc. ** ** If *pRc is initially non-zero then this routine is a no-op. | > > > > > > > > > > > | 133495 133496 133497 133498 133499 133500 133501 133502 133503 133504 133505 133506 133507 133508 133509 133510 133511 133512 133513 133514 133515 133516 133517 133518 133519 |
/* Invoke the tokenizer destructor to free the tokenizer. */
p->pTokenizer->pModule->xDestroy(p->pTokenizer);
sqlite3_free(p);
return SQLITE_OK;
}
/*
** Write an error message into *pzErr
*/
SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){
va_list ap;
sqlite3_free(*pzErr);
va_start(ap, zFormat);
*pzErr = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
}
/*
** Construct one or more SQL statements from the format string given
** and then evaluate those statements. The success code is written
** into *pRc.
**
** If *pRc is initially non-zero then this routine is a no-op.
|
| ︙ | ︙ | |||
133434 133435 133436 133437 133438 133439 133440 | */ static int fts3ContentColumns( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */ const char *zTbl, /* Name of content table */ const char ***pazCol, /* OUT: Malloc'd array of column names */ int *pnCol, /* OUT: Size of array *pazCol */ | | > > > > | 134025 134026 134027 134028 134029 134030 134031 134032 134033 134034 134035 134036 134037 134038 134039 134040 134041 134042 134043 134044 134045 134046 134047 134048 134049 134050 134051 134052 134053 |
*/
static int fts3ContentColumns(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */
const char *zTbl, /* Name of content table */
const char ***pazCol, /* OUT: Malloc'd array of column names */
int *pnCol, /* OUT: Size of array *pazCol */
int *pnStr, /* OUT: Bytes of string content */
char **pzErr /* OUT: error message */
){
int rc = SQLITE_OK; /* Return code */
char *zSql; /* "SELECT *" statement on zTbl */
sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */
zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
if( rc!=SQLITE_OK ){
sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db));
}
}
sqlite3_free(zSql);
if( rc==SQLITE_OK ){
const char **azCol; /* Output array */
int nStr = 0; /* Size of all column names (incl. 0x00) */
int nCol; /* Number of table columns */
|
| ︙ | ︙ | |||
133523 133524 133525 133526 133527 133528 133529 | char *zCsr; /* Space for holding column names */ int nDb; /* Bytes required to hold database name */ int nName; /* Bytes required to hold table name */ int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ const char **aCol; /* Array of column names */ sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ | | | 134118 134119 134120 134121 134122 134123 134124 134125 134126 134127 134128 134129 134130 134131 134132 | char *zCsr; /* Space for holding column names */ int nDb; /* Bytes required to hold database name */ int nName; /* Bytes required to hold table name */ int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ const char **aCol; /* Array of column names */ sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ int nIndex = 0; /* Size of aIndex[] array */ struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ /* The results of parsing supported FTS4 key=value options: */ int bNoDocsize = 0; /* True to omit %_docsize table */ int bDescIdx = 0; /* True to store descending indexes */ char *zPrefix = 0; /* Prefix parameter value (or NULL) */ char *zCompress = 0; /* compress=? parameter (or NULL) */ |
| ︙ | ︙ | |||
133611 133612 133613 133614 133615 133616 133617 |
for(iOpt=0; iOpt<SizeofArray(aFts4Opt); iOpt++){
struct Fts4Option *pOp = &aFts4Opt[iOpt];
if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){
break;
}
}
if( iOpt==SizeofArray(aFts4Opt) ){
| | | | 134206 134207 134208 134209 134210 134211 134212 134213 134214 134215 134216 134217 134218 134219 134220 134221 134222 134223 134224 134225 134226 |
for(iOpt=0; iOpt<SizeofArray(aFts4Opt); iOpt++){
struct Fts4Option *pOp = &aFts4Opt[iOpt];
if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){
break;
}
}
if( iOpt==SizeofArray(aFts4Opt) ){
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
rc = SQLITE_ERROR;
}else{
switch( iOpt ){
case 0: /* MATCHINFO */
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
rc = SQLITE_ERROR;
}
bNoDocsize = 1;
break;
case 1: /* PREFIX */
sqlite3_free(zPrefix);
|
| ︙ | ︙ | |||
133645 133646 133647 133648 133649 133650 133651 |
zVal = 0;
break;
case 4: /* ORDER */
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
){
| | | 134240 134241 134242 134243 134244 134245 134246 134247 134248 134249 134250 134251 134252 134253 134254 |
zVal = 0;
break;
case 4: /* ORDER */
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
){
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
rc = SQLITE_ERROR;
}
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
break;
case 5: /* CONTENT */
sqlite3_free(zContent);
|
| ︙ | ︙ | |||
133696 133697 133698 133699 133700 133701 133702 |
sqlite3_free(zCompress);
sqlite3_free(zUncompress);
zCompress = 0;
zUncompress = 0;
if( nCol==0 ){
sqlite3_free((void*)aCol);
aCol = 0;
| | | 134291 134292 134293 134294 134295 134296 134297 134298 134299 134300 134301 134302 134303 134304 134305 |
sqlite3_free(zCompress);
sqlite3_free(zUncompress);
zCompress = 0;
zUncompress = 0;
if( nCol==0 ){
sqlite3_free((void*)aCol);
aCol = 0;
rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
/* If a languageid= option was specified, remove the language id
** column from the aCol[] array. */
if( rc==SQLITE_OK && zLanguageid ){
int j;
for(j=0; j<nCol; j++){
if( sqlite3_stricmp(zLanguageid, aCol[j])==0 ){
|
| ︙ | ︙ | |||
133731 133732 133733 133734 133735 133736 133737 |
if( rc!=SQLITE_OK ) goto fts3_init_out;
}
assert( pTokenizer );
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
if( rc==SQLITE_ERROR ){
assert( zPrefix );
| | | 134326 134327 134328 134329 134330 134331 134332 134333 134334 134335 134336 134337 134338 134339 134340 |
if( rc!=SQLITE_OK ) goto fts3_init_out;
}
assert( pTokenizer );
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
if( rc==SQLITE_ERROR ){
assert( zPrefix );
sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
}
if( rc!=SQLITE_OK ) goto fts3_init_out;
/* Allocate and populate the Fts3Table structure. */
nByte = sizeof(Fts3Table) + /* Fts3Table */
nCol * sizeof(char *) + /* azColumn */
nIndex * sizeof(struct Fts3Index) + /* aIndex */
|
| ︙ | ︙ | |||
133813 133814 133815 133816 133817 133818 133819 |
sqlite3_free(zNot);
azNotindexed[i] = 0;
}
}
}
for(i=0; i<nNotindexed; i++){
if( azNotindexed[i] ){
| | | | 134408 134409 134410 134411 134412 134413 134414 134415 134416 134417 134418 134419 134420 134421 134422 134423 134424 134425 134426 134427 134428 134429 134430 |
sqlite3_free(zNot);
azNotindexed[i] = 0;
}
}
}
for(i=0; i<nNotindexed; i++){
if( azNotindexed[i] ){
sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]);
rc = SQLITE_ERROR;
}
}
if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
rc = SQLITE_ERROR;
sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss);
}
p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
if( rc!=SQLITE_OK ) goto fts3_init_out;
/* If this is an xCreate call, create the underlying tables in the
** database. TODO: For xConnect(), it could verify that said tables exist.
|
| ︙ | ︙ | |||
134917 134918 134919 134920 134921 134922 134923 | ** ** If the docids in the input doclists are sorted in ascending order, ** parameter bDescDoclist should be false. If they are sorted in ascending ** order, it should be passed a non-zero value. ** ** The right-hand input doclist is overwritten by this function. */ | | | > | > > > > > | > | 135512 135513 135514 135515 135516 135517 135518 135519 135520 135521 135522 135523 135524 135525 135526 135527 135528 135529 135530 135531 135532 135533 135534 135535 135536 135537 135538 135539 135540 135541 135542 135543 135544 135545 135546 135547 135548 135549 135550 135551 135552 |
**
** If the docids in the input doclists are sorted in ascending order,
** parameter bDescDoclist should be false. If they are sorted in ascending
** order, it should be passed a non-zero value.
**
** The right-hand input doclist is overwritten by this function.
*/
static int fts3DoclistPhraseMerge(
int bDescDoclist, /* True if arguments are desc */
int nDist, /* Distance from left to right (1=adjacent) */
char *aLeft, int nLeft, /* Left doclist */
char **paRight, int *pnRight /* IN/OUT: Right/output doclist */
){
sqlite3_int64 i1 = 0;
sqlite3_int64 i2 = 0;
sqlite3_int64 iPrev = 0;
char *aRight = *paRight;
char *pEnd1 = &aLeft[nLeft];
char *pEnd2 = &aRight[*pnRight];
char *p1 = aLeft;
char *p2 = aRight;
char *p;
int bFirstOut = 0;
char *aOut;
assert( nDist>0 );
if( bDescDoclist ){
aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
if( aOut==0 ) return SQLITE_NOMEM;
}else{
aOut = aRight;
}
p = aOut;
fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1);
fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2);
while( p1 && p2 ){
sqlite3_int64 iDiff = DOCID_CMP(i1, i2);
if( iDiff==0 ){
char *pSave = p;
|
| ︙ | ︙ | |||
134965 134966 134967 134968 134969 134970 134971 134972 134973 134974 134975 134976 134977 134978 |
}else{
fts3PoslistCopy(0, &p2);
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
}
}
*pnRight = (int)(p - aOut);
}
/*
** Argument pList points to a position list nList bytes in size. This
** function checks to see if the position list contains any entries for
** a token in position 0 (of any column). If so, it writes argument iDelta
** to the output buffer pOut, followed by a position list consisting only
| > > > > > > | 135567 135568 135569 135570 135571 135572 135573 135574 135575 135576 135577 135578 135579 135580 135581 135582 135583 135584 135585 135586 |
}else{
fts3PoslistCopy(0, &p2);
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
}
}
*pnRight = (int)(p - aOut);
if( bDescDoclist ){
sqlite3_free(aRight);
*paRight = aOut;
}
return SQLITE_OK;
}
/*
** Argument pList points to a position list nList bytes in size. This
** function checks to see if the position list contains any entries for
** a token in position 0 (of any column). If so, it writes argument iDelta
** to the output buffer pOut, followed by a position list consisting only
|
| ︙ | ︙ | |||
135089 135090 135091 135092 135093 135094 135095 |
Fts3Table *p, /* FTS table handle */
TermSelect *pTS, /* TermSelect object to merge into */
char *aDoclist, /* Pointer to doclist */
int nDoclist /* Size of aDoclist in bytes */
){
if( pTS->aaOutput[0]==0 ){
/* If this is the first term selected, copy the doclist to the output
| | > > > > > > > > > > > > > > | | 135697 135698 135699 135700 135701 135702 135703 135704 135705 135706 135707 135708 135709 135710 135711 135712 135713 135714 135715 135716 135717 135718 135719 135720 135721 135722 135723 135724 135725 135726 |
Fts3Table *p, /* FTS table handle */
TermSelect *pTS, /* TermSelect object to merge into */
char *aDoclist, /* Pointer to doclist */
int nDoclist /* Size of aDoclist in bytes */
){
if( pTS->aaOutput[0]==0 ){
/* If this is the first term selected, copy the doclist to the output
** buffer using memcpy().
**
** Add FTS3_VARINT_MAX bytes of unused space to the end of the
** allocation. This is so as to ensure that the buffer is big enough
** to hold the current doclist AND'd with any other doclist. If the
** doclists are stored in order=ASC order, this padding would not be
** required (since the size of [doclistA AND doclistB] is always less
** than or equal to the size of [doclistA] in that case). But this is
** not true for order=DESC. For example, a doclist containing (1, -1)
** may be smaller than (-1), as in the first example the -1 may be stored
** as a single-byte delta, whereas in the second it must be stored as a
** FTS3_VARINT_MAX byte varint.
**
** Similar padding is added in the fts3DoclistOrMerge() function.
*/
pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
}else{
return SQLITE_NOMEM;
}
}else{
|
| ︙ | ︙ | |||
135187 135188 135189 135190 135191 135192 135193 |
** for the pending-terms. If this is a scan, then this call must be being
** made by an fts4aux module, not an FTS table. In this case calling
** Fts3SegReaderPending might segfault, as the data structures used by
** fts4aux are not completely populated. So it's easiest to filter these
** calls out here. */
if( iLevel<0 && p->aIndex ){
Fts3SegReader *pSeg = 0;
| | | 135809 135810 135811 135812 135813 135814 135815 135816 135817 135818 135819 135820 135821 135822 135823 |
** for the pending-terms. If this is a scan, then this call must be being
** made by an fts4aux module, not an FTS table. In this case calling
** Fts3SegReaderPending might segfault, as the data structures used by
** fts4aux are not completely populated. So it's easiest to filter these
** calls out here. */
if( iLevel<0 && p->aIndex ){
Fts3SegReader *pSeg = 0;
rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
if( rc==SQLITE_OK && pSeg ){
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
}
}
if( iLevel!=FTS3_SEGCURSOR_PENDING ){
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
135836 135837 135838 135839 135840 135841 135842 135843 135844 135845 135846 |
** moves *ppPoslist so that it instead points to the first byte of the
** same position list.
*/
static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
char c = 0;
while( p>pStart && (c=*p--)==0 );
while( p>pStart && (*p & 0x80) | c ){
c = *p--;
}
| > > > > > > | > > > > > > > > > > > > > > | 136458 136459 136460 136461 136462 136463 136464 136465 136466 136467 136468 136469 136470 136471 136472 136473 136474 136475 136476 136477 136478 136479 136480 136481 136482 136483 136484 136485 136486 136487 136488 136489 136490 136491 136492 136493 136494 136495 136496 |
** moves *ppPoslist so that it instead points to the first byte of the
** same position list.
*/
static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
char c = 0;
/* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
while( p>pStart && (c=*p--)==0 );
/* Search backwards for a varint with value zero (the end of the previous
** poslist). This is an 0x00 byte preceded by some byte that does not
** have the 0x80 bit set. */
while( p>pStart && (*p & 0x80) | c ){
c = *p--;
}
assert( p==pStart || c==0 );
/* At this point p points to that preceding byte without the 0x80 bit
** set. So to find the start of the poslist, skip forward 2 bytes then
** over a varint.
**
** Normally. The other case is that p==pStart and the poslist to return
** is the first in the doclist. In this case do not skip forward 2 bytes.
** The second part of the if condition (c==0 && *ppPoslist>&p[2])
** is required for cases where the first byte of a doclist and the
** doclist is empty. For example, if the first docid is 10, a doclist
** that begins with:
**
** 0x0A 0x00 <next docid delta varint>
*/
if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
while( *p++&0x80 );
*ppPoslist = p;
}
/*
** Helper function used by the implementation of the overloaded snippet(),
** offsets() and optimize() SQL functions.
|
| ︙ | ︙ | |||
135911 135912 135913 135914 135915 135916 135917 135918 135919 135920 135921 135922 135923 135924 |
case 5: iCol = sqlite3_value_int(apVal[4]);
case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]);
case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]);
case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
}
if( !zEllipsis || !zEnd || !zStart ){
sqlite3_result_error_nomem(pContext);
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
}
}
/*
** Implementation of the offsets() function for FTS3
| > > | 136553 136554 136555 136556 136557 136558 136559 136560 136561 136562 136563 136564 136565 136566 136567 136568 |
case 5: iCol = sqlite3_value_int(apVal[4]);
case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]);
case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]);
case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
}
if( !zEllipsis || !zEnd || !zStart ){
sqlite3_result_error_nomem(pContext);
}else if( nToken==0 ){
sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
}else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
}
}
/*
** Implementation of the offsets() function for FTS3
|
| ︙ | ︙ | |||
136346 136347 136348 136349 136350 136351 136352 136353 | /* ** Arguments pList/nList contain the doclist for token iToken of phrase p. ** It is merged into the main doclist stored in p->doclist.aAll/nAll. ** ** This function assumes that pList points to a buffer allocated using ** sqlite3_malloc(). This function takes responsibility for eventually ** freeing the buffer. */ | > > | > | 136990 136991 136992 136993 136994 136995 136996 136997 136998 136999 137000 137001 137002 137003 137004 137005 137006 137007 137008 137009 137010 137011 137012 137013 137014 |
/*
** Arguments pList/nList contain the doclist for token iToken of phrase p.
** It is merged into the main doclist stored in p->doclist.aAll/nAll.
**
** This function assumes that pList points to a buffer allocated using
** sqlite3_malloc(). This function takes responsibility for eventually
** freeing the buffer.
**
** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs.
*/
static int fts3EvalPhraseMergeToken(
Fts3Table *pTab, /* FTS Table pointer */
Fts3Phrase *p, /* Phrase to merge pList/nList into */
int iToken, /* Token pList/nList corresponds to */
char *pList, /* Pointer to doclist */
int nList /* Number of bytes in pList */
){
int rc = SQLITE_OK;
assert( iToken!=p->iDoclistToken );
if( pList==0 ){
sqlite3_free(p->doclist.aAll);
p->doclist.aAll = 0;
p->doclist.nAll = 0;
}
|
| ︙ | ︙ | |||
136392 136393 136394 136395 136396 136397 136398 |
pRight = p->doclist.aAll;
nRight = p->doclist.nAll;
pLeft = pList;
nLeft = nList;
nDiff = p->iDoclistToken - iToken;
}
| > | > > | 137039 137040 137041 137042 137043 137044 137045 137046 137047 137048 137049 137050 137051 137052 137053 137054 137055 137056 137057 137058 137059 137060 137061 137062 |
pRight = p->doclist.aAll;
nRight = p->doclist.nAll;
pLeft = pList;
nLeft = nList;
nDiff = p->iDoclistToken - iToken;
}
rc = fts3DoclistPhraseMerge(
pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight
);
sqlite3_free(pLeft);
p->doclist.aAll = pRight;
p->doclist.nAll = nRight;
}
if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken;
return rc;
}
/*
** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist
** does not take deferred tokens into account.
**
** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
|
| ︙ | ︙ | |||
136424 136425 136426 136427 136428 136429 136430 |
assert( pToken->pDeferred==0 || pToken->pSegcsr==0 );
if( pToken->pSegcsr ){
int nThis = 0;
char *pThis = 0;
rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis);
if( rc==SQLITE_OK ){
| | | 137074 137075 137076 137077 137078 137079 137080 137081 137082 137083 137084 137085 137086 137087 137088 |
assert( pToken->pDeferred==0 || pToken->pSegcsr==0 );
if( pToken->pSegcsr ){
int nThis = 0;
char *pThis = 0;
rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis);
if( rc==SQLITE_OK ){
rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
}
}
assert( pToken->pSegcsr==0 );
}
return rc;
}
|
| ︙ | ︙ | |||
136966 136967 136968 136969 136970 136971 136972 |
static void fts3EvalStartReaders(
Fts3Cursor *pCsr, /* FTS Cursor handle */
Fts3Expr *pExpr, /* Expression to initialize phrases in */
int *pRc /* IN/OUT: Error code */
){
if( pExpr && SQLITE_OK==*pRc ){
if( pExpr->eType==FTSQUERY_PHRASE ){
| < > > | | | | > | 137616 137617 137618 137619 137620 137621 137622 137623 137624 137625 137626 137627 137628 137629 137630 137631 137632 137633 137634 137635 137636 137637 |
static void fts3EvalStartReaders(
Fts3Cursor *pCsr, /* FTS Cursor handle */
Fts3Expr *pExpr, /* Expression to initialize phrases in */
int *pRc /* IN/OUT: Error code */
){
if( pExpr && SQLITE_OK==*pRc ){
if( pExpr->eType==FTSQUERY_PHRASE ){
int nToken = pExpr->pPhrase->nToken;
if( nToken ){
int i;
for(i=0; i<nToken; i++){
if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
}
pExpr->bDeferred = (i==nToken);
}
*pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
}else{
fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
fts3EvalStartReaders(pCsr, pExpr->pRight, pRc);
pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
}
}
|
| ︙ | ︙ | |||
137226 137227 137228 137229 137230 137231 137232 137233 137234 |
** part of a multi-token phrase. Either way, the entire doclist will
** (eventually) be loaded into memory. It may as well be now. */
Fts3PhraseToken *pToken = pTC->pToken;
int nList = 0;
char *pList = 0;
rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList);
assert( rc==SQLITE_OK || pList==0 );
if( rc==SQLITE_OK ){
int nCount;
| > > > > > < | 137878 137879 137880 137881 137882 137883 137884 137885 137886 137887 137888 137889 137890 137891 137892 137893 137894 137895 137896 137897 137898 |
** part of a multi-token phrase. Either way, the entire doclist will
** (eventually) be loaded into memory. It may as well be now. */
Fts3PhraseToken *pToken = pTC->pToken;
int nList = 0;
char *pList = 0;
rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList);
assert( rc==SQLITE_OK || pList==0 );
if( rc==SQLITE_OK ){
rc = fts3EvalPhraseMergeToken(
pTab, pTC->pPhrase, pTC->iToken,pList,nList
);
}
if( rc==SQLITE_OK ){
int nCount;
nCount = fts3DoclistCountDocids(
pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll
);
if( ii==0 || nCount<nMinEst ) nMinEst = nCount;
}
}
}
|
| ︙ | ︙ | |||
138130 138131 138132 138133 138134 138135 138136 |
}
}
if( rc!=SQLITE_OK ) return rc;
pIter = pPhrase->pOrPoslist;
iDocid = pPhrase->iOrDocid;
if( pCsr->bDesc==bDescDoclist ){
| > | | 138786 138787 138788 138789 138790 138791 138792 138793 138794 138795 138796 138797 138798 138799 138800 138801 |
}
}
if( rc!=SQLITE_OK ) return rc;
pIter = pPhrase->pOrPoslist;
iDocid = pPhrase->iOrDocid;
if( pCsr->bDesc==bDescDoclist ){
bEof = !pPhrase->doclist.nAll ||
(pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
sqlite3Fts3DoclistNext(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
&pIter, &iDocid, &bEof
);
}
}else{
|
| ︙ | ︙ | |||
138211 138212 138213 138214 138215 138216 138217 | #if !SQLITE_CORE /* ** Initialize API pointer table, if required. */ #ifdef _WIN32 __declspec(dllexport) #endif | | | 138868 138869 138870 138871 138872 138873 138874 138875 138876 138877 138878 138879 138880 138881 138882 |
#if !SQLITE_CORE
/*
** Initialize API pointer table, if required.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi)
return sqlite3Fts3Init(db);
}
|
| ︙ | ︙ | |||
138342 138343 138344 138345 138346 138347 138348 | memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); *ppVtab = (sqlite3_vtab *)p; return SQLITE_OK; bad_args: | | | 138999 139000 139001 139002 139003 139004 139005 139006 139007 139008 139009 139010 139011 139012 139013 | memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); *ppVtab = (sqlite3_vtab *)p; return SQLITE_OK; bad_args: sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); return SQLITE_ERROR; } /* ** This function does the work for both the xDisconnect and xDestroy methods. ** These tables have no persistent representation of their own, so xDisconnect ** and xDestroy are identical operations. |
| ︙ | ︙ | |||
139800 139801 139802 139803 139804 139805 139806 |
}
}
if( rc!=SQLITE_OK ){
sqlite3Fts3ExprFree(*ppExpr);
*ppExpr = 0;
if( rc==SQLITE_TOOBIG ){
| | | | 140457 140458 140459 140460 140461 140462 140463 140464 140465 140466 140467 140468 140469 140470 140471 140472 140473 140474 140475 140476 140477 |
}
}
if( rc!=SQLITE_OK ){
sqlite3Fts3ExprFree(*ppExpr);
*ppExpr = 0;
if( rc==SQLITE_TOOBIG ){
sqlite3Fts3ErrMsg(pzErr,
"FTS expression tree is too large (maximum depth %d)",
SQLITE_FTS3_MAX_EXPR_DEPTH
);
rc = SQLITE_ERROR;
}else if( rc==SQLITE_ERROR ){
sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
}
}
return rc;
}
/*
|
| ︙ | ︙ | |||
141282 141283 141284 141285 141286 141287 141288 |
z = zCopy;
}
z[n] = '\0';
sqlite3Fts3Dequote(z);
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
if( !m ){
| | | 141939 141940 141941 141942 141943 141944 141945 141946 141947 141948 141949 141950 141951 141952 141953 |
z = zCopy;
}
z[n] = '\0';
sqlite3Fts3Dequote(z);
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
if( !m ){
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
rc = SQLITE_ERROR;
}else{
char const **aArg = 0;
int iArg = 0;
z = &z[n+1];
while( z<zEnd && (NULL!=(z = (char *)sqlite3Fts3NextToken(z, &n))) ){
int nNew = sizeof(char *)*(iArg+1);
|
| ︙ | ︙ | |||
141305 141306 141307 141308 141309 141310 141311 |
z[n] = '\0';
sqlite3Fts3Dequote(z);
z = &z[n+1];
}
rc = m->xCreate(iArg, aArg, ppTok);
assert( rc!=SQLITE_OK || *ppTok );
if( rc!=SQLITE_OK ){
| | | 141962 141963 141964 141965 141966 141967 141968 141969 141970 141971 141972 141973 141974 141975 141976 |
z[n] = '\0';
sqlite3Fts3Dequote(z);
z = &z[n+1];
}
rc = m->xCreate(iArg, aArg, ppTok);
assert( rc!=SQLITE_OK || *ppTok );
if( rc!=SQLITE_OK ){
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
}else{
(*ppTok)->pModule = m;
}
sqlite3_free((void *)aArg);
}
sqlite3_free(zCopy);
|
| ︙ | ︙ | |||
141389 141390 141391 141392 141393 141394 141395 |
nInput = sqlite3_value_bytes(argv[argc-1]);
zInput = (const char *)sqlite3_value_text(argv[argc-1]);
pHash = (Fts3Hash *)sqlite3_user_data(context);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
| | | | | 142046 142047 142048 142049 142050 142051 142052 142053 142054 142055 142056 142057 142058 142059 142060 142061 142062 |
nInput = sqlite3_value_bytes(argv[argc-1]);
zInput = (const char *)sqlite3_value_text(argv[argc-1]);
pHash = (Fts3Hash *)sqlite3_user_data(context);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
sqlite3_result_error(context, zErr2, -1);
sqlite3_free(zErr2);
return;
}
pRet = Tcl_NewObj();
Tcl_IncrRefCount(pRet);
for(i=1; i<argc-1; i++){
|
| ︙ | ︙ | |||
141926 141927 141928 141929 141930 141931 141932 |
char **pzErr
){
sqlite3_tokenizer_module *p;
int nName = (int)strlen(zName);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
| | | 142583 142584 142585 142586 142587 142588 142589 142590 142591 142592 142593 142594 142595 142596 142597 |
char **pzErr
){
sqlite3_tokenizer_module *p;
int nName = (int)strlen(zName);
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
if( !p ){
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
return SQLITE_ERROR;
}
*pp = p;
return SQLITE_OK;
}
|
| ︙ | ︙ | |||
142623 142624 142625 142626 142627 142628 142629 | /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", /* 24 */ "", /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", | | | 143280 143281 143282 143283 143284 143285 143286 143287 143288 143289 143290 143291 143292 143293 143294 | /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", /* 24 */ "", /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", /* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", /* This statement is used to determine which level to read the input from ** when performing an incremental merge. It returns the absolute level number ** of the oldest level in the db that contains at least ? segments. Or, ** if no level in the FTS index contains more than ? segments, the statement ** returns zero rows. */ /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?" |
| ︙ | ︙ | |||
145741 145742 145743 145744 145745 145746 145747 |
int bSeenDone = 0;
int rc;
sqlite3_stmt *pAllLangid = 0;
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
| | > | 146398 146399 146400 146401 146402 146403 146404 146405 146406 146407 146408 146409 146410 146411 146412 146413 |
int bSeenDone = 0;
int rc;
sqlite3_stmt *pAllLangid = 0;
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
sqlite3_bind_int(pAllLangid, 2, p->nIndex);
while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
int i;
int iLangid = sqlite3_column_int(pAllLangid, 0);
for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
if( rc==SQLITE_DONE ){
bSeenDone = 1;
|
| ︙ | ︙ | |||
147073 147074 147075 147076 147077 147078 147079 | i = pHint->n-2; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); | | | 147731 147732 147733 147734 147735 147736 147737 147738 147739 147740 147741 147742 147743 147744 147745 | i = pHint->n-2; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); if( i!=nHint ) return FTS_CORRUPT_VTAB; return SQLITE_OK; } /* ** Attempt an incremental merge that writes nMerge leaf blocks. |
| ︙ | ︙ | |||
147441 147442 147443 147444 147445 147446 147447 |
u64 cksum2 = 0; /* Checksum based on %_content contents */
sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */
/* This block calculates the checksum according to the FTS index. */
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
| | > < | 148099 148100 148101 148102 148103 148104 148105 148106 148107 148108 148109 148110 148111 148112 148113 148114 148115 148116 148117 148118 148119 148120 148121 148122 148123 148124 148125 148126 |
u64 cksum2 = 0; /* Checksum based on %_content contents */
sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */
/* This block calculates the checksum according to the FTS index. */
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
if( rc==SQLITE_OK ){
int rc2;
sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
sqlite3_bind_int(pAllLangid, 2, p->nIndex);
while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
int iLangid = sqlite3_column_int(pAllLangid, 0);
int i;
for(i=0; i<p->nIndex; i++){
cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc);
}
}
rc2 = sqlite3_reset(pAllLangid);
if( rc==SQLITE_OK ) rc = rc2;
}
/* This block calculates the checksum according to the %_content table */
if( rc==SQLITE_OK ){
sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
sqlite3_stmt *pStmt = 0;
char *zSql;
zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
if( !zSql ){
|
| ︙ | ︙ | |||
147551 147552 147553 147554 147555 147556 147557 |
*/
static int fts3DoIntegrityCheck(
Fts3Table *p /* FTS3 table handle */
){
int rc;
int bOk = 0;
rc = fts3IntegrityCheck(p, &bOk);
| | | 148209 148210 148211 148212 148213 148214 148215 148216 148217 148218 148219 148220 148221 148222 148223 |
*/
static int fts3DoIntegrityCheck(
Fts3Table *p /* FTS3 table handle */
){
int rc;
int bOk = 0;
rc = fts3IntegrityCheck(p, &bOk);
if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
return rc;
}
/*
** Handle a 'special' INSERT of the form:
**
** "INSERT INTO tbl(tbl) VALUES(<expr>)"
|
| ︙ | ︙ | |||
147989 147990 147991 147992 147993 147994 147995 147996 147997 147998 147999 148000 148001 148002 | #define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ #define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ #define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ #define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ #define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ #define FTS3_MATCHINFO_LCS 's' /* nCol values */ #define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ /* ** The default value for the second argument to matchinfo(). */ #define FTS3_MATCHINFO_DEFAULT "pcx" | > | 148647 148648 148649 148650 148651 148652 148653 148654 148655 148656 148657 148658 148659 148660 148661 | #define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ #define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ #define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ #define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ #define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ #define FTS3_MATCHINFO_LCS 's' /* nCol values */ #define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ #define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */ /* ** The default value for the second argument to matchinfo(). */ #define FTS3_MATCHINFO_DEFAULT "pcx" |
| ︙ | ︙ | |||
148770 148771 148772 148773 148774 148775 148776 148777 148778 148779 148780 148781 148782 148783 148784 148785 148786 148787 148788 148789 148790 148791 148792 |
}else{
p->aMatchinfo[iStart+i*3] = 0;
}
}
return rc;
}
static int fts3MatchinfoCheck(
Fts3Table *pTab,
char cArg,
char **pzErr
){
if( (cArg==FTS3_MATCHINFO_NPHRASE)
|| (cArg==FTS3_MATCHINFO_NCOL)
|| (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4)
|| (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|| (cArg==FTS3_MATCHINFO_LCS)
|| (cArg==FTS3_MATCHINFO_HITS)
){
return SQLITE_OK;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | 149429 149430 149431 149432 149433 149434 149435 149436 149437 149438 149439 149440 149441 149442 149443 149444 149445 149446 149447 149448 149449 149450 149451 149452 149453 149454 149455 149456 149457 149458 149459 149460 149461 149462 149463 149464 149465 149466 149467 149468 149469 149470 149471 149472 149473 149474 149475 149476 149477 149478 149479 149480 149481 149482 149483 149484 149485 149486 149487 149488 149489 149490 149491 149492 149493 149494 149495 149496 149497 149498 149499 149500 149501 149502 149503 149504 149505 149506 149507 149508 149509 149510 149511 149512 149513 149514 149515 149516 149517 149518 149519 149520 149521 149522 149523 149524 149525 149526 149527 |
}else{
p->aMatchinfo[iStart+i*3] = 0;
}
}
return rc;
}
/*
** fts3ExprIterate() callback used to gather information for the matchinfo
** directive 'y'.
*/
static int fts3ExprLHitsCb(
Fts3Expr *pExpr, /* Phrase expression node */
int iPhrase, /* Phrase number */
void *pCtx /* Pointer to MatchInfo structure */
){
MatchInfo *p = (MatchInfo *)pCtx;
Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
int rc = SQLITE_OK;
int iStart = iPhrase * p->nCol;
Fts3Expr *pEof; /* Ancestor node already at EOF */
/* This must be a phrase */
assert( pExpr->pPhrase );
/* Initialize all output integers to zero. */
memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
/* Check if this or any parent node is at EOF. If so, then all output
** values are zero. */
for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
Fts3Phrase *pPhrase = pExpr->pPhrase;
char *pIter = pPhrase->doclist.pList;
int iCol = 0;
while( 1 ){
int nHit = fts3ColumnlistCount(&pIter);
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
p->aMatchinfo[iStart + iCol] = (u32)nHit;
}
assert( *pIter==0x00 || *pIter==0x01 );
if( *pIter!=0x01 ) break;
pIter++;
pIter += fts3GetVarint32(pIter, &iCol);
}
}
return rc;
}
static int fts3MatchinfoCheck(
Fts3Table *pTab,
char cArg,
char **pzErr
){
if( (cArg==FTS3_MATCHINFO_NPHRASE)
|| (cArg==FTS3_MATCHINFO_NCOL)
|| (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4)
|| (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|| (cArg==FTS3_MATCHINFO_LCS)
|| (cArg==FTS3_MATCHINFO_HITS)
|| (cArg==FTS3_MATCHINFO_LHITS)
){
return SQLITE_OK;
}
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
return SQLITE_ERROR;
}
static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
int nVal; /* Number of integers output by cArg */
switch( cArg ){
case FTS3_MATCHINFO_NDOC:
case FTS3_MATCHINFO_NPHRASE:
case FTS3_MATCHINFO_NCOL:
nVal = 1;
break;
case FTS3_MATCHINFO_AVGLENGTH:
case FTS3_MATCHINFO_LENGTH:
case FTS3_MATCHINFO_LCS:
nVal = pInfo->nCol;
break;
case FTS3_MATCHINFO_LHITS:
nVal = pInfo->nCol * pInfo->nPhrase;
break;
default:
assert( cArg==FTS3_MATCHINFO_HITS );
nVal = pInfo->nCol * pInfo->nPhrase * 3;
break;
}
|
| ︙ | ︙ | |||
149059 149060 149061 149062 149063 149064 149065 149066 149067 149068 149069 149070 149071 149072 |
case FTS3_MATCHINFO_LCS:
rc = fts3ExprLoadDoclists(pCsr, 0, 0);
if( rc==SQLITE_OK ){
rc = fts3MatchinfoLcs(pCsr, pInfo);
}
break;
default: {
Fts3Expr *pExpr;
assert( zArg[i]==FTS3_MATCHINFO_HITS );
pExpr = pCsr->pExpr;
rc = fts3ExprLoadDoclists(pCsr, 0, 0);
if( rc!=SQLITE_OK ) break;
| > > > > | 149768 149769 149770 149771 149772 149773 149774 149775 149776 149777 149778 149779 149780 149781 149782 149783 149784 149785 |
case FTS3_MATCHINFO_LCS:
rc = fts3ExprLoadDoclists(pCsr, 0, 0);
if( rc==SQLITE_OK ){
rc = fts3MatchinfoLcs(pCsr, pInfo);
}
break;
case FTS3_MATCHINFO_LHITS:
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
break;
default: {
Fts3Expr *pExpr;
assert( zArg[i]==FTS3_MATCHINFO_HITS );
pExpr = pCsr->pExpr;
rc = fts3ExprLoadDoclists(pCsr, 0, 0);
if( rc!=SQLITE_OK ) break;
|
| ︙ | ︙ | |||
153072 153073 153074 153075 153076 153077 153078 |
** the conflicting row can be removed before proceeding. In the second
** case, SQLITE_CONSTRAINT must be returned regardless of the
** conflict-handling mode specified by the user.
*/
if( nData>1 ){
int ii;
| | > > > > > > > | > | | | 153785 153786 153787 153788 153789 153790 153791 153792 153793 153794 153795 153796 153797 153798 153799 153800 153801 153802 153803 153804 153805 153806 153807 153808 153809 153810 153811 153812 153813 153814 153815 153816 153817 153818 153819 153820 153821 153822 |
** the conflicting row can be removed before proceeding. In the second
** case, SQLITE_CONSTRAINT must be returned regardless of the
** conflict-handling mode specified by the user.
*/
if( nData>1 ){
int ii;
/* Populate the cell.aCoord[] array. The first coordinate is azData[3].
**
** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
** with "column" that are interpreted as table constraints.
** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
** This problem was discovered after years of use, so we silently ignore
** these kinds of misdeclared tables to avoid breaking any legacy.
*/
assert( nData<=(pRtree->nDim*2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<nData-4; ii+=2){
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
rc = SQLITE_CONSTRAINT;
goto constraint;
}
}
}else
#endif
{
for(ii=0; ii<nData-4; ii+=2){
cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
rc = SQLITE_CONSTRAINT;
goto constraint;
}
}
|
| ︙ | ︙ | |||
153658 153659 153660 153661 153662 153663 153664 |
sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
}
}
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
| | | 154379 154380 154381 154382 154383 154384 154385 154386 154387 154388 154389 154390 154391 154392 154393 |
sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
}
}
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zGeom, /* Name of the new SQL function */
int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
void *pContext /* Extra data associated with the callback */
){
RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
|
| ︙ | ︙ | |||
153682 153683 153684 153685 153686 153687 153688 | ); } /* ** Register a new 2nd-generation geometry function for use with the ** r-tree MATCH operator. */ | | | 154403 154404 154405 154406 154407 154408 154409 154410 154411 154412 154413 154414 154415 154416 154417 |
);
}
/*
** Register a new 2nd-generation geometry function for use with the
** r-tree MATCH operator.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zQueryFunc, /* Name of new SQL function */
int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
void *pContext, /* Extra data passed into the callback */
void (*xDestructor)(void*) /* Destructor for the extra data */
){
RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
|
| ︙ | ︙ | |||
153707 153708 153709 153710 153711 153712 153713 | ); } #if !SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif | | | 154428 154429 154430 154431 154432 154433 154434 154435 154436 154437 154438 154439 154440 154441 154442 |
);
}
#if !SQLITE_CORE
#ifdef _WIN32
__declspec(dllexport)
#endif
SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi)
return sqlite3RtreeInit(db);
}
|
| ︙ | ︙ | |||
154212 154213 154214 154215 154216 154217 154218 | return rc; } #if !SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif | | | 154933 154934 154935 154936 154937 154938 154939 154940 154941 154942 154943 154944 154945 154946 154947 |
return rc;
}
#if !SQLITE_CORE
#ifdef _WIN32
__declspec(dllexport)
#endif
SQLITE_API int SQLITE_STDCALL sqlite3_icu_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi)
return sqlite3IcuInit(db);
}
|
| ︙ | ︙ | |||
154487 154488 154489 154490 154491 154492 154493 | *ppModule = &icuTokenizerModule; } #endif /* defined(SQLITE_ENABLE_ICU) */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ /************** End of fts3_icu.c ********************************************/ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 155208 155209 155210 155211 155212 155213 155214 155215 155216 155217 155218 155219 155220 155221 155222 155223 155224 155225 155226 155227 155228 155229 155230 155231 155232 155233 155234 155235 155236 155237 155238 155239 155240 155241 155242 155243 155244 155245 155246 155247 155248 155249 155250 155251 155252 155253 155254 155255 155256 155257 155258 155259 155260 155261 155262 155263 155264 155265 155266 155267 155268 155269 155270 155271 155272 155273 155274 155275 155276 155277 155278 155279 155280 155281 155282 155283 155284 155285 155286 155287 155288 155289 155290 155291 155292 155293 155294 155295 155296 155297 155298 155299 155300 155301 155302 155303 155304 155305 155306 155307 155308 155309 155310 155311 155312 155313 155314 155315 155316 155317 155318 155319 155320 155321 155322 155323 155324 155325 155326 155327 155328 155329 155330 155331 155332 155333 155334 155335 155336 155337 155338 155339 155340 155341 155342 155343 155344 155345 155346 155347 155348 155349 155350 155351 155352 155353 155354 155355 155356 155357 155358 155359 155360 155361 155362 155363 155364 155365 155366 155367 155368 155369 155370 155371 155372 155373 155374 155375 155376 155377 155378 155379 155380 155381 155382 155383 155384 155385 155386 155387 155388 155389 155390 155391 155392 155393 155394 155395 155396 155397 155398 155399 155400 155401 155402 155403 155404 155405 155406 155407 155408 155409 155410 155411 155412 155413 155414 155415 155416 155417 155418 155419 155420 155421 155422 155423 155424 155425 155426 155427 155428 155429 155430 155431 155432 155433 155434 155435 155436 155437 155438 155439 155440 155441 155442 155443 155444 155445 155446 155447 155448 155449 155450 155451 155452 155453 155454 155455 155456 155457 155458 155459 155460 155461 155462 155463 155464 155465 155466 155467 155468 155469 155470 155471 155472 155473 155474 155475 155476 155477 155478 155479 155480 155481 155482 155483 155484 155485 155486 155487 155488 155489 155490 155491 155492 155493 155494 155495 155496 155497 155498 155499 155500 155501 155502 155503 155504 155505 155506 155507 155508 155509 155510 155511 155512 155513 155514 155515 155516 155517 155518 155519 155520 155521 155522 155523 155524 155525 155526 155527 155528 155529 155530 155531 155532 155533 155534 155535 155536 155537 155538 155539 155540 155541 155542 155543 155544 155545 155546 155547 155548 155549 155550 155551 155552 155553 155554 155555 155556 155557 155558 155559 155560 155561 155562 155563 155564 155565 155566 155567 155568 155569 155570 155571 155572 155573 155574 155575 155576 155577 155578 155579 155580 155581 155582 155583 155584 155585 155586 155587 155588 155589 155590 155591 155592 155593 155594 155595 155596 155597 155598 155599 155600 155601 155602 155603 155604 155605 155606 155607 155608 155609 155610 155611 155612 155613 155614 155615 155616 155617 155618 155619 155620 155621 155622 155623 155624 155625 155626 155627 155628 155629 155630 155631 155632 155633 155634 155635 155636 155637 155638 155639 155640 155641 155642 155643 155644 155645 155646 155647 155648 155649 155650 155651 155652 155653 155654 155655 155656 155657 155658 155659 155660 155661 155662 155663 155664 155665 155666 155667 155668 155669 155670 155671 155672 155673 155674 155675 155676 155677 155678 155679 155680 155681 155682 155683 155684 155685 155686 155687 155688 155689 155690 155691 155692 155693 155694 155695 155696 155697 155698 155699 155700 155701 155702 155703 155704 155705 155706 155707 155708 155709 155710 155711 155712 155713 155714 155715 155716 155717 155718 155719 155720 155721 155722 155723 155724 155725 155726 155727 155728 155729 155730 155731 155732 155733 155734 155735 155736 155737 155738 155739 155740 155741 155742 155743 155744 155745 155746 155747 155748 155749 155750 155751 155752 155753 155754 155755 155756 155757 155758 155759 155760 155761 155762 155763 155764 155765 155766 155767 155768 155769 155770 155771 155772 155773 155774 155775 155776 155777 155778 155779 155780 155781 155782 155783 155784 155785 155786 155787 155788 155789 155790 155791 155792 155793 155794 155795 155796 155797 155798 155799 155800 155801 155802 155803 155804 155805 155806 155807 155808 155809 155810 155811 155812 155813 155814 155815 155816 155817 155818 155819 155820 155821 155822 155823 155824 155825 155826 155827 155828 155829 155830 155831 155832 155833 155834 155835 155836 155837 155838 155839 155840 155841 155842 155843 155844 155845 155846 155847 155848 155849 155850 155851 155852 155853 155854 155855 155856 155857 155858 155859 155860 155861 155862 155863 155864 155865 |
*ppModule = &icuTokenizerModule;
}
#endif /* defined(SQLITE_ENABLE_ICU) */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
/************** End of fts3_icu.c ********************************************/
/************** Begin file dbstat.c ******************************************/
/*
** 2010 July 12
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains an implementation of the "dbstat" virtual table.
**
** The dbstat virtual table is used to extract low-level formatting
** information from an SQLite database in order to implement the
** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
** for an example implementation.
*/
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
** Page paths:
**
** The value of the 'path' column describes the path taken from the
** root-node of the b-tree structure to each page. The value of the
** root-node path is '/'.
**
** The value of the path for the left-most child page of the root of
** a b-tree is '/000/'. (Btrees store content ordered from left to right
** so the pages to the left have smaller keys than the pages to the right.)
** The next to left-most child of the root page is
** '/001', and so on, each sibling page identified by a 3-digit hex
** value. The children of the 451st left-most sibling have paths such
** as '/1c2/000/, '/1c2/001/' etc.
**
** Overflow pages are specified by appending a '+' character and a
** six-digit hexadecimal value to the path to the cell they are linked
** from. For example, the three overflow pages in a chain linked from
** the left-most cell of the 450th child of the root page are identified
** by the paths:
**
** '/1c2/000+000000' // First page in overflow chain
** '/1c2/000+000001' // Second page in overflow chain
** '/1c2/000+000002' // Third page in overflow chain
**
** If the paths are sorted using the BINARY collation sequence, then
** the overflow pages associated with a cell will appear earlier in the
** sort-order than its child page:
**
** '/1c2/000/' // Left-most child of 451st child of root
*/
#define VTAB_SCHEMA \
"CREATE TABLE xx( " \
" name STRING, /* Name of table or index */" \
" path INTEGER, /* Path to page from root */" \
" pageno INTEGER, /* Page number */" \
" pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \
" ncell INTEGER, /* Cells on page (0 for overflow) */" \
" payload INTEGER, /* Bytes of payload on this page */" \
" unused INTEGER, /* Bytes of unused space on this page */" \
" mx_payload INTEGER, /* Largest payload size of all cells */" \
" pgoffset INTEGER, /* Offset of page in file */" \
" pgsize INTEGER /* Size of the page */" \
");"
typedef struct StatTable StatTable;
typedef struct StatCursor StatCursor;
typedef struct StatPage StatPage;
typedef struct StatCell StatCell;
struct StatCell {
int nLocal; /* Bytes of local payload */
u32 iChildPg; /* Child node (or 0 if this is a leaf) */
int nOvfl; /* Entries in aOvfl[] */
u32 *aOvfl; /* Array of overflow page numbers */
int nLastOvfl; /* Bytes of payload on final overflow page */
int iOvfl; /* Iterates through aOvfl[] */
};
struct StatPage {
u32 iPgno;
DbPage *pPg;
int iCell;
char *zPath; /* Path to this page */
/* Variables populated by statDecodePage(): */
u8 flags; /* Copy of flags byte */
int nCell; /* Number of cells on page */
int nUnused; /* Number of unused bytes on page */
StatCell *aCell; /* Array of parsed cells */
u32 iRightChildPg; /* Right-child page number (or 0) */
int nMxPayload; /* Largest payload of any cell on this page */
};
struct StatCursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Iterates through set of root pages */
int isEof; /* After pStmt has returned SQLITE_DONE */
StatPage aPage[32];
int iPage; /* Current entry in aPage[] */
/* Values to return. */
char *zName; /* Value of 'name' column */
char *zPath; /* Value of 'path' column */
u32 iPageno; /* Value of 'pageno' column */
char *zPagetype; /* Value of 'pagetype' column */
int nCell; /* Value of 'ncell' column */
int nPayload; /* Value of 'payload' column */
int nUnused; /* Value of 'unused' column */
int nMxPayload; /* Value of 'mx_payload' column */
i64 iOffset; /* Value of 'pgOffset' column */
int szPage; /* Value of 'pgSize' column */
};
struct StatTable {
sqlite3_vtab base;
sqlite3 *db;
int iDb; /* Index of database to analyze */
};
#ifndef get2byte
# define get2byte(x) ((x)[0]<<8 | (x)[1])
#endif
/*
** Connect to or create a statvfs virtual table.
*/
static int statConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
StatTable *pTab = 0;
int rc = SQLITE_OK;
int iDb;
if( argc>=4 ){
iDb = sqlite3FindDbName(db, argv[3]);
if( iDb<0 ){
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
return SQLITE_ERROR;
}
}else{
iDb = 0;
}
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
if( rc==SQLITE_OK ){
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
if( pTab==0 ) rc = SQLITE_NOMEM;
}
assert( rc==SQLITE_OK || pTab==0 );
if( rc==SQLITE_OK ){
memset(pTab, 0, sizeof(StatTable));
pTab->db = db;
pTab->iDb = iDb;
}
*ppVtab = (sqlite3_vtab*)pTab;
return rc;
}
/*
** Disconnect from or destroy a statvfs virtual table.
*/
static int statDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
** There is no "best-index". This virtual table always does a linear
** scan of the binary VFS log file.
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
/* Records are always returned in ascending order of (name, path).
** If this will satisfy the client, set the orderByConsumed flag so that
** SQLite does not do an external sort.
*/
if( ( pIdxInfo->nOrderBy==1
&& pIdxInfo->aOrderBy[0].iColumn==0
&& pIdxInfo->aOrderBy[0].desc==0
) ||
( pIdxInfo->nOrderBy==2
&& pIdxInfo->aOrderBy[0].iColumn==0
&& pIdxInfo->aOrderBy[0].desc==0
&& pIdxInfo->aOrderBy[1].iColumn==1
&& pIdxInfo->aOrderBy[1].desc==0
)
){
pIdxInfo->orderByConsumed = 1;
}
pIdxInfo->estimatedCost = 10.0;
return SQLITE_OK;
}
/*
** Open a new statvfs cursor.
*/
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
StatTable *pTab = (StatTable *)pVTab;
StatCursor *pCsr;
int rc;
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
if( pCsr==0 ){
rc = SQLITE_NOMEM;
}else{
char *zSql;
memset(pCsr, 0, sizeof(StatCursor));
pCsr->base.pVtab = pVTab;
zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
"SELECT name, rootpage, type"
" FROM \"%w\".sqlite_master WHERE rootpage!=0"
" ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
if( rc!=SQLITE_OK ){
sqlite3_free(pCsr);
pCsr = 0;
}
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
return rc;
}
static void statClearPage(StatPage *p){
int i;
if( p->aCell ){
for(i=0; i<p->nCell; i++){
sqlite3_free(p->aCell[i].aOvfl);
}
sqlite3_free(p->aCell);
}
sqlite3PagerUnref(p->pPg);
sqlite3_free(p->zPath);
memset(p, 0, sizeof(StatPage));
}
static void statResetCsr(StatCursor *pCsr){
int i;
sqlite3_reset(pCsr->pStmt);
for(i=0; i<ArraySize(pCsr->aPage); i++){
statClearPage(&pCsr->aPage[i]);
}
pCsr->iPage = 0;
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
}
/*
** Close a statvfs cursor.
*/
static int statClose(sqlite3_vtab_cursor *pCursor){
StatCursor *pCsr = (StatCursor *)pCursor;
statResetCsr(pCsr);
sqlite3_finalize(pCsr->pStmt);
sqlite3_free(pCsr);
return SQLITE_OK;
}
static void getLocalPayload(
int nUsable, /* Usable bytes per page */
u8 flags, /* Page flags */
int nTotal, /* Total record (payload) size */
int *pnLocal /* OUT: Bytes stored locally */
){
int nLocal;
int nMinLocal;
int nMaxLocal;
if( flags==0x0D ){ /* Table leaf node */
nMinLocal = (nUsable - 12) * 32 / 255 - 23;
nMaxLocal = nUsable - 35;
}else{ /* Index interior and leaf nodes */
nMinLocal = (nUsable - 12) * 32 / 255 - 23;
nMaxLocal = (nUsable - 12) * 64 / 255 - 23;
}
nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
if( nLocal>nMaxLocal ) nLocal = nMinLocal;
*pnLocal = nLocal;
}
static int statDecodePage(Btree *pBt, StatPage *p){
int nUnused;
int iOff;
int nHdr;
int isLeaf;
int szPage;
u8 *aData = sqlite3PagerGetData(p->pPg);
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
p->flags = aHdr[0];
p->nCell = get2byte(&aHdr[3]);
p->nMxPayload = 0;
isLeaf = (p->flags==0x0A || p->flags==0x0D);
nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
nUnused += (int)aHdr[7];
iOff = get2byte(&aHdr[1]);
while( iOff ){
nUnused += get2byte(&aData[iOff+2]);
iOff = get2byte(&aData[iOff]);
}
p->nUnused = nUnused;
p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
szPage = sqlite3BtreeGetPageSize(pBt);
if( p->nCell ){
int i; /* Used to iterate through cells */
int nUsable; /* Usable bytes per page */
sqlite3BtreeEnter(pBt);
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
sqlite3BtreeLeave(pBt);
p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
if( p->aCell==0 ) return SQLITE_NOMEM;
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
for(i=0; i<p->nCell; i++){
StatCell *pCell = &p->aCell[i];
iOff = get2byte(&aData[nHdr+i*2]);
if( !isLeaf ){
pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
iOff += 4;
}
if( p->flags==0x05 ){
/* A table interior node. nPayload==0. */
}else{
u32 nPayload; /* Bytes of payload total (local+overflow) */
int nLocal; /* Bytes of payload stored locally */
iOff += getVarint32(&aData[iOff], nPayload);
if( p->flags==0x0D ){
u64 dummy;
iOff += sqlite3GetVarint(&aData[iOff], &dummy);
}
if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
pCell->nLocal = nLocal;
assert( nLocal>=0 );
assert( nPayload>=(u32)nLocal );
assert( nLocal<=(nUsable-35) );
if( nPayload>(u32)nLocal ){
int j;
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
for(j=1; j<nOvfl; j++){
int rc;
u32 iPrev = pCell->aOvfl[j-1];
DbPage *pPg = 0;
rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
if( rc!=SQLITE_OK ){
assert( pPg==0 );
return rc;
}
pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg));
sqlite3PagerUnref(pPg);
}
}
}
}
}
return SQLITE_OK;
}
/*
** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
** the current value of pCsr->iPageno.
*/
static void statSizeAndOffset(StatCursor *pCsr){
StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_file *fd;
sqlite3_int64 x[2];
/* The default page size and offset */
pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
/* If connected to a ZIPVFS backend, override the page size and
** offset with actual values obtained from ZIPVFS.
*/
fd = sqlite3PagerFile(pPager);
x[0] = pCsr->iPageno;
if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
pCsr->iOffset = x[0];
pCsr->szPage = (int)x[1];
}
}
/*
** Move a statvfs cursor to the next entry in the file.
*/
static int statNext(sqlite3_vtab_cursor *pCursor){
int rc;
int nPayload;
char *z;
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable *)pCursor->pVtab;
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
statNextRestart:
if( pCsr->aPage[0].pPg==0 ){
rc = sqlite3_step(pCsr->pStmt);
if( rc==SQLITE_ROW ){
int nPage;
u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
sqlite3PagerPagecount(pPager, &nPage);
if( nPage==0 ){
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
}
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
pCsr->aPage[0].iPgno = iRoot;
pCsr->aPage[0].iCell = 0;
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
pCsr->iPage = 0;
if( z==0 ) rc = SQLITE_NOMEM;
}else{
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
}
}else{
/* Page p itself has already been visited. */
StatPage *p = &pCsr->aPage[pCsr->iPage];
while( p->iCell<p->nCell ){
StatCell *pCell = &p->aCell[p->iCell];
if( pCell->iOvfl<pCell->nOvfl ){
int nUsable;
sqlite3BtreeEnter(pBt);
nUsable = sqlite3BtreeGetPageSize(pBt) -
sqlite3BtreeGetReserveNoMutex(pBt);
sqlite3BtreeLeave(pBt);
pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
pCsr->zPagetype = "overflow";
pCsr->nCell = 0;
pCsr->nMxPayload = 0;
pCsr->zPath = z = sqlite3_mprintf(
"%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
);
if( pCell->iOvfl<pCell->nOvfl-1 ){
pCsr->nUnused = 0;
pCsr->nPayload = nUsable - 4;
}else{
pCsr->nPayload = pCell->nLastOvfl;
pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
}
pCell->iOvfl++;
statSizeAndOffset(pCsr);
return z==0 ? SQLITE_NOMEM : SQLITE_OK;
}
if( p->iRightChildPg ) break;
p->iCell++;
}
if( !p->iRightChildPg || p->iCell>p->nCell ){
statClearPage(p);
if( pCsr->iPage==0 ) return statNext(pCursor);
pCsr->iPage--;
goto statNextRestart; /* Tail recursion */
}
pCsr->iPage++;
assert( p==&pCsr->aPage[pCsr->iPage-1] );
if( p->iCell==p->nCell ){
p[1].iPgno = p->iRightChildPg;
}else{
p[1].iPgno = p->aCell[p->iCell].iChildPg;
}
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
p[1].iCell = 0;
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
p->iCell++;
if( z==0 ) rc = SQLITE_NOMEM;
}
/* Populate the StatCursor fields with the values to be returned
** by the xColumn() and xRowid() methods.
*/
if( rc==SQLITE_OK ){
int i;
StatPage *p = &pCsr->aPage[pCsr->iPage];
pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
pCsr->iPageno = p->iPgno;
rc = statDecodePage(pBt, p);
if( rc==SQLITE_OK ){
statSizeAndOffset(pCsr);
switch( p->flags ){
case 0x05: /* table internal */
case 0x02: /* index internal */
pCsr->zPagetype = "internal";
break;
case 0x0D: /* table leaf */
case 0x0A: /* index leaf */
pCsr->zPagetype = "leaf";
break;
default:
pCsr->zPagetype = "corrupted";
break;
}
pCsr->nCell = p->nCell;
pCsr->nUnused = p->nUnused;
pCsr->nMxPayload = p->nMxPayload;
pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
if( z==0 ) rc = SQLITE_NOMEM;
nPayload = 0;
for(i=0; i<p->nCell; i++){
nPayload += p->aCell[i].nLocal;
}
pCsr->nPayload = nPayload;
}
}
return rc;
}
static int statEof(sqlite3_vtab_cursor *pCursor){
StatCursor *pCsr = (StatCursor *)pCursor;
return pCsr->isEof;
}
static int statFilter(
sqlite3_vtab_cursor *pCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
StatCursor *pCsr = (StatCursor *)pCursor;
statResetCsr(pCsr);
return statNext(pCursor);
}
static int statColumn(
sqlite3_vtab_cursor *pCursor,
sqlite3_context *ctx,
int i
){
StatCursor *pCsr = (StatCursor *)pCursor;
switch( i ){
case 0: /* name */
sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
break;
case 1: /* path */
sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
break;
case 2: /* pageno */
sqlite3_result_int64(ctx, pCsr->iPageno);
break;
case 3: /* pagetype */
sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
break;
case 4: /* ncell */
sqlite3_result_int(ctx, pCsr->nCell);
break;
case 5: /* payload */
sqlite3_result_int(ctx, pCsr->nPayload);
break;
case 6: /* unused */
sqlite3_result_int(ctx, pCsr->nUnused);
break;
case 7: /* mx_payload */
sqlite3_result_int(ctx, pCsr->nMxPayload);
break;
case 8: /* pgoffset */
sqlite3_result_int64(ctx, pCsr->iOffset);
break;
default: /* pgsize */
assert( i==9 );
sqlite3_result_int(ctx, pCsr->szPage);
break;
}
return SQLITE_OK;
}
static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
StatCursor *pCsr = (StatCursor *)pCursor;
*pRowid = pCsr->iPageno;
return SQLITE_OK;
}
/*
** Invoke this routine to register the "dbstat" virtual table module
*/
SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){
static sqlite3_module dbstat_module = {
0, /* iVersion */
statConnect, /* xCreate */
statConnect, /* xConnect */
statBestIndex, /* xBestIndex */
statDisconnect, /* xDisconnect */
statDisconnect, /* xDestroy */
statOpen, /* xOpen - open a cursor */
statClose, /* xClose - close a cursor */
statFilter, /* xFilter - configure scan constraints */
statNext, /* xNext - advance a cursor */
statEof, /* xEof - check for end of scan */
statColumn, /* xColumn - read data */
statRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
}
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
/************** End of dbstat.c **********************************************/
|
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
39 40 41 42 43 44 45 |
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
| | < < < < < < > > > | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
** Provide the ability to override linkage features of the interface.
*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
#ifndef SQLITE_STDCALL
# define SQLITE_STDCALL
#endif
/*
** These no-op macros are used in front of interfaces to mark those
** interfaces as either deprecated or experimental. New applications
** should not use deprecated interfaces - they are supported for backwards
** compatibility only. Application writers should be aware that
** experimental interfaces are subject to change in point releases.
|
| ︙ | ︙ | |||
110 111 112 113 114 115 116 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.10.1" #define SQLITE_VERSION_NUMBER 3008010 #define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
145 146 147 148 149 150 151 | ** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void); SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void); SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** ** ^The sqlite3_compileoption_used() function returns 0 or 1 ** indicating whether the specified option was defined at ** compile time. ^The SQLITE_ prefix may be omitted from the |
| ︙ | ︙ | |||
172 173 174 175 176 177 178 | ** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS | | | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | ** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName); SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N); #endif /* ** CAPI3REF: Test To See If The Library Is Threadsafe ** ** ^The sqlite3_threadsafe() function returns zero if and only if ** SQLite was compiled with mutexing code omitted due to the |
| ︙ | ︙ | |||
212 213 214 215 216 217 218 | ** sqlite3_threadsafe() function shows only the compile-time setting of ** thread safety, not any run-time changes to that setting made by ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() ** is unchanged by calls to sqlite3_config().)^ ** ** See the [threading mode] documentation for additional information. */ | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
** sqlite3_threadsafe() function shows only the compile-time setting of
** thread safety, not any run-time changes to that setting made by
** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
** is unchanged by calls to sqlite3_config().)^
**
** See the [threading mode] documentation for additional information.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
** the opaque structure named "sqlite3". It is useful to think of an sqlite3
|
| ︙ | ︙ | |||
269 270 271 272 273 274 275 276 277 278 279 280 281 282 | */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** | > | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | */ #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection ** DESTRUCTOR: sqlite3 ** ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors ** for the [sqlite3] object. ** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if ** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** |
| ︙ | ︙ | |||
308 309 310 311 312 313 314 | ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ | | | > | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | ** must be either a NULL ** pointer or an [sqlite3] object pointer obtained ** from [sqlite3_open()], [sqlite3_open16()], or ** [sqlite3_open_v2()], and not previously closed. ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*); SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface ** METHOD: sqlite3 ** ** The sqlite3_exec() interface is a convenience wrapper around ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** ** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, |
| ︙ | ︙ | |||
379 380 381 382 383 384 385 | ** is a valid and open [database connection]. ** <li> The application must not close the [database connection] specified by ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. ** <li> The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. ** </ul> */ | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | ** is a valid and open [database connection]. ** <li> The application must not close the [database connection] specified by ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. ** <li> The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. ** </ul> */ SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ char **errmsg /* Error msg written here */ ); |
| ︙ | ︙ | |||
1339 1340 1341 1342 1343 1344 1345 | ** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for ** sqlite3_os_init() and sqlite3_os_end(). An application-supplied ** implementation of sqlite3_os_init() or sqlite3_os_end() ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ | | | | | | 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 | ** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for ** sqlite3_os_init() and sqlite3_os_end(). An application-supplied ** implementation of sqlite3_os_init() or sqlite3_os_end() ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void); SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void); SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void); SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void); /* ** CAPI3REF: Configuring The SQLite Library ** ** The sqlite3_config() interface is used to make global configuration ** changes to SQLite in order to tune SQLite to the specific needs of ** the application. The default configuration is recommended for most |
| ︙ | ︙ | |||
1373 1374 1375 1376 1377 1378 1379 | ** vary depending on the [configuration option] ** in the first argument. ** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ | | > | | 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 | ** vary depending on the [configuration option] ** in the first argument. ** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections ** METHOD: sqlite3 ** ** The sqlite3_db_config() interface is used to make configuration ** changes to a [database connection]. The interface is similar to ** [sqlite3_config()] except that the changes apply to a single ** [database connection] (specified in the first argument). ** ** The second argument to sqlite3_db_config(D,V,...) is the ** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if ** the call is considered successful. */ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines ** ** An instance of this object defines the interface between SQLite ** and low-level memory allocation routines. ** |
| ︙ | ︙ | |||
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 | #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ | > | > | 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 | #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff); /* ** CAPI3REF: Last Insert Rowid ** METHOD: sqlite3 ** ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) ** has a unique 64-bit signed ** integer key called the [ROWID | "rowid"]. ^The rowid is always available ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those ** names are not also used by explicitly declared columns. ^If ** the table has a column of type [INTEGER PRIMARY KEY] then that column |
| ︙ | ︙ | |||
1930 1931 1932 1933 1934 1935 1936 | ** If a separate thread performs a new [INSERT] on the same ** database connection while the [sqlite3_last_insert_rowid()] ** function is running and thus changes the last insert [rowid], ** then the value returned by [sqlite3_last_insert_rowid()] is ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ | | > | 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 | ** If a separate thread performs a new [INSERT] on the same ** database connection while the [sqlite3_last_insert_rowid()] ** function is running and thus changes the last insert [rowid], ** then the value returned by [sqlite3_last_insert_rowid()] is ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*); /* ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 ** ** ^This function returns the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** ^Executing any other type of SQL statement does not modify the value ** returned by this function. ** |
| ︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 | ** See also the [sqlite3_total_changes()] interface, the ** [count_changes pragma], and the [changes() SQL function]. ** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ | | > | > | 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 | ** See also the [sqlite3_total_changes()] interface, the ** [count_changes pragma], and the [changes() SQL function]. ** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified ** METHOD: sqlite3 ** ** ^This function returns the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as ** part of trigger programs. ^Executing any other type of SQL statement ** does not affect the value returned by sqlite3_total_changes(). ** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. ** ** See also the [sqlite3_changes()] interface, the ** [count_changes pragma], and the [total_changes() SQL function]. ** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. */ SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query ** METHOD: sqlite3 ** ** ^This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically ** called in response to a user action such as pressing "Cancel" ** or Ctrl-C where the user wants a long query operation to halt ** immediately. ** |
| ︙ | ︙ | |||
2044 2045 2046 2047 2048 2049 2050 | ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. ** ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ | | | 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 | ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. ** ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete ** ** These routines are useful during command-line input to determine if the ** currently entered text seems to form a complete SQL statement or ** if additional input is needed before sending the text into |
| ︙ | ︙ | |||
2079 2080 2081 2082 2083 2084 2085 | ** ** The input to [sqlite3_complete()] must be a zero-terminated ** UTF-8 string. ** ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ | | | > | 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 |
**
** The input to [sqlite3_complete()] must be a zero-terminated
** UTF-8 string.
**
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
** KEYWORDS: {busy-handler callback} {busy handler}
** METHOD: sqlite3
**
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
** that might be invoked with argument P whenever
** an attempt is made to access a database table associated with
** [database connection] D when another thread
** or process has the table locked.
** The sqlite3_busy_handler() interface is used to implement
|
| ︙ | ︙ | |||
2140 2141 2142 2143 2144 2145 2146 | ** database connection that invoked the busy handler. In other words, ** the busy handler is not reentrant. Any such actions ** result in undefined behavior. ** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ | | > | > | 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 | ** database connection that invoked the busy handler. In other words, ** the busy handler is not reentrant. Any such actions ** result in undefined behavior. ** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout ** METHOD: sqlite3 ** ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps ** for a specified amount of time when a table is locked. ^The handler ** will sleep multiple times until at least "ms" milliseconds of sleeping ** have accumulated. ^After at least "ms" milliseconds of sleeping, ** the handler returns 0 which causes [sqlite3_step()] to return ** [SQLITE_BUSY]. ** ** ^Calling this routine with an argument less than or equal to zero ** turns off all busy handlers. ** ** ^(There can only be a single busy handler for a particular ** [database connection] at any given moment. If another busy handler ** was defined (using [sqlite3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ ** ** See also: [PRAGMA busy_timeout] */ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** ** Definition: A <b>result table</b> is memory data structure created by the ** [sqlite3_get_table()] interface. A result table records the ** complete query results from one or more queries. |
| ︙ | ︙ | |||
2236 2237 2238 2239 2240 2241 2242 | ** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access ** to any internal data structures of SQLite. It uses only the public ** interface defined here. As a consequence, errors that occur in the ** wrapper layer outside of the internal [sqlite3_exec()] call are not ** reflected in subsequent calls to [sqlite3_errcode()] or ** [sqlite3_errmsg()]. */ | | | | 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 | ** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access ** to any internal data structures of SQLite. It uses only the public ** interface defined here. As a consequence, errors that occur in the ** wrapper layer outside of the internal [sqlite3_exec()] call are not ** reflected in subsequent calls to [sqlite3_errcode()] or ** [sqlite3_errmsg()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** These routines understand most of the common K&R formatting options, |
| ︙ | ︙ | |||
2350 2351 2352 2353 2354 2355 2356 | ** character.)^ The "%w" formatting option is intended for safely inserting ** table and column names into a constructed SQL statement. ** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ | | | | | | 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 | ** character.)^ The "%w" formatting option is intended for safely inserting ** table and column names into a constructed SQL statement. ** ** ^(The "%z" formatting option works like "%s" but with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string.)^ */ SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...); SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list); SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...); SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list); /* ** CAPI3REF: Memory Allocation Subsystem ** ** The SQLite core uses these three routines for all of its own ** internal memory allocation needs. "Core" in the previous sentence ** does not include operating-system specific VFS implementation. The |
| ︙ | ︙ | |||
2443 2444 2445 2446 2447 2448 2449 | ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** ** The application must not read or write any part of ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ | | | | | | | | 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 | ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** ** The application must not read or write any part of ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int); SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64); SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int); SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64); SQLITE_API void SQLITE_STDCALL sqlite3_free(void*); SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*); /* ** CAPI3REF: Memory Allocator Statistics ** ** SQLite provides these two interfaces for reporting on the status ** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] ** routines, which form the built-in memory allocation subsystem. |
| ︙ | ︙ | |||
2473 2474 2475 2476 2477 2478 2479 | ** ** ^The memory high-water mark is reset to the current value of ** [sqlite3_memory_used()] if and only if the parameter to ** [sqlite3_memory_highwater()] is true. ^The value returned ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ | | | | 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 | ** ** ^The memory high-water mark is reset to the current value of ** [sqlite3_memory_used()] if and only if the parameter to ** [sqlite3_memory_highwater()] is true. ^The value returned ** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Pseudo-Random Number Generator ** ** SQLite contains a high-quality pseudo-random number generator (PRNG) used to ** select random [ROWID | ROWIDs] when inserting new records into a table that ** already uses the largest possible [ROWID]. The PRNG is also used for |
| ︙ | ︙ | |||
2497 2498 2499 2500 2501 2502 2503 | ** seeded using randomness obtained from the xRandomness method of ** the default [sqlite3_vfs] object. ** ^If the previous call to this routine had an N of 1 or more and a ** non-NULL P then the pseudo-randomness is generated ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ | | > | 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 | ** seeded using randomness obtained from the xRandomness method of ** the default [sqlite3_vfs] object. ** ^If the previous call to this routine had an N of 1 or more and a ** non-NULL P then the pseudo-randomness is generated ** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks ** METHOD: sqlite3 ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled ** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], ** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various ** points during the compilation process, as logic is being created |
| ︙ | ︙ | |||
2579 2580 2581 2582 2583 2584 2585 | ** ** ^Note that the authorizer callback is invoked only during ** [sqlite3_prepare()] or its variants. Authorization is not ** performed during statement evaluation in [sqlite3_step()], unless ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ | | | 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 | ** ** ^Note that the authorizer callback is invoked only during ** [sqlite3_prepare()] or its variants. Authorization is not ** performed during statement evaluation in [sqlite3_step()], unless ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData ); /* ** CAPI3REF: Authorizer Return Codes |
| ︙ | ︙ | |||
2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 | #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ #define SQLITE_COPY 0 /* No longer used */ #define SQLITE_RECURSIVE 33 /* NULL NULL */ /* ** CAPI3REF: Tracing And Profiling Functions ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. ** ** ^The callback function registered by sqlite3_trace() is invoked at ** various times when an SQL statement is being run by [sqlite3_step()]. ** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the | > | 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 | #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ #define SQLITE_COPY 0 /* No longer used */ #define SQLITE_RECURSIVE 33 /* NULL NULL */ /* ** CAPI3REF: Tracing And Profiling Functions ** METHOD: sqlite3 ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. ** ** ^The callback function registered by sqlite3_trace() is invoked at ** various times when an SQL statement is being run by [sqlite3_step()]. ** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the |
| ︙ | ︙ | |||
2683 2684 2685 2686 2687 2688 2689 | ** time is in units of nanoseconds, however the current implementation ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite ** might provide greater resolution on the profiler callback. The ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ | | | > | 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 | ** time is in units of nanoseconds, however the current implementation ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite ** might provide greater resolution on the profiler callback. The ** sqlite3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: Query Progress Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** |
| ︙ | ︙ | |||
2718 2719 2720 2721 2722 2723 2724 | ** ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** */ | | > | 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 | ** ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** */ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection ** CONSTRUCTOR: sqlite3 ** ** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for ** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte ** order for sqlite3_open16(). ^(A [database connection] handle is usually ** returned in *ppDb, even if an error occurs. The only exception is that ** if SQLite is unable to allocate memory to hold the [sqlite3] object, |
| ︙ | ︙ | |||
2946 2947 2948 2949 2950 2951 2952 | ** ** <b>Note to Windows Runtime users:</b> The temporary directory must be set ** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various ** features that require the use of temporary files may fail. ** ** See also: [sqlite3_temp_directory] */ | | | | | 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 | ** ** <b>Note to Windows Runtime users:</b> The temporary directory must be set ** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various ** features that require the use of temporary files may fail. ** ** See also: [sqlite3_temp_directory] */ SQLITE_API int SQLITE_STDCALL sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); SQLITE_API int SQLITE_STDCALL sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); SQLITE_API int SQLITE_STDCALL sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ); /* |
| ︙ | ︙ | |||
3000 3001 3002 3003 3004 3005 3006 | ** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that SQLite passed into the xOpen ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. */ | | | | > | 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 | ** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that SQLite passed into the xOpen ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam); SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64); /* ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** ** ^If the most recent sqlite3_* API call associated with ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. ** If the most recent API call was successful, ** then the return value from sqlite3_errcode() is undefined. |
| ︙ | ︙ | |||
3045 3046 3047 3048 3049 3050 3051 | ** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after ** all calls to the interfaces listed here are completed. ** ** If an interface fails with SQLITE_MISUSE, that means the interface ** was invoked incorrectly by the application. In that case, the ** error code and message may or may not be set. */ | | | | | | | | > > > | > | | | < | | < < < > | 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 |
** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
** all calls to the interfaces listed here are completed.
**
** If an interface fails with SQLITE_MISUSE, that means the interface
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
/*
** CAPI3REF: Prepared Statement Object
** KEYWORDS: {prepared statement} {prepared statements}
**
** An instance of this object represents a single SQL statement that
** has been compiled into binary form and is ready to be evaluated.
**
** Think of each SQL statement as a separate computer program. The
** original SQL text is source code. A prepared statement object
** is the compiled object code. All SQL must be converted into a
** prepared statement before it can be run.
**
** The life-cycle of a prepared statement object usually goes like this:
**
** <ol>
** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
** <li> Bind values to [parameters] using the sqlite3_bind_*()
** interfaces.
** <li> Run the SQL by calling [sqlite3_step()] one or more times.
** <li> Reset the prepared statement using [sqlite3_reset()] then go back
** to step 2. Do this zero or more times.
** <li> Destroy the object using [sqlite3_finalize()].
** </ol>
*/
typedef struct sqlite3_stmt sqlite3_stmt;
/*
** CAPI3REF: Run-time Limits
** METHOD: sqlite3
**
** ^(This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
** [database connection] whose limit is to be set or queried. The
** second parameter is one of the [limit categories] that define a
** class of constructs to be size limited. The third parameter is the
** new limit for that construct.)^
|
| ︙ | ︙ | |||
3116 3117 3118 3119 3120 3121 3122 | ** attack. Developers might also want to use the [sqlite3_set_authorizer()] ** interface to further control untrusted SQL. The size of the database ** created by an untrusted script can be contained using the ** [max_page_count] [PRAGMA]. ** ** New run-time limit categories may be added in future releases. */ | | | 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 |
** attack. Developers might also want to use the [sqlite3_set_authorizer()]
** interface to further control untrusted SQL. The size of the database
** created by an untrusted script can be contained using the
** [max_page_count] [PRAGMA].
**
** New run-time limit categories may be added in future releases.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
** KEYWORDS: {limit category} {*limit categories}
**
** These constants define various performance limits
** that can be lowered at run-time using [sqlite3_limit()].
|
| ︙ | ︙ | |||
3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 |
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()]. The database connection must not have been closed.
| > > | 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 |
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
**
** To execute an SQL query, it must first be compiled into a byte-code
** program using one of these routines.
**
** The first argument, "db", is a [database connection] obtained from a
** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
** [sqlite3_open16()]. The database connection must not have been closed.
|
| ︙ | ︙ | |||
3266 3267 3268 3269 3270 3271 3272 | ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** </li> ** </ol> */ | | | | | > | > | 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 | ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** </li> ** </ol> */ SQLITE_API int SQLITE_STDCALL sqlite3_prepare( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int SQLITE_STDCALL sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); /* ** CAPI3REF: Retrieving Statement SQL ** METHOD: sqlite3_stmt ** ** ^This interface can be used to retrieve a saved copy of the original ** SQL text used to create a [prepared statement] if that statement was ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database ** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** and only if the [prepared statement] X makes no direct changes to ** the content of the database file. ** ** Note that [application-defined SQL functions] or ** [virtual tables] might change the database indirectly as a side effect. |
| ︙ | ︙ | |||
3333 3334 3335 3336 3337 3338 3339 | ** since the statements themselves do not actually modify the database but ** rather they control the timing of when other statements modify the ** database. ^The [ATTACH] and [DETACH] statements also cause ** sqlite3_stmt_readonly() to return true since, while those statements ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. */ | | > | | 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 |
** since the statements themselves do not actually modify the database but
** rather they control the timing of when other statements modify the
** database. ^The [ATTACH] and [DETACH] statements also cause
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
** [prepared statement] S has been stepped at least once using
** [sqlite3_step(S)] but has not run to completion and/or has not
** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
** interface returns false if S is a NULL pointer. If S is not a
** NULL pointer and is not a pointer to a valid [prepared statement]
** object, then the behavior is undefined and probably undesirable.
**
** This interface can be used in combination [sqlite3_next_stmt()]
** to locate all prepared statements associated with a database
** connection that are in need of being reset. This can be used,
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
** that can be stored in a database table. SQLite uses dynamic typing
|
| ︙ | ︙ | |||
3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 |
*/
typedef struct sqlite3_context sqlite3_context;
/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li> ?
| > | 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 |
*/
typedef struct sqlite3_context sqlite3_context;
/*
** CAPI3REF: Binding Values To Prepared Statements
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
** METHOD: sqlite3_stmt
**
** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
** literals may be replaced by a [parameter] that matches one of following
** templates:
**
** <ul>
** <li> ?
|
| ︙ | ︙ | |||
3513 3514 3515 3516 3517 3518 3519 | ** [SQLITE_MAX_LENGTH]. ** ^[SQLITE_RANGE] is returned if the parameter ** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. ** ** See also: [sqlite3_bind_parameter_count()], ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ | | | | | | | | | | | | > | > | 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 |
** [SQLITE_MAX_LENGTH].
** ^[SQLITE_RANGE] is returned if the parameter
** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails.
**
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
/*
** CAPI3REF: Number Of SQL Parameters
** METHOD: sqlite3_stmt
**
** ^This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
** placeholders for values that are [sqlite3_bind_blob | bound]
** to the parameters at a later time.
**
** ^(This routine actually returns the index of the largest (rightmost)
** parameter. For all forms except ?NNN, this will correspond to the
** number of unique parameters. If parameters of the ?NNN form are used,
** there may be gaps in the list.)^
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
** METHOD: sqlite3_stmt
**
** ^The sqlite3_bind_parameter_name(P,N) interface returns
** the name of the N-th [SQL parameter] in the [prepared statement] P.
** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
** respectively.
** In other words, the initial ":" or "$" or "@" or "?"
|
| ︙ | ︙ | |||
3572 3573 3574 3575 3576 3577 3578 | ** originally specified as UTF-16 in [sqlite3_prepare16()] or ** [sqlite3_prepare16_v2()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ | | > | > | > | > | 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 | ** originally specified as UTF-16 in [sqlite3_prepare16()] or ** [sqlite3_prepare16_v2()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int); /* ** CAPI3REF: Index Of A Parameter With A Given Name ** METHOD: sqlite3_stmt ** ** ^Return the index of an SQL parameter given its name. ^The ** index value returned is suitable for use as the second ** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero ** is returned if no matching parameter is found. ^The parameter ** name must be given in UTF-8 even if the original statement ** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. ** ** See also: [sqlite3_bind_blob|sqlite3_bind()], ** [sqlite3_bind_parameter_count()], and ** [sqlite3_bind_parameter_index()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement ** METHOD: sqlite3_stmt ** ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset ** the [sqlite3_bind_blob | bindings] on a [prepared statement]. ** ^Use this routine to reset all host parameters to NULL. */ SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*); /* ** CAPI3REF: Number Of Columns In A Result Set ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL ** statement that does not return data (for example an [UPDATE]). ** ** See also: [sqlite3_data_count()] */ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Column Names In A Result Set ** METHOD: sqlite3_stmt ** ** ^These routines return the name assigned to a particular column ** in the result set of a [SELECT] statement. ^The sqlite3_column_name() ** interface returns a pointer to a zero-terminated UTF-8 string ** and sqlite3_column_name16() returns a pointer to a zero-terminated ** UTF-16 string. ^The first parameter is the [prepared statement] ** that implements the [SELECT] statement. ^The second parameter is the |
| ︙ | ︙ | |||
3636 3637 3638 3639 3640 3641 3642 | ** NULL pointer is returned. ** ** ^The name of a result column is the value of the "AS" clause for ** that column, if there is an AS clause. If there is no AS clause ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ | | | > | 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 | ** NULL pointer is returned. ** ** ^The name of a result column is the value of the "AS" clause for ** that column, if there is an AS clause. If there is no AS clause ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result ** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in ** [SELECT] statement. ** ^The name of the database or table or column can be returned as ** either a UTF-8 or UTF-16 string. ^The _database_ routines return ** the database name, the _table_ routines return the table name, and |
| ︙ | ︙ | |||
3684 3685 3686 3687 3688 3689 3690 | ** undefined. ** ** If two or more threads call one or more ** [sqlite3_column_database_name | column metadata interfaces] ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ | | | | | | | > | 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 | ** undefined. ** ** If two or more threads call one or more ** [sqlite3_column_database_name | column metadata interfaces] ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int); SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int); SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int); /* ** CAPI3REF: Declared Datatype Of A Query Result ** METHOD: sqlite3_stmt ** ** ^(The first parameter is a [prepared statement]. ** If this statement is a [SELECT] statement and the Nth column of the ** returned result set of that [SELECT] is a table column (not an ** expression or subquery) then the declared type of the table ** column is returned.)^ ^If the Nth column of the result set is an ** expression or subquery, then a NULL pointer is returned. |
| ︙ | ︙ | |||
3720 3721 3722 3723 3724 3725 3726 | ** ^SQLite uses dynamic run-time typing. ^So just because a column ** is declared to contain a particular type does not mean that the ** data stored in that column is of the declared type. SQLite is ** strongly typed, but the typing is dynamic not static. ^Type ** is associated with individual values, not with the containers ** used to hold those values. */ | | | > | 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 | ** ^SQLite uses dynamic run-time typing. ^So just because a column ** is declared to contain a particular type does not mean that the ** data stored in that column is of the declared type. SQLite is ** strongly typed, but the typing is dynamic not static. ^Type ** is associated with individual values, not with the containers ** used to hold those values. */ SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int); /* ** CAPI3REF: Evaluate An SQL Statement ** METHOD: sqlite3_stmt ** ** After a [prepared statement] has been prepared using either ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy ** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function ** must be called one or more times to evaluate the statement. ** ** The details of the behavior of the sqlite3_step() interface depend |
| ︙ | ︙ | |||
3800 3801 3802 3803 3804 3805 3806 | ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly ** by sqlite3_step(). The use of the "v2" interface is recommended. */ | | > | | 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 | ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead ** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly ** by sqlite3_step(). The use of the "v2" interface is recommended. */ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set ** METHOD: sqlite3_stmt ** ** ^The sqlite3_data_count(P) interface returns the number of columns in the ** current row of the result set of [prepared statement] P. ** ^If prepared statement P does not have results ready to return ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of ** interfaces) then sqlite3_data_count(P) returns 0. ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. ** ^The sqlite3_data_count(P) routine returns 0 if the previous call to ** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) ** will return non-zero if previous call to [sqlite3_step](P) returned ** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] ** where it always returns zero since each step of that multi-step ** pragma returns 0 columns of data. ** ** See also: [sqlite3_column_count()] */ SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Fundamental Datatypes ** KEYWORDS: SQLITE_TEXT ** ** ^(Every value in SQLite has one of five fundamental datatypes: ** |
| ︙ | ︙ | |||
3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 |
# define SQLITE_TEXT 3
#endif
#define SQLITE3_TEXT 3
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
| > | 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 |
# define SQLITE_TEXT 3
#endif
#define SQLITE3_TEXT 3
/*
** CAPI3REF: Result Values From A Query
** KEYWORDS: {column access functions}
** METHOD: sqlite3_stmt
**
** These routines form the "result set" interface.
**
** ^These routines return information about a single column of the current
** result row of a query. ^In every case the first argument is a pointer
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
|
| ︙ | ︙ | |||
4016 4017 4018 4019 4020 4021 4022 | ** ** ^(If a memory allocation error occurs during the evaluation of any ** of these routines, a default value is returned. The default value ** is either the integer 0, the floating point number 0.0, or a NULL ** pointer. Subsequent calls to [sqlite3_errcode()] will return ** [SQLITE_NOMEM].)^ */ | | | | | | | | | | | > | 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 | ** ** ^(If a memory allocation error occurs during the evaluation of any ** of these routines, a default value is returned. The default value ** is either the integer 0, the floating point number 0.0, or a NULL ** pointer. Subsequent calls to [sqlite3_errcode()] will return ** [SQLITE_NOMEM].)^ */ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol); SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol); SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol); SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol); SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol); SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object ** DESTRUCTOR: sqlite3_stmt ** ** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors ** or if the statement is never been evaluated, then sqlite3_finalize() returns ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then ** sqlite3_finalize(S) returns the appropriate [error code] or ** [extended error code]. |
| ︙ | ︙ | |||
4052 4053 4054 4055 4056 4057 4058 | ** ** The application must finalize every [prepared statement] in order to avoid ** resource leaks. It is a grievous error for the application to try to use ** a prepared statement after it has been finalized. Any use of a prepared ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ | | > | 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 | ** ** The application must finalize every [prepared statement] in order to avoid ** resource leaks. It is a grievous error for the application to try to use ** a prepared statement after it has been finalized. Any use of a prepared ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt); /* ** CAPI3REF: Reset A Prepared Statement Object ** METHOD: sqlite3_stmt ** ** The sqlite3_reset() function is called to reset a [prepared statement] ** object back to its initial state, ready to be re-executed. ** ^Any SQL statement variables that had values bound to them using ** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. ** Use [sqlite3_clear_bindings()] to reset the bindings. ** |
| ︙ | ︙ | |||
4078 4079 4080 4081 4082 4083 4084 | ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code]. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ | | > | 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 |
** ^If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite3_reset(S)] returns an appropriate [error code].
**
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
** of existing SQL functions or aggregates. The only differences between
** these routines are the text encoding expected for
** the second parameter (the name of the function being created)
** and the presence or absence of a destructor callback for
|
| ︙ | ︙ | |||
4177 4178 4179 4180 4181 4182 4183 | ** ^Built-in functions may be overloaded by new application-defined functions. ** ** ^An application-defined function is permitted to call other ** SQLite interfaces. However, such calls must not ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ | | | | | 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 | ** ^Built-in functions may be overloaded by new application-defined functions. ** ** ^An application-defined function is permitted to call other ** SQLite interfaces. However, such calls must not ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ SQLITE_API int SQLITE_STDCALL sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2( sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), |
| ︙ | ︙ | |||
4243 4244 4245 4246 4247 4248 4249 | ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid ** the use of these functions. To encourage programmers to avoid ** these functions, we will not explain what they do. */ #ifndef SQLITE_OMIT_DEPRECATED | | | | | | | > | 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 |
** These functions are [deprecated]. In order to maintain
** backwards compatibility with older code, these functions continue
** to be supported. However, new applications should avoid
** the use of these functions. To encourage programmers to avoid
** these functions, we will not explain what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
/*
** CAPI3REF: Obtaining SQL Function Parameter Values
** METHOD: sqlite3_value
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
** the function or aggregate.
**
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
|
| ︙ | ︙ | |||
4297 4298 4299 4300 4301 4302 4303 | ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ | | | | | | | | | | | | | > | 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 | ** [sqlite3_value_text16()] can be invalidated by a subsequent call to ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], ** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. */ SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*); SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*); SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*); SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*); SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*); SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*); SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*); SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context ** METHOD: sqlite3_context ** ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** ** ^The first time the sqlite3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite ** allocates N of memory, zeroes out that memory, and returns a pointer |
| ︙ | ︙ | |||
4352 4353 4354 4355 4356 4357 4358 | ** [sqlite3_context | SQL function context] that is the first parameter ** to the xStep or xFinal callback routine that implements the aggregate ** function. ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ | | > | > | > | 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 | ** [sqlite3_context | SQL function context] that is the first parameter ** to the xStep or xFinal callback routine that implements the aggregate ** function. ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions ** METHOD: sqlite3_context ** ** ^The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) ** of the [sqlite3_create_function()] ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. ** ** This routine must be called from the same thread in which ** the application-defined function is running. */ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*); /* ** CAPI3REF: Database Connection For Functions ** METHOD: sqlite3_context ** ** ^The sqlite3_context_db_handle() interface returns a copy of ** the pointer to the [database connection] (the 1st parameter) ** of the [sqlite3_create_function()] ** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. */ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to ** multiple invocations of the same SQL function during query execution, under ** some circumstances the associated metadata may be preserved. An example ** of where this might be useful is in a regular-expression matching ** function. The compiled version of the regular expression can be stored as |
| ︙ | ︙ | |||
4429 4430 4431 4432 4433 4434 4435 | ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. */ | | | | 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 | ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. */ SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior ** ** These are special values for the destructor that is passed in as the ** final argument to routines like [sqlite3_result_blob()]. ^If the destructor |
| ︙ | ︙ | |||
4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 | */ typedef void (*sqlite3_destructor_type)(void*); #define SQLITE_STATIC ((sqlite3_destructor_type)0) #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) /* ** CAPI3REF: Setting The Result Of An SQL Function ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See ** [sqlite3_create_function()] and [sqlite3_create_function16()] ** for additional information. ** ** These functions work very much like the [parameter binding] family of | > | 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 | */ typedef void (*sqlite3_destructor_type)(void*); #define SQLITE_STATIC ((sqlite3_destructor_type)0) #define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) /* ** CAPI3REF: Setting The Result Of An SQL Function ** METHOD: sqlite3_context ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See ** [sqlite3_create_function()] and [sqlite3_create_function16()] ** for additional information. ** ** These functions work very much like the [parameter binding] family of |
| ︙ | ︙ | |||
4565 4566 4567 4568 4569 4570 4571 | ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received ** the [sqlite3_context] pointer, the results are undefined. */ | | | | | | | | | | | | | | | | | | | > | 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 |
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
/*
** CAPI3REF: Define New Collating Sequences
** METHOD: sqlite3
**
** ^These functions add, remove, or modify a [collation] associated
** with the [database connection] specified as the first argument.
**
** ^The name of the collation is a UTF-8 string
** for sqlite3_create_collation() and sqlite3_create_collation_v2()
** and a UTF-16 string in native byte order for sqlite3_create_collation16().
|
| ︙ | ︙ | |||
4665 4666 4667 4668 4669 4670 4671 | ** themselves rather than expecting SQLite to deal with it for them. ** This is different from every other SQLite interface. The inconsistency ** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ | | | | > | 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 | ** themselves rather than expecting SQLite to deal with it for them. ** This is different from every other SQLite interface. The inconsistency ** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation( sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); /* ** CAPI3REF: Collation Needed Callbacks ** METHOD: sqlite3 ** ** ^To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the ** [database connection] to be invoked whenever an undefined collation ** sequence is required. ** ** ^If the function is registered using the sqlite3_collation_needed() API, |
| ︙ | ︙ | |||
4714 4715 4716 4717 4718 4719 4720 | ** sequence function required. The fourth parameter is the name of the ** required collation sequence.)^ ** ** The callback function should register the desired collation using ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. */ | | | | | | | | | | 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 | ** sequence function required. The fourth parameter is the name of the ** required collation sequence.)^ ** ** The callback function should register the desired collation using ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or ** [sqlite3_create_collation_v2()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef SQLITE_HAS_CODEC /* ** Specify the key for an encrypted database. This routine should be ** called right after sqlite3_open(). ** ** The code to implement this API is not available in the public release ** of SQLite. */ SQLITE_API int SQLITE_STDCALL sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); SQLITE_API int SQLITE_STDCALL sqlite3_key_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The key */ ); /* ** Change the key on an open database. If the current database is not ** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the ** database is decrypted. ** ** The code to implement this API is not available in the public release ** of SQLite. */ SQLITE_API int SQLITE_STDCALL sqlite3_rekey( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The new key */ ); /* ** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ SQLITE_API void SQLITE_STDCALL sqlite3_activate_see( const char *zPassPhrase /* Activation phrase */ ); #endif #ifdef SQLITE_ENABLE_CEROD /* ** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod( const char *zPassPhrase /* Activation phrase */ ); #endif /* ** CAPI3REF: Suspend Execution For A Short Time ** |
| ︙ | ︙ | |||
4797 4798 4799 4800 4801 4802 4803 | ** ** ^SQLite implements this interface by calling the xSleep() ** method of the default [sqlite3_vfs] object. If the xSleep() method ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ | | | 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 | ** ** ^SQLite implements this interface by calling the xSleep() ** method of the default [sqlite3_vfs] object. If the xSleep() method ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int); /* ** CAPI3REF: Name Of The Folder Holding Temporary Files ** ** ^(If this global variable is made to point to a string which is ** the name of a folder (a.k.a. directory), then all temporary files ** created by SQLite when using a built-in [sqlite3_vfs | VFS] |
| ︙ | ︙ | |||
4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 |
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
**
** If certain kinds of errors occur on a statement within a multi-statement
** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
** transaction might be rolled back automatically. The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
| > | > | > | > | > | > | 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 |
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
** METHOD: sqlite3
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
** ^Autocommit mode is disabled by a [BEGIN] statement.
** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
**
** If certain kinds of errors occur on a statement within a multi-statement
** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
** transaction might be rolled back automatically. The only way to
** find out whether SQLite automatically rolled back the transaction after
** an error is to use this function.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
** METHOD: sqlite3_stmt
**
** ^The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. ^The [database connection]
** returned by sqlite3_db_handle is the same [database connection]
** that was the first argument
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
**
** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
** associated with database N of connection D. ^The main database file
** has the name "main". If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
** a NULL pointer is returned.
**
** ^The filename returned by this function is the output of the
** xFullPathname method of the [VFS]. ^In other words, the filename
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
*/
SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
** METHOD: sqlite3
**
** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
** METHOD: sqlite3
**
** ^This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
** then this interface returns a pointer to the first prepared statement
** associated with the database connection pDb. ^If no prepared statement
** satisfies the conditions of this routine, it returns NULL.
**
** The [database connection] pointer D in a call to
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
** METHOD: sqlite3
**
** ^The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is [COMMIT | committed].
** ^Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** ^The sqlite3_rollback_hook() interface registers a callback
** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
|
| ︙ | ︙ | |||
5015 5016 5017 5018 5019 5020 5021 | ** rolled back if an explicit "ROLLBACK" statement is executed, or ** an error or constraint causes an implicit rollback to occur. ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** ** See also the [sqlite3_update_hook()] interface. */ | | | > | 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 | ** rolled back if an explicit "ROLLBACK" statement is executed, or ** an error or constraint causes an implicit rollback to occur. ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** ** See also the [sqlite3_update_hook()] interface. */ SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument ** to be invoked whenever a row is updated, inserted or deleted in ** a rowid table. ** ^Any callback set by a previous call to this function ** for the same database connection is overridden. |
| ︙ | ︙ | |||
5066 5067 5068 5069 5070 5071 5072 | ** returns the P argument from the previous call ** on the same [database connection] D, or NULL for ** the first call on D. ** ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] ** interfaces. */ | | | 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 | ** returns the P argument from the previous call ** on the same [database connection] D, or NULL for ** the first call on D. ** ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()] ** interfaces. */ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook( sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache |
| ︙ | ︙ | |||
5106 5107 5108 5109 5110 5111 5112 | ** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ | | | > | | 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 | ** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory ** ** ^The sqlite3_release_memory() interface attempts to free N bytes ** of heap memory by deallocating non-essential memory allocations ** held by the database library. Memory used to cache database ** pages to improve performance is an example of non-essential memory. ** ^sqlite3_release_memory() returns the number of bytes actually freed, ** which might be more or less than the amount requested. ** ^The sqlite3_release_memory() routine is a no-op returning zero ** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** ** See also: [sqlite3_db_release_memory()] */ SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int); /* ** CAPI3REF: Free Memory Used By A Database Connection ** METHOD: sqlite3 ** ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the ** [sqlite3_release_memory()] interface, this interface is in effect even ** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is ** omitted. ** ** See also: [sqlite3_release_memory()] */ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size ** ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. ** ^SQLite strives to keep heap memory utilization below the soft heap |
| ︙ | ︙ | |||
5187 5188 5189 5190 5191 5192 5193 | ** the page cache is the predominate memory user in SQLite, most ** applications will achieve adequate soft heap limit enforcement without ** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** ** The circumstances under which SQLite will enforce the soft heap limit may ** changes in future releases of SQLite. */ | | | > | 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 | ** the page cache is the predominate memory user in SQLite, most ** applications will achieve adequate soft heap limit enforcement without ** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** ** The circumstances under which SQLite will enforce the soft heap limit may ** changes in future releases of SQLite. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface ** DEPRECATED ** ** This is a deprecated version of the [sqlite3_soft_heap_limit64()] ** interface. This routine is provided for historical compatibility ** only. All new applications should use the ** [sqlite3_soft_heap_limit64()] interface rather than this one. */ SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N); /* ** CAPI3REF: Extract Metadata About A Column Of A Table ** METHOD: sqlite3 ** ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns ** information about column C of table T in database D ** on [database connection] X.)^ ^The sqlite3_table_column_metadata() ** interface returns SQLITE_OK and fills in the non-NULL pointers in ** the final five arguments with appropriate values if the specified ** column exists. ^The sqlite3_table_column_metadata() interface returns |
| ︙ | ︙ | |||
5267 5268 5269 5270 5271 5272 5273 | ** auto increment: 0 ** </pre>)^ ** ** ^This function causes all database schemas to be read from disk and ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ | | > | 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 | ** auto increment: 0 ** </pre>)^ ** ** ^This function causes all database schemas to be read from disk and ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ const char *zColumnName, /* Column name */ char const **pzDataType, /* OUTPUT: Declared data type */ char const **pzCollSeq, /* OUTPUT: Collation sequence name */ int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ int *pPrimaryKey, /* OUTPUT: True if column part of PK */ int *pAutoinc /* OUTPUT: True if column is auto-increment */ ); /* ** CAPI3REF: Load An Extension ** METHOD: sqlite3 ** ** ^This interface loads an SQLite extension library from the named file. ** ** ^The sqlite3_load_extension() interface attempts to load an ** [SQLite extension] library contained in the file zFile. If ** the file cannot be loaded directly, attempts are made to load ** with various operating-system specific extensions added. |
| ︙ | ︙ | |||
5313 5314 5315 5316 5317 5318 5319 | ** ** ^Extension loading must be enabled using ** [sqlite3_enable_load_extension()] prior to calling this API, ** otherwise an error will be returned. ** ** See also the [load_extension() SQL function]. */ | | > | | 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 | ** ** ^Extension loading must be enabled using ** [sqlite3_enable_load_extension()] prior to calling this API, ** otherwise an error will be returned. ** ** See also the [load_extension() SQL function]. */ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ); /* ** CAPI3REF: Enable Or Disable Extension Loading ** METHOD: sqlite3 ** ** ^So as not to open security holes in older applications that are ** unprepared to deal with [extension loading], and as a means of disabling ** [extension loading] while evaluating user-entered SQL, the following API ** is provided to turn the [sqlite3_load_extension()] mechanism on and off. ** ** ^Extension loading is off by default. ** ^Call the sqlite3_enable_load_extension() routine with onoff==1 ** to turn extension loading on and call it with onoff==0 to turn ** it back off again. */ SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ** CAPI3REF: Automatically Load Statically Linked Extensions ** ** ^This interface causes the xEntryPoint() function to be invoked for ** each new [database connection] that is created. The idea here is that ** xEntryPoint() is the entry point for a statically linked [SQLite extension] |
| ︙ | ︙ | |||
5371 5372 5373 5374 5375 5376 5377 | ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already ** on the list of automatic extensions is a harmless no-op. ^No entry point ** will be called more than once for each database connection that is opened. ** ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ | | | | | 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 | ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already ** on the list of automatic extensions is a harmless no-op. ^No entry point ** will be called more than once for each database connection that is opened. ** ** See also: [sqlite3_reset_auto_extension()] ** and [sqlite3_cancel_auto_extension()] */ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading ** ** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the ** initialization routine X that was registered using a prior call to ** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] ** routine returns 1 if initialization routine X was successfully ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading ** ** ^This interface disables all automatic extensions previously ** registered using [sqlite3_auto_extension()]. */ SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void); /* ** The interface to the virtual-table mechanism is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** ** When the virtual-table mechanism stabilizes, we will declare the |
| ︙ | ︙ | |||
5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 | #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 #define SQLITE_INDEX_CONSTRAINT_GE 32 #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* ** CAPI3REF: Register A Virtual Table Implementation ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before ** creating a new [virtual table] using the module and before using a ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified | > | 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 | #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 #define SQLITE_INDEX_CONSTRAINT_GE 32 #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* ** CAPI3REF: Register A Virtual Table Implementation ** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before ** creating a new [virtual table] using the module and before using a ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified |
| ︙ | ︙ | |||
5594 5595 5596 5597 5598 5599 5600 | ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ | | | | 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 | ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also ** be invoked if the call to sqlite3_create_module_v2() fails. ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. */ SQLITE_API int SQLITE_STDCALL sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ void(*xDestroy)(void*) /* Module destructor function */ ); |
| ︙ | ︙ | |||
5663 5664 5665 5666 5667 5668 5669 | ** CAPI3REF: Declare The Schema Of A Virtual Table ** ** ^The [xCreate] and [xConnect] methods of a ** [virtual table module] call this interface ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ | | > | | 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 | ** CAPI3REF: Declare The Schema Of A Virtual Table ** ** ^The [xCreate] and [xConnect] methods of a ** [virtual table module] call this interface ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table ** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions ** using the [xFindFunction] method of the [virtual table module]. ** But global versions of those functions ** must exist in order to be overloaded.)^ ** ** ^(This API makes sure a global version of a function with a particular ** name and number of parameters exists. If no such function exists ** before this API is called, a new function is created.)^ ^The implementation ** of the new function always causes an exception to be thrown. So ** the new function is not good for anything by itself. Its only ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up ** to a comment remarkably similar to this one) is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** |
| ︙ | ︙ | |||
5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 | ** can be used to read or write small subsections of the BLOB. ** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. */ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; ** in other words, the same BLOB that would be selected by: ** ** <pre> ** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; | > > | 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 | ** can be used to read or write small subsections of the BLOB. ** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. */ typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O ** METHOD: sqlite3 ** CONSTRUCTOR: sqlite3_blob ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; ** in other words, the same BLOB that would be selected by: ** ** <pre> ** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; |
| ︙ | ︙ | |||
5778 5779 5780 5781 5782 5783 5784 | ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces ** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. */ | | > | > | > | > | 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 | ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces ** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually ** be released by a call to [sqlite3_blob_close()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, const char *zColumn, sqlite3_int64 iRow, int flags, sqlite3_blob **ppBlob ); /* ** CAPI3REF: Move a BLOB Handle to a New Row ** METHOD: sqlite3_blob ** ** ^This function is used to move an existing blob handle so that it points ** to a different row of the same database table. ^The new row is identified ** by the rowid value passed as the second argument. Only the row can be ** changed. ^The database, table and column on which the blob handle is open ** remain the same. Moving an existing blob handle to a new row can be ** faster than closing the existing handle and opening a new one. ** ** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - ** it must exist and there must be either a blob or text value stored in ** the nominated column.)^ ^If the new row is not present in the table, or if ** it does not contain a blob or text value, or if another error occurs, an ** SQLite error code is returned and the blob handle is considered aborted. ** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or ** [sqlite3_blob_reopen()] on an aborted blob handle immediately return ** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle ** always returns zero. ** ** ^This function sets the database handle error code and message. */ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); /* ** CAPI3REF: Close A BLOB Handle ** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed ** unconditionally. Even if this routine returns an error code, the ** handle is still closed.)^ ** ** ^If the blob handle being closed was opened for read-write access, and if ** the database is in auto-commit mode and there are no other open read-write ** blob handles or active write statements, the current transaction is ** committed. ^If an error occurs while committing the transaction, an error ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an ** open blob handle results in undefined behaviour. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *); /* ** CAPI3REF: Read Data From A BLOB Incrementally ** METHOD: sqlite3_blob ** ** ^(This function is used to read data from an open [BLOB handle] into a ** caller-supplied buffer. N bytes of data are copied into buffer Z ** from the open BLOB, starting at offset iOffset.)^ ** ** ^If offset iOffset is less than N bytes from the end of the BLOB, ** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is |
| ︙ | ︙ | |||
5875 5876 5877 5878 5879 5880 5881 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_write()]. */ | | > | 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_write()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally ** METHOD: sqlite3_blob ** ** ^(This function is used to write data into an open [BLOB handle] from a ** caller-supplied buffer. N bytes of data are copied from the buffer Z ** into the open BLOB, starting at offset iOffset.)^ ** ** ^(On success, sqlite3_blob_write() returns SQLITE_OK. ** Otherwise, an [error code] or an [extended error code] is returned.)^ |
| ︙ | ︙ | |||
5916 5917 5918 5919 5920 5921 5922 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_read()]. */ | | | 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 | ** This routine only works on a [BLOB handle] which has been created ** by a prior successful call to [sqlite3_blob_open()] and which has not ** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** ** See also: [sqlite3_blob_read()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** CAPI3REF: Virtual File System Objects ** ** A virtual filesystem (VFS) is an [sqlite3_vfs] object ** that SQLite uses to interact ** with the underlying operating system. Most SQLite builds come with a |
| ︙ | ︙ | |||
5947 5948 5949 5950 5951 5952 5953 | ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** ** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ | | | | | 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 | ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** ** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName); SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*); /* ** CAPI3REF: Mutexes ** ** The SQLite core uses these routines for thread ** synchronization. Though they are intended for internal ** use by SQLite, code that links against SQLite is |
| ︙ | ︙ | |||
6062 6063 6064 6065 6066 6067 6068 | ** ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or ** sqlite3_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ | | | | | | | 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 | ** ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or ** sqlite3_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int); SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*); SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*); SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*); SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object ** ** An instance of this structure defines the low-level routines ** used to allocate and use mutexes. ** |
| ︙ | ︙ | |||
6176 6177 6178 6179 6180 6181 6182 | ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the ** call to sqlite3_mutex_held() to fail, so a non-zero return is ** the appropriate thing to do. The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG | | | | 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 | ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the ** call to sqlite3_mutex_held() to fail, so a non-zero return is ** the appropriate thing to do. The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*); SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*); #endif /* ** CAPI3REF: Mutex Types ** ** The [sqlite3_mutex_alloc()] interface takes a single argument ** which is one of these integer constants. |
| ︙ | ︙ | |||
6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ /* ** CAPI3REF: Retrieve the mutex for a database connection ** ** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ | > | > | 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 | #define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ /* ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** ** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files ** METHOD: sqlite3 ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated ** with a particular database identified by the second argument. ^The ** name of the database is "main" for the main database or "temp" for the ** TEMP database, or the name that appears after the AS keyword for ** databases that are added using the [ATTACH] SQL command. |
| ︙ | ︙ | |||
6247 6248 6249 6250 6251 6252 6253 | ** or [sqlite3_errmsg()]. The underlying xFileControl method might ** also return SQLITE_ERROR. There is no way to distinguish between ** an incorrect zDbName and an SQLITE_ERROR return from the underlying ** xFileControl method. ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ | | | | 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 | ** or [sqlite3_errmsg()]. The underlying xFileControl method might ** also return SQLITE_ERROR. There is no way to distinguish between ** an incorrect zDbName and an SQLITE_ERROR return from the underlying ** xFileControl method. ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); /* ** CAPI3REF: Testing Interface ** ** ^The sqlite3_test_control() interface is used to read out internal ** state of SQLite and to inject faults into SQLite for testing ** purposes. ^The first parameter is an operation code that determines ** the number, meaning, and operation of all subsequent parameters. ** ** This interface is not for use by applications. It exists solely ** for verifying the correct operation of the SQLite library. Depending ** on how the SQLite library is compiled, this interface might not exist. ** ** The details of the operation codes, their meanings, the parameters ** they take, and what they do are all subject to change without notice. ** Unlike most of the SQLite API, this function is not guaranteed to ** operate consistently from one release to the next. */ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...); /* ** CAPI3REF: Testing Interface Operation Codes ** ** These constants are the valid operation code parameters used ** as the first argument to [sqlite3_test_control()]. ** |
| ︙ | ︙ | |||
6329 6330 6331 6332 6333 6334 6335 | ** ** If either the current value or the highwater mark is too large to ** be represented by a 32-bit integer, then the values returned by ** sqlite3_status() are undefined. ** ** See also: [sqlite3_db_status()] */ | | | | 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 | ** ** If either the current value or the highwater mark is too large to ** be represented by a 32-bit integer, then the values returned by ** sqlite3_status() are undefined. ** ** See also: [sqlite3_db_status()] */ SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); SQLITE_API int SQLITE_STDCALL sqlite3_status64( int op, sqlite3_int64 *pCurrent, sqlite3_int64 *pHighwater, int resetFlag ); |
| ︙ | ︙ | |||
6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 | #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 #define SQLITE_STATUS_SCRATCH_SIZE 8 #define SQLITE_STATUS_MALLOC_COUNT 9 /* ** CAPI3REF: Database Connection Status ** ** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the ** database connection object to be interrogated. ^The second argument ** is an integer constant, taken from the set of ** [SQLITE_DBSTATUS options], that ** determines the parameter to interrogate. The set of ** [SQLITE_DBSTATUS options] is likely ** to grow in future releases of SQLite. ** ** ^The current value of the requested parameter is written into *pCur ** and the highest instantaneous value is written into *pHiwtr. ^If ** the resetFlg is true, then the highest instantaneous value is ** reset back down to the current value. ** ** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a ** non-zero [error code] on failure. ** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ | > | | 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 |
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
#define SQLITE_STATUS_SCRATCH_SIZE 8
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
** CAPI3REF: Database Connection Status
** METHOD: sqlite3
**
** ^This interface is used to retrieve runtime status information
** about a single [database connection]. ^The first argument is the
** database connection object to be interrogated. ^The second argument
** is an integer constant, taken from the set of
** [SQLITE_DBSTATUS options], that
** determines the parameter to interrogate. The set of
** [SQLITE_DBSTATUS options] is likely
** to grow in future releases of SQLite.
**
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
|
| ︙ | ︙ | |||
6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 | #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number ** of times it has performed specific operations.)^ These counters can ** be used to monitor the performance characteristics of the prepared ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate | > | 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 | #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number ** of times it has performed specific operations.)^ These counters can ** be used to monitor the performance characteristics of the prepared ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate |
| ︙ | ︙ | |||
6582 6583 6584 6585 6586 6587 6588 | ** to be interrogated.)^ ** ^The current value of the requested counter is returned. ** ^If the resetFlg is true, then the counter is reset to zero after this ** interface call returns. ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ | | | 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 |
** to be interrogated.)^
** ^The current value of the requested counter is returned.
** ^If the resetFlg is true, then the counter is reset to zero after this
** interface call returns.
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
**
** These preprocessor macros define integer codes that name counter
** values associated with the [sqlite3_stmt_status()] interface.
|
| ︙ | ︙ | |||
7051 7052 7053 7054 7055 7056 7057 | ** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ | | | | | | > | 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 | ** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ const char *zDestName, /* Destination database name */ sqlite3 *pSource, /* Source database handle */ const char *zSourceName /* Source database name */ ); SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage); SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p); SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p); SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification ** METHOD: sqlite3 ** ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or ** individual tables within the shared-cache cannot be obtained. See ** [SQLite Shared-Cache Mode] for a description of shared-cache locking. ** ^This API may be used to register a callback that SQLite will invoke ** when the connection currently holding the required lock relinquishes it. |
| ︙ | ︙ | |||
7176 7177 7178 7179 7180 7181 7182 | ** ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ | | | | | | 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 | ** ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ ); /* ** CAPI3REF: String Comparison ** ** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications ** and extensions to compare the contents of two buffers containing UTF-8 ** strings in a case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *); SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: String Globbing * ** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches ** the glob pattern P, and it returns non-zero if string X does not match ** the glob pattern P. ^The definition of glob pattern matching used in ** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the ** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case ** sensitive. ** ** Note that this routine returns zero on a match and non-zero if the strings ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr); /* ** CAPI3REF: Error Logging Interface ** ** ^The [sqlite3_log()] interface writes a message into the [error log] ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. ** ^If logging is enabled, the zFormat string and subsequent arguments are |
| ︙ | ︙ | |||
7230 7231 7232 7233 7234 7235 7236 | ** ** To avoid deadlocks and other threading problems, the sqlite3_log() routine ** will not use dynamically allocated memory. The log message is stored in ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ | | > | 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 | ** ** To avoid deadlocks and other threading problems, the sqlite3_log() routine ** will not use dynamically allocated memory. The log message is stored in ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook ** METHOD: sqlite3 ** ** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. ** ** ^(The callback is invoked by SQLite after the commit has taken place and ** the associated write-lock on the database released)^, so the implementation ** may read, write or [checkpoint] the database as required. |
| ︙ | ︙ | |||
7265 7266 7267 7268 7269 7270 7271 | ** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^Note that the ** [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** those overwrite any prior [sqlite3_wal_hook()] settings. */ | | > | 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 | ** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^Note that the ** [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** those overwrite any prior [sqlite3_wal_hook()] settings. */ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook( sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* ); /* ** CAPI3REF: Configure an auto-checkpoint ** METHOD: sqlite3 ** ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around ** [sqlite3_wal_hook()] that causes any database on [database connection] D ** to automatically [checkpoint] ** after committing a transaction if there are N or ** more frames in the [write-ahead log] file. ^Passing zero or ** a negative value as the nFrame parameter disables automatic |
| ︙ | ︙ | |||
7299 7300 7301 7302 7303 7304 7305 | ** ** ^Every new [database connection] defaults to having the auto-checkpoint ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] ** pages. The use of this interface ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ | | > | > | 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 | ** ** ^Every new [database connection] defaults to having the auto-checkpoint ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] ** pages. The use of this interface ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N); /* ** CAPI3REF: Checkpoint a database ** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ ** ** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the ** [write-ahead log] for database X on [database connection] D to be ** transferred into the database file and for the write-ahead log to ** be reset. See the [checkpointing] documentation for addition ** information. ** ** This interface used to be the only way to cause a checkpoint to ** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] ** interface was added. This interface is retained for backwards ** compatibility and as a convenience for applications that need to manually ** start a callback but which do not need the full power (and corresponding ** complication) of [sqlite3_wal_checkpoint_v2()]. */ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Checkpoint a database ** METHOD: sqlite3 ** ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint ** operation on database X of [database connection] D in mode M. Status ** information is written back into integers pointed to by L and C.)^ ** ^(The M parameter must be a valid [checkpoint mode]:)^ ** ** <dl> |
| ︙ | ︙ | |||
7413 7414 7415 7416 7417 7418 7419 | ** the sqlite3_wal_checkpoint_v2() interface ** sets the error information that is queried by ** [sqlite3_errcode()] and [sqlite3_errmsg()]. ** ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ | | | 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 | ** the sqlite3_wal_checkpoint_v2() interface ** sets the error information that is queried by ** [sqlite3_errcode()] and [sqlite3_errmsg()]. ** ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2( sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ int *pnLog, /* OUT: Size of WAL log in frames */ int *pnCkpt /* OUT: Total number of frames checkpointed */ ); |
| ︙ | ︙ | |||
7449 7450 7451 7452 7453 7454 7455 | ** If this interface is invoked outside the context of an xConnect or ** xCreate virtual table method then the behavior is undefined. ** ** At present, there is only one option that may be configured using ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ | | | 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 | ** If this interface is invoked outside the context of an xConnect or ** xCreate virtual table method then the behavior is undefined. ** ** At present, there is only one option that may be configured using ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options ** ** These macros define the various options to the ** [sqlite3_vtab_config()] interface that [virtual table] implementations ** can use to customize and optimize their behavior. |
| ︙ | ︙ | |||
7502 7503 7504 7505 7506 7507 7508 | ** This function may only be called from within a call to the [xUpdate] method ** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The ** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], ** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode ** of the SQL statement that triggered the call to the [xUpdate] method of the ** [virtual table]. */ | | | 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 |
** This function may only be called from within a call to the [xUpdate] method
** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
** These constants are returned by [sqlite3_vtab_on_conflict()] to
** inform a [virtual table] implementation what the [ON CONFLICT] mode
|
| ︙ | ︙ | |||
7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 | #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 /* ** CAPI3REF: Prepared Statement Scan Status ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only | > | 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 | #define SQLITE_SCANSTAT_EST 2 #define SQLITE_SCANSTAT_NAME 3 #define SQLITE_SCANSTAT_EXPLAIN 4 #define SQLITE_SCANSTAT_SELECTID 5 /* ** CAPI3REF: Prepared Statement Scan Status ** METHOD: sqlite3_stmt ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this ** interface to compare the predicted and the measured performance and ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. ** ** Since this interface is expected to be rarely used, it is only |
| ︙ | ︙ | |||
7606 7607 7608 7609 7610 7611 7612 | ** ^Statistics might not be available for all loops in all statements. ^In cases ** where there exist loops with no available statistics, this function behaves ** as if the loop did not exist - it returns non-zero and leave the variable ** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ | | > | | 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 | ** ^Statistics might not be available for all loops in all statements. ^In cases ** where there exist loops with no available statistics, this function behaves ** as if the loop did not exist - it returns non-zero and leave the variable ** that pOut points to unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] */ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); /* ** CAPI3REF: Zero Scan-Status Counters ** METHOD: sqlite3_stmt ** ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. ** ** This API is only available if the library is built with pre-processor ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. */ SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT |
| ︙ | ︙ | |||
7676 7677 7678 7679 7680 7681 7682 | /* ** Register a geometry callback named zGeom that can be used as part of an ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ | | | 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 | /* ** Register a geometry callback named zGeom that can be used as part of an ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), void *pContext ); |
| ︙ | ︙ | |||
7702 7703 7704 7705 7706 7707 7708 | /* ** Register a 2nd-generation geometry callback named zScore that can be ** used as part of an R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) */ | | | 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 | /* ** Register a 2nd-generation geometry callback named zScore that can be ** used as part of an R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...) */ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback( sqlite3 *db, const char *zQueryFunc, int (*xQueryFunc)(sqlite3_rtree_query_info*), void *pContext, void (*xDestructor)(void*) ); |
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fMB)",
v, (double)v/1000000.0);
}else{
sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fGB)",
v, (double)v/1000000000.0);
}
}
/*
** WEBPAGE: stat
**
** Show statistics and global information about the repository.
*/
void stat_page(void){
| > > > > > > > > > > > > > > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fMB)",
v, (double)v/1000000.0);
}else{
sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fGB)",
v, (double)v/1000000000.0);
}
}
/*
** Return the approximate size as KB, MB, GB, or TB.
*/
void approxSizeName(int nOut, char *zOut, sqlite3_int64 v){
if( v<1000 ){
sqlite3_snprintf(nOut, zOut, "%lld bytes", v);
}else if( v<1000000 ){
sqlite3_snprintf(nOut, zOut, "%.1fKB", (double)v/1000.0);
}else if( v<1000000000 ){
sqlite3_snprintf(nOut, zOut, "%.1fMB", (double)v/1000000.0);
}else{
sqlite3_snprintf(nOut, zOut, "%.1fGB", (double)v/1000000000.0);
}
}
/*
** WEBPAGE: stat
**
** Show statistics and global information about the repository.
*/
void stat_page(void){
|
| ︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
if( g.perm.Admin ){
style_submenu_element("URLs", "URLs and Checkouts", "urllist");
style_submenu_element("Schema", "Repository Schema", "repo_schema");
style_submenu_element("Web-Cache", "Web-Cache Stats", "cachestat");
}
style_submenu_element("Activity Reports", 0, "reports");
style_submenu_element("SHA1 Collisions", 0, "hash-collisions");
@ <table class="label-value">
@ <tr><th>Repository Size:</th><td>
fsize = file_size(g.zRepositoryName);
bigSizeName(sizeof(zBuf), zBuf, fsize);
@ %s(zBuf)
@ </td></tr>
if( !brief ){
| > > > | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
if( g.perm.Admin ){
style_submenu_element("URLs", "URLs and Checkouts", "urllist");
style_submenu_element("Schema", "Repository Schema", "repo_schema");
style_submenu_element("Web-Cache", "Web-Cache Stats", "cachestat");
}
style_submenu_element("Activity Reports", 0, "reports");
style_submenu_element("SHA1 Collisions", 0, "hash-collisions");
if( sqlite3_libversion_number()>=3008010 ){
style_submenu_element("Table Sizes", 0, "repo-tabsize");
}
@ <table class="label-value">
@ <tr><th>Repository Size:</th><td>
fsize = file_size(g.zRepositoryName);
bigSizeName(sizeof(zBuf), zBuf, fsize);
@ %s(zBuf)
@ </td></tr>
if( !brief ){
|
| ︙ | ︙ | |||
353 354 355 356 357 358 359 |
while( db_step(&q)==SQLITE_ROW ){
@ %h(db_column_text(&q, 0));
}
@ </pre>
db_finalize(&q);
style_footer();
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
while( db_step(&q)==SQLITE_ROW ){
@ %h(db_column_text(&q, 0));
}
@ </pre>
db_finalize(&q);
style_footer();
}
/*
** WEBPAGE: repo-tabsize
**
** Show relative sizes of tables in the repository database.
*/
void repo_tabsize_page(void){
int nPageFree;
sqlite3_int64 fsize;
char zBuf[100];
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("Repository Table Sizes");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_element("Stat", "Repository Stats", "stat");
db_multi_exec(
"CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
"CREATE TEMP TABLE trans(name TEXT PRIMARY KEY, tabname TEXT)WITHOUT ROWID;"
"INSERT INTO trans(name,tabname)"
" SELECT name, tbl_name FROM %s.sqlite_master;"
"CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
"INSERT INTO piechart(amt,label)"
" SELECT count(*), "
" coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
" FROM dbx"
" GROUP BY 2 ORDER BY 2;",
db_name("repository"), db_name("repository")
);
nPageFree = db_int(0, "PRAGMA \"%w\".freelist_count", db_name("repository"));
if( nPageFree>0 ){
db_multi_exec(
"INSERT INTO piechart(amt,label) VALUES(%d,'freelist')",
nPageFree
);
}
fsize = file_size(g.zRepositoryName);
approxSizeName(sizeof(zBuf), zBuf, fsize);
@ <h2>Repository Size: %s(zBuf)</h2>
@ <center><svg width='800' height='500'>
piechart_render(800,500,PIE_OTHER|PIE_PERCENT);
@ </svg></center>
if( g.localOpen ){
db_multi_exec(
"DROP TABLE temp.dbx;"
"CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
"DELETE FROM trans;"
"INSERT INTO trans(name,tabname)"
" SELECT name, tbl_name FROM %s.sqlite_master;"
"DELETE FROM piechart;"
"INSERT INTO piechart(amt,label)"
" SELECT count(*), "
" coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
" FROM dbx"
" GROUP BY 2 ORDER BY 2;",
db_name("localdb"), db_name("localdb")
);
nPageFree = db_int(0, "PRAGMA \"%s\".freelist_count", db_name("localdb"));
if( nPageFree>0 ){
db_multi_exec(
"INSERT INTO piechart(amt,label) VALUES(%d,'freelist')",
nPageFree
);
}
fsize = file_size(g.zLocalDbName);
approxSizeName(sizeof(zBuf), zBuf, fsize);
@ <h2>%h(file_tail(g.zLocalDbName)) Size: %s(zBuf)</h2>
@ <center><svg width='800' height='500'>
piechart_render(800,500,PIE_OTHER|PIE_PERCENT);
@ </svg></center>
}
style_footer();
}
|
Changes to src/statrep.c.
| ︙ | ︙ | |||
402 403 404 405 406 407 408 |
int nEventTotal = 0; /* Total event count */
int rowClass = 0; /* counter for alternating
row colors */
int nMaxEvents = 1; /* max number of events for
all rows. */
stats_report_init_view();
stats_report_event_types_menu("byuser", NULL);
| < < < < < > > > > > > > > > > > > > > > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 |
int nEventTotal = 0; /* Total event count */
int rowClass = 0; /* counter for alternating
row colors */
int nMaxEvents = 1; /* max number of events for
all rows. */
stats_report_init_view();
stats_report_event_types_menu("byuser", NULL);
@ <h1>Timeline Events
@ (%s(stats_report_label_for_type())) by User</h1>
db_multi_exec(
"CREATE TEMP TABLE piechart(amt,label);"
"INSERT INTO piechart SELECT count(*), user FROM v_reports"
" GROUP BY user ORDER BY count(*) DESC;"
);
if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
@ <center><svg width=700 height=400>
piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
@ </svg></centre><hr/>
}
@ <table class='statistics-report-table-events' border='0'
@ cellpadding='2' cellspacing='0' id='statsTable'>
@ <thead><tr>
@ <th>User</th>
@ <th>Events</th>
@ <th width='90%%'><!-- relative commits graph --></th>
@ </tr></thead><tbody>
db_prepare(&query,
"SELECT user, "
"COUNT(*) AS eventCount "
"FROM v_reports "
"GROUP BY user ORDER BY eventCount DESC");
while( SQLITE_ROW == db_step(&query) ){
const int nCount = db_column_int(&query, 1);
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
}
db_reset(&query);
|
| ︙ | ︙ | |||
466 467 468 469 470 471 472 |
db_multi_exec(
"CREATE TEMP TABLE statrep(filename, cnt);"
"INSERT INTO statrep(filename, cnt)"
" SELECT filename.name, count(distinct mlink.mid)"
" FROM filename, mlink"
" WHERE filename.fnid=mlink.fnid"
| | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
db_multi_exec(
"CREATE TEMP TABLE statrep(filename, cnt);"
"INSERT INTO statrep(filename, cnt)"
" SELECT filename.name, count(distinct mlink.mid)"
" FROM filename, mlink"
" WHERE filename.fnid=mlink.fnid"
" GROUP BY 1;"
);
db_prepare(&query,
"SELECT filename, cnt FROM statrep ORDER BY cnt DESC, filename /*sort*/"
);
mxEvent = db_int(1, "SELECT max(cnt) FROM statrep");
@ <h1>Check-ins Per File</h1>
@ <table class='statistics-report-table-events' border='0'
|
| ︙ | ︙ | |||
526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
db_prepare(&query,
"SELECT cast(mtime %% 7 AS INTEGER) dow, "
"COUNT(*) AS eventCount "
"FROM v_reports "
"GROUP BY dow ORDER BY dow");
@ <h1>Timeline Events
@ (%s(stats_report_label_for_type())) by Day of the Week</h1>
@ <table class='statistics-report-table-events' border='0'
@ cellpadding='2' cellspacing='0' id='statsTable'>
@ <thead><tr>
@ <th>DoW</th>
@ <th>Day</th>
@ <th>Events</th>
@ <th width='90%%'><!-- relative commits graph --></th>
| > > > > > > > > > > > > > | 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
db_prepare(&query,
"SELECT cast(mtime %% 7 AS INTEGER) dow, "
"COUNT(*) AS eventCount "
"FROM v_reports "
"GROUP BY dow ORDER BY dow");
@ <h1>Timeline Events
@ (%s(stats_report_label_for_type())) by Day of the Week</h1>
db_multi_exec(
"CREATE TEMP TABLE piechart(amt,label);"
"INSERT INTO piechart SELECT count(*), cast(mtime %% 7 AS INT) FROM v_reports"
" GROUP BY 2 ORDER BY 2;"
"UPDATE piechart SET label = CASE label WHEN 0 THEN 'Monday' WHEN 1 THEN 'Tuesday'"
" WHEN 2 THEN 'Wednesday' WHEN 3 THEN 'Thursday' WHEN 4 THEN 'Friday'"
" WHEN 5 THEN 'Saturday' ELSE 'Sunday' END;"
);
if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
@ <center><svg width=700 height=400>
piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
@ </svg></centre><hr/>
}
@ <table class='statistics-report-table-events' border='0'
@ cellpadding='2' cellspacing='0' id='statsTable'>
@ <thead><tr>
@ <th>DoW</th>
@ <th>Day</th>
@ <th>Events</th>
@ <th width='90%%'><!-- relative commits graph --></th>
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
699 700 701 702 703 704 705 |
{ "td.timelineTime",
"the format for the timeline time display",
@ vertical-align: top;
@ text-align: right;
@ white-space: nowrap;
},
{ "td.timelineGraph",
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 |
{ "td.timelineTime",
"the format for the timeline time display",
@ vertical-align: top;
@ text-align: right;
@ white-space: nowrap;
},
{ "td.timelineGraph",
"the format for the graph placeholder cells in timelines",
@ width: 20px;
@ text-align: left;
@ vertical-align: top;
},
{ ".tl-canvas",
"timeline graph canvas",
@ margin: 0 6px 0 10px;
},
{ ".tl-rail",
"maximum rail spacing",
@ width: 18px;
},
{ ".tl-mergeoffset",
"maximum spacing between merge risers and primary child risers",
@ width: 2px;
},
{ ".tl-nodemark",
"adjusts the vertical position of graph nodes",
@ margin-top: 5px;
},
{ ".tl-node",
"commit node",
@ width: 10px;
@ height: 10px;
@ border: 1px solid #000;
@ background: #fff;
@ cursor: pointer;
},
{ ".tl-node.leaf:after",
"leaf commit marker",
@ content: '';
@ position: absolute;
@ top: 3px;
@ left: 3px;
@ width: 4px;
@ height: 4px;
@ background: #000;
},
{ ".tl-node.sel:after",
"selected commit node marker",
@ content: '';
@ position: absolute;
@ top: 2px;
@ left: 2px;
@ width: 6px;
@ height: 6px;
@ background: red;
},
{ ".tl-arrow",
"arrow",
@ width: 0;
@ height: 0;
@ transform: scale(.999);
@ border: 0 solid transparent;
},
{ ".tl-arrow.u",
"up arrow",
@ margin-top: -1px;
@ border-width: 0 3px;
@ border-bottom: 7px solid #000;
},
{ ".tl-arrow.u.sm",
"small up arrow",
@ border-bottom: 5px solid #000;
},
{ ".tl-line",
"line",
@ background: #000;
@ width: 2px;
},
{ ".tl-arrow.merge",
"merge arrow",
@ height: 1px;
@ border-width: 2px 0;
},
{ ".tl-arrow.merge.l",
"left merge arrow",
@ border-right: 3px solid #000;
},
{ ".tl-arrow.merge.r",
"right merge arrow",
@ border-left: 3px solid #000;
},
{ ".tl-line.merge",
"merge line",
@ width: 1px;
},
{ ".tl-arrow.warp",
"timewarp arrow",
@ margin-left: 1px;
@ border-width: 3px 0;
@ border-left: 7px solid #600000;
},
{ ".tl-line.warp",
"timewarp line",
@ background: #600000;
},
{ "a.tagLink",
"the format for the tag links",
@
},
{ "span.tagDsp",
"the format for the tag display(no history permission!)",
@ font-weight: bold;
|
| ︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 |
"odd table row color",
@ /* Use default */
},
{ "#usetupEditCapability",
"format for capabilities string, mentioned on the user edit page",
@ font-weight: bold;
},
| < < < < | 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 |
"odd table row color",
@ /* Use default */
},
{ "#usetupEditCapability",
"format for capabilities string, mentioned on the user edit page",
@ font-weight: bold;
},
{ "table.adminLogTable",
"Class for the /admin_log table",
@ text-align: left;
},
{ ".adminLogTable .adminTime",
"Class for the /admin_log table",
@ text-align: left;
|
| ︙ | ︙ | |||
1334 1335 1336 1337 1338 1339 1340 |
cssDefaultList[i].value
);
}
}
}
/*
| | < | | > < > | < | | > < > > > > > > > > > > > > > > > > > > > > > > > | | 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 |
cssDefaultList[i].value
);
}
}
}
/*
** Search string zCss for zSelector.
**
** Return true if found. Return false if not found
*/
static int containsSelector(const char *zCss, const char *zSelector){
const char *z;
int n;
int selectorLen = (int)strlen(zSelector);
for(z=zCss; *z; z+=selectorLen){
z = strstr(z, zSelector);
if( z==0 ) return 0;
if( z!=zCss ){
for( n=-1; z+n!=zCss && fossil_isspace(z[n]); n--);
if( z+n!=zCss && z[n]!=',' && z[n]!= '}' && z[n]!='/' ) continue;
}
for( n=selectorLen; z[n] && fossil_isspace(z[n]); n++ );
if( z[n]==',' || z[n]=='{' || z[n]=='/' ) return 1;
}
return 0;
}
/*
** COMMAND: test-contains-selector
**
** Usage: %fossil test-contains-selector FILENAME SELECTOR
**
** Determine if the CSS stylesheet FILENAME contains SELECTOR.
*/
void contains_selector_cmd(void){
int found;
char *zSelector;
Blob css;
if( g.argc!=4 ) usage("FILENAME SELECTOR");
blob_read_from_file(&css, g.argv[2]);
zSelector = g.argv[3];
found = containsSelector(blob_str(&css), zSelector);
fossil_print("%s %s\n", zSelector, found ? "found" : "not found");
blob_reset(&css);
}
/*
** WEBPAGE: style.css
**
** Return the style sheet.
*/
void page_style_css(void){
Blob css;
int i;
cgi_set_content_type("text/css");
blob_init(&css,skin_get("css"),-1);
/* add special missing definitions */
for(i=1; cssDefaultList[i].elementClass; i++){
char *z = blob_str(&css);
if( !containsSelector(z, cssDefaultList[i].elementClass) ){
blob_appendf(&css, "/* %s */\n%s {\n%s}\n",
cssDefaultList[i].comment,
cssDefaultList[i].elementClass,
cssDefaultList[i].value);
}
}
|
| ︙ | ︙ | |||
1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 |
/* Tell CGI that the content returned by this page is considered cacheable */
g.isConst = 1;
}
/*
** WEBPAGE: test_env
*/
void page_test_env(void){
char c;
int i;
int showAll;
char zCap[30];
static const char *const azCgiVars[] = {
| > > > | 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 |
/* Tell CGI that the content returned by this page is considered cacheable */
g.isConst = 1;
}
/*
** WEBPAGE: test_env
**
** Display CGI-variables and other aspects of the run-time
** environment, for debugging and trouble-shooting purposes.
*/
void page_test_env(void){
char c;
int i;
int showAll;
char zCap[30];
static const char *const azCgiVars[] = {
|
| ︙ | ︙ | |||
1464 1465 1466 1467 1468 1469 1470 |
if( zRedir ) cgi_redirect(zRedir);
}
style_footer();
if( g.perm.Admin && P("err") ) fossil_fatal("%s", P("err"));
}
/*
| < < > | 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 |
if( zRedir ) cgi_redirect(zRedir);
}
style_footer();
if( g.perm.Admin && P("err") ) fossil_fatal("%s", P("err"));
}
/*
** WEBPAGE: honeypot
** This page is a honeypot for spiders and bots.
*/
void honeypot_page(void){
cgi_set_status(403, "Forbidden");
@ <p>Please enable javascript or log in to see this content</p>
}
|
Changes to src/tag.c.
| ︙ | ︙ | |||
534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
tag_cmd_usage:
usage("add|cancel|find|list ...");
}
/*
** WEBPAGE: taglist
*/
void taglist_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read ){
login_needed(g.anon.Read);
| > > | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 |
tag_cmd_usage:
usage("add|cancel|find|list ...");
}
/*
** WEBPAGE: taglist
**
** List all non-propagating symbolic tags.
*/
void taglist_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read ){
login_needed(g.anon.Read);
|
| ︙ | ︙ | |||
573 574 575 576 577 578 579 580 581 582 583 584 585 586 |
@ </ul>
db_finalize(&q);
style_footer();
}
/*
** WEBPAGE: /tagtimeline
*/
void tagtimeline_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
| > > > | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
@ </ul>
db_finalize(&q);
style_footer();
}
/*
** WEBPAGE: /tagtimeline
**
** Render a timeline with all check-ins that contain non-propagating
** symbolic tags.
*/
void tagtimeline_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
|
| ︙ | ︙ |
Changes to src/th.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** The implementation of the TH core. This file contains the parser, and ** the implementation of the interface in th.h. */ #include "config.h" #include "th.h" #include <string.h> #include <assert.h> | | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/*
** The implementation of the TH core. This file contains the parser, and
** the implementation of the interface in th.h.
*/
#include "config.h"
#include "th.h"
#include <string.h>
#include <assert.h>
typedef struct Th_Command Th_Command;
typedef struct Th_Frame Th_Frame;
typedef struct Th_Variable Th_Variable;
typedef struct Th_InterpAndList Th_InterpAndList;
/*
** Interpreter structure.
*/
struct Th_Interp {
Th_Vtab *pVtab; /* Copy of the argument passed to Th_CreateInterp() */
char *zResult; /* Current interpreter result (Th_Malloc()ed) */
|
| ︙ | ︙ | |||
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
*/
struct Th_Variable {
int nRef; /* Number of references to this structure */
int nData; /* Number of bytes at Th_Variable.zData */
char *zData; /* Data for scalar variables */
Th_Hash *pHash; /* Data for array variables */
};
/*
** Hash table API:
*/
#define TH_HASHSIZE 257
struct Th_Hash {
Th_HashEntry *a[TH_HASHSIZE];
| > > > > > > > > > > > | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
*/
struct Th_Variable {
int nRef; /* Number of references to this structure */
int nData; /* Number of bytes at Th_Variable.zData */
char *zData; /* Data for scalar variables */
Th_Hash *pHash; /* Data for array variables */
};
/*
** This structure is used to pass complete context information to the
** hash iteration callback functions that need a Th_Interp and a list
** to operate on, e.g. thListAppendHashKey().
*/
struct Th_InterpAndList {
Th_Interp *interp; /* Associated interpreter context */
char **pzList; /* IN/OUT: Ptr to ptr to list */
int *pnList; /* IN/OUT: Current length of *pzList */
};
/*
** Hash table API:
*/
#define TH_HASHSIZE 257
struct Th_Hash {
Th_HashEntry *a[TH_HASHSIZE];
|
| ︙ | ︙ | |||
296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
if( pCommand->xDel ){
pCommand->xDel((Th_Interp *)pContext, pCommand->pContext);
}
Th_Free((Th_Interp *)pContext, pEntry->pData);
pEntry->pData = 0;
return 1;
}
/*
** Push a new frame onto the stack.
*/
static int thPushFrame(Th_Interp *interp, Th_Frame *pFrame){
pFrame->paVar = Th_HashNew(interp);
pFrame->pCaller = interp->pFrame;
| > > > > > > > > > > > > > > > | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
if( pCommand->xDel ){
pCommand->xDel((Th_Interp *)pContext, pCommand->pContext);
}
Th_Free((Th_Interp *)pContext, pEntry->pData);
pEntry->pData = 0;
return 1;
}
/*
** Argument pEntry points to an entry in a hash table. The key is
** the list element to be added.
**
** Argument pContext is a pointer to the Th_InterpAndList structure.
**
** Always returns non-zero.
*/
static int thListAppendHashKey(Th_HashEntry *pEntry, void *pContext){
Th_InterpAndList *pInterpAndList = (Th_InterpAndList *)pContext;
Th_ListAppend(pInterpAndList->interp, pInterpAndList->pzList,
pInterpAndList->pnList, pEntry->zKey, pEntry->nKey);
return 1;
}
/*
** Push a new frame onto the stack.
*/
static int thPushFrame(Th_Interp *interp, Th_Frame *pFrame){
pFrame->paVar = Th_HashNew(interp);
pFrame->pCaller = interp->pFrame;
|
| ︙ | ︙ | |||
2225 2226 2227 2228 2229 2230 2231 2232 |
}
default: {
int j;
const char *zOp;
for(j=0; (zOp=aOperator[j].zOp); j++){
int nOp = aOperator[j].nOp;
int isMatch = 0;
| > | | < | | > > > > > > > > > > > | 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 |
}
default: {
int j;
const char *zOp;
for(j=0; (zOp=aOperator[j].zOp); j++){
int nOp = aOperator[j].nOp;
int nRemain = nExpr - i;
int isMatch = 0;
if( nRemain>=nOp && 0==memcmp(zOp, &zExpr[i], nOp) ){
isMatch = 1;
}
if( isMatch ){
if( aOperator[j].eOp==OP_CLOSE_BRACKET ){
nNest--;
}else if( nRemain>nOp ){
if( aOperator[j].eOp==OP_OPEN_BRACKET ){
nNest++;
}
}else{
/*
** This is not really a match because this operator cannot
** legally appear at the end of the string.
*/
isMatch = 0;
}
}
if( nToken>0 && aOperator[j].iPrecedence==1 ){
Expr *pPrev = apToken[nToken-1];
if( !pPrev->pOp || pPrev->pOp->eOp==OP_CLOSE_BRACKET ){
continue;
}
}
|
| ︙ | ︙ | |||
2644 2645 2646 2647 2648 2649 2650 |
int base = 10;
int (*isdigit)(char) = th_isdigit;
if( n<0 ){
n = th_strlen(z);
}
| | < | | | | | | | | | | | | | < | 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 |
int base = 10;
int (*isdigit)(char) = th_isdigit;
if( n<0 ){
n = th_strlen(z);
}
if( n>1 && (z[0]=='-' || z[0]=='+') ){
i = 1;
}
if( (n-i)>2 && z[i]=='0' ){
if( z[i+1]=='x' || z[i+1]=='X' ){
i += 2;
base = 16;
isdigit = th_ishexdig;
}else if( z[i+1]=='o' || z[i+1]=='O' ){
i += 2;
base = 8;
isdigit = th_isoctdig;
}else if( z[i+1]=='b' || z[i+1]=='B' ){
i += 2;
base = 2;
isdigit = th_isbindig;
}
}
for(; i<n; i++){
char c = z[i];
if( !isdigit(c) ){
Th_ErrorMessage(interp, "expected integer, got: \"", z, n);
return TH_ERROR;
|
| ︙ | ︙ | |||
2821 2822 2823 2824 2825 2826 2827 |
*z++ = zExp[i];
}
}
*z = '\0';
return Th_SetResult(interp, zBuf, -1);
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 |
*z++ = zExp[i];
}
}
*z = '\0';
return Th_SetResult(interp, zBuf, -1);
}
/*
** Appends all currently registered command names to the specified list
** and returns TH_OK upon success. Any other return value indicates an
** error.
*/
int Th_ListAppendCommands(Th_Interp *interp, char **pzList, int *pnList){
Th_InterpAndList *p = (Th_InterpAndList *)Th_Malloc(
interp, sizeof(Th_InterpAndList)
);
p->interp = interp;
p->pzList = pzList;
p->pnList = pnList;
Th_HashIterate(interp, interp->paCmd, thListAppendHashKey, p);
Th_Free(interp, p);
return TH_OK;
}
/*
** Appends all variable names for the current frame to the specified list
** and returns TH_OK upon success. Any other return value indicates an
** error. If the current frame cannot be obtained, TH_ERROR is returned.
*/
int Th_ListAppendVariables(Th_Interp *interp, char **pzList, int *pnList){
Th_Frame *pFrame = getFrame(interp, 0);
if( pFrame ){
Th_InterpAndList *p = (Th_InterpAndList *)Th_Malloc(
interp, sizeof(Th_InterpAndList)
);
p->interp = interp;
p->pzList = pzList;
p->pnList = pnList;
Th_HashIterate(interp, pFrame->paVar, thListAppendHashKey, p);
Th_Free(interp, p);
return TH_OK;
}else{
return TH_ERROR;
}
}
|
Changes to src/th.h.
| ︙ | ︙ | |||
136 137 138 139 140 141 142 143 144 145 146 147 148 149 | ** Functions for handling numbers and pointers. */ int Th_ToInt(Th_Interp *, const char *, int, int *); int Th_ToDouble(Th_Interp *, const char *, int, double *); int Th_SetResultInt(Th_Interp *, int); int Th_SetResultDouble(Th_Interp *, double); /* ** Drop in replacements for the corresponding standard library functions. */ int th_strlen(const char *); int th_isdigit(char); int th_isspace(char); int th_isalnum(char); | > > > > > > | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | ** Functions for handling numbers and pointers. */ int Th_ToInt(Th_Interp *, const char *, int, int *); int Th_ToDouble(Th_Interp *, const char *, int, double *); int Th_SetResultInt(Th_Interp *, int); int Th_SetResultDouble(Th_Interp *, double); /* ** Functions for handling command and variable introspection. */ int Th_ListAppendCommands(Th_Interp *, char **, int *); int Th_ListAppendVariables(Th_Interp *, char **, int *); /* ** Drop in replacements for the corresponding standard library functions. */ int th_strlen(const char *); int th_isdigit(char); int th_isspace(char); int th_isalnum(char); |
| ︙ | ︙ |
Changes to src/th_lang.c.
| ︙ | ︙ | |||
846 847 848 849 850 851 852 | Th_SetResult(interp, z, n); return TH_OK; } /* ** TH Syntax: ** | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 |
Th_SetResult(interp, z, n);
return TH_OK;
}
/*
** TH Syntax:
**
** info exists VARNAME
*/
static int info_exists_command(
Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
){
int rc;
if( argc!=3 ){
return Th_WrongNumArgs(interp, "info exists var");
}
rc = Th_ExistsVar(interp, argv[2], argl[2]);
Th_SetResultInt(interp, rc);
return TH_OK;
}
/*
** TH Syntax:
**
** info commands
*/
static int info_commands_command(
Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
){
int rc;
char *zElem = 0;
int nElem = 0;
if( argc!=2 ){
return Th_WrongNumArgs(interp, "info commands");
}
rc = Th_ListAppendCommands(interp, &zElem, &nElem);
if( rc!=TH_OK ){
return rc;
}
Th_SetResult(interp, zElem, nElem);
return TH_OK;
}
/*
** TH Syntax:
**
** info vars
*/
static int info_vars_command(
Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
){
int rc;
char *zElem = 0;
int nElem = 0;
if( argc!=2 ){
return Th_WrongNumArgs(interp, "info vars");
}
rc = Th_ListAppendVariables(interp, &zElem, &nElem);
if( rc!=TH_OK ){
return rc;
}
Th_SetResult(interp, zElem, nElem);
return TH_OK;
}
/*
** TH Syntax:
**
** unset VAR
*/
static int unset_command(
|
| ︙ | ︙ | |||
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 |
};
return Th_CallSubCommand(interp, ctx, argc, argv, argl, aSub);
}
/*
** TH Syntax:
**
** info exists VARNAME
*/
static int info_command(
Th_Interp *interp,
void *ctx,
int argc,
const char **argv,
int *argl
){
static const Th_SubCommand aSub[] = {
| > > > | > | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 |
};
return Th_CallSubCommand(interp, ctx, argc, argv, argl, aSub);
}
/*
** TH Syntax:
**
** info commands
** info exists VARNAME
** info vars
*/
static int info_command(
Th_Interp *interp,
void *ctx,
int argc,
const char **argv,
int *argl
){
static const Th_SubCommand aSub[] = {
{ "commands", info_commands_command },
{ "exists", info_exists_command },
{ "vars", info_vars_command },
{ 0, 0 }
};
return Th_CallSubCommand(interp, ctx, argc, argv, argl, aSub);
}
/*
** Convert the script level frame specification (used by the commands
|
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
172 173 174 175 176 177 178 | ** True if output is enabled. False if disabled. */ static int enableOutput = 1; /* ** TH1 command: enable_output BOOLEAN ** | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | ** True if output is enabled. False if disabled. */ static int enableOutput = 1; /* ** TH1 command: enable_output BOOLEAN ** ** Enable or disable the puts and wiki commands. */ static int enableOutputCmd( Th_Interp *interp, void *p, int argc, const char **argv, int *argl |
| ︙ | ︙ | |||
337 338 339 340 341 342 343 344 345 |
return Th_WrongNumArgs(interp, "puts STRING");
}
sendText((char*)argv[1], argl[1], *(unsigned int*)pConvert);
return TH_OK;
}
/*
** TH1 command: wiki STRING
**
| > | > | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
return Th_WrongNumArgs(interp, "puts STRING");
}
sendText((char*)argv[1], argl[1], *(unsigned int*)pConvert);
return TH_OK;
}
/*
** TH1 command: decorate STRING
** TH1 command: wiki STRING
**
** Render the input string as wiki. For the decorate command, only links
** are handled.
*/
static int wikiCmd(
Th_Interp *interp,
void *p,
int argc,
const char **argv,
int *argl
|
| ︙ | ︙ | |||
503 504 505 506 507 508 509 510 511 512 513 514 515 516 | /* ** TH1 command: hasfeature STRING ** ** Return true if the fossil binary has the given compile-time feature ** enabled. The set of features includes: ** ** "ssl" = FOSSIL_ENABLE_SSL ** "th1Docs" = FOSSIL_ENABLE_TH1_DOCS ** "th1Hooks" = FOSSIL_ENABLE_TH1_HOOKS ** "tcl" = FOSSIL_ENABLE_TCL ** "useTclStubs" = USE_TCL_STUBS ** "tclStubs" = FOSSIL_ENABLE_TCL_STUBS ** "tclPrivateStubs" = FOSSIL_ENABLE_TCL_PRIVATE_STUBS ** "json" = FOSSIL_ENABLE_JSON | > | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | /* ** TH1 command: hasfeature STRING ** ** Return true if the fossil binary has the given compile-time feature ** enabled. The set of features includes: ** ** "ssl" = FOSSIL_ENABLE_SSL ** "legacyMvRm" = FOSSIL_ENABLE_LEGACY_MV_RM ** "th1Docs" = FOSSIL_ENABLE_TH1_DOCS ** "th1Hooks" = FOSSIL_ENABLE_TH1_HOOKS ** "tcl" = FOSSIL_ENABLE_TCL ** "useTclStubs" = USE_TCL_STUBS ** "tclStubs" = FOSSIL_ENABLE_TCL_STUBS ** "tclPrivateStubs" = FOSSIL_ENABLE_TCL_PRIVATE_STUBS ** "json" = FOSSIL_ENABLE_JSON |
| ︙ | ︙ | |||
534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
if(NULL==zArg){
/* placeholder for following ifdefs... */
}
#if defined(FOSSIL_ENABLE_SSL)
else if( 0 == fossil_strnicmp( zArg, "ssl\0", 4 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_TH1_DOCS)
else if( 0 == fossil_strnicmp( zArg, "th1Docs\0", 8 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_TH1_HOOKS)
| > > > > > | 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
if(NULL==zArg){
/* placeholder for following ifdefs... */
}
#if defined(FOSSIL_ENABLE_SSL)
else if( 0 == fossil_strnicmp( zArg, "ssl\0", 4 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_LEGACY_MV_RM)
else if( 0 == fossil_strnicmp( zArg, "legacyMvRm\0", 11 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_TH1_DOCS)
else if( 0 == fossil_strnicmp( zArg, "th1Docs\0", 8 ) ){
rc = 1;
}
#endif
#if defined(FOSSIL_ENABLE_TH1_HOOKS)
|
| ︙ | ︙ |
Changes to src/th_tcl.c.
| ︙ | ︙ | |||
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
/*
** Creates and initializes a Tcl interpreter for use with the specified TH1
** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
** by the caller. This must be declared here because quite a few functions in
** this file need to use it before it can be defined.
*/
static int createTclInterp(Th_Interp *interp, void *pContext);
/*
** Returns a name for a Tcl return code.
*/
static const char *getTclReturnCodeName(
int rc,
int nullIfOk
){
static char zRc[32];
switch( rc ){
case TCL_OK: return nullIfOk ? 0 : "TCL_OK";
case TCL_ERROR: return "TCL_ERROR";
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
/*
** Creates and initializes a Tcl interpreter for use with the specified TH1
** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
** by the caller. This must be declared here because quite a few functions in
** this file need to use it before it can be defined.
*/
static int createTclInterp(Th_Interp *interp, void *pContext);
/*
** Returns the TH1 return code corresponding to the specified Tcl
** return code.
*/
static int getTh1ReturnCode(
int rc /* The Tcl return code value to convert. */
){
switch( rc ){
case /*0*/ TCL_OK: return /*0*/ TH_OK;
case /*1*/ TCL_ERROR: return /*1*/ TH_ERROR;
case /*2*/ TCL_RETURN: return /*3*/ TH_RETURN;
case /*3*/ TCL_BREAK: return /*2*/ TH_BREAK;
case /*4*/ TCL_CONTINUE: return /*4*/ TH_CONTINUE;
default /*?*/: return /*?*/ rc;
}
}
/*
** Returns the Tcl return code corresponding to the specified TH1
** return code.
*/
static int getTclReturnCode(
int rc /* The TH1 return code value to convert. */
){
switch( rc ){
case /*0*/ TH_OK: return /*0*/ TCL_OK;
case /*1*/ TH_ERROR: return /*1*/ TCL_ERROR;
case /*2*/ TH_BREAK: return /*3*/ TCL_BREAK;
case /*3*/ TH_RETURN: return /*2*/ TCL_RETURN;
case /*4*/ TH_CONTINUE: return /*4*/ TCL_CONTINUE;
default /*?*/: return /*?*/ rc;
}
}
/*
** Returns a name for a Tcl return code.
*/
static const char *getTclReturnCodeName(
int rc,
int nullIfOk
){
static char zRc[32];
switch( rc ){
case TCL_OK: return nullIfOk ? 0 : "TCL_OK";
case TCL_ERROR: return "TCL_ERROR";
case TCL_RETURN: return "TCL_RETURN";
case TCL_BREAK: return "TCL_BREAK";
case TCL_CONTINUE: return "TCL_CONTINUE";
default: {
sqlite3_snprintf(sizeof(zRc), zRc, "Tcl return code %d", rc);
}
}
return zRc;
}
|
| ︙ | ︙ | |||
348 349 350 351 352 353 354 |
tclContext->pPostContext : tclContext->pPreContext,
interp, ctx, argc, argv, argl, rc);
}
return rc;
}
/*
| | | > > | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
tclContext->pPostContext : tclContext->pPreContext,
interp, ctx, argc, argv, argl, rc);
}
return rc;
}
/*
** TH1 command: tclEval arg ?arg ...?
**
** Evaluates the Tcl script and returns its result verbatim. If a Tcl script
** error is generated, it will be transformed into a TH1 script error. A Tcl
** interpreter will be created automatically if it has not been already.
*/
static int tclEval_command(
Th_Interp *interp,
void *ctx,
int argc,
const char **argv,
int *argl
|
| ︙ | ︙ | |||
398 399 400 401 402 403 404 |
rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
Tcl_DecrRefCount(objPtr);
FREE_ARGV_TO_OBJV();
}
zResult = getTclResult(tclInterp, &nResult);
Th_SetResult(interp, zResult, nResult);
Tcl_Release((ClientData)tclInterp);
| | > | | > > | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
Tcl_DecrRefCount(objPtr);
FREE_ARGV_TO_OBJV();
}
zResult = getTclResult(tclInterp, &nResult);
Th_SetResult(interp, zResult, nResult);
Tcl_Release((ClientData)tclInterp);
rc = notifyPreOrPostEval(1, interp, ctx, argc, argv, argl,
getTh1ReturnCode(rc));
return rc;
}
/*
** TH1 command: tclExpr arg ?arg ...?
**
** Evaluates the Tcl expression and returns its result verbatim. If a Tcl
** script error is generated, it will be transformed into a TH1 script error.
** A Tcl interpreter will be created automatically if it has not been already.
*/
static int tclExpr_command(
Th_Interp *interp,
void *ctx,
int argc,
const char **argv,
int *argl
|
| ︙ | ︙ | |||
459 460 461 462 463 464 465 |
zResult = Tcl_GetStringFromObj(resultObjPtr, &nResult);
}else{
zResult = getTclResult(tclInterp, &nResult);
}
Th_SetResult(interp, zResult, nResult);
if( rc==TCL_OK ) Tcl_DecrRefCount(resultObjPtr);
Tcl_Release((ClientData)tclInterp);
| | > | | > > | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
zResult = Tcl_GetStringFromObj(resultObjPtr, &nResult);
}else{
zResult = getTclResult(tclInterp, &nResult);
}
Th_SetResult(interp, zResult, nResult);
if( rc==TCL_OK ) Tcl_DecrRefCount(resultObjPtr);
Tcl_Release((ClientData)tclInterp);
rc = notifyPreOrPostEval(1, interp, ctx, argc, argv, argl,
getTh1ReturnCode(rc));
return rc;
}
/*
** TH1 command: tclInvoke command ?arg ...?
**
** Invokes the Tcl command using the supplied arguments. No additional
** substitutions are performed on the arguments. A Tcl interpreter will
** be created automatically if it has not been already.
*/
static int tclInvoke_command(
Th_Interp *interp,
void *ctx,
int argc,
const char **argv,
int *argl
|
| ︙ | ︙ | |||
531 532 533 534 535 536 537 |
COPY_ARGV_TO_OBJV();
rc = Tcl_EvalObjv(tclInterp, objc, objv, 0);
FREE_ARGV_TO_OBJV();
}
zResult = getTclResult(tclInterp, &nResult);
Th_SetResult(interp, zResult, nResult);
Tcl_Release((ClientData)tclInterp);
| | > | | > | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 |
COPY_ARGV_TO_OBJV();
rc = Tcl_EvalObjv(tclInterp, objc, objv, 0);
FREE_ARGV_TO_OBJV();
}
zResult = getTclResult(tclInterp, &nResult);
Th_SetResult(interp, zResult, nResult);
Tcl_Release((ClientData)tclInterp);
rc = notifyPreOrPostEval(1, interp, ctx, argc, argv, argl,
getTh1ReturnCode(rc));
return rc;
}
/*
** Tcl command: th1Eval arg
**
** Evaluates the TH1 script and returns its result verbatim. If a TH1 script
** error is generated, it will be transformed into a Tcl script error.
*/
static int Th1EvalObjCmd(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[]
){
|
| ︙ | ︙ | |||
564 565 566 567 568 569 570 |
Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL);
return TCL_ERROR;
}
arg = Tcl_GetStringFromObj(objv[1], &nArg);
rc = Th_Eval(th1Interp, 0, arg, nArg);
arg = Th_GetResult(th1Interp, &nArg);
Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, nArg));
| | | | > | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 |
Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL);
return TCL_ERROR;
}
arg = Tcl_GetStringFromObj(objv[1], &nArg);
rc = Th_Eval(th1Interp, 0, arg, nArg);
arg = Th_GetResult(th1Interp, &nArg);
Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, nArg));
return getTclReturnCode(rc);
}
/*
** Tcl command: th1Expr arg
**
** Evaluates the TH1 expression and returns its result verbatim. If a TH1
** script error is generated, it will be transformed into a Tcl script error.
*/
static int Th1ExprObjCmd(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[]
){
|
| ︙ | ︙ | |||
596 597 598 599 600 601 602 |
Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL);
return TCL_ERROR;
}
arg = Tcl_GetStringFromObj(objv[1], &nArg);
rc = Th_Expr(th1Interp, arg, nArg);
arg = Th_GetResult(th1Interp, &nArg);
Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, nArg));
| | | 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 |
Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL);
return TCL_ERROR;
}
arg = Tcl_GetStringFromObj(objv[1], &nArg);
rc = Th_Expr(th1Interp, arg, nArg);
arg = Th_GetResult(th1Interp, &nArg);
Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, nArg));
return getTclReturnCode(rc);
}
/*
** Array of Tcl integration commands. Used when adding or removing the Tcl
** integration commands from TH1.
*/
static struct _Command {
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
106 107 108 109 110 111 112 |
int r, g, b; /* Values for red, green, and blue */
int h1, h2, h3, h4; /* Elements of the hash value */
int mx, mn; /* Components of HSV */
static char zColor[10]; /* The resulting color */
static int ix[2] = {0,0}; /* Color chooser parameters */
if( ix[0]==0 ){
| | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
int r, g, b; /* Values for red, green, and blue */
int h1, h2, h3, h4; /* Elements of the hash value */
int mx, mn; /* Components of HSV */
static char zColor[10]; /* The resulting color */
static int ix[2] = {0,0}; /* Color chooser parameters */
if( ix[0]==0 ){
if( skin_detail_boolean("white-foreground") ){
ix[0] = 140;
ix[1] = 40;
}else{
ix[0] = 216;
ix[1] = 16;
}
}
|
| ︙ | ︙ | |||
161 162 163 164 165 166 167 |
** testing the hash_color() function.
*/
void test_hash_color_page(void){
const char *zBr;
char zNm[10];
int i, cnt;
login_check_credentials();
| < | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
** testing the hash_color() function.
*/
void test_hash_color_page(void){
const char *zBr;
char zNm[10];
int i, cnt;
login_check_credentials();
style_header("Hash Color Test");
for(i=cnt=0; i<10; i++){
sqlite3_snprintf(sizeof(zNm),zNm,"b%d",i);
zBr = P(zNm);
if( zBr && zBr[0] ){
@ <p style='border:1px solid;background-color:%s(hash_color(zBr));'>
|
| ︙ | ︙ | |||
240 241 242 243 244 245 246 |
zPrevDate[0] = 0;
mxWikiLen = db_get_int("timeline-max-comment", 0);
dateFormat = db_get_int("timeline-date-format", 0);
zDateFmt = P("datefmt");
if( zDateFmt ) dateFormat = atoi(zDateFmt);
if( tmFlags & TIMELINE_GRAPH ){
pGraph = graph_init();
| < < < < < | < > | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
zPrevDate[0] = 0;
mxWikiLen = db_get_int("timeline-max-comment", 0);
dateFormat = db_get_int("timeline-date-format", 0);
zDateFmt = P("datefmt");
if( zDateFmt ) dateFormat = atoi(zDateFmt);
if( tmFlags & TIMELINE_GRAPH ){
pGraph = graph_init();
}
db_static_prepare(&qbranch,
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
TAG_BRANCH
);
@ <table id="timelineTable" class="timelineTable">
blob_zero(&comment);
while( db_step(pQuery)==SQLITE_ROW ){
int rid = db_column_int(pQuery, 0);
const char *zUuid = db_column_text(pQuery, 1);
int isLeaf = db_column_int(pQuery, 5);
const char *zBgClr = db_column_text(pQuery, 6);
const char *zDate = db_column_text(pQuery, 2);
const char *zType = db_column_text(pQuery, 7);
const char *zUser = db_column_text(pQuery, 4);
const char *zTagList = db_column_text(pQuery, 8);
int tagid = db_column_int(pQuery, 9);
const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
const char *zBr = 0; /* Branch */
int commentColumn = 3; /* Column containing comment text */
int modPending; /* Pending moderation */
char *zDateLink; /* URL for the link on the timestamp */
char zTime[20];
if( zDate==0 ){
zDate = "YYYY-MM-DD HH:MM:SS"; /* Something wrong with the repo */
}
modPending = moderation_pending(rid);
if( tagid ){
|
| ︙ | ︙ | |||
349 350 351 352 353 354 355 |
@ <tr class="timelineSelected">
pendingEndTr = 2;
}else if( rid==vid ){
@ <tr class="timelineCurrent">
}else {
@ <tr>
}
| > | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
@ <tr class="timelineSelected">
pendingEndTr = 2;
}else if( rid==vid ){
@ <tr class="timelineCurrent">
}else {
@ <tr>
}
zDateLink = href("%R/timeline?c=%!S&unhide", zUuid);
@ <td class="timelineTime">%z(zDateLink)%s(zTime)</a></td>
@ <td class="timelineGraph">
if( tmFlags & TIMELINE_UCOLOR ) zBgClr = zUser ? hash_color(zUser) : 0;
if( zType[0]=='c'
&& (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
){
db_reset(&qbranch);
db_bind_int(&qbranch, ":rid", rid);
|
| ︙ | ︙ | |||
388 389 390 391 392 393 394 |
while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){
aParent[nParent++] = db_column_int(&qparent, 0);
}
db_reset(&qparent);
gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
zUuid, isLeaf);
db_reset(&qbranch);
| | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){
aParent[nParent++] = db_column_int(&qparent, 0);
}
db_reset(&qparent);
gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr,
zUuid, isLeaf);
db_reset(&qbranch);
@ <div id="m%d(gidx)" class="tl-nodemark"></div>
}
@</td>
if( zBgClr && zBgClr[0] && rid!=selectedRid ){
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
}else{
@ <td class="timelineTableCell">
}
|
| ︙ | ︙ | |||
496 497 498 499 500 501 502 |
/* Generate the file-change list if requested */
if( (tmFlags & (TIMELINE_FCHANGES|TIMELINE_FRENAMES))!=0
&& zType[0]=='c' && g.perm.Hyperlink
){
int inUl = 0;
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
| | | > | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 |
/* Generate the file-change list if requested */
if( (tmFlags & (TIMELINE_FCHANGES|TIMELINE_FRENAMES))!=0
&& zType[0]=='c' && g.perm.Hyperlink
){
int inUl = 0;
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
"SELECT pid,"
" fid,"
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
" (SELECT uuid FROM blob WHERE rid=fid),"
" (SELECT uuid FROM blob WHERE rid=pid),"
" (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
" FROM mlink"
" WHERE mid=:mid AND (pid!=fid OR pfnid>0)"
" AND (fid>0 OR"
" fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=:mid))"
" AND NOT mlink.isaux"
" ORDER BY 3 /*sort*/"
);
fchngQueryInit = 1;
}
db_bind_int(&fchngQuery, ":mid", rid);
while( db_step(&fchngQuery)==SQLITE_ROW ){
const char *zFilename = db_column_text(&fchngQuery, 2);
int isNew = db_column_int(&fchngQuery, 0)<=0;
int isMergeNew = db_column_int(&fchngQuery, 0)<0;
int fid = db_column_int(&fchngQuery, 1);
int isDel = fid==0;
const char *zOldName = db_column_text(&fchngQuery, 5);
const char *zOld = db_column_text(&fchngQuery, 4);
const char *zNew = db_column_text(&fchngQuery, 3);
const char *zUnpub = "";
char *zA;
|
| ︙ | ︙ | |||
543 544 545 546 547 548 549 |
continue;
}
zA = href("%R/artifact/%!S",fid?zNew:zOld);
if( content_is_private(fid) ){
zUnpub = UNPUB_TAG;
}
if( isNew ){
| | > > > > > | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
continue;
}
zA = href("%R/artifact/%!S",fid?zNew:zOld);
if( content_is_private(fid) ){
zUnpub = UNPUB_TAG;
}
if( isNew ){
@ <li> %s(zA)%h(zFilename)</a>%s(zId) %s(zUnpub)
if( isMergeNew ){
@ (added by merge)
}else{
@ (new file)
}
@ %z(href("%R/artifact/%!S",zNew))[view]</a></li>
}else if( isDel ){
@ <li> %s(zA)%h(zFilename)</a> (deleted)</li>
}else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
@ <li> %h(zOldName) → %s(zA)%h(zFilename)</a>%s(zId)
@ %s(zUnpub) %z(href("%R/artifact/%!S",zNew))[view]</a></li>
}else{
if( zOldName!=0 ){
|
| ︙ | ︙ | |||
580 581 582 583 584 585 586 |
}
if( pGraph ){
graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
| < < < < < < < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < > > | < < < < | < > > > | > | > > | > > > > > > > > | | | | < < < < < < < < < < < < | | > > > > | < < | | | | > > > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | | < | | | > | | < < | < < < < < < < < | | < | | | < < < | < < < < < < < < | | | < | | | > | < | | | < | | < | | | > | > > > | | | < | < < | > | | | < < > | | < < | > > | > > > > | | | > | < < | | > | > > | | | < | | < < < < | | < < | | < < | | | < | | | < < < < < < < < < < < < | | | | | | | | | | | > > | | | > | | | < | < < < < < < < < | < > | > | | | | | | | | | < < < < < | < < < < | | > | > | < > > < < < > > | | | > | | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 |
}
if( pGraph ){
graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
@ <tr class="timelineBottom"><td></td><td></td><td></td></tr>
}
}
@ </table>
if( fchngQueryInit ) db_finalize(&fchngQuery);
timeline_output_graph_javascript(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0, 0);
}
/*
** Change the RGB background color given in the argument in a foreground
** color with the same hue.
*/
static const char *bg_to_fg(const char *zIn){
int i;
unsigned int x[3];
unsigned int mx = 0;
static int whiteFg = -1;
static char zRes[10];
if( strlen(zIn)!=7 || zIn[0]!='#' ) return zIn;
zIn++;
for(i=0; i<3; i++){
x[i] = hex_digit_value(zIn[0])*16 + hex_digit_value(zIn[1]);
zIn += 2;
if( x[i]>mx ) mx = x[i];
}
if( whiteFg<0 ) whiteFg = skin_detail_boolean("white-foreground");
if( whiteFg ){
/* Make the color lighter */
static const unsigned int t = 215;
if( mx<t ) for(i=0; i<3; i++) x[i] += t - mx;
}else{
/* Make the color darker */
static const unsigned int t = 128;
if( mx>t ) for(i=0; i<3; i++) x[i] -= mx - t;
}
sqlite3_snprintf(sizeof(zRes),zRes,"#%02x%02x%02x",x[0],x[1],x[2]);
return zRes;
}
/*
** Generate all of the necessary javascript to generate a timeline
** graph.
*/
void timeline_output_graph_javascript(
GraphContext *pGraph, /* The graph to be displayed */
int omitDescenders, /* True to omit descenders */
int fileDiff /* True for file diff. False for check-in diff */
){
if( pGraph && pGraph->nErr==0 && pGraph->nRow>0 ){
GraphRow *pRow;
int i;
char cSep;
int iRailPitch; /* Pixels between consecutive rails */
int showArrowheads; /* True to draw arrowheads. False to omit. */
int circleNodes; /* True for circle nodes. False for square nodes */
int colorGraph; /* Use colors for graph lines */
iRailPitch = atoi(PD("railpitch","0"));
showArrowheads = skin_detail_boolean("timeline-arrowheads");
circleNodes = skin_detail_boolean("timeline-circle-nodes");
colorGraph = skin_detail_boolean("timeline-color-graph-lines");
@ <script>(function(){
@ "use strict";
@ var css = "";
if( circleNodes ){
@ css += ".tl-node, .tl-node:after { border-radius: 50%%; }";
}
if( !showArrowheads ){
@ css += ".tl-arrow.u { display: none; }";
}
@ if( css!=="" ){
@ var style = document.createElement("style");
@ style.textContent = css;
@ document.querySelector("head").appendChild(style);
@ }
/* the rowinfo[] array contains all the information needed to generate
** the graph. Each entry contains information for a single row:
**
** id: The id of the <div> element for the row. This is an integer.
** to get an actual id, prepend "m" to the integer. The top node
** is 1 and numbers increase moving down the timeline.
** bg: The background color for this row
** r: The "rail" that the node for this row sits on. The left-most
** rail is 0 and the number increases to the right.
** d: True if there is a "descender" - an arrow coming from the bottom
** of the page straight up to this node.
** mo: "merge-out". If non-negative, this is the rail position
** for the upward portion of a merge arrow. The merge arrow goes up
** to the row identified by mu:. If this value is negative then
** node has no merge children and no merge-out line is drawn.
** mu: The id of the row which is the top of the merge-out arrow.
** u: Draw a thick child-line out of the top of this node and up to
** the node with an id equal to this value. 0 if it is straight to
** the top of the page, -1 if there is no thick-line riser.
** f: 0x01: a leaf node.
** au: An array of integers that define thick-line risers for branches.
** The integers are in pairs. For each pair, the first integer is
** is the rail on which the riser should run and the second integer
** is the id of the node upto which the riser should run.
** mi: "merge-in". An array of integer rail positions from which
** merge arrows should be drawn into this node. If the value is
** negative, then the rail position is the absolute value of mi[]
** and a thin merge-arrow descender is drawn to the bottom of
** the screen.
** h: The SHA1 hash of the object being graphed
*/
cgi_printf("var rowinfo = [\n");
for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
cgi_printf("{id:%d,bg:\"%s\",r:%d,d:%d,mo:%d,mu:%d,u:%d,f:%d,au:",
pRow->idx, /* id */
pRow->zBgClr, /* bg */
pRow->iRail, /* r */
pRow->bDescender, /* d */
pRow->mergeOut, /* mo */
pRow->mergeUpto, /* mu */
pRow->aiRiser[pRow->iRail], /* u */
pRow->isLeaf ? 1 : 0 /* f */
);
/* u */
cSep = '[';
for(i=0; i<GR_MAX_RAIL; i++){
if( i==pRow->iRail ) continue;
if( pRow->aiRiser[i]>0 ){
cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
cSep = ',';
}
}
if( cSep=='[' ) cgi_printf("[");
cgi_printf("],");
if( colorGraph && pRow->zBgClr[0]=='#' ){
cgi_printf("fg:\"%s\",", bg_to_fg(pRow->zBgClr));
}
/* mi */
cgi_printf("mi:");
cSep = '[';
for(i=0; i<GR_MAX_RAIL; i++){
if( pRow->mergeIn[i] ){
int mi = i;
if( pRow->mergeDown & (1<<i) ) mi = -mi;
cgi_printf("%c%d", cSep, mi);
cSep = ',';
}
}
if( cSep=='[' ) cgi_printf("[");
cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
}
cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
graph_free(pGraph);
@ var canvasDiv;
@ var railPitch;
@ var mergeOffset;
@ var node, arrow, arrowSmall, line, mArrow, mLine, wArrow, wLine;
@ function initGraph(){
@ var parent = gebi("timelineTable").rows[0].cells[1];
@ parent.style.verticalAlign = "top";
@ canvasDiv = document.createElement("div");
@ canvasDiv.className = "tl-canvas";
@ canvasDiv.style.position = "absolute";
@ parent.appendChild(canvasDiv);
@
@ var elems = {};
@ var elemClasses = [
@ "rail", "mergeoffset", "node", "arrow u", "arrow u sm", "line",
@ "arrow merge r", "line merge", "arrow warp", "line warp"
@ ];
@ for( var i=0; i<elemClasses.length; i++ ){
@ var cls = elemClasses[i];
@ var elem = document.createElement("div");
@ elem.className = "tl-" + cls;
@ if( cls.indexOf("line")==0 ) elem.className += " v";
@ canvasDiv.appendChild(elem);
@ var k = cls.replace(/\s/g, "_");
@ var r = elem.getBoundingClientRect();
@ var w = Math.round(r.right - r.left);
@ var h = Math.round(r.bottom - r.top);
@ elems[k] = {w: w, h: h, cls: cls};
@ }
@ node = elems.node;
@ arrow = elems.arrow_u;
@ arrowSmall = elems.arrow_u_sm;
@ line = elems.line;
@ mArrow = elems.arrow_merge_r;
@ mLine = elems.line_merge;
@ wArrow = elems.arrow_warp;
@ wLine = elems.line_warp;
@
@ var minRailPitch = Math.ceil((node.w+line.w)/2 + mArrow.w + 1);
if( iRailPitch ){
@ railPitch = %d(iRailPitch);
}else{
@ railPitch = elems.rail.w;
@ railPitch -= Math.floor((nrail-1)*(railPitch-minRailPitch)/21);
}
@ railPitch = Math.max(railPitch, minRailPitch);
@
if( PB("nomo") ){
@ mergeOffset = 0;
}else{
@ mergeOffset = railPitch-minRailPitch-mLine.w;
@ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
@ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
}
@
@ var canvasWidth = (nrail-1)*railPitch + node.w;
@ canvasDiv.style.width = canvasWidth + "px";
@ canvasDiv.style.position = "relative";
@ }
@ function drawBox(cls,color,x0,y0,x1,y1){
@ var n = document.createElement("div");
@ x0 = Math.floor(x0);
@ y0 = Math.floor(y0);
@ x1 = x1 || x1===0 ? Math.floor(x1) : x0;
@ y1 = y1 || y1===0 ? Math.floor(y1) : y0;
@ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
@ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
@ var w = x1-x0;
@ var h = y1-y0;
@ n.style.position = "absolute";
@ n.style.left = x0+"px";
@ n.style.top = y0+"px";
@ if( w ) n.style.width = w+"px";
@ if( h ) n.style.height = h+"px";
@ if( color ) n.style.backgroundColor = color;
@ n.className = "tl-"+cls;
@ canvasDiv.appendChild(n);
@ return n;
@ }
@ function absoluteY(obj){
@ var top = 0;
@ if( obj.offsetParent ){
@ do{
@ top += obj.offsetTop;
@ }while( obj = obj.offsetParent );
@ }
@ return top;
@ }
@ function miLineY(p){
@ return p.y + node.h - mLine.w - 1;
@ }
@ function drawLine(elem,color,x0,y0,x1,y1){
@ var cls = elem.cls + " ";
@ if( x1===null ){
@ x1 = x0+elem.w;
@ cls += "v";
@ }else{
@ y1 = y0+elem.w;
@ cls += "h";
@ }
@ drawBox(cls,color,x0,y0,x1,y1);
@ }
@ function drawUpArrow(from,to,color){
@ var y = to.y + node.h;
@ var arrowSpace = from.y - y + (!from.id || from.r!=to.r ? node.h/2 : 0);
@ var arw = arrowSpace < arrow.h*1.5 ? arrowSmall : arrow;
@ var x = to.x + (node.w-line.w)/2;
@ var y0 = from.y + node.h/2;
@ var y1 = Math.ceil(to.y + node.h + arw.h/2);
@ drawLine(line,color,x,y0,null,y1);
@ x = to.x + (node.w-arw.w)/2;
@ var n = drawBox(arw.cls,null,x,y);
@ n.style.borderBottomColor = color;
@ }
@ function drawMergeLine(x0,y0,x1,y1){
@ drawLine(mLine,null,x0,y0,x1,y1);
@ }
@ function drawMergeArrow(p,rail){
@ var x0 = rail*railPitch + node.w/2;
@ if( rail in mergeLines ){
@ x0 += mergeLines[rail];
@ if( p.r<rail ) x0 += mLine.w;
@ }else{
@ x0 += (p.r<rail ? -1 : 1)*line.w/2;
@ }
@ var x1 = mArrow.w ? mArrow.w/2 : -node.w/2;
@ x1 = p.x + (p.r<rail ? node.w + Math.ceil(x1) : -x1);
@ var y = miLineY(p);
@ drawMergeLine(x0,y,x1,null);
@ var x = p.x + (p.r<rail ? node.w : -mArrow.w);
@ var cls = "arrow merge " + (p.r<rail ? "l" : "r");
@ drawBox(cls,null,x,y+(mLine.w-mArrow.h)/2);
@ }
@ function drawNode(p, btm){
@ if( p.u>0 ) drawUpArrow(p,rowinfo[p.u-1],p.fg);
@ var cls = node.cls;
@ if( p.mi.length ) cls += " merge";
@ if( p.f&1 ) cls += " leaf";
@ var n = drawBox(cls,p.bg,p.x,p.y);
@ n.id = "tln"+p.id;
@ n.onclick = clickOnNode;
@ n.style.zIndex = 10;
if( !omitDescenders ){
@ if( p.u==0 ) drawUpArrow(p,{x: p.x, y: -node.h},p.fg);
@ if( p.d ) drawUpArrow({x: p.x, y: btm-node.h/2},p,p.fg);
}
@ if( p.mo>=0 ){
@ var x0 = p.x + node.w/2;
@ var x1 = p.mo*railPitch + node.w/2;
@ var u = rowinfo[p.mu-1];
@ var y1 = miLineY(u);
@ if( p.u<0 || p.mo!=p.r ){
@ x1 += mergeLines[p.mo] = -mLine.w/2;
@ var y0 = p.y+2;
@ if( p.r!=p.mo ) drawMergeLine(x0,y0,x1+(x0<x1 ? mLine.w : 0),null);
@ drawMergeLine(x1,y0+mLine.w,null,y1);
@ }else if( mergeOffset ){
@ mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
@ x1 += mergeLines[p.mo];
@ drawMergeLine(x1,p.y+node.h/2,null,y1);
@ }else{
@ delete mergeLines[p.mo];
@ }
@ }
@ for( var i=0; i<p.au.length; i+=2 ){
@ var rail = p.au[i];
@ var x0 = p.x + node.w/2;
@ var x1 = rail*railPitch + (node.w-line.w)/2;
@ if( x0<x1 ){
@ x0 = Math.ceil(x0);
@ x1 += line.w;
@ }
@ var y0 = p.y + (node.h-line.w)/2;
@ var u = rowinfo[p.au[i+1]-1];
@ if( u.id<p.id ){
@ drawLine(line,u.fg,x0,y0,x1,null);
@ drawUpArrow(p,u,u.fg);
@ }else{
@ var y1 = u.y + (node.h-line.w)/2;
@ drawLine(wLine,u.fg,x0,y0,x1,null);
@ drawLine(wLine,u.fg,x1-line.w,y0,null,y1+line.w);
@ drawLine(wLine,u.fg,x1,y1,u.x-wArrow.w/2,null);
@ var x = u.x-wArrow.w;
@ var y = u.y+(node.h-wArrow.h)/2;
@ var n = drawBox(wArrow.cls,null,x,y);
@ if( u.fg ) n.style.borderLeftColor = u.fg;
@ }
@ }
@ for( var i=0; i<p.mi.length; i++ ){
@ var rail = p.mi[i];
@ if( rail<0 ){
@ rail = -rail;
@ mergeLines[rail] = -mLine.w/2;
@ var x = rail*railPitch + (node.w-mLine.w)/2;
@ drawMergeLine(x,miLineY(p),null,btm);
@ }
@ drawMergeArrow(p,rail);
@ }
@ }
@ var mergeLines;
@ function renderGraph(){
@ mergeLines = {};
@ canvasDiv.innerHTML = "";
@ var canvasY = absoluteY(canvasDiv);
@ for( var i=0; i<rowinfo.length; i++ ){
@ rowinfo[i].y = absoluteY(gebi("m"+rowinfo[i].id)) - canvasY;
@ rowinfo[i].x = rowinfo[i].r*railPitch;
@ }
@ var tlBtm = document.querySelector(".timelineBottom");
@ if( tlBtm.offsetHeight<node.h ){
@ tlBtm.style.height = node.h + "px";
@ }
@ var btm = absoluteY(tlBtm) - canvasY + tlBtm.offsetHeight;
@ for( var i=rowinfo.length-1; i>=0; i-- ){
@ drawNode(rowinfo[i], btm);
@ }
@ }
@ var selRow;
@ function clickOnNode(){
@ var p = rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-1];
@ if( !selRow ){
@ selRow = p;
@ this.className += " sel";
@ canvasDiv.className += " sel";
@ }else if( selRow==p ){
@ selRow = null;
@ this.className = this.className.replace(" sel", "");
@ canvasDiv.className = canvasDiv.className.replace(" sel", "");
@ }else{
if( fileDiff ){
@ location.href="%R/fdiff?v1="+selRow.h+"&v2="+p.h+"&sbs=1";
}else{
if( db_get_boolean("show-version-diffs", 0)==0 ){
@ location.href="%R/vdiff?from="+selRow.h+"&to="+p.h+"&sbs=0";
}else{
@ location.href="%R/vdiff?from="+selRow.h+"&to="+p.h+"&sbs=1";
}
}
@ }
@ }
@ var lastRow = gebi("m"+rowinfo[rowinfo.length-1].id);
@ var lastY = 0;
@ function checkHeight(){
@ var h = absoluteY(lastRow);
@ if( h!=lastY ){
@ renderGraph();
@ lastY = h;
@ }
@ setTimeout(checkHeight, 1000);
@ }
@ initGraph();
@ checkHeight();
@ }())</script>
}
}
/*
** Create a temporary table suitable for storing timeline data.
*/
static void timeline_temp_table(void){
|
| ︙ | ︙ | |||
1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 | ** from=UUID Path from... ** to=UUID ... to this ** shortest ... show only the shortest path ** uf=FUUID Show only check-ins that use given file version ** brbg Background color from branch name ** ubg Background color from user ** namechng Show only check-ins that filename changes ** ym=YYYY-MM Shown only events for the given year/month. ** datefmt=N Override the date format ** ** p= and d= can appear individually or together. If either p= or d= ** appear, then u=, y=, a=, and b= are ignored. ** ** If both a= and b= appear then both upper and lower bounds are honored. | > | 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 | ** from=UUID Path from... ** to=UUID ... to this ** shortest ... show only the shortest path ** uf=FUUID Show only check-ins that use given file version ** brbg Background color from branch name ** ubg Background color from user ** namechng Show only check-ins that filename changes ** forks Show only forks and their children ** ym=YYYY-MM Shown only events for the given year/month. ** datefmt=N Override the date format ** ** p= and d= can appear individually or together. If either p= or d= ** appear, then u=, y=, a=, and b= are ignored. ** ** If both a= and b= appear then both upper and lower bounds are honored. |
| ︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 |
const char *zBrName = P("r"); /* Show events related to this tag */
const char *zSearch = P("s"); /* Search string */
const char *zUses = P("uf"); /* Only show check-ins hold this file */
const char *zYearMonth = P("ym"); /* Show check-ins for the given YYYY-MM */
const char *zYearWeek = P("yw"); /* Check-ins for YYYY-WW (week-of-year) */
int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
int renameOnly = P("namechng")!=0; /* Show only check-ins that rename files */
int tagid; /* Tag ID */
int tmFlags = 0; /* Timeline flags */
const char *zThisTag = 0; /* Suppress links to this tag */
const char *zThisUser = 0; /* Suppress links to this user */
HQuery url; /* URL for various branch links */
int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
| > | 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 |
const char *zBrName = P("r"); /* Show events related to this tag */
const char *zSearch = P("s"); /* Search string */
const char *zUses = P("uf"); /* Only show check-ins hold this file */
const char *zYearMonth = P("ym"); /* Show check-ins for the given YYYY-MM */
const char *zYearWeek = P("yw"); /* Check-ins for YYYY-WW (week-of-year) */
int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
int renameOnly = P("namechng")!=0; /* Show only check-ins that rename files */
int forkOnly = PB("forks"); /* Show only forks and their children */
int tagid; /* Tag ID */
int tmFlags = 0; /* Timeline flags */
const char *zThisTag = 0; /* Suppress links to this tag */
const char *zThisUser = 0; /* Suppress links to this user */
HQuery url; /* URL for various branch links */
int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
|
| ︙ | ︙ | |||
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 |
if( renameOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO rnfile"
" SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
);
disableY = 1;
}
style_header("Timeline");
login_anonymous_available();
timeline_temp_table();
blob_zero(&sql);
blob_zero(&desc);
| > > > > > > > > > > > > > > > > > > > > | 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 |
if( renameOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO rnfile"
" SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
);
disableY = 1;
}
if( forkOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfork(rid INTEGER PRIMARY KEY);\n"
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT pid FROM plink\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" GROUP BY pid"
" HAVING count(*)>1;\n"
"INSERT OR IGNORE INTO rnfork(rid)"
" SELECT cid FROM plink\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" AND pid IN rnfork;",
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
);
tmFlags |= TIMELINE_UNHIDE;
zType = "ci";
disableY = 1;
}
style_header("Timeline");
login_anonymous_available();
timeline_temp_table();
blob_zero(&sql);
blob_zero(&desc);
|
| ︙ | ︙ | |||
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 |
char *zDate;
if( zUses ){
blob_append_sql(&sql, " AND event.objid IN usesfile ");
}
if( renameOnly ){
blob_append_sql(&sql, " AND event.objid IN rnfile ");
}
if( zYearMonth ){
blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
zYearMonth);
}
else if( zYearWeek ){
blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
zYearWeek);
| > > > | 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 |
char *zDate;
if( zUses ){
blob_append_sql(&sql, " AND event.objid IN usesfile ");
}
if( renameOnly ){
blob_append_sql(&sql, " AND event.objid IN rnfile ");
}
if( forkOnly ){
blob_append_sql(&sql, " AND event.objid IN rnfork ");
}
if( zYearMonth ){
blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
zYearMonth);
}
else if( zYearWeek ){
blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
zYearWeek);
|
| ︙ | ︙ | |||
1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 |
href("%R/artifact/%!S",zUses), zUses);
tmFlags |= TIMELINE_DISJOINT;
}
if( renameOnly ){
blob_appendf(&desc, " that contain filename changes");
tmFlags |= TIMELINE_DISJOINT|TIMELINE_FRENAMES;
}
if( zUser ){
blob_appendf(&desc, " by user %h", zUser);
tmFlags |= TIMELINE_DISJOINT;
}
if( zTagName ){
blob_appendf(&desc, " tagged with \"%h\"", zTagName);
tmFlags |= TIMELINE_DISJOINT;
| > > > > | 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 |
href("%R/artifact/%!S",zUses), zUses);
tmFlags |= TIMELINE_DISJOINT;
}
if( renameOnly ){
blob_appendf(&desc, " that contain filename changes");
tmFlags |= TIMELINE_DISJOINT|TIMELINE_FRENAMES;
}
if( forkOnly ){
blob_appendf(&desc, " associated with forks");
tmFlags |= TIMELINE_DISJOINT;
}
if( zUser ){
blob_appendf(&desc, " by user %h", zUser);
tmFlags |= TIMELINE_DISJOINT;
}
if( zTagName ){
blob_appendf(&desc, " tagged with \"%h\"", zTagName);
tmFlags |= TIMELINE_DISJOINT;
|
| ︙ | ︙ | |||
1786 1787 1788 1789 1790 1791 1792 |
/* record another X lines */
nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags);
fossil_free(zFree);
if(verboseFlag){
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
| | | 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 |
/* record another X lines */
nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags);
fossil_free(zFree);
if(verboseFlag){
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
"SELECT (pid<=0) AS isnew,"
" (fid==0) AS isdel,"
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
" (SELECT uuid FROM blob WHERE rid=fid),"
" (SELECT uuid FROM blob WHERE rid=pid)"
" FROM mlink"
" WHERE mid=:mid AND pid!=fid"
" ORDER BY 3 /*sort*/"
|
| ︙ | ︙ | |||
2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 |
}
}
db_finalize(&q);
}
/*
** WEBPAGE: test_timewarps
*/
void test_timewarp_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read || !g.perm.Hyperlink ){
login_needed(g.anon.Read && g.anon.Hyperlink);
| > > > > > | 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 |
}
}
db_finalize(&q);
}
/*
** WEBPAGE: test_timewarps
**
** Show all check-ins that are "timewarps". A timewarp is a
** check-in that occurs before its parent, according to the
** timestamp information on the check-in. This can only actually
** happen, of course, if a users system clock is set incorrectly.
*/
void test_timewarp_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read || !g.perm.Hyperlink ){
login_needed(g.anon.Read && g.anon.Hyperlink);
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
439 440 441 442 443 444 445 | @ </ul></font> } /* ** WEBPAGE: tktview ** URL: tktview?name=UUID ** | | | 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
@ </ul></font>
}
/*
** WEBPAGE: tktview
** URL: tktview?name=UUID
**
** View a ticket identified by the name= query parameter.
*/
void tktview_page(void){
const char *zScript;
char *zFullName;
const char *zUuid = PD("name","");
login_check_credentials();
|
| ︙ | ︙ |
Changes to src/tktsetup.c.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 | ** setup screens. */ #include "config.h" #include "tktsetup.h" #include <assert.h> /* | < > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
** setup screens.
*/
#include "config.h"
#include "tktsetup.h"
#include <assert.h>
/*
** WEBPAGE: tktsetup
** Main sub-menu for configuring the ticketing system.
*/
void tktsetup_page(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ | |||
165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
@ %h(zDfltValue)
@ </pre></blockquote>
style_footer();
}
/*
** WEBPAGE: tktsetup_tab
*/
void tktsetup_tab_page(void){
static const char zDesc[] =
@ Enter a valid CREATE TABLE statement for the "ticket" table. The
@ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime"
@ with an unique index on "tkt_uuid" and "tkt_mtime".
;
| > > | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
@ %h(zDfltValue)
@ </pre></blockquote>
style_footer();
}
/*
** WEBPAGE: tktsetup_tab
** Administrative page for defining the "ticket" table used
** to hold ticket information.
*/
void tktsetup_tab_page(void){
static const char zDesc[] =
@ Enter a valid CREATE TABLE statement for the "ticket" table. The
@ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime"
@ with an unique index on "tkt_uuid" and "tkt_mtime".
;
|
| ︙ | ︙ | |||
241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
*/
const char *ticket_common_code(void){
return db_get("ticket-common", (char*)zDefaultTicketCommon);
}
/*
** WEBPAGE: tktsetup_com
*/
void tktsetup_com_page(void){
static const char zDesc[] =
@ Enter TH1 script that initializes variables prior to generating
@ any of the ticket view, edit, or creation pages.
;
tktsetup_generic(
| > > | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
*/
const char *ticket_common_code(void){
return db_get("ticket-common", (char*)zDefaultTicketCommon);
}
/*
** WEBPAGE: tktsetup_com
** Administrative page used to define TH1 script that is
** common to all ticket screens.
*/
void tktsetup_com_page(void){
static const char zDesc[] =
@ Enter TH1 script that initializes variables prior to generating
@ any of the ticket view, edit, or creation pages.
;
tktsetup_generic(
|
| ︙ | ︙ | |||
271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
*/
const char *ticket_change_code(void){
return db_get("ticket-change", (char*)zDefaultTicketChange);
}
/*
** WEBPAGE: tktsetup_change
*/
void tktsetup_change_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs after processing the ticket editing
@ and creation pages.
;
tktsetup_generic(
| > > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
*/
const char *ticket_change_code(void){
return db_get("ticket-change", (char*)zDefaultTicketChange);
}
/*
** WEBPAGE: tktsetup_change
** Adminstrative screen used to view or edit the TH1 script
** that shows ticket changes.
*/
void tktsetup_change_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs after processing the ticket editing
@ and creation pages.
;
tktsetup_generic(
|
| ︙ | ︙ | |||
414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
*/
const char *ticket_newpage_code(void){
return db_get("ticket-newpage", (char*)zDefaultNew);
}
/*
** WEBPAGE: tktsetup_newpage
*/
void tktsetup_newpage_page(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "new ticket"
@ page
;
tktsetup_generic(
| > > | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
*/
const char *ticket_newpage_code(void){
return db_get("ticket-newpage", (char*)zDefaultNew);
}
/*
** WEBPAGE: tktsetup_newpage
** Administrative page used to view or edit the TH1 script used
** to enter new tickets.
*/
void tktsetup_newpage_page(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "new ticket"
@ page
;
tktsetup_generic(
|
| ︙ | ︙ | |||
553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
*/
const char *ticket_viewpage_code(void){
return db_get("ticket-viewpage", (char*)zDefaultView);
}
/*
** WEBPAGE: tktsetup_viewpage
*/
void tktsetup_viewpage_page(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "view ticket" page
;
tktsetup_generic(
"HTML For Viewing Tickets",
| > > | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
*/
const char *ticket_viewpage_code(void){
return db_get("ticket-viewpage", (char*)zDefaultView);
}
/*
** WEBPAGE: tktsetup_viewpage
** Administrative page used to view or edit the TH1 script that
** displays individual tickets.
*/
void tktsetup_viewpage_page(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "view ticket" page
;
tktsetup_generic(
"HTML For Viewing Tickets",
|
| ︙ | ︙ | |||
692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
*/
const char *ticket_editpage_code(void){
return db_get("ticket-editpage", (char*)zDefaultEdit);
}
/*
** WEBPAGE: tktsetup_editpage
*/
void tktsetup_editpage_page(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "edit ticket" page
;
tktsetup_generic(
"HTML For Editing Tickets",
| > > | 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 |
*/
const char *ticket_editpage_code(void){
return db_get("ticket-editpage", (char*)zDefaultEdit);
}
/*
** WEBPAGE: tktsetup_editpage
** Administrative page for viewing or editing the TH1 script that
** drives the ticket editing page.
*/
void tktsetup_editpage_page(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "edit ticket" page
;
tktsetup_generic(
"HTML For Editing Tickets",
|
| ︙ | ︙ | |||
746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
*/
const char *ticket_reportlist_code(void){
return db_get("ticket-reportlist", (char*)zDefaultReportList);
}
/*
** WEBPAGE: tktsetup_reportlist
*/
void tktsetup_reportlist(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "report list" page
;
tktsetup_generic(
"HTML For Report List",
| > > | 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 |
*/
const char *ticket_reportlist_code(void){
return db_get("ticket-reportlist", (char*)zDefaultReportList);
}
/*
** WEBPAGE: tktsetup_reportlist
** Administrative page used to view or edit the TH1 script that
** defines the "report list" page.
*/
void tktsetup_reportlist(void){
static const char zDesc[] =
@ Enter HTML with embedded TH1 script that will render the "report list" page
;
tktsetup_generic(
"HTML For Report List",
|
| ︙ | ︙ | |||
793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
*/
char *ticket_report_template(void){
return db_get("ticket-report-template", zDefaultReport);
}
/*
** WEBPAGE: tktsetup_rpttplt
*/
void tktsetup_rpttplt_page(void){
static const char zDesc[] =
@ Enter the default ticket report format template. This is the
@ template report format that initially appears when creating a
@ new ticket summary report.
;
| > > > | 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 |
*/
char *ticket_report_template(void){
return db_get("ticket-report-template", zDefaultReport);
}
/*
** WEBPAGE: tktsetup_rpttplt
**
** Administrative page used to view or edit the ticket report
** template.
*/
void tktsetup_rpttplt_page(void){
static const char zDesc[] =
@ Enter the default ticket report format template. This is the
@ template report format that initially appears when creating a
@ new ticket summary report.
;
|
| ︙ | ︙ | |||
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 |
*/
const char *ticket_key_template(void){
return db_get("ticket-key-template", (char*)zDefaultKey);
}
/*
** WEBPAGE: tktsetup_keytplt
*/
void tktsetup_keytplt_page(void){
static const char zDesc[] =
@ Enter the default ticket report color-key template. This is the
@ the color-key that initially appears when creating a
@ new ticket summary report.
;
tktsetup_generic(
"Default Report Color-Key Template",
"ticket-key-template",
zDefaultKey,
zDesc,
0,
0,
10
);
}
/*
** WEBPAGE: tktsetup_timeline
*/
void tktsetup_timeline_page(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
| > > > > > > | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 |
*/
const char *ticket_key_template(void){
return db_get("ticket-key-template", (char*)zDefaultKey);
}
/*
** WEBPAGE: tktsetup_keytplt
**
** Administrative page used to view or edit the Key template
** for tickets.
*/
void tktsetup_keytplt_page(void){
static const char zDesc[] =
@ Enter the default ticket report color-key template. This is the
@ the color-key that initially appears when creating a
@ new ticket summary report.
;
tktsetup_generic(
"Default Report Color-Key Template",
"ticket-key-template",
zDefaultKey,
zDesc,
0,
0,
10
);
}
/*
** WEBPAGE: tktsetup_timeline
**
** Administrative page used ot configure how tickets are
** rendered on timeline views.
*/
void tktsetup_timeline_page(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ |
Changes to src/update.c.
| ︙ | ︙ | |||
173 174 175 176 177 178 179 |
}else if( fossil_strcmp(g.argv[2], "latest")==0 ){
/* If VERSION is "latest", then use the same algorithm to find the
** target as if VERSION were omitted and the --latest flag is present.
*/
latestFlag = 1;
}else{
tid = name_to_typed_rid(g.argv[2],"ci");
| | | < < | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
}else if( fossil_strcmp(g.argv[2], "latest")==0 ){
/* If VERSION is "latest", then use the same algorithm to find the
** target as if VERSION were omitted and the --latest flag is present.
*/
latestFlag = 1;
}else{
tid = name_to_typed_rid(g.argv[2],"ci");
if( tid==0 || !is_a_version(tid) ){
fossil_fatal("no such check-in: %s", g.argv[2]);
}
}
}
/* If no VERSION is specified on the command-line, then look for a
** descendent of the current version. If there are multiple descendants,
** look for one from the same branch as the current version. If there
|
| ︙ | ︙ | |||
542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
case -2: zLabel = "backout merge"; break;
}
fossil_warning("uncommitted %s against %S.",
zLabel, db_column_text(&q, 0));
nMerge++;
}
db_finalize(&q);
if( nConflict ){
if( internalUpdate ){
internalConflictCnt = nConflict;
nConflict = 0;
}else{
fossil_warning("WARNING: %d merge conflicts", nConflict);
| > | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
case -2: zLabel = "backout merge"; break;
}
fossil_warning("uncommitted %s against %S.",
zLabel, db_column_text(&q, 0));
nMerge++;
}
db_finalize(&q);
leaf_ambiguity_warning(tid, tid);
if( nConflict ){
if( internalUpdate ){
internalConflictCnt = nConflict;
nConflict = 0;
}else{
fossil_warning("WARNING: %d merge conflicts", nConflict);
|
| ︙ | ︙ | |||
649 650 651 652 653 654 655 | int historical_version_of_file( const char *revision, /* The check-in containing the file */ const char *file, /* Full treename of the file */ Blob *content, /* Put the content here */ int *pIsLink, /* Set to true if file is link. */ int *pIsExe, /* Set to true if file is executable */ int *pIsBin, /* Set to true if file is binary */ | | | 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
int historical_version_of_file(
const char *revision, /* The check-in containing the file */
const char *file, /* Full treename of the file */
Blob *content, /* Put the content here */
int *pIsLink, /* Set to true if file is link. */
int *pIsExe, /* Set to true if file is executable */
int *pIsBin, /* Set to true if file is binary */
int errCode /* Error code if file not found. Panic if <= 0. */
){
Manifest *pManifest;
ManifestFile *pFile;
int rid=0;
if( revision ){
rid = name_to_typed_rid(revision,"ci");
|
| ︙ | ︙ |
Changes to src/url.c.
| ︙ | ︙ | |||
452 453 454 455 456 457 458 |
/*
** Resets the given URL object, deallocating any memory
** it uses.
*/
void url_reset(HQuery *p){
blob_reset(&p->url);
| | | | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 |
/*
** Resets the given URL object, deallocating any memory
** it uses.
*/
void url_reset(HQuery *p){
blob_reset(&p->url);
fossil_free((void *)p->azName);
fossil_free((void *)p->azValue);
url_initialize(p, p->zBase);
}
/*
** Add a fixed parameter to an HQuery. Or remove the parameters if zValue==0.
*/
void url_add_parameter(HQuery *p, const char *zName, const char *zValue){
|
| ︙ | ︙ | |||
478 479 480 481 482 483 484 |
return;
}
}
assert( i==p->nParam );
if( zValue==0 ) return;
if( i>=p->nAlloc ){
p->nAlloc = p->nAlloc*2 + 10;
| | > | > | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
return;
}
}
assert( i==p->nParam );
if( zValue==0 ) return;
if( i>=p->nAlloc ){
p->nAlloc = p->nAlloc*2 + 10;
p->azName = fossil_realloc((void *)p->azName,
sizeof(p->azName[0])*p->nAlloc);
p->azValue = fossil_realloc((void *)p->azValue,
sizeof(p->azValue[0])*p->nAlloc);
}
p->azName[i] = zName;
p->azValue[i] = zValue;
p->nParam++;
}
/*
|
| ︙ | ︙ |
Changes to src/user.c.
| ︙ | ︙ | |||
408 409 410 411 412 413 414 |
" WHERE length(pw)>0 AND length(pw)!=40"
);
}
/*
** WEBPAGE: access_log
**
| > > > > > | | | | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
" WHERE length(pw)>0 AND length(pw)!=40"
);
}
/*
** WEBPAGE: access_log
**
** Show login attempts, including timestamp and IP address.
** Requires Admin privileges.
**
** Query parameters:
**
** y=N 1: success only. 2: failure only. 3: both (default: 3)
** n=N Number of entries to show (default: 200)
** o=N Skip this many entries (default: 0)
*/
void access_log_page(void){
int y = atoi(PD("y","3"));
int n = atoi(PD("n","200"));
int skip = atoi(PD("o","0"));
Blob sql;
Stmt q;
int cnt = 0;
int rc;
login_check_credentials();
|
| ︙ | ︙ |
Changes to src/utf8.c.
| ︙ | ︙ | |||
321 322 323 324 325 326 327 |
/* stdout/stderr is not a console. */
return -1;
}
/* If blob to be written to the Windows console is not
* UTF-8, convert it to UTF-8 first.
*/
| | | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
/* stdout/stderr is not a console. */
return -1;
}
/* If blob to be written to the Windows console is not
* UTF-8, convert it to UTF-8 first.
*/
blob_init(&blob, zUtf8, nByte);
blob_to_utf8_no_bom(&blob, 1);
nChar = MultiByteToWideChar(CP_UTF8, 0, blob_buffer(&blob),
blob_size(&blob), NULL, 0);
zUnicode = malloc( (nChar + 1) *sizeof(zUnicode[0]) );
if( zUnicode==0 ){
return 0;
}
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
544 545 546 547 548 549 550 | ** Returns the total number of files found. */ int vfile_dir_scan( Blob *pPath, /* Base directory to be scanned */ int nPrefix, /* Number of bytes in base directory name */ unsigned scanFlags, /* Zero or more SCAN_xxx flags */ Glob *pIgnore1, /* Do not add directories that match this GLOB */ | | < | < | 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 |
** Returns the total number of files found.
*/
int vfile_dir_scan(
Blob *pPath, /* Base directory to be scanned */
int nPrefix, /* Number of bytes in base directory name */
unsigned scanFlags, /* Zero or more SCAN_xxx flags */
Glob *pIgnore1, /* Do not add directories that match this GLOB */
Glob *pIgnore2 /* Omit directories matching this GLOB too */
){
int result = 0;
DIR *d;
int origSize;
struct dirent *pEntry;
int skipAll = 0;
static Stmt ins;
static Stmt upd;
static int depth = 0;
void *zNative;
origSize = blob_size(pPath);
if( pIgnore1 || pIgnore2 ){
blob_appendf(pPath, "/");
if( glob_match(pIgnore1, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1;
if( glob_match(pIgnore2, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1;
blob_resize(pPath, origSize);
}
if( skipAll ) return result;
if( depth==0 ){
db_multi_exec("DROP TABLE IF EXISTS dscan_temp;"
"CREATE TEMP TABLE dscan_temp("
|
| ︙ | ︙ | |||
602 603 604 605 606 607 608 |
if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
}
zOrigPath = mprintf("%s", blob_str(pPath));
zUtf8 = fossil_filename_to_utf8(pEntry->d_name);
blob_appendf(pPath, "/%s", zUtf8);
zPath = blob_str(pPath);
if( glob_match(pIgnore1, &zPath[nPrefix+1]) ||
| | < | | 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 |
if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
}
zOrigPath = mprintf("%s", blob_str(pPath));
zUtf8 = fossil_filename_to_utf8(pEntry->d_name);
blob_appendf(pPath, "/%s", zUtf8);
zPath = blob_str(pPath);
if( glob_match(pIgnore1, &zPath[nPrefix+1]) ||
glob_match(pIgnore2, &zPath[nPrefix+1]) ){
/* do nothing */
#ifdef _DIRENT_HAVE_D_TYPE
}else if( (pEntry->d_type==DT_UNKNOWN || pEntry->d_type==DT_LNK)
? (file_wd_isdir(zPath)==1) : (pEntry->d_type==DT_DIR) ){
#else
}else if( file_wd_isdir(zPath)==1 ){
#endif
if( (scanFlags & SCAN_NESTED) || !vfile_top_of_checkout(zPath) ){
char *zSavePath = mprintf("%s", zPath);
int count = vfile_dir_scan(pPath, nPrefix, scanFlags, pIgnore1,
pIgnore2);
db_bind_text(&ins, ":file", &zSavePath[nPrefix+1]);
db_bind_int(&ins, ":count", count);
db_step(&ins);
db_reset(&ins);
fossil_free(zSavePath);
result += count; /* found X normal files? */
}
|
| ︙ | ︙ | |||
914 915 916 917 918 919 920 921 922 923 924 925 926 927 |
}
manifest_destroy(pManifest);
md5sum_finish(pOut);
}
/*
** COMMAND: test-agg-cksum
*/
void test_agg_cksum_cmd(void){
int vid;
Blob hash, hash2;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
vfile_aggregate_checksum_disk(vid, &hash);
| > > > > > | 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 |
}
manifest_destroy(pManifest);
md5sum_finish(pOut);
}
/*
** COMMAND: test-agg-cksum
**
** Display the aggregate checksum for content computed in several
** different ways. The aggregate checksum is used during "fossil commit"
** to double-check that the information about to be committed to the
** repository exactly matches the information currently in the check-out.
*/
void test_agg_cksum_cmd(void){
int vid;
Blob hash, hash2;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
vfile_aggregate_checksum_disk(vid, &hash);
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
return 0;
}
/*
** WEBPAGE: home
** WEBPAGE: index
** WEBPAGE: not_found
*/
void home_page(void){
char *zPageName = db_get("project-name",0);
char *zIndexPage = db_get("index-page",0);
login_check_credentials();
if( zIndexPage ){
const char *zPathInfo = P("PATH_INFO");
| > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
return 0;
}
/*
** WEBPAGE: home
** WEBPAGE: index
** WEBPAGE: not_found
**
** The /home, /index, and /not_found pages all redirect to the homepage
** configured by the administrator.
*/
void home_page(void){
char *zPageName = db_get("project-name",0);
char *zIndexPage = db_get("index-page",0);
login_check_credentials();
if( zIndexPage ){
const char *zPathInfo = P("PATH_INFO");
|
| ︙ | ︙ | |||
456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
}
return azStyles[1];
}
/*
** WEBPAGE: wikiedit
** URL: /wikiedit?name=PAGENAME
*/
void wikiedit_page(void){
char *zTag;
int rid = 0;
int isSandbox;
Blob wiki;
Manifest *pWiki = 0;
| > > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 |
}
return azStyles[1];
}
/*
** WEBPAGE: wikiedit
** URL: /wikiedit?name=PAGENAME
**
** Edit a wiki page.
*/
void wikiedit_page(void){
char *zTag;
int rid = 0;
int isSandbox;
Blob wiki;
Manifest *pWiki = 0;
|
| ︙ | ︙ | |||
702 703 704 705 706 707 708 709 710 711 712 713 714 715 |
}
fossil_free(zDate);
}
/*
** WEBPAGE: wikiappend
** URL: /wikiappend?name=PAGENAME&mimetype=MIMETYPE
*/
void wikiappend_page(void){
char *zTag;
int rid = 0;
int isSandbox;
const char *zPageName;
const char *zUser;
| > > | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
}
fossil_free(zDate);
}
/*
** WEBPAGE: wikiappend
** URL: /wikiappend?name=PAGENAME&mimetype=MIMETYPE
**
** Append text to the end of a wiki page.
*/
void wikiappend_page(void){
char *zTag;
int rid = 0;
int isSandbox;
const char *zPageName;
const char *zUser;
|
| ︙ | ︙ | |||
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 |
db_finalize(&q);
@ </ul>
style_footer();
}
/*
** WEBPAGE: wiki_rules
*/
void wikirules_page(void){
style_header("Wiki Formatting Rules");
@ <h2>Formatting Rule Summary</h2>
@ <ol>
@ <li>Blank lines are paragraph breaks</li>
@ <li>Bullets are "*" surrounded by two spaces at the beginning of the
| > > | 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 |
db_finalize(&q);
@ </ul>
style_footer();
}
/*
** WEBPAGE: wiki_rules
**
** Show the formatting rules for Fossil wiki.
*/
void wikirules_page(void){
style_header("Wiki Formatting Rules");
@ <h2>Formatting Rule Summary</h2>
@ <ol>
@ <li>Blank lines are paragraph breaks</li>
@ <li>Bullets are "*" surrounded by two spaces at the beginning of the
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 |
zIn += n;
}
if( iCur ) blob_append(pOut, "\n", 1);
}
/*
** COMMAND: test-html-tidy
*/
void test_html_tidy(void){
Blob in, out;
int i;
for(i=2; i<g.argc; i++){
blob_read_from_file(&in, g.argv[i]);
| > > > | 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 |
zIn += n;
}
if( iCur ) blob_append(pOut, "\n", 1);
}
/*
** COMMAND: test-html-tidy
**
** Run the htmlTidy() routine on the content of all files named on
** the command-line and write the results to standard output.
*/
void test_html_tidy(void){
Blob in, out;
int i;
for(i=2; i<g.argc; i++){
blob_read_from_file(&in, g.argv[i]);
|
| ︙ | ︙ | |||
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 |
zIn += n;
}
if( nNL==0 ) blob_append(pOut, "\n", 1);
}
/*
** COMMAND: test-html-to-text
*/
void test_html_to_text(void){
Blob in, out;
int i;
for(i=2; i<g.argc; i++){
blob_read_from_file(&in, g.argv[i]);
| > > > > > > > > > | 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 |
zIn += n;
}
if( nNL==0 ) blob_append(pOut, "\n", 1);
}
/*
** COMMAND: test-html-to-text
**
** Usage: %fossil test-html-to-text FILE ...
**
** Read all files named on the command-line. Convert the file
** content from HTML to text and write the results on standard
** output.
**
** This command is intended as a test and debug interface for
** the html_to_plaintext() routine.
*/
void test_html_to_text(void){
Blob in, out;
int i;
for(i=2; i<g.argc; i++){
blob_read_from_file(&in, g.argv[i]);
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 |
**
** Should only happen in response to a clone. This message tells
** the client what product to use for the new database.
*/
if( blob_eq(&xfer.aToken[0],"push")
&& xfer.nToken==3
&& (syncFlags & SYNC_CLONE)!=0
| < < < < | 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 |
**
** Should only happen in response to a clone. This message tells
** the client what product to use for the new database.
*/
if( blob_eq(&xfer.aToken[0],"push")
&& xfer.nToken==3
&& (syncFlags & SYNC_CLONE)!=0
&& blob_is_uuid(&xfer.aToken[2])
){
if( zPCode==0 ){
zPCode = mprintf("%b", &xfer.aToken[2]);
db_set("project-code", zPCode, 0);
}
if( cloneSeqno>0 ) blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
nCardSent++;
}else
|
| ︙ | ︙ | |||
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 |
transport_close(&g.url);
transport_global_shutdown(&g.url);
if( nErr && go==2 ){
db_multi_exec("DROP TABLE onremote");
manifest_crosslink_end(MC_PERMIT_HOOKS);
content_enable_dephantomize(1);
db_end_transaction(0);
}
return nErr;
}
| > > > > | 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 |
transport_close(&g.url);
transport_global_shutdown(&g.url);
if( nErr && go==2 ){
db_multi_exec("DROP TABLE onremote");
manifest_crosslink_end(MC_PERMIT_HOOKS);
content_enable_dephantomize(1);
db_end_transaction(0);
}
if( (syncFlags & SYNC_CLONE)==0 && g.rcvid && fossil_any_has_fork(g.rcvid) ){
fossil_warning("***** WARNING: a fork has occurred *****\n"
"use \"fossil leaves -multiple\" for more details.");
}
return nErr;
}
|
Changes to src/xfersetup.c.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 | ** setup screens. */ #include "config.h" #include "xfersetup.h" #include <assert.h> /* | < > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
** setup screens.
*/
#include "config.h"
#include "xfersetup.h"
#include <assert.h>
/*
** WEBPAGE: xfersetup
** Main sub-menu for configuring the transfer system.
*/
void xfersetup_page(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
|
| ︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
style_footer();
}
static const char *zDefaultXferCommon = 0;
/*
** WEBPAGE: xfersetup_com
*/
void xfersetup_com_page(void){
static const char zDesc[] =
@ Enter TH1 script that initializes variables prior to running
@ any of the transfer request scripts.
;
xfersetup_generic(
| > > | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
style_footer();
}
static const char *zDefaultXferCommon = 0;
/*
** WEBPAGE: xfersetup_com
** View or edit the TH1 script that runs prior to receiving a
** transfer.
*/
void xfersetup_com_page(void){
static const char zDesc[] =
@ Enter TH1 script that initializes variables prior to running
@ any of the transfer request scripts.
;
xfersetup_generic(
|
| ︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
);
}
static const char *zDefaultXferPush = 0;
/*
** WEBPAGE: xfersetup_push
*/
void xfersetup_push_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs after processing <strong>push</strong>
@ transfer requests.
;
xfersetup_generic(
| > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
);
}
static const char *zDefaultXferPush = 0;
/*
** WEBPAGE: xfersetup_push
** View or edit the TH1 script that runs after receiving a "push".
*/
void xfersetup_push_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs after processing <strong>push</strong>
@ transfer requests.
;
xfersetup_generic(
|
| ︙ | ︙ | |||
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
);
}
static const char *zDefaultXferCommit = 0;
/*
** WEBPAGE: xfersetup_commit
*/
void xfersetup_commit_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs when a commit is processed.
;
xfersetup_generic(
"Transfer Commit Script",
"xfer-commit-script",
zDefaultXferCommit,
zDesc,
0,
0,
30
);
}
static const char *zDefaultXferTicket = 0;
/*
** WEBPAGE: xfersetup_ticket
*/
void xfersetup_ticket_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs when a ticket change is processed.
;
xfersetup_generic(
"Transfer Ticket Script",
| > > > > | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
);
}
static const char *zDefaultXferCommit = 0;
/*
** WEBPAGE: xfersetup_commit
** View or edit the TH1 script that runs when a transfer commit
** is processed.
*/
void xfersetup_commit_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs when a commit is processed.
;
xfersetup_generic(
"Transfer Commit Script",
"xfer-commit-script",
zDefaultXferCommit,
zDesc,
0,
0,
30
);
}
static const char *zDefaultXferTicket = 0;
/*
** WEBPAGE: xfersetup_ticket
** View or edit the TH1 script that runs when a ticket change artifact
** is processed during a transfer.
*/
void xfersetup_ticket_page(void){
static const char zDesc[] =
@ Enter TH1 script that runs when a ticket change is processed.
;
xfersetup_generic(
"Transfer Ticket Script",
|
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
397 398 399 400 401 402 403 |
*/
void baseline_zip_cmd(void){
int rid;
Blob zip;
const char *zName;
zName = find_option("name", 0, 1);
db_find_and_open_repository(0, 0);
| | | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
*/
void baseline_zip_cmd(void){
int rid;
Blob zip;
const char *zName;
zName = find_option("name", 0, 1);
db_find_and_open_repository(0, 0);
/* We should be done with options.. */
verify_all_options();
if( g.argc!=4 ){
usage("VERSION OUTPUTFILE");
}
rid = name_to_typed_rid(g.argv[2],"ci");
|
| ︙ | ︙ |
Added test/contains-selector.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#
# Copyright (c) 2015 D. Richard Hipp
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the Simplified BSD License (also
# known as the "2-Clause License" or "FreeBSD License".)
#
# This program is distributed in the hope that it will be useful,
# but without any warranty; without even the implied warranty of
# merchantability or fitness for a particular purpose.
#
# Author contact information:
# drh@hwaci.com
# http://www.hwaci.com/drh/
#
############################################################################
#
# Test containsSelector() function in src/style.c
#
proc contains-selector {testId css selectorResultMap} {
set css [string trim $css]
set filename [file join $::tempPath compare-selector.css]
set fh [open $filename w]
puts -nonewline $fh $css
close $fh
foreach {selector found} $selectorResultMap {
set expected "$selector [expr {$found ? "found" : "not found"}]"
set result [fossil test-contains-selector $filename $selector]
test "contains-selector $testId $selector" {$result eq $expected}
}
file delete $filename
}
contains-selector 1 {
.a.b {}
.c .de {}
/* comment */
.c .d, .e /* comment */ {}
} {
.a 0
.b 0
.a.b 1
.c 0
.d 0
{.c.d} 0
{.c .d} 1
.e 1
}
|
Changes to test/release-checklist.wiki.
1 2 3 4 5 6 7 | <title>Release Checklist</title> This file describes the testing procedures for Fossil prior to an official release. <ol> <li><p> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <title>Release Checklist</title> This file describes the testing procedures for Fossil prior to an official release. <ol> <li><p> From a private directory (not the source tree) run "<b>tclsh $SRC/test/tester.tcl $FOSSIL</b>" where $FOSSIL is the name of the executable under test and $SRC is the source tree. Verify that there are no errors. <li><p> Click on each of the links in in the [./graph-test-1.wiki] document and verify that all graphs are |
| ︙ | ︙ |
Changes to test/th1.test.
| ︙ | ︙ | |||
40 41 42 43 44 45 46 |
fossil test-th-eval --open-config "setting -strict -- abc"
test th1-setting-4 {$RESULT eq {TH_ERROR: no value for setting "abc"}}
###############################################################################
fossil test-th-eval --open-config "setting autosync"
| | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
fossil test-th-eval --open-config "setting -strict -- abc"
test th1-setting-4 {$RESULT eq {TH_ERROR: no value for setting "abc"}}
###############################################################################
fossil test-th-eval --open-config "setting autosync"
test th1-setting-5 {$RESULT eq 0 || $RESULT eq 1 || $RESULT eq "on"}
###############################################################################
fossil test-th-eval --open-config "setting -strict autosync"
test th1-setting-6 {$RESULT eq 0 || $RESULT eq 1 || $RESULT eq "on"}
###############################################################################
fossil test-th-eval --open-config "setting --"
test th1-setting-7 {$RESULT eq \
{TH_ERROR: wrong # args: should be "setting ?-strict? ?--? name"}}
|
| ︙ | ︙ | |||
508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
###############################################################################
fossil test-th-eval "expr (((1)*2)*2)"
test th1-expr-41 {$RESULT eq {4}}
###############################################################################
fossil test-th-eval "checkout 1"; # NOTE: Assumes running "in tree".
test th1-checkout-1 {[string length $RESULT] > 0}
###############################################################################
fossil test-th-eval "checkout"; # NOTE: Assumes running "in tree".
test th1-checkout-2 {[string length $RESULT] > 0}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
###############################################################################
fossil test-th-eval "expr (((1)*2)*2)"
test th1-expr-41 {$RESULT eq {4}}
###############################################################################
fossil test-th-eval "expr +"
test th1-expr-42 {$RESULT eq {TH_ERROR: syntax error in expression: "+"}}
###############################################################################
fossil test-th-eval "expr -"
test th1-expr-43 {$RESULT eq {TH_ERROR: syntax error in expression: "-"}}
###############################################################################
fossil test-th-eval "expr ++"
test th1-expr-44 {$RESULT eq {TH_ERROR: syntax error in expression: "++"}}
###############################################################################
fossil test-th-eval "expr --"
test th1-expr-45 {$RESULT eq {TH_ERROR: syntax error in expression: "--"}}
###############################################################################
fossil test-th-eval "lindex list +"
test th1-expr-46 {$RESULT eq {TH_ERROR: expected integer, got: "+"}}
###############################################################################
fossil test-th-eval "lindex list -"
test th1-expr-47 {$RESULT eq {TH_ERROR: expected integer, got: "-"}}
###############################################################################
fossil test-th-eval "lindex list +0x"
test th1-expr-48 {$RESULT eq {TH_ERROR: expected integer, got: "+0x"}}
###############################################################################
fossil test-th-eval "lindex list -0x"
test th1-expr-49 {$RESULT eq {TH_ERROR: expected integer, got: "-0x"}}
###############################################################################
fossil test-th-eval "checkout 1"; # NOTE: Assumes running "in tree".
test th1-checkout-1 {[string length $RESULT] > 0}
###############################################################################
fossil test-th-eval "checkout"; # NOTE: Assumes running "in tree".
test th1-checkout-2 {[string length $RESULT] > 0}
|
| ︙ | ︙ | |||
806 807 808 809 810 811 812 |
fossil test-th-eval "reinitialize; globalState configuration"
test th1-reinitialize-1 {$RESULT eq ""}
###############################################################################
fossil test-th-eval "reinitialize 1; globalState configuration"
test th1-reinitialize-2 {$RESULT ne ""}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
fossil test-th-eval "reinitialize; globalState configuration"
test th1-reinitialize-1 {$RESULT eq ""}
###############################################################################
fossil test-th-eval "reinitialize 1; globalState configuration"
test th1-reinitialize-2 {$RESULT ne ""}
###############################################################################
#
# NOTE: This test may fail if the command names do not always come
# out in a deterministic order from TH1.
#
fossil test-th-eval "info commands"
test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
enable_output uplevel http expr utime styleFooter catch if tclReady\
searchable reinitialize combobox lindex query html anoncap randhex\
llength for set break regexp styleHeader puts return checkout decorate\
artifact trace wiki proc hascap globalState continue getParameter\
hasfeature setting breakpoint upvar render repository string unset\
setParameter list error info rename anycap httpize}}
###############################################################################
fossil test-th-eval "info vars"
test th1-info-vars-1 {$RESULT eq ""}
###############################################################################
fossil test-th-eval "set x 1; info vars"
test th1-info-vars-2 {$RESULT eq "x"}
###############################################################################
fossil test-th-eval "set x 1; unset x; info vars"
test th1-info-vars-3 {$RESULT eq ""}
###############################################################################
fossil test-th-eval "proc foo {} {set x 1; info vars}; foo"
test th1-info-vars-4 {$RESULT eq "x"}
###############################################################################
fossil test-th-eval "set y 1; proc foo {} {set x 1; uplevel 1 {info vars}}; foo"
test th1-info-vars-5 {$RESULT eq "y"}
|
Changes to win/Makefile.PellesCGMake.
| ︙ | ︙ | |||
81 82 83 84 85 86 87 | UTILS_OBJ=$(UTILS:.exe=.obj) UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) # define the SQLite files, which need special flags on compile SQLITESRC=sqlite3.c ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | UTILS_OBJ=$(UTILS:.exe=.obj) UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR)$(uf:.exe=.c)) # define the SQLite files, which need special flags on compile SQLITESRC=sqlite3.c ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR)$(sf)) SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj)) SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_WIN32_NO_ANSI # define the SQLite shell files, which need special flags on compile SQLITESHELLSRC=shell.c ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR)$(sf)) SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj)) SQLITESHELLDEFINES=-Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 | | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O RC=$(DMDIR)\bin\rcc RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ APPNAME = $(OBJDIR)\fossil$(E) all: $(APPNAME) $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link cd $(OBJDIR) codecheck1$E $(SRC) $(DMDIR)\bin\link @link $(OBJDIR)\fossil.res: $B\win\fossil.rc $(RC) $(RCFLAGS) -o$@ $** $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ +echo fossil >> $@ +echo fossil >> $@ +echo $(LIBS) >> $@ +echo. >> $@ +echo fossil >> $@ translate$E: $(SRCDIR)\translate.c |
| ︙ | ︙ | |||
552 553 554 555 556 557 558 559 560 561 562 563 564 565 | +translate$E $** > $@ $(OBJDIR)\path$O : path_.c path.h $(TCC) -o$@ -c path_.c path_.c : $(SRCDIR)\path.c +translate$E $** > $@ $(OBJDIR)\pivot$O : pivot_.c pivot.h $(TCC) -o$@ -c pivot_.c pivot_.c : $(SRCDIR)\pivot.c +translate$E $** > $@ | > > > > > > | 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | +translate$E $** > $@ $(OBJDIR)\path$O : path_.c path.h $(TCC) -o$@ -c path_.c path_.c : $(SRCDIR)\path.c +translate$E $** > $@ $(OBJDIR)\piechart$O : piechart_.c piechart.h $(TCC) -o$@ -c piechart_.c piechart_.c : $(SRCDIR)\piechart.c +translate$E $** > $@ $(OBJDIR)\pivot$O : pivot_.c pivot.h $(TCC) -o$@ -c pivot_.c pivot_.c : $(SRCDIR)\pivot.c +translate$E $** > $@ |
| ︙ | ︙ | |||
830 831 832 833 834 835 836 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h | | | 836 837 838 839 840 841 842 843 844 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h @copy /Y nul: headers |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # # FOSSIL_ENABLE_SSL = 1 #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 #### Enable TH1 scripts in embedded documentation files # # FOSSIL_ENABLE_TH1_DOCS = 1 #### Enable hooks for commands and web pages via TH1 # | > > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # # FOSSIL_ENABLE_SSL = 1 #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 #### Enable legacy treatment of mv/rm (skip checkout files) # # FOSSIL_ENABLE_LEGACY_MV_RM = 1 #### Enable TH1 scripts in embedded documentation files # # FOSSIL_ENABLE_TH1_DOCS = 1 #### Enable hooks for commands and web pages via TH1 # |
| ︙ | ︙ | |||
249 250 251 252 253 254 255 256 257 258 259 260 261 262 | endif # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif # With TH1 embedded docs support ifdef FOSSIL_ENABLE_TH1_DOCS TCC += -DFOSSIL_ENABLE_TH1_DOCS=1 RCC += -DFOSSIL_ENABLE_TH1_DOCS=1 endif | > > > > > > | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | endif # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif # With legacy treatment of mv/rm ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 endif # With TH1 embedded docs support ifdef FOSSIL_ENABLE_TH1_DOCS TCC += -DFOSSIL_ENABLE_TH1_DOCS=1 RCC += -DFOSSIL_ENABLE_TH1_DOCS=1 endif |
| ︙ | ︙ | |||
435 436 437 438 439 440 441 442 443 444 445 446 447 448 | $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/path.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/publish.c \ $(SRCDIR)/purge.c \ $(SRCDIR)/rebuild.c \ | > | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/path.c \ $(SRCDIR)/piechart.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/publish.c \ $(SRCDIR)/purge.c \ $(SRCDIR)/rebuild.c \ |
| ︙ | ︙ | |||
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | $(SRCDIR)/winhttp.c \ $(SRCDIR)/wysiwyg.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../skins/black_and_white/css.txt \ $(SRCDIR)/../skins/black_and_white/footer.txt \ $(SRCDIR)/../skins/black_and_white/header.txt \ $(SRCDIR)/../skins/blitz/css.txt \ $(SRCDIR)/../skins/blitz/footer.txt \ $(SRCDIR)/../skins/blitz/header.txt \ $(SRCDIR)/../skins/blitz/ticket.txt \ $(SRCDIR)/../skins/blitz_no_logo/css.txt \ $(SRCDIR)/../skins/blitz_no_logo/footer.txt \ $(SRCDIR)/../skins/blitz_no_logo/header.txt \ $(SRCDIR)/../skins/blitz_no_logo/ticket.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ $(SRCDIR)/../skins/enhanced1/header.txt \ $(SRCDIR)/../skins/khaki/css.txt \ $(SRCDIR)/../skins/khaki/footer.txt \ $(SRCDIR)/../skins/khaki/header.txt \ $(SRCDIR)/../skins/original/css.txt \ $(SRCDIR)/../skins/original/footer.txt \ $(SRCDIR)/../skins/original/header.txt \ $(SRCDIR)/../skins/plain_gray/css.txt \ $(SRCDIR)/../skins/plain_gray/footer.txt \ $(SRCDIR)/../skins/plain_gray/header.txt \ $(SRCDIR)/../skins/rounded1/css.txt \ $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ | > > > > > > > > > > > > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | $(SRCDIR)/winhttp.c \ $(SRCDIR)/wysiwyg.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../skins/aht/details.txt \ $(SRCDIR)/../skins/black_and_white/css.txt \ $(SRCDIR)/../skins/black_and_white/details.txt \ $(SRCDIR)/../skins/black_and_white/footer.txt \ $(SRCDIR)/../skins/black_and_white/header.txt \ $(SRCDIR)/../skins/blitz/css.txt \ $(SRCDIR)/../skins/blitz/details.txt \ $(SRCDIR)/../skins/blitz/footer.txt \ $(SRCDIR)/../skins/blitz/header.txt \ $(SRCDIR)/../skins/blitz/ticket.txt \ $(SRCDIR)/../skins/blitz_no_logo/css.txt \ $(SRCDIR)/../skins/blitz_no_logo/details.txt \ $(SRCDIR)/../skins/blitz_no_logo/footer.txt \ $(SRCDIR)/../skins/blitz_no_logo/header.txt \ $(SRCDIR)/../skins/blitz_no_logo/ticket.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ $(SRCDIR)/../skins/enhanced1/header.txt \ $(SRCDIR)/../skins/khaki/css.txt \ $(SRCDIR)/../skins/khaki/details.txt \ $(SRCDIR)/../skins/khaki/footer.txt \ $(SRCDIR)/../skins/khaki/header.txt \ $(SRCDIR)/../skins/original/css.txt \ $(SRCDIR)/../skins/original/details.txt \ $(SRCDIR)/../skins/original/footer.txt \ $(SRCDIR)/../skins/original/header.txt \ $(SRCDIR)/../skins/plain_gray/css.txt \ $(SRCDIR)/../skins/plain_gray/details.txt \ $(SRCDIR)/../skins/plain_gray/footer.txt \ $(SRCDIR)/../skins/plain_gray/header.txt \ $(SRCDIR)/../skins/rounded1/css.txt \ $(SRCDIR)/../skins/rounded1/details.txt \ $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ |
| ︙ | ︙ | |||
594 595 596 597 598 599 600 601 602 603 604 605 606 607 | $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/path_.c \ $(OBJDIR)/pivot_.c \ $(OBJDIR)/popen_.c \ $(OBJDIR)/pqueue_.c \ $(OBJDIR)/printf_.c \ $(OBJDIR)/publish_.c \ $(OBJDIR)/purge_.c \ $(OBJDIR)/rebuild_.c \ | > | 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/path_.c \ $(OBJDIR)/piechart_.c \ $(OBJDIR)/pivot_.c \ $(OBJDIR)/popen_.c \ $(OBJDIR)/pqueue_.c \ $(OBJDIR)/printf_.c \ $(OBJDIR)/publish_.c \ $(OBJDIR)/purge_.c \ $(OBJDIR)/rebuild_.c \ |
| ︙ | ︙ | |||
714 715 716 717 718 719 720 721 722 723 724 725 726 727 | $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/path.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/publish.o \ $(OBJDIR)/purge.o \ $(OBJDIR)/rebuild.o \ | > | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/path.o \ $(OBJDIR)/piechart.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/publish.o \ $(OBJDIR)/purge.o \ $(OBJDIR)/rebuild.o \ |
| ︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ | > | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 | $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ $(OBJDIR)/piechart_.c:$(OBJDIR)/piechart.h \ $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| ︙ | ︙ | |||
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 | $(OBJDIR)/path_.c: $(SRCDIR)/path.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/path.c >$@ $(OBJDIR)/path.o: $(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c $(OBJDIR)/path.h: $(OBJDIR)/headers $(OBJDIR)/pivot_.c: $(SRCDIR)/pivot.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/pivot.c >$@ $(OBJDIR)/pivot.o: $(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c | > > > > > > > > | 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 | $(OBJDIR)/path_.c: $(SRCDIR)/path.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/path.c >$@ $(OBJDIR)/path.o: $(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c $(OBJDIR)/path.h: $(OBJDIR)/headers $(OBJDIR)/piechart_.c: $(SRCDIR)/piechart.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/piechart.c >$@ $(OBJDIR)/piechart.o: $(OBJDIR)/piechart_.c $(OBJDIR)/piechart.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/piechart.o -c $(OBJDIR)/piechart_.c $(OBJDIR)/piechart.h: $(OBJDIR)/headers $(OBJDIR)/pivot_.c: $(SRCDIR)/pivot.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/pivot.c >$@ $(OBJDIR)/pivot.o: $(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c |
| ︙ | ︙ | |||
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_WIN32_NO_ANSI \
-D_HAVE__MINGW_H \
-DSQLITE_USE_MALLOC_H \
-DSQLITE_USE_MSIZE
SHELL_OPTIONS = -Dmain=sqlite3_shell \
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
| > | 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_WIN32_NO_ANSI \
-D_HAVE__MINGW_H \
-DSQLITE_USE_MALLOC_H \
-DSQLITE_USE_MSIZE
SHELL_OPTIONS = -Dmain=sqlite3_shell \
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
|
| ︙ | ︙ |
Changes to win/Makefile.mingw.mistachkin.
| ︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # FOSSIL_ENABLE_SSL = 1 #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 #### Enable TH1 scripts in embedded documentation files # FOSSIL_ENABLE_TH1_DOCS = 1 #### Enable hooks for commands and web pages via TH1 # | > > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # FOSSIL_ENABLE_SSL = 1 #### Automatically build OpenSSL when building Fossil (causes rebuild # issues when building incrementally). # # FOSSIL_BUILD_SSL = 1 #### Enable legacy treatment of mv/rm (skip checkout files) # FOSSIL_ENABLE_LEGACY_MV_RM = 1 #### Enable TH1 scripts in embedded documentation files # FOSSIL_ENABLE_TH1_DOCS = 1 #### Enable hooks for commands and web pages via TH1 # |
| ︙ | ︙ | |||
249 250 251 252 253 254 255 256 257 258 259 260 261 262 | endif # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif # With TH1 embedded docs support ifdef FOSSIL_ENABLE_TH1_DOCS TCC += -DFOSSIL_ENABLE_TH1_DOCS=1 RCC += -DFOSSIL_ENABLE_TH1_DOCS=1 endif | > > > > > > | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | endif # With HTTPS support ifdef FOSSIL_ENABLE_SSL TCC += -DFOSSIL_ENABLE_SSL=1 RCC += -DFOSSIL_ENABLE_SSL=1 endif # With legacy treatment of mv/rm ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC += -DFOSSIL_ENABLE_LEGACY_MV_RM=1 endif # With TH1 embedded docs support ifdef FOSSIL_ENABLE_TH1_DOCS TCC += -DFOSSIL_ENABLE_TH1_DOCS=1 RCC += -DFOSSIL_ENABLE_TH1_DOCS=1 endif |
| ︙ | ︙ | |||
435 436 437 438 439 440 441 442 443 444 445 446 447 448 | $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/path.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/publish.c \ $(SRCDIR)/purge.c \ $(SRCDIR)/rebuild.c \ | > | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 | $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/path.c \ $(SRCDIR)/piechart.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/publish.c \ $(SRCDIR)/purge.c \ $(SRCDIR)/rebuild.c \ |
| ︙ | ︙ | |||
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | $(SRCDIR)/winhttp.c \ $(SRCDIR)/wysiwyg.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../skins/black_and_white/css.txt \ $(SRCDIR)/../skins/black_and_white/footer.txt \ $(SRCDIR)/../skins/black_and_white/header.txt \ $(SRCDIR)/../skins/blitz/css.txt \ $(SRCDIR)/../skins/blitz/footer.txt \ $(SRCDIR)/../skins/blitz/header.txt \ $(SRCDIR)/../skins/blitz/ticket.txt \ $(SRCDIR)/../skins/blitz_no_logo/css.txt \ $(SRCDIR)/../skins/blitz_no_logo/footer.txt \ $(SRCDIR)/../skins/blitz_no_logo/header.txt \ $(SRCDIR)/../skins/blitz_no_logo/ticket.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ $(SRCDIR)/../skins/enhanced1/header.txt \ $(SRCDIR)/../skins/khaki/css.txt \ $(SRCDIR)/../skins/khaki/footer.txt \ $(SRCDIR)/../skins/khaki/header.txt \ $(SRCDIR)/../skins/original/css.txt \ $(SRCDIR)/../skins/original/footer.txt \ $(SRCDIR)/../skins/original/header.txt \ $(SRCDIR)/../skins/plain_gray/css.txt \ $(SRCDIR)/../skins/plain_gray/footer.txt \ $(SRCDIR)/../skins/plain_gray/header.txt \ $(SRCDIR)/../skins/rounded1/css.txt \ $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ | > > > > > > > > > > > > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | $(SRCDIR)/winhttp.c \ $(SRCDIR)/wysiwyg.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../skins/aht/details.txt \ $(SRCDIR)/../skins/black_and_white/css.txt \ $(SRCDIR)/../skins/black_and_white/details.txt \ $(SRCDIR)/../skins/black_and_white/footer.txt \ $(SRCDIR)/../skins/black_and_white/header.txt \ $(SRCDIR)/../skins/blitz/css.txt \ $(SRCDIR)/../skins/blitz/details.txt \ $(SRCDIR)/../skins/blitz/footer.txt \ $(SRCDIR)/../skins/blitz/header.txt \ $(SRCDIR)/../skins/blitz/ticket.txt \ $(SRCDIR)/../skins/blitz_no_logo/css.txt \ $(SRCDIR)/../skins/blitz_no_logo/details.txt \ $(SRCDIR)/../skins/blitz_no_logo/footer.txt \ $(SRCDIR)/../skins/blitz_no_logo/header.txt \ $(SRCDIR)/../skins/blitz_no_logo/ticket.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ $(SRCDIR)/../skins/enhanced1/header.txt \ $(SRCDIR)/../skins/khaki/css.txt \ $(SRCDIR)/../skins/khaki/details.txt \ $(SRCDIR)/../skins/khaki/footer.txt \ $(SRCDIR)/../skins/khaki/header.txt \ $(SRCDIR)/../skins/original/css.txt \ $(SRCDIR)/../skins/original/details.txt \ $(SRCDIR)/../skins/original/footer.txt \ $(SRCDIR)/../skins/original/header.txt \ $(SRCDIR)/../skins/plain_gray/css.txt \ $(SRCDIR)/../skins/plain_gray/details.txt \ $(SRCDIR)/../skins/plain_gray/footer.txt \ $(SRCDIR)/../skins/plain_gray/header.txt \ $(SRCDIR)/../skins/rounded1/css.txt \ $(SRCDIR)/../skins/rounded1/details.txt \ $(SRCDIR)/../skins/rounded1/footer.txt \ $(SRCDIR)/../skins/rounded1/header.txt \ $(SRCDIR)/../skins/xekri/css.txt \ $(SRCDIR)/../skins/xekri/details.txt \ $(SRCDIR)/../skins/xekri/footer.txt \ $(SRCDIR)/../skins/xekri/header.txt \ $(SRCDIR)/diff.tcl \ $(SRCDIR)/markdown.md TRANS_SRC = \ $(OBJDIR)/add_.c \ |
| ︙ | ︙ | |||
594 595 596 597 598 599 600 601 602 603 604 605 606 607 | $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/path_.c \ $(OBJDIR)/pivot_.c \ $(OBJDIR)/popen_.c \ $(OBJDIR)/pqueue_.c \ $(OBJDIR)/printf_.c \ $(OBJDIR)/publish_.c \ $(OBJDIR)/purge_.c \ $(OBJDIR)/rebuild_.c \ | > | 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/path_.c \ $(OBJDIR)/piechart_.c \ $(OBJDIR)/pivot_.c \ $(OBJDIR)/popen_.c \ $(OBJDIR)/pqueue_.c \ $(OBJDIR)/printf_.c \ $(OBJDIR)/publish_.c \ $(OBJDIR)/purge_.c \ $(OBJDIR)/rebuild_.c \ |
| ︙ | ︙ | |||
714 715 716 717 718 719 720 721 722 723 724 725 726 727 | $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/path.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/publish.o \ $(OBJDIR)/purge.o \ $(OBJDIR)/rebuild.o \ | > | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/path.o \ $(OBJDIR)/piechart.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/publish.o \ $(OBJDIR)/purge.o \ $(OBJDIR)/rebuild.o \ |
| ︙ | ︙ | |||
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ | > | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 | $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ $(OBJDIR)/piechart_.c:$(OBJDIR)/piechart.h \ $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| ︙ | ︙ | |||
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 | $(OBJDIR)/path_.c: $(SRCDIR)/path.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/path.c >$@ $(OBJDIR)/path.o: $(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c $(OBJDIR)/path.h: $(OBJDIR)/headers $(OBJDIR)/pivot_.c: $(SRCDIR)/pivot.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/pivot.c >$@ $(OBJDIR)/pivot.o: $(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c | > > > > > > > > | 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 | $(OBJDIR)/path_.c: $(SRCDIR)/path.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/path.c >$@ $(OBJDIR)/path.o: $(OBJDIR)/path_.c $(OBJDIR)/path.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c $(OBJDIR)/path.h: $(OBJDIR)/headers $(OBJDIR)/piechart_.c: $(SRCDIR)/piechart.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/piechart.c >$@ $(OBJDIR)/piechart.o: $(OBJDIR)/piechart_.c $(OBJDIR)/piechart.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/piechart.o -c $(OBJDIR)/piechart_.c $(OBJDIR)/piechart.h: $(OBJDIR)/headers $(OBJDIR)/pivot_.c: $(SRCDIR)/pivot.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/pivot.c >$@ $(OBJDIR)/pivot.o: $(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c |
| ︙ | ︙ | |||
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_WIN32_NO_ANSI \
-D_HAVE__MINGW_H \
-DSQLITE_USE_MALLOC_H \
-DSQLITE_USE_MSIZE
SHELL_OPTIONS = -Dmain=sqlite3_shell \
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
| > | 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 |
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_WIN32_NO_ANSI \
-D_HAVE__MINGW_H \
-DSQLITE_USE_MALLOC_H \
-DSQLITE_USE_MSIZE
SHELL_OPTIONS = -Dmain=sqlite3_shell \
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
|
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # FOSSIL_ENABLE_MINIZ = 1 # Uncomment to enable SSL support # FOSSIL_ENABLE_SSL = 1 # Uncomment to build SSL libraries # FOSSIL_BUILD_SSL = 1 # Uncomment to enable TH1 scripts in embedded documentation files # FOSSIL_ENABLE_TH1_DOCS = 1 # Uncomment to enable TH1 hooks # FOSSIL_ENABLE_TH1_HOOKS = 1 | > > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | # FOSSIL_ENABLE_MINIZ = 1 # Uncomment to enable SSL support # FOSSIL_ENABLE_SSL = 1 # Uncomment to build SSL libraries # FOSSIL_BUILD_SSL = 1 # Uncomment to enable legacy treatment of mv/rm # FOSSIL_ENABLE_LEGACY_MV_RM = 1 # Uncomment to enable TH1 scripts in embedded documentation files # FOSSIL_ENABLE_TH1_DOCS = 1 # Uncomment to enable TH1 hooks # FOSSIL_ENABLE_TH1_HOOKS = 1 |
| ︙ | ︙ | |||
158 159 160 161 162 163 164 165 166 167 168 169 170 171 | !ifdef FOSSIL_ENABLE_SSL TCC = $(TCC) /DFOSSIL_ENABLE_SSL=1 RCC = $(RCC) /DFOSSIL_ENABLE_SSL=1 LIBS = $(LIBS) $(SSLLIB) LIBDIR = $(LIBDIR) /LIBPATH:$(SSLLIBDIR) !endif !ifdef FOSSIL_ENABLE_TH1_DOCS TCC = $(TCC) /DFOSSIL_ENABLE_TH1_DOCS=1 RCC = $(RCC) /DFOSSIL_ENABLE_TH1_DOCS=1 !endif !ifdef FOSSIL_ENABLE_TH1_HOOKS | > > > > > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | !ifdef FOSSIL_ENABLE_SSL TCC = $(TCC) /DFOSSIL_ENABLE_SSL=1 RCC = $(RCC) /DFOSSIL_ENABLE_SSL=1 LIBS = $(LIBS) $(SSLLIB) LIBDIR = $(LIBDIR) /LIBPATH:$(SSLLIBDIR) !endif !ifdef FOSSIL_ENABLE_LEGACY_MV_RM TCC = $(TCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 RCC = $(RCC) /DFOSSIL_ENABLE_LEGACY_MV_RM=1 !endif !ifdef FOSSIL_ENABLE_TH1_DOCS TCC = $(TCC) /DFOSSIL_ENABLE_TH1_DOCS=1 RCC = $(RCC) /DFOSSIL_ENABLE_TH1_DOCS=1 !endif !ifdef FOSSIL_ENABLE_TH1_HOOKS |
| ︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_THREADSAFE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS3_PARENTHESIS \
/DSQLITE_WIN32_NO_ANSI
SHELL_OPTIONS = /Dmain=sqlite3_shell \
/DSQLITE_OMIT_LOAD_EXTENSION=1 \
/DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
/DSQLITE_SHELL_DBNAME_PROC=fossil_open \
/Daccess=file_access \
| > | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_THREADSAFE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS3_PARENTHESIS \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_WIN32_NO_ANSI
SHELL_OPTIONS = /Dmain=sqlite3_shell \
/DSQLITE_OMIT_LOAD_EXTENSION=1 \
/DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
/DSQLITE_SHELL_DBNAME_PROC=fossil_open \
/Daccess=file_access \
|
| ︙ | ︙ | |||
276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
markdown_html_.c \
md5_.c \
merge_.c \
merge3_.c \
moderate_.c \
name_.c \
path_.c \
pivot_.c \
popen_.c \
pqueue_.c \
printf_.c \
publish_.c \
purge_.c \
rebuild_.c \
| > | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
markdown_html_.c \
md5_.c \
merge_.c \
merge3_.c \
moderate_.c \
name_.c \
path_.c \
piechart_.c \
pivot_.c \
popen_.c \
pqueue_.c \
printf_.c \
publish_.c \
purge_.c \
rebuild_.c \
|
| ︙ | ︙ | |||
323 324 325 326 327 328 329 |
winfile_.c \
winhttp_.c \
wysiwyg_.c \
xfer_.c \
xfersetup_.c \
zip_.c
| | > > > > > > > > > > > > | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
winfile_.c \
winhttp_.c \
wysiwyg_.c \
xfer_.c \
xfersetup_.c \
zip_.c
EXTRA_FILES = $(SRCDIR)\../skins/aht/details.txt \
$(SRCDIR)\../skins/black_and_white/css.txt \
$(SRCDIR)\../skins/black_and_white/details.txt \
$(SRCDIR)\../skins/black_and_white/footer.txt \
$(SRCDIR)\../skins/black_and_white/header.txt \
$(SRCDIR)\../skins/blitz/css.txt \
$(SRCDIR)\../skins/blitz/details.txt \
$(SRCDIR)\../skins/blitz/footer.txt \
$(SRCDIR)\../skins/blitz/header.txt \
$(SRCDIR)\../skins/blitz/ticket.txt \
$(SRCDIR)\../skins/blitz_no_logo/css.txt \
$(SRCDIR)\../skins/blitz_no_logo/details.txt \
$(SRCDIR)\../skins/blitz_no_logo/footer.txt \
$(SRCDIR)\../skins/blitz_no_logo/header.txt \
$(SRCDIR)\../skins/blitz_no_logo/ticket.txt \
$(SRCDIR)\../skins/default/css.txt \
$(SRCDIR)\../skins/default/details.txt \
$(SRCDIR)\../skins/default/footer.txt \
$(SRCDIR)\../skins/default/header.txt \
$(SRCDIR)\../skins/eagle/css.txt \
$(SRCDIR)\../skins/eagle/details.txt \
$(SRCDIR)\../skins/eagle/footer.txt \
$(SRCDIR)\../skins/eagle/header.txt \
$(SRCDIR)\../skins/enhanced1/css.txt \
$(SRCDIR)\../skins/enhanced1/details.txt \
$(SRCDIR)\../skins/enhanced1/footer.txt \
$(SRCDIR)\../skins/enhanced1/header.txt \
$(SRCDIR)\../skins/khaki/css.txt \
$(SRCDIR)\../skins/khaki/details.txt \
$(SRCDIR)\../skins/khaki/footer.txt \
$(SRCDIR)\../skins/khaki/header.txt \
$(SRCDIR)\../skins/original/css.txt \
$(SRCDIR)\../skins/original/details.txt \
$(SRCDIR)\../skins/original/footer.txt \
$(SRCDIR)\../skins/original/header.txt \
$(SRCDIR)\../skins/plain_gray/css.txt \
$(SRCDIR)\../skins/plain_gray/details.txt \
$(SRCDIR)\../skins/plain_gray/footer.txt \
$(SRCDIR)\../skins/plain_gray/header.txt \
$(SRCDIR)\../skins/rounded1/css.txt \
$(SRCDIR)\../skins/rounded1/details.txt \
$(SRCDIR)\../skins/rounded1/footer.txt \
$(SRCDIR)\../skins/rounded1/header.txt \
$(SRCDIR)\../skins/xekri/css.txt \
$(SRCDIR)\../skins/xekri/details.txt \
$(SRCDIR)\../skins/xekri/footer.txt \
$(SRCDIR)\../skins/xekri/header.txt \
$(SRCDIR)\diff.tcl \
$(SRCDIR)\markdown.md
OBJ = $(OX)\add$O \
$(OX)\allrepo$O \
|
| ︙ | ︙ | |||
434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
$(OX)\markdown_html$O \
$(OX)\md5$O \
$(OX)\merge$O \
$(OX)\merge3$O \
$(OX)\moderate$O \
$(OX)\name$O \
$(OX)\path$O \
$(OX)\pivot$O \
$(OX)\popen$O \
$(OX)\pqueue$O \
$(OX)\printf$O \
$(OX)\publish$O \
$(OX)\purge$O \
$(OX)\rebuild$O \
| > | 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
$(OX)\markdown_html$O \
$(OX)\md5$O \
$(OX)\merge$O \
$(OX)\merge3$O \
$(OX)\moderate$O \
$(OX)\name$O \
$(OX)\path$O \
$(OX)\piechart$O \
$(OX)\pivot$O \
$(OX)\popen$O \
$(OX)\pqueue$O \
$(OX)\printf$O \
$(OX)\publish$O \
$(OX)\purge$O \
$(OX)\rebuild$O \
|
| ︙ | ︙ | |||
609 610 611 612 613 614 615 616 617 618 619 620 621 622 | echo $(OX)\markdown_html.obj >> $@ echo $(OX)\md5.obj >> $@ echo $(OX)\merge.obj >> $@ echo $(OX)\merge3.obj >> $@ echo $(OX)\moderate.obj >> $@ echo $(OX)\name.obj >> $@ echo $(OX)\path.obj >> $@ echo $(OX)\pivot.obj >> $@ echo $(OX)\popen.obj >> $@ echo $(OX)\pqueue.obj >> $@ echo $(OX)\printf.obj >> $@ echo $(OX)\publish.obj >> $@ echo $(OX)\purge.obj >> $@ echo $(OX)\rebuild.obj >> $@ | > | 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 | echo $(OX)\markdown_html.obj >> $@ echo $(OX)\md5.obj >> $@ echo $(OX)\merge.obj >> $@ echo $(OX)\merge3.obj >> $@ echo $(OX)\moderate.obj >> $@ echo $(OX)\name.obj >> $@ echo $(OX)\path.obj >> $@ echo $(OX)\piechart.obj >> $@ echo $(OX)\pivot.obj >> $@ echo $(OX)\popen.obj >> $@ echo $(OX)\pqueue.obj >> $@ echo $(OX)\printf.obj >> $@ echo $(OX)\publish.obj >> $@ echo $(OX)\purge.obj >> $@ echo $(OX)\rebuild.obj >> $@ |
| ︙ | ︙ | |||
1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 | translate$E $** > $@ $(OX)\path$O : path_.c path.h $(TCC) /Fo$@ -c path_.c path_.c : $(SRCDIR)\path.c translate$E $** > $@ $(OX)\pivot$O : pivot_.c pivot.h $(TCC) /Fo$@ -c pivot_.c pivot_.c : $(SRCDIR)\pivot.c translate$E $** > $@ | > > > > > > | 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 | translate$E $** > $@ $(OX)\path$O : path_.c path.h $(TCC) /Fo$@ -c path_.c path_.c : $(SRCDIR)\path.c translate$E $** > $@ $(OX)\piechart$O : piechart_.c piechart.h $(TCC) /Fo$@ -c piechart_.c piechart_.c : $(SRCDIR)\piechart.c translate$E $** > $@ $(OX)\pivot$O : pivot_.c pivot.h $(TCC) /Fo$@ -c pivot_.c pivot_.c : $(SRCDIR)\pivot.c translate$E $** > $@ |
| ︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 | markdown_html_.c:markdown_html.h \ md5_.c:md5.h \ merge_.c:merge.h \ merge3_.c:merge3.h \ moderate_.c:moderate.h \ name_.c:name.h \ path_.c:path.h \ pivot_.c:pivot.h \ popen_.c:popen.h \ pqueue_.c:pqueue.h \ printf_.c:printf.h \ publish_.c:publish.h \ purge_.c:purge.h \ rebuild_.c:rebuild.h \ | > | 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 | markdown_html_.c:markdown_html.h \ md5_.c:md5.h \ merge_.c:merge.h \ merge3_.c:merge3.h \ moderate_.c:moderate.h \ name_.c:name.h \ path_.c:path.h \ piechart_.c:piechart.h \ pivot_.c:pivot.h \ popen_.c:popen.h \ pqueue_.c:pqueue.h \ printf_.c:printf.h \ publish_.c:publish.h \ purge_.c:purge.h \ rebuild_.c:rebuild.h \ |
| ︙ | ︙ |
Changes to win/fossil.rc.
| ︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
VALUE "CommandLineIsUnicode", "No\0"
#else
VALUE "CommandLineIsUnicode", "Yes\0"
#endif /* defined(BROKEN_MINGW_CMDLINE) */
#if defined(FOSSIL_ENABLE_SSL)
VALUE "SslEnabled", "Yes, " OPENSSL_VERSION_TEXT "\0"
#endif /* defined(FOSSIL_ENABLE_SSL) */
#if defined(FOSSIL_ENABLE_TH1_DOCS)
VALUE "Th1Docs", "Yes\0"
#else
VALUE "Th1Docs", "No\0"
#endif /* defined(FOSSIL_ENABLE_TH1_DOCS) */
#if defined(FOSSIL_ENABLE_TH1_HOOKS)
VALUE "Th1Hooks", "Yes\0"
| > > > > > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
VALUE "CommandLineIsUnicode", "No\0"
#else
VALUE "CommandLineIsUnicode", "Yes\0"
#endif /* defined(BROKEN_MINGW_CMDLINE) */
#if defined(FOSSIL_ENABLE_SSL)
VALUE "SslEnabled", "Yes, " OPENSSL_VERSION_TEXT "\0"
#endif /* defined(FOSSIL_ENABLE_SSL) */
#if defined(FOSSIL_ENABLE_LEGACY_MV_RM)
VALUE "LegacyMvRm", "Yes\0"
#else
VALUE "LegacyMvRm", "No\0"
#endif /* defined(FOSSIL_ENABLE_LEGACY_MV_RM) */
#if defined(FOSSIL_ENABLE_TH1_DOCS)
VALUE "Th1Docs", "Yes\0"
#else
VALUE "Th1Docs", "No\0"
#endif /* defined(FOSSIL_ENABLE_TH1_DOCS) */
#if defined(FOSSIL_ENABLE_TH1_HOOKS)
VALUE "Th1Hooks", "Yes\0"
|
| ︙ | ︙ |
Changes to www/build.wiki.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 | </ol> <p><hr> <h2>1.0 Obtaining The Source Code</h2> <p>Fossil is self-hosting, so you can obtain a ZIP archive or tarball | | | | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | </ol> <p><hr> <h2>1.0 Obtaining The Source Code</h2> <p>Fossil is self-hosting, so you can obtain a ZIP archive or tarball containing a snapshot of the <em>latest</em> version directly from Fossil's own fossil repository. Additionally, source archives of <em>released</em> versions of fossil are available from the <a href="http://www.fossil-scm.org/download.html">downloads page</a>. To obtain a development version of fossil, follow these steps:</p> <ol> <li><p>Point your web browser to <a href="http://www.fossil-scm.org/"> http://www.fossil-scm.org/</a>.</p></li> <li><p>Click on the <a href="http://www.fossil-scm.org/fossil/timeline">Timeline</a> link at the top of the page.</p></li> <li><p>Select a version of of Fossil you want to download. The latest version on the trunk branch is usually a good choice. Click on its link.</p></li> <li><p>Finally, click on one of the "Zip Archive" or "Tarball" links, according to your preference. These link will build a ZIP archive or a gzip-compressed tarball of the complete source code and download it to your computer. </ol> <h2>Aside: Is it really safe to use an unreleased development version of the Fossil source code?</h2> Yes! Any check-in on the [/timeline?t=trunk | trunk branch] of the Fossil [http://fossil-scm.org/fossil/timeline | Fossil self-hosting repository] will work fine. (Dodgy code is always on a branch.) In the unlikely event that you pick a version with a serious bug, it still won't clobber your files. Fossil uses several [./selfcheck.wiki | self-checks] prior to committing any repository change that prevent loss-of-work due to bugs. |
| ︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | If you do not have the OpenSSL library installed on your system, then add <b>--with-openssl=none</b> to omit the https functionality. <li><p> To build a statically linked binary (suitable for use inside a chroot jail) add the <b>--static</b> option. <li><p> Other configuration options can be seen by running <b>./configure --help</b> </ol> <li><p>Run "<b>make</b>" to build the "fossil" or "fossil.exe" executable. The details depend on your platform and compiler. <ol type="a"> <li><p><i>Unix</i> → the configure-generated Makefile should work on all Unix and Unix-like systems. Simply type "<b>make</b>". | > > > > | | | > > > > > > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
If you do not have the OpenSSL library installed on your system, then
add <b>--with-openssl=none</b> to omit the https functionality.
<li><p>
To build a statically linked binary (suitable for use inside a chroot
jail) add the <b>--static</b> option.
<li><p>
To enable the native [./th1.md#tclEval | Tcl integration feature] feature,
add the <b>--with-tcl=1</b> and <b>--with-tcl-private-stubs=1</b> options.
<li><p>
Other configuration options can be seen by running
<b>./configure --help</b>
</ol>
<li><p>Run "<b>make</b>" to build the "fossil" or "fossil.exe" executable.
The details depend on your platform and compiler.
<ol type="a">
<li><p><i>Unix</i> → the configure-generated Makefile should work on
all Unix and Unix-like systems. Simply type "<b>make</b>".
<li><p><i>Unix without running "configure"</i> → if you prefer to avoid
running configure, you can also use: <b>make -f Makefile.classic</b>. You may
want to make minor edits to Makefile.classic to configure the build for your
system.
<li><p><i>MinGW3.x (not 4.0)/MinGW-w64</i> → Use the mingw makefile:
"<b>make -f win/Makefile.mingw</b>". On a Windows box you will
need either Cygwin or Msys as build environment. On Cygwin, Linux
or Darwin you may want to make minor edits to win/Makefile.mingw
to configure the cross-compile environment.
To enable the native [./th1.md#tclEval | Tcl integration feature], use a
command line like the following (all on one line):
<b>make -f win/Makefile.mingw FOSSIL_ENABLE_TCL=1 FOSSIL_ENABLE_TCL_STUBS=1 FOSSIL_ENABLE_TCL_PRIVATE_STUBS=1</b>
Hint: don't use MinGW-4.0, it will compile but fossil won't work correctly, see
<a href="https://www.fossil-scm.org/index.html/tktview/18cff45a4e210430e24c">https://www.fossil-scm.org/index.html/tktview/18cff45a4e210430e24c</a>.
<li><p><i>MSVC</i> → Use the MSVC makefile. First
change to the "win/" subdirectory ("<b>cd win</b>") then run
"<b>nmake /f Makefile.msc</b>".<br><br>Alternatively, the batch
file "<b>win\buildmsvc.bat</b>" may be used and it will attempt to
|
| ︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | and finally run one of the following commands: <blockquote><pre> nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin </pre></blockquote> <blockquote><pre> buildmsvc.bat FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin </pre></blockquote> <li><p><i>Cygwin</i> → The same as other Unix-like systems. It is recommended to configure using: "<b>configure --disable-internal-sqlite</b>", making sure you have the "libsqlite3-devel" , "zlib-devel" and "openssl-devel" packages installed first. </ol> </ol> <h2>3.0 Installing</h2> <ol> <li value="8"> | > > > > > > > > > | | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | and finally run one of the following commands: <blockquote><pre> nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin </pre></blockquote> <blockquote><pre> buildmsvc.bat FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin </pre></blockquote> To enable the optional native [./th1.md#tclEval | Tcl integration feature], run one of the following commands or add the "FOSSIL_ENABLE_TCL=1" argument to one of the other NMAKE command lines: <blockquote><pre> nmake /f Makefile.msc FOSSIL_ENABLE_TCL=1 </pre></blockquote> <blockquote><pre> buildmsvc.bat FOSSIL_ENABLE_TCL=1 </pre></blockquote> <li><p><i>Cygwin</i> → The same as other Unix-like systems. It is recommended to configure using: "<b>configure --disable-internal-sqlite</b>", making sure you have the "libsqlite3-devel" , "zlib-devel" and "openssl-devel" packages installed first. </ol> </ol> <h2>3.0 Installing</h2> <ol> <li value="8"> <p>The finished binary is named "fossil" (or "fossil.exe" on Windows). Put this binary in a directory that is somewhere on your PATH environment variable. It does not matter where.</p> <li> <p><b>(Optional:)</b> To uninstall, just delete the binary.</p> </ol> <h2>4.0 Additional Considerations</h2> <ul> <li><p> If the makefiles that come with Fossil do not work for you, or for some other reason you want to know how to build Fossil manually, then refer to the [./makefile.wiki | Fossil Build Process] document which describes in detail what the makefiles do behind the scenes. <li><p> The fossil executable is self-contained and stand-alone and usually requires no special libraries or other software to be installed. However, the "--tk" option to the [/help/diff|diff command] requires that Tcl/Tk be installed on the local machine. You can get Tcl/Tk from [http://www.activestate.com/activetcl|ActiveState]. <li><p> To build on older Macs (circa 2002, MacOS 10.2) edit the Makefile generated by configure to add the following lines: <blockquote><pre> TCC += -DSQLITE_WITHOUT_ZONEMALLOC TCC += -D_BSD_SOURCE TCC += -DWITHOUT_ICONV TCC += -Dsocketlen_t=int TCC += -DSQLITE_MAX_MMAP_SIZE=0 </pre></blockquote> </ul> |
Changes to www/changes.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<title>Change Log</title>
<h2>Changes for Version 1.33 (not released yet)</h2>
* Add [/help?cmd=import|fossil import --svn], for importing a subversion
repository into fossil which was exported using "svnadmin dump".
<h2>Changes for Version 1.32 (2015-03-14)</h2>
* When creating a new repository using [/help?cmd=init|fossil init], ensure
that the new repository is fully compatible with historical versions of
Fossil by having a valid manifest as RID 1.
* Anti-aliased rendering of arrowheads on timeline graphs.
* Added vi/less-style key bindings to the --tk diff GUI.
* Documentation updates to fix spellings and changes all "checkins" to
"check-ins".
* Add the --repolist option to server commands such as
[/help?cmd=server|fossil server] or [/help?cmd=http|fossil http].
* Added the "Xekri" skin.
* Enhance the "ln=" query parameter on artifact displays to accept multiple
ranges, separate by spaces (or "+" when URL-encoded).
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
<title>Change Log</title>
<h2>Changes for Version 1.33 (not released yet)</h2>
* Improved fork detection on [/help?cmd=update|fossil update],
[/help?cmd=status|fossil status] and related commands.
* Change the default skin to what used to be called "San Francisco Modern".
* Add the [/repo-tabsize] web page
* Add [/help?cmd=import|fossil import --svn], for importing a subversion
repository into fossil which was exported using "svnadmin dump".
* Add the "--compress-only" option to [/help?cmd=rebuild|fossil rebuild].
* Use a pie chart on the [/reports?view=byuser] page.
* Enhanced [/help?cmd=clean|fossil clean --verily] so that it ignores
keep-glob and ignore-glob settings. Added the -x alias for --verily.
* Add the --soft and --hard options to [/help?cmd=rm|fossil rm] and
[/help?cmd=mv|fossil mv]. The default is still --soft, but that is
now configurable at compile-time or by the mv-rm-files setting.
* Improved ability to [./customgraph.md|customize the timelime graph].
* Improvements to the [/sitemap] page.
* Automatically adjust the [/help?cmd=timeline|CLI timeline] to the terminal
width on Linux.
* Added <nowiki>[info commands] and [info vars]</nowiki> commands to TH1.
These commands perform the same function as their Tcl counterparts,
except they do not accept a pattern argument.
* Fix some obscure issues with TH1 expression processing.
* Fix titles in search results for documents that are not wiki, markdown,
or HTML.
* Formally translate TH1 to Tcl return codes and vice-versa, where
necessary, in the Tcl integration subsystem.
* Add [/help?cmd=leaves|fossil leaves -multiple], for finding multiple
leaves on the same branch.
* Added the "Blitz" skin option.
* Removed the ".fossil-settings/keep-glob" file. It should not have been
checked into the repository.
* Update the built-in SQLite to version 3.8.10.1.
* Made [/help?cmd=open|fossil open] honor ".fossil-settings/allow-symlinks".
* Allow [/help?cmd=add|fossil add] to be used on symlinks to nonexistent or
unreadable files in the same way as [/help?cmd=addremove|fossil addremove].
* Added fork warning to be issued if sync produced a fork
<h2>Changes for Version 1.32 (2015-03-14)</h2>
* When creating a new repository using [/help?cmd=init|fossil init], ensure
that the new repository is fully compatible with historical versions of
Fossil by having a valid manifest as RID 1.
* Anti-aliased rendering of arrowheads on timeline graphs.
* Added vi/less-style key bindings to the --tk diff GUI.
* Documentation updates to fix spellings and changes all "checkins" to
"check-ins".
* Add the --repolist option to server commands such as
[/help?cmd=server|fossil server] or [/help?cmd=http|fossil http].
* Added the "Xekri" skin.
* Enhance the "ln=" query parameter on artifact displays to accept multiple
ranges, separate by spaces (or "+" when URL-encoded).
* Added [/help?cmd=forget|fossil forget] as an alias for
[/help?cmd=rm|fossil rm].
<h2>Changes For Version 1.31 (2015-02-23)</h2>
* Change the auxiliary schema by adding columns MLINK.ISAUX and MLINK.PMID
columns to the schema, to support better drawing of file change graphs.
A [/help?cmd=rebuild|fossil rebuild] is recommended but is not required.
so that the new graph drawing logic can work effectively.
* Added [/search|search] over Check-in comments, Documents, Tickets and
Wiki. Disabled by default. The search can be either a full-scan or it
can use an index that is kept up-to-date automatically. The new
/srchsetup web-page and the [/help?cmd=fts-config|fts-config] command
were added to help configure the search capability. Expect further
enhancements to the search capabilities in subsequent releases.
* Added form elements to some submenus (in particular the /timeline)
for easier operation.
* Added the --ifneeded option to [/help?cmd=rebuild|fossil rebuild].
* Added "override skins" using the "skin:" line of the CGI script or
using the --skin LABEL option on the [/help?cmd=server|server],
[/help?cmd=ui|ui], or [/help?cmd=http|http] commands.
* Embedded html documents that begin with
<doc class="fossil-doc"> are displayed with standard
headers and footers added.
* Allow <div style='...'> markup in [/wiki_rules|wiki].
* Renamed "Events" to "Technical Notes", while updating the technote
display and control pages. Add support for technotes as plain text
or as Markdown.
|
| ︙ | ︙ |
Added www/customgraph.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# Customizing the Timeline Graph
Beginning with version 1.33, Fossil gives users and skin authors significantly
more control over the look and feel of the timeline graph.
## <a id="basic-style"></a>Basic Style Options
Fossil includes several options for changing the graph's style without having
to delve into CSS. These can be found in the details.txt file of your skin or
under Admin/Skins/Details in the web UI.
* ###`timeline-arrowheads`
Set this to `0` to hide arrowheads on primary child lines.
* ###`timeline-circle-nodes`
Set this to `1` to make check-in nodes circular instead of square.
* ###`timeline-color-graph-lines`
Set this to `1` to colorize primary child lines.
* ###`white-foreground`
Set this to `1` if your skin uses white (or any light color) text.
This tells Fossil to generate darker background colors for branches.
## <a id="adv-style"></a>Advanced Styling
If the above options aren't enough for you, it's time to get your hands dirty
with CSS. To get started, I recommend first copying all the [graph-related CSS
rules](#default-css) to your stylesheet. Then it's simply a matter of making
the necessary changes to achieve the look you want. So, next, let's look at the
various graph elements and what purpose they serve.
Each element used to construct the timeline graph falls into one of two
categories: visible elements and positioning elements. We'll start with the
latter, less obvious type.
## <a id="pos-elems"></a>Positioning Elements
These elements aren't intended to be seen. They're only used to help position
the graph and its visible elements.
* ###<a id="tl-canvas"></a>`.tl-canvas`
Set the left and right margins on this class to give the desired amount
of space between the graph and its adjacent columns in the timeline.
#### Additional Classes
* `.sel`: See [`.tl-node`](#tl-node) for more information.
* ###<a id="tl-rail"></a>`.tl-rail`
Think of rails as invisible vertical lines on which check-in nodes are
placed. The more simultaneous branches in a graph, the more rails required
to draw it. Setting the `width` property on this class determines the
maximum spacing between rails. This spacing is automatically reduced as
the number of rails increases. If you change the `width` of `.tl-node`
elements, you'll probably need to change this value, too.
* ###<a id="tl-mergeoffset"></a>`.tl-mergeoffset`
A merge line often runs vertically right beside a primary child line. This
class's `width` property specifies the maximum spacing between the two.
Setting this value to `0` will eliminate the vertical merge lines.
Instead, the merge arrow will extend directly off the primary child line.
As with rail spacing, this is also adjusted automatically as needed.
* ###<a id="tl-nodemark"></a>`.tl-nodemark`
In the timeline table, the second cell in each check-in row contains an
invisible div with this class. These divs are used to determine the
vertical position of the nodes. By setting the `margin-top` property,
you can adjust this position.
## <a id="vis-elems"></a>Visible Elements
These are the elements you can actually see on the timeline graph: the nodes,
arrows, and lines. Each of these elements may also have additional classes
attached to them, depending on their context.
* ###<a id="tl-node"></a>`.tl-node`
A node exists for each check-in in the timeline.
#### Additional Classes
* `.leaf`: Specifies that the check-in is a leaf (i.e. that it has no
children in the same branch).
* `.merge`: Specifies that the check-in contains a merge.
* `.sel`: When the user clicks a node to designate it as the beginning
of a diff, this class is added to both the node itself and the
[`.tl-canvas`](#tl-canvas) element. The class is removed from both
elements when the node is clicked again.
* ###<a id="tl-arrow"></a>`.tl-arrow`
Arrows point from parent nodes to their children. Technically, this
class is just for the arrowhead. The rest of the arrow is composed
of [`.tl-line`](#tl-line) elements.
There are six additional classes that are used to distinguish the different
types of arrows. However, only these combinations are valid:
* `.u`: Up arrow that points to a child from its primary parent.
* `.u.sm`: Smaller up arrow, used when there is limited space between
parent and child nodes.
* `.merge.l` or `.merge.r`: Merge arrow pointing either to the left or
right.
* `.warp`: A timewarped arrow (always points to the right), used when a
misconfigured clock makes a check-in appear to have occurred before its
parent ([example](https://www.sqlite.org/src/timeline?c=2010-09-29&nd)).
* ###<a id="tl-line"></a>`.tl-line`
Along with arrows, lines connect parent and child nodes. Line thickness is
determined by the `width` property, regardless of whether the line is
horizontal or vertical. You can also use borders to create special line
styles. Here's a CSS snippet for making dotted merge lines:
.tl-line.merge {
width: 0;
background: transparent;
border: 0 dotted #000;
}
.tl-line.merge.h {
border-top-width: 1px;
}
.tl-line.merge.v {
border-left-width: 1px;
}
#### Additional Classes
* `.merge`: A merge line.
* `.h` or `.v`: Horizontal or vertical.
* `.warp`: A timewarped line.
## <a id="default-css"></a>Default Timeline Graph CSS
.tl-canvas {
margin: 0 6px 0 10px;
}
.tl-rail {
width: 18px;
}
.tl-mergeoffset {
width: 2px;
}
.tl-nodemark {
margin-top: 5px;
}
.tl-node {
width: 10px;
height: 10px;
border: 1px solid #000;
background: #fff;
cursor: pointer;
}
.tl-node.leaf:after {
content: '';
position: absolute;
top: 3px;
left: 3px;
width: 4px;
height: 4px;
background: #000;
}
.tl-node.sel:after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 6px;
height: 6px;
background: red;
}
.tl-arrow {
width: 0;
height: 0;
transform: scale(.999);
border: 0 solid transparent;
}
.tl-arrow.u {
margin-top: -1px;
border-width: 0 3px;
border-bottom: 7px solid #000;
}
.tl-arrow.u.sm {
border-bottom: 5px solid #000;
}
.tl-line {
background: #000;
width: 2px;
}
.tl-arrow.merge {
height: 1px;
border-width: 2px 0;
}
.tl-arrow.merge.l {
border-right: 3px solid #000;
}
.tl-arrow.merge.r {
border-left: 3px solid #000;
}
.tl-line.merge {
width: 1px;
}
.tl-arrow.warp {
margin-left: 1px;
border-width: 3px 0;
border-left: 7px solid #600000;
}
.tl-line.warp {
background: #600000;
}
|
Changes to www/customskin.md.
| ︙ | ︙ | |||
44 45 46 47 48 49 50 | Built-in Skins -------------- Fossil comes with several built-in skins. The sources to these built-ins can be found in the Fossil source tree under the skins/ folder. The skins/ folder contains a separate subfolder for each built-in skin, with each | > | > | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | Built-in Skins -------------- Fossil comes with several built-in skins. The sources to these built-ins can be found in the Fossil source tree under the skins/ folder. The skins/ folder contains a separate subfolder for each built-in skin, with each subfolders holding four files, "css.txt", "details.txt", "footer.txt", and "header.txt", that describe the CSS, rendering options, footer, and header for that skin, respectively. The skin of a repository can be changed to any of the built-in skins using the web interface by going to the /setup_skin web page (requires Admin privileges) and clicking the appropriate button. Or, the --skin command line option can be used for the [fossil ui](../../../help?cmd=ui) or [fossil server](../../../help?cmd=server) commands to force that particular |
| ︙ | ︙ | |||
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
Developers are free, of course, to develop new skins using any method they
want, but the following is a technique that has worked well in the past and
can serve as a starting point for future work:
1. Select a built-in skin that is closest to the desired look. Make
copies of the css, footer, and header into files name "css.txt",
"footer.txt", and "header.txt" in some temporary directory.
If the Fossil source code is available, then these three files can
be copied directly out of one of the subdirectories under skins. If
sources are not easily at hand, then a copy/paste out of the
CSS, footer, and header editing screens under the Admin menu will
work just as well. The important point is that the three files
be named exactly "css.txt", "footer.txt", and "header.txt" and that
they all be in the same directory.
2. Run the [fossil ui](../../../help?cmd=ui) command with an extra
option "--skin SKINDIR" where SKINDIR is the name of the directory
in which the three txt files were stored in step 1. This will bring
up the Fossil website using the tree files in SKINDIR.
| > | | > | > | > > > > | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
Developers are free, of course, to develop new skins using any method they
want, but the following is a technique that has worked well in the past and
can serve as a starting point for future work:
1. Select a built-in skin that is closest to the desired look. Make
copies of the css, footer, and header into files name "css.txt",
"details.txt",
"footer.txt", and "header.txt" in some temporary directory.
If the Fossil source code is available, then these three files can
be copied directly out of one of the subdirectories under skins. If
sources are not easily at hand, then a copy/paste out of the
CSS, footer, and header editing screens under the Admin menu will
work just as well. The important point is that the three files
be named exactly "css.txt", "footer.txt", and "header.txt" and that
they all be in the same directory.
2. Run the [fossil ui](../../../help?cmd=ui) command with an extra
option "--skin SKINDIR" where SKINDIR is the name of the directory
in which the three txt files were stored in step 1. This will bring
up the Fossil website using the tree files in SKINDIR.
3. Edit the four txt files in SKINDIR. After making each small change,
press Reload on the web browser to see the effect of that change.
Iterate until the desired look is achieved.
4. Copy/paste the resulting css.txt, details.txt,
header.txt, and footer.txt files
into the CSS, details, header, and footer configuration screens
under the Admin/Skins menu.
See Also
--------
* [Customizing the Timeline Graph](customgraph.md)
|
Changes to www/event.wiki.
1 2 3 4 5 6 7 8 9 10 11 | <title>Technical Notes</title> <h2>What Is A "Technote"?</h2> In Fossil, a "technical note" or "technote" (formerly called an "event") is a special kind of [./wikitheory.wiki | wiki page] that is associated with a point in time rather than having a page name. Each technote causes a single entry to appear on the [/timeline?y=e | Timeline Page]. Clicking on the timeline link will display the text of the technote. The wiki content, the timeline entry text, the | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<title>Technical Notes</title>
<h2>What Is A "Technote"?</h2>
In Fossil, a "technical note" or "technote" (formerly called an "event")
is a special kind of [./wikitheory.wiki | wiki page]
that is associated with a point in time rather than having a page name.
Each technote causes a single entry to appear on the
[/timeline?y=e | Timeline Page].
Clicking on the timeline link will display the text of the technote.
The wiki content, the timeline entry text, the
time of the technote, and the timeline background color can all be edited.
As with check-ins, wiki, and tickets, all technotes automatically synchronize
to other repositories. Hence, technotes can be viewed, created, and edited
off-line. And the complete edit history for technotes is maintained
for auditing purposes.
Possible uses for technotes include:
* <b>Milestones</b>. Project milestones, such as releases or beta-test
cycles, can be recorded as technotes. The timeline entry for the technote
can be something simple like "Version 1.2.3" perhaps with a bright
color background to draw attention to the entry and the wiki content
can contain release notes, for example.
* <b>Blog Entries</b>. Blog entries from developers describing the current
state of a project, or rational for various design decisions, or
roadmaps for future development, can be entered as technotes.
* <b>Process Checkpoints</b>. For projects that have a formal process,
technotes can be used to record the completion or the initiation of
various process steps. For example, a technote can be used to record
the successful completion of a long-running test, perhaps with
performance results and details of where the test was run and who
ran it recorded in the wiki content.
* <b>News Articles</b>. Significant occurrences in the lifecycle of
a project can be recorded as news articles using technotes. Perhaps the
domain name of the canonical website for a project changes, or new
server hardware is obtained. Such happenings are appropriate for
reporting as news.
* <b>Announcements</b>. Changes to the composition of the development
team or acquisition of new project sponsors can be communicated as
announcements which can be implemented as technotes.
No project is required to use technotes. But technotes can help many projects
stay better organized and provide a better historical record of the
development progress.
<h2>Viewing Technotes</h2>
Because technotes are considered a special kind of wiki,
users must have permission to read wiki in order read technotes.
Enable the "j" permission under the /Setup/Users menu in order
to give specific users or user classes the ability to view wiki
and technotes.
Technotes show up on the timeline. Click on the hyperlink beside the
technote title to see the complete text.
|
| ︙ | ︙ |
Changes to www/mkindex.tcl.
| ︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
build.wiki {Compiling and Installing Fossil}
checkin_names.wiki {Check-in And Version Names}
checkin.wiki {Check-in Checklist}
changes.wiki {Fossil Changelog}
copyright-release.html {Contributor License Agreement}
concepts.wiki {Fossil Core Concepts}
contribute.wiki {Contributing Code or Documentation To The Fossil Project}
customskin.md {Theming: Customizing The Appearance of Web Pages}
custom_ticket.wiki {Customizing The Ticket System}
delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm}
delta_format.wiki {Fossil Delta Format}
embeddeddoc.wiki {Embedded Project Documentation}
event.wiki {Events}
faq.wiki {Frequently Asked Questions}
| > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
build.wiki {Compiling and Installing Fossil}
checkin_names.wiki {Check-in And Version Names}
checkin.wiki {Check-in Checklist}
changes.wiki {Fossil Changelog}
copyright-release.html {Contributor License Agreement}
concepts.wiki {Fossil Core Concepts}
contribute.wiki {Contributing Code or Documentation To The Fossil Project}
customgraph.md {Theming: Customizing the Timeline Graph}
customskin.md {Theming: Customizing The Appearance of Web Pages}
custom_ticket.wiki {Customizing The Ticket System}
delta_encoder_algorithm.wiki {Fossil Delta Encoding Algorithm}
delta_format.wiki {Fossil Delta Format}
embeddeddoc.wiki {Embedded Project Documentation}
event.wiki {Events}
faq.wiki {Frequently Asked Questions}
|
| ︙ | ︙ |
Changes to www/permutedindex.html.
| ︙ | ︙ | |||
32 33 34 35 36 37 38 | <li><a href="password.wiki">Authentication — Password Management And</a></li> <li><a href="antibot.wiki">Bots — Defense against Spiders and</a></li> <li><a href="private.wiki">Branches — Creating, Syncing, and Deleting Private</a></li> <li><a href="branching.wiki">Branching, Forking, Merging, and Tagging</a></li> <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li> <li><a href="makefile.wiki">Build Process — The Fossil</a></li> <li><a href="changes.wiki">Changelog — Fossil</a></li> | < > > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | <li><a href="password.wiki">Authentication — Password Management And</a></li> <li><a href="antibot.wiki">Bots — Defense against Spiders and</a></li> <li><a href="private.wiki">Branches — Creating, Syncing, and Deleting Private</a></li> <li><a href="branching.wiki">Branching, Forking, Merging, and Tagging</a></li> <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li> <li><a href="makefile.wiki">Build Process — The Fossil</a></li> <li><a href="changes.wiki">Changelog — Fossil</a></li> <li><a href="checkin_names.wiki">Check-in And Version Names</a></li> <li><a href="checkin.wiki">Check-in Checklist</a></li> <li><a href="checkin.wiki">Checklist — Check-in</a></li> <li><a href="../test/release-checklist.wiki">Checklist — Pre-Release Testing</a></li> <li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li> <li><a href="selfcheck.wiki">Checks — Fossil Repository Integrity Self</a></li> <li><a href="contribute.wiki">Code or Documentation To The Fossil Project — Contributing</a></li> <li><a href="style.wiki">Code Style Guidelines — Source</a></li> <li><a href="build.wiki">Compiling and Installing Fossil</a></li> <li><a href="concepts.wiki">Concepts — Fossil Core</a></li> <li><a href="server.wiki">Configure A Fossil Server — How To</a></li> <li><a href="shunning.wiki">Content From Fossil — Shunning: Deleting</a></li> <li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li> <li><a href="copyright-release.html">Contributor License Agreement</a></li> <li><a href="concepts.wiki">Core Concepts — Fossil</a></li> <li><a href="newrepo.wiki">Create A New Fossil Repository — How To</a></li> <li><a href="private.wiki">Creating, Syncing, and Deleting Private Branches</a></li> <li><a href="qandc.wiki">Criticisms — Questions And</a></li> <li><a href="customskin.md">Customizing The Appearance of Web Pages — Theming:</a></li> <li><a href="custom_ticket.wiki">Customizing The Ticket System</a></li> <li><a href="customgraph.md">Customizing the Timeline Graph — Theming:</a></li> <li><a href="tech_overview.wiki">Databases Used By Fossil — SQLite</a></li> <li><a href="antibot.wiki">Defense against Spiders and Bots</a></li> <li><a href="shunning.wiki">Deleting Content From Fossil — Shunning:</a></li> <li><a href="private.wiki">Deleting Private Branches — Creating, Syncing, and</a></li> <li><a href="delta_encoder_algorithm.wiki">Delta Encoding Algorithm — Fossil</a></li> <li><a href="delta_format.wiki">Delta Format — Fossil</a></li> <li><a href="tech_overview.wiki">Design And Implementation Of Fossil — A Technical Overview Of The</a></li> |
| ︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 102 103 104 105 106 | <li><a href="faq.wiki">Frequently Asked Questions</a></li> <li><a href="shunning.wiki">From Fossil — Shunning: Deleting Content</a></li> <li><a href="inout.wiki">From Git — Import And Export To And</a></li> <li><a href="quotes.wiki">General — Quotes: What People Are Saying About Fossil, Git, and DVCSes in</a></li> <li><a href="fossil-v-git.wiki">Git — Fossil Versus</a></li> <li><a href="inout.wiki">Git — Import And Export To And From</a></li> <li><a href="quotes.wiki">Git, and DVCSes in General — Quotes: What People Are Saying About Fossil,</a></li> <li><a href="quickstart.wiki">Guide — Fossil Quick Start</a></li> <li><a href="style.wiki">Guidelines — Source Code Style</a></li> <li><a href="hacker-howto.wiki">Hacker How-To</a></li> <li><a href="adding_code.wiki">Hacking Fossil</a></li> <li><a href="hints.wiki">Hints — Fossil Tips And Usage</a></li> <li><a href="index.wiki">Home Page</a></li> <li><a href="selfhost.wiki">Hosting Repositories — Fossil Self</a></li> | > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | <li><a href="faq.wiki">Frequently Asked Questions</a></li> <li><a href="shunning.wiki">From Fossil — Shunning: Deleting Content</a></li> <li><a href="inout.wiki">From Git — Import And Export To And</a></li> <li><a href="quotes.wiki">General — Quotes: What People Are Saying About Fossil, Git, and DVCSes in</a></li> <li><a href="fossil-v-git.wiki">Git — Fossil Versus</a></li> <li><a href="inout.wiki">Git — Import And Export To And From</a></li> <li><a href="quotes.wiki">Git, and DVCSes in General — Quotes: What People Are Saying About Fossil,</a></li> <li><a href="customgraph.md">Graph — Theming: Customizing the Timeline</a></li> <li><a href="quickstart.wiki">Guide — Fossil Quick Start</a></li> <li><a href="style.wiki">Guidelines — Source Code Style</a></li> <li><a href="hacker-howto.wiki">Hacker How-To</a></li> <li><a href="adding_code.wiki">Hacking Fossil</a></li> <li><a href="hints.wiki">Hints — Fossil Tips And Usage</a></li> <li><a href="index.wiki">Home Page</a></li> <li><a href="selfhost.wiki">Hosting Repositories — Fossil Self</a></li> |
| ︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> <li><a href="makefile.wiki">The Fossil Build Process</a></li> <li><a href="sync.wiki">The Fossil Sync Protocol</a></li> <li><a href="tickets.wiki">The Fossil Ticket System</a></li> <li><a href="webui.wiki">The Fossil Web Interface</a></li> <li><a href="th1.md">The TH1 Scripting Language</a></li> <li><a href="customskin.md">Theming: Customizing The Appearance of Web Pages</a></li> <li><a href="theory1.wiki">Thoughts On The Design Of The Fossil DVCS</a></li> <li><a href="custom_ticket.wiki">Ticket System — Customizing The</a></li> <li><a href="tickets.wiki">Ticket System — The Fossil</a></li> <li><a href="hints.wiki">Tips And Usage Hints — Fossil</a></li> <li><a href="bugtheory.wiki">Tracking In Fossil — Bug</a></li> <li><a href="fiveminutes.wiki">Update and Running in 5 Minutes as a Single User</a></li> <li><a href="hints.wiki">Usage Hints — Fossil Tips And</a></li> <li><a href="fiveminutes.wiki">User — Update and Running in 5 Minutes as a Single</a></li> <li><a href="ssl.wiki">Using SSL with Fossil</a></li> <li><a href="checkin_names.wiki">Version Names — Check-in And</a></li> | > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | <li><a href="th1.md">TH1 Scripting Language — The</a></li> <li><a href="makefile.wiki">The Fossil Build Process</a></li> <li><a href="sync.wiki">The Fossil Sync Protocol</a></li> <li><a href="tickets.wiki">The Fossil Ticket System</a></li> <li><a href="webui.wiki">The Fossil Web Interface</a></li> <li><a href="th1.md">The TH1 Scripting Language</a></li> <li><a href="customskin.md">Theming: Customizing The Appearance of Web Pages</a></li> <li><a href="customgraph.md">Theming: Customizing the Timeline Graph</a></li> <li><a href="theory1.wiki">Thoughts On The Design Of The Fossil DVCS</a></li> <li><a href="custom_ticket.wiki">Ticket System — Customizing The</a></li> <li><a href="tickets.wiki">Ticket System — The Fossil</a></li> <li><a href="customgraph.md">Timeline Graph — Theming: Customizing the</a></li> <li><a href="hints.wiki">Tips And Usage Hints — Fossil</a></li> <li><a href="bugtheory.wiki">Tracking In Fossil — Bug</a></li> <li><a href="fiveminutes.wiki">Update and Running in 5 Minutes as a Single User</a></li> <li><a href="hints.wiki">Usage Hints — Fossil Tips And</a></li> <li><a href="fiveminutes.wiki">User — Update and Running in 5 Minutes as a Single</a></li> <li><a href="ssl.wiki">Using SSL with Fossil</a></li> <li><a href="checkin_names.wiki">Version Names — Check-in And</a></li> |
| ︙ | ︙ |
Changes to www/th1.md.
1 2 3 4 5 6 7 8 9 | TH1 Scripts =========== TH1 is a very small scripting language used to help generate web-page content in Fossil. Origins ------- | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | TH1 Scripts =========== TH1 is a very small scripting language used to help generate web-page content in Fossil. Origins ------- TH1 began as a minimalist re-implementation of the Tcl scripting language. There was a need to test the SQLite library on Symbian phones, but at that time all of the test cases for SQLite were written in Tcl and Tcl could not be easily compiled on the SymbianOS. So TH1 was developed as a cut-down version of Tcl that would facilitate running the SQLite test scripts on SymbianOS. The testing of SQLite on SymbianOS was eventually accomplished by other means. But Fossil was first being designed at about the same time. Early prototypes of Fossil were written in pure Tcl. But as the development shifted toward the use of C-code, the need arose to have a Tcl-like scripting language to help with code generation. TH1 was small and light-weight and used minimal resources and seemed ideally suited for the task. The name "TH1" stands "Test Harness 1", since that was its original purpose. Overview -------- |
| ︙ | ︙ | |||
76 77 78 79 80 81 82 | So, you see, even though the example above spans five lines, it is really just a single command. Summary of Core TH1 Commands ---------------------------- | | > > | | < > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 |
So, you see, even though the example above spans five lines, it is really
just a single command.
Summary of Core TH1 Commands
----------------------------
The original Tcl language after when TH1 is modeled has a very rich
repertoire of commands. TH1, as it is designed to be minimalist and
embedded has a greatly reduced command set. The following bullets
summarize the commands available in TH1:
* break
* catch SCRIPT ?VARIABLE?
* continue
* error ?STRING?
* expr EXPR
* for INIT-SCRIPT TEST-EXPR NEXT-SCRIPT BODY-SCRIPT
* if EXPR SCRIPT (elseif EXPR SCRIPT)* ?else SCRIPT?
* info commands
* info exists VARNAME
* info vars
* lindex LIST INDEX
* list ARG ...
* llength LIST
* proc NAME ARG-LIST BODY-SCRIPT
* rename OLD NEW
* return ?-code CODE? ?VALUE?
* set VARNAME VALUE
* string compare STR1 STR2
* string first NEEDLE HAYSTACK ?START-INDEX?
* string is CLASS STRING
* string last NEEDLE HAYSTACK ?START-INDEX?
* string length STRING
* string range STRING FIRST LAST
* string repeat STRING COUNT
* unset VARNAME
* uplevel ?LEVEL? SCRIPT
* upvar ?FRAME? OTHERVAR MYVAR ?OTHERVAR MYVAR?
All of the above commands works as in the original Tcl. Refer to the
Tcl documentation for details.
TH1 Extended Commands
---------------------
There are many new commands added to TH1 and used to access the special
features of Fossil. The following is a summary of the extended commands:
* anoncap
* anycap
* artifact
* checkout
* combobox
* date
* decorate
* enable_output
* getParameter
* globalState
* hascap
* hasfeature
* html
* htmlize
* http
* httpize
* linecount
* puts
* query
* randhex
* regexp
* reinitialize
* render
* repository
* searchable
* setParameter
* setting
* styleHeader
* styleFooter
* tclEval
* tclExpr
* tclInvoke
* tclReady
* trace
* stime
* utime
* wiki
Each of the commands above is documented by a block comment above their
implementation in the th\_main.c or th\_tcl.c source files.
All commands starting with "tcl", with the exception of "tclReady",
require the Tcl integration subsystem be included at compile-time.
Additionally, the "tcl" repository setting must be enabled at runtime
in order to successfully make use of these commands.
<a name="anoncap"></a>TH1 anoncap Command
-----------------------------------------
* anoncap STRING...
Returns true if the anonymous user has all of the capabilities listed
in STRING.
<a name="anycap"></a>TH1 anycap Command
---------------------------------------
* anycap STRING
Returns true if the current user user has any one of the capabilities
listed in STRING.
<a name="artifact"></a>TH1 artifact Command
-------------------------------------------
* artifact ID ?FILENAME?
Attempts to locate the specified artifact and return its contents. An
error is generated if the repository is not open or the artifact cannot
be found.
<a name="checkout"></a>TH1 checkout Command
-------------------------------------------
* checkout ?BOOLEAN?
Return the fully qualified directory name of the current checkout or an
empty string if it is not available. Optionally, it will attempt to find
the current checkout, opening the configuration ("user") database and the
repository as necessary, if the boolean argument is non-zero.
<a name="combobox"></a>TH1 combobox Command
-------------------------------------------
* combobox NAME TEXT-LIST NUMLINES
Generates and emits an HTML combobox. NAME is both the name of the
CGI parameter and the name of a variable that contains the currently
selected value. TEXT-LIST is a list of possible values for the
combobox. NUMLINES is 1 for a true combobox. If NUMLINES is greater
than one then the display is a listbox with the number of lines given.
<a name="date"></a>TH1 date Command
-----------------------------------
* date ?-local?
Return a strings which is the current time and date. If the -local
option is used, the date appears using localtime instead of UTC.
<a name="decorate"></a>TH1 decorate Command
-------------------------------------------
* decorate STRING
Renders STRING as wiki content; however, only links are handled. No
other markup is processed.
<a name="enable_output"></a>TH1 enable_output Command
-----------------------------------------------------
* enable_output BOOLEAN
Enable or disable sending output when the combobox, puts, or wiki
commands are used.
<a name="getParameter"></a>TH1 getParameter Command
---------------------------------------------------
* getParameter NAME ?DEFAULT?
Returns the value of the specified query parameter or the specified
default value when there is no matching query parameter.
<a name="globalState"></a>TH1 globalState Command
-------------------------------------------------
* globalState NAME ?DEFAULT?
Returns a string containing the value of the specified global state
variable -OR- the specified default value. The supported items are:
1. **checkout** -- _Active local checkout directory, if any._
1. **configuration** -- _Active configuration database file name, if any._
1. **executable** -- _Fully qualified executable file name._
1. **flags** -- _TH1 initialization flags._
1. **log** -- _Error log file name, if any._
1. **repository** -- _Active local repository file name, if any._
1. **top** -- _Base path for the active server instance, if applicable._
1. **user** -- _Active user name, if any._
1. **vfs** -- _SQLite VFS in use, if overridden._
Attempts to query for unsupported global state variables will result
in a script error. Additional global state variables may be exposed
in the future.
<a name="hascap"></a>TH1 hascap Command
---------------------------------------
* hascap STRING...
Returns true if the current user has all of the capabilities listed
in STRING.
<a name="hasfeature"></a>TH1 hasfeature Command
-----------------------------------------------
* hasfeature STRING
Returns true if the binary has the given compile-time feature enabled.
The possible features are:
1. **ssl** -- _Support for the HTTPS transport._
1. **legacyMvRm** -- _Support for legacy mv/rm command behavior._
1. **th1Docs** -- _Support for TH1 in embedded documentation._
1. **th1Hooks** -- _Support for TH1 command and web page hooks._
1. **tcl** -- _Support for Tcl integration._
1. **useTclStubs** -- _Tcl stubs enabled in the Tcl headers._
1. **tclStubs** -- _Uses Tcl stubs (i.e. linking with stubs library)._
1. **tclPrivateStubs** -- _Uses Tcl private stubs (i.e. header-only)._
1. **json** -- _Support for the JSON APIs._
1. **markdown** -- _Support for Markdown documentation format._
1. **unicodeCmdLine** -- _The command line arguments are Unicode._
<a name="html"></a>TH1 html Command
-----------------------------------
* html STRING
Outputs the STRING escaped for HTML.
<a name="htmlize"></a>TH1 htmlize Command
-----------------------------------------
* htmlize STRING
Escape all characters of STRING which have special meaning in HTML.
Returns the escaped string.
<a name="http"></a>TH1 http Command
-----------------------------------
* http ?-asynchronous? ?--? url ?payload?
Performs an HTTP or HTTPS request for the specified URL. If a
payload is present, it will be interpreted as text/plain and
the POST method will be used; otherwise, the GET method will
be used. Upon success, if the -asynchronous option is used, an
empty string is returned as the result; otherwise, the response
from the server is returned as the result. Synchronous requests
are not currently implemented.
<a name="httpize"></a>TH1 httpize Command
-----------------------------------------
* httpize STRING
Escape all characters of STRING which have special meaning in URI
components. Returns the escaped string.
<a name="linecount"></a>TH1 linecount Command
---------------------------------------------
* linecount STRING MAX MIN
Returns one more than the number of \n characters in STRING. But
never returns less than MIN or more than MAX.
<a name="puts"></a>TH1 puts Command
-----------------------------------
* puts STRING
Outputs the STRING unchanged.
<a name="query"></a>TH1 query Command
-------------------------------------
* query SQL CODE
Runs the SQL query given by the SQL argument. For each row in the result
set, run CODE.
In SQL, parameters such as $var are filled in using the value of variable
"var". Result values are stored in variables with the column name prior
to each invocation of CODE.
<a name="randhex"></a>TH1 randhex Command
-----------------------------------------
* randhex N
Returns a string of N*2 random hexadecimal digits with N<50. If N is
omitted, use a value of 10.
<a name="regexp"></a>TH1 regexp Command
---------------------------------------
* regexp ?-nocase? ?--? exp string
Checks the string against the specified regular expression and returns
non-zero if it matches. If the regular expression is invalid or cannot
be compiled, an error will be generated.
<a name="reinitialize"></a>TH1 reinitialize Command
---------------------------------------------------
* reinitialize ?FLAGS?
Reinitializes the TH1 interpreter using the specified flags.
<a name="render"></a>TH1 render Command
---------------------------------------
* render STRING
Renders the TH1 template and writes the results.
<a name="repository"></a>TH1 repository Command
-----------------------------------------------
* repository ?BOOLEAN?
Returns the fully qualified file name of the open repository or an empty
string if one is not currently open. Optionally, it will attempt to open
the repository if the boolean argument is non-zero.
<a name="searchable"></a>TH1 searchable Command
-----------------------------------------------
* searchable STRING...
Return true if searching in any of the document classes identified
by STRING is enabled for the repository and user has the necessary
capabilities to perform the search. The possible document classes
are:
1. **c** -- _Check-in comments_
1. **d** -- _Embedded documentation_
1. **t** -- _Tickets_
1. **w** -- _Wiki_
To be clear, only one of the document classes identified by each STRING
needs to be searchable in order for that argument to be true. But all
arguments must be true for this routine to return true. Hence, to see
if ALL document classes are searchable:
if {[searchable c d t w]} {...}
But to see if ANY document class is searchable:
if {[searchable cdtw]} {...}
This command is useful for enabling or disabling a "Search" entry on the
menu bar.
<a name="setParameter"></a>TH1 setParameter Command
---------------------------------------------------
* setParameter NAME VALUE
Sets the value of the specified query parameter.
<a name="setting"></a>TH1 setting Command
-----------------------------------------
* setting name
Gets and returns the value of the specified setting.
<a name="styleHeader"></a>TH1 styleHeader Command
-------------------------------------------------
* styleHeader TITLE
Render the configured style header.
<a name="styleFooter"></a>TH1 styleFooter Command
-------------------------------------------------
* styleFooter
Render the configured style footer.
<a name="tclEval"></a>TH1 tclEval Command
-----------------------------------------
**This command requires the Tcl integration feature.**
* tclEval arg ?arg ...?
Evaluates the Tcl script and returns its result verbatim. If a Tcl script
error is generated, it will be transformed into a TH1 script error. A Tcl
interpreter will be created automatically if it has not been already.
<a name="tclExpr"></a>TH1 tclExpr Command
-----------------------------------------
**This command requires the Tcl integration feature.**
* tclExpr arg ?arg ...?
Evaluates the Tcl expression and returns its result verbatim. If a Tcl
script error is generated, it will be transformed into a TH1 script error.
A Tcl interpreter will be created automatically if it has not been already.
<a name="tclInvoke"></a>TH1 tclInvoke Command
---------------------------------------------
**This command requires the Tcl integration feature.**
* tclInvoke command ?arg ...?
Invokes the Tcl command using the supplied arguments. No additional
substitutions are performed on the arguments. A Tcl interpreter will
be created automatically if it has not been already.
<a name="tclReady"></a>TH1 tclReady Command
-------------------------------------------
* tclReady
Returns true if the binary has the Tcl integration feature enabled and it
is currently available for use by TH1 scripts.
<a name="trace"></a>TH1 trace Command
-------------------------------------
* trace STRING
Generates a TH1 trace message if TH1 tracing is enabled.
<a name="stime"></a>TH1 stime Command
-------------------------------------
* stime
Returns the number of microseconds of CPU time consumed by the current
process in system space.
<a name="utime"></a>TH1 utime Command
-------------------------------------
* utime
Returns the number of microseconds of CPU time consumed by the current
process in user space.
<a name="wiki"></a>TH1 wiki Command
-----------------------------------
* wiki STRING
Renders STRING as wiki content.
Tcl Integration Commands
------------------------
When the Tcl integration subsystem is enabled, several commands are added
to the Tcl interpreter. They are used to allow Tcl scripts access to the
Fossil functionality provided via TH1. The following is a summary of the
Tcl commands:
* th1Eval
* th1Expr
<a name="th1Eval"></a>Tcl th1Eval Command
-----------------------------------------
**This command requires the Tcl integration feature.**
* th1Eval arg
Evaluates the TH1 script and returns its result verbatim. If a TH1 script
error is generated, it will be transformed into a Tcl script error.
<a name="th1Expr"></a>Tcl th1Expr Command
-----------------------------------------
**This command requires the Tcl integration feature.**
* th1Expr arg
Evaluates the TH1 expression and returns its result verbatim. If a TH1
script error is generated, it will be transformed into a Tcl script error.
Further Notes
-------------
**To Do:** We would like to have a community volunteer go through and
copy the documentation for each of these commands (with appropriate
format changes and spelling and grammar corrections) into subsequent
sections of this document. It is suggested that the list of extension
commands be left intact - as a quick reference. But it would be really
nice to also have the details of what each command does.
|