Fossil SCM
merge trunk
Commit
5589ebbd6188aa0554360fad5b7a3a7a5d6f12fa
Parent
69491bb45ed3ffb…
30 files changed
+2
-2
+307
+4
-4
+44
-1
+44
-1
+4
-4
+1
-3
-1
+6
-1
+36
+3
+9
-2
+265
-35
+2
+1
+10
-5
+2
-2
+3
-3
+41
-13
+21
-20
+263
-156
+121
-97
+2
-2
+1
-1
+47
-16
+22
-4
+41
+30
+21
~
src/branch.c
~
src/bundle.c
~
src/content.c
~
src/db.c
~
src/db.c
~
src/descendants.c
~
src/finfo.c
~
src/foci.c
~
src/fusefs.c
~
src/info.c
~
src/main.mk
~
src/makemake.tcl
~
src/mkversion.c
~
src/name.c
~
src/publish.c
~
src/purge.c
~
src/rebuild.c
~
src/schema.c
~
src/setup.c
~
src/shun.c
~
src/sqlcmd.c
~
src/sqlite3.c
~
src/sqlite3.h
~
src/stat.c
~
src/tag.c
~
src/timeline.c
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.msc
~
www/checkin_names.wiki
+2
-2
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -357,11 +357,11 @@ | ||
| 357 | 357 | if( colorTest ){ |
| 358 | 358 | const char *zColor = hash_color(zBr); |
| 359 | 359 | @ <li><span style="background-color: %s(zColor)"> |
| 360 | 360 | @ %h(zBr) → %s(zColor)</span></li> |
| 361 | 361 | }else{ |
| 362 | - @ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li> | |
| 362 | + @ <li>%z(href("%R/timeline?r=%T&n=200",zBr))%h(zBr)</a></li> | |
| 363 | 363 | } |
| 364 | 364 | } |
| 365 | 365 | if( cnt ){ |
| 366 | 366 | @ </ul> |
| 367 | 367 | } |
| @@ -385,11 +385,11 @@ | ||
| 385 | 385 | " AND tag.tagname GLOB 'sym-*'", |
| 386 | 386 | rid |
| 387 | 387 | ); |
| 388 | 388 | while( db_step(&q)==SQLITE_ROW ){ |
| 389 | 389 | const char *zTagName = db_column_text(&q, 0); |
| 390 | - @ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a> | |
| 390 | + @ %z(href("%R/timeline?r=%T&n=200",zTagName))[timeline]</a> | |
| 391 | 391 | } |
| 392 | 392 | db_finalize(&q); |
| 393 | 393 | } |
| 394 | 394 | |
| 395 | 395 | /* |
| 396 | 396 | |
| 397 | 397 | ADDED src/bundle.c |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -357,11 +357,11 @@ | |
| 357 | if( colorTest ){ |
| 358 | const char *zColor = hash_color(zBr); |
| 359 | @ <li><span style="background-color: %s(zColor)"> |
| 360 | @ %h(zBr) → %s(zColor)</span></li> |
| 361 | }else{ |
| 362 | @ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li> |
| 363 | } |
| 364 | } |
| 365 | if( cnt ){ |
| 366 | @ </ul> |
| 367 | } |
| @@ -385,11 +385,11 @@ | |
| 385 | " AND tag.tagname GLOB 'sym-*'", |
| 386 | rid |
| 387 | ); |
| 388 | while( db_step(&q)==SQLITE_ROW ){ |
| 389 | const char *zTagName = db_column_text(&q, 0); |
| 390 | @ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a> |
| 391 | } |
| 392 | db_finalize(&q); |
| 393 | } |
| 394 | |
| 395 | /* |
| 396 | |
| 397 | DDED src/bundle.c |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -357,11 +357,11 @@ | |
| 357 | if( colorTest ){ |
| 358 | const char *zColor = hash_color(zBr); |
| 359 | @ <li><span style="background-color: %s(zColor)"> |
| 360 | @ %h(zBr) → %s(zColor)</span></li> |
| 361 | }else{ |
| 362 | @ <li>%z(href("%R/timeline?r=%T&n=200",zBr))%h(zBr)</a></li> |
| 363 | } |
| 364 | } |
| 365 | if( cnt ){ |
| 366 | @ </ul> |
| 367 | } |
| @@ -385,11 +385,11 @@ | |
| 385 | " AND tag.tagname GLOB 'sym-*'", |
| 386 | rid |
| 387 | ); |
| 388 | while( db_step(&q)==SQLITE_ROW ){ |
| 389 | const char *zTagName = db_column_text(&q, 0); |
| 390 | @ %z(href("%R/timeline?r=%T&n=200",zTagName))[timeline]</a> |
| 391 | } |
| 392 | db_finalize(&q); |
| 393 | } |
| 394 | |
| 395 | /* |
| 396 | |
| 397 | DDED src/bundle.c |
+307
| --- a/src/bundle.c | ||
| +++ b/src/bundle.c | ||
| @@ -0,0 +1,307 @@ | ||
| 1 | +/* | |
| 2 | +** Copyright (==40** Copyright (c) 2014 D/* | |
| 3 | +** Copyright (c) 2014 D. Richard Hipp | |
| 4 | +** | |
| 5 | +** This program is free software; you can redistribute it and/or | |
| 6 | +** modify it under the terms of the Simplified BSD License (also | |
| 7 | +** known as the "2-Clause License" or "FreeBSD License".) | |
| 8 | + | |
| 9 | +** This program is distributed in the hope that it will be useful, | |
| 10 | +** but without any warranty; without even the implied warranty of | |
| 11 | +** merchantability or fitness for a particular purpose. | |
| 12 | +** | |
| 13 | +** Author contact information: | |
| 14 | +** [email protected] | |
| 15 | +** http://www.hwaci.com/drh/ | |
| 16 | +** | |
| 17 | +******************************************************************************* | |
| 18 | +** | |
| 19 | +** This file contains code used to implement and manage a "bundle" file. | |
| 20 | +*/ | |
| 21 | +#include "config.h" | |
| 22 | +#include "bundle.h" | |
| 23 | +#include <assert.h> | |
| 24 | + | |
| 25 | +/* | |
| 26 | +** SQL code used to initialize the schema of a bundle. | |
| 27 | +** | |
| 28 | +** The bblob.delta field can be an integer, a text string, or NULL. | |
| 29 | +** If an integer, then the corresponding blobid is the delta basis. | |
| 30 | +** If a text string, then that string is a SHA1 hash for the delta | |
| 31 | +** basis, whister is ainory. If NULL, then | |
| 32 | +** data contains content without delta compression. | |
| 33 | +*/ | |
| 34 | +static const cha r zBundleInit[] = | |
| 35 | +@ CREATE TABLE IF NOT EXISTS "%w".bconfig( | |
| 36 | +@ bcname TEXT, | |
| 37 | +@ bcvalue ANY | |
| 38 | +@ ); | |
| 39 | +@ CREATE TABLE IF NOT EXISTS "%w".bblob( | |
| 40 | +@ blobid INTEGER PRIMARY KEY, -- Blob ID | |
| 41 | +@ uuid TEXT SHA1 NOT NULL, -- hash of expanded blob | |
| 42 | +@ sz INT NOT NULL, -- Size of blob after expansion | |
| 43 | +@ delta ANY, -- Delta compression basis, or NULL | |
| 44 | +@ notes TEXT, -- Description of content | |
| 45 | +@ data BLOB -- compressed content | |
| 46 | +@ ); | |
| 47 | +; | |
| 48 | + | |
| 49 | +/* | |
| 50 | +** Attach a bundle file to the current database connection using the | |
| 51 | +** attachment name zBName. | |
| 52 | +*/ | |
| 53 | +static void bundle_attach_file( | |
| 54 | + const char *zFile, /* Name of the file that contains the bundle */ | |
| 55 | + const char *zBName, /* Attachment name */ | |
| 56 | + int doInit /* Initialize a new bundle, if true */ | |
| 57 | +){ | |
| 58 | + int rc; | |
| 59 | + char *zErrMsg = 0; | |
| 60 | + char *zSql; | |
| 61 | + if( )<0 ){blob.rid=tobundle.rid" | |
| 62 | + _size(zFile, ExtFILE)<0 ){ | |
| 63 | + fossil_fatal("no such file: %s", zFile); | |
| 64 | + } | |
| 65 | + assert( g.db ); | |
| 66 | + zSql = sqlite3_mprintf("ATTAfatalhat string is a SHA1 c = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); | |
| 67 | + sqlite3_free(zSql); | |
| 68 | + if( rc!=SQLITE_OK || zErrMsg ){ | |
| 69 | + if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); | |
| 70 | + fossil_fatal("not a valid bundle: %s", zFile); | |
| 71 | + } | |
| 72 | + if( doInit ){ | |
| 73 | + db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); | |
| 74 | + }else{ | |
| 75 | + sqlite3_stmt *pStmt; | |
| 76 | + zSql = sqlite3_mprintf("SELECT bcname, bcvalue" | |
| 77 | + " FROM \"%w\".bconfig", zBName);panic that string is a SHA1fatalhat string is a SHA1 hash for the delta | |
| 78 | +** basis, whister is presumably in the main repository. If NULL, then | |
| 79 | +** data contains content without delta compression. | |
| 80 | +*/ | |
| 81 | +static const char zBundleInit[] = | |
| 82 | +@ CREATE TABLE IF NOT EXISTS "%w".bconfig( | |
| 83 | +@ bcname TEXT, | |
| 84 | +@ bcvalue ANY | |
| 85 | +@ ); | |
| 86 | +@ CREATE TABLE IF NOT EXISTS "%w".bblob( | |
| 87 | +@ blobid INTEGER Pfatalhat string is a SHA1 hash for the delta | |
| 88 | +** basis, whister is presumably in the main repository. If NULL, then | |
| 89 | +** data contains content without delta compressio} | |
| 90 | +} | |
| 91 | + | |
| 92 | +/* | |
| 93 | +**sociates("ok", 1); | |
| 94 | + | |
| 95 | + /* NULL | |
| 96 | +@ notes TEXT, -- Description of content | |
| 97 | +@ data BLOB -- compressed content | |
| 98 | +@ ); | |
| 99 | +; | |
| 100 | + | |
| 101 | +/* | |
| 102 | +** Attac ter is presumably iHipp | |
| 103 | +** | |
| 104 | +** This program is free software; you can redistribute it and/or | |
| 105 | +** modify it under the terms of the Simplified BSD License (also | |
| 106 | +** known as the "2-Clause License" or "FreeBSD License".) | |
| 107 | + | |
| 108 | +** This program is distributed in the hope that it will be useful, | |
| 109 | +** but without any warranty; without even the implied warranty of | |
| 110 | +** merchantability or fitness for a particular purpose. | |
| 111 | +** | |
| 112 | +** Author contact information: | |
| 113 | +** [email protected] | |
| 114 | +** http://www.hwaci.com/drh/ | |
| 115 | +** | |
| 116 | +******************************************************************************* | |
| 117 | +** | |
| 118 | +** This file contains code used to implement and manage a "bundle" file. | |
| 119 | +*/ | |
| 120 | +#include "config.h" | |
| 121 | +#include "bundle.h" | |
| 122 | +#include <assert.h> | |
| 123 | + | |
| 124 | +/* | |
| 125 | +** SQL code used to initialize the schema of a bundle. | |
| 126 | +** | |
| 127 | +** The bblob.delta field can be an integer, a text string, or NULL. | |
| 128 | +** If an integer, then the corresponding blobid is the delta basis. | |
| 129 | +** If a text string, then that string is a SHA1 hash for the delta | |
| 130 | +** basis, whister is ainory. If NULL, then | |
| 131 | +** data contains content without delta compression. | |
| 132 | +*/ | |
| 133 | +static const char zBundleInit[] = | |
| 134 | +@ CREATE TABLE IF NOT EXISTS "%w/mpressed content | |
| 135 | +@ ); | |
| 136 | +; | |
| 137 | + | |
| 138 | +/* | |
| 139 | +** Attach a bundle file to the current database connection using the | |
| 140 | +** attachment name zBName. | |
| 141 | +*/ | |
| 142 | +static void bundle_attach_file( | |
| 143 | + const char *zFile, /* Name of the file that contains the bundle */ | |
| 144 | + const char *zBName, /* Attachment name */ | |
| 145 | + int doInit /* Initialize a new bundle, if true */ | |
| 146 | +){ | |
| 147 | + int rc; | |
| 148 | + char *zErrMsg = 0; | |
| 149 | + char *zSql; | |
| 150 | + if( )<0 ){blob.rid=tobundle.rid" | |
| 151 | + _size(zFile, ExtFILE)<0 ){ | |
| 152 | + fossil_fatal("no such file: %s", zFile); | |
| 153 | + } | |
| 154 | + assert( g.db ); | |
| 155 | + zSql = sqlite3_mprintf("ATTAfatalhat string is a SHA1 c = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); | |
| 156 | + sqlite3_free(zSql); | |
| 157 | + if( rc!=SQLITE_OK || zErrMsg ){ | |
| 158 | + if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); | |
| 159 | + fossil_fatal("not a valid bundle: %s", zFile); | |
| 160 | + } | |
| 161 | + if( doInit ){ | |
| 162 | + db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); | |
| 163 | + }else{ | |
| 164 | + sqlite3_stmt *pStmt; | |
| 165 | + zSql = sqlite3_mprintf("SELECT bcname, bcvalue" | |
| 166 | + " FROM \"%w\".bconfig", zBName);panic that string is a SHA1fatalhat string is a SHA1 hash for the delta | |
| 167 | +** basis, whister is presumably in the main repository. If NULL, then | |
| 168 | +** data contains content without delta compression. | |
| 169 | +*/ | |
| 170 | +statc const char zBundleInit[] = | |
| 171 | +@ CREATE TABLE IF NOT EXISTS "%w".bconfig( | |
| 172 | +@ bcname TEXT, | |
| 173 | +@ bcvalue ANY | |
| 174 | +@ ); | |
| 175 | +@ CREATE TABLE IF NOT EXISTS "% Pfatalhat string is a SHA1 hash for the delta | |
| 176 | +** basis, whister is presumably in the main reposa contains content without delta compressio} | |
| 177 | +} | |
| 178 | + | |
| 179 | +/* | |
| 180 | +**sociates("ok", 1); | |
| 181 | + | |
| 182 | + /* NULL | |
| 183 | +@ notes TEXT, -- Description of ontent | |
| 184 | +@ data BLOB content | |
| 185 | +@ ); | |
| 186 | +; | |
| 187 | + | |
| 188 | +/* | |
| 189 | +** Attach a bundle file to the current database connection using the | |
| 190 | +** attachment name zBName. | |
| 191 | +*/ | |
| 192 | +static void bundle_attach_file( | |
| 193 | + const char *zFile, /* Name of the file that contains the bundle */ | |
| 194 | + const char *zBName, */ | |
| 195 | +){ | |
| 196 | + int rc; | |
| 197 | + char *zErrMsg = 0; | |
| 198 | + char *zSql; | |
| 199 | + if( !doInit && file_size(zFile, ExtFILE)<0 ){ | |
| 200 | + fossil_fatal("no such file: %s", zFile); | |
| 201 | + } | |
| 202 | + assert( g.db ); | |
| 203 | + zSql = sqlite3_mprintf("ATTACH %Q AS %Q", zFile, zBName); | |
| 204 | + if( zSql==0 ) fossil_fatal("out of memory"); | |
| 205 | + rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); | |
| 206 | + sqlite3_free(zSql); | |
| 207 | + if( rc!=SQLITE_OK || zErrMsg ){ | |
| 208 | + if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); | |
| 209 | + fossil_fatal("not a valid bundle: %s", zFile); | |
| 210 | + } | |
| 211 | + if( doInit ){ | |
| 212 | + db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); | |
| 213 | + }else{ | |
| 214 | + sqlite3_stmt *pStmt; | |
| 215 | + zSql = sqlite3_mprintf("SELECT bcname, bcvalue" | |
| 216 | + " FROM \"%w\".bconfig", zBName); | |
| 217 | + if( zSql==0 ) fossil_fatal("out of memory"); | |
| 218 | + rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, 0); | |
| 219 | + if( rc ) fossil_fatal("not a valid bundle: %s", zFile); | |
| 220 | + sqlite3_free(zSql); | |
| 221 | + sqlite3_finalize(pStmt); | |
| 222 | + zSql = sqlite3_mprintf("SELECT blobid, uuid, | |
| 223 | +**makesright (==40** Copyright (c) 2014 D/* | |
| 224 | +** Copyright (c) 2014 D. Richard Hipp | |
| 225 | +** | |
| 226 | +** This program is free software; you can redistribute it and/or | |
| 227 | +** modify it under the terms of the Simplified BSD License (also | |
| 228 | +** known as the "2-Clause License" or "FreeBSD License".) | |
| 229 | + | |
| 230 | +** This program is distributed in the hope that it will be useful, | |
| 231 | +** but without any warranty; without even the implied warranty of | |
| 232 | +** merchantability or fitness for a particular purpose. | |
| 233 | +** | |
| 234 | +** Author contact information: | |
| 235 | +** [email protected] | |
| 236 | +** http://www.hwaci.com/drh/ | |
| 237 | +** | |
| 238 | +******************************************************************************* | |
| 239 | +** | |
| 240 | +** This file contains code used to implement and manage a "bundle" file. | |
| 241 | +*/ | |
| 242 | +#include "config.h" | |
| 243 | +#include "bundle.h" | |
| 244 | +#include <assert.h> | |
| 245 | + | |
| 246 | +/* | |
| 247 | +** SQe schema of a bundle. | |
| 248 | +** | |
| 249 | +** The bblob.delta field can be an integer, a text string, or NULL. | |
| 250 | +** If an integer, then the corresponding blobid is the delta basis. | |
| 251 | +** If a text string, then that string is a SHA1 hash for the delta | |
| 252 | +** basis, whister is presumably in the ain repository. If NULL, then | |
| 253 | +** data contains content without delta compression. | |
| 254 | +*/ | |
| 255 | +static const char zBundleInit[] = | |
| 256 | +@ CREATE TABLE IF NOT EXISTS "%w".bconfig(e ANY | |
| 257 | +@ ); | |
| 258 | +@ CREATE TABLE IF NOT EXISTS "%w".bblob( | |
| 259 | +@ blobid INTEGER PRIMARY KEY, -- Blob ID | |
| 260 | +@ uuid TEXT SHA1 NOT NULL, -- hash of expanded blob | |
| 261 | +@ sz INT NOT NULL, -- Size of blob after expansion | |
| 262 | +@ delta ANY, -- Delta compression basis, or NULL | |
| 263 | +@ notes TEXT, -- Description of content | |
| 264 | +@ data BLOB -- compressed content | |
| 265 | +@ ); | |
| 266 | +; | |
| 267 | + | |
| 268 | +/* | |
| 269 | +** Attach a bundle file to the current database connection using the | |
| 270 | +** attachment name zBName. | |
| 271 | +*/ | |
| 272 | +static void bundle_attach_file( | |
| 273 | + const char *zFile, /* Name of the file that contains the bundle */ | |
| 274 | + const char *zBName, /* Attachment name */ | |
| 275 | + int doInit /* Initialize a new bundle, if true */ | |
| 276 | +){ | |
| 277 | + int rc; | |
| 278 | + char *zErrMsg = 0; | |
| 279 | + char *zSql; | |
| 280 | + if( )<0 ){blob.rid=tobundle.rid" | |
| 281 | + _size(zFile, ExtFILE)<0 ){ | |
| 282 | + fossil_fatal("no such file: %s", zFile); | |
| 283 | + } | |
| 284 | + assert( g.db ); | |
| 285 | + zSql = sqlite3_mprintf("ATTAfatalhat string is a SHA1 c = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); | |
| 286 | + sqlite3_free(zSql); | |
| 287 | + if( rc!=SQLITE_OK || zErrMsg ){ | |
| 288 | + if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); | |
| 289 | + fossil_fatal("not a valid bundle: %s", zFile); | |
| 290 | + } | |
| 291 | + if( doInit ){ | |
| 292 | + db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); | |
| 293 | + }else{ | |
| 294 | + sqlite3_stmt *pStmt; | |
| 295 | + zSql = sqlite3_mprintf("SELECT bcname, bcvalue" | |
| 296 | + " FROM \"%w\".bconfig", zBName);panic that string is a SHA1fatalhat string is a SHA1 hash for the delta | |
| 297 | +** basis, whister is presumably in the main repository. If NULL, then | |
| 298 | +** data contains content without delta compression. | |
| 299 | +*/ | |
| 300 | +static const char zBundleInit[] = | |
| 301 | +@ CREATE TABLE IF NOT EXISTS "%w".bconfig( | |
| 302 | +@ bcname TEXT, | |
| 303 | +@ bcvalue ANY | |
| 304 | +@ ); | |
| 305 | +@ CREATE TABLE IF NOT EXISTS "%w".bblob( | |
| 306 | +@ blobid INTEGER Pfatalhat string is a SHA1 hash for the delta | |
| 307 | +** basis, whist ins |
| --- a/src/bundle.c | |
| +++ b/src/bundle.c | |
| @@ -0,0 +1,307 @@ | |
| --- a/src/bundle.c | |
| +++ b/src/bundle.c | |
| @@ -0,0 +1,307 @@ | |
| 1 | /* |
| 2 | ** Copyright (==40** Copyright (c) 2014 D/* |
| 3 | ** Copyright (c) 2014 D. Richard Hipp |
| 4 | ** |
| 5 | ** This program is free software; you can redistribute it and/or |
| 6 | ** modify it under the terms of the Simplified BSD License (also |
| 7 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 8 | |
| 9 | ** This program is distributed in the hope that it will be useful, |
| 10 | ** but without any warranty; without even the implied warranty of |
| 11 | ** merchantability or fitness for a particular purpose. |
| 12 | ** |
| 13 | ** Author contact information: |
| 14 | ** [email protected] |
| 15 | ** http://www.hwaci.com/drh/ |
| 16 | ** |
| 17 | ******************************************************************************* |
| 18 | ** |
| 19 | ** This file contains code used to implement and manage a "bundle" file. |
| 20 | */ |
| 21 | #include "config.h" |
| 22 | #include "bundle.h" |
| 23 | #include <assert.h> |
| 24 | |
| 25 | /* |
| 26 | ** SQL code used to initialize the schema of a bundle. |
| 27 | ** |
| 28 | ** The bblob.delta field can be an integer, a text string, or NULL. |
| 29 | ** If an integer, then the corresponding blobid is the delta basis. |
| 30 | ** If a text string, then that string is a SHA1 hash for the delta |
| 31 | ** basis, whister is ainory. If NULL, then |
| 32 | ** data contains content without delta compression. |
| 33 | */ |
| 34 | static const cha r zBundleInit[] = |
| 35 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 36 | @ bcname TEXT, |
| 37 | @ bcvalue ANY |
| 38 | @ ); |
| 39 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 40 | @ blobid INTEGER PRIMARY KEY, -- Blob ID |
| 41 | @ uuid TEXT SHA1 NOT NULL, -- hash of expanded blob |
| 42 | @ sz INT NOT NULL, -- Size of blob after expansion |
| 43 | @ delta ANY, -- Delta compression basis, or NULL |
| 44 | @ notes TEXT, -- Description of content |
| 45 | @ data BLOB -- compressed content |
| 46 | @ ); |
| 47 | ; |
| 48 | |
| 49 | /* |
| 50 | ** Attach a bundle file to the current database connection using the |
| 51 | ** attachment name zBName. |
| 52 | */ |
| 53 | static void bundle_attach_file( |
| 54 | const char *zFile, /* Name of the file that contains the bundle */ |
| 55 | const char *zBName, /* Attachment name */ |
| 56 | int doInit /* Initialize a new bundle, if true */ |
| 57 | ){ |
| 58 | int rc; |
| 59 | char *zErrMsg = 0; |
| 60 | char *zSql; |
| 61 | if( )<0 ){blob.rid=tobundle.rid" |
| 62 | _size(zFile, ExtFILE)<0 ){ |
| 63 | fossil_fatal("no such file: %s", zFile); |
| 64 | } |
| 65 | assert( g.db ); |
| 66 | zSql = sqlite3_mprintf("ATTAfatalhat string is a SHA1 c = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); |
| 67 | sqlite3_free(zSql); |
| 68 | if( rc!=SQLITE_OK || zErrMsg ){ |
| 69 | if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); |
| 70 | fossil_fatal("not a valid bundle: %s", zFile); |
| 71 | } |
| 72 | if( doInit ){ |
| 73 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 74 | }else{ |
| 75 | sqlite3_stmt *pStmt; |
| 76 | zSql = sqlite3_mprintf("SELECT bcname, bcvalue" |
| 77 | " FROM \"%w\".bconfig", zBName);panic that string is a SHA1fatalhat string is a SHA1 hash for the delta |
| 78 | ** basis, whister is presumably in the main repository. If NULL, then |
| 79 | ** data contains content without delta compression. |
| 80 | */ |
| 81 | static const char zBundleInit[] = |
| 82 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 83 | @ bcname TEXT, |
| 84 | @ bcvalue ANY |
| 85 | @ ); |
| 86 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 87 | @ blobid INTEGER Pfatalhat string is a SHA1 hash for the delta |
| 88 | ** basis, whister is presumably in the main repository. If NULL, then |
| 89 | ** data contains content without delta compressio} |
| 90 | } |
| 91 | |
| 92 | /* |
| 93 | **sociates("ok", 1); |
| 94 | |
| 95 | /* NULL |
| 96 | @ notes TEXT, -- Description of content |
| 97 | @ data BLOB -- compressed content |
| 98 | @ ); |
| 99 | ; |
| 100 | |
| 101 | /* |
| 102 | ** Attac ter is presumably iHipp |
| 103 | ** |
| 104 | ** This program is free software; you can redistribute it and/or |
| 105 | ** modify it under the terms of the Simplified BSD License (also |
| 106 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 107 | |
| 108 | ** This program is distributed in the hope that it will be useful, |
| 109 | ** but without any warranty; without even the implied warranty of |
| 110 | ** merchantability or fitness for a particular purpose. |
| 111 | ** |
| 112 | ** Author contact information: |
| 113 | ** [email protected] |
| 114 | ** http://www.hwaci.com/drh/ |
| 115 | ** |
| 116 | ******************************************************************************* |
| 117 | ** |
| 118 | ** This file contains code used to implement and manage a "bundle" file. |
| 119 | */ |
| 120 | #include "config.h" |
| 121 | #include "bundle.h" |
| 122 | #include <assert.h> |
| 123 | |
| 124 | /* |
| 125 | ** SQL code used to initialize the schema of a bundle. |
| 126 | ** |
| 127 | ** The bblob.delta field can be an integer, a text string, or NULL. |
| 128 | ** If an integer, then the corresponding blobid is the delta basis. |
| 129 | ** If a text string, then that string is a SHA1 hash for the delta |
| 130 | ** basis, whister is ainory. If NULL, then |
| 131 | ** data contains content without delta compression. |
| 132 | */ |
| 133 | static const char zBundleInit[] = |
| 134 | @ CREATE TABLE IF NOT EXISTS "%w/mpressed content |
| 135 | @ ); |
| 136 | ; |
| 137 | |
| 138 | /* |
| 139 | ** Attach a bundle file to the current database connection using the |
| 140 | ** attachment name zBName. |
| 141 | */ |
| 142 | static void bundle_attach_file( |
| 143 | const char *zFile, /* Name of the file that contains the bundle */ |
| 144 | const char *zBName, /* Attachment name */ |
| 145 | int doInit /* Initialize a new bundle, if true */ |
| 146 | ){ |
| 147 | int rc; |
| 148 | char *zErrMsg = 0; |
| 149 | char *zSql; |
| 150 | if( )<0 ){blob.rid=tobundle.rid" |
| 151 | _size(zFile, ExtFILE)<0 ){ |
| 152 | fossil_fatal("no such file: %s", zFile); |
| 153 | } |
| 154 | assert( g.db ); |
| 155 | zSql = sqlite3_mprintf("ATTAfatalhat string is a SHA1 c = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); |
| 156 | sqlite3_free(zSql); |
| 157 | if( rc!=SQLITE_OK || zErrMsg ){ |
| 158 | if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); |
| 159 | fossil_fatal("not a valid bundle: %s", zFile); |
| 160 | } |
| 161 | if( doInit ){ |
| 162 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 163 | }else{ |
| 164 | sqlite3_stmt *pStmt; |
| 165 | zSql = sqlite3_mprintf("SELECT bcname, bcvalue" |
| 166 | " FROM \"%w\".bconfig", zBName);panic that string is a SHA1fatalhat string is a SHA1 hash for the delta |
| 167 | ** basis, whister is presumably in the main repository. If NULL, then |
| 168 | ** data contains content without delta compression. |
| 169 | */ |
| 170 | statc const char zBundleInit[] = |
| 171 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 172 | @ bcname TEXT, |
| 173 | @ bcvalue ANY |
| 174 | @ ); |
| 175 | @ CREATE TABLE IF NOT EXISTS "% Pfatalhat string is a SHA1 hash for the delta |
| 176 | ** basis, whister is presumably in the main reposa contains content without delta compressio} |
| 177 | } |
| 178 | |
| 179 | /* |
| 180 | **sociates("ok", 1); |
| 181 | |
| 182 | /* NULL |
| 183 | @ notes TEXT, -- Description of ontent |
| 184 | @ data BLOB content |
| 185 | @ ); |
| 186 | ; |
| 187 | |
| 188 | /* |
| 189 | ** Attach a bundle file to the current database connection using the |
| 190 | ** attachment name zBName. |
| 191 | */ |
| 192 | static void bundle_attach_file( |
| 193 | const char *zFile, /* Name of the file that contains the bundle */ |
| 194 | const char *zBName, */ |
| 195 | ){ |
| 196 | int rc; |
| 197 | char *zErrMsg = 0; |
| 198 | char *zSql; |
| 199 | if( !doInit && file_size(zFile, ExtFILE)<0 ){ |
| 200 | fossil_fatal("no such file: %s", zFile); |
| 201 | } |
| 202 | assert( g.db ); |
| 203 | zSql = sqlite3_mprintf("ATTACH %Q AS %Q", zFile, zBName); |
| 204 | if( zSql==0 ) fossil_fatal("out of memory"); |
| 205 | rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); |
| 206 | sqlite3_free(zSql); |
| 207 | if( rc!=SQLITE_OK || zErrMsg ){ |
| 208 | if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); |
| 209 | fossil_fatal("not a valid bundle: %s", zFile); |
| 210 | } |
| 211 | if( doInit ){ |
| 212 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 213 | }else{ |
| 214 | sqlite3_stmt *pStmt; |
| 215 | zSql = sqlite3_mprintf("SELECT bcname, bcvalue" |
| 216 | " FROM \"%w\".bconfig", zBName); |
| 217 | if( zSql==0 ) fossil_fatal("out of memory"); |
| 218 | rc = sqlite3_prepare(g.db, zSql, -1, &pStmt, 0); |
| 219 | if( rc ) fossil_fatal("not a valid bundle: %s", zFile); |
| 220 | sqlite3_free(zSql); |
| 221 | sqlite3_finalize(pStmt); |
| 222 | zSql = sqlite3_mprintf("SELECT blobid, uuid, |
| 223 | **makesright (==40** Copyright (c) 2014 D/* |
| 224 | ** Copyright (c) 2014 D. Richard Hipp |
| 225 | ** |
| 226 | ** This program is free software; you can redistribute it and/or |
| 227 | ** modify it under the terms of the Simplified BSD License (also |
| 228 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 229 | |
| 230 | ** This program is distributed in the hope that it will be useful, |
| 231 | ** but without any warranty; without even the implied warranty of |
| 232 | ** merchantability or fitness for a particular purpose. |
| 233 | ** |
| 234 | ** Author contact information: |
| 235 | ** [email protected] |
| 236 | ** http://www.hwaci.com/drh/ |
| 237 | ** |
| 238 | ******************************************************************************* |
| 239 | ** |
| 240 | ** This file contains code used to implement and manage a "bundle" file. |
| 241 | */ |
| 242 | #include "config.h" |
| 243 | #include "bundle.h" |
| 244 | #include <assert.h> |
| 245 | |
| 246 | /* |
| 247 | ** SQe schema of a bundle. |
| 248 | ** |
| 249 | ** The bblob.delta field can be an integer, a text string, or NULL. |
| 250 | ** If an integer, then the corresponding blobid is the delta basis. |
| 251 | ** If a text string, then that string is a SHA1 hash for the delta |
| 252 | ** basis, whister is presumably in the ain repository. If NULL, then |
| 253 | ** data contains content without delta compression. |
| 254 | */ |
| 255 | static const char zBundleInit[] = |
| 256 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig(e ANY |
| 257 | @ ); |
| 258 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 259 | @ blobid INTEGER PRIMARY KEY, -- Blob ID |
| 260 | @ uuid TEXT SHA1 NOT NULL, -- hash of expanded blob |
| 261 | @ sz INT NOT NULL, -- Size of blob after expansion |
| 262 | @ delta ANY, -- Delta compression basis, or NULL |
| 263 | @ notes TEXT, -- Description of content |
| 264 | @ data BLOB -- compressed content |
| 265 | @ ); |
| 266 | ; |
| 267 | |
| 268 | /* |
| 269 | ** Attach a bundle file to the current database connection using the |
| 270 | ** attachment name zBName. |
| 271 | */ |
| 272 | static void bundle_attach_file( |
| 273 | const char *zFile, /* Name of the file that contains the bundle */ |
| 274 | const char *zBName, /* Attachment name */ |
| 275 | int doInit /* Initialize a new bundle, if true */ |
| 276 | ){ |
| 277 | int rc; |
| 278 | char *zErrMsg = 0; |
| 279 | char *zSql; |
| 280 | if( )<0 ){blob.rid=tobundle.rid" |
| 281 | _size(zFile, ExtFILE)<0 ){ |
| 282 | fossil_fatal("no such file: %s", zFile); |
| 283 | } |
| 284 | assert( g.db ); |
| 285 | zSql = sqlite3_mprintf("ATTAfatalhat string is a SHA1 c = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); |
| 286 | sqlite3_free(zSql); |
| 287 | if( rc!=SQLITE_OK || zErrMsg ){ |
| 288 | if( zErrMsg==0 ) zErrMsg = (char*)sqlite3_errmsg(g.db); |
| 289 | fossil_fatal("not a valid bundle: %s", zFile); |
| 290 | } |
| 291 | if( doInit ){ |
| 292 | db_multi_exec(zBundleInit /*works-like:"%w%w"*/, zBName, zBName); |
| 293 | }else{ |
| 294 | sqlite3_stmt *pStmt; |
| 295 | zSql = sqlite3_mprintf("SELECT bcname, bcvalue" |
| 296 | " FROM \"%w\".bconfig", zBName);panic that string is a SHA1fatalhat string is a SHA1 hash for the delta |
| 297 | ** basis, whister is presumably in the main repository. If NULL, then |
| 298 | ** data contains content without delta compression. |
| 299 | */ |
| 300 | static const char zBundleInit[] = |
| 301 | @ CREATE TABLE IF NOT EXISTS "%w".bconfig( |
| 302 | @ bcname TEXT, |
| 303 | @ bcvalue ANY |
| 304 | @ ); |
| 305 | @ CREATE TABLE IF NOT EXISTS "%w".bblob( |
| 306 | @ blobid INTEGER Pfatalhat string is a SHA1 hash for the delta |
| 307 | ** basis, whist ins |
+4
-4
| --- src/content.c | ||
| +++ src/content.c | ||
| @@ -567,14 +567,14 @@ | ||
| 567 | 567 | db_exec(&s1); |
| 568 | 568 | rid = db_last_insert_rowid(); |
| 569 | 569 | if( !pBlob ){ |
| 570 | 570 | db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid); |
| 571 | 571 | } |
| 572 | - if( g.markPrivate || isPrivate ){ | |
| 573 | - db_multi_exec("INSERT INTO private VALUES(%d)", rid); | |
| 574 | - markAsUnclustered = 0; | |
| 575 | - } | |
| 572 | + } | |
| 573 | + if( g.markPrivate || isPrivate ){ | |
| 574 | + db_multi_exec("INSERT INTO private VALUES(%d)", rid); | |
| 575 | + markAsUnclustered = 0; | |
| 576 | 576 | } |
| 577 | 577 | if( nBlob==0 ) blob_reset(&cmpr); |
| 578 | 578 | |
| 579 | 579 | /* If the srcId is specified, then the data we just added is |
| 580 | 580 | ** really a delta. Record this fact in the delta table. |
| 581 | 581 |
| --- src/content.c | |
| +++ src/content.c | |
| @@ -567,14 +567,14 @@ | |
| 567 | db_exec(&s1); |
| 568 | rid = db_last_insert_rowid(); |
| 569 | if( !pBlob ){ |
| 570 | db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid); |
| 571 | } |
| 572 | if( g.markPrivate || isPrivate ){ |
| 573 | db_multi_exec("INSERT INTO private VALUES(%d)", rid); |
| 574 | markAsUnclustered = 0; |
| 575 | } |
| 576 | } |
| 577 | if( nBlob==0 ) blob_reset(&cmpr); |
| 578 | |
| 579 | /* If the srcId is specified, then the data we just added is |
| 580 | ** really a delta. Record this fact in the delta table. |
| 581 |
| --- src/content.c | |
| +++ src/content.c | |
| @@ -567,14 +567,14 @@ | |
| 567 | db_exec(&s1); |
| 568 | rid = db_last_insert_rowid(); |
| 569 | if( !pBlob ){ |
| 570 | db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid); |
| 571 | } |
| 572 | } |
| 573 | if( g.markPrivate || isPrivate ){ |
| 574 | db_multi_exec("INSERT INTO private VALUES(%d)", rid); |
| 575 | markAsUnclustered = 0; |
| 576 | } |
| 577 | if( nBlob==0 ) blob_reset(&cmpr); |
| 578 | |
| 579 | /* If the srcId is specified, then the data we just added is |
| 580 | ** really a delta. Record this fact in the delta table. |
| 581 |
M
src/db.c
+44
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -424,10 +424,13 @@ | ||
| 424 | 424 | |
| 425 | 425 | /* |
| 426 | 426 | ** Extract text, integer, or blob values from the N-th column of the |
| 427 | 427 | ** current row. |
| 428 | 428 | */ |
| 429 | +int db_column_type(Stmt *pStmt, int N){ | |
| 430 | + return sqlite3_column_type(pStmt->pStmt, N); | |
| 431 | +} | |
| 429 | 432 | int db_column_bytes(Stmt *pStmt, int N){ |
| 430 | 433 | return sqlite3_column_bytes(pStmt->pStmt, N); |
| 431 | 434 | } |
| 432 | 435 | int db_column_int(Stmt *pStmt, int N){ |
| 433 | 436 | return sqlite3_column_int(pStmt->pStmt, N); |
| @@ -486,10 +489,50 @@ | ||
| 486 | 489 | while( (rc = db_step(pStmt))==SQLITE_ROW ){} |
| 487 | 490 | rc = db_reset(pStmt); |
| 488 | 491 | db_check_result(rc); |
| 489 | 492 | return rc; |
| 490 | 493 | } |
| 494 | + | |
| 495 | +/* | |
| 496 | +** Print the output of one or more SQL queries on standard output. | |
| 497 | +** This routine is used for debugging purposes only. | |
| 498 | +*/ | |
| 499 | +int db_debug(const char *zSql, ...){ | |
| 500 | + Blob sql; | |
| 501 | + int rc = SQLITE_OK; | |
| 502 | + va_list ap; | |
| 503 | + const char *z, *zEnd; | |
| 504 | + sqlite3_stmt *pStmt; | |
| 505 | + blob_init(&sql, 0, 0); | |
| 506 | + va_start(ap, zSql); | |
| 507 | + blob_vappendf(&sql, zSql, ap); | |
| 508 | + va_end(ap); | |
| 509 | + z = blob_str(&sql); | |
| 510 | + while( rc==SQLITE_OK && z[0] ){ | |
| 511 | + pStmt = 0; | |
| 512 | + rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); | |
| 513 | + if( rc!=SQLITE_OK ) break; | |
| 514 | + if( pStmt ){ | |
| 515 | + int nRow = 0; | |
| 516 | + db.nPrepare++; | |
| 517 | + while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 518 | + int i, n; | |
| 519 | + if( nRow++ > 0 ) fossil_print("\n"); | |
| 520 | + n = sqlite3_column_count(pStmt); | |
| 521 | + for(i=0; i<n; i++){ | |
| 522 | + fossil_print("%s = %s\n", sqlite3_column_name(pStmt, i), | |
| 523 | + sqlite3_column_text(pStmt,i)); | |
| 524 | + } | |
| 525 | + } | |
| 526 | + rc = sqlite3_finalize(pStmt); | |
| 527 | + if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); | |
| 528 | + } | |
| 529 | + z = zEnd; | |
| 530 | + } | |
| 531 | + blob_reset(&sql); | |
| 532 | + return rc; | |
| 533 | +} | |
| 491 | 534 | |
| 492 | 535 | /* |
| 493 | 536 | ** Execute multiple SQL statements. |
| 494 | 537 | */ |
| 495 | 538 | int db_multi_exec(const char *zSql, ...){ |
| @@ -722,11 +765,11 @@ | ||
| 722 | 765 | arg = (const char*)sqlite3_value_text(argv[0]); |
| 723 | 766 | if(!arg){ |
| 724 | 767 | sqlite3_result_error(context, "Expecting a STRING argument", -1); |
| 725 | 768 | }else{ |
| 726 | 769 | int rid; |
| 727 | - type = (2==argc) ? sqlite3_value_text(argv[1]) : 0; | |
| 770 | + type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0; | |
| 728 | 771 | if(!type) type = "ci"; |
| 729 | 772 | rid = symbolic_name_to_rid( arg, type ); |
| 730 | 773 | if(rid<0){ |
| 731 | 774 | sqlite3_result_error(context, "Symbolic name is ambiguous.", -1); |
| 732 | 775 | }else if(0==rid){ |
| 733 | 776 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -424,10 +424,13 @@ | |
| 424 | |
| 425 | /* |
| 426 | ** Extract text, integer, or blob values from the N-th column of the |
| 427 | ** current row. |
| 428 | */ |
| 429 | int db_column_bytes(Stmt *pStmt, int N){ |
| 430 | return sqlite3_column_bytes(pStmt->pStmt, N); |
| 431 | } |
| 432 | int db_column_int(Stmt *pStmt, int N){ |
| 433 | return sqlite3_column_int(pStmt->pStmt, N); |
| @@ -486,10 +489,50 @@ | |
| 486 | while( (rc = db_step(pStmt))==SQLITE_ROW ){} |
| 487 | rc = db_reset(pStmt); |
| 488 | db_check_result(rc); |
| 489 | return rc; |
| 490 | } |
| 491 | |
| 492 | /* |
| 493 | ** Execute multiple SQL statements. |
| 494 | */ |
| 495 | int db_multi_exec(const char *zSql, ...){ |
| @@ -722,11 +765,11 @@ | |
| 722 | arg = (const char*)sqlite3_value_text(argv[0]); |
| 723 | if(!arg){ |
| 724 | sqlite3_result_error(context, "Expecting a STRING argument", -1); |
| 725 | }else{ |
| 726 | int rid; |
| 727 | type = (2==argc) ? sqlite3_value_text(argv[1]) : 0; |
| 728 | if(!type) type = "ci"; |
| 729 | rid = symbolic_name_to_rid( arg, type ); |
| 730 | if(rid<0){ |
| 731 | sqlite3_result_error(context, "Symbolic name is ambiguous.", -1); |
| 732 | }else if(0==rid){ |
| 733 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -424,10 +424,13 @@ | |
| 424 | |
| 425 | /* |
| 426 | ** Extract text, integer, or blob values from the N-th column of the |
| 427 | ** current row. |
| 428 | */ |
| 429 | int db_column_type(Stmt *pStmt, int N){ |
| 430 | return sqlite3_column_type(pStmt->pStmt, N); |
| 431 | } |
| 432 | int db_column_bytes(Stmt *pStmt, int N){ |
| 433 | return sqlite3_column_bytes(pStmt->pStmt, N); |
| 434 | } |
| 435 | int db_column_int(Stmt *pStmt, int N){ |
| 436 | return sqlite3_column_int(pStmt->pStmt, N); |
| @@ -486,10 +489,50 @@ | |
| 489 | while( (rc = db_step(pStmt))==SQLITE_ROW ){} |
| 490 | rc = db_reset(pStmt); |
| 491 | db_check_result(rc); |
| 492 | return rc; |
| 493 | } |
| 494 | |
| 495 | /* |
| 496 | ** Print the output of one or more SQL queries on standard output. |
| 497 | ** This routine is used for debugging purposes only. |
| 498 | */ |
| 499 | int db_debug(const char *zSql, ...){ |
| 500 | Blob sql; |
| 501 | int rc = SQLITE_OK; |
| 502 | va_list ap; |
| 503 | const char *z, *zEnd; |
| 504 | sqlite3_stmt *pStmt; |
| 505 | blob_init(&sql, 0, 0); |
| 506 | va_start(ap, zSql); |
| 507 | blob_vappendf(&sql, zSql, ap); |
| 508 | va_end(ap); |
| 509 | z = blob_str(&sql); |
| 510 | while( rc==SQLITE_OK && z[0] ){ |
| 511 | pStmt = 0; |
| 512 | rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); |
| 513 | if( rc!=SQLITE_OK ) break; |
| 514 | if( pStmt ){ |
| 515 | int nRow = 0; |
| 516 | db.nPrepare++; |
| 517 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 518 | int i, n; |
| 519 | if( nRow++ > 0 ) fossil_print("\n"); |
| 520 | n = sqlite3_column_count(pStmt); |
| 521 | for(i=0; i<n; i++){ |
| 522 | fossil_print("%s = %s\n", sqlite3_column_name(pStmt, i), |
| 523 | sqlite3_column_text(pStmt,i)); |
| 524 | } |
| 525 | } |
| 526 | rc = sqlite3_finalize(pStmt); |
| 527 | if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); |
| 528 | } |
| 529 | z = zEnd; |
| 530 | } |
| 531 | blob_reset(&sql); |
| 532 | return rc; |
| 533 | } |
| 534 | |
| 535 | /* |
| 536 | ** Execute multiple SQL statements. |
| 537 | */ |
| 538 | int db_multi_exec(const char *zSql, ...){ |
| @@ -722,11 +765,11 @@ | |
| 765 | arg = (const char*)sqlite3_value_text(argv[0]); |
| 766 | if(!arg){ |
| 767 | sqlite3_result_error(context, "Expecting a STRING argument", -1); |
| 768 | }else{ |
| 769 | int rid; |
| 770 | type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0; |
| 771 | if(!type) type = "ci"; |
| 772 | rid = symbolic_name_to_rid( arg, type ); |
| 773 | if(rid<0){ |
| 774 | sqlite3_result_error(context, "Symbolic name is ambiguous.", -1); |
| 775 | }else if(0==rid){ |
| 776 |
M
src/db.c
+44
-1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -424,10 +424,13 @@ | ||
| 424 | 424 | |
| 425 | 425 | /* |
| 426 | 426 | ** Extract text, integer, or blob values from the N-th column of the |
| 427 | 427 | ** current row. |
| 428 | 428 | */ |
| 429 | +int db_column_type(Stmt *pStmt, int N){ | |
| 430 | + return sqlite3_column_type(pStmt->pStmt, N); | |
| 431 | +} | |
| 429 | 432 | int db_column_bytes(Stmt *pStmt, int N){ |
| 430 | 433 | return sqlite3_column_bytes(pStmt->pStmt, N); |
| 431 | 434 | } |
| 432 | 435 | int db_column_int(Stmt *pStmt, int N){ |
| 433 | 436 | return sqlite3_column_int(pStmt->pStmt, N); |
| @@ -486,10 +489,50 @@ | ||
| 486 | 489 | while( (rc = db_step(pStmt))==SQLITE_ROW ){} |
| 487 | 490 | rc = db_reset(pStmt); |
| 488 | 491 | db_check_result(rc); |
| 489 | 492 | return rc; |
| 490 | 493 | } |
| 494 | + | |
| 495 | +/* | |
| 496 | +** Print the output of one or more SQL queries on standard output. | |
| 497 | +** This routine is used for debugging purposes only. | |
| 498 | +*/ | |
| 499 | +int db_debug(const char *zSql, ...){ | |
| 500 | + Blob sql; | |
| 501 | + int rc = SQLITE_OK; | |
| 502 | + va_list ap; | |
| 503 | + const char *z, *zEnd; | |
| 504 | + sqlite3_stmt *pStmt; | |
| 505 | + blob_init(&sql, 0, 0); | |
| 506 | + va_start(ap, zSql); | |
| 507 | + blob_vappendf(&sql, zSql, ap); | |
| 508 | + va_end(ap); | |
| 509 | + z = blob_str(&sql); | |
| 510 | + while( rc==SQLITE_OK && z[0] ){ | |
| 511 | + pStmt = 0; | |
| 512 | + rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); | |
| 513 | + if( rc!=SQLITE_OK ) break; | |
| 514 | + if( pStmt ){ | |
| 515 | + int nRow = 0; | |
| 516 | + db.nPrepare++; | |
| 517 | + while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 518 | + int i, n; | |
| 519 | + if( nRow++ > 0 ) fossil_print("\n"); | |
| 520 | + n = sqlite3_column_count(pStmt); | |
| 521 | + for(i=0; i<n; i++){ | |
| 522 | + fossil_print("%s = %s\n", sqlite3_column_name(pStmt, i), | |
| 523 | + sqlite3_column_text(pStmt,i)); | |
| 524 | + } | |
| 525 | + } | |
| 526 | + rc = sqlite3_finalize(pStmt); | |
| 527 | + if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); | |
| 528 | + } | |
| 529 | + z = zEnd; | |
| 530 | + } | |
| 531 | + blob_reset(&sql); | |
| 532 | + return rc; | |
| 533 | +} | |
| 491 | 534 | |
| 492 | 535 | /* |
| 493 | 536 | ** Execute multiple SQL statements. |
| 494 | 537 | */ |
| 495 | 538 | int db_multi_exec(const char *zSql, ...){ |
| @@ -722,11 +765,11 @@ | ||
| 722 | 765 | arg = (const char*)sqlite3_value_text(argv[0]); |
| 723 | 766 | if(!arg){ |
| 724 | 767 | sqlite3_result_error(context, "Expecting a STRING argument", -1); |
| 725 | 768 | }else{ |
| 726 | 769 | int rid; |
| 727 | - type = (2==argc) ? sqlite3_value_text(argv[1]) : 0; | |
| 770 | + type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0; | |
| 728 | 771 | if(!type) type = "ci"; |
| 729 | 772 | rid = symbolic_name_to_rid( arg, type ); |
| 730 | 773 | if(rid<0){ |
| 731 | 774 | sqlite3_result_error(context, "Symbolic name is ambiguous.", -1); |
| 732 | 775 | }else if(0==rid){ |
| 733 | 776 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -424,10 +424,13 @@ | |
| 424 | |
| 425 | /* |
| 426 | ** Extract text, integer, or blob values from the N-th column of the |
| 427 | ** current row. |
| 428 | */ |
| 429 | int db_column_bytes(Stmt *pStmt, int N){ |
| 430 | return sqlite3_column_bytes(pStmt->pStmt, N); |
| 431 | } |
| 432 | int db_column_int(Stmt *pStmt, int N){ |
| 433 | return sqlite3_column_int(pStmt->pStmt, N); |
| @@ -486,10 +489,50 @@ | |
| 486 | while( (rc = db_step(pStmt))==SQLITE_ROW ){} |
| 487 | rc = db_reset(pStmt); |
| 488 | db_check_result(rc); |
| 489 | return rc; |
| 490 | } |
| 491 | |
| 492 | /* |
| 493 | ** Execute multiple SQL statements. |
| 494 | */ |
| 495 | int db_multi_exec(const char *zSql, ...){ |
| @@ -722,11 +765,11 @@ | |
| 722 | arg = (const char*)sqlite3_value_text(argv[0]); |
| 723 | if(!arg){ |
| 724 | sqlite3_result_error(context, "Expecting a STRING argument", -1); |
| 725 | }else{ |
| 726 | int rid; |
| 727 | type = (2==argc) ? sqlite3_value_text(argv[1]) : 0; |
| 728 | if(!type) type = "ci"; |
| 729 | rid = symbolic_name_to_rid( arg, type ); |
| 730 | if(rid<0){ |
| 731 | sqlite3_result_error(context, "Symbolic name is ambiguous.", -1); |
| 732 | }else if(0==rid){ |
| 733 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -424,10 +424,13 @@ | |
| 424 | |
| 425 | /* |
| 426 | ** Extract text, integer, or blob values from the N-th column of the |
| 427 | ** current row. |
| 428 | */ |
| 429 | int db_column_type(Stmt *pStmt, int N){ |
| 430 | return sqlite3_column_type(pStmt->pStmt, N); |
| 431 | } |
| 432 | int db_column_bytes(Stmt *pStmt, int N){ |
| 433 | return sqlite3_column_bytes(pStmt->pStmt, N); |
| 434 | } |
| 435 | int db_column_int(Stmt *pStmt, int N){ |
| 436 | return sqlite3_column_int(pStmt->pStmt, N); |
| @@ -486,10 +489,50 @@ | |
| 489 | while( (rc = db_step(pStmt))==SQLITE_ROW ){} |
| 490 | rc = db_reset(pStmt); |
| 491 | db_check_result(rc); |
| 492 | return rc; |
| 493 | } |
| 494 | |
| 495 | /* |
| 496 | ** Print the output of one or more SQL queries on standard output. |
| 497 | ** This routine is used for debugging purposes only. |
| 498 | */ |
| 499 | int db_debug(const char *zSql, ...){ |
| 500 | Blob sql; |
| 501 | int rc = SQLITE_OK; |
| 502 | va_list ap; |
| 503 | const char *z, *zEnd; |
| 504 | sqlite3_stmt *pStmt; |
| 505 | blob_init(&sql, 0, 0); |
| 506 | va_start(ap, zSql); |
| 507 | blob_vappendf(&sql, zSql, ap); |
| 508 | va_end(ap); |
| 509 | z = blob_str(&sql); |
| 510 | while( rc==SQLITE_OK && z[0] ){ |
| 511 | pStmt = 0; |
| 512 | rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd); |
| 513 | if( rc!=SQLITE_OK ) break; |
| 514 | if( pStmt ){ |
| 515 | int nRow = 0; |
| 516 | db.nPrepare++; |
| 517 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 518 | int i, n; |
| 519 | if( nRow++ > 0 ) fossil_print("\n"); |
| 520 | n = sqlite3_column_count(pStmt); |
| 521 | for(i=0; i<n; i++){ |
| 522 | fossil_print("%s = %s\n", sqlite3_column_name(pStmt, i), |
| 523 | sqlite3_column_text(pStmt,i)); |
| 524 | } |
| 525 | } |
| 526 | rc = sqlite3_finalize(pStmt); |
| 527 | if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z); |
| 528 | } |
| 529 | z = zEnd; |
| 530 | } |
| 531 | blob_reset(&sql); |
| 532 | return rc; |
| 533 | } |
| 534 | |
| 535 | /* |
| 536 | ** Execute multiple SQL statements. |
| 537 | */ |
| 538 | int db_multi_exec(const char *zSql, ...){ |
| @@ -722,11 +765,11 @@ | |
| 765 | arg = (const char*)sqlite3_value_text(argv[0]); |
| 766 | if(!arg){ |
| 767 | sqlite3_result_error(context, "Expecting a STRING argument", -1); |
| 768 | }else{ |
| 769 | int rid; |
| 770 | type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0; |
| 771 | if(!type) type = "ci"; |
| 772 | rid = symbolic_name_to_rid( arg, type ); |
| 773 | if(rid<0){ |
| 774 | sqlite3_result_error(context, "Symbolic name is ambiguous.", -1); |
| 775 | }else if(0==rid){ |
| 776 |
+4
-4
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -289,14 +289,14 @@ | ||
| 289 | 289 | } |
| 290 | 290 | |
| 291 | 291 | /* |
| 292 | 292 | ** COMMAND: descendants* |
| 293 | 293 | ** |
| 294 | -** Usage: %fossil descendants ?BASELINE-ID? ?OPTIONS? | |
| 294 | +** Usage: %fossil descendants ?CHECKIN? ?OPTIONS? | |
| 295 | 295 | ** |
| 296 | -** Find all leaf descendants of the baseline specified or if the argument | |
| 297 | -** is omitted, of the baseline currently checked out. | |
| 296 | +** Find all leaf descendants of the checkin specified or if the argument | |
| 297 | +** is omitted, of the checkin currently checked out. | |
| 298 | 298 | ** |
| 299 | 299 | ** Options: |
| 300 | 300 | ** -R|--repository FILE Extract info from repository FILE |
| 301 | 301 | ** -W|--width <num> Width of lines (default is to auto-detect). |
| 302 | 302 | ** Must be >20 or 0 (= no limit, resulting in a |
| @@ -334,11 +334,11 @@ | ||
| 334 | 334 | "%s" |
| 335 | 335 | " AND event.objid IN (SELECT rid FROM leaves)" |
| 336 | 336 | " ORDER BY event.mtime DESC", |
| 337 | 337 | timeline_query_for_tty() |
| 338 | 338 | ); |
| 339 | - print_timeline(&q, -20, width, 0); | |
| 339 | + print_timeline(&q, 0, width, 0); | |
| 340 | 340 | db_finalize(&q); |
| 341 | 341 | } |
| 342 | 342 | |
| 343 | 343 | /* |
| 344 | 344 | ** COMMAND: leaves* |
| 345 | 345 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -289,14 +289,14 @@ | |
| 289 | } |
| 290 | |
| 291 | /* |
| 292 | ** COMMAND: descendants* |
| 293 | ** |
| 294 | ** Usage: %fossil descendants ?BASELINE-ID? ?OPTIONS? |
| 295 | ** |
| 296 | ** Find all leaf descendants of the baseline specified or if the argument |
| 297 | ** is omitted, of the baseline currently checked out. |
| 298 | ** |
| 299 | ** Options: |
| 300 | ** -R|--repository FILE Extract info from repository FILE |
| 301 | ** -W|--width <num> Width of lines (default is to auto-detect). |
| 302 | ** Must be >20 or 0 (= no limit, resulting in a |
| @@ -334,11 +334,11 @@ | |
| 334 | "%s" |
| 335 | " AND event.objid IN (SELECT rid FROM leaves)" |
| 336 | " ORDER BY event.mtime DESC", |
| 337 | timeline_query_for_tty() |
| 338 | ); |
| 339 | print_timeline(&q, -20, width, 0); |
| 340 | db_finalize(&q); |
| 341 | } |
| 342 | |
| 343 | /* |
| 344 | ** COMMAND: leaves* |
| 345 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -289,14 +289,14 @@ | |
| 289 | } |
| 290 | |
| 291 | /* |
| 292 | ** COMMAND: descendants* |
| 293 | ** |
| 294 | ** Usage: %fossil descendants ?CHECKIN? ?OPTIONS? |
| 295 | ** |
| 296 | ** Find all leaf descendants of the checkin specified or if the argument |
| 297 | ** is omitted, of the checkin currently checked out. |
| 298 | ** |
| 299 | ** Options: |
| 300 | ** -R|--repository FILE Extract info from repository FILE |
| 301 | ** -W|--width <num> Width of lines (default is to auto-detect). |
| 302 | ** Must be >20 or 0 (= no limit, resulting in a |
| @@ -334,11 +334,11 @@ | |
| 334 | "%s" |
| 335 | " AND event.objid IN (SELECT rid FROM leaves)" |
| 336 | " ORDER BY event.mtime DESC", |
| 337 | timeline_query_for_tty() |
| 338 | ); |
| 339 | print_timeline(&q, 0, width, 0); |
| 340 | db_finalize(&q); |
| 341 | } |
| 342 | |
| 343 | /* |
| 344 | ** COMMAND: leaves* |
| 345 |
+1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -495,10 +495,11 @@ | ||
| 495 | 495 | @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) sz=%d(sz) |
| 496 | 496 | if( srcid ){ |
| 497 | 497 | @ srcid=%d(srcid) |
| 498 | 498 | } |
| 499 | 499 | } |
| 500 | + tag_private_status(frid); | |
| 500 | 501 | @ </td></tr> |
| 501 | 502 | } |
| 502 | 503 | db_finalize(&q); |
| 503 | 504 | if( pGraph ){ |
| 504 | 505 | graph_finish(pGraph, 0); |
| 505 | 506 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -495,10 +495,11 @@ | |
| 495 | @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) sz=%d(sz) |
| 496 | if( srcid ){ |
| 497 | @ srcid=%d(srcid) |
| 498 | } |
| 499 | } |
| 500 | @ </td></tr> |
| 501 | } |
| 502 | db_finalize(&q); |
| 503 | if( pGraph ){ |
| 504 | graph_finish(pGraph, 0); |
| 505 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -495,10 +495,11 @@ | |
| 495 | @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) sz=%d(sz) |
| 496 | if( srcid ){ |
| 497 | @ srcid=%d(srcid) |
| 498 | } |
| 499 | } |
| 500 | tag_private_status(frid); |
| 501 | @ </td></tr> |
| 502 | } |
| 503 | db_finalize(&q); |
| 504 | if( pGraph ){ |
| 505 | graph_finish(pGraph, 0); |
| 506 |
-3
| --- src/foci.c | ||
| +++ src/foci.c | ||
| @@ -104,14 +104,11 @@ | ||
| 104 | 104 | |
| 105 | 105 | /* |
| 106 | 106 | ** Open a new focivfs cursor. |
| 107 | 107 | */ |
| 108 | 108 | static int fociOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |
| 109 | - FociTable *pTab = (FociTable *)pVTab; | |
| 110 | 109 | FociCursor *pCsr; |
| 111 | - int rc; | |
| 112 | - | |
| 113 | 110 | pCsr = (FociCursor *)sqlite3_malloc(sizeof(FociCursor)); |
| 114 | 111 | memset(pCsr, 0, sizeof(FociCursor)); |
| 115 | 112 | pCsr->base.pVtab = pVTab; |
| 116 | 113 | *ppCursor = (sqlite3_vtab_cursor *)pCsr; |
| 117 | 114 | return SQLITE_OK; |
| 118 | 115 |
| --- src/foci.c | |
| +++ src/foci.c | |
| @@ -104,14 +104,11 @@ | |
| 104 | |
| 105 | /* |
| 106 | ** Open a new focivfs cursor. |
| 107 | */ |
| 108 | static int fociOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |
| 109 | FociTable *pTab = (FociTable *)pVTab; |
| 110 | FociCursor *pCsr; |
| 111 | int rc; |
| 112 | |
| 113 | pCsr = (FociCursor *)sqlite3_malloc(sizeof(FociCursor)); |
| 114 | memset(pCsr, 0, sizeof(FociCursor)); |
| 115 | pCsr->base.pVtab = pVTab; |
| 116 | *ppCursor = (sqlite3_vtab_cursor *)pCsr; |
| 117 | return SQLITE_OK; |
| 118 |
| --- src/foci.c | |
| +++ src/foci.c | |
| @@ -104,14 +104,11 @@ | |
| 104 | |
| 105 | /* |
| 106 | ** Open a new focivfs cursor. |
| 107 | */ |
| 108 | static int fociOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |
| 109 | FociCursor *pCsr; |
| 110 | pCsr = (FociCursor *)sqlite3_malloc(sizeof(FociCursor)); |
| 111 | memset(pCsr, 0, sizeof(FociCursor)); |
| 112 | pCsr->base.pVtab = pVTab; |
| 113 | *ppCursor = (sqlite3_vtab_cursor *)pCsr; |
| 114 | return SQLITE_OK; |
| 115 |
-1
| --- src/fusefs.c | ||
| +++ src/fusefs.c | ||
| @@ -319,11 +319,10 @@ | ||
| 319 | 319 | #ifndef FOSSIL_HAVE_FUSEFS |
| 320 | 320 | fossil_fatal("this build of fossil does not support the fuse filesystem"); |
| 321 | 321 | #else |
| 322 | 322 | char *zMountPoint; |
| 323 | 323 | char *azNewArgv[5]; |
| 324 | - int i; | |
| 325 | 324 | int doDebug = find_option("debug","d",0)!=0; |
| 326 | 325 | |
| 327 | 326 | db_find_and_open_repository(0,0); |
| 328 | 327 | verify_all_options(); |
| 329 | 328 | blob_init(&fusefs.content, 0, 0); |
| 330 | 329 |
| --- src/fusefs.c | |
| +++ src/fusefs.c | |
| @@ -319,11 +319,10 @@ | |
| 319 | #ifndef FOSSIL_HAVE_FUSEFS |
| 320 | fossil_fatal("this build of fossil does not support the fuse filesystem"); |
| 321 | #else |
| 322 | char *zMountPoint; |
| 323 | char *azNewArgv[5]; |
| 324 | int i; |
| 325 | int doDebug = find_option("debug","d",0)!=0; |
| 326 | |
| 327 | db_find_and_open_repository(0,0); |
| 328 | verify_all_options(); |
| 329 | blob_init(&fusefs.content, 0, 0); |
| 330 |
| --- src/fusefs.c | |
| +++ src/fusefs.c | |
| @@ -319,11 +319,10 @@ | |
| 319 | #ifndef FOSSIL_HAVE_FUSEFS |
| 320 | fossil_fatal("this build of fossil does not support the fuse filesystem"); |
| 321 | #else |
| 322 | char *zMountPoint; |
| 323 | char *azNewArgv[5]; |
| 324 | int doDebug = find_option("debug","d",0)!=0; |
| 325 | |
| 326 | db_find_and_open_repository(0,0); |
| 327 | verify_all_options(); |
| 328 | blob_init(&fusefs.content, 0, 0); |
| 329 |
+6
-1
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -931,10 +931,11 @@ | ||
| 931 | 931 | }else{ |
| 932 | 932 | @ tags: %h(zTagList), |
| 933 | 933 | } |
| 934 | 934 | @ date: |
| 935 | 935 | hyperlink_to_date(zDate, ")"); |
| 936 | + tag_private_status(rid); | |
| 936 | 937 | } |
| 937 | 938 | db_finalize(&q); |
| 938 | 939 | } |
| 939 | 940 | |
| 940 | 941 | |
| @@ -1203,19 +1204,20 @@ | ||
| 1203 | 1204 | }else{ |
| 1204 | 1205 | @ <li>File |
| 1205 | 1206 | } |
| 1206 | 1207 | objType |= OBJTYPE_CONTENT; |
| 1207 | 1208 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 1209 | + tag_private_status(rid); | |
| 1208 | 1210 | if( showDetail ){ |
| 1209 | 1211 | @ <ul> |
| 1210 | 1212 | } |
| 1211 | 1213 | prevName = fossil_strdup(zName); |
| 1212 | 1214 | } |
| 1213 | 1215 | if( showDetail ){ |
| 1214 | 1216 | @ <li> |
| 1215 | 1217 | hyperlink_to_date(zDate,""); |
| 1216 | - @ — part of check-in | |
| 1218 | + @ — part of checkin | |
| 1217 | 1219 | hyperlink_to_uuid(zVers); |
| 1218 | 1220 | }else{ |
| 1219 | 1221 | @ — part of checkin |
| 1220 | 1222 | hyperlink_to_uuid(zVers); |
| 1221 | 1223 | @ at |
| @@ -1314,10 +1316,11 @@ | ||
| 1314 | 1316 | hyperlink_to_user(zUser,zDate," on"); |
| 1315 | 1317 | hyperlink_to_date(zDate, "."); |
| 1316 | 1318 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1317 | 1319 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1318 | 1320 | } |
| 1321 | + tag_private_status(rid); | |
| 1319 | 1322 | cnt++; |
| 1320 | 1323 | } |
| 1321 | 1324 | db_finalize(&q); |
| 1322 | 1325 | } |
| 1323 | 1326 | db_prepare(&q, |
| @@ -1357,17 +1360,19 @@ | ||
| 1357 | 1360 | hyperlink_to_date(zDate,"."); |
| 1358 | 1361 | cnt++; |
| 1359 | 1362 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1360 | 1363 | blob_append(pDownloadName, zFilename, -1); |
| 1361 | 1364 | } |
| 1365 | + tag_private_status(rid); | |
| 1362 | 1366 | } |
| 1363 | 1367 | db_finalize(&q); |
| 1364 | 1368 | if( cnt==0 ){ |
| 1365 | 1369 | @ Control artifact. |
| 1366 | 1370 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1367 | 1371 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1368 | 1372 | } |
| 1373 | + tag_private_status(rid); | |
| 1369 | 1374 | } |
| 1370 | 1375 | return objType; |
| 1371 | 1376 | } |
| 1372 | 1377 | |
| 1373 | 1378 | |
| 1374 | 1379 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -931,10 +931,11 @@ | |
| 931 | }else{ |
| 932 | @ tags: %h(zTagList), |
| 933 | } |
| 934 | @ date: |
| 935 | hyperlink_to_date(zDate, ")"); |
| 936 | } |
| 937 | db_finalize(&q); |
| 938 | } |
| 939 | |
| 940 | |
| @@ -1203,19 +1204,20 @@ | |
| 1203 | }else{ |
| 1204 | @ <li>File |
| 1205 | } |
| 1206 | objType |= OBJTYPE_CONTENT; |
| 1207 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 1208 | if( showDetail ){ |
| 1209 | @ <ul> |
| 1210 | } |
| 1211 | prevName = fossil_strdup(zName); |
| 1212 | } |
| 1213 | if( showDetail ){ |
| 1214 | @ <li> |
| 1215 | hyperlink_to_date(zDate,""); |
| 1216 | @ — part of check-in |
| 1217 | hyperlink_to_uuid(zVers); |
| 1218 | }else{ |
| 1219 | @ — part of checkin |
| 1220 | hyperlink_to_uuid(zVers); |
| 1221 | @ at |
| @@ -1314,10 +1316,11 @@ | |
| 1314 | hyperlink_to_user(zUser,zDate," on"); |
| 1315 | hyperlink_to_date(zDate, "."); |
| 1316 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1317 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1318 | } |
| 1319 | cnt++; |
| 1320 | } |
| 1321 | db_finalize(&q); |
| 1322 | } |
| 1323 | db_prepare(&q, |
| @@ -1357,17 +1360,19 @@ | |
| 1357 | hyperlink_to_date(zDate,"."); |
| 1358 | cnt++; |
| 1359 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1360 | blob_append(pDownloadName, zFilename, -1); |
| 1361 | } |
| 1362 | } |
| 1363 | db_finalize(&q); |
| 1364 | if( cnt==0 ){ |
| 1365 | @ Control artifact. |
| 1366 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1367 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1368 | } |
| 1369 | } |
| 1370 | return objType; |
| 1371 | } |
| 1372 | |
| 1373 | |
| 1374 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -931,10 +931,11 @@ | |
| 931 | }else{ |
| 932 | @ tags: %h(zTagList), |
| 933 | } |
| 934 | @ date: |
| 935 | hyperlink_to_date(zDate, ")"); |
| 936 | tag_private_status(rid); |
| 937 | } |
| 938 | db_finalize(&q); |
| 939 | } |
| 940 | |
| 941 | |
| @@ -1203,19 +1204,20 @@ | |
| 1204 | }else{ |
| 1205 | @ <li>File |
| 1206 | } |
| 1207 | objType |= OBJTYPE_CONTENT; |
| 1208 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 1209 | tag_private_status(rid); |
| 1210 | if( showDetail ){ |
| 1211 | @ <ul> |
| 1212 | } |
| 1213 | prevName = fossil_strdup(zName); |
| 1214 | } |
| 1215 | if( showDetail ){ |
| 1216 | @ <li> |
| 1217 | hyperlink_to_date(zDate,""); |
| 1218 | @ — part of checkin |
| 1219 | hyperlink_to_uuid(zVers); |
| 1220 | }else{ |
| 1221 | @ — part of checkin |
| 1222 | hyperlink_to_uuid(zVers); |
| 1223 | @ at |
| @@ -1314,10 +1316,11 @@ | |
| 1316 | hyperlink_to_user(zUser,zDate," on"); |
| 1317 | hyperlink_to_date(zDate, "."); |
| 1318 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1319 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1320 | } |
| 1321 | tag_private_status(rid); |
| 1322 | cnt++; |
| 1323 | } |
| 1324 | db_finalize(&q); |
| 1325 | } |
| 1326 | db_prepare(&q, |
| @@ -1357,17 +1360,19 @@ | |
| 1360 | hyperlink_to_date(zDate,"."); |
| 1361 | cnt++; |
| 1362 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1363 | blob_append(pDownloadName, zFilename, -1); |
| 1364 | } |
| 1365 | tag_private_status(rid); |
| 1366 | } |
| 1367 | db_finalize(&q); |
| 1368 | if( cnt==0 ){ |
| 1369 | @ Control artifact. |
| 1370 | if( pDownloadName && blob_size(pDownloadName)==0 ){ |
| 1371 | blob_appendf(pDownloadName, "%.10s.txt", zUuid); |
| 1372 | } |
| 1373 | tag_private_status(rid); |
| 1374 | } |
| 1375 | return objType; |
| 1376 | } |
| 1377 | |
| 1378 | |
| 1379 |
+36
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -21,10 +21,11 @@ | ||
| 21 | 21 | $(SRCDIR)/bisect.c \ |
| 22 | 22 | $(SRCDIR)/blob.c \ |
| 23 | 23 | $(SRCDIR)/branch.c \ |
| 24 | 24 | $(SRCDIR)/browse.c \ |
| 25 | 25 | $(SRCDIR)/builtin.c \ |
| 26 | + $(SRCDIR)/bundle.c \ | |
| 26 | 27 | $(SRCDIR)/cache.c \ |
| 27 | 28 | $(SRCDIR)/captcha.c \ |
| 28 | 29 | $(SRCDIR)/cgi.c \ |
| 29 | 30 | $(SRCDIR)/checkin.c \ |
| 30 | 31 | $(SRCDIR)/checkout.c \ |
| @@ -87,10 +88,12 @@ | ||
| 87 | 88 | $(SRCDIR)/path.c \ |
| 88 | 89 | $(SRCDIR)/pivot.c \ |
| 89 | 90 | $(SRCDIR)/popen.c \ |
| 90 | 91 | $(SRCDIR)/pqueue.c \ |
| 91 | 92 | $(SRCDIR)/printf.c \ |
| 93 | + $(SRCDIR)/publish.c \ | |
| 94 | + $(SRCDIR)/purge.c \ | |
| 92 | 95 | $(SRCDIR)/rebuild.c \ |
| 93 | 96 | $(SRCDIR)/regexp.c \ |
| 94 | 97 | $(SRCDIR)/report.c \ |
| 95 | 98 | $(SRCDIR)/rss.c \ |
| 96 | 99 | $(SRCDIR)/schema.c \ |
| @@ -139,10 +142,11 @@ | ||
| 139 | 142 | $(OBJDIR)/bisect_.c \ |
| 140 | 143 | $(OBJDIR)/blob_.c \ |
| 141 | 144 | $(OBJDIR)/branch_.c \ |
| 142 | 145 | $(OBJDIR)/browse_.c \ |
| 143 | 146 | $(OBJDIR)/builtin_.c \ |
| 147 | + $(OBJDIR)/bundle_.c \ | |
| 144 | 148 | $(OBJDIR)/cache_.c \ |
| 145 | 149 | $(OBJDIR)/captcha_.c \ |
| 146 | 150 | $(OBJDIR)/cgi_.c \ |
| 147 | 151 | $(OBJDIR)/checkin_.c \ |
| 148 | 152 | $(OBJDIR)/checkout_.c \ |
| @@ -205,10 +209,12 @@ | ||
| 205 | 209 | $(OBJDIR)/path_.c \ |
| 206 | 210 | $(OBJDIR)/pivot_.c \ |
| 207 | 211 | $(OBJDIR)/popen_.c \ |
| 208 | 212 | $(OBJDIR)/pqueue_.c \ |
| 209 | 213 | $(OBJDIR)/printf_.c \ |
| 214 | + $(OBJDIR)/publish_.c \ | |
| 215 | + $(OBJDIR)/purge_.c \ | |
| 210 | 216 | $(OBJDIR)/rebuild_.c \ |
| 211 | 217 | $(OBJDIR)/regexp_.c \ |
| 212 | 218 | $(OBJDIR)/report_.c \ |
| 213 | 219 | $(OBJDIR)/rss_.c \ |
| 214 | 220 | $(OBJDIR)/schema_.c \ |
| @@ -254,10 +260,11 @@ | ||
| 254 | 260 | $(OBJDIR)/bisect.o \ |
| 255 | 261 | $(OBJDIR)/blob.o \ |
| 256 | 262 | $(OBJDIR)/branch.o \ |
| 257 | 263 | $(OBJDIR)/browse.o \ |
| 258 | 264 | $(OBJDIR)/builtin.o \ |
| 265 | + $(OBJDIR)/bundle.o \ | |
| 259 | 266 | $(OBJDIR)/cache.o \ |
| 260 | 267 | $(OBJDIR)/captcha.o \ |
| 261 | 268 | $(OBJDIR)/cgi.o \ |
| 262 | 269 | $(OBJDIR)/checkin.o \ |
| 263 | 270 | $(OBJDIR)/checkout.o \ |
| @@ -320,10 +327,12 @@ | ||
| 320 | 327 | $(OBJDIR)/path.o \ |
| 321 | 328 | $(OBJDIR)/pivot.o \ |
| 322 | 329 | $(OBJDIR)/popen.o \ |
| 323 | 330 | $(OBJDIR)/pqueue.o \ |
| 324 | 331 | $(OBJDIR)/printf.o \ |
| 332 | + $(OBJDIR)/publish.o \ | |
| 333 | + $(OBJDIR)/purge.o \ | |
| 325 | 334 | $(OBJDIR)/rebuild.o \ |
| 326 | 335 | $(OBJDIR)/regexp.o \ |
| 327 | 336 | $(OBJDIR)/report.o \ |
| 328 | 337 | $(OBJDIR)/rss.o \ |
| 329 | 338 | $(OBJDIR)/schema.o \ |
| @@ -478,10 +487,11 @@ | ||
| 478 | 487 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 479 | 488 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 480 | 489 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 481 | 490 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 482 | 491 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 492 | + $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \ | |
| 483 | 493 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 484 | 494 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 485 | 495 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 486 | 496 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 487 | 497 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -544,10 +554,12 @@ | ||
| 544 | 554 | $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| 545 | 555 | $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ |
| 546 | 556 | $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ |
| 547 | 557 | $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ |
| 548 | 558 | $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ |
| 559 | + $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ | |
| 560 | + $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ | |
| 549 | 561 | $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| 550 | 562 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ |
| 551 | 563 | $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ |
| 552 | 564 | $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ |
| 553 | 565 | $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ |
| @@ -660,10 +672,18 @@ | ||
| 660 | 672 | |
| 661 | 673 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 662 | 674 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 663 | 675 | |
| 664 | 676 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 677 | + | |
| 678 | +$(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(OBJDIR)/translate | |
| 679 | + $(OBJDIR)/translate $(SRCDIR)/bundle.c >$@ | |
| 680 | + | |
| 681 | +$(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h | |
| 682 | + $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c | |
| 683 | + | |
| 684 | +$(OBJDIR)/bundle.h: $(OBJDIR)/headers | |
| 665 | 685 | |
| 666 | 686 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate |
| 667 | 687 | $(OBJDIR)/translate $(SRCDIR)/cache.c >$@ |
| 668 | 688 | |
| 669 | 689 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| @@ -1188,10 +1208,26 @@ | ||
| 1188 | 1208 | |
| 1189 | 1209 | $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h |
| 1190 | 1210 | $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c |
| 1191 | 1211 | |
| 1192 | 1212 | $(OBJDIR)/printf.h: $(OBJDIR)/headers |
| 1213 | + | |
| 1214 | +$(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(OBJDIR)/translate | |
| 1215 | + $(OBJDIR)/translate $(SRCDIR)/publish.c >$@ | |
| 1216 | + | |
| 1217 | +$(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h | |
| 1218 | + $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c | |
| 1219 | + | |
| 1220 | +$(OBJDIR)/publish.h: $(OBJDIR)/headers | |
| 1221 | + | |
| 1222 | +$(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(OBJDIR)/translate | |
| 1223 | + $(OBJDIR)/translate $(SRCDIR)/purge.c >$@ | |
| 1224 | + | |
| 1225 | +$(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h | |
| 1226 | + $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c | |
| 1227 | + | |
| 1228 | +$(OBJDIR)/purge.h: $(OBJDIR)/headers | |
| 1193 | 1229 | |
| 1194 | 1230 | $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(OBJDIR)/translate |
| 1195 | 1231 | $(OBJDIR)/translate $(SRCDIR)/rebuild.c >$@ |
| 1196 | 1232 | |
| 1197 | 1233 | $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h |
| 1198 | 1234 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -21,10 +21,11 @@ | |
| 21 | $(SRCDIR)/bisect.c \ |
| 22 | $(SRCDIR)/blob.c \ |
| 23 | $(SRCDIR)/branch.c \ |
| 24 | $(SRCDIR)/browse.c \ |
| 25 | $(SRCDIR)/builtin.c \ |
| 26 | $(SRCDIR)/cache.c \ |
| 27 | $(SRCDIR)/captcha.c \ |
| 28 | $(SRCDIR)/cgi.c \ |
| 29 | $(SRCDIR)/checkin.c \ |
| 30 | $(SRCDIR)/checkout.c \ |
| @@ -87,10 +88,12 @@ | |
| 87 | $(SRCDIR)/path.c \ |
| 88 | $(SRCDIR)/pivot.c \ |
| 89 | $(SRCDIR)/popen.c \ |
| 90 | $(SRCDIR)/pqueue.c \ |
| 91 | $(SRCDIR)/printf.c \ |
| 92 | $(SRCDIR)/rebuild.c \ |
| 93 | $(SRCDIR)/regexp.c \ |
| 94 | $(SRCDIR)/report.c \ |
| 95 | $(SRCDIR)/rss.c \ |
| 96 | $(SRCDIR)/schema.c \ |
| @@ -139,10 +142,11 @@ | |
| 139 | $(OBJDIR)/bisect_.c \ |
| 140 | $(OBJDIR)/blob_.c \ |
| 141 | $(OBJDIR)/branch_.c \ |
| 142 | $(OBJDIR)/browse_.c \ |
| 143 | $(OBJDIR)/builtin_.c \ |
| 144 | $(OBJDIR)/cache_.c \ |
| 145 | $(OBJDIR)/captcha_.c \ |
| 146 | $(OBJDIR)/cgi_.c \ |
| 147 | $(OBJDIR)/checkin_.c \ |
| 148 | $(OBJDIR)/checkout_.c \ |
| @@ -205,10 +209,12 @@ | |
| 205 | $(OBJDIR)/path_.c \ |
| 206 | $(OBJDIR)/pivot_.c \ |
| 207 | $(OBJDIR)/popen_.c \ |
| 208 | $(OBJDIR)/pqueue_.c \ |
| 209 | $(OBJDIR)/printf_.c \ |
| 210 | $(OBJDIR)/rebuild_.c \ |
| 211 | $(OBJDIR)/regexp_.c \ |
| 212 | $(OBJDIR)/report_.c \ |
| 213 | $(OBJDIR)/rss_.c \ |
| 214 | $(OBJDIR)/schema_.c \ |
| @@ -254,10 +260,11 @@ | |
| 254 | $(OBJDIR)/bisect.o \ |
| 255 | $(OBJDIR)/blob.o \ |
| 256 | $(OBJDIR)/branch.o \ |
| 257 | $(OBJDIR)/browse.o \ |
| 258 | $(OBJDIR)/builtin.o \ |
| 259 | $(OBJDIR)/cache.o \ |
| 260 | $(OBJDIR)/captcha.o \ |
| 261 | $(OBJDIR)/cgi.o \ |
| 262 | $(OBJDIR)/checkin.o \ |
| 263 | $(OBJDIR)/checkout.o \ |
| @@ -320,10 +327,12 @@ | |
| 320 | $(OBJDIR)/path.o \ |
| 321 | $(OBJDIR)/pivot.o \ |
| 322 | $(OBJDIR)/popen.o \ |
| 323 | $(OBJDIR)/pqueue.o \ |
| 324 | $(OBJDIR)/printf.o \ |
| 325 | $(OBJDIR)/rebuild.o \ |
| 326 | $(OBJDIR)/regexp.o \ |
| 327 | $(OBJDIR)/report.o \ |
| 328 | $(OBJDIR)/rss.o \ |
| 329 | $(OBJDIR)/schema.o \ |
| @@ -478,10 +487,11 @@ | |
| 478 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 479 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 480 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 481 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 482 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 483 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 484 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 485 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 486 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 487 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -544,10 +554,12 @@ | |
| 544 | $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| 545 | $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ |
| 546 | $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ |
| 547 | $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ |
| 548 | $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ |
| 549 | $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| 550 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ |
| 551 | $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ |
| 552 | $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ |
| 553 | $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ |
| @@ -660,10 +672,18 @@ | |
| 660 | |
| 661 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 662 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 663 | |
| 664 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 665 | |
| 666 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate |
| 667 | $(OBJDIR)/translate $(SRCDIR)/cache.c >$@ |
| 668 | |
| 669 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| @@ -1188,10 +1208,26 @@ | |
| 1188 | |
| 1189 | $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h |
| 1190 | $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c |
| 1191 | |
| 1192 | $(OBJDIR)/printf.h: $(OBJDIR)/headers |
| 1193 | |
| 1194 | $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(OBJDIR)/translate |
| 1195 | $(OBJDIR)/translate $(SRCDIR)/rebuild.c >$@ |
| 1196 | |
| 1197 | $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h |
| 1198 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -21,10 +21,11 @@ | |
| 21 | $(SRCDIR)/bisect.c \ |
| 22 | $(SRCDIR)/blob.c \ |
| 23 | $(SRCDIR)/branch.c \ |
| 24 | $(SRCDIR)/browse.c \ |
| 25 | $(SRCDIR)/builtin.c \ |
| 26 | $(SRCDIR)/bundle.c \ |
| 27 | $(SRCDIR)/cache.c \ |
| 28 | $(SRCDIR)/captcha.c \ |
| 29 | $(SRCDIR)/cgi.c \ |
| 30 | $(SRCDIR)/checkin.c \ |
| 31 | $(SRCDIR)/checkout.c \ |
| @@ -87,10 +88,12 @@ | |
| 88 | $(SRCDIR)/path.c \ |
| 89 | $(SRCDIR)/pivot.c \ |
| 90 | $(SRCDIR)/popen.c \ |
| 91 | $(SRCDIR)/pqueue.c \ |
| 92 | $(SRCDIR)/printf.c \ |
| 93 | $(SRCDIR)/publish.c \ |
| 94 | $(SRCDIR)/purge.c \ |
| 95 | $(SRCDIR)/rebuild.c \ |
| 96 | $(SRCDIR)/regexp.c \ |
| 97 | $(SRCDIR)/report.c \ |
| 98 | $(SRCDIR)/rss.c \ |
| 99 | $(SRCDIR)/schema.c \ |
| @@ -139,10 +142,11 @@ | |
| 142 | $(OBJDIR)/bisect_.c \ |
| 143 | $(OBJDIR)/blob_.c \ |
| 144 | $(OBJDIR)/branch_.c \ |
| 145 | $(OBJDIR)/browse_.c \ |
| 146 | $(OBJDIR)/builtin_.c \ |
| 147 | $(OBJDIR)/bundle_.c \ |
| 148 | $(OBJDIR)/cache_.c \ |
| 149 | $(OBJDIR)/captcha_.c \ |
| 150 | $(OBJDIR)/cgi_.c \ |
| 151 | $(OBJDIR)/checkin_.c \ |
| 152 | $(OBJDIR)/checkout_.c \ |
| @@ -205,10 +209,12 @@ | |
| 209 | $(OBJDIR)/path_.c \ |
| 210 | $(OBJDIR)/pivot_.c \ |
| 211 | $(OBJDIR)/popen_.c \ |
| 212 | $(OBJDIR)/pqueue_.c \ |
| 213 | $(OBJDIR)/printf_.c \ |
| 214 | $(OBJDIR)/publish_.c \ |
| 215 | $(OBJDIR)/purge_.c \ |
| 216 | $(OBJDIR)/rebuild_.c \ |
| 217 | $(OBJDIR)/regexp_.c \ |
| 218 | $(OBJDIR)/report_.c \ |
| 219 | $(OBJDIR)/rss_.c \ |
| 220 | $(OBJDIR)/schema_.c \ |
| @@ -254,10 +260,11 @@ | |
| 260 | $(OBJDIR)/bisect.o \ |
| 261 | $(OBJDIR)/blob.o \ |
| 262 | $(OBJDIR)/branch.o \ |
| 263 | $(OBJDIR)/browse.o \ |
| 264 | $(OBJDIR)/builtin.o \ |
| 265 | $(OBJDIR)/bundle.o \ |
| 266 | $(OBJDIR)/cache.o \ |
| 267 | $(OBJDIR)/captcha.o \ |
| 268 | $(OBJDIR)/cgi.o \ |
| 269 | $(OBJDIR)/checkin.o \ |
| 270 | $(OBJDIR)/checkout.o \ |
| @@ -320,10 +327,12 @@ | |
| 327 | $(OBJDIR)/path.o \ |
| 328 | $(OBJDIR)/pivot.o \ |
| 329 | $(OBJDIR)/popen.o \ |
| 330 | $(OBJDIR)/pqueue.o \ |
| 331 | $(OBJDIR)/printf.o \ |
| 332 | $(OBJDIR)/publish.o \ |
| 333 | $(OBJDIR)/purge.o \ |
| 334 | $(OBJDIR)/rebuild.o \ |
| 335 | $(OBJDIR)/regexp.o \ |
| 336 | $(OBJDIR)/report.o \ |
| 337 | $(OBJDIR)/rss.o \ |
| 338 | $(OBJDIR)/schema.o \ |
| @@ -478,10 +487,11 @@ | |
| 487 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 488 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 489 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 490 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 491 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 492 | $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \ |
| 493 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 494 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 495 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 496 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 497 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -544,10 +554,12 @@ | |
| 554 | $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| 555 | $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ |
| 556 | $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ |
| 557 | $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ |
| 558 | $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ |
| 559 | $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ |
| 560 | $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ |
| 561 | $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| 562 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ |
| 563 | $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ |
| 564 | $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ |
| 565 | $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ |
| @@ -660,10 +672,18 @@ | |
| 672 | |
| 673 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 674 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 675 | |
| 676 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 677 | |
| 678 | $(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(OBJDIR)/translate |
| 679 | $(OBJDIR)/translate $(SRCDIR)/bundle.c >$@ |
| 680 | |
| 681 | $(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h |
| 682 | $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c |
| 683 | |
| 684 | $(OBJDIR)/bundle.h: $(OBJDIR)/headers |
| 685 | |
| 686 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate |
| 687 | $(OBJDIR)/translate $(SRCDIR)/cache.c >$@ |
| 688 | |
| 689 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| @@ -1188,10 +1208,26 @@ | |
| 1208 | |
| 1209 | $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h |
| 1210 | $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c |
| 1211 | |
| 1212 | $(OBJDIR)/printf.h: $(OBJDIR)/headers |
| 1213 | |
| 1214 | $(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(OBJDIR)/translate |
| 1215 | $(OBJDIR)/translate $(SRCDIR)/publish.c >$@ |
| 1216 | |
| 1217 | $(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h |
| 1218 | $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c |
| 1219 | |
| 1220 | $(OBJDIR)/publish.h: $(OBJDIR)/headers |
| 1221 | |
| 1222 | $(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(OBJDIR)/translate |
| 1223 | $(OBJDIR)/translate $(SRCDIR)/purge.c >$@ |
| 1224 | |
| 1225 | $(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h |
| 1226 | $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c |
| 1227 | |
| 1228 | $(OBJDIR)/purge.h: $(OBJDIR)/headers |
| 1229 | |
| 1230 | $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(OBJDIR)/translate |
| 1231 | $(OBJDIR)/translate $(SRCDIR)/rebuild.c >$@ |
| 1232 | |
| 1233 | $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h |
| 1234 |
+3
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -28,10 +28,11 @@ | ||
| 28 | 28 | bisect |
| 29 | 29 | blob |
| 30 | 30 | branch |
| 31 | 31 | browse |
| 32 | 32 | builtin |
| 33 | + bundle | |
| 33 | 34 | cache |
| 34 | 35 | captcha |
| 35 | 36 | cgi |
| 36 | 37 | checkin |
| 37 | 38 | checkout |
| @@ -93,10 +94,12 @@ | ||
| 93 | 94 | path |
| 94 | 95 | pivot |
| 95 | 96 | popen |
| 96 | 97 | pqueue |
| 97 | 98 | printf |
| 99 | + publish | |
| 100 | + purge | |
| 98 | 101 | rebuild |
| 99 | 102 | regexp |
| 100 | 103 | report |
| 101 | 104 | rss |
| 102 | 105 | schema |
| 103 | 106 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -28,10 +28,11 @@ | |
| 28 | bisect |
| 29 | blob |
| 30 | branch |
| 31 | browse |
| 32 | builtin |
| 33 | cache |
| 34 | captcha |
| 35 | cgi |
| 36 | checkin |
| 37 | checkout |
| @@ -93,10 +94,12 @@ | |
| 93 | path |
| 94 | pivot |
| 95 | popen |
| 96 | pqueue |
| 97 | printf |
| 98 | rebuild |
| 99 | regexp |
| 100 | report |
| 101 | rss |
| 102 | schema |
| 103 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -28,10 +28,11 @@ | |
| 28 | bisect |
| 29 | blob |
| 30 | branch |
| 31 | browse |
| 32 | builtin |
| 33 | bundle |
| 34 | cache |
| 35 | captcha |
| 36 | cgi |
| 37 | checkin |
| 38 | checkout |
| @@ -93,10 +94,12 @@ | |
| 94 | path |
| 95 | pivot |
| 96 | popen |
| 97 | pqueue |
| 98 | printf |
| 99 | publish |
| 100 | purge |
| 101 | rebuild |
| 102 | regexp |
| 103 | report |
| 104 | rss |
| 105 | schema |
| 106 |
+9
-2
| --- src/mkversion.c | ||
| +++ src/mkversion.c | ||
| @@ -7,10 +7,11 @@ | ||
| 7 | 7 | ** |
| 8 | 8 | ** Note that the manifest.uuid and manifest files are generated by Fossil. |
| 9 | 9 | */ |
| 10 | 10 | #include <stdio.h> |
| 11 | 11 | #include <string.h> |
| 12 | +#include <stdlib.h> | |
| 12 | 13 | |
| 13 | 14 | int main(int argc, char *argv[]){ |
| 14 | 15 | FILE *m,*u,*v; |
| 15 | 16 | char *z; |
| 16 | 17 | int i, x, d; |
| @@ -17,11 +18,14 @@ | ||
| 17 | 18 | char b[1000]; |
| 18 | 19 | char vx[1000]; |
| 19 | 20 | memset(b,0,sizeof(b)); |
| 20 | 21 | memset(vx,0,sizeof(vx)); |
| 21 | 22 | u = fopen(argv[1],"r"); |
| 22 | - fgets(b, sizeof(b)-1,u); | |
| 23 | + if( fgets(b, sizeof(b)-1,u)==0 ){ | |
| 24 | + fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]); | |
| 25 | + exit(1); | |
| 26 | + } | |
| 23 | 27 | fclose(u); |
| 24 | 28 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 25 | 29 | *z = 0; |
| 26 | 30 | printf("#define MANIFEST_UUID \"%s\"\n",b); |
| 27 | 31 | printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); |
| @@ -32,11 +36,14 @@ | ||
| 32 | 36 | printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2); |
| 33 | 37 | } |
| 34 | 38 | } |
| 35 | 39 | fclose(m); |
| 36 | 40 | v = fopen(argv[3],"r"); |
| 37 | - fgets(b, sizeof(b)-1,v); | |
| 41 | + if( fgets(b, sizeof(b)-1,v)==0 ){ | |
| 42 | + fprintf(stderr, "malformed VERSION file: %s\n", argv[3]); | |
| 43 | + exit(1); | |
| 44 | + } | |
| 38 | 45 | fclose(v); |
| 39 | 46 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 40 | 47 | *z = 0; |
| 41 | 48 | printf("#define RELEASE_VERSION \"%s\"\n", b); |
| 42 | 49 | x=0; |
| 43 | 50 |
| --- src/mkversion.c | |
| +++ src/mkversion.c | |
| @@ -7,10 +7,11 @@ | |
| 7 | ** |
| 8 | ** Note that the manifest.uuid and manifest files are generated by Fossil. |
| 9 | */ |
| 10 | #include <stdio.h> |
| 11 | #include <string.h> |
| 12 | |
| 13 | int main(int argc, char *argv[]){ |
| 14 | FILE *m,*u,*v; |
| 15 | char *z; |
| 16 | int i, x, d; |
| @@ -17,11 +18,14 @@ | |
| 17 | char b[1000]; |
| 18 | char vx[1000]; |
| 19 | memset(b,0,sizeof(b)); |
| 20 | memset(vx,0,sizeof(vx)); |
| 21 | u = fopen(argv[1],"r"); |
| 22 | fgets(b, sizeof(b)-1,u); |
| 23 | fclose(u); |
| 24 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 25 | *z = 0; |
| 26 | printf("#define MANIFEST_UUID \"%s\"\n",b); |
| 27 | printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); |
| @@ -32,11 +36,14 @@ | |
| 32 | printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2); |
| 33 | } |
| 34 | } |
| 35 | fclose(m); |
| 36 | v = fopen(argv[3],"r"); |
| 37 | fgets(b, sizeof(b)-1,v); |
| 38 | fclose(v); |
| 39 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 40 | *z = 0; |
| 41 | printf("#define RELEASE_VERSION \"%s\"\n", b); |
| 42 | x=0; |
| 43 |
| --- src/mkversion.c | |
| +++ src/mkversion.c | |
| @@ -7,10 +7,11 @@ | |
| 7 | ** |
| 8 | ** Note that the manifest.uuid and manifest files are generated by Fossil. |
| 9 | */ |
| 10 | #include <stdio.h> |
| 11 | #include <string.h> |
| 12 | #include <stdlib.h> |
| 13 | |
| 14 | int main(int argc, char *argv[]){ |
| 15 | FILE *m,*u,*v; |
| 16 | char *z; |
| 17 | int i, x, d; |
| @@ -17,11 +18,14 @@ | |
| 18 | char b[1000]; |
| 19 | char vx[1000]; |
| 20 | memset(b,0,sizeof(b)); |
| 21 | memset(vx,0,sizeof(vx)); |
| 22 | u = fopen(argv[1],"r"); |
| 23 | if( fgets(b, sizeof(b)-1,u)==0 ){ |
| 24 | fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]); |
| 25 | exit(1); |
| 26 | } |
| 27 | fclose(u); |
| 28 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 29 | *z = 0; |
| 30 | printf("#define MANIFEST_UUID \"%s\"\n",b); |
| 31 | printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); |
| @@ -32,11 +36,14 @@ | |
| 36 | printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2); |
| 37 | } |
| 38 | } |
| 39 | fclose(m); |
| 40 | v = fopen(argv[3],"r"); |
| 41 | if( fgets(b, sizeof(b)-1,v)==0 ){ |
| 42 | fprintf(stderr, "malformed VERSION file: %s\n", argv[3]); |
| 43 | exit(1); |
| 44 | } |
| 45 | fclose(v); |
| 46 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 47 | *z = 0; |
| 48 | printf("#define RELEASE_VERSION \"%s\"\n", b); |
| 49 | x=0; |
| 50 |
+265
-35
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -42,10 +42,44 @@ | ||
| 42 | 42 | if( z[7]!='-') return 0; |
| 43 | 43 | if( !fossil_isdigit(z[8]) ) return 0; |
| 44 | 44 | if( !fossil_isdigit(z[9]) ) return 0; |
| 45 | 45 | return 1; |
| 46 | 46 | } |
| 47 | + | |
| 48 | +/* | |
| 49 | +** Return the RID that is the "root" of the branch that contains | |
| 50 | +** check-in "rid" if inBranch==0 or the first check-in in the branch | |
| 51 | +** if inBranch==1. | |
| 52 | +*/ | |
| 53 | +int start_of_branch(int rid, int inBranch){ | |
| 54 | + Stmt q; | |
| 55 | + int rc; | |
| 56 | + char *zBr; | |
| 57 | + zBr = db_text("trunk","SELECT value FROM tagxref" | |
| 58 | + " WHERE rid=%d AND tagid=%d" | |
| 59 | + " AND tagtype>0", | |
| 60 | + rid, TAG_BRANCH); | |
| 61 | + db_prepare(&q, | |
| 62 | + "SELECT pid, EXISTS(SELECT 1 FROM tagxref" | |
| 63 | + " WHERE tagid=%d AND tagtype>0" | |
| 64 | + " AND value=%Q AND rid=plink.pid)" | |
| 65 | + " FROM plink" | |
| 66 | + " WHERE cid=:cid AND isprim", | |
| 67 | + TAG_BRANCH, zBr | |
| 68 | + ); | |
| 69 | + fossil_free(zBr); | |
| 70 | + do{ | |
| 71 | + db_reset(&q); | |
| 72 | + db_bind_int(&q, ":cid", rid); | |
| 73 | + rc = db_step(&q); | |
| 74 | + if( rc!=SQLITE_ROW ) break; | |
| 75 | + if( inBranch && db_column_int(&q,1)==0 ) break; | |
| 76 | + rid = db_column_int(&q, 0); | |
| 77 | + }while( db_column_int(&q, 1)==1 && rid>0 ); | |
| 78 | + db_finalize(&q); | |
| 79 | + return rid; | |
| 80 | +} | |
| 47 | 81 | |
| 48 | 82 | /* |
| 49 | 83 | ** Convert a symbolic name into a RID. Acceptable forms: |
| 50 | 84 | ** |
| 51 | 85 | ** * SHA1 hash |
| @@ -66,20 +100,28 @@ | ||
| 66 | 100 | ** Return the RID of the matching artifact. Or return 0 if the name does not |
| 67 | 101 | ** match any known object. Or return -1 if the name is ambiguous. |
| 68 | 102 | ** |
| 69 | 103 | ** The zType parameter specifies the type of artifact: ci, t, w, e, g. |
| 70 | 104 | ** If zType is NULL or "" or "*" then any type of artifact will serve. |
| 105 | +** If zType is "br" then find the first check-in of the named branch | |
| 106 | +** rather than the last. | |
| 71 | 107 | ** zType is "ci" in most use cases since we are usually searching for |
| 72 | 108 | ** a check-in. |
| 73 | 109 | */ |
| 74 | 110 | int symbolic_name_to_rid(const char *zTag, const char *zType){ |
| 75 | 111 | int vid; |
| 76 | 112 | int rid = 0; |
| 77 | 113 | int nTag; |
| 78 | 114 | int i; |
| 115 | + int startOfBranch = 0; | |
| 79 | 116 | |
| 80 | - if( zType==0 || zType[0]==0 ) zType = "*"; | |
| 117 | + if( zType==0 || zType[0]==0 ){ | |
| 118 | + zType = "*"; | |
| 119 | + }else if( zType[0]=='b' ){ | |
| 120 | + zType = "ci"; | |
| 121 | + startOfBranch = 1; | |
| 122 | + } | |
| 81 | 123 | if( zTag==0 || zTag[0]==0 ) return 0; |
| 82 | 124 | |
| 83 | 125 | /* special keyword: "tip" */ |
| 84 | 126 | if( fossil_strcmp(zTag, "tip")==0 && (zType[0]=='*' || zType[0]=='c') ){ |
| 85 | 127 | rid = db_int(0, |
| @@ -151,41 +193,18 @@ | ||
| 151 | 193 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 152 | 194 | " AND event.objid=tagxref.rid " |
| 153 | 195 | " AND event.type GLOB '%q'", |
| 154 | 196 | &zTag[4], zType |
| 155 | 197 | ); |
| 198 | + if( startOfBranch ) rid = start_of_branch(rid,1); | |
| 156 | 199 | return rid; |
| 157 | 200 | } |
| 158 | 201 | |
| 159 | 202 | /* root:TAG -> The origin of the branch */ |
| 160 | 203 | if( memcmp(zTag, "root:", 5)==0 ){ |
| 161 | - Stmt q; | |
| 162 | - int rc; | |
| 163 | - char *zBr; | |
| 164 | 204 | rid = symbolic_name_to_rid(zTag+5, zType); |
| 165 | - zBr = db_text("trunk","SELECT value FROM tagxref" | |
| 166 | - " WHERE rid=%d AND tagid=%d" | |
| 167 | - " AND tagtype>0", | |
| 168 | - rid, TAG_BRANCH); | |
| 169 | - db_prepare(&q, | |
| 170 | - "SELECT pid, EXISTS(SELECT 1 FROM tagxref" | |
| 171 | - " WHERE tagid=%d AND tagtype>0" | |
| 172 | - " AND value=%Q AND rid=plink.pid)" | |
| 173 | - " FROM plink" | |
| 174 | - " WHERE cid=:cid AND isprim", | |
| 175 | - TAG_BRANCH, zBr | |
| 176 | - ); | |
| 177 | - fossil_free(zBr); | |
| 178 | - do{ | |
| 179 | - db_reset(&q); | |
| 180 | - db_bind_int(&q, ":cid", rid); | |
| 181 | - rc = db_step(&q); | |
| 182 | - if( rc!=SQLITE_ROW ) break; | |
| 183 | - rid = db_column_int(&q, 0); | |
| 184 | - }while( db_column_int(&q, 1)==1 && rid>0 ); | |
| 185 | - db_finalize(&q); | |
| 186 | - return rid; | |
| 205 | + return start_of_branch(rid, 0); | |
| 187 | 206 | } |
| 188 | 207 | |
| 189 | 208 | /* symbolic-name ":" date-time */ |
| 190 | 209 | nTag = strlen(zTag); |
| 191 | 210 | for(i=0; i<nTag-10 && zTag[i]!=':'; i++){} |
| @@ -245,11 +264,14 @@ | ||
| 245 | 264 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 246 | 265 | " AND event.objid=tagxref.rid " |
| 247 | 266 | " AND event.type GLOB '%q'", |
| 248 | 267 | zTag, zType |
| 249 | 268 | ); |
| 250 | - if( rid>0 ) return rid; | |
| 269 | + if( rid>0 ){ | |
| 270 | + if( startOfBranch ) rid = start_of_branch(rid,1); | |
| 271 | + return rid; | |
| 272 | + } | |
| 251 | 273 | |
| 252 | 274 | /* Undocumented: numeric tags get translated directly into the RID */ |
| 253 | 275 | if( memcmp(zTag, "rid:", 4)==0 ){ |
| 254 | 276 | zTag += 4; |
| 255 | 277 | for(i=0; fossil_isdigit(zTag[i]); i++){} |
| @@ -391,18 +413,15 @@ | ||
| 391 | 413 | int rid; |
| 392 | 414 | |
| 393 | 415 | if( zName==0 || zName[0]==0 ) return 0; |
| 394 | 416 | rid = symbolic_name_to_rid(zName, zType); |
| 395 | 417 | if( rid<0 ){ |
| 396 | - fossil_error(1, "ambiguous name: %s", zName); | |
| 397 | - return 0; | |
| 418 | + fossil_fatal("ambiguous name: %s", zName); | |
| 398 | 419 | }else if( rid==0 ){ |
| 399 | - fossil_error(1, "not found: %s", zName); | |
| 400 | - return 0; | |
| 401 | - }else{ | |
| 402 | - return rid; | |
| 420 | + fossil_fatal("not found: %s", zName); | |
| 403 | 421 | } |
| 422 | + return rid; | |
| 404 | 423 | } |
| 405 | 424 | int name_to_rid(const char *zName){ |
| 406 | 425 | return name_to_typed_rid(zName, "*"); |
| 407 | 426 | } |
| 408 | 427 | |
| @@ -505,11 +524,11 @@ | ||
| 505 | 524 | } |
| 506 | 525 | |
| 507 | 526 | /* |
| 508 | 527 | ** Generate a description of artifact "rid" |
| 509 | 528 | */ |
| 510 | -static void whatis_rid(int rid, int verboseFlag){ | |
| 529 | +void whatis_rid(int rid, int verboseFlag){ | |
| 511 | 530 | Stmt q; |
| 512 | 531 | int cnt; |
| 513 | 532 | |
| 514 | 533 | /* Basic information about the object. */ |
| 515 | 534 | db_prepare(&q, |
| @@ -657,21 +676,23 @@ | ||
| 657 | 676 | void whatis_cmd(void){ |
| 658 | 677 | int rid; |
| 659 | 678 | const char *zName; |
| 660 | 679 | int verboseFlag; |
| 661 | 680 | int i; |
| 681 | + const char *zType = 0; | |
| 662 | 682 | db_find_and_open_repository(0,0); |
| 663 | 683 | verboseFlag = find_option("verbose","v",0)!=0; |
| 684 | + zType = find_option("type",0,1); | |
| 664 | 685 | |
| 665 | 686 | /* We should be done with options.. */ |
| 666 | 687 | verify_all_options(); |
| 667 | 688 | |
| 668 | 689 | if( g.argc<3 ) usage("whatis NAME ..."); |
| 669 | 690 | for(i=2; i<g.argc; i++){ |
| 670 | 691 | zName = g.argv[i]; |
| 671 | 692 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 672 | - rid = symbolic_name_to_rid(zName, 0); | |
| 693 | + rid = symbolic_name_to_rid(zName, zType); | |
| 673 | 694 | if( rid<0 ){ |
| 674 | 695 | Stmt q; |
| 675 | 696 | int cnt = 0; |
| 676 | 697 | fossil_print("name: %s (ambiguous)\n", zName); |
| 677 | 698 | db_prepare(&q, |
| @@ -757,5 +778,214 @@ | ||
| 757 | 778 | while( db_step(&q)==SQLITE_ROW ){ |
| 758 | 779 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 759 | 780 | } |
| 760 | 781 | db_finalize(&q); |
| 761 | 782 | } |
| 783 | + | |
| 784 | +/* | |
| 785 | +** Schema for the description table | |
| 786 | +*/ | |
| 787 | +static const char zDescTab[] = | |
| 788 | +@ CREATE TEMP TABLE IF NOT EXISTS description( | |
| 789 | +@ rid INTEGER PRIMARY KEY, -- RID of the object | |
| 790 | +@ uuid TEXT, -- SHA1 hash of the object | |
| 791 | +@ ctime DATETIME, -- Time of creation | |
| 792 | +@ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts | |
| 793 | +@ type TEXT, -- file, checkin, wiki, ticket, etc. | |
| 794 | +@ summary TEXT, -- Summary comment for the object | |
| 795 | +@ detail TEXT -- filename, checkin comment, etc | |
| 796 | +@ ); | |
| 797 | +; | |
| 798 | + | |
| 799 | +/* | |
| 800 | +** Create the description table if it does not already exists. | |
| 801 | +** Populate fields of this table with descriptions for all artifacts | |
| 802 | +** whose RID matches the SQL expression in zWhere. | |
| 803 | +*/ | |
| 804 | +void describe_artifacts(const char *zWhere){ | |
| 805 | + db_multi_exec("%s", zDescTab/*safe-for-%s*/); | |
| 806 | + | |
| 807 | + /* Describe checkins */ | |
| 808 | + db_multi_exec( | |
| 809 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 810 | + "SELECT blob.rid, blob.uuid, event.mtime, 'checkin',\n" | |
| 811 | + " 'checkin on ' || strftime('%%Y-%%m-%%d %%H:%%M',event.mtime)\n" | |
| 812 | + " FROM event, blob\n" | |
| 813 | + " WHERE event.objid %s AND event.type='ci'\n" | |
| 814 | + " AND event.objid=blob.rid;", | |
| 815 | + zWhere /*safe-for-%s*/ | |
| 816 | + ); | |
| 817 | + | |
| 818 | + /* Describe files */ | |
| 819 | + db_multi_exec( | |
| 820 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 821 | + "SELECT blob.rid, blob.uuid, event.mtime, 'file', 'file '||filename.name\n" | |
| 822 | + " FROM mlink, blob, event, filename\n" | |
| 823 | + " WHERE mlink.fid %s\n" | |
| 824 | + " AND mlink.mid=event.objid\n" | |
| 825 | + " AND filename.fnid=mlink.fnid\n" | |
| 826 | + " AND mlink.fid=blob.rid;", | |
| 827 | + zWhere /*safe-for-%s*/ | |
| 828 | + ); | |
| 829 | + | |
| 830 | + /* Describe tags */ | |
| 831 | + db_multi_exec( | |
| 832 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 833 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n" | |
| 834 | + " 'tag '||substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n" | |
| 835 | + " FROM tagxref, blob\n" | |
| 836 | + " WHERE tagxref.srcid %s AND tagxref.srcid!=tagxref.rid\n" | |
| 837 | + " AND tagxref.srcid=blob.rid;", | |
| 838 | + zWhere /*safe-for-%s*/ | |
| 839 | + ); | |
| 840 | + | |
| 841 | + /* Cluster artifacts */ | |
| 842 | + db_multi_exec( | |
| 843 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 844 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster', 'cluster'\n" | |
| 845 | + " FROM tagxref, blob\n" | |
| 846 | + " WHERE tagxref.rid %s\n" | |
| 847 | + " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n" | |
| 848 | + " AND blob.rid=tagxref.rid;", | |
| 849 | + zWhere /*safe-for-%s*/ | |
| 850 | + ); | |
| 851 | + | |
| 852 | + /* Ticket change artifacts */ | |
| 853 | + db_multi_exec( | |
| 854 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 855 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n" | |
| 856 | + " 'ticket '||substr(tag.tagname,5,21)\n" | |
| 857 | + " FROM tagxref, tag, blob\n" | |
| 858 | + " WHERE tagxref.rid %s\n" | |
| 859 | + " AND tag.tagid=tagxref.tagid\n" | |
| 860 | + " AND tag.tagname GLOB 'tkt-*'" | |
| 861 | + " AND blob.rid=tagxref.rid;", | |
| 862 | + zWhere /*safe-for-%s*/ | |
| 863 | + ); | |
| 864 | + | |
| 865 | + /* Wiki edit artifacts */ | |
| 866 | + db_multi_exec( | |
| 867 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 868 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n" | |
| 869 | + " printf('wiki \"%%s\"',substr(tag.tagname,6))\n" | |
| 870 | + " FROM tagxref, tag, blob\n" | |
| 871 | + " WHERE tagxref.rid %s\n" | |
| 872 | + " AND tag.tagid=tagxref.tagid\n" | |
| 873 | + " AND tag.tagname GLOB 'wiki-*'" | |
| 874 | + " AND blob.rid=tagxref.rid;", | |
| 875 | + zWhere /*safe-for-%s*/ | |
| 876 | + ); | |
| 877 | + | |
| 878 | + /* Event edit artifacts */ | |
| 879 | + db_multi_exec( | |
| 880 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" | |
| 881 | + "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n" | |
| 882 | + " 'event '||substr(tag.tagname,7)\n" | |
| 883 | + " FROM tagxref, tag, blob\n" | |
| 884 | + " WHERE tagxref.rid %s\n" | |
| 885 | + " AND tag.tagid=tagxref.tagid\n" | |
| 886 | + " AND tag.tagname GLOB 'event-*'" | |
| 887 | + " AND blob.rid=tagxref.rid;", | |
| 888 | + zWhere /*safe-for-%s*/ | |
| 889 | + ); | |
| 890 | + | |
| 891 | + /* Attachments */ | |
| 892 | + db_multi_exec( | |
| 893 | + "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" | |
| 894 | + "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n" | |
| 895 | + " 'attachment '||attachment.filename\n" | |
| 896 | + " FROM attachment, blob\n" | |
| 897 | + " WHERE attachment.src %s\n" | |
| 898 | + " AND blob.rid=attachment.src;", | |
| 899 | + zWhere /*safe-for-%s*/ | |
| 900 | + ); | |
| 901 | + | |
| 902 | + /* Everything else */ | |
| 903 | + db_multi_exec( | |
| 904 | + "INSERT OR IGNORE INTO description(rid,uuid,type,summary)\n" | |
| 905 | + "SELECT blob.rid, blob.uuid," | |
| 906 | + " CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n" | |
| 907 | + " 'unknown'\n" | |
| 908 | + " FROM blob WHERE blob.rid %s;", | |
| 909 | + zWhere /*safe-for-%s*/ | |
| 910 | + ); | |
| 911 | + | |
| 912 | + /* Mark private elements */ | |
| 913 | + db_multi_exec( | |
| 914 | + "UPDATE description SET isPrivate=1 WHERE rid IN private" | |
| 915 | + ); | |
| 916 | +} | |
| 917 | + | |
| 918 | +/* | |
| 919 | +** Print the content of the description table on stdout | |
| 920 | +*/ | |
| 921 | +int describe_artifacts_to_stdout(const char *zWhere, const char *zLabel){ | |
| 922 | + Stmt q; | |
| 923 | + int cnt = 0; | |
| 924 | + describe_artifacts(zWhere); | |
| 925 | + db_prepare(&q, | |
| 926 | + "SELECT uuid, summary, isPrivate\n" | |
| 927 | + " FROM description\n" | |
| 928 | + " ORDER BY ctime, type;" | |
| 929 | + ); | |
| 930 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 931 | + if( zLabel ){ | |
| 932 | + fossil_print("%s\n", zLabel); | |
| 933 | + zLabel = 0; | |
| 934 | + } | |
| 935 | + fossil_print(" %.16s %s", db_column_text(&q,0), db_column_text(&q,1)); | |
| 936 | + if( db_column_int(&q,2) ) fossil_print(" (unpublished)"); | |
| 937 | + fossil_print("\n"); | |
| 938 | + cnt++; | |
| 939 | + } | |
| 940 | + db_finalize(&q); | |
| 941 | + db_multi_exec("DELETE FROM description;"); | |
| 942 | + return cnt; | |
| 943 | +} | |
| 944 | + | |
| 945 | +/* | |
| 946 | +** COMMAND: test-describe-artifacts | |
| 947 | +** | |
| 948 | +** Usage: %fossil test-describe-artifacts | |
| 949 | +** | |
| 950 | +** Display a one-line description of every artifact. | |
| 951 | +*/ | |
| 952 | +void test_describe_artifacts_cmd(void){ | |
| 953 | + db_find_and_open_repository(0,0); | |
| 954 | + describe_artifacts_to_stdout("IN (SELECT rid FROM blob)", 0); | |
| 955 | +} | |
| 956 | + | |
| 957 | +/* | |
| 958 | +** COMMAND: test-unsent | |
| 959 | +** | |
| 960 | +** Usage: %fossil test-unsent | |
| 961 | +** | |
| 962 | +** Show all artifacts in the unsent table | |
| 963 | +*/ | |
| 964 | +void test_unsent_cmd(void){ | |
| 965 | + db_find_and_open_repository(0,0); | |
| 966 | + describe_artifacts_to_stdout("IN unsent", 0); | |
| 967 | +} | |
| 968 | + | |
| 969 | +/* | |
| 970 | +** COMMAND: test-unclustered | |
| 971 | +** | |
| 972 | +** Usage: %fossil test-unclustered | |
| 973 | +** | |
| 974 | +** Show all artifacts in the unclustered table | |
| 975 | +*/ | |
| 976 | +void test_unclusterd_cmd(void){ | |
| 977 | + db_find_and_open_repository(0,0); | |
| 978 | + describe_artifacts_to_stdout("IN unclustered", 0); | |
| 979 | +} | |
| 980 | + | |
| 981 | +/* | |
| 982 | +** COMMAND: test-phantoms | |
| 983 | +** | |
| 984 | +** Usage: %fossil test-phantoms | |
| 985 | +** | |
| 986 | +** Show all phantom artifacts | |
| 987 | +*/ | |
| 988 | +void test_phatoms_cmd(void){ | |
| 989 | + db_find_and_open_repository(0,0); | |
| 990 | + describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0); | |
| 991 | +} | |
| 762 | 992 | |
| 763 | 993 | ADDED src/publish.c |
| 764 | 994 | ADDED src/purge.c |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -42,10 +42,44 @@ | |
| 42 | if( z[7]!='-') return 0; |
| 43 | if( !fossil_isdigit(z[8]) ) return 0; |
| 44 | if( !fossil_isdigit(z[9]) ) return 0; |
| 45 | return 1; |
| 46 | } |
| 47 | |
| 48 | /* |
| 49 | ** Convert a symbolic name into a RID. Acceptable forms: |
| 50 | ** |
| 51 | ** * SHA1 hash |
| @@ -66,20 +100,28 @@ | |
| 66 | ** Return the RID of the matching artifact. Or return 0 if the name does not |
| 67 | ** match any known object. Or return -1 if the name is ambiguous. |
| 68 | ** |
| 69 | ** The zType parameter specifies the type of artifact: ci, t, w, e, g. |
| 70 | ** If zType is NULL or "" or "*" then any type of artifact will serve. |
| 71 | ** zType is "ci" in most use cases since we are usually searching for |
| 72 | ** a check-in. |
| 73 | */ |
| 74 | int symbolic_name_to_rid(const char *zTag, const char *zType){ |
| 75 | int vid; |
| 76 | int rid = 0; |
| 77 | int nTag; |
| 78 | int i; |
| 79 | |
| 80 | if( zType==0 || zType[0]==0 ) zType = "*"; |
| 81 | if( zTag==0 || zTag[0]==0 ) return 0; |
| 82 | |
| 83 | /* special keyword: "tip" */ |
| 84 | if( fossil_strcmp(zTag, "tip")==0 && (zType[0]=='*' || zType[0]=='c') ){ |
| 85 | rid = db_int(0, |
| @@ -151,41 +193,18 @@ | |
| 151 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 152 | " AND event.objid=tagxref.rid " |
| 153 | " AND event.type GLOB '%q'", |
| 154 | &zTag[4], zType |
| 155 | ); |
| 156 | return rid; |
| 157 | } |
| 158 | |
| 159 | /* root:TAG -> The origin of the branch */ |
| 160 | if( memcmp(zTag, "root:", 5)==0 ){ |
| 161 | Stmt q; |
| 162 | int rc; |
| 163 | char *zBr; |
| 164 | rid = symbolic_name_to_rid(zTag+5, zType); |
| 165 | zBr = db_text("trunk","SELECT value FROM tagxref" |
| 166 | " WHERE rid=%d AND tagid=%d" |
| 167 | " AND tagtype>0", |
| 168 | rid, TAG_BRANCH); |
| 169 | db_prepare(&q, |
| 170 | "SELECT pid, EXISTS(SELECT 1 FROM tagxref" |
| 171 | " WHERE tagid=%d AND tagtype>0" |
| 172 | " AND value=%Q AND rid=plink.pid)" |
| 173 | " FROM plink" |
| 174 | " WHERE cid=:cid AND isprim", |
| 175 | TAG_BRANCH, zBr |
| 176 | ); |
| 177 | fossil_free(zBr); |
| 178 | do{ |
| 179 | db_reset(&q); |
| 180 | db_bind_int(&q, ":cid", rid); |
| 181 | rc = db_step(&q); |
| 182 | if( rc!=SQLITE_ROW ) break; |
| 183 | rid = db_column_int(&q, 0); |
| 184 | }while( db_column_int(&q, 1)==1 && rid>0 ); |
| 185 | db_finalize(&q); |
| 186 | return rid; |
| 187 | } |
| 188 | |
| 189 | /* symbolic-name ":" date-time */ |
| 190 | nTag = strlen(zTag); |
| 191 | for(i=0; i<nTag-10 && zTag[i]!=':'; i++){} |
| @@ -245,11 +264,14 @@ | |
| 245 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 246 | " AND event.objid=tagxref.rid " |
| 247 | " AND event.type GLOB '%q'", |
| 248 | zTag, zType |
| 249 | ); |
| 250 | if( rid>0 ) return rid; |
| 251 | |
| 252 | /* Undocumented: numeric tags get translated directly into the RID */ |
| 253 | if( memcmp(zTag, "rid:", 4)==0 ){ |
| 254 | zTag += 4; |
| 255 | for(i=0; fossil_isdigit(zTag[i]); i++){} |
| @@ -391,18 +413,15 @@ | |
| 391 | int rid; |
| 392 | |
| 393 | if( zName==0 || zName[0]==0 ) return 0; |
| 394 | rid = symbolic_name_to_rid(zName, zType); |
| 395 | if( rid<0 ){ |
| 396 | fossil_error(1, "ambiguous name: %s", zName); |
| 397 | return 0; |
| 398 | }else if( rid==0 ){ |
| 399 | fossil_error(1, "not found: %s", zName); |
| 400 | return 0; |
| 401 | }else{ |
| 402 | return rid; |
| 403 | } |
| 404 | } |
| 405 | int name_to_rid(const char *zName){ |
| 406 | return name_to_typed_rid(zName, "*"); |
| 407 | } |
| 408 | |
| @@ -505,11 +524,11 @@ | |
| 505 | } |
| 506 | |
| 507 | /* |
| 508 | ** Generate a description of artifact "rid" |
| 509 | */ |
| 510 | static void whatis_rid(int rid, int verboseFlag){ |
| 511 | Stmt q; |
| 512 | int cnt; |
| 513 | |
| 514 | /* Basic information about the object. */ |
| 515 | db_prepare(&q, |
| @@ -657,21 +676,23 @@ | |
| 657 | void whatis_cmd(void){ |
| 658 | int rid; |
| 659 | const char *zName; |
| 660 | int verboseFlag; |
| 661 | int i; |
| 662 | db_find_and_open_repository(0,0); |
| 663 | verboseFlag = find_option("verbose","v",0)!=0; |
| 664 | |
| 665 | /* We should be done with options.. */ |
| 666 | verify_all_options(); |
| 667 | |
| 668 | if( g.argc<3 ) usage("whatis NAME ..."); |
| 669 | for(i=2; i<g.argc; i++){ |
| 670 | zName = g.argv[i]; |
| 671 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 672 | rid = symbolic_name_to_rid(zName, 0); |
| 673 | if( rid<0 ){ |
| 674 | Stmt q; |
| 675 | int cnt = 0; |
| 676 | fossil_print("name: %s (ambiguous)\n", zName); |
| 677 | db_prepare(&q, |
| @@ -757,5 +778,214 @@ | |
| 757 | while( db_step(&q)==SQLITE_ROW ){ |
| 758 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 759 | } |
| 760 | db_finalize(&q); |
| 761 | } |
| 762 | |
| 763 | DDED src/publish.c |
| 764 | DDED src/purge.c |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -42,10 +42,44 @@ | |
| 42 | if( z[7]!='-') return 0; |
| 43 | if( !fossil_isdigit(z[8]) ) return 0; |
| 44 | if( !fossil_isdigit(z[9]) ) return 0; |
| 45 | return 1; |
| 46 | } |
| 47 | |
| 48 | /* |
| 49 | ** Return the RID that is the "root" of the branch that contains |
| 50 | ** check-in "rid" if inBranch==0 or the first check-in in the branch |
| 51 | ** if inBranch==1. |
| 52 | */ |
| 53 | int start_of_branch(int rid, int inBranch){ |
| 54 | Stmt q; |
| 55 | int rc; |
| 56 | char *zBr; |
| 57 | zBr = db_text("trunk","SELECT value FROM tagxref" |
| 58 | " WHERE rid=%d AND tagid=%d" |
| 59 | " AND tagtype>0", |
| 60 | rid, TAG_BRANCH); |
| 61 | db_prepare(&q, |
| 62 | "SELECT pid, EXISTS(SELECT 1 FROM tagxref" |
| 63 | " WHERE tagid=%d AND tagtype>0" |
| 64 | " AND value=%Q AND rid=plink.pid)" |
| 65 | " FROM plink" |
| 66 | " WHERE cid=:cid AND isprim", |
| 67 | TAG_BRANCH, zBr |
| 68 | ); |
| 69 | fossil_free(zBr); |
| 70 | do{ |
| 71 | db_reset(&q); |
| 72 | db_bind_int(&q, ":cid", rid); |
| 73 | rc = db_step(&q); |
| 74 | if( rc!=SQLITE_ROW ) break; |
| 75 | if( inBranch && db_column_int(&q,1)==0 ) break; |
| 76 | rid = db_column_int(&q, 0); |
| 77 | }while( db_column_int(&q, 1)==1 && rid>0 ); |
| 78 | db_finalize(&q); |
| 79 | return rid; |
| 80 | } |
| 81 | |
| 82 | /* |
| 83 | ** Convert a symbolic name into a RID. Acceptable forms: |
| 84 | ** |
| 85 | ** * SHA1 hash |
| @@ -66,20 +100,28 @@ | |
| 100 | ** Return the RID of the matching artifact. Or return 0 if the name does not |
| 101 | ** match any known object. Or return -1 if the name is ambiguous. |
| 102 | ** |
| 103 | ** The zType parameter specifies the type of artifact: ci, t, w, e, g. |
| 104 | ** If zType is NULL or "" or "*" then any type of artifact will serve. |
| 105 | ** If zType is "br" then find the first check-in of the named branch |
| 106 | ** rather than the last. |
| 107 | ** zType is "ci" in most use cases since we are usually searching for |
| 108 | ** a check-in. |
| 109 | */ |
| 110 | int symbolic_name_to_rid(const char *zTag, const char *zType){ |
| 111 | int vid; |
| 112 | int rid = 0; |
| 113 | int nTag; |
| 114 | int i; |
| 115 | int startOfBranch = 0; |
| 116 | |
| 117 | if( zType==0 || zType[0]==0 ){ |
| 118 | zType = "*"; |
| 119 | }else if( zType[0]=='b' ){ |
| 120 | zType = "ci"; |
| 121 | startOfBranch = 1; |
| 122 | } |
| 123 | if( zTag==0 || zTag[0]==0 ) return 0; |
| 124 | |
| 125 | /* special keyword: "tip" */ |
| 126 | if( fossil_strcmp(zTag, "tip")==0 && (zType[0]=='*' || zType[0]=='c') ){ |
| 127 | rid = db_int(0, |
| @@ -151,41 +193,18 @@ | |
| 193 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 194 | " AND event.objid=tagxref.rid " |
| 195 | " AND event.type GLOB '%q'", |
| 196 | &zTag[4], zType |
| 197 | ); |
| 198 | if( startOfBranch ) rid = start_of_branch(rid,1); |
| 199 | return rid; |
| 200 | } |
| 201 | |
| 202 | /* root:TAG -> The origin of the branch */ |
| 203 | if( memcmp(zTag, "root:", 5)==0 ){ |
| 204 | rid = symbolic_name_to_rid(zTag+5, zType); |
| 205 | return start_of_branch(rid, 0); |
| 206 | } |
| 207 | |
| 208 | /* symbolic-name ":" date-time */ |
| 209 | nTag = strlen(zTag); |
| 210 | for(i=0; i<nTag-10 && zTag[i]!=':'; i++){} |
| @@ -245,11 +264,14 @@ | |
| 264 | " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " |
| 265 | " AND event.objid=tagxref.rid " |
| 266 | " AND event.type GLOB '%q'", |
| 267 | zTag, zType |
| 268 | ); |
| 269 | if( rid>0 ){ |
| 270 | if( startOfBranch ) rid = start_of_branch(rid,1); |
| 271 | return rid; |
| 272 | } |
| 273 | |
| 274 | /* Undocumented: numeric tags get translated directly into the RID */ |
| 275 | if( memcmp(zTag, "rid:", 4)==0 ){ |
| 276 | zTag += 4; |
| 277 | for(i=0; fossil_isdigit(zTag[i]); i++){} |
| @@ -391,18 +413,15 @@ | |
| 413 | int rid; |
| 414 | |
| 415 | if( zName==0 || zName[0]==0 ) return 0; |
| 416 | rid = symbolic_name_to_rid(zName, zType); |
| 417 | if( rid<0 ){ |
| 418 | fossil_fatal("ambiguous name: %s", zName); |
| 419 | }else if( rid==0 ){ |
| 420 | fossil_fatal("not found: %s", zName); |
| 421 | } |
| 422 | return rid; |
| 423 | } |
| 424 | int name_to_rid(const char *zName){ |
| 425 | return name_to_typed_rid(zName, "*"); |
| 426 | } |
| 427 | |
| @@ -505,11 +524,11 @@ | |
| 524 | } |
| 525 | |
| 526 | /* |
| 527 | ** Generate a description of artifact "rid" |
| 528 | */ |
| 529 | void whatis_rid(int rid, int verboseFlag){ |
| 530 | Stmt q; |
| 531 | int cnt; |
| 532 | |
| 533 | /* Basic information about the object. */ |
| 534 | db_prepare(&q, |
| @@ -657,21 +676,23 @@ | |
| 676 | void whatis_cmd(void){ |
| 677 | int rid; |
| 678 | const char *zName; |
| 679 | int verboseFlag; |
| 680 | int i; |
| 681 | const char *zType = 0; |
| 682 | db_find_and_open_repository(0,0); |
| 683 | verboseFlag = find_option("verbose","v",0)!=0; |
| 684 | zType = find_option("type",0,1); |
| 685 | |
| 686 | /* We should be done with options.. */ |
| 687 | verify_all_options(); |
| 688 | |
| 689 | if( g.argc<3 ) usage("whatis NAME ..."); |
| 690 | for(i=2; i<g.argc; i++){ |
| 691 | zName = g.argv[i]; |
| 692 | if( i>2 ) fossil_print("%.79c\n",'-'); |
| 693 | rid = symbolic_name_to_rid(zName, zType); |
| 694 | if( rid<0 ){ |
| 695 | Stmt q; |
| 696 | int cnt = 0; |
| 697 | fossil_print("name: %s (ambiguous)\n", zName); |
| 698 | db_prepare(&q, |
| @@ -757,5 +778,214 @@ | |
| 778 | while( db_step(&q)==SQLITE_ROW ){ |
| 779 | fossil_print("%s\n", db_column_text(&q, 0)); |
| 780 | } |
| 781 | db_finalize(&q); |
| 782 | } |
| 783 | |
| 784 | /* |
| 785 | ** Schema for the description table |
| 786 | */ |
| 787 | static const char zDescTab[] = |
| 788 | @ CREATE TEMP TABLE IF NOT EXISTS description( |
| 789 | @ rid INTEGER PRIMARY KEY, -- RID of the object |
| 790 | @ uuid TEXT, -- SHA1 hash of the object |
| 791 | @ ctime DATETIME, -- Time of creation |
| 792 | @ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts |
| 793 | @ type TEXT, -- file, checkin, wiki, ticket, etc. |
| 794 | @ summary TEXT, -- Summary comment for the object |
| 795 | @ detail TEXT -- filename, checkin comment, etc |
| 796 | @ ); |
| 797 | ; |
| 798 | |
| 799 | /* |
| 800 | ** Create the description table if it does not already exists. |
| 801 | ** Populate fields of this table with descriptions for all artifacts |
| 802 | ** whose RID matches the SQL expression in zWhere. |
| 803 | */ |
| 804 | void describe_artifacts(const char *zWhere){ |
| 805 | db_multi_exec("%s", zDescTab/*safe-for-%s*/); |
| 806 | |
| 807 | /* Describe checkins */ |
| 808 | db_multi_exec( |
| 809 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 810 | "SELECT blob.rid, blob.uuid, event.mtime, 'checkin',\n" |
| 811 | " 'checkin on ' || strftime('%%Y-%%m-%%d %%H:%%M',event.mtime)\n" |
| 812 | " FROM event, blob\n" |
| 813 | " WHERE event.objid %s AND event.type='ci'\n" |
| 814 | " AND event.objid=blob.rid;", |
| 815 | zWhere /*safe-for-%s*/ |
| 816 | ); |
| 817 | |
| 818 | /* Describe files */ |
| 819 | db_multi_exec( |
| 820 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 821 | "SELECT blob.rid, blob.uuid, event.mtime, 'file', 'file '||filename.name\n" |
| 822 | " FROM mlink, blob, event, filename\n" |
| 823 | " WHERE mlink.fid %s\n" |
| 824 | " AND mlink.mid=event.objid\n" |
| 825 | " AND filename.fnid=mlink.fnid\n" |
| 826 | " AND mlink.fid=blob.rid;", |
| 827 | zWhere /*safe-for-%s*/ |
| 828 | ); |
| 829 | |
| 830 | /* Describe tags */ |
| 831 | db_multi_exec( |
| 832 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 833 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n" |
| 834 | " 'tag '||substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n" |
| 835 | " FROM tagxref, blob\n" |
| 836 | " WHERE tagxref.srcid %s AND tagxref.srcid!=tagxref.rid\n" |
| 837 | " AND tagxref.srcid=blob.rid;", |
| 838 | zWhere /*safe-for-%s*/ |
| 839 | ); |
| 840 | |
| 841 | /* Cluster artifacts */ |
| 842 | db_multi_exec( |
| 843 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 844 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster', 'cluster'\n" |
| 845 | " FROM tagxref, blob\n" |
| 846 | " WHERE tagxref.rid %s\n" |
| 847 | " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n" |
| 848 | " AND blob.rid=tagxref.rid;", |
| 849 | zWhere /*safe-for-%s*/ |
| 850 | ); |
| 851 | |
| 852 | /* Ticket change artifacts */ |
| 853 | db_multi_exec( |
| 854 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 855 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n" |
| 856 | " 'ticket '||substr(tag.tagname,5,21)\n" |
| 857 | " FROM tagxref, tag, blob\n" |
| 858 | " WHERE tagxref.rid %s\n" |
| 859 | " AND tag.tagid=tagxref.tagid\n" |
| 860 | " AND tag.tagname GLOB 'tkt-*'" |
| 861 | " AND blob.rid=tagxref.rid;", |
| 862 | zWhere /*safe-for-%s*/ |
| 863 | ); |
| 864 | |
| 865 | /* Wiki edit artifacts */ |
| 866 | db_multi_exec( |
| 867 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 868 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n" |
| 869 | " printf('wiki \"%%s\"',substr(tag.tagname,6))\n" |
| 870 | " FROM tagxref, tag, blob\n" |
| 871 | " WHERE tagxref.rid %s\n" |
| 872 | " AND tag.tagid=tagxref.tagid\n" |
| 873 | " AND tag.tagname GLOB 'wiki-*'" |
| 874 | " AND blob.rid=tagxref.rid;", |
| 875 | zWhere /*safe-for-%s*/ |
| 876 | ); |
| 877 | |
| 878 | /* Event edit artifacts */ |
| 879 | db_multi_exec( |
| 880 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n" |
| 881 | "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n" |
| 882 | " 'event '||substr(tag.tagname,7)\n" |
| 883 | " FROM tagxref, tag, blob\n" |
| 884 | " WHERE tagxref.rid %s\n" |
| 885 | " AND tag.tagid=tagxref.tagid\n" |
| 886 | " AND tag.tagname GLOB 'event-*'" |
| 887 | " AND blob.rid=tagxref.rid;", |
| 888 | zWhere /*safe-for-%s*/ |
| 889 | ); |
| 890 | |
| 891 | /* Attachments */ |
| 892 | db_multi_exec( |
| 893 | "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n" |
| 894 | "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n" |
| 895 | " 'attachment '||attachment.filename\n" |
| 896 | " FROM attachment, blob\n" |
| 897 | " WHERE attachment.src %s\n" |
| 898 | " AND blob.rid=attachment.src;", |
| 899 | zWhere /*safe-for-%s*/ |
| 900 | ); |
| 901 | |
| 902 | /* Everything else */ |
| 903 | db_multi_exec( |
| 904 | "INSERT OR IGNORE INTO description(rid,uuid,type,summary)\n" |
| 905 | "SELECT blob.rid, blob.uuid," |
| 906 | " CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n" |
| 907 | " 'unknown'\n" |
| 908 | " FROM blob WHERE blob.rid %s;", |
| 909 | zWhere /*safe-for-%s*/ |
| 910 | ); |
| 911 | |
| 912 | /* Mark private elements */ |
| 913 | db_multi_exec( |
| 914 | "UPDATE description SET isPrivate=1 WHERE rid IN private" |
| 915 | ); |
| 916 | } |
| 917 | |
| 918 | /* |
| 919 | ** Print the content of the description table on stdout |
| 920 | */ |
| 921 | int describe_artifacts_to_stdout(const char *zWhere, const char *zLabel){ |
| 922 | Stmt q; |
| 923 | int cnt = 0; |
| 924 | describe_artifacts(zWhere); |
| 925 | db_prepare(&q, |
| 926 | "SELECT uuid, summary, isPrivate\n" |
| 927 | " FROM description\n" |
| 928 | " ORDER BY ctime, type;" |
| 929 | ); |
| 930 | while( db_step(&q)==SQLITE_ROW ){ |
| 931 | if( zLabel ){ |
| 932 | fossil_print("%s\n", zLabel); |
| 933 | zLabel = 0; |
| 934 | } |
| 935 | fossil_print(" %.16s %s", db_column_text(&q,0), db_column_text(&q,1)); |
| 936 | if( db_column_int(&q,2) ) fossil_print(" (unpublished)"); |
| 937 | fossil_print("\n"); |
| 938 | cnt++; |
| 939 | } |
| 940 | db_finalize(&q); |
| 941 | db_multi_exec("DELETE FROM description;"); |
| 942 | return cnt; |
| 943 | } |
| 944 | |
| 945 | /* |
| 946 | ** COMMAND: test-describe-artifacts |
| 947 | ** |
| 948 | ** Usage: %fossil test-describe-artifacts |
| 949 | ** |
| 950 | ** Display a one-line description of every artifact. |
| 951 | */ |
| 952 | void test_describe_artifacts_cmd(void){ |
| 953 | db_find_and_open_repository(0,0); |
| 954 | describe_artifacts_to_stdout("IN (SELECT rid FROM blob)", 0); |
| 955 | } |
| 956 | |
| 957 | /* |
| 958 | ** COMMAND: test-unsent |
| 959 | ** |
| 960 | ** Usage: %fossil test-unsent |
| 961 | ** |
| 962 | ** Show all artifacts in the unsent table |
| 963 | */ |
| 964 | void test_unsent_cmd(void){ |
| 965 | db_find_and_open_repository(0,0); |
| 966 | describe_artifacts_to_stdout("IN unsent", 0); |
| 967 | } |
| 968 | |
| 969 | /* |
| 970 | ** COMMAND: test-unclustered |
| 971 | ** |
| 972 | ** Usage: %fossil test-unclustered |
| 973 | ** |
| 974 | ** Show all artifacts in the unclustered table |
| 975 | */ |
| 976 | void test_unclusterd_cmd(void){ |
| 977 | db_find_and_open_repository(0,0); |
| 978 | describe_artifacts_to_stdout("IN unclustered", 0); |
| 979 | } |
| 980 | |
| 981 | /* |
| 982 | ** COMMAND: test-phantoms |
| 983 | ** |
| 984 | ** Usage: %fossil test-phantoms |
| 985 | ** |
| 986 | ** Show all phantom artifacts |
| 987 | */ |
| 988 | void test_phatoms_cmd(void){ |
| 989 | db_find_and_open_repository(0,0); |
| 990 | describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0); |
| 991 | } |
| 992 | |
| 993 | DDED src/publish.c |
| 994 | DDED src/purge.c |
+2
| --- a/src/publish.c | ||
| +++ b/src/publish.c | ||
| @@ -0,0 +1,2 @@ | ||
| 1 | +/* | |
| 2 | +** Copyright (c) 2014 D. Richardat |
| --- a/src/publish.c | |
| +++ b/src/publish.c | |
| @@ -0,0 +1,2 @@ | |
| --- a/src/publish.c | |
| +++ b/src/publish.c | |
| @@ -0,0 +1,2 @@ | |
| 1 | /* |
| 2 | ** Copyright (c) 2014 D. Richardat |
+1
| --- a/src/purge.c | ||
| +++ b/src/purge.c | ||
| @@ -0,0 +1 @@ | ||
| 1 | +db_n%s.sqlite_master WHERE name='plink'" AND sql GLOB '* baseiddb_int(-1,"PRAGMA t |
| --- a/src/purge.c | |
| +++ b/src/purge.c | |
| @@ -0,0 +1 @@ | |
| --- a/src/purge.c | |
| +++ b/src/purge.c | |
| @@ -0,0 +1 @@ | |
| 1 | db_n%s.sqlite_master WHERE name='plink'" AND sql GLOB '* baseiddb_int(-1,"PRAGMA t |
+10
-5
| --- src/rebuild.c | ||
| +++ src/rebuild.c | ||
| @@ -348,11 +348,12 @@ | ||
| 348 | 348 | zTable = db_text(0, |
| 349 | 349 | "SELECT name FROM sqlite_master /*scan*/" |
| 350 | 350 | " WHERE type='table'" |
| 351 | 351 | " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user'," |
| 352 | 352 | "'config','shun','private','reportfmt'," |
| 353 | - "'concealed','accesslog','modreq')" | |
| 353 | + "'concealed','accesslog','modreq'," | |
| 354 | + "'purgeevent','purgeitem')" | |
| 354 | 355 | " AND name NOT GLOB 'sqlite_*'" |
| 355 | 356 | " AND name NOT GLOB 'fx_*'" |
| 356 | 357 | ); |
| 357 | 358 | if( zTable==0 ) break; |
| 358 | 359 | db_multi_exec("DROP TABLE %Q", zTable); |
| @@ -829,14 +830,18 @@ | ||
| 829 | 830 | "DELETE FROM config WHERE name GLOB 'skin:*';" |
| 830 | 831 | "DELETE FROM config WHERE name GLOB 'subrepo:*';" |
| 831 | 832 | ); |
| 832 | 833 | if( bVerily ){ |
| 833 | 834 | db_multi_exec( |
| 834 | - "DELETE FROM concealed;" | |
| 835 | - "UPDATE rcvfrom SET ipaddr='unknown';" | |
| 836 | - "DROP TABLE IF EXISTS accesslog;" | |
| 837 | - "UPDATE user SET photo=NULL, info='';" | |
| 835 | + "DELETE FROM concealed;\n" | |
| 836 | + "UPDATE rcvfrom SET ipaddr='unknown';\n" | |
| 837 | + "DROP TABLE IF EXISTS accesslog;\n" | |
| 838 | + "UPDATE user SET photo=NULL, info='';\n" | |
| 839 | + "DROP TABLE IF EXISTS purgeevent;\n" | |
| 840 | + "DROP TABLE IF EXISTS purgeitem;\n" | |
| 841 | + "DROP TABLE IF EXISTS admin_log;\n" | |
| 842 | + "DROP TABLE IF EXISTS vcache;\n" | |
| 838 | 843 | ); |
| 839 | 844 | } |
| 840 | 845 | } |
| 841 | 846 | if( !bNeedRebuild ){ |
| 842 | 847 | db_end_transaction(0); |
| 843 | 848 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -348,11 +348,12 @@ | |
| 348 | zTable = db_text(0, |
| 349 | "SELECT name FROM sqlite_master /*scan*/" |
| 350 | " WHERE type='table'" |
| 351 | " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user'," |
| 352 | "'config','shun','private','reportfmt'," |
| 353 | "'concealed','accesslog','modreq')" |
| 354 | " AND name NOT GLOB 'sqlite_*'" |
| 355 | " AND name NOT GLOB 'fx_*'" |
| 356 | ); |
| 357 | if( zTable==0 ) break; |
| 358 | db_multi_exec("DROP TABLE %Q", zTable); |
| @@ -829,14 +830,18 @@ | |
| 829 | "DELETE FROM config WHERE name GLOB 'skin:*';" |
| 830 | "DELETE FROM config WHERE name GLOB 'subrepo:*';" |
| 831 | ); |
| 832 | if( bVerily ){ |
| 833 | db_multi_exec( |
| 834 | "DELETE FROM concealed;" |
| 835 | "UPDATE rcvfrom SET ipaddr='unknown';" |
| 836 | "DROP TABLE IF EXISTS accesslog;" |
| 837 | "UPDATE user SET photo=NULL, info='';" |
| 838 | ); |
| 839 | } |
| 840 | } |
| 841 | if( !bNeedRebuild ){ |
| 842 | db_end_transaction(0); |
| 843 |
| --- src/rebuild.c | |
| +++ src/rebuild.c | |
| @@ -348,11 +348,12 @@ | |
| 348 | zTable = db_text(0, |
| 349 | "SELECT name FROM sqlite_master /*scan*/" |
| 350 | " WHERE type='table'" |
| 351 | " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user'," |
| 352 | "'config','shun','private','reportfmt'," |
| 353 | "'concealed','accesslog','modreq'," |
| 354 | "'purgeevent','purgeitem')" |
| 355 | " AND name NOT GLOB 'sqlite_*'" |
| 356 | " AND name NOT GLOB 'fx_*'" |
| 357 | ); |
| 358 | if( zTable==0 ) break; |
| 359 | db_multi_exec("DROP TABLE %Q", zTable); |
| @@ -829,14 +830,18 @@ | |
| 830 | "DELETE FROM config WHERE name GLOB 'skin:*';" |
| 831 | "DELETE FROM config WHERE name GLOB 'subrepo:*';" |
| 832 | ); |
| 833 | if( bVerily ){ |
| 834 | db_multi_exec( |
| 835 | "DELETE FROM concealed;\n" |
| 836 | "UPDATE rcvfrom SET ipaddr='unknown';\n" |
| 837 | "DROP TABLE IF EXISTS accesslog;\n" |
| 838 | "UPDATE user SET photo=NULL, info='';\n" |
| 839 | "DROP TABLE IF EXISTS purgeevent;\n" |
| 840 | "DROP TABLE IF EXISTS purgeitem;\n" |
| 841 | "DROP TABLE IF EXISTS admin_log;\n" |
| 842 | "DROP TABLE IF EXISTS vcache;\n" |
| 843 | ); |
| 844 | } |
| 845 | } |
| 846 | if( !bNeedRebuild ){ |
| 847 | db_end_transaction(0); |
| 848 |
+2
-2
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -81,12 +81,12 @@ | ||
| 81 | 81 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 82 | 82 | @ content BLOB, -- Compressed content of this record |
| 83 | 83 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 84 | 84 | @ ); |
| 85 | 85 | @ CREATE TABLE delta( |
| 86 | -@ rid INTEGER PRIMARY KEY, -- Record ID | |
| 87 | -@ srcid INTEGER NOT NULL REFERENCES blob -- Record holding source document | |
| 86 | +@ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed | |
| 87 | +@ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression | |
| 88 | 88 | @ ); |
| 89 | 89 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 90 | 90 | @ |
| 91 | 91 | @ ------------------------------------------------------------------------- |
| 92 | 92 | @ -- The BLOB and DELTA tables above hold the "global state" of a Fossil |
| 93 | 93 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -81,12 +81,12 @@ | |
| 81 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 82 | @ content BLOB, -- Compressed content of this record |
| 83 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 84 | @ ); |
| 85 | @ CREATE TABLE delta( |
| 86 | @ rid INTEGER PRIMARY KEY, -- Record ID |
| 87 | @ srcid INTEGER NOT NULL REFERENCES blob -- Record holding source document |
| 88 | @ ); |
| 89 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 90 | @ |
| 91 | @ ------------------------------------------------------------------------- |
| 92 | @ -- The BLOB and DELTA tables above hold the "global state" of a Fossil |
| 93 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -81,12 +81,12 @@ | |
| 81 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 82 | @ content BLOB, -- Compressed content of this record |
| 83 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 84 | @ ); |
| 85 | @ CREATE TABLE delta( |
| 86 | @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed |
| 87 | @ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression |
| 88 | @ ); |
| 89 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 90 | @ |
| 91 | @ ------------------------------------------------------------------------- |
| 92 | @ -- The BLOB and DELTA tables above hold the "global state" of a Fossil |
| 93 |
+3
-3
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -105,15 +105,15 @@ | ||
| 105 | 105 | "Edit HTML text for an ad unit inserted after the menu bar"); |
| 106 | 106 | setup_menu_entry("Logo", "setup_logo", |
| 107 | 107 | "Change the logo and background images for the server"); |
| 108 | 108 | setup_menu_entry("Shunned", "shun", |
| 109 | 109 | "Show artifacts that are shunned by this repository"); |
| 110 | - setup_menu_entry("Log", "rcvfromlist", | |
| 110 | + setup_menu_entry("Artifact Receipts Log", "rcvfromlist", | |
| 111 | 111 | "A record of received artifacts and their sources"); |
| 112 | - setup_menu_entry("User-Log", "access_log", | |
| 112 | + setup_menu_entry("User Log", "access_log", | |
| 113 | 113 | "A record of login attempts"); |
| 114 | - setup_menu_entry("Admin-Log", "admin_log", | |
| 114 | + setup_menu_entry("Administrative Log", "admin_log", | |
| 115 | 115 | "View the admin_log entries"); |
| 116 | 116 | setup_menu_entry("Stats", "stat", |
| 117 | 117 | "Display repository statistics"); |
| 118 | 118 | setup_menu_entry("SQL", "admin_sql", |
| 119 | 119 | "Enter raw SQL commands"); |
| 120 | 120 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -105,15 +105,15 @@ | |
| 105 | "Edit HTML text for an ad unit inserted after the menu bar"); |
| 106 | setup_menu_entry("Logo", "setup_logo", |
| 107 | "Change the logo and background images for the server"); |
| 108 | setup_menu_entry("Shunned", "shun", |
| 109 | "Show artifacts that are shunned by this repository"); |
| 110 | setup_menu_entry("Log", "rcvfromlist", |
| 111 | "A record of received artifacts and their sources"); |
| 112 | setup_menu_entry("User-Log", "access_log", |
| 113 | "A record of login attempts"); |
| 114 | setup_menu_entry("Admin-Log", "admin_log", |
| 115 | "View the admin_log entries"); |
| 116 | setup_menu_entry("Stats", "stat", |
| 117 | "Display repository statistics"); |
| 118 | setup_menu_entry("SQL", "admin_sql", |
| 119 | "Enter raw SQL commands"); |
| 120 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -105,15 +105,15 @@ | |
| 105 | "Edit HTML text for an ad unit inserted after the menu bar"); |
| 106 | setup_menu_entry("Logo", "setup_logo", |
| 107 | "Change the logo and background images for the server"); |
| 108 | setup_menu_entry("Shunned", "shun", |
| 109 | "Show artifacts that are shunned by this repository"); |
| 110 | setup_menu_entry("Artifact Receipts Log", "rcvfromlist", |
| 111 | "A record of received artifacts and their sources"); |
| 112 | setup_menu_entry("User Log", "access_log", |
| 113 | "A record of login attempts"); |
| 114 | setup_menu_entry("Administrative Log", "admin_log", |
| 115 | "View the admin_log entries"); |
| 116 | setup_menu_entry("Stats", "stat", |
| 117 | "Display repository statistics"); |
| 118 | setup_menu_entry("SQL", "admin_sql", |
| 119 | "Enter raw SQL commands"); |
| 120 |
+41
-13
| --- src/shun.c | ||
| +++ src/shun.c | ||
| @@ -295,37 +295,50 @@ | ||
| 295 | 295 | ** |
| 296 | 296 | ** Show a listing of RCVFROM table entries. |
| 297 | 297 | */ |
| 298 | 298 | void rcvfromlist_page(void){ |
| 299 | 299 | int ofst = atoi(PD("ofst","0")); |
| 300 | + int showAll = P("all")!=0; | |
| 300 | 301 | int cnt; |
| 301 | 302 | Stmt q; |
| 302 | 303 | |
| 303 | 304 | login_check_credentials(); |
| 304 | 305 | if( !g.perm.Admin ){ |
| 305 | 306 | login_needed(); |
| 306 | 307 | } |
| 307 | - style_header("Content Sources"); | |
| 308 | + style_header("Artifact Receipts"); | |
| 309 | + if( showAll ){ | |
| 310 | + ofst = 0; | |
| 311 | + }else{ | |
| 312 | + style_submenu_element("All", "All", "rcvfromlist?all=1"); | |
| 313 | + } | |
| 308 | 314 | if( ofst>0 ){ |
| 309 | 315 | style_submenu_element("Newer", "Newer", "rcvfromlist?ofst=%d", |
| 310 | 316 | ofst>30 ? ofst-30 : 0); |
| 311 | 317 | } |
| 318 | + db_multi_exec( | |
| 319 | + "CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);" | |
| 320 | + "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;" | |
| 321 | + ); | |
| 312 | 322 | db_prepare(&q, |
| 313 | - "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" | |
| 323 | + "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr," | |
| 324 | + " EXISTS(SELECT 1 FROM rcvidUsed WHERE x=rcvfrom.rcvid)" | |
| 314 | 325 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 315 | - " ORDER BY rcvid DESC LIMIT 31 OFFSET %d", | |
| 316 | - ofst | |
| 326 | + " ORDER BY rcvid DESC LIMIT %d OFFSET %d", | |
| 327 | + showAll ? -1 : 31, ofst | |
| 317 | 328 | ); |
| 318 | 329 | @ <p>Whenever new artifacts are added to the repository, either by |
| 319 | 330 | @ push or using the web interface, an entry is made in the RCVFROM table |
| 320 | 331 | @ to record the source of that artifact. This log facilitates |
| 321 | 332 | @ finding and fixing attempts to inject illicit content into the |
| 322 | 333 | @ repository.</p> |
| 323 | 334 | @ |
| 324 | 335 | @ <p>Click on the "rcvid" to show a list of specific artifacts received |
| 325 | 336 | @ by a transaction. After identifying illicit artifacts, remove them |
| 326 | - @ using the "Shun" feature.</p> | |
| 337 | + @ using the "Shun" button. If an "rcvid" is not hyperlinked, that means | |
| 338 | + @ all artifacts associated with that rcvid have already been shunned | |
| 339 | + @ or purged.</p> | |
| 327 | 340 | @ |
| 328 | 341 | @ <table cellpadding="0" cellspacing="0" border="0"> |
| 329 | 342 | @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th> |
| 330 | 343 | @ <th style="padding-right: 15px;text-align: left;">Date</th> |
| 331 | 344 | @ <th style="padding-right: 15px;text-align: left;">User</th> |
| @@ -334,17 +347,22 @@ | ||
| 334 | 347 | while( db_step(&q)==SQLITE_ROW ){ |
| 335 | 348 | int rcvid = db_column_int(&q, 0); |
| 336 | 349 | const char *zUser = db_column_text(&q, 1); |
| 337 | 350 | const char *zDate = db_column_text(&q, 2); |
| 338 | 351 | const char *zIpAddr = db_column_text(&q, 3); |
| 339 | - if( cnt==30 ){ | |
| 352 | + if( cnt==30 && !showAll ){ | |
| 340 | 353 | style_submenu_element("Older", "Older", |
| 341 | 354 | "rcvfromlist?ofst=%d", ofst+30); |
| 342 | 355 | }else{ |
| 343 | 356 | cnt++; |
| 344 | 357 | @ <tr> |
| 345 | - @ <td style="padding-right: 15px;text-align: right;"><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td> | |
| 358 | + if( db_column_int(&q,4) ){ | |
| 359 | + @ <td style="padding-right: 15px;text-align: right;"> | |
| 360 | + @ <a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td> | |
| 361 | + }else{ | |
| 362 | + @ <td style="padding-right: 15px;text-align: right;">%d(rcvid)</td> | |
| 363 | + } | |
| 346 | 364 | @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td> |
| 347 | 365 | @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td> |
| 348 | 366 | @ <td style="text-align: left;">%s(zIpAddr)</td> |
| 349 | 367 | @ </tr> |
| 350 | 368 | } |
| @@ -365,22 +383,24 @@ | ||
| 365 | 383 | |
| 366 | 384 | login_check_credentials(); |
| 367 | 385 | if( !g.perm.Admin ){ |
| 368 | 386 | login_needed(); |
| 369 | 387 | } |
| 370 | - style_header("Content Source %d", rcvid); | |
| 388 | + style_header("Artifact Receipt %d", rcvid); | |
| 371 | 389 | if( db_exists( |
| 372 | 390 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 373 | 391 | " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 374 | 392 | ){ |
| 375 | - style_submenu_element("Shun All", "Shun All", "shun?shun&rcvid=%d#addshun", rcvid); | |
| 393 | + style_submenu_element("Shun All", "Shun All", | |
| 394 | + "shun?shun&rcvid=%d#addshun", rcvid); | |
| 376 | 395 | } |
| 377 | 396 | if( db_exists( |
| 378 | 397 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 379 | 398 | " EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 380 | 399 | ){ |
| 381 | - style_submenu_element("Unshun All", "Unshun All", "shun?accept&rcvid=%d#delshun", rcvid); | |
| 400 | + style_submenu_element("Unshun All", "Unshun All", | |
| 401 | + "shun?accept&rcvid=%d#delshun", rcvid); | |
| 382 | 402 | } |
| 383 | 403 | db_prepare(&q, |
| 384 | 404 | "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 385 | 405 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 386 | 406 | " WHERE rcvid=%d", |
| @@ -399,22 +419,30 @@ | ||
| 399 | 419 | @ <td valign="top">%s(zDate)</td></tr> |
| 400 | 420 | @ <tr><th valign="top" align="right">IP Address:</th> |
| 401 | 421 | @ <td valign="top">%s(zIpAddr)</td></tr> |
| 402 | 422 | } |
| 403 | 423 | db_finalize(&q); |
| 424 | + db_multi_exec( | |
| 425 | + "CREATE TEMP TABLE toshow(rid INTEGER PRIMARY KEY);" | |
| 426 | + "INSERT INTO toshow SELECT rid FROM blob WHERE rcvid=%d", rcvid | |
| 427 | + ); | |
| 428 | + describe_artifacts("IN toshow"); | |
| 404 | 429 | db_prepare(&q, |
| 405 | - "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid | |
| 430 | + "SELECT blob.rid, blob.uuid, blob.size, description.summary\n" | |
| 431 | + " FROM blob LEFT JOIN description ON (blob.rid=description.rid)" | |
| 432 | + " WHERE blob.rcvid=%d", rcvid | |
| 406 | 433 | ); |
| 407 | 434 | @ <tr><th valign="top" align="right">Artifacts:</th> |
| 408 | 435 | @ <td valign="top"> |
| 409 | 436 | while( db_step(&q)==SQLITE_ROW ){ |
| 410 | - int rid = db_column_int(&q, 0); | |
| 411 | 437 | const char *zUuid = db_column_text(&q, 1); |
| 412 | 438 | int size = db_column_int(&q, 2); |
| 439 | + const char *zDesc = db_column_text(&q, 3); | |
| 440 | + if( zDesc==0 ) zDesc = ""; | |
| 413 | 441 | @ <a href="%s(g.zTop)/info/%s(zUuid)">%s(zUuid)</a> |
| 414 | - @ (rid: %d(rid), size: %d(size))<br /> | |
| 442 | + @ %h(zDesc) (size: %d(size))<br /> | |
| 415 | 443 | } |
| 416 | 444 | @ </td></tr> |
| 417 | 445 | @ </table> |
| 418 | 446 | db_finalize(&q); |
| 419 | 447 | style_footer(); |
| 420 | 448 | } |
| 421 | 449 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -295,37 +295,50 @@ | |
| 295 | ** |
| 296 | ** Show a listing of RCVFROM table entries. |
| 297 | */ |
| 298 | void rcvfromlist_page(void){ |
| 299 | int ofst = atoi(PD("ofst","0")); |
| 300 | int cnt; |
| 301 | Stmt q; |
| 302 | |
| 303 | login_check_credentials(); |
| 304 | if( !g.perm.Admin ){ |
| 305 | login_needed(); |
| 306 | } |
| 307 | style_header("Content Sources"); |
| 308 | if( ofst>0 ){ |
| 309 | style_submenu_element("Newer", "Newer", "rcvfromlist?ofst=%d", |
| 310 | ofst>30 ? ofst-30 : 0); |
| 311 | } |
| 312 | db_prepare(&q, |
| 313 | "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 314 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 315 | " ORDER BY rcvid DESC LIMIT 31 OFFSET %d", |
| 316 | ofst |
| 317 | ); |
| 318 | @ <p>Whenever new artifacts are added to the repository, either by |
| 319 | @ push or using the web interface, an entry is made in the RCVFROM table |
| 320 | @ to record the source of that artifact. This log facilitates |
| 321 | @ finding and fixing attempts to inject illicit content into the |
| 322 | @ repository.</p> |
| 323 | @ |
| 324 | @ <p>Click on the "rcvid" to show a list of specific artifacts received |
| 325 | @ by a transaction. After identifying illicit artifacts, remove them |
| 326 | @ using the "Shun" feature.</p> |
| 327 | @ |
| 328 | @ <table cellpadding="0" cellspacing="0" border="0"> |
| 329 | @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th> |
| 330 | @ <th style="padding-right: 15px;text-align: left;">Date</th> |
| 331 | @ <th style="padding-right: 15px;text-align: left;">User</th> |
| @@ -334,17 +347,22 @@ | |
| 334 | while( db_step(&q)==SQLITE_ROW ){ |
| 335 | int rcvid = db_column_int(&q, 0); |
| 336 | const char *zUser = db_column_text(&q, 1); |
| 337 | const char *zDate = db_column_text(&q, 2); |
| 338 | const char *zIpAddr = db_column_text(&q, 3); |
| 339 | if( cnt==30 ){ |
| 340 | style_submenu_element("Older", "Older", |
| 341 | "rcvfromlist?ofst=%d", ofst+30); |
| 342 | }else{ |
| 343 | cnt++; |
| 344 | @ <tr> |
| 345 | @ <td style="padding-right: 15px;text-align: right;"><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td> |
| 346 | @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td> |
| 347 | @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td> |
| 348 | @ <td style="text-align: left;">%s(zIpAddr)</td> |
| 349 | @ </tr> |
| 350 | } |
| @@ -365,22 +383,24 @@ | |
| 365 | |
| 366 | login_check_credentials(); |
| 367 | if( !g.perm.Admin ){ |
| 368 | login_needed(); |
| 369 | } |
| 370 | style_header("Content Source %d", rcvid); |
| 371 | if( db_exists( |
| 372 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 373 | " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 374 | ){ |
| 375 | style_submenu_element("Shun All", "Shun All", "shun?shun&rcvid=%d#addshun", rcvid); |
| 376 | } |
| 377 | if( db_exists( |
| 378 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 379 | " EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 380 | ){ |
| 381 | style_submenu_element("Unshun All", "Unshun All", "shun?accept&rcvid=%d#delshun", rcvid); |
| 382 | } |
| 383 | db_prepare(&q, |
| 384 | "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 385 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 386 | " WHERE rcvid=%d", |
| @@ -399,22 +419,30 @@ | |
| 399 | @ <td valign="top">%s(zDate)</td></tr> |
| 400 | @ <tr><th valign="top" align="right">IP Address:</th> |
| 401 | @ <td valign="top">%s(zIpAddr)</td></tr> |
| 402 | } |
| 403 | db_finalize(&q); |
| 404 | db_prepare(&q, |
| 405 | "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid |
| 406 | ); |
| 407 | @ <tr><th valign="top" align="right">Artifacts:</th> |
| 408 | @ <td valign="top"> |
| 409 | while( db_step(&q)==SQLITE_ROW ){ |
| 410 | int rid = db_column_int(&q, 0); |
| 411 | const char *zUuid = db_column_text(&q, 1); |
| 412 | int size = db_column_int(&q, 2); |
| 413 | @ <a href="%s(g.zTop)/info/%s(zUuid)">%s(zUuid)</a> |
| 414 | @ (rid: %d(rid), size: %d(size))<br /> |
| 415 | } |
| 416 | @ </td></tr> |
| 417 | @ </table> |
| 418 | db_finalize(&q); |
| 419 | style_footer(); |
| 420 | } |
| 421 |
| --- src/shun.c | |
| +++ src/shun.c | |
| @@ -295,37 +295,50 @@ | |
| 295 | ** |
| 296 | ** Show a listing of RCVFROM table entries. |
| 297 | */ |
| 298 | void rcvfromlist_page(void){ |
| 299 | int ofst = atoi(PD("ofst","0")); |
| 300 | int showAll = P("all")!=0; |
| 301 | int cnt; |
| 302 | Stmt q; |
| 303 | |
| 304 | login_check_credentials(); |
| 305 | if( !g.perm.Admin ){ |
| 306 | login_needed(); |
| 307 | } |
| 308 | style_header("Artifact Receipts"); |
| 309 | if( showAll ){ |
| 310 | ofst = 0; |
| 311 | }else{ |
| 312 | style_submenu_element("All", "All", "rcvfromlist?all=1"); |
| 313 | } |
| 314 | if( ofst>0 ){ |
| 315 | style_submenu_element("Newer", "Newer", "rcvfromlist?ofst=%d", |
| 316 | ofst>30 ? ofst-30 : 0); |
| 317 | } |
| 318 | db_multi_exec( |
| 319 | "CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);" |
| 320 | "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;" |
| 321 | ); |
| 322 | db_prepare(&q, |
| 323 | "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr," |
| 324 | " EXISTS(SELECT 1 FROM rcvidUsed WHERE x=rcvfrom.rcvid)" |
| 325 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 326 | " ORDER BY rcvid DESC LIMIT %d OFFSET %d", |
| 327 | showAll ? -1 : 31, ofst |
| 328 | ); |
| 329 | @ <p>Whenever new artifacts are added to the repository, either by |
| 330 | @ push or using the web interface, an entry is made in the RCVFROM table |
| 331 | @ to record the source of that artifact. This log facilitates |
| 332 | @ finding and fixing attempts to inject illicit content into the |
| 333 | @ repository.</p> |
| 334 | @ |
| 335 | @ <p>Click on the "rcvid" to show a list of specific artifacts received |
| 336 | @ by a transaction. After identifying illicit artifacts, remove them |
| 337 | @ using the "Shun" button. If an "rcvid" is not hyperlinked, that means |
| 338 | @ all artifacts associated with that rcvid have already been shunned |
| 339 | @ or purged.</p> |
| 340 | @ |
| 341 | @ <table cellpadding="0" cellspacing="0" border="0"> |
| 342 | @ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th> |
| 343 | @ <th style="padding-right: 15px;text-align: left;">Date</th> |
| 344 | @ <th style="padding-right: 15px;text-align: left;">User</th> |
| @@ -334,17 +347,22 @@ | |
| 347 | while( db_step(&q)==SQLITE_ROW ){ |
| 348 | int rcvid = db_column_int(&q, 0); |
| 349 | const char *zUser = db_column_text(&q, 1); |
| 350 | const char *zDate = db_column_text(&q, 2); |
| 351 | const char *zIpAddr = db_column_text(&q, 3); |
| 352 | if( cnt==30 && !showAll ){ |
| 353 | style_submenu_element("Older", "Older", |
| 354 | "rcvfromlist?ofst=%d", ofst+30); |
| 355 | }else{ |
| 356 | cnt++; |
| 357 | @ <tr> |
| 358 | if( db_column_int(&q,4) ){ |
| 359 | @ <td style="padding-right: 15px;text-align: right;"> |
| 360 | @ <a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td> |
| 361 | }else{ |
| 362 | @ <td style="padding-right: 15px;text-align: right;">%d(rcvid)</td> |
| 363 | } |
| 364 | @ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td> |
| 365 | @ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td> |
| 366 | @ <td style="text-align: left;">%s(zIpAddr)</td> |
| 367 | @ </tr> |
| 368 | } |
| @@ -365,22 +383,24 @@ | |
| 383 | |
| 384 | login_check_credentials(); |
| 385 | if( !g.perm.Admin ){ |
| 386 | login_needed(); |
| 387 | } |
| 388 | style_header("Artifact Receipt %d", rcvid); |
| 389 | if( db_exists( |
| 390 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 391 | " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 392 | ){ |
| 393 | style_submenu_element("Shun All", "Shun All", |
| 394 | "shun?shun&rcvid=%d#addshun", rcvid); |
| 395 | } |
| 396 | if( db_exists( |
| 397 | "SELECT 1 FROM blob WHERE rcvid=%d AND" |
| 398 | " EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid) |
| 399 | ){ |
| 400 | style_submenu_element("Unshun All", "Unshun All", |
| 401 | "shun?accept&rcvid=%d#delshun", rcvid); |
| 402 | } |
| 403 | db_prepare(&q, |
| 404 | "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" |
| 405 | " FROM rcvfrom LEFT JOIN user USING(uid)" |
| 406 | " WHERE rcvid=%d", |
| @@ -399,22 +419,30 @@ | |
| 419 | @ <td valign="top">%s(zDate)</td></tr> |
| 420 | @ <tr><th valign="top" align="right">IP Address:</th> |
| 421 | @ <td valign="top">%s(zIpAddr)</td></tr> |
| 422 | } |
| 423 | db_finalize(&q); |
| 424 | db_multi_exec( |
| 425 | "CREATE TEMP TABLE toshow(rid INTEGER PRIMARY KEY);" |
| 426 | "INSERT INTO toshow SELECT rid FROM blob WHERE rcvid=%d", rcvid |
| 427 | ); |
| 428 | describe_artifacts("IN toshow"); |
| 429 | db_prepare(&q, |
| 430 | "SELECT blob.rid, blob.uuid, blob.size, description.summary\n" |
| 431 | " FROM blob LEFT JOIN description ON (blob.rid=description.rid)" |
| 432 | " WHERE blob.rcvid=%d", rcvid |
| 433 | ); |
| 434 | @ <tr><th valign="top" align="right">Artifacts:</th> |
| 435 | @ <td valign="top"> |
| 436 | while( db_step(&q)==SQLITE_ROW ){ |
| 437 | const char *zUuid = db_column_text(&q, 1); |
| 438 | int size = db_column_int(&q, 2); |
| 439 | const char *zDesc = db_column_text(&q, 3); |
| 440 | if( zDesc==0 ) zDesc = ""; |
| 441 | @ <a href="%s(g.zTop)/info/%s(zUuid)">%s(zUuid)</a> |
| 442 | @ %h(zDesc) (size: %d(size))<br /> |
| 443 | } |
| 444 | @ </td></tr> |
| 445 | @ </table> |
| 446 | db_finalize(&q); |
| 447 | style_footer(); |
| 448 | } |
| 449 |
+21
-20
| --- src/sqlcmd.c | ||
| +++ src/sqlcmd.c | ||
| @@ -106,10 +106,24 @@ | ||
| 106 | 106 | sqlite3_result_blob(context, pOut, nOut, sqlite3_free); |
| 107 | 107 | }else{ |
| 108 | 108 | sqlite3_result_error(context, "input is not zlib compressed", -1); |
| 109 | 109 | } |
| 110 | 110 | } |
| 111 | + | |
| 112 | +/* | |
| 113 | +** Add the content(), compress(), and decompress() SQL functions to | |
| 114 | +** database connection db. | |
| 115 | +*/ | |
| 116 | +int add_content_sql_commands(sqlite3 *db){ | |
| 117 | + sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, | |
| 118 | + sqlcmd_content, 0, 0); | |
| 119 | + sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0, | |
| 120 | + sqlcmd_compress, 0, 0); | |
| 121 | + sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0, | |
| 122 | + sqlcmd_decompress, 0, 0); | |
| 123 | + return SQLITE_OK; | |
| 124 | +} | |
| 111 | 125 | |
| 112 | 126 | /* |
| 113 | 127 | ** This is the "automatic extension" initializer that runs right after |
| 114 | 128 | ** the connection to the repository database is opened. Set up the |
| 115 | 129 | ** database connection to be more useful to the human operator. |
| @@ -117,40 +131,27 @@ | ||
| 117 | 131 | static int sqlcmd_autoinit( |
| 118 | 132 | sqlite3 *db, |
| 119 | 133 | const char **pzErrMsg, |
| 120 | 134 | const void *notUsed |
| 121 | 135 | ){ |
| 122 | - char *zSql; | |
| 123 | - int rc = SQLITE_OK; | |
| 124 | - sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, | |
| 125 | - sqlcmd_content, 0, 0); | |
| 126 | - sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0, | |
| 127 | - sqlcmd_compress, 0, 0); | |
| 128 | - sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0, | |
| 129 | - sqlcmd_decompress, 0, 0); | |
| 136 | + add_content_sql_commands(db); | |
| 130 | 137 | re_add_sql_func(db); |
| 131 | - foci_register(db); | |
| 132 | 138 | g.zMainDbType = "repository"; |
| 139 | + foci_register(db); | |
| 133 | 140 | g.repositoryOpen = 1; |
| 134 | 141 | g.db = db; |
| 135 | - db_open_config(1); | |
| 136 | - if( g.zLocalDbName ){ | |
| 137 | - zSql = sqlite3_mprintf("ATTACH %Q AS localdb;", g.zLocalDbName); | |
| 138 | - rc = sqlite3_exec(db, zSql, 0, 0, 0); | |
| 139 | - sqlite3_free(zSql); | |
| 140 | - } | |
| 141 | - return rc; | |
| 142 | + return SQLITE_OK; | |
| 142 | 143 | } |
| 143 | 144 | |
| 144 | 145 | /* |
| 145 | 146 | ** COMMAND: sqlite3 |
| 146 | 147 | ** |
| 147 | -** Usage: %fossil sqlite3 ?SQL-COMMANDS? ?OPTIONS? | |
| 148 | +** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? | |
| 148 | 149 | ** |
| 149 | -** Run the standalone sqlite3 command-line shell on the repository database | |
| 150 | -** for the current checkout, or whatever repository is specified by the | |
| 151 | -** -R command-line option. | |
| 150 | +** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS. | |
| 151 | +** If DATABASE is omitted, then the repository that serves the working | |
| 152 | +** directory is opened. | |
| 152 | 153 | ** |
| 153 | 154 | ** WARNING: Careless use of this command can corrupt a Fossil repository |
| 154 | 155 | ** in ways that are unrecoverable. Be sure you know what you are doing before |
| 155 | 156 | ** running any SQL commands that modifies the repository database. |
| 156 | 157 | */ |
| 157 | 158 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -106,10 +106,24 @@ | |
| 106 | sqlite3_result_blob(context, pOut, nOut, sqlite3_free); |
| 107 | }else{ |
| 108 | sqlite3_result_error(context, "input is not zlib compressed", -1); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | /* |
| 113 | ** This is the "automatic extension" initializer that runs right after |
| 114 | ** the connection to the repository database is opened. Set up the |
| 115 | ** database connection to be more useful to the human operator. |
| @@ -117,40 +131,27 @@ | |
| 117 | static int sqlcmd_autoinit( |
| 118 | sqlite3 *db, |
| 119 | const char **pzErrMsg, |
| 120 | const void *notUsed |
| 121 | ){ |
| 122 | char *zSql; |
| 123 | int rc = SQLITE_OK; |
| 124 | sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, |
| 125 | sqlcmd_content, 0, 0); |
| 126 | sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0, |
| 127 | sqlcmd_compress, 0, 0); |
| 128 | sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0, |
| 129 | sqlcmd_decompress, 0, 0); |
| 130 | re_add_sql_func(db); |
| 131 | foci_register(db); |
| 132 | g.zMainDbType = "repository"; |
| 133 | g.repositoryOpen = 1; |
| 134 | g.db = db; |
| 135 | db_open_config(1); |
| 136 | if( g.zLocalDbName ){ |
| 137 | zSql = sqlite3_mprintf("ATTACH %Q AS localdb;", g.zLocalDbName); |
| 138 | rc = sqlite3_exec(db, zSql, 0, 0, 0); |
| 139 | sqlite3_free(zSql); |
| 140 | } |
| 141 | return rc; |
| 142 | } |
| 143 | |
| 144 | /* |
| 145 | ** COMMAND: sqlite3 |
| 146 | ** |
| 147 | ** Usage: %fossil sqlite3 ?SQL-COMMANDS? ?OPTIONS? |
| 148 | ** |
| 149 | ** Run the standalone sqlite3 command-line shell on the repository database |
| 150 | ** for the current checkout, or whatever repository is specified by the |
| 151 | ** -R command-line option. |
| 152 | ** |
| 153 | ** WARNING: Careless use of this command can corrupt a Fossil repository |
| 154 | ** in ways that are unrecoverable. Be sure you know what you are doing before |
| 155 | ** running any SQL commands that modifies the repository database. |
| 156 | */ |
| 157 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -106,10 +106,24 @@ | |
| 106 | sqlite3_result_blob(context, pOut, nOut, sqlite3_free); |
| 107 | }else{ |
| 108 | sqlite3_result_error(context, "input is not zlib compressed", -1); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | /* |
| 113 | ** Add the content(), compress(), and decompress() SQL functions to |
| 114 | ** database connection db. |
| 115 | */ |
| 116 | int add_content_sql_commands(sqlite3 *db){ |
| 117 | sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, |
| 118 | sqlcmd_content, 0, 0); |
| 119 | sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0, |
| 120 | sqlcmd_compress, 0, 0); |
| 121 | sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, 0, |
| 122 | sqlcmd_decompress, 0, 0); |
| 123 | return SQLITE_OK; |
| 124 | } |
| 125 | |
| 126 | /* |
| 127 | ** This is the "automatic extension" initializer that runs right after |
| 128 | ** the connection to the repository database is opened. Set up the |
| 129 | ** database connection to be more useful to the human operator. |
| @@ -117,40 +131,27 @@ | |
| 131 | static int sqlcmd_autoinit( |
| 132 | sqlite3 *db, |
| 133 | const char **pzErrMsg, |
| 134 | const void *notUsed |
| 135 | ){ |
| 136 | add_content_sql_commands(db); |
| 137 | re_add_sql_func(db); |
| 138 | g.zMainDbType = "repository"; |
| 139 | foci_register(db); |
| 140 | g.repositoryOpen = 1; |
| 141 | g.db = db; |
| 142 | return SQLITE_OK; |
| 143 | } |
| 144 | |
| 145 | /* |
| 146 | ** COMMAND: sqlite3 |
| 147 | ** |
| 148 | ** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS? |
| 149 | ** |
| 150 | ** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS. |
| 151 | ** If DATABASE is omitted, then the repository that serves the working |
| 152 | ** directory is opened. |
| 153 | ** |
| 154 | ** WARNING: Careless use of this command can corrupt a Fossil repository |
| 155 | ** in ways that are unrecoverable. Be sure you know what you are doing before |
| 156 | ** running any SQL commands that modifies the repository database. |
| 157 | */ |
| 158 |
+263
-156
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -231,11 +231,11 @@ | ||
| 231 | 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | 233 | */ |
| 234 | 234 | #define SQLITE_VERSION "3.8.8" |
| 235 | 235 | #define SQLITE_VERSION_NUMBER 3008008 |
| 236 | -#define SQLITE_SOURCE_ID "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e" | |
| 236 | +#define SQLITE_SOURCE_ID "2014-12-06 14:56:49 6aeece19a235344be2537e66a3fe08b1febfb5a0" | |
| 237 | 237 | |
| 238 | 238 | /* |
| 239 | 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | 241 | ** |
| @@ -1343,11 +1343,11 @@ | ||
| 1343 | 1343 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED |
| 1344 | 1344 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE |
| 1345 | 1345 | ** </ul> |
| 1346 | 1346 | ** |
| 1347 | 1347 | ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as |
| 1348 | -** was given no the corresponding lock. | |
| 1348 | +** was given on the corresponding lock. | |
| 1349 | 1349 | ** |
| 1350 | 1350 | ** The xShmLock method can transition between unlocked and SHARED or |
| 1351 | 1351 | ** between unlocked and EXCLUSIVE. It cannot transition between SHARED |
| 1352 | 1352 | ** and EXCLUSIVE. |
| 1353 | 1353 | */ |
| @@ -1646,12 +1646,12 @@ | ||
| 1646 | 1646 | ** tracks memory usage, for example. </dd> |
| 1647 | 1647 | ** |
| 1648 | 1648 | ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> |
| 1649 | 1649 | ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, |
| 1650 | 1650 | ** interpreted as a boolean, which enables or disables the collection of |
| 1651 | -** memory allocation statistics. ^(When memory allocation statistics are disabled, the | |
| 1652 | -** following SQLite interfaces become non-operational: | |
| 1651 | +** memory allocation statistics. ^(When memory allocation statistics are | |
| 1652 | +** disabled, the following SQLite interfaces become non-operational: | |
| 1653 | 1653 | ** <ul> |
| 1654 | 1654 | ** <li> [sqlite3_memory_used()] |
| 1655 | 1655 | ** <li> [sqlite3_memory_highwater()] |
| 1656 | 1656 | ** <li> [sqlite3_soft_heap_limit64()] |
| 1657 | 1657 | ** <li> [sqlite3_status()] |
| @@ -1688,11 +1688,12 @@ | ||
| 1688 | 1688 | ** that SQLite can use for the database page cache with the default page |
| 1689 | 1689 | ** cache implementation. |
| 1690 | 1690 | ** This configuration should not be used if an application-define page |
| 1691 | 1691 | ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] |
| 1692 | 1692 | ** configuration option. |
| 1693 | -** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned | |
| 1693 | +** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to | |
| 1694 | +** 8-byte aligned | |
| 1694 | 1695 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1695 | 1696 | ** The sz argument should be the size of the largest database page |
| 1696 | 1697 | ** (a power of two between 512 and 32768) plus some extra bytes for each |
| 1697 | 1698 | ** page header. ^The number of extra bytes needed by the page header |
| 1698 | 1699 | ** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option |
| @@ -1708,11 +1709,12 @@ | ||
| 1708 | 1709 | ** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd> |
| 1709 | 1710 | ** |
| 1710 | 1711 | ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> |
| 1711 | 1712 | ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer |
| 1712 | 1713 | ** that SQLite will use for all of its dynamic memory allocation needs |
| 1713 | -** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. | |
| 1714 | +** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and | |
| 1715 | +** [SQLITE_CONFIG_PAGECACHE]. | |
| 1714 | 1716 | ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled |
| 1715 | 1717 | ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns |
| 1716 | 1718 | ** [SQLITE_ERROR] if invoked otherwise. |
| 1717 | 1719 | ** ^There are three arguments to SQLITE_CONFIG_HEAP: |
| 1718 | 1720 | ** An 8-byte aligned pointer to the memory, |
| @@ -1728,13 +1730,13 @@ | ||
| 1728 | 1730 | ** for the minimum allocation size are 2**5 through 2**8.</dd> |
| 1729 | 1731 | ** |
| 1730 | 1732 | ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1731 | 1733 | ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a |
| 1732 | 1734 | ** pointer to an instance of the [sqlite3_mutex_methods] structure. |
| 1733 | -** The argument specifies alternative low-level mutex routines to be used in place | |
| 1734 | -** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the | |
| 1735 | -** content of the [sqlite3_mutex_methods] structure before the call to | |
| 1735 | +** The argument specifies alternative low-level mutex routines to be used | |
| 1736 | +** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of | |
| 1737 | +** the content of the [sqlite3_mutex_methods] structure before the call to | |
| 1736 | 1738 | ** [sqlite3_config()] returns. ^If SQLite is compiled with |
| 1737 | 1739 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then |
| 1738 | 1740 | ** the entire mutexing subsystem is omitted from the build and hence calls to |
| 1739 | 1741 | ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will |
| 1740 | 1742 | ** return [SQLITE_ERROR].</dd> |
| @@ -1768,12 +1770,12 @@ | ||
| 1768 | 1770 | ** the interface to a custom page cache implementation.)^ |
| 1769 | 1771 | ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> |
| 1770 | 1772 | ** |
| 1771 | 1773 | ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> |
| 1772 | 1774 | ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which |
| 1773 | -** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of the current | |
| 1774 | -** page cache implementation into that object.)^ </dd> | |
| 1775 | +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of | |
| 1776 | +** the current page cache implementation into that object.)^ </dd> | |
| 1775 | 1777 | ** |
| 1776 | 1778 | ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> |
| 1777 | 1779 | ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite |
| 1778 | 1780 | ** global [error log]. |
| 1779 | 1781 | ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a |
| @@ -1794,12 +1796,13 @@ | ||
| 1794 | 1796 | ** function must be threadsafe. </dd> |
| 1795 | 1797 | ** |
| 1796 | 1798 | ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI |
| 1797 | 1799 | ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| 1798 | 1800 | ** If non-zero, then URI handling is globally enabled. If the parameter is zero, |
| 1799 | -** then URI handling is globally disabled.)^ ^If URI handling is globally enabled, | |
| 1800 | -** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or | |
| 1801 | +** then URI handling is globally disabled.)^ ^If URI handling is globally | |
| 1802 | +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], | |
| 1803 | +** [sqlite3_open16()] or | |
| 1801 | 1804 | ** specified as part of [ATTACH] commands are interpreted as URIs, regardless |
| 1802 | 1805 | ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database |
| 1803 | 1806 | ** connection is opened. ^If it is globally disabled, filenames are |
| 1804 | 1807 | ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the |
| 1805 | 1808 | ** database connection is opened. ^(By default, URI handling is globally |
| @@ -1857,21 +1860,21 @@ | ||
| 1857 | 1860 | ** changed to its compile-time default. |
| 1858 | 1861 | ** |
| 1859 | 1862 | ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1860 | 1863 | ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1861 | 1864 | ** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is |
| 1862 | -** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. | |
| 1863 | -** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value | |
| 1865 | +** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro | |
| 1866 | +** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value | |
| 1864 | 1867 | ** that specifies the maximum size of the created heap. |
| 1865 | 1868 | ** </dl> |
| 1866 | 1869 | ** |
| 1867 | 1870 | ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] |
| 1868 | 1871 | ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ |
| 1869 | 1872 | ** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which |
| 1870 | 1873 | ** is a pointer to an integer and writes into that integer the number of extra |
| 1871 | -** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of | |
| 1872 | -** extra space required can change depending on the compiler, | |
| 1874 | +** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. | |
| 1875 | +** The amount of extra space required can change depending on the compiler, | |
| 1873 | 1876 | ** target platform, and SQLite version. |
| 1874 | 1877 | ** </dl> |
| 1875 | 1878 | */ |
| 1876 | 1879 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1877 | 1880 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| @@ -2171,10 +2174,11 @@ | ||
| 2171 | 2174 | SQLITE_API int sqlite3_complete(const char *sql); |
| 2172 | 2175 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2173 | 2176 | |
| 2174 | 2177 | /* |
| 2175 | 2178 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2179 | +** KEYWORDS: {busy-handler callback} {busy handler} | |
| 2176 | 2180 | ** |
| 2177 | 2181 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2178 | 2182 | ** that might be invoked with argument P whenever |
| 2179 | 2183 | ** an attempt is made to access a database table associated with |
| 2180 | 2184 | ** [database connection] D when another thread |
| @@ -2187,11 +2191,11 @@ | ||
| 2187 | 2191 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2188 | 2192 | ** |
| 2189 | 2193 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2190 | 2194 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2191 | 2195 | ** the busy handler callback is the number of times that the busy handler has |
| 2192 | -** been invoked for the same locking event. ^If the | |
| 2196 | +** been invoked previously for the same locking event. ^If the | |
| 2193 | 2197 | ** busy callback returns 0, then no additional attempts are made to |
| 2194 | 2198 | ** access the database and [SQLITE_BUSY] is returned |
| 2195 | 2199 | ** to the application. |
| 2196 | 2200 | ** ^If the callback returns non-zero, then another attempt |
| 2197 | 2201 | ** is made to access the database and the cycle repeats. |
| @@ -4642,11 +4646,12 @@ | ||
| 4642 | 4646 | ** If these routines are called from within the different thread |
| 4643 | 4647 | ** than the one containing the application-defined function that received |
| 4644 | 4648 | ** the [sqlite3_context] pointer, the results are undefined. |
| 4645 | 4649 | */ |
| 4646 | 4650 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); |
| 4647 | -SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void(*)(void*)); | |
| 4651 | +SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, | |
| 4652 | + sqlite3_uint64,void(*)(void*)); | |
| 4648 | 4653 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); |
| 4649 | 4654 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); |
| 4650 | 4655 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); |
| 4651 | 4656 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); |
| 4652 | 4657 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); |
| @@ -7368,101 +7373,118 @@ | ||
| 7368 | 7373 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 7369 | 7374 | |
| 7370 | 7375 | /* |
| 7371 | 7376 | ** CAPI3REF: Checkpoint a database |
| 7372 | 7377 | ** |
| 7373 | -** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X | |
| 7374 | -** on [database connection] D to be [checkpointed]. ^If X is NULL or an | |
| 7375 | -** empty string, then a checkpoint is run on all databases of | |
| 7376 | -** connection D. ^If the database connection D is not in | |
| 7377 | -** [WAL | write-ahead log mode] then this interface is a harmless no-op. | |
| 7378 | -** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a | |
| 7379 | -** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. | |
| 7380 | -** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL | |
| 7381 | -** or RESET checkpoint. | |
| 7382 | -** | |
| 7383 | -** ^The [wal_checkpoint pragma] can be used to invoke this interface | |
| 7384 | -** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the | |
| 7385 | -** [wal_autocheckpoint pragma] can be used to cause this interface to be | |
| 7386 | -** run whenever the WAL reaches a certain size threshold. | |
| 7387 | -** | |
| 7388 | -** See also: [sqlite3_wal_checkpoint_v2()] | |
| 7378 | +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to | |
| 7379 | +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ | |
| 7380 | +** | |
| 7381 | +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the | |
| 7382 | +** [write-ahead log] for database X on [database connection] D to be | |
| 7383 | +** transferred into the database file and for the write-ahead log to | |
| 7384 | +** be reset. See the [checkpointing] documentation for addition | |
| 7385 | +** information. | |
| 7386 | +** | |
| 7387 | +** This interface used to be the only way to cause a checkpoint to | |
| 7388 | +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] | |
| 7389 | +** interface was added. This interface is retained for backwards | |
| 7390 | +** compatibility and as a convenience for applications that need to manually | |
| 7391 | +** start a callback but which do not need the full power (and corresponding | |
| 7392 | +** complication) of [sqlite3_wal_checkpoint_v2()]. | |
| 7389 | 7393 | */ |
| 7390 | 7394 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); |
| 7391 | 7395 | |
| 7392 | 7396 | /* |
| 7393 | 7397 | ** CAPI3REF: Checkpoint a database |
| 7394 | 7398 | ** |
| 7395 | -** Run a checkpoint operation on WAL database zDb attached to database | |
| 7396 | -** handle db. The specific operation is determined by the value of the | |
| 7397 | -** eMode parameter: | |
| 7399 | +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint | |
| 7400 | +** operation on database X of [database connection] D in mode M. Status | |
| 7401 | +** information is written back into integers pointed to by L and C.)^ | |
| 7402 | +** ^(The M parameter must be a valid [checkpoint mode]:)^ | |
| 7398 | 7403 | ** |
| 7399 | 7404 | ** <dl> |
| 7400 | 7405 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7401 | -** Checkpoint as many frames as possible without waiting for any database | |
| 7402 | -** readers or writers to finish. Sync the db file if all frames in the log | |
| 7403 | -** are checkpointed. This mode is the same as calling | |
| 7404 | -** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] | |
| 7405 | -** is never invoked. | |
| 7406 | +** ^Checkpoint as many frames as possible without waiting for any database | |
| 7407 | +** readers or writers to finish, then sync the database file if all frames | |
| 7408 | +** in the log were checkpointed. ^The [busy-handler callback] | |
| 7409 | +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. | |
| 7410 | +** ^On the other hand, passive mode might leave the checkpoint unfinished | |
| 7411 | +** if there are concurrent readers or writers. | |
| 7406 | 7412 | ** |
| 7407 | 7413 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7408 | -** This mode blocks (it invokes the | |
| 7414 | +** ^This mode blocks (it invokes the | |
| 7409 | 7415 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7410 | 7416 | ** database writer and all readers are reading from the most recent database |
| 7411 | -** snapshot. It then checkpoints all frames in the log file and syncs the | |
| 7412 | -** database file. This call blocks database writers while it is running, | |
| 7413 | -** but not database readers. | |
| 7417 | +** snapshot. ^It then checkpoints all frames in the log file and syncs the | |
| 7418 | +** database file. ^This mode blocks new database writers while it is pending, | |
| 7419 | +** but new database readers are allowed to continue unimpeded. | |
| 7414 | 7420 | ** |
| 7415 | 7421 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7416 | -** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after | |
| 7417 | -** checkpointing the log file it blocks (calls the | |
| 7418 | -** [sqlite3_busy_handler|busy-handler callback]) | |
| 7419 | -** until all readers are reading from the database file only. This ensures | |
| 7420 | -** that the next client to write to the database file restarts the log file | |
| 7421 | -** from the beginning. This call blocks database writers while it is running, | |
| 7422 | -** but not database readers. | |
| 7422 | +** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition | |
| 7423 | +** that after checkpointing the log file it blocks (calls the | |
| 7424 | +** [busy-handler callback]) | |
| 7425 | +** until all readers are reading from the database file only. ^This ensures | |
| 7426 | +** that the next writer will restart the log file from the beginning. | |
| 7427 | +** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new | |
| 7428 | +** database writer attempts while it is pending, but does not impede readers. | |
| 7429 | +** | |
| 7430 | +** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd> | |
| 7431 | +** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the | |
| 7432 | +** addition that it also truncates the log file to zero bytes just prior | |
| 7433 | +** to a successful return. | |
| 7423 | 7434 | ** </dl> |
| 7424 | 7435 | ** |
| 7425 | -** If pnLog is not NULL, then *pnLog is set to the total number of frames in | |
| 7426 | -** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to | |
| 7427 | -** the total number of checkpointed frames (including any that were already | |
| 7428 | -** checkpointed when this function is called). *pnLog and *pnCkpt may be | |
| 7429 | -** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. | |
| 7430 | -** If no values are available because of an error, they are both set to -1 | |
| 7431 | -** before returning to communicate this to the caller. | |
| 7436 | +** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in | |
| 7437 | +** the log file or to -1 if the checkpoint could not run because | |
| 7438 | +** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not | |
| 7439 | +** NULL,then *pnCkpt is set to the total number of checkpointed frames in the | |
| 7440 | +** log file (including any that were already checkpointed before the function | |
| 7441 | +** was called) or to -1 if the checkpoint could not run due to an error or | |
| 7442 | +** because the database is not in WAL mode. ^Note that upon successful | |
| 7443 | +** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been | |
| 7444 | +** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. | |
| 7432 | 7445 | ** |
| 7433 | -** All calls obtain an exclusive "checkpoint" lock on the database file. If | |
| 7446 | +** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If | |
| 7434 | 7447 | ** any other process is running a checkpoint operation at the same time, the |
| 7435 | -** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a | |
| 7448 | +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a | |
| 7436 | 7449 | ** busy-handler configured, it will not be invoked in this case. |
| 7437 | 7450 | ** |
| 7438 | -** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive | |
| 7439 | -** "writer" lock on the database file. If the writer lock cannot be obtained | |
| 7440 | -** immediately, and a busy-handler is configured, it is invoked and the writer | |
| 7441 | -** lock retried until either the busy-handler returns 0 or the lock is | |
| 7442 | -** successfully obtained. The busy-handler is also invoked while waiting for | |
| 7443 | -** database readers as described above. If the busy-handler returns 0 before | |
| 7451 | +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the | |
| 7452 | +** exclusive "writer" lock on the database file. ^If the writer lock cannot be | |
| 7453 | +** obtained immediately, and a busy-handler is configured, it is invoked and | |
| 7454 | +** the writer lock retried until either the busy-handler returns 0 or the lock | |
| 7455 | +** is successfully obtained. ^The busy-handler is also invoked while waiting for | |
| 7456 | +** database readers as described above. ^If the busy-handler returns 0 before | |
| 7444 | 7457 | ** the writer lock is obtained or while waiting for database readers, the |
| 7445 | 7458 | ** checkpoint operation proceeds from that point in the same way as |
| 7446 | 7459 | ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible |
| 7447 | -** without blocking any further. SQLITE_BUSY is returned in this case. | |
| 7460 | +** without blocking any further. ^SQLITE_BUSY is returned in this case. | |
| 7448 | 7461 | ** |
| 7449 | -** If parameter zDb is NULL or points to a zero length string, then the | |
| 7450 | -** specified operation is attempted on all WAL databases. In this case the | |
| 7451 | -** values written to output parameters *pnLog and *pnCkpt are undefined. If | |
| 7462 | +** ^If parameter zDb is NULL or points to a zero length string, then the | |
| 7463 | +** specified operation is attempted on all WAL databases [attached] to | |
| 7464 | +** [database connection] db. In this case the | |
| 7465 | +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If | |
| 7452 | 7466 | ** an SQLITE_BUSY error is encountered when processing one or more of the |
| 7453 | 7467 | ** attached WAL databases, the operation is still attempted on any remaining |
| 7454 | -** attached databases and SQLITE_BUSY is returned to the caller. If any other | |
| 7468 | +** attached databases and SQLITE_BUSY is returned at the end. ^If any other | |
| 7455 | 7469 | ** error occurs while processing an attached database, processing is abandoned |
| 7456 | -** and the error code returned to the caller immediately. If no error | |
| 7470 | +** and the error code is returned to the caller immediately. ^If no error | |
| 7457 | 7471 | ** (SQLITE_BUSY or otherwise) is encountered while processing the attached |
| 7458 | 7472 | ** databases, SQLITE_OK is returned. |
| 7459 | 7473 | ** |
| 7460 | -** If database zDb is the name of an attached database that is not in WAL | |
| 7461 | -** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If | |
| 7474 | +** ^If database zDb is the name of an attached database that is not in WAL | |
| 7475 | +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If | |
| 7462 | 7476 | ** zDb is not NULL (or a zero length string) and is not the name of any |
| 7463 | 7477 | ** attached database, SQLITE_ERROR is returned to the caller. |
| 7478 | +** | |
| 7479 | +** ^Unless it returns SQLITE_MISUSE, | |
| 7480 | +** the sqlite3_wal_checkpoint_v2() interface | |
| 7481 | +** sets the error information that is queried by | |
| 7482 | +** [sqlite3_errcode()] and [sqlite3_errmsg()]. | |
| 7483 | +** | |
| 7484 | +** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface | |
| 7485 | +** from SQL. | |
| 7464 | 7486 | */ |
| 7465 | 7487 | SQLITE_API int sqlite3_wal_checkpoint_v2( |
| 7466 | 7488 | sqlite3 *db, /* Database handle */ |
| 7467 | 7489 | const char *zDb, /* Name of attached database (or NULL) */ |
| 7468 | 7490 | int eMode, /* SQLITE_CHECKPOINT_* value */ |
| @@ -7469,20 +7491,22 @@ | ||
| 7469 | 7491 | int *pnLog, /* OUT: Size of WAL log in frames */ |
| 7470 | 7492 | int *pnCkpt /* OUT: Total number of frames checkpointed */ |
| 7471 | 7493 | ); |
| 7472 | 7494 | |
| 7473 | 7495 | /* |
| 7474 | -** CAPI3REF: Checkpoint operation parameters | |
| 7496 | +** CAPI3REF: Checkpoint Mode Values | |
| 7497 | +** KEYWORDS: {checkpoint mode} | |
| 7475 | 7498 | ** |
| 7476 | -** These constants can be used as the 3rd parameter to | |
| 7477 | -** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] | |
| 7478 | -** documentation for additional information about the meaning and use of | |
| 7479 | -** each of these values. | |
| 7499 | +** These constants define all valid values for the "checkpoint mode" passed | |
| 7500 | +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. | |
| 7501 | +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the | |
| 7502 | +** meaning of each of these checkpoint modes. | |
| 7480 | 7503 | */ |
| 7481 | -#define SQLITE_CHECKPOINT_PASSIVE 0 | |
| 7482 | -#define SQLITE_CHECKPOINT_FULL 1 | |
| 7483 | -#define SQLITE_CHECKPOINT_RESTART 2 | |
| 7504 | +#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ | |
| 7505 | +#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ | |
| 7506 | +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ | |
| 7507 | +#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ | |
| 7484 | 7508 | |
| 7485 | 7509 | /* |
| 7486 | 7510 | ** CAPI3REF: Virtual Table Interface Configuration |
| 7487 | 7511 | ** |
| 7488 | 7512 | ** This function may be called by either the [xConnect] or [xCreate] method |
| @@ -7577,16 +7601,16 @@ | ||
| 7577 | 7601 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7578 | 7602 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7579 | 7603 | ** |
| 7580 | 7604 | ** <dl> |
| 7581 | 7605 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7582 | -** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the | |
| 7583 | -** total number of times that the X-th loop has run.</dd> | |
| 7606 | +** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be | |
| 7607 | +** set to the total number of times that the X-th loop has run.</dd> | |
| 7584 | 7608 | ** |
| 7585 | 7609 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> |
| 7586 | -** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the | |
| 7587 | -** total number of rows examined by all iterations of the X-th loop.</dd> | |
| 7610 | +** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set | |
| 7611 | +** to the total number of rows examined by all iterations of the X-th loop.</dd> | |
| 7588 | 7612 | ** |
| 7589 | 7613 | ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> |
| 7590 | 7614 | ** <dd>^The "double" variable pointed to by the T parameter will be set to the |
| 7591 | 7615 | ** query planner's estimate for the average number of rows output from each |
| 7592 | 7616 | ** iteration of the X-th loop. If the query planner's estimates was accurate, |
| @@ -7593,18 +7617,18 @@ | ||
| 7593 | 7617 | ** then this value will approximate the quotient NVISIT/NLOOP and the |
| 7594 | 7618 | ** product of this value for all prior loops with the same SELECTID will |
| 7595 | 7619 | ** be the NLOOP value for the current loop. |
| 7596 | 7620 | ** |
| 7597 | 7621 | ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> |
| 7598 | -** <dd>^The "const char *" variable pointed to by the T parameter will be set to | |
| 7599 | -** a zero-terminated UTF-8 string containing the name of the index or table used | |
| 7600 | -** for the X-th loop. | |
| 7622 | +** <dd>^The "const char *" variable pointed to by the T parameter will be set | |
| 7623 | +** to a zero-terminated UTF-8 string containing the name of the index or table | |
| 7624 | +** used for the X-th loop. | |
| 7601 | 7625 | ** |
| 7602 | 7626 | ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> |
| 7603 | -** <dd>^The "const char *" variable pointed to by the T parameter will be set to | |
| 7604 | -** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description | |
| 7605 | -** for the X-th loop. | |
| 7627 | +** <dd>^The "const char *" variable pointed to by the T parameter will be set | |
| 7628 | +** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] | |
| 7629 | +** description for the X-th loop. | |
| 7606 | 7630 | ** |
| 7607 | 7631 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> |
| 7608 | 7632 | ** <dd>^The "int" variable pointed to by the T parameter will be set to the |
| 7609 | 7633 | ** "select-id" for the X-th loop. The select-id identifies which query or |
| 7610 | 7634 | ** subquery the loop is part of. The main query has a select-id of zero. |
| @@ -7623,12 +7647,12 @@ | ||
| 7623 | 7647 | ** CAPI3REF: Prepared Statement Scan Status |
| 7624 | 7648 | ** |
| 7625 | 7649 | ** Return status data for a single loop within query pStmt. |
| 7626 | 7650 | ** |
| 7627 | 7651 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7628 | -** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of | |
| 7629 | -** this interface is undefined. | |
| 7652 | +** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior | |
| 7653 | +** of this interface is undefined. | |
| 7630 | 7654 | ** ^The requested measurement is written into a variable pointed to by |
| 7631 | 7655 | ** the "pOut" parameter. |
| 7632 | 7656 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. |
| 7633 | 7657 | ** Loops are numbered starting from zero. ^If idx is out of range - less than |
| 7634 | 7658 | ** zero or greater than or equal to the total number of loops used to implement |
| @@ -11675,11 +11699,11 @@ | ||
| 11675 | 11699 | }; |
| 11676 | 11700 | |
| 11677 | 11701 | /* |
| 11678 | 11702 | ** The following are the meanings of bits in the Expr.flags field. |
| 11679 | 11703 | */ |
| 11680 | -#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */ | |
| 11704 | +#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ | |
| 11681 | 11705 | #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ |
| 11682 | 11706 | #define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ |
| 11683 | 11707 | #define EP_Error 0x000008 /* Expression contains one or more errors */ |
| 11684 | 11708 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 11685 | 11709 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| @@ -11695,10 +11719,11 @@ | ||
| 11695 | 11719 | #define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ |
| 11696 | 11720 | #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ |
| 11697 | 11721 | #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ |
| 11698 | 11722 | #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ |
| 11699 | 11723 | #define EP_Constant 0x080000 /* Node is a constant */ |
| 11724 | +#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ | |
| 11700 | 11725 | |
| 11701 | 11726 | /* |
| 11702 | 11727 | ** These macros can be used to test, set, or clear bits in the |
| 11703 | 11728 | ** Expr.flags field. |
| 11704 | 11729 | */ |
| @@ -48199,11 +48224,12 @@ | ||
| 48199 | 48224 | */ |
| 48200 | 48225 | SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ |
| 48201 | 48226 | int rc = SQLITE_OK; |
| 48202 | 48227 | if( pPager->pWal ){ |
| 48203 | 48228 | rc = sqlite3WalCheckpoint(pPager->pWal, eMode, |
| 48204 | - pPager->xBusyHandler, pPager->pBusyHandlerArg, | |
| 48229 | + (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), | |
| 48230 | + pPager->pBusyHandlerArg, | |
| 48205 | 48231 | pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, |
| 48206 | 48232 | pnLog, pnCkpt |
| 48207 | 48233 | ); |
| 48208 | 48234 | } |
| 48209 | 48235 | return rc; |
| @@ -50009,10 +50035,42 @@ | ||
| 50009 | 50035 | ** Return the page-size in bytes used by the database. |
| 50010 | 50036 | */ |
| 50011 | 50037 | static int walPagesize(Wal *pWal){ |
| 50012 | 50038 | return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); |
| 50013 | 50039 | } |
| 50040 | + | |
| 50041 | +/* | |
| 50042 | +** The following is guaranteed when this function is called: | |
| 50043 | +** | |
| 50044 | +** a) the WRITER lock is held, | |
| 50045 | +** b) the entire log file has been checkpointed, and | |
| 50046 | +** c) any existing readers are reading exclusively from the database | |
| 50047 | +** file - there are no readers that may attempt to read a frame from | |
| 50048 | +** the log file. | |
| 50049 | +** | |
| 50050 | +** This function updates the shared-memory structures so that the next | |
| 50051 | +** client to write to the database (which may be this one) does so by | |
| 50052 | +** writing frames into the start of the log file. | |
| 50053 | +** | |
| 50054 | +** The value of parameter salt1 is used as the aSalt[1] value in the | |
| 50055 | +** new wal-index header. It should be passed a pseudo-random value (i.e. | |
| 50056 | +** one obtained from sqlite3_randomness()). | |
| 50057 | +*/ | |
| 50058 | +static void walRestartHdr(Wal *pWal, u32 salt1){ | |
| 50059 | + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); | |
| 50060 | + int i; /* Loop counter */ | |
| 50061 | + u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ | |
| 50062 | + pWal->nCkpt++; | |
| 50063 | + pWal->hdr.mxFrame = 0; | |
| 50064 | + sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); | |
| 50065 | + memcpy(&pWal->hdr.aSalt[1], &salt1, 4); | |
| 50066 | + walIndexWriteHdr(pWal); | |
| 50067 | + pInfo->nBackfill = 0; | |
| 50068 | + pInfo->aReadMark[1] = 0; | |
| 50069 | + for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; | |
| 50070 | + assert( pInfo->aReadMark[0]==0 ); | |
| 50071 | +} | |
| 50014 | 50072 | |
| 50015 | 50073 | /* |
| 50016 | 50074 | ** Copy as much content as we can from the WAL back into the database file |
| 50017 | 50075 | ** in response to an sqlite3_wal_checkpoint() request or the equivalent. |
| 50018 | 50076 | ** |
| @@ -50044,11 +50102,11 @@ | ||
| 50044 | 50102 | ** time. |
| 50045 | 50103 | */ |
| 50046 | 50104 | static int walCheckpoint( |
| 50047 | 50105 | Wal *pWal, /* Wal connection */ |
| 50048 | 50106 | int eMode, /* One of PASSIVE, FULL or RESTART */ |
| 50049 | - int (*xBusyCall)(void*), /* Function to call when busy */ | |
| 50107 | + int (*xBusy)(void*), /* Function to call when busy */ | |
| 50050 | 50108 | void *pBusyArg, /* Context argument for xBusyHandler */ |
| 50051 | 50109 | int sync_flags, /* Flags for OsSync() (or 0) */ |
| 50052 | 50110 | u8 *zBuf /* Temporary buffer to use */ |
| 50053 | 50111 | ){ |
| 50054 | 50112 | int rc; /* Return code */ |
| @@ -50058,11 +50116,10 @@ | ||
| 50058 | 50116 | u32 iFrame = 0; /* Wal frame containing data for iDbpage */ |
| 50059 | 50117 | u32 mxSafeFrame; /* Max frame that can be backfilled */ |
| 50060 | 50118 | u32 mxPage; /* Max database page to write */ |
| 50061 | 50119 | int i; /* Loop counter */ |
| 50062 | 50120 | volatile WalCkptInfo *pInfo; /* The checkpoint status information */ |
| 50063 | - int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */ | |
| 50064 | 50121 | |
| 50065 | 50122 | szPage = walPagesize(pWal); |
| 50066 | 50123 | testcase( szPage<=32768 ); |
| 50067 | 50124 | testcase( szPage>=65536 ); |
| 50068 | 50125 | pInfo = walCkptInfo(pWal); |
| @@ -50073,11 +50130,13 @@ | ||
| 50073 | 50130 | if( rc!=SQLITE_OK ){ |
| 50074 | 50131 | return rc; |
| 50075 | 50132 | } |
| 50076 | 50133 | assert( pIter ); |
| 50077 | 50134 | |
| 50078 | - if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall; | |
| 50135 | + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked | |
| 50136 | + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ | |
| 50137 | + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); | |
| 50079 | 50138 | |
| 50080 | 50139 | /* Compute in mxSafeFrame the index of the last frame of the WAL that is |
| 50081 | 50140 | ** safe to write into the database. Frames beyond mxSafeFrame might |
| 50082 | 50141 | ** overwrite database pages that are in use by active readers and thus |
| 50083 | 50142 | ** cannot be backfilled from the WAL. |
| @@ -50162,23 +50221,42 @@ | ||
| 50162 | 50221 | /* Reset the return code so as not to report a checkpoint failure |
| 50163 | 50222 | ** just because there are active readers. */ |
| 50164 | 50223 | rc = SQLITE_OK; |
| 50165 | 50224 | } |
| 50166 | 50225 | |
| 50167 | - /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal | |
| 50168 | - ** file has been copied into the database file, then block until all | |
| 50169 | - ** readers have finished using the wal file. This ensures that the next | |
| 50170 | - ** process to write to the database restarts the wal file. | |
| 50226 | + /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the | |
| 50227 | + ** entire wal file has been copied into the database file, then block | |
| 50228 | + ** until all readers have finished using the wal file. This ensures that | |
| 50229 | + ** the next process to write to the database restarts the wal file. | |
| 50171 | 50230 | */ |
| 50172 | 50231 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 50173 | 50232 | assert( pWal->writeLock ); |
| 50174 | 50233 | if( pInfo->nBackfill<pWal->hdr.mxFrame ){ |
| 50175 | 50234 | rc = SQLITE_BUSY; |
| 50176 | - }else if( eMode==SQLITE_CHECKPOINT_RESTART ){ | |
| 50235 | + }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ | |
| 50236 | + u32 salt1; | |
| 50237 | + sqlite3_randomness(4, &salt1); | |
| 50177 | 50238 | assert( mxSafeFrame==pWal->hdr.mxFrame ); |
| 50178 | 50239 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 50179 | 50240 | if( rc==SQLITE_OK ){ |
| 50241 | + if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ | |
| 50242 | + /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as | |
| 50243 | + ** SQLITE_CHECKPOINT_RESTART with the addition that it also | |
| 50244 | + ** truncates the log file to zero bytes just prior to a | |
| 50245 | + ** successful return. | |
| 50246 | + ** | |
| 50247 | + ** In theory, it might be safe to do this without updating the | |
| 50248 | + ** wal-index header in shared memory, as all subsequent reader or | |
| 50249 | + ** writer clients should see that the entire log file has been | |
| 50250 | + ** checkpointed and behave accordingly. This seems unsafe though, | |
| 50251 | + ** as it would leave the system in a state where the contents of | |
| 50252 | + ** the wal-index header do not match the contents of the | |
| 50253 | + ** file-system. To avoid this, update the wal-index header to | |
| 50254 | + ** indicate that the log file contains zero valid frames. */ | |
| 50255 | + walRestartHdr(pWal, salt1); | |
| 50256 | + rc = sqlite3OsTruncate(pWal->pWalFd, 0); | |
| 50257 | + } | |
| 50180 | 50258 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 50181 | 50259 | } |
| 50182 | 50260 | } |
| 50183 | 50261 | } |
| 50184 | 50262 | |
| @@ -50960,11 +51038,10 @@ | ||
| 50960 | 51038 | } |
| 50961 | 51039 | |
| 50962 | 51040 | return rc; |
| 50963 | 51041 | } |
| 50964 | 51042 | |
| 50965 | - | |
| 50966 | 51043 | /* |
| 50967 | 51044 | ** This function is called just before writing a set of frames to the log |
| 50968 | 51045 | ** file (see sqlite3WalFrames()). It checks to see if, instead of appending |
| 50969 | 51046 | ** to the current log file, it is possible to overwrite the start of the |
| 50970 | 51047 | ** existing log file with the new frames (i.e. "reset" the log). If so, |
| @@ -50993,24 +51070,12 @@ | ||
| 50993 | 51070 | ** wal-index header to reflect this. |
| 50994 | 51071 | ** |
| 50995 | 51072 | ** In theory it would be Ok to update the cache of the header only |
| 50996 | 51073 | ** at this point. But updating the actual wal-index header is also |
| 50997 | 51074 | ** safe and means there is no special case for sqlite3WalUndo() |
| 50998 | - ** to handle if this transaction is rolled back. | |
| 50999 | - */ | |
| 51000 | - int i; /* Loop counter */ | |
| 51001 | - u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ | |
| 51002 | - | |
| 51003 | - pWal->nCkpt++; | |
| 51004 | - pWal->hdr.mxFrame = 0; | |
| 51005 | - sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); | |
| 51006 | - aSalt[1] = salt1; | |
| 51007 | - walIndexWriteHdr(pWal); | |
| 51008 | - pInfo->nBackfill = 0; | |
| 51009 | - pInfo->aReadMark[1] = 0; | |
| 51010 | - for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; | |
| 51011 | - assert( pInfo->aReadMark[0]==0 ); | |
| 51075 | + ** to handle if this transaction is rolled back. */ | |
| 51076 | + walRestartHdr(pWal, salt1); | |
| 51012 | 51077 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 51013 | 51078 | }else if( rc!=SQLITE_BUSY ){ |
| 51014 | 51079 | return rc; |
| 51015 | 51080 | } |
| 51016 | 51081 | } |
| @@ -51294,11 +51359,11 @@ | ||
| 51294 | 51359 | ** If parameter xBusy is not NULL, it is a pointer to a busy-handler |
| 51295 | 51360 | ** callback. In this case this function runs a blocking checkpoint. |
| 51296 | 51361 | */ |
| 51297 | 51362 | SQLITE_PRIVATE int sqlite3WalCheckpoint( |
| 51298 | 51363 | Wal *pWal, /* Wal connection */ |
| 51299 | - int eMode, /* PASSIVE, FULL or RESTART */ | |
| 51364 | + int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ | |
| 51300 | 51365 | int (*xBusy)(void*), /* Function to call when busy */ |
| 51301 | 51366 | void *pBusyArg, /* Context argument for xBusyHandler */ |
| 51302 | 51367 | int sync_flags, /* Flags to sync db file with (or 0) */ |
| 51303 | 51368 | int nBuf, /* Size of temporary buffer */ |
| 51304 | 51369 | u8 *zBuf, /* Temporary buffer to use */ |
| @@ -51306,40 +51371,54 @@ | ||
| 51306 | 51371 | int *pnCkpt /* OUT: Number of backfilled frames in WAL */ |
| 51307 | 51372 | ){ |
| 51308 | 51373 | int rc; /* Return code */ |
| 51309 | 51374 | int isChanged = 0; /* True if a new wal-index header is loaded */ |
| 51310 | 51375 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 51376 | + int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */ | |
| 51311 | 51377 | |
| 51312 | 51378 | assert( pWal->ckptLock==0 ); |
| 51313 | 51379 | assert( pWal->writeLock==0 ); |
| 51314 | 51380 | |
| 51381 | + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked | |
| 51382 | + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ | |
| 51383 | + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); | |
| 51384 | + | |
| 51315 | 51385 | if( pWal->readOnly ) return SQLITE_READONLY; |
| 51316 | 51386 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 51387 | + | |
| 51388 | + /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive | |
| 51389 | + ** "checkpoint" lock on the database file. */ | |
| 51317 | 51390 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 51318 | 51391 | if( rc ){ |
| 51319 | - /* Usually this is SQLITE_BUSY meaning that another thread or process | |
| 51320 | - ** is already running a checkpoint, or maybe a recovery. But it might | |
| 51321 | - ** also be SQLITE_IOERR. */ | |
| 51392 | + /* EVIDENCE-OF: R-10421-19736 If any other process is running a | |
| 51393 | + ** checkpoint operation at the same time, the lock cannot be obtained and | |
| 51394 | + ** SQLITE_BUSY is returned. | |
| 51395 | + ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured, | |
| 51396 | + ** it will not be invoked in this case. | |
| 51397 | + */ | |
| 51398 | + testcase( rc==SQLITE_BUSY ); | |
| 51399 | + testcase( xBusy!=0 ); | |
| 51322 | 51400 | return rc; |
| 51323 | 51401 | } |
| 51324 | 51402 | pWal->ckptLock = 1; |
| 51325 | 51403 | |
| 51326 | - /* If this is a blocking-checkpoint, then obtain the write-lock as well | |
| 51327 | - ** to prevent any writers from running while the checkpoint is underway. | |
| 51328 | - ** This has to be done before the call to walIndexReadHdr() below. | |
| 51404 | + /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and | |
| 51405 | + ** TRUNCATE modes also obtain the exclusive "writer" lock on the database | |
| 51406 | + ** file. | |
| 51329 | 51407 | ** |
| 51330 | - ** If the writer lock cannot be obtained, then a passive checkpoint is | |
| 51331 | - ** run instead. Since the checkpointer is not holding the writer lock, | |
| 51332 | - ** there is no point in blocking waiting for any readers. Assuming no | |
| 51333 | - ** other error occurs, this function will return SQLITE_BUSY to the caller. | |
| 51408 | + ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained | |
| 51409 | + ** immediately, and a busy-handler is configured, it is invoked and the | |
| 51410 | + ** writer lock retried until either the busy-handler returns 0 or the | |
| 51411 | + ** lock is successfully obtained. | |
| 51334 | 51412 | */ |
| 51335 | 51413 | if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 51336 | 51414 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1); |
| 51337 | 51415 | if( rc==SQLITE_OK ){ |
| 51338 | 51416 | pWal->writeLock = 1; |
| 51339 | 51417 | }else if( rc==SQLITE_BUSY ){ |
| 51340 | 51418 | eMode2 = SQLITE_CHECKPOINT_PASSIVE; |
| 51419 | + xBusy2 = 0; | |
| 51341 | 51420 | rc = SQLITE_OK; |
| 51342 | 51421 | } |
| 51343 | 51422 | } |
| 51344 | 51423 | |
| 51345 | 51424 | /* Read the wal-index header. */ |
| @@ -51353,11 +51432,11 @@ | ||
| 51353 | 51432 | /* Copy data from the log to the database file. */ |
| 51354 | 51433 | if( rc==SQLITE_OK ){ |
| 51355 | 51434 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ |
| 51356 | 51435 | rc = SQLITE_CORRUPT_BKPT; |
| 51357 | 51436 | }else{ |
| 51358 | - rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf); | |
| 51437 | + rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); | |
| 51359 | 51438 | } |
| 51360 | 51439 | |
| 51361 | 51440 | /* If no error occurred, set the output variables. */ |
| 51362 | 51441 | if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ |
| 51363 | 51442 | if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; |
| @@ -53821,11 +53900,11 @@ | ||
| 53821 | 53900 | ** to see if defragmentation is necessary. |
| 53822 | 53901 | */ |
| 53823 | 53902 | testcase( gap+2+nByte==top ); |
| 53824 | 53903 | if( gap+2+nByte>top ){ |
| 53825 | 53904 | defragment_page: |
| 53826 | - testcase( pPage->nCell==0 ); | |
| 53905 | + assert( pPage->nCell>0 || CORRUPT_DB ); | |
| 53827 | 53906 | rc = defragmentPage(pPage); |
| 53828 | 53907 | if( rc ) return rc; |
| 53829 | 53908 | top = get2byteNotZero(&data[hdr+5]); |
| 53830 | 53909 | assert( gap+nByte<=top ); |
| 53831 | 53910 | } |
| @@ -58881,11 +58960,11 @@ | ||
| 58881 | 58960 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 58882 | 58961 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| 58883 | 58962 | assert( pPage->nOverflow==1 ); |
| 58884 | 58963 | |
| 58885 | 58964 | /* This error condition is now caught prior to reaching this function */ |
| 58886 | - if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; | |
| 58965 | + if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT; | |
| 58887 | 58966 | |
| 58888 | 58967 | /* Allocate a new page. This page will become the right-sibling of |
| 58889 | 58968 | ** pPage. Make the parent page writable, so that the new divider cell |
| 58890 | 58969 | ** may be inserted. If both these operations are successful, proceed. |
| 58891 | 58970 | */ |
| @@ -59324,11 +59403,15 @@ | ||
| 59324 | 59403 | ** pointer of the divider cell */ |
| 59325 | 59404 | memcpy(apCell[nCell], &pOld->aData[8], 4); |
| 59326 | 59405 | }else{ |
| 59327 | 59406 | assert( leafCorrection==4 ); |
| 59328 | 59407 | if( szCell[nCell]<4 ){ |
| 59329 | - /* Do not allow any cells smaller than 4 bytes. */ | |
| 59408 | + /* Do not allow any cells smaller than 4 bytes. If a smaller cell | |
| 59409 | + ** does exist, pad it with 0x00 bytes. */ | |
| 59410 | + assert( szCell[nCell]==3 ); | |
| 59411 | + assert( apCell[nCell]==&pTemp[iSpace1-3] ); | |
| 59412 | + pTemp[iSpace1++] = 0x00; | |
| 59330 | 59413 | szCell[nCell] = 4; |
| 59331 | 59414 | } |
| 59332 | 59415 | } |
| 59333 | 59416 | nCell++; |
| 59334 | 59417 | } |
| @@ -59559,11 +59642,15 @@ | ||
| 59559 | 59642 | ** was either part of sibling page iOld (possibly an overflow cell), |
| 59560 | 59643 | ** or else the divider cell to the left of sibling page iOld. So, |
| 59561 | 59644 | ** if sibling page iOld had the same page number as pNew, and if |
| 59562 | 59645 | ** pCell really was a part of sibling page iOld (not a divider or |
| 59563 | 59646 | ** overflow cell), we can skip updating the pointer map entries. */ |
| 59564 | - if( pNew->pgno!=aPgno[iOld] || pCell<aOld || pCell>=&aOld[usableSize] ){ | |
| 59647 | + if( iOld>=nNew | |
| 59648 | + || pNew->pgno!=aPgno[iOld] | |
| 59649 | + || pCell<aOld | |
| 59650 | + || pCell>=&aOld[usableSize] | |
| 59651 | + ){ | |
| 59565 | 59652 | if( !leafCorrection ){ |
| 59566 | 59653 | ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); |
| 59567 | 59654 | } |
| 59568 | 59655 | if( szCell[i]>pNew->minLocal ){ |
| 59569 | 59656 | ptrmapPutOvflPtr(pNew, pCell, &rc); |
| @@ -65699,11 +65786,11 @@ | ||
| 65699 | 65786 | for(n=0; n<nVar; n++){ |
| 65700 | 65787 | p->aVar[n].flags = MEM_Null; |
| 65701 | 65788 | p->aVar[n].db = db; |
| 65702 | 65789 | } |
| 65703 | 65790 | } |
| 65704 | - if( p->azVar ){ | |
| 65791 | + if( p->azVar && pParse->nzVar>0 ){ | |
| 65705 | 65792 | p->nzVar = pParse->nzVar; |
| 65706 | 65793 | memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); |
| 65707 | 65794 | memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); |
| 65708 | 65795 | } |
| 65709 | 65796 | if( p->aMem ){ |
| @@ -75629,12 +75716,12 @@ | ||
| 75629 | 75716 | |
| 75630 | 75717 | #ifndef SQLITE_OMIT_WAL |
| 75631 | 75718 | /* Opcode: Checkpoint P1 P2 P3 * * |
| 75632 | 75719 | ** |
| 75633 | 75720 | ** Checkpoint database P1. This is a no-op if P1 is not currently in |
| 75634 | -** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL | |
| 75635 | -** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns | |
| 75721 | +** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL, | |
| 75722 | +** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns | |
| 75636 | 75723 | ** SQLITE_BUSY or not, respectively. Write the number of pages in the |
| 75637 | 75724 | ** WAL after the checkpoint into mem[P3+1] and the number of pages |
| 75638 | 75725 | ** in the WAL that have been checkpointed after the checkpoint |
| 75639 | 75726 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 75640 | 75727 | ** mem[P3+2] are initialized to -1. |
| @@ -75648,10 +75735,11 @@ | ||
| 75648 | 75735 | aRes[0] = 0; |
| 75649 | 75736 | aRes[1] = aRes[2] = -1; |
| 75650 | 75737 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 75651 | 75738 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 75652 | 75739 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 75740 | + || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE | |
| 75653 | 75741 | ); |
| 75654 | 75742 | rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); |
| 75655 | 75743 | if( rc==SQLITE_BUSY ){ |
| 75656 | 75744 | rc = SQLITE_OK; |
| 75657 | 75745 | aRes[0] = 1; |
| @@ -80411,10 +80499,14 @@ | ||
| 80411 | 80499 | } |
| 80412 | 80500 | } |
| 80413 | 80501 | if( pMatch ){ |
| 80414 | 80502 | pExpr->iTable = pMatch->iCursor; |
| 80415 | 80503 | pExpr->pTab = pMatch->pTab; |
| 80504 | + assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */ | |
| 80505 | + if( (pMatch->jointype & JT_LEFT)!=0 ){ | |
| 80506 | + ExprSetProperty(pExpr, EP_CanBeNull); | |
| 80507 | + } | |
| 80416 | 80508 | pSchema = pExpr->pTab->pSchema; |
| 80417 | 80509 | } |
| 80418 | 80510 | } /* if( pSrcList ) */ |
| 80419 | 80511 | |
| 80420 | 80512 | #ifndef SQLITE_OMIT_TRIGGER |
| @@ -82968,11 +83060,12 @@ | ||
| 82968 | 83060 | case TK_FLOAT: |
| 82969 | 83061 | case TK_BLOB: |
| 82970 | 83062 | return 0; |
| 82971 | 83063 | case TK_COLUMN: |
| 82972 | 83064 | assert( p->pTab!=0 ); |
| 82973 | - return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0; | |
| 83065 | + return ExprHasProperty(p, EP_CanBeNull) || | |
| 83066 | + (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); | |
| 82974 | 83067 | default: |
| 82975 | 83068 | return 1; |
| 82976 | 83069 | } |
| 82977 | 83070 | } |
| 82978 | 83071 | |
| @@ -88351,11 +88444,11 @@ | ||
| 88351 | 88444 | tRowcnt avgEq = 0; |
| 88352 | 88445 | tRowcnt nRow; /* Number of rows in index */ |
| 88353 | 88446 | i64 nSum100 = 0; /* Number of terms contributing to sumEq */ |
| 88354 | 88447 | i64 nDist100; /* Number of distinct values in index */ |
| 88355 | 88448 | |
| 88356 | - if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){ | |
| 88449 | + if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ | |
| 88357 | 88450 | nRow = pFinal->anLt[iCol]; |
| 88358 | 88451 | nDist100 = (i64)100 * pFinal->anDLt[iCol]; |
| 88359 | 88452 | nSample--; |
| 88360 | 88453 | }else{ |
| 88361 | 88454 | nRow = pIdx->aiRowEst[0]; |
| @@ -103921,11 +104014,11 @@ | ||
| 103921 | 104014 | break; |
| 103922 | 104015 | #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ |
| 103923 | 104016 | |
| 103924 | 104017 | #ifndef SQLITE_OMIT_WAL |
| 103925 | 104018 | /* |
| 103926 | - ** PRAGMA [database.]wal_checkpoint = passive|full|restart | |
| 104019 | + ** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate | |
| 103927 | 104020 | ** |
| 103928 | 104021 | ** Checkpoint the database. |
| 103929 | 104022 | */ |
| 103930 | 104023 | case PragTyp_WAL_CHECKPOINT: { |
| 103931 | 104024 | int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); |
| @@ -103933,10 +104026,12 @@ | ||
| 103933 | 104026 | if( zRight ){ |
| 103934 | 104027 | if( sqlite3StrICmp(zRight, "full")==0 ){ |
| 103935 | 104028 | eMode = SQLITE_CHECKPOINT_FULL; |
| 103936 | 104029 | }else if( sqlite3StrICmp(zRight, "restart")==0 ){ |
| 103937 | 104030 | eMode = SQLITE_CHECKPOINT_RESTART; |
| 104031 | + }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ | |
| 104032 | + eMode = SQLITE_CHECKPOINT_TRUNCATE; | |
| 103938 | 104033 | } |
| 103939 | 104034 | } |
| 103940 | 104035 | sqlite3VdbeSetNumCols(v, 3); |
| 103941 | 104036 | pParse->nMem = 3; |
| 103942 | 104037 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); |
| @@ -109840,11 +109935,11 @@ | ||
| 109840 | 109935 | ** |
| 109841 | 109936 | ** SELECT DISTINCT xyz FROM ... ORDER BY xyz |
| 109842 | 109937 | ** |
| 109843 | 109938 | ** is transformed to: |
| 109844 | 109939 | ** |
| 109845 | - ** SELECT xyz FROM ... GROUP BY xyz | |
| 109940 | + ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz | |
| 109846 | 109941 | ** |
| 109847 | 109942 | ** The second form is preferred as a single index (or temp-table) may be |
| 109848 | 109943 | ** used for both the ORDER BY and DISTINCT processing. As originally |
| 109849 | 109944 | ** written the query must use a temp-table for at least one of the ORDER |
| 109850 | 109945 | ** BY and DISTINCT, and an index or separate temp-table for the other. |
| @@ -109853,11 +109948,10 @@ | ||
| 109853 | 109948 | && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 |
| 109854 | 109949 | ){ |
| 109855 | 109950 | p->selFlags &= ~SF_Distinct; |
| 109856 | 109951 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); |
| 109857 | 109952 | pGroupBy = p->pGroupBy; |
| 109858 | - sSort.pOrderBy = 0; | |
| 109859 | 109953 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 109860 | 109954 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| 109861 | 109955 | ** original setting of the SF_Distinct flag, not the current setting */ |
| 109862 | 109956 | assert( sDistinct.isTnct ); |
| 109863 | 109957 | } |
| @@ -114808,10 +114902,11 @@ | ||
| 114808 | 114902 | memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); |
| 114809 | 114903 | if( pOld!=pWC->aStatic ){ |
| 114810 | 114904 | sqlite3DbFree(db, pOld); |
| 114811 | 114905 | } |
| 114812 | 114906 | pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); |
| 114907 | + memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm)); | |
| 114813 | 114908 | } |
| 114814 | 114909 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 114815 | 114910 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 114816 | 114911 | pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; |
| 114817 | 114912 | }else{ |
| @@ -117533,11 +117628,11 @@ | ||
| 117533 | 117628 | WhereLevel *pLvl, /* Level to add scanstatus() entry for */ |
| 117534 | 117629 | int addrExplain /* Address of OP_Explain (or 0) */ |
| 117535 | 117630 | ){ |
| 117536 | 117631 | const char *zObj = 0; |
| 117537 | 117632 | WhereLoop *pLoop = pLvl->pWLoop; |
| 117538 | - if( (pLoop->wsFlags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ | |
| 117633 | + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ | |
| 117539 | 117634 | zObj = pLoop->u.btree.pIndex->zName; |
| 117540 | 117635 | }else{ |
| 117541 | 117636 | zObj = pSrclist->a[pLvl->iFrom].zName; |
| 117542 | 117637 | } |
| 117543 | 117638 | sqlite3VdbeScanStatus( |
| @@ -118177,14 +118272,13 @@ | ||
| 118177 | 118272 | int iTerm; |
| 118178 | 118273 | for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ |
| 118179 | 118274 | Expr *pExpr = pWC->a[iTerm].pExpr; |
| 118180 | 118275 | if( &pWC->a[iTerm] == pTerm ) continue; |
| 118181 | 118276 | if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; |
| 118182 | - testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); | |
| 118183 | - testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); | |
| 118184 | - if( pWC->a[iTerm].wtFlags & (TERM_ORINFO|TERM_VIRTUAL) ) continue; | |
| 118277 | + if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue; | |
| 118185 | 118278 | if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; |
| 118279 | + testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); | |
| 118186 | 118280 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 118187 | 118281 | pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); |
| 118188 | 118282 | } |
| 118189 | 118283 | if( pAndExpr ){ |
| 118190 | 118284 | pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); |
| @@ -127079,10 +127173,18 @@ | ||
| 127079 | 127173 | |
| 127080 | 127174 | /* Close all database connections */ |
| 127081 | 127175 | for(j=0; j<db->nDb; j++){ |
| 127082 | 127176 | struct Db *pDb = &db->aDb[j]; |
| 127083 | 127177 | if( pDb->pBt ){ |
| 127178 | + if( pDb->pSchema ){ | |
| 127179 | + /* Must clear the KeyInfo cache. See ticket [e4a18565a36884b00edf] */ | |
| 127180 | + for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){ | |
| 127181 | + Index *pIdx = sqliteHashData(i); | |
| 127182 | + sqlite3KeyInfoUnref(pIdx->pKeyInfo); | |
| 127183 | + pIdx->pKeyInfo = 0; | |
| 127184 | + } | |
| 127185 | + } | |
| 127084 | 127186 | sqlite3BtreeClose(pDb->pBt); |
| 127085 | 127187 | pDb->pBt = 0; |
| 127086 | 127188 | if( j!=1 ){ |
| 127087 | 127189 | pDb->pSchema = 0; |
| 127088 | 127190 | } |
| @@ -127983,14 +128085,17 @@ | ||
| 127983 | 128085 | |
| 127984 | 128086 | /* Initialize the output variables to -1 in case an error occurs. */ |
| 127985 | 128087 | if( pnLog ) *pnLog = -1; |
| 127986 | 128088 | if( pnCkpt ) *pnCkpt = -1; |
| 127987 | 128089 | |
| 127988 | - assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE ); | |
| 127989 | - assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART ); | |
| 127990 | - assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART ); | |
| 127991 | - if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){ | |
| 128090 | + assert( SQLITE_CHECKPOINT_PASSIVE==0 ); | |
| 128091 | + assert( SQLITE_CHECKPOINT_FULL==1 ); | |
| 128092 | + assert( SQLITE_CHECKPOINT_RESTART==2 ); | |
| 128093 | + assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); | |
| 128094 | + if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){ | |
| 128095 | + /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint | |
| 128096 | + ** mode: */ | |
| 127992 | 128097 | return SQLITE_MISUSE; |
| 127993 | 128098 | } |
| 127994 | 128099 | |
| 127995 | 128100 | sqlite3_mutex_enter(db->mutex); |
| 127996 | 128101 | if( zDb && zDb[0] ){ |
| @@ -128014,11 +128119,13 @@ | ||
| 128014 | 128119 | ** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points |
| 128015 | 128120 | ** to contains a zero-length string, all attached databases are |
| 128016 | 128121 | ** checkpointed. |
| 128017 | 128122 | */ |
| 128018 | 128123 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ |
| 128019 | - return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0); | |
| 128124 | + /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to | |
| 128125 | + ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ | |
| 128126 | + return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); | |
| 128020 | 128127 | } |
| 128021 | 128128 | |
| 128022 | 128129 | #ifndef SQLITE_OMIT_WAL |
| 128023 | 128130 | /* |
| 128024 | 128131 | ** Run a checkpoint on database iDb. This is a no-op if database iDb is |
| @@ -139164,11 +139271,11 @@ | ||
| 139164 | 139271 | ** Return true if the m-value for z is 1 or more. In other words, |
| 139165 | 139272 | ** return true if z contains at least one vowel that is followed |
| 139166 | 139273 | ** by a consonant. |
| 139167 | 139274 | ** |
| 139168 | 139275 | ** In this routine z[] is in reverse order. So we are really looking |
| 139169 | -** for an instance of of a consonant followed by a vowel. | |
| 139276 | +** for an instance of a consonant followed by a vowel. | |
| 139170 | 139277 | */ |
| 139171 | 139278 | static int m_gt_0(const char *z){ |
| 139172 | 139279 | while( isVowel(z) ){ z++; } |
| 139173 | 139280 | if( *z==0 ) return 0; |
| 139174 | 139281 | while( isConsonant(z) ){ z++; } |
| 139175 | 139282 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -231,11 +231,11 @@ | |
| 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | */ |
| 234 | #define SQLITE_VERSION "3.8.8" |
| 235 | #define SQLITE_VERSION_NUMBER 3008008 |
| 236 | #define SQLITE_SOURCE_ID "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e" |
| 237 | |
| 238 | /* |
| 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | ** |
| @@ -1343,11 +1343,11 @@ | |
| 1343 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED |
| 1344 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE |
| 1345 | ** </ul> |
| 1346 | ** |
| 1347 | ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as |
| 1348 | ** was given no the corresponding lock. |
| 1349 | ** |
| 1350 | ** The xShmLock method can transition between unlocked and SHARED or |
| 1351 | ** between unlocked and EXCLUSIVE. It cannot transition between SHARED |
| 1352 | ** and EXCLUSIVE. |
| 1353 | */ |
| @@ -1646,12 +1646,12 @@ | |
| 1646 | ** tracks memory usage, for example. </dd> |
| 1647 | ** |
| 1648 | ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> |
| 1649 | ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, |
| 1650 | ** interpreted as a boolean, which enables or disables the collection of |
| 1651 | ** memory allocation statistics. ^(When memory allocation statistics are disabled, the |
| 1652 | ** following SQLite interfaces become non-operational: |
| 1653 | ** <ul> |
| 1654 | ** <li> [sqlite3_memory_used()] |
| 1655 | ** <li> [sqlite3_memory_highwater()] |
| 1656 | ** <li> [sqlite3_soft_heap_limit64()] |
| 1657 | ** <li> [sqlite3_status()] |
| @@ -1688,11 +1688,12 @@ | |
| 1688 | ** that SQLite can use for the database page cache with the default page |
| 1689 | ** cache implementation. |
| 1690 | ** This configuration should not be used if an application-define page |
| 1691 | ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] |
| 1692 | ** configuration option. |
| 1693 | ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned |
| 1694 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1695 | ** The sz argument should be the size of the largest database page |
| 1696 | ** (a power of two between 512 and 32768) plus some extra bytes for each |
| 1697 | ** page header. ^The number of extra bytes needed by the page header |
| 1698 | ** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option |
| @@ -1708,11 +1709,12 @@ | |
| 1708 | ** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd> |
| 1709 | ** |
| 1710 | ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> |
| 1711 | ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer |
| 1712 | ** that SQLite will use for all of its dynamic memory allocation needs |
| 1713 | ** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. |
| 1714 | ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled |
| 1715 | ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns |
| 1716 | ** [SQLITE_ERROR] if invoked otherwise. |
| 1717 | ** ^There are three arguments to SQLITE_CONFIG_HEAP: |
| 1718 | ** An 8-byte aligned pointer to the memory, |
| @@ -1728,13 +1730,13 @@ | |
| 1728 | ** for the minimum allocation size are 2**5 through 2**8.</dd> |
| 1729 | ** |
| 1730 | ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1731 | ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a |
| 1732 | ** pointer to an instance of the [sqlite3_mutex_methods] structure. |
| 1733 | ** The argument specifies alternative low-level mutex routines to be used in place |
| 1734 | ** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the |
| 1735 | ** content of the [sqlite3_mutex_methods] structure before the call to |
| 1736 | ** [sqlite3_config()] returns. ^If SQLite is compiled with |
| 1737 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then |
| 1738 | ** the entire mutexing subsystem is omitted from the build and hence calls to |
| 1739 | ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will |
| 1740 | ** return [SQLITE_ERROR].</dd> |
| @@ -1768,12 +1770,12 @@ | |
| 1768 | ** the interface to a custom page cache implementation.)^ |
| 1769 | ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> |
| 1770 | ** |
| 1771 | ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> |
| 1772 | ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which |
| 1773 | ** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of the current |
| 1774 | ** page cache implementation into that object.)^ </dd> |
| 1775 | ** |
| 1776 | ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> |
| 1777 | ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite |
| 1778 | ** global [error log]. |
| 1779 | ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a |
| @@ -1794,12 +1796,13 @@ | |
| 1794 | ** function must be threadsafe. </dd> |
| 1795 | ** |
| 1796 | ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI |
| 1797 | ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| 1798 | ** If non-zero, then URI handling is globally enabled. If the parameter is zero, |
| 1799 | ** then URI handling is globally disabled.)^ ^If URI handling is globally enabled, |
| 1800 | ** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or |
| 1801 | ** specified as part of [ATTACH] commands are interpreted as URIs, regardless |
| 1802 | ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database |
| 1803 | ** connection is opened. ^If it is globally disabled, filenames are |
| 1804 | ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the |
| 1805 | ** database connection is opened. ^(By default, URI handling is globally |
| @@ -1857,21 +1860,21 @@ | |
| 1857 | ** changed to its compile-time default. |
| 1858 | ** |
| 1859 | ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1860 | ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1861 | ** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is |
| 1862 | ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. |
| 1863 | ** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value |
| 1864 | ** that specifies the maximum size of the created heap. |
| 1865 | ** </dl> |
| 1866 | ** |
| 1867 | ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] |
| 1868 | ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ |
| 1869 | ** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which |
| 1870 | ** is a pointer to an integer and writes into that integer the number of extra |
| 1871 | ** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of |
| 1872 | ** extra space required can change depending on the compiler, |
| 1873 | ** target platform, and SQLite version. |
| 1874 | ** </dl> |
| 1875 | */ |
| 1876 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1877 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| @@ -2171,10 +2174,11 @@ | |
| 2171 | SQLITE_API int sqlite3_complete(const char *sql); |
| 2172 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2173 | |
| 2174 | /* |
| 2175 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2176 | ** |
| 2177 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2178 | ** that might be invoked with argument P whenever |
| 2179 | ** an attempt is made to access a database table associated with |
| 2180 | ** [database connection] D when another thread |
| @@ -2187,11 +2191,11 @@ | |
| 2187 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2188 | ** |
| 2189 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2190 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2191 | ** the busy handler callback is the number of times that the busy handler has |
| 2192 | ** been invoked for the same locking event. ^If the |
| 2193 | ** busy callback returns 0, then no additional attempts are made to |
| 2194 | ** access the database and [SQLITE_BUSY] is returned |
| 2195 | ** to the application. |
| 2196 | ** ^If the callback returns non-zero, then another attempt |
| 2197 | ** is made to access the database and the cycle repeats. |
| @@ -4642,11 +4646,12 @@ | |
| 4642 | ** If these routines are called from within the different thread |
| 4643 | ** than the one containing the application-defined function that received |
| 4644 | ** the [sqlite3_context] pointer, the results are undefined. |
| 4645 | */ |
| 4646 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); |
| 4647 | SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void(*)(void*)); |
| 4648 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); |
| 4649 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); |
| 4650 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); |
| 4651 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); |
| 4652 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); |
| @@ -7368,101 +7373,118 @@ | |
| 7368 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 7369 | |
| 7370 | /* |
| 7371 | ** CAPI3REF: Checkpoint a database |
| 7372 | ** |
| 7373 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7374 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7375 | ** empty string, then a checkpoint is run on all databases of |
| 7376 | ** connection D. ^If the database connection D is not in |
| 7377 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7378 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a |
| 7379 | ** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. |
| 7380 | ** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL |
| 7381 | ** or RESET checkpoint. |
| 7382 | ** |
| 7383 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7384 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7385 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7386 | ** run whenever the WAL reaches a certain size threshold. |
| 7387 | ** |
| 7388 | ** See also: [sqlite3_wal_checkpoint_v2()] |
| 7389 | */ |
| 7390 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); |
| 7391 | |
| 7392 | /* |
| 7393 | ** CAPI3REF: Checkpoint a database |
| 7394 | ** |
| 7395 | ** Run a checkpoint operation on WAL database zDb attached to database |
| 7396 | ** handle db. The specific operation is determined by the value of the |
| 7397 | ** eMode parameter: |
| 7398 | ** |
| 7399 | ** <dl> |
| 7400 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7401 | ** Checkpoint as many frames as possible without waiting for any database |
| 7402 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7403 | ** are checkpointed. This mode is the same as calling |
| 7404 | ** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] |
| 7405 | ** is never invoked. |
| 7406 | ** |
| 7407 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7408 | ** This mode blocks (it invokes the |
| 7409 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7410 | ** database writer and all readers are reading from the most recent database |
| 7411 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7412 | ** database file. This call blocks database writers while it is running, |
| 7413 | ** but not database readers. |
| 7414 | ** |
| 7415 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7416 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7417 | ** checkpointing the log file it blocks (calls the |
| 7418 | ** [sqlite3_busy_handler|busy-handler callback]) |
| 7419 | ** until all readers are reading from the database file only. This ensures |
| 7420 | ** that the next client to write to the database file restarts the log file |
| 7421 | ** from the beginning. This call blocks database writers while it is running, |
| 7422 | ** but not database readers. |
| 7423 | ** </dl> |
| 7424 | ** |
| 7425 | ** If pnLog is not NULL, then *pnLog is set to the total number of frames in |
| 7426 | ** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to |
| 7427 | ** the total number of checkpointed frames (including any that were already |
| 7428 | ** checkpointed when this function is called). *pnLog and *pnCkpt may be |
| 7429 | ** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. |
| 7430 | ** If no values are available because of an error, they are both set to -1 |
| 7431 | ** before returning to communicate this to the caller. |
| 7432 | ** |
| 7433 | ** All calls obtain an exclusive "checkpoint" lock on the database file. If |
| 7434 | ** any other process is running a checkpoint operation at the same time, the |
| 7435 | ** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a |
| 7436 | ** busy-handler configured, it will not be invoked in this case. |
| 7437 | ** |
| 7438 | ** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive |
| 7439 | ** "writer" lock on the database file. If the writer lock cannot be obtained |
| 7440 | ** immediately, and a busy-handler is configured, it is invoked and the writer |
| 7441 | ** lock retried until either the busy-handler returns 0 or the lock is |
| 7442 | ** successfully obtained. The busy-handler is also invoked while waiting for |
| 7443 | ** database readers as described above. If the busy-handler returns 0 before |
| 7444 | ** the writer lock is obtained or while waiting for database readers, the |
| 7445 | ** checkpoint operation proceeds from that point in the same way as |
| 7446 | ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible |
| 7447 | ** without blocking any further. SQLITE_BUSY is returned in this case. |
| 7448 | ** |
| 7449 | ** If parameter zDb is NULL or points to a zero length string, then the |
| 7450 | ** specified operation is attempted on all WAL databases. In this case the |
| 7451 | ** values written to output parameters *pnLog and *pnCkpt are undefined. If |
| 7452 | ** an SQLITE_BUSY error is encountered when processing one or more of the |
| 7453 | ** attached WAL databases, the operation is still attempted on any remaining |
| 7454 | ** attached databases and SQLITE_BUSY is returned to the caller. If any other |
| 7455 | ** error occurs while processing an attached database, processing is abandoned |
| 7456 | ** and the error code returned to the caller immediately. If no error |
| 7457 | ** (SQLITE_BUSY or otherwise) is encountered while processing the attached |
| 7458 | ** databases, SQLITE_OK is returned. |
| 7459 | ** |
| 7460 | ** If database zDb is the name of an attached database that is not in WAL |
| 7461 | ** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If |
| 7462 | ** zDb is not NULL (or a zero length string) and is not the name of any |
| 7463 | ** attached database, SQLITE_ERROR is returned to the caller. |
| 7464 | */ |
| 7465 | SQLITE_API int sqlite3_wal_checkpoint_v2( |
| 7466 | sqlite3 *db, /* Database handle */ |
| 7467 | const char *zDb, /* Name of attached database (or NULL) */ |
| 7468 | int eMode, /* SQLITE_CHECKPOINT_* value */ |
| @@ -7469,20 +7491,22 @@ | |
| 7469 | int *pnLog, /* OUT: Size of WAL log in frames */ |
| 7470 | int *pnCkpt /* OUT: Total number of frames checkpointed */ |
| 7471 | ); |
| 7472 | |
| 7473 | /* |
| 7474 | ** CAPI3REF: Checkpoint operation parameters |
| 7475 | ** |
| 7476 | ** These constants can be used as the 3rd parameter to |
| 7477 | ** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] |
| 7478 | ** documentation for additional information about the meaning and use of |
| 7479 | ** each of these values. |
| 7480 | */ |
| 7481 | #define SQLITE_CHECKPOINT_PASSIVE 0 |
| 7482 | #define SQLITE_CHECKPOINT_FULL 1 |
| 7483 | #define SQLITE_CHECKPOINT_RESTART 2 |
| 7484 | |
| 7485 | /* |
| 7486 | ** CAPI3REF: Virtual Table Interface Configuration |
| 7487 | ** |
| 7488 | ** This function may be called by either the [xConnect] or [xCreate] method |
| @@ -7577,16 +7601,16 @@ | |
| 7577 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7578 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7579 | ** |
| 7580 | ** <dl> |
| 7581 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7582 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the |
| 7583 | ** total number of times that the X-th loop has run.</dd> |
| 7584 | ** |
| 7585 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> |
| 7586 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the |
| 7587 | ** total number of rows examined by all iterations of the X-th loop.</dd> |
| 7588 | ** |
| 7589 | ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> |
| 7590 | ** <dd>^The "double" variable pointed to by the T parameter will be set to the |
| 7591 | ** query planner's estimate for the average number of rows output from each |
| 7592 | ** iteration of the X-th loop. If the query planner's estimates was accurate, |
| @@ -7593,18 +7617,18 @@ | |
| 7593 | ** then this value will approximate the quotient NVISIT/NLOOP and the |
| 7594 | ** product of this value for all prior loops with the same SELECTID will |
| 7595 | ** be the NLOOP value for the current loop. |
| 7596 | ** |
| 7597 | ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> |
| 7598 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set to |
| 7599 | ** a zero-terminated UTF-8 string containing the name of the index or table used |
| 7600 | ** for the X-th loop. |
| 7601 | ** |
| 7602 | ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> |
| 7603 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set to |
| 7604 | ** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description |
| 7605 | ** for the X-th loop. |
| 7606 | ** |
| 7607 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> |
| 7608 | ** <dd>^The "int" variable pointed to by the T parameter will be set to the |
| 7609 | ** "select-id" for the X-th loop. The select-id identifies which query or |
| 7610 | ** subquery the loop is part of. The main query has a select-id of zero. |
| @@ -7623,12 +7647,12 @@ | |
| 7623 | ** CAPI3REF: Prepared Statement Scan Status |
| 7624 | ** |
| 7625 | ** Return status data for a single loop within query pStmt. |
| 7626 | ** |
| 7627 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7628 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of |
| 7629 | ** this interface is undefined. |
| 7630 | ** ^The requested measurement is written into a variable pointed to by |
| 7631 | ** the "pOut" parameter. |
| 7632 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. |
| 7633 | ** Loops are numbered starting from zero. ^If idx is out of range - less than |
| 7634 | ** zero or greater than or equal to the total number of loops used to implement |
| @@ -11675,11 +11699,11 @@ | |
| 11675 | }; |
| 11676 | |
| 11677 | /* |
| 11678 | ** The following are the meanings of bits in the Expr.flags field. |
| 11679 | */ |
| 11680 | #define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */ |
| 11681 | #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ |
| 11682 | #define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ |
| 11683 | #define EP_Error 0x000008 /* Expression contains one or more errors */ |
| 11684 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 11685 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| @@ -11695,10 +11719,11 @@ | |
| 11695 | #define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ |
| 11696 | #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ |
| 11697 | #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ |
| 11698 | #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ |
| 11699 | #define EP_Constant 0x080000 /* Node is a constant */ |
| 11700 | |
| 11701 | /* |
| 11702 | ** These macros can be used to test, set, or clear bits in the |
| 11703 | ** Expr.flags field. |
| 11704 | */ |
| @@ -48199,11 +48224,12 @@ | |
| 48199 | */ |
| 48200 | SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ |
| 48201 | int rc = SQLITE_OK; |
| 48202 | if( pPager->pWal ){ |
| 48203 | rc = sqlite3WalCheckpoint(pPager->pWal, eMode, |
| 48204 | pPager->xBusyHandler, pPager->pBusyHandlerArg, |
| 48205 | pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, |
| 48206 | pnLog, pnCkpt |
| 48207 | ); |
| 48208 | } |
| 48209 | return rc; |
| @@ -50009,10 +50035,42 @@ | |
| 50009 | ** Return the page-size in bytes used by the database. |
| 50010 | */ |
| 50011 | static int walPagesize(Wal *pWal){ |
| 50012 | return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); |
| 50013 | } |
| 50014 | |
| 50015 | /* |
| 50016 | ** Copy as much content as we can from the WAL back into the database file |
| 50017 | ** in response to an sqlite3_wal_checkpoint() request or the equivalent. |
| 50018 | ** |
| @@ -50044,11 +50102,11 @@ | |
| 50044 | ** time. |
| 50045 | */ |
| 50046 | static int walCheckpoint( |
| 50047 | Wal *pWal, /* Wal connection */ |
| 50048 | int eMode, /* One of PASSIVE, FULL or RESTART */ |
| 50049 | int (*xBusyCall)(void*), /* Function to call when busy */ |
| 50050 | void *pBusyArg, /* Context argument for xBusyHandler */ |
| 50051 | int sync_flags, /* Flags for OsSync() (or 0) */ |
| 50052 | u8 *zBuf /* Temporary buffer to use */ |
| 50053 | ){ |
| 50054 | int rc; /* Return code */ |
| @@ -50058,11 +50116,10 @@ | |
| 50058 | u32 iFrame = 0; /* Wal frame containing data for iDbpage */ |
| 50059 | u32 mxSafeFrame; /* Max frame that can be backfilled */ |
| 50060 | u32 mxPage; /* Max database page to write */ |
| 50061 | int i; /* Loop counter */ |
| 50062 | volatile WalCkptInfo *pInfo; /* The checkpoint status information */ |
| 50063 | int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */ |
| 50064 | |
| 50065 | szPage = walPagesize(pWal); |
| 50066 | testcase( szPage<=32768 ); |
| 50067 | testcase( szPage>=65536 ); |
| 50068 | pInfo = walCkptInfo(pWal); |
| @@ -50073,11 +50130,13 @@ | |
| 50073 | if( rc!=SQLITE_OK ){ |
| 50074 | return rc; |
| 50075 | } |
| 50076 | assert( pIter ); |
| 50077 | |
| 50078 | if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall; |
| 50079 | |
| 50080 | /* Compute in mxSafeFrame the index of the last frame of the WAL that is |
| 50081 | ** safe to write into the database. Frames beyond mxSafeFrame might |
| 50082 | ** overwrite database pages that are in use by active readers and thus |
| 50083 | ** cannot be backfilled from the WAL. |
| @@ -50162,23 +50221,42 @@ | |
| 50162 | /* Reset the return code so as not to report a checkpoint failure |
| 50163 | ** just because there are active readers. */ |
| 50164 | rc = SQLITE_OK; |
| 50165 | } |
| 50166 | |
| 50167 | /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal |
| 50168 | ** file has been copied into the database file, then block until all |
| 50169 | ** readers have finished using the wal file. This ensures that the next |
| 50170 | ** process to write to the database restarts the wal file. |
| 50171 | */ |
| 50172 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 50173 | assert( pWal->writeLock ); |
| 50174 | if( pInfo->nBackfill<pWal->hdr.mxFrame ){ |
| 50175 | rc = SQLITE_BUSY; |
| 50176 | }else if( eMode==SQLITE_CHECKPOINT_RESTART ){ |
| 50177 | assert( mxSafeFrame==pWal->hdr.mxFrame ); |
| 50178 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 50179 | if( rc==SQLITE_OK ){ |
| 50180 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 50181 | } |
| 50182 | } |
| 50183 | } |
| 50184 | |
| @@ -50960,11 +51038,10 @@ | |
| 50960 | } |
| 50961 | |
| 50962 | return rc; |
| 50963 | } |
| 50964 | |
| 50965 | |
| 50966 | /* |
| 50967 | ** This function is called just before writing a set of frames to the log |
| 50968 | ** file (see sqlite3WalFrames()). It checks to see if, instead of appending |
| 50969 | ** to the current log file, it is possible to overwrite the start of the |
| 50970 | ** existing log file with the new frames (i.e. "reset" the log). If so, |
| @@ -50993,24 +51070,12 @@ | |
| 50993 | ** wal-index header to reflect this. |
| 50994 | ** |
| 50995 | ** In theory it would be Ok to update the cache of the header only |
| 50996 | ** at this point. But updating the actual wal-index header is also |
| 50997 | ** safe and means there is no special case for sqlite3WalUndo() |
| 50998 | ** to handle if this transaction is rolled back. |
| 50999 | */ |
| 51000 | int i; /* Loop counter */ |
| 51001 | u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ |
| 51002 | |
| 51003 | pWal->nCkpt++; |
| 51004 | pWal->hdr.mxFrame = 0; |
| 51005 | sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); |
| 51006 | aSalt[1] = salt1; |
| 51007 | walIndexWriteHdr(pWal); |
| 51008 | pInfo->nBackfill = 0; |
| 51009 | pInfo->aReadMark[1] = 0; |
| 51010 | for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 51011 | assert( pInfo->aReadMark[0]==0 ); |
| 51012 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 51013 | }else if( rc!=SQLITE_BUSY ){ |
| 51014 | return rc; |
| 51015 | } |
| 51016 | } |
| @@ -51294,11 +51359,11 @@ | |
| 51294 | ** If parameter xBusy is not NULL, it is a pointer to a busy-handler |
| 51295 | ** callback. In this case this function runs a blocking checkpoint. |
| 51296 | */ |
| 51297 | SQLITE_PRIVATE int sqlite3WalCheckpoint( |
| 51298 | Wal *pWal, /* Wal connection */ |
| 51299 | int eMode, /* PASSIVE, FULL or RESTART */ |
| 51300 | int (*xBusy)(void*), /* Function to call when busy */ |
| 51301 | void *pBusyArg, /* Context argument for xBusyHandler */ |
| 51302 | int sync_flags, /* Flags to sync db file with (or 0) */ |
| 51303 | int nBuf, /* Size of temporary buffer */ |
| 51304 | u8 *zBuf, /* Temporary buffer to use */ |
| @@ -51306,40 +51371,54 @@ | |
| 51306 | int *pnCkpt /* OUT: Number of backfilled frames in WAL */ |
| 51307 | ){ |
| 51308 | int rc; /* Return code */ |
| 51309 | int isChanged = 0; /* True if a new wal-index header is loaded */ |
| 51310 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 51311 | |
| 51312 | assert( pWal->ckptLock==0 ); |
| 51313 | assert( pWal->writeLock==0 ); |
| 51314 | |
| 51315 | if( pWal->readOnly ) return SQLITE_READONLY; |
| 51316 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 51317 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 51318 | if( rc ){ |
| 51319 | /* Usually this is SQLITE_BUSY meaning that another thread or process |
| 51320 | ** is already running a checkpoint, or maybe a recovery. But it might |
| 51321 | ** also be SQLITE_IOERR. */ |
| 51322 | return rc; |
| 51323 | } |
| 51324 | pWal->ckptLock = 1; |
| 51325 | |
| 51326 | /* If this is a blocking-checkpoint, then obtain the write-lock as well |
| 51327 | ** to prevent any writers from running while the checkpoint is underway. |
| 51328 | ** This has to be done before the call to walIndexReadHdr() below. |
| 51329 | ** |
| 51330 | ** If the writer lock cannot be obtained, then a passive checkpoint is |
| 51331 | ** run instead. Since the checkpointer is not holding the writer lock, |
| 51332 | ** there is no point in blocking waiting for any readers. Assuming no |
| 51333 | ** other error occurs, this function will return SQLITE_BUSY to the caller. |
| 51334 | */ |
| 51335 | if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 51336 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1); |
| 51337 | if( rc==SQLITE_OK ){ |
| 51338 | pWal->writeLock = 1; |
| 51339 | }else if( rc==SQLITE_BUSY ){ |
| 51340 | eMode2 = SQLITE_CHECKPOINT_PASSIVE; |
| 51341 | rc = SQLITE_OK; |
| 51342 | } |
| 51343 | } |
| 51344 | |
| 51345 | /* Read the wal-index header. */ |
| @@ -51353,11 +51432,11 @@ | |
| 51353 | /* Copy data from the log to the database file. */ |
| 51354 | if( rc==SQLITE_OK ){ |
| 51355 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ |
| 51356 | rc = SQLITE_CORRUPT_BKPT; |
| 51357 | }else{ |
| 51358 | rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf); |
| 51359 | } |
| 51360 | |
| 51361 | /* If no error occurred, set the output variables. */ |
| 51362 | if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ |
| 51363 | if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; |
| @@ -53821,11 +53900,11 @@ | |
| 53821 | ** to see if defragmentation is necessary. |
| 53822 | */ |
| 53823 | testcase( gap+2+nByte==top ); |
| 53824 | if( gap+2+nByte>top ){ |
| 53825 | defragment_page: |
| 53826 | testcase( pPage->nCell==0 ); |
| 53827 | rc = defragmentPage(pPage); |
| 53828 | if( rc ) return rc; |
| 53829 | top = get2byteNotZero(&data[hdr+5]); |
| 53830 | assert( gap+nByte<=top ); |
| 53831 | } |
| @@ -58881,11 +58960,11 @@ | |
| 58881 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 58882 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| 58883 | assert( pPage->nOverflow==1 ); |
| 58884 | |
| 58885 | /* This error condition is now caught prior to reaching this function */ |
| 58886 | if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; |
| 58887 | |
| 58888 | /* Allocate a new page. This page will become the right-sibling of |
| 58889 | ** pPage. Make the parent page writable, so that the new divider cell |
| 58890 | ** may be inserted. If both these operations are successful, proceed. |
| 58891 | */ |
| @@ -59324,11 +59403,15 @@ | |
| 59324 | ** pointer of the divider cell */ |
| 59325 | memcpy(apCell[nCell], &pOld->aData[8], 4); |
| 59326 | }else{ |
| 59327 | assert( leafCorrection==4 ); |
| 59328 | if( szCell[nCell]<4 ){ |
| 59329 | /* Do not allow any cells smaller than 4 bytes. */ |
| 59330 | szCell[nCell] = 4; |
| 59331 | } |
| 59332 | } |
| 59333 | nCell++; |
| 59334 | } |
| @@ -59559,11 +59642,15 @@ | |
| 59559 | ** was either part of sibling page iOld (possibly an overflow cell), |
| 59560 | ** or else the divider cell to the left of sibling page iOld. So, |
| 59561 | ** if sibling page iOld had the same page number as pNew, and if |
| 59562 | ** pCell really was a part of sibling page iOld (not a divider or |
| 59563 | ** overflow cell), we can skip updating the pointer map entries. */ |
| 59564 | if( pNew->pgno!=aPgno[iOld] || pCell<aOld || pCell>=&aOld[usableSize] ){ |
| 59565 | if( !leafCorrection ){ |
| 59566 | ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); |
| 59567 | } |
| 59568 | if( szCell[i]>pNew->minLocal ){ |
| 59569 | ptrmapPutOvflPtr(pNew, pCell, &rc); |
| @@ -65699,11 +65786,11 @@ | |
| 65699 | for(n=0; n<nVar; n++){ |
| 65700 | p->aVar[n].flags = MEM_Null; |
| 65701 | p->aVar[n].db = db; |
| 65702 | } |
| 65703 | } |
| 65704 | if( p->azVar ){ |
| 65705 | p->nzVar = pParse->nzVar; |
| 65706 | memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); |
| 65707 | memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); |
| 65708 | } |
| 65709 | if( p->aMem ){ |
| @@ -75629,12 +75716,12 @@ | |
| 75629 | |
| 75630 | #ifndef SQLITE_OMIT_WAL |
| 75631 | /* Opcode: Checkpoint P1 P2 P3 * * |
| 75632 | ** |
| 75633 | ** Checkpoint database P1. This is a no-op if P1 is not currently in |
| 75634 | ** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL |
| 75635 | ** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns |
| 75636 | ** SQLITE_BUSY or not, respectively. Write the number of pages in the |
| 75637 | ** WAL after the checkpoint into mem[P3+1] and the number of pages |
| 75638 | ** in the WAL that have been checkpointed after the checkpoint |
| 75639 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 75640 | ** mem[P3+2] are initialized to -1. |
| @@ -75648,10 +75735,11 @@ | |
| 75648 | aRes[0] = 0; |
| 75649 | aRes[1] = aRes[2] = -1; |
| 75650 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 75651 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 75652 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 75653 | ); |
| 75654 | rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); |
| 75655 | if( rc==SQLITE_BUSY ){ |
| 75656 | rc = SQLITE_OK; |
| 75657 | aRes[0] = 1; |
| @@ -80411,10 +80499,14 @@ | |
| 80411 | } |
| 80412 | } |
| 80413 | if( pMatch ){ |
| 80414 | pExpr->iTable = pMatch->iCursor; |
| 80415 | pExpr->pTab = pMatch->pTab; |
| 80416 | pSchema = pExpr->pTab->pSchema; |
| 80417 | } |
| 80418 | } /* if( pSrcList ) */ |
| 80419 | |
| 80420 | #ifndef SQLITE_OMIT_TRIGGER |
| @@ -82968,11 +83060,12 @@ | |
| 82968 | case TK_FLOAT: |
| 82969 | case TK_BLOB: |
| 82970 | return 0; |
| 82971 | case TK_COLUMN: |
| 82972 | assert( p->pTab!=0 ); |
| 82973 | return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0; |
| 82974 | default: |
| 82975 | return 1; |
| 82976 | } |
| 82977 | } |
| 82978 | |
| @@ -88351,11 +88444,11 @@ | |
| 88351 | tRowcnt avgEq = 0; |
| 88352 | tRowcnt nRow; /* Number of rows in index */ |
| 88353 | i64 nSum100 = 0; /* Number of terms contributing to sumEq */ |
| 88354 | i64 nDist100; /* Number of distinct values in index */ |
| 88355 | |
| 88356 | if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){ |
| 88357 | nRow = pFinal->anLt[iCol]; |
| 88358 | nDist100 = (i64)100 * pFinal->anDLt[iCol]; |
| 88359 | nSample--; |
| 88360 | }else{ |
| 88361 | nRow = pIdx->aiRowEst[0]; |
| @@ -103921,11 +104014,11 @@ | |
| 103921 | break; |
| 103922 | #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ |
| 103923 | |
| 103924 | #ifndef SQLITE_OMIT_WAL |
| 103925 | /* |
| 103926 | ** PRAGMA [database.]wal_checkpoint = passive|full|restart |
| 103927 | ** |
| 103928 | ** Checkpoint the database. |
| 103929 | */ |
| 103930 | case PragTyp_WAL_CHECKPOINT: { |
| 103931 | int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); |
| @@ -103933,10 +104026,12 @@ | |
| 103933 | if( zRight ){ |
| 103934 | if( sqlite3StrICmp(zRight, "full")==0 ){ |
| 103935 | eMode = SQLITE_CHECKPOINT_FULL; |
| 103936 | }else if( sqlite3StrICmp(zRight, "restart")==0 ){ |
| 103937 | eMode = SQLITE_CHECKPOINT_RESTART; |
| 103938 | } |
| 103939 | } |
| 103940 | sqlite3VdbeSetNumCols(v, 3); |
| 103941 | pParse->nMem = 3; |
| 103942 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); |
| @@ -109840,11 +109935,11 @@ | |
| 109840 | ** |
| 109841 | ** SELECT DISTINCT xyz FROM ... ORDER BY xyz |
| 109842 | ** |
| 109843 | ** is transformed to: |
| 109844 | ** |
| 109845 | ** SELECT xyz FROM ... GROUP BY xyz |
| 109846 | ** |
| 109847 | ** The second form is preferred as a single index (or temp-table) may be |
| 109848 | ** used for both the ORDER BY and DISTINCT processing. As originally |
| 109849 | ** written the query must use a temp-table for at least one of the ORDER |
| 109850 | ** BY and DISTINCT, and an index or separate temp-table for the other. |
| @@ -109853,11 +109948,10 @@ | |
| 109853 | && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 |
| 109854 | ){ |
| 109855 | p->selFlags &= ~SF_Distinct; |
| 109856 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); |
| 109857 | pGroupBy = p->pGroupBy; |
| 109858 | sSort.pOrderBy = 0; |
| 109859 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 109860 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| 109861 | ** original setting of the SF_Distinct flag, not the current setting */ |
| 109862 | assert( sDistinct.isTnct ); |
| 109863 | } |
| @@ -114808,10 +114902,11 @@ | |
| 114808 | memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); |
| 114809 | if( pOld!=pWC->aStatic ){ |
| 114810 | sqlite3DbFree(db, pOld); |
| 114811 | } |
| 114812 | pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); |
| 114813 | } |
| 114814 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 114815 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 114816 | pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; |
| 114817 | }else{ |
| @@ -117533,11 +117628,11 @@ | |
| 117533 | WhereLevel *pLvl, /* Level to add scanstatus() entry for */ |
| 117534 | int addrExplain /* Address of OP_Explain (or 0) */ |
| 117535 | ){ |
| 117536 | const char *zObj = 0; |
| 117537 | WhereLoop *pLoop = pLvl->pWLoop; |
| 117538 | if( (pLoop->wsFlags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ |
| 117539 | zObj = pLoop->u.btree.pIndex->zName; |
| 117540 | }else{ |
| 117541 | zObj = pSrclist->a[pLvl->iFrom].zName; |
| 117542 | } |
| 117543 | sqlite3VdbeScanStatus( |
| @@ -118177,14 +118272,13 @@ | |
| 118177 | int iTerm; |
| 118178 | for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ |
| 118179 | Expr *pExpr = pWC->a[iTerm].pExpr; |
| 118180 | if( &pWC->a[iTerm] == pTerm ) continue; |
| 118181 | if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; |
| 118182 | testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); |
| 118183 | testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); |
| 118184 | if( pWC->a[iTerm].wtFlags & (TERM_ORINFO|TERM_VIRTUAL) ) continue; |
| 118185 | if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; |
| 118186 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 118187 | pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); |
| 118188 | } |
| 118189 | if( pAndExpr ){ |
| 118190 | pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); |
| @@ -127079,10 +127173,18 @@ | |
| 127079 | |
| 127080 | /* Close all database connections */ |
| 127081 | for(j=0; j<db->nDb; j++){ |
| 127082 | struct Db *pDb = &db->aDb[j]; |
| 127083 | if( pDb->pBt ){ |
| 127084 | sqlite3BtreeClose(pDb->pBt); |
| 127085 | pDb->pBt = 0; |
| 127086 | if( j!=1 ){ |
| 127087 | pDb->pSchema = 0; |
| 127088 | } |
| @@ -127983,14 +128085,17 @@ | |
| 127983 | |
| 127984 | /* Initialize the output variables to -1 in case an error occurs. */ |
| 127985 | if( pnLog ) *pnLog = -1; |
| 127986 | if( pnCkpt ) *pnCkpt = -1; |
| 127987 | |
| 127988 | assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE ); |
| 127989 | assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART ); |
| 127990 | assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART ); |
| 127991 | if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){ |
| 127992 | return SQLITE_MISUSE; |
| 127993 | } |
| 127994 | |
| 127995 | sqlite3_mutex_enter(db->mutex); |
| 127996 | if( zDb && zDb[0] ){ |
| @@ -128014,11 +128119,13 @@ | |
| 128014 | ** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points |
| 128015 | ** to contains a zero-length string, all attached databases are |
| 128016 | ** checkpointed. |
| 128017 | */ |
| 128018 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ |
| 128019 | return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0); |
| 128020 | } |
| 128021 | |
| 128022 | #ifndef SQLITE_OMIT_WAL |
| 128023 | /* |
| 128024 | ** Run a checkpoint on database iDb. This is a no-op if database iDb is |
| @@ -139164,11 +139271,11 @@ | |
| 139164 | ** Return true if the m-value for z is 1 or more. In other words, |
| 139165 | ** return true if z contains at least one vowel that is followed |
| 139166 | ** by a consonant. |
| 139167 | ** |
| 139168 | ** In this routine z[] is in reverse order. So we are really looking |
| 139169 | ** for an instance of of a consonant followed by a vowel. |
| 139170 | */ |
| 139171 | static int m_gt_0(const char *z){ |
| 139172 | while( isVowel(z) ){ z++; } |
| 139173 | if( *z==0 ) return 0; |
| 139174 | while( isConsonant(z) ){ z++; } |
| 139175 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -231,11 +231,11 @@ | |
| 231 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 232 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 233 | */ |
| 234 | #define SQLITE_VERSION "3.8.8" |
| 235 | #define SQLITE_VERSION_NUMBER 3008008 |
| 236 | #define SQLITE_SOURCE_ID "2014-12-06 14:56:49 6aeece19a235344be2537e66a3fe08b1febfb5a0" |
| 237 | |
| 238 | /* |
| 239 | ** CAPI3REF: Run-Time Library Version Numbers |
| 240 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 241 | ** |
| @@ -1343,11 +1343,11 @@ | |
| 1343 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED |
| 1344 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE |
| 1345 | ** </ul> |
| 1346 | ** |
| 1347 | ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as |
| 1348 | ** was given on the corresponding lock. |
| 1349 | ** |
| 1350 | ** The xShmLock method can transition between unlocked and SHARED or |
| 1351 | ** between unlocked and EXCLUSIVE. It cannot transition between SHARED |
| 1352 | ** and EXCLUSIVE. |
| 1353 | */ |
| @@ -1646,12 +1646,12 @@ | |
| 1646 | ** tracks memory usage, for example. </dd> |
| 1647 | ** |
| 1648 | ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> |
| 1649 | ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, |
| 1650 | ** interpreted as a boolean, which enables or disables the collection of |
| 1651 | ** memory allocation statistics. ^(When memory allocation statistics are |
| 1652 | ** disabled, the following SQLite interfaces become non-operational: |
| 1653 | ** <ul> |
| 1654 | ** <li> [sqlite3_memory_used()] |
| 1655 | ** <li> [sqlite3_memory_highwater()] |
| 1656 | ** <li> [sqlite3_soft_heap_limit64()] |
| 1657 | ** <li> [sqlite3_status()] |
| @@ -1688,11 +1688,12 @@ | |
| 1688 | ** that SQLite can use for the database page cache with the default page |
| 1689 | ** cache implementation. |
| 1690 | ** This configuration should not be used if an application-define page |
| 1691 | ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] |
| 1692 | ** configuration option. |
| 1693 | ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to |
| 1694 | ** 8-byte aligned |
| 1695 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1696 | ** The sz argument should be the size of the largest database page |
| 1697 | ** (a power of two between 512 and 32768) plus some extra bytes for each |
| 1698 | ** page header. ^The number of extra bytes needed by the page header |
| 1699 | ** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option |
| @@ -1708,11 +1709,12 @@ | |
| 1709 | ** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd> |
| 1710 | ** |
| 1711 | ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> |
| 1712 | ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer |
| 1713 | ** that SQLite will use for all of its dynamic memory allocation needs |
| 1714 | ** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and |
| 1715 | ** [SQLITE_CONFIG_PAGECACHE]. |
| 1716 | ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled |
| 1717 | ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns |
| 1718 | ** [SQLITE_ERROR] if invoked otherwise. |
| 1719 | ** ^There are three arguments to SQLITE_CONFIG_HEAP: |
| 1720 | ** An 8-byte aligned pointer to the memory, |
| @@ -1728,13 +1730,13 @@ | |
| 1730 | ** for the minimum allocation size are 2**5 through 2**8.</dd> |
| 1731 | ** |
| 1732 | ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1733 | ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a |
| 1734 | ** pointer to an instance of the [sqlite3_mutex_methods] structure. |
| 1735 | ** The argument specifies alternative low-level mutex routines to be used |
| 1736 | ** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of |
| 1737 | ** the content of the [sqlite3_mutex_methods] structure before the call to |
| 1738 | ** [sqlite3_config()] returns. ^If SQLite is compiled with |
| 1739 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then |
| 1740 | ** the entire mutexing subsystem is omitted from the build and hence calls to |
| 1741 | ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will |
| 1742 | ** return [SQLITE_ERROR].</dd> |
| @@ -1768,12 +1770,12 @@ | |
| 1770 | ** the interface to a custom page cache implementation.)^ |
| 1771 | ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> |
| 1772 | ** |
| 1773 | ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> |
| 1774 | ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which |
| 1775 | ** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of |
| 1776 | ** the current page cache implementation into that object.)^ </dd> |
| 1777 | ** |
| 1778 | ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> |
| 1779 | ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite |
| 1780 | ** global [error log]. |
| 1781 | ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a |
| @@ -1794,12 +1796,13 @@ | |
| 1796 | ** function must be threadsafe. </dd> |
| 1797 | ** |
| 1798 | ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI |
| 1799 | ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| 1800 | ** If non-zero, then URI handling is globally enabled. If the parameter is zero, |
| 1801 | ** then URI handling is globally disabled.)^ ^If URI handling is globally |
| 1802 | ** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], |
| 1803 | ** [sqlite3_open16()] or |
| 1804 | ** specified as part of [ATTACH] commands are interpreted as URIs, regardless |
| 1805 | ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database |
| 1806 | ** connection is opened. ^If it is globally disabled, filenames are |
| 1807 | ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the |
| 1808 | ** database connection is opened. ^(By default, URI handling is globally |
| @@ -1857,21 +1860,21 @@ | |
| 1860 | ** changed to its compile-time default. |
| 1861 | ** |
| 1862 | ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1863 | ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1864 | ** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is |
| 1865 | ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro |
| 1866 | ** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value |
| 1867 | ** that specifies the maximum size of the created heap. |
| 1868 | ** </dl> |
| 1869 | ** |
| 1870 | ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] |
| 1871 | ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ |
| 1872 | ** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which |
| 1873 | ** is a pointer to an integer and writes into that integer the number of extra |
| 1874 | ** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. |
| 1875 | ** The amount of extra space required can change depending on the compiler, |
| 1876 | ** target platform, and SQLite version. |
| 1877 | ** </dl> |
| 1878 | */ |
| 1879 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1880 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| @@ -2171,10 +2174,11 @@ | |
| 2174 | SQLITE_API int sqlite3_complete(const char *sql); |
| 2175 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2176 | |
| 2177 | /* |
| 2178 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2179 | ** KEYWORDS: {busy-handler callback} {busy handler} |
| 2180 | ** |
| 2181 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2182 | ** that might be invoked with argument P whenever |
| 2183 | ** an attempt is made to access a database table associated with |
| 2184 | ** [database connection] D when another thread |
| @@ -2187,11 +2191,11 @@ | |
| 2191 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2192 | ** |
| 2193 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2194 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2195 | ** the busy handler callback is the number of times that the busy handler has |
| 2196 | ** been invoked previously for the same locking event. ^If the |
| 2197 | ** busy callback returns 0, then no additional attempts are made to |
| 2198 | ** access the database and [SQLITE_BUSY] is returned |
| 2199 | ** to the application. |
| 2200 | ** ^If the callback returns non-zero, then another attempt |
| 2201 | ** is made to access the database and the cycle repeats. |
| @@ -4642,11 +4646,12 @@ | |
| 4646 | ** If these routines are called from within the different thread |
| 4647 | ** than the one containing the application-defined function that received |
| 4648 | ** the [sqlite3_context] pointer, the results are undefined. |
| 4649 | */ |
| 4650 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); |
| 4651 | SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, |
| 4652 | sqlite3_uint64,void(*)(void*)); |
| 4653 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); |
| 4654 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); |
| 4655 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); |
| 4656 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); |
| 4657 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); |
| @@ -7368,101 +7373,118 @@ | |
| 7373 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 7374 | |
| 7375 | /* |
| 7376 | ** CAPI3REF: Checkpoint a database |
| 7377 | ** |
| 7378 | ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to |
| 7379 | ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ |
| 7380 | ** |
| 7381 | ** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the |
| 7382 | ** [write-ahead log] for database X on [database connection] D to be |
| 7383 | ** transferred into the database file and for the write-ahead log to |
| 7384 | ** be reset. See the [checkpointing] documentation for addition |
| 7385 | ** information. |
| 7386 | ** |
| 7387 | ** This interface used to be the only way to cause a checkpoint to |
| 7388 | ** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] |
| 7389 | ** interface was added. This interface is retained for backwards |
| 7390 | ** compatibility and as a convenience for applications that need to manually |
| 7391 | ** start a callback but which do not need the full power (and corresponding |
| 7392 | ** complication) of [sqlite3_wal_checkpoint_v2()]. |
| 7393 | */ |
| 7394 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); |
| 7395 | |
| 7396 | /* |
| 7397 | ** CAPI3REF: Checkpoint a database |
| 7398 | ** |
| 7399 | ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint |
| 7400 | ** operation on database X of [database connection] D in mode M. Status |
| 7401 | ** information is written back into integers pointed to by L and C.)^ |
| 7402 | ** ^(The M parameter must be a valid [checkpoint mode]:)^ |
| 7403 | ** |
| 7404 | ** <dl> |
| 7405 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7406 | ** ^Checkpoint as many frames as possible without waiting for any database |
| 7407 | ** readers or writers to finish, then sync the database file if all frames |
| 7408 | ** in the log were checkpointed. ^The [busy-handler callback] |
| 7409 | ** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. |
| 7410 | ** ^On the other hand, passive mode might leave the checkpoint unfinished |
| 7411 | ** if there are concurrent readers or writers. |
| 7412 | ** |
| 7413 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7414 | ** ^This mode blocks (it invokes the |
| 7415 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7416 | ** database writer and all readers are reading from the most recent database |
| 7417 | ** snapshot. ^It then checkpoints all frames in the log file and syncs the |
| 7418 | ** database file. ^This mode blocks new database writers while it is pending, |
| 7419 | ** but new database readers are allowed to continue unimpeded. |
| 7420 | ** |
| 7421 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7422 | ** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition |
| 7423 | ** that after checkpointing the log file it blocks (calls the |
| 7424 | ** [busy-handler callback]) |
| 7425 | ** until all readers are reading from the database file only. ^This ensures |
| 7426 | ** that the next writer will restart the log file from the beginning. |
| 7427 | ** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new |
| 7428 | ** database writer attempts while it is pending, but does not impede readers. |
| 7429 | ** |
| 7430 | ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd> |
| 7431 | ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the |
| 7432 | ** addition that it also truncates the log file to zero bytes just prior |
| 7433 | ** to a successful return. |
| 7434 | ** </dl> |
| 7435 | ** |
| 7436 | ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in |
| 7437 | ** the log file or to -1 if the checkpoint could not run because |
| 7438 | ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not |
| 7439 | ** NULL,then *pnCkpt is set to the total number of checkpointed frames in the |
| 7440 | ** log file (including any that were already checkpointed before the function |
| 7441 | ** was called) or to -1 if the checkpoint could not run due to an error or |
| 7442 | ** because the database is not in WAL mode. ^Note that upon successful |
| 7443 | ** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been |
| 7444 | ** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. |
| 7445 | ** |
| 7446 | ** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If |
| 7447 | ** any other process is running a checkpoint operation at the same time, the |
| 7448 | ** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a |
| 7449 | ** busy-handler configured, it will not be invoked in this case. |
| 7450 | ** |
| 7451 | ** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the |
| 7452 | ** exclusive "writer" lock on the database file. ^If the writer lock cannot be |
| 7453 | ** obtained immediately, and a busy-handler is configured, it is invoked and |
| 7454 | ** the writer lock retried until either the busy-handler returns 0 or the lock |
| 7455 | ** is successfully obtained. ^The busy-handler is also invoked while waiting for |
| 7456 | ** database readers as described above. ^If the busy-handler returns 0 before |
| 7457 | ** the writer lock is obtained or while waiting for database readers, the |
| 7458 | ** checkpoint operation proceeds from that point in the same way as |
| 7459 | ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible |
| 7460 | ** without blocking any further. ^SQLITE_BUSY is returned in this case. |
| 7461 | ** |
| 7462 | ** ^If parameter zDb is NULL or points to a zero length string, then the |
| 7463 | ** specified operation is attempted on all WAL databases [attached] to |
| 7464 | ** [database connection] db. In this case the |
| 7465 | ** values written to output parameters *pnLog and *pnCkpt are undefined. ^If |
| 7466 | ** an SQLITE_BUSY error is encountered when processing one or more of the |
| 7467 | ** attached WAL databases, the operation is still attempted on any remaining |
| 7468 | ** attached databases and SQLITE_BUSY is returned at the end. ^If any other |
| 7469 | ** error occurs while processing an attached database, processing is abandoned |
| 7470 | ** and the error code is returned to the caller immediately. ^If no error |
| 7471 | ** (SQLITE_BUSY or otherwise) is encountered while processing the attached |
| 7472 | ** databases, SQLITE_OK is returned. |
| 7473 | ** |
| 7474 | ** ^If database zDb is the name of an attached database that is not in WAL |
| 7475 | ** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If |
| 7476 | ** zDb is not NULL (or a zero length string) and is not the name of any |
| 7477 | ** attached database, SQLITE_ERROR is returned to the caller. |
| 7478 | ** |
| 7479 | ** ^Unless it returns SQLITE_MISUSE, |
| 7480 | ** the sqlite3_wal_checkpoint_v2() interface |
| 7481 | ** sets the error information that is queried by |
| 7482 | ** [sqlite3_errcode()] and [sqlite3_errmsg()]. |
| 7483 | ** |
| 7484 | ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface |
| 7485 | ** from SQL. |
| 7486 | */ |
| 7487 | SQLITE_API int sqlite3_wal_checkpoint_v2( |
| 7488 | sqlite3 *db, /* Database handle */ |
| 7489 | const char *zDb, /* Name of attached database (or NULL) */ |
| 7490 | int eMode, /* SQLITE_CHECKPOINT_* value */ |
| @@ -7469,20 +7491,22 @@ | |
| 7491 | int *pnLog, /* OUT: Size of WAL log in frames */ |
| 7492 | int *pnCkpt /* OUT: Total number of frames checkpointed */ |
| 7493 | ); |
| 7494 | |
| 7495 | /* |
| 7496 | ** CAPI3REF: Checkpoint Mode Values |
| 7497 | ** KEYWORDS: {checkpoint mode} |
| 7498 | ** |
| 7499 | ** These constants define all valid values for the "checkpoint mode" passed |
| 7500 | ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. |
| 7501 | ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the |
| 7502 | ** meaning of each of these checkpoint modes. |
| 7503 | */ |
| 7504 | #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ |
| 7505 | #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ |
| 7506 | #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ |
| 7507 | #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ |
| 7508 | |
| 7509 | /* |
| 7510 | ** CAPI3REF: Virtual Table Interface Configuration |
| 7511 | ** |
| 7512 | ** This function may be called by either the [xConnect] or [xCreate] method |
| @@ -7577,16 +7601,16 @@ | |
| 7601 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7602 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7603 | ** |
| 7604 | ** <dl> |
| 7605 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7606 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7607 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7608 | ** |
| 7609 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> |
| 7610 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set |
| 7611 | ** to the total number of rows examined by all iterations of the X-th loop.</dd> |
| 7612 | ** |
| 7613 | ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> |
| 7614 | ** <dd>^The "double" variable pointed to by the T parameter will be set to the |
| 7615 | ** query planner's estimate for the average number of rows output from each |
| 7616 | ** iteration of the X-th loop. If the query planner's estimates was accurate, |
| @@ -7593,18 +7617,18 @@ | |
| 7617 | ** then this value will approximate the quotient NVISIT/NLOOP and the |
| 7618 | ** product of this value for all prior loops with the same SELECTID will |
| 7619 | ** be the NLOOP value for the current loop. |
| 7620 | ** |
| 7621 | ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> |
| 7622 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set |
| 7623 | ** to a zero-terminated UTF-8 string containing the name of the index or table |
| 7624 | ** used for the X-th loop. |
| 7625 | ** |
| 7626 | ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> |
| 7627 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set |
| 7628 | ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] |
| 7629 | ** description for the X-th loop. |
| 7630 | ** |
| 7631 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> |
| 7632 | ** <dd>^The "int" variable pointed to by the T parameter will be set to the |
| 7633 | ** "select-id" for the X-th loop. The select-id identifies which query or |
| 7634 | ** subquery the loop is part of. The main query has a select-id of zero. |
| @@ -7623,12 +7647,12 @@ | |
| 7647 | ** CAPI3REF: Prepared Statement Scan Status |
| 7648 | ** |
| 7649 | ** Return status data for a single loop within query pStmt. |
| 7650 | ** |
| 7651 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7652 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7653 | ** of this interface is undefined. |
| 7654 | ** ^The requested measurement is written into a variable pointed to by |
| 7655 | ** the "pOut" parameter. |
| 7656 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. |
| 7657 | ** Loops are numbered starting from zero. ^If idx is out of range - less than |
| 7658 | ** zero or greater than or equal to the total number of loops used to implement |
| @@ -11675,11 +11699,11 @@ | |
| 11699 | }; |
| 11700 | |
| 11701 | /* |
| 11702 | ** The following are the meanings of bits in the Expr.flags field. |
| 11703 | */ |
| 11704 | #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ |
| 11705 | #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ |
| 11706 | #define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ |
| 11707 | #define EP_Error 0x000008 /* Expression contains one or more errors */ |
| 11708 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 11709 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| @@ -11695,10 +11719,11 @@ | |
| 11719 | #define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ |
| 11720 | #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ |
| 11721 | #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ |
| 11722 | #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ |
| 11723 | #define EP_Constant 0x080000 /* Node is a constant */ |
| 11724 | #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ |
| 11725 | |
| 11726 | /* |
| 11727 | ** These macros can be used to test, set, or clear bits in the |
| 11728 | ** Expr.flags field. |
| 11729 | */ |
| @@ -48199,11 +48224,12 @@ | |
| 48224 | */ |
| 48225 | SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ |
| 48226 | int rc = SQLITE_OK; |
| 48227 | if( pPager->pWal ){ |
| 48228 | rc = sqlite3WalCheckpoint(pPager->pWal, eMode, |
| 48229 | (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), |
| 48230 | pPager->pBusyHandlerArg, |
| 48231 | pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, |
| 48232 | pnLog, pnCkpt |
| 48233 | ); |
| 48234 | } |
| 48235 | return rc; |
| @@ -50009,10 +50035,42 @@ | |
| 50035 | ** Return the page-size in bytes used by the database. |
| 50036 | */ |
| 50037 | static int walPagesize(Wal *pWal){ |
| 50038 | return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); |
| 50039 | } |
| 50040 | |
| 50041 | /* |
| 50042 | ** The following is guaranteed when this function is called: |
| 50043 | ** |
| 50044 | ** a) the WRITER lock is held, |
| 50045 | ** b) the entire log file has been checkpointed, and |
| 50046 | ** c) any existing readers are reading exclusively from the database |
| 50047 | ** file - there are no readers that may attempt to read a frame from |
| 50048 | ** the log file. |
| 50049 | ** |
| 50050 | ** This function updates the shared-memory structures so that the next |
| 50051 | ** client to write to the database (which may be this one) does so by |
| 50052 | ** writing frames into the start of the log file. |
| 50053 | ** |
| 50054 | ** The value of parameter salt1 is used as the aSalt[1] value in the |
| 50055 | ** new wal-index header. It should be passed a pseudo-random value (i.e. |
| 50056 | ** one obtained from sqlite3_randomness()). |
| 50057 | */ |
| 50058 | static void walRestartHdr(Wal *pWal, u32 salt1){ |
| 50059 | volatile WalCkptInfo *pInfo = walCkptInfo(pWal); |
| 50060 | int i; /* Loop counter */ |
| 50061 | u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ |
| 50062 | pWal->nCkpt++; |
| 50063 | pWal->hdr.mxFrame = 0; |
| 50064 | sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); |
| 50065 | memcpy(&pWal->hdr.aSalt[1], &salt1, 4); |
| 50066 | walIndexWriteHdr(pWal); |
| 50067 | pInfo->nBackfill = 0; |
| 50068 | pInfo->aReadMark[1] = 0; |
| 50069 | for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 50070 | assert( pInfo->aReadMark[0]==0 ); |
| 50071 | } |
| 50072 | |
| 50073 | /* |
| 50074 | ** Copy as much content as we can from the WAL back into the database file |
| 50075 | ** in response to an sqlite3_wal_checkpoint() request or the equivalent. |
| 50076 | ** |
| @@ -50044,11 +50102,11 @@ | |
| 50102 | ** time. |
| 50103 | */ |
| 50104 | static int walCheckpoint( |
| 50105 | Wal *pWal, /* Wal connection */ |
| 50106 | int eMode, /* One of PASSIVE, FULL or RESTART */ |
| 50107 | int (*xBusy)(void*), /* Function to call when busy */ |
| 50108 | void *pBusyArg, /* Context argument for xBusyHandler */ |
| 50109 | int sync_flags, /* Flags for OsSync() (or 0) */ |
| 50110 | u8 *zBuf /* Temporary buffer to use */ |
| 50111 | ){ |
| 50112 | int rc; /* Return code */ |
| @@ -50058,11 +50116,10 @@ | |
| 50116 | u32 iFrame = 0; /* Wal frame containing data for iDbpage */ |
| 50117 | u32 mxSafeFrame; /* Max frame that can be backfilled */ |
| 50118 | u32 mxPage; /* Max database page to write */ |
| 50119 | int i; /* Loop counter */ |
| 50120 | volatile WalCkptInfo *pInfo; /* The checkpoint status information */ |
| 50121 | |
| 50122 | szPage = walPagesize(pWal); |
| 50123 | testcase( szPage<=32768 ); |
| 50124 | testcase( szPage>=65536 ); |
| 50125 | pInfo = walCkptInfo(pWal); |
| @@ -50073,11 +50130,13 @@ | |
| 50130 | if( rc!=SQLITE_OK ){ |
| 50131 | return rc; |
| 50132 | } |
| 50133 | assert( pIter ); |
| 50134 | |
| 50135 | /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked |
| 50136 | ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ |
| 50137 | assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); |
| 50138 | |
| 50139 | /* Compute in mxSafeFrame the index of the last frame of the WAL that is |
| 50140 | ** safe to write into the database. Frames beyond mxSafeFrame might |
| 50141 | ** overwrite database pages that are in use by active readers and thus |
| 50142 | ** cannot be backfilled from the WAL. |
| @@ -50162,23 +50221,42 @@ | |
| 50221 | /* Reset the return code so as not to report a checkpoint failure |
| 50222 | ** just because there are active readers. */ |
| 50223 | rc = SQLITE_OK; |
| 50224 | } |
| 50225 | |
| 50226 | /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the |
| 50227 | ** entire wal file has been copied into the database file, then block |
| 50228 | ** until all readers have finished using the wal file. This ensures that |
| 50229 | ** the next process to write to the database restarts the wal file. |
| 50230 | */ |
| 50231 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 50232 | assert( pWal->writeLock ); |
| 50233 | if( pInfo->nBackfill<pWal->hdr.mxFrame ){ |
| 50234 | rc = SQLITE_BUSY; |
| 50235 | }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ |
| 50236 | u32 salt1; |
| 50237 | sqlite3_randomness(4, &salt1); |
| 50238 | assert( mxSafeFrame==pWal->hdr.mxFrame ); |
| 50239 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 50240 | if( rc==SQLITE_OK ){ |
| 50241 | if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ |
| 50242 | /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as |
| 50243 | ** SQLITE_CHECKPOINT_RESTART with the addition that it also |
| 50244 | ** truncates the log file to zero bytes just prior to a |
| 50245 | ** successful return. |
| 50246 | ** |
| 50247 | ** In theory, it might be safe to do this without updating the |
| 50248 | ** wal-index header in shared memory, as all subsequent reader or |
| 50249 | ** writer clients should see that the entire log file has been |
| 50250 | ** checkpointed and behave accordingly. This seems unsafe though, |
| 50251 | ** as it would leave the system in a state where the contents of |
| 50252 | ** the wal-index header do not match the contents of the |
| 50253 | ** file-system. To avoid this, update the wal-index header to |
| 50254 | ** indicate that the log file contains zero valid frames. */ |
| 50255 | walRestartHdr(pWal, salt1); |
| 50256 | rc = sqlite3OsTruncate(pWal->pWalFd, 0); |
| 50257 | } |
| 50258 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 50259 | } |
| 50260 | } |
| 50261 | } |
| 50262 | |
| @@ -50960,11 +51038,10 @@ | |
| 51038 | } |
| 51039 | |
| 51040 | return rc; |
| 51041 | } |
| 51042 | |
| 51043 | /* |
| 51044 | ** This function is called just before writing a set of frames to the log |
| 51045 | ** file (see sqlite3WalFrames()). It checks to see if, instead of appending |
| 51046 | ** to the current log file, it is possible to overwrite the start of the |
| 51047 | ** existing log file with the new frames (i.e. "reset" the log). If so, |
| @@ -50993,24 +51070,12 @@ | |
| 51070 | ** wal-index header to reflect this. |
| 51071 | ** |
| 51072 | ** In theory it would be Ok to update the cache of the header only |
| 51073 | ** at this point. But updating the actual wal-index header is also |
| 51074 | ** safe and means there is no special case for sqlite3WalUndo() |
| 51075 | ** to handle if this transaction is rolled back. */ |
| 51076 | walRestartHdr(pWal, salt1); |
| 51077 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 51078 | }else if( rc!=SQLITE_BUSY ){ |
| 51079 | return rc; |
| 51080 | } |
| 51081 | } |
| @@ -51294,11 +51359,11 @@ | |
| 51359 | ** If parameter xBusy is not NULL, it is a pointer to a busy-handler |
| 51360 | ** callback. In this case this function runs a blocking checkpoint. |
| 51361 | */ |
| 51362 | SQLITE_PRIVATE int sqlite3WalCheckpoint( |
| 51363 | Wal *pWal, /* Wal connection */ |
| 51364 | int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ |
| 51365 | int (*xBusy)(void*), /* Function to call when busy */ |
| 51366 | void *pBusyArg, /* Context argument for xBusyHandler */ |
| 51367 | int sync_flags, /* Flags to sync db file with (or 0) */ |
| 51368 | int nBuf, /* Size of temporary buffer */ |
| 51369 | u8 *zBuf, /* Temporary buffer to use */ |
| @@ -51306,40 +51371,54 @@ | |
| 51371 | int *pnCkpt /* OUT: Number of backfilled frames in WAL */ |
| 51372 | ){ |
| 51373 | int rc; /* Return code */ |
| 51374 | int isChanged = 0; /* True if a new wal-index header is loaded */ |
| 51375 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 51376 | int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */ |
| 51377 | |
| 51378 | assert( pWal->ckptLock==0 ); |
| 51379 | assert( pWal->writeLock==0 ); |
| 51380 | |
| 51381 | /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked |
| 51382 | ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ |
| 51383 | assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); |
| 51384 | |
| 51385 | if( pWal->readOnly ) return SQLITE_READONLY; |
| 51386 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 51387 | |
| 51388 | /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive |
| 51389 | ** "checkpoint" lock on the database file. */ |
| 51390 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 51391 | if( rc ){ |
| 51392 | /* EVIDENCE-OF: R-10421-19736 If any other process is running a |
| 51393 | ** checkpoint operation at the same time, the lock cannot be obtained and |
| 51394 | ** SQLITE_BUSY is returned. |
| 51395 | ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured, |
| 51396 | ** it will not be invoked in this case. |
| 51397 | */ |
| 51398 | testcase( rc==SQLITE_BUSY ); |
| 51399 | testcase( xBusy!=0 ); |
| 51400 | return rc; |
| 51401 | } |
| 51402 | pWal->ckptLock = 1; |
| 51403 | |
| 51404 | /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and |
| 51405 | ** TRUNCATE modes also obtain the exclusive "writer" lock on the database |
| 51406 | ** file. |
| 51407 | ** |
| 51408 | ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained |
| 51409 | ** immediately, and a busy-handler is configured, it is invoked and the |
| 51410 | ** writer lock retried until either the busy-handler returns 0 or the |
| 51411 | ** lock is successfully obtained. |
| 51412 | */ |
| 51413 | if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 51414 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1); |
| 51415 | if( rc==SQLITE_OK ){ |
| 51416 | pWal->writeLock = 1; |
| 51417 | }else if( rc==SQLITE_BUSY ){ |
| 51418 | eMode2 = SQLITE_CHECKPOINT_PASSIVE; |
| 51419 | xBusy2 = 0; |
| 51420 | rc = SQLITE_OK; |
| 51421 | } |
| 51422 | } |
| 51423 | |
| 51424 | /* Read the wal-index header. */ |
| @@ -51353,11 +51432,11 @@ | |
| 51432 | /* Copy data from the log to the database file. */ |
| 51433 | if( rc==SQLITE_OK ){ |
| 51434 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ |
| 51435 | rc = SQLITE_CORRUPT_BKPT; |
| 51436 | }else{ |
| 51437 | rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); |
| 51438 | } |
| 51439 | |
| 51440 | /* If no error occurred, set the output variables. */ |
| 51441 | if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ |
| 51442 | if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; |
| @@ -53821,11 +53900,11 @@ | |
| 53900 | ** to see if defragmentation is necessary. |
| 53901 | */ |
| 53902 | testcase( gap+2+nByte==top ); |
| 53903 | if( gap+2+nByte>top ){ |
| 53904 | defragment_page: |
| 53905 | assert( pPage->nCell>0 || CORRUPT_DB ); |
| 53906 | rc = defragmentPage(pPage); |
| 53907 | if( rc ) return rc; |
| 53908 | top = get2byteNotZero(&data[hdr+5]); |
| 53909 | assert( gap+nByte<=top ); |
| 53910 | } |
| @@ -58881,11 +58960,11 @@ | |
| 58960 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 58961 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| 58962 | assert( pPage->nOverflow==1 ); |
| 58963 | |
| 58964 | /* This error condition is now caught prior to reaching this function */ |
| 58965 | if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT; |
| 58966 | |
| 58967 | /* Allocate a new page. This page will become the right-sibling of |
| 58968 | ** pPage. Make the parent page writable, so that the new divider cell |
| 58969 | ** may be inserted. If both these operations are successful, proceed. |
| 58970 | */ |
| @@ -59324,11 +59403,15 @@ | |
| 59403 | ** pointer of the divider cell */ |
| 59404 | memcpy(apCell[nCell], &pOld->aData[8], 4); |
| 59405 | }else{ |
| 59406 | assert( leafCorrection==4 ); |
| 59407 | if( szCell[nCell]<4 ){ |
| 59408 | /* Do not allow any cells smaller than 4 bytes. If a smaller cell |
| 59409 | ** does exist, pad it with 0x00 bytes. */ |
| 59410 | assert( szCell[nCell]==3 ); |
| 59411 | assert( apCell[nCell]==&pTemp[iSpace1-3] ); |
| 59412 | pTemp[iSpace1++] = 0x00; |
| 59413 | szCell[nCell] = 4; |
| 59414 | } |
| 59415 | } |
| 59416 | nCell++; |
| 59417 | } |
| @@ -59559,11 +59642,15 @@ | |
| 59642 | ** was either part of sibling page iOld (possibly an overflow cell), |
| 59643 | ** or else the divider cell to the left of sibling page iOld. So, |
| 59644 | ** if sibling page iOld had the same page number as pNew, and if |
| 59645 | ** pCell really was a part of sibling page iOld (not a divider or |
| 59646 | ** overflow cell), we can skip updating the pointer map entries. */ |
| 59647 | if( iOld>=nNew |
| 59648 | || pNew->pgno!=aPgno[iOld] |
| 59649 | || pCell<aOld |
| 59650 | || pCell>=&aOld[usableSize] |
| 59651 | ){ |
| 59652 | if( !leafCorrection ){ |
| 59653 | ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); |
| 59654 | } |
| 59655 | if( szCell[i]>pNew->minLocal ){ |
| 59656 | ptrmapPutOvflPtr(pNew, pCell, &rc); |
| @@ -65699,11 +65786,11 @@ | |
| 65786 | for(n=0; n<nVar; n++){ |
| 65787 | p->aVar[n].flags = MEM_Null; |
| 65788 | p->aVar[n].db = db; |
| 65789 | } |
| 65790 | } |
| 65791 | if( p->azVar && pParse->nzVar>0 ){ |
| 65792 | p->nzVar = pParse->nzVar; |
| 65793 | memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); |
| 65794 | memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); |
| 65795 | } |
| 65796 | if( p->aMem ){ |
| @@ -75629,12 +75716,12 @@ | |
| 75716 | |
| 75717 | #ifndef SQLITE_OMIT_WAL |
| 75718 | /* Opcode: Checkpoint P1 P2 P3 * * |
| 75719 | ** |
| 75720 | ** Checkpoint database P1. This is a no-op if P1 is not currently in |
| 75721 | ** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL, |
| 75722 | ** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns |
| 75723 | ** SQLITE_BUSY or not, respectively. Write the number of pages in the |
| 75724 | ** WAL after the checkpoint into mem[P3+1] and the number of pages |
| 75725 | ** in the WAL that have been checkpointed after the checkpoint |
| 75726 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 75727 | ** mem[P3+2] are initialized to -1. |
| @@ -75648,10 +75735,11 @@ | |
| 75735 | aRes[0] = 0; |
| 75736 | aRes[1] = aRes[2] = -1; |
| 75737 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 75738 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 75739 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 75740 | || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE |
| 75741 | ); |
| 75742 | rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); |
| 75743 | if( rc==SQLITE_BUSY ){ |
| 75744 | rc = SQLITE_OK; |
| 75745 | aRes[0] = 1; |
| @@ -80411,10 +80499,14 @@ | |
| 80499 | } |
| 80500 | } |
| 80501 | if( pMatch ){ |
| 80502 | pExpr->iTable = pMatch->iCursor; |
| 80503 | pExpr->pTab = pMatch->pTab; |
| 80504 | assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */ |
| 80505 | if( (pMatch->jointype & JT_LEFT)!=0 ){ |
| 80506 | ExprSetProperty(pExpr, EP_CanBeNull); |
| 80507 | } |
| 80508 | pSchema = pExpr->pTab->pSchema; |
| 80509 | } |
| 80510 | } /* if( pSrcList ) */ |
| 80511 | |
| 80512 | #ifndef SQLITE_OMIT_TRIGGER |
| @@ -82968,11 +83060,12 @@ | |
| 83060 | case TK_FLOAT: |
| 83061 | case TK_BLOB: |
| 83062 | return 0; |
| 83063 | case TK_COLUMN: |
| 83064 | assert( p->pTab!=0 ); |
| 83065 | return ExprHasProperty(p, EP_CanBeNull) || |
| 83066 | (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); |
| 83067 | default: |
| 83068 | return 1; |
| 83069 | } |
| 83070 | } |
| 83071 | |
| @@ -88351,11 +88444,11 @@ | |
| 88444 | tRowcnt avgEq = 0; |
| 88445 | tRowcnt nRow; /* Number of rows in index */ |
| 88446 | i64 nSum100 = 0; /* Number of terms contributing to sumEq */ |
| 88447 | i64 nDist100; /* Number of distinct values in index */ |
| 88448 | |
| 88449 | if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ |
| 88450 | nRow = pFinal->anLt[iCol]; |
| 88451 | nDist100 = (i64)100 * pFinal->anDLt[iCol]; |
| 88452 | nSample--; |
| 88453 | }else{ |
| 88454 | nRow = pIdx->aiRowEst[0]; |
| @@ -103921,11 +104014,11 @@ | |
| 104014 | break; |
| 104015 | #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ |
| 104016 | |
| 104017 | #ifndef SQLITE_OMIT_WAL |
| 104018 | /* |
| 104019 | ** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate |
| 104020 | ** |
| 104021 | ** Checkpoint the database. |
| 104022 | */ |
| 104023 | case PragTyp_WAL_CHECKPOINT: { |
| 104024 | int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); |
| @@ -103933,10 +104026,12 @@ | |
| 104026 | if( zRight ){ |
| 104027 | if( sqlite3StrICmp(zRight, "full")==0 ){ |
| 104028 | eMode = SQLITE_CHECKPOINT_FULL; |
| 104029 | }else if( sqlite3StrICmp(zRight, "restart")==0 ){ |
| 104030 | eMode = SQLITE_CHECKPOINT_RESTART; |
| 104031 | }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ |
| 104032 | eMode = SQLITE_CHECKPOINT_TRUNCATE; |
| 104033 | } |
| 104034 | } |
| 104035 | sqlite3VdbeSetNumCols(v, 3); |
| 104036 | pParse->nMem = 3; |
| 104037 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); |
| @@ -109840,11 +109935,11 @@ | |
| 109935 | ** |
| 109936 | ** SELECT DISTINCT xyz FROM ... ORDER BY xyz |
| 109937 | ** |
| 109938 | ** is transformed to: |
| 109939 | ** |
| 109940 | ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz |
| 109941 | ** |
| 109942 | ** The second form is preferred as a single index (or temp-table) may be |
| 109943 | ** used for both the ORDER BY and DISTINCT processing. As originally |
| 109944 | ** written the query must use a temp-table for at least one of the ORDER |
| 109945 | ** BY and DISTINCT, and an index or separate temp-table for the other. |
| @@ -109853,11 +109948,10 @@ | |
| 109948 | && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0 |
| 109949 | ){ |
| 109950 | p->selFlags &= ~SF_Distinct; |
| 109951 | p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0); |
| 109952 | pGroupBy = p->pGroupBy; |
| 109953 | /* Notice that even thought SF_Distinct has been cleared from p->selFlags, |
| 109954 | ** the sDistinct.isTnct is still set. Hence, isTnct represents the |
| 109955 | ** original setting of the SF_Distinct flag, not the current setting */ |
| 109956 | assert( sDistinct.isTnct ); |
| 109957 | } |
| @@ -114808,10 +114902,11 @@ | |
| 114902 | memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); |
| 114903 | if( pOld!=pWC->aStatic ){ |
| 114904 | sqlite3DbFree(db, pOld); |
| 114905 | } |
| 114906 | pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); |
| 114907 | memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm)); |
| 114908 | } |
| 114909 | pTerm = &pWC->a[idx = pWC->nTerm++]; |
| 114910 | if( p && ExprHasProperty(p, EP_Unlikely) ){ |
| 114911 | pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; |
| 114912 | }else{ |
| @@ -117533,11 +117628,11 @@ | |
| 117628 | WhereLevel *pLvl, /* Level to add scanstatus() entry for */ |
| 117629 | int addrExplain /* Address of OP_Explain (or 0) */ |
| 117630 | ){ |
| 117631 | const char *zObj = 0; |
| 117632 | WhereLoop *pLoop = pLvl->pWLoop; |
| 117633 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ |
| 117634 | zObj = pLoop->u.btree.pIndex->zName; |
| 117635 | }else{ |
| 117636 | zObj = pSrclist->a[pLvl->iFrom].zName; |
| 117637 | } |
| 117638 | sqlite3VdbeScanStatus( |
| @@ -118177,14 +118272,13 @@ | |
| 118272 | int iTerm; |
| 118273 | for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ |
| 118274 | Expr *pExpr = pWC->a[iTerm].pExpr; |
| 118275 | if( &pWC->a[iTerm] == pTerm ) continue; |
| 118276 | if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; |
| 118277 | if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue; |
| 118278 | if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; |
| 118279 | testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); |
| 118280 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 118281 | pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); |
| 118282 | } |
| 118283 | if( pAndExpr ){ |
| 118284 | pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); |
| @@ -127079,10 +127173,18 @@ | |
| 127173 | |
| 127174 | /* Close all database connections */ |
| 127175 | for(j=0; j<db->nDb; j++){ |
| 127176 | struct Db *pDb = &db->aDb[j]; |
| 127177 | if( pDb->pBt ){ |
| 127178 | if( pDb->pSchema ){ |
| 127179 | /* Must clear the KeyInfo cache. See ticket [e4a18565a36884b00edf] */ |
| 127180 | for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){ |
| 127181 | Index *pIdx = sqliteHashData(i); |
| 127182 | sqlite3KeyInfoUnref(pIdx->pKeyInfo); |
| 127183 | pIdx->pKeyInfo = 0; |
| 127184 | } |
| 127185 | } |
| 127186 | sqlite3BtreeClose(pDb->pBt); |
| 127187 | pDb->pBt = 0; |
| 127188 | if( j!=1 ){ |
| 127189 | pDb->pSchema = 0; |
| 127190 | } |
| @@ -127983,14 +128085,17 @@ | |
| 128085 | |
| 128086 | /* Initialize the output variables to -1 in case an error occurs. */ |
| 128087 | if( pnLog ) *pnLog = -1; |
| 128088 | if( pnCkpt ) *pnCkpt = -1; |
| 128089 | |
| 128090 | assert( SQLITE_CHECKPOINT_PASSIVE==0 ); |
| 128091 | assert( SQLITE_CHECKPOINT_FULL==1 ); |
| 128092 | assert( SQLITE_CHECKPOINT_RESTART==2 ); |
| 128093 | assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); |
| 128094 | if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){ |
| 128095 | /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint |
| 128096 | ** mode: */ |
| 128097 | return SQLITE_MISUSE; |
| 128098 | } |
| 128099 | |
| 128100 | sqlite3_mutex_enter(db->mutex); |
| 128101 | if( zDb && zDb[0] ){ |
| @@ -128014,11 +128119,13 @@ | |
| 128119 | ** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points |
| 128120 | ** to contains a zero-length string, all attached databases are |
| 128121 | ** checkpointed. |
| 128122 | */ |
| 128123 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ |
| 128124 | /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to |
| 128125 | ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ |
| 128126 | return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); |
| 128127 | } |
| 128128 | |
| 128129 | #ifndef SQLITE_OMIT_WAL |
| 128130 | /* |
| 128131 | ** Run a checkpoint on database iDb. This is a no-op if database iDb is |
| @@ -139164,11 +139271,11 @@ | |
| 139271 | ** Return true if the m-value for z is 1 or more. In other words, |
| 139272 | ** return true if z contains at least one vowel that is followed |
| 139273 | ** by a consonant. |
| 139274 | ** |
| 139275 | ** In this routine z[] is in reverse order. So we are really looking |
| 139276 | ** for an instance of a consonant followed by a vowel. |
| 139277 | */ |
| 139278 | static int m_gt_0(const char *z){ |
| 139279 | while( isVowel(z) ){ z++; } |
| 139280 | if( *z==0 ) return 0; |
| 139281 | while( isConsonant(z) ){ z++; } |
| 139282 |
+121
-97
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.8.8" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008008 |
| 112 | -#define SQLITE_SOURCE_ID "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e" | |
| 112 | +#define SQLITE_SOURCE_ID "2014-12-06 14:56:49 6aeece19a235344be2537e66a3fe08b1febfb5a0" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -1219,11 +1219,11 @@ | ||
| 1219 | 1219 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED |
| 1220 | 1220 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE |
| 1221 | 1221 | ** </ul> |
| 1222 | 1222 | ** |
| 1223 | 1223 | ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as |
| 1224 | -** was given no the corresponding lock. | |
| 1224 | +** was given on the corresponding lock. | |
| 1225 | 1225 | ** |
| 1226 | 1226 | ** The xShmLock method can transition between unlocked and SHARED or |
| 1227 | 1227 | ** between unlocked and EXCLUSIVE. It cannot transition between SHARED |
| 1228 | 1228 | ** and EXCLUSIVE. |
| 1229 | 1229 | */ |
| @@ -1522,12 +1522,12 @@ | ||
| 1522 | 1522 | ** tracks memory usage, for example. </dd> |
| 1523 | 1523 | ** |
| 1524 | 1524 | ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> |
| 1525 | 1525 | ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, |
| 1526 | 1526 | ** interpreted as a boolean, which enables or disables the collection of |
| 1527 | -** memory allocation statistics. ^(When memory allocation statistics are disabled, the | |
| 1528 | -** following SQLite interfaces become non-operational: | |
| 1527 | +** memory allocation statistics. ^(When memory allocation statistics are | |
| 1528 | +** disabled, the following SQLite interfaces become non-operational: | |
| 1529 | 1529 | ** <ul> |
| 1530 | 1530 | ** <li> [sqlite3_memory_used()] |
| 1531 | 1531 | ** <li> [sqlite3_memory_highwater()] |
| 1532 | 1532 | ** <li> [sqlite3_soft_heap_limit64()] |
| 1533 | 1533 | ** <li> [sqlite3_status()] |
| @@ -1564,11 +1564,12 @@ | ||
| 1564 | 1564 | ** that SQLite can use for the database page cache with the default page |
| 1565 | 1565 | ** cache implementation. |
| 1566 | 1566 | ** This configuration should not be used if an application-define page |
| 1567 | 1567 | ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] |
| 1568 | 1568 | ** configuration option. |
| 1569 | -** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned | |
| 1569 | +** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to | |
| 1570 | +** 8-byte aligned | |
| 1570 | 1571 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1571 | 1572 | ** The sz argument should be the size of the largest database page |
| 1572 | 1573 | ** (a power of two between 512 and 32768) plus some extra bytes for each |
| 1573 | 1574 | ** page header. ^The number of extra bytes needed by the page header |
| 1574 | 1575 | ** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option |
| @@ -1584,11 +1585,12 @@ | ||
| 1584 | 1585 | ** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd> |
| 1585 | 1586 | ** |
| 1586 | 1587 | ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> |
| 1587 | 1588 | ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer |
| 1588 | 1589 | ** that SQLite will use for all of its dynamic memory allocation needs |
| 1589 | -** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. | |
| 1590 | +** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and | |
| 1591 | +** [SQLITE_CONFIG_PAGECACHE]. | |
| 1590 | 1592 | ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled |
| 1591 | 1593 | ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns |
| 1592 | 1594 | ** [SQLITE_ERROR] if invoked otherwise. |
| 1593 | 1595 | ** ^There are three arguments to SQLITE_CONFIG_HEAP: |
| 1594 | 1596 | ** An 8-byte aligned pointer to the memory, |
| @@ -1604,13 +1606,13 @@ | ||
| 1604 | 1606 | ** for the minimum allocation size are 2**5 through 2**8.</dd> |
| 1605 | 1607 | ** |
| 1606 | 1608 | ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1607 | 1609 | ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a |
| 1608 | 1610 | ** pointer to an instance of the [sqlite3_mutex_methods] structure. |
| 1609 | -** The argument specifies alternative low-level mutex routines to be used in place | |
| 1610 | -** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the | |
| 1611 | -** content of the [sqlite3_mutex_methods] structure before the call to | |
| 1611 | +** The argument specifies alternative low-level mutex routines to be used | |
| 1612 | +** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of | |
| 1613 | +** the content of the [sqlite3_mutex_methods] structure before the call to | |
| 1612 | 1614 | ** [sqlite3_config()] returns. ^If SQLite is compiled with |
| 1613 | 1615 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then |
| 1614 | 1616 | ** the entire mutexing subsystem is omitted from the build and hence calls to |
| 1615 | 1617 | ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will |
| 1616 | 1618 | ** return [SQLITE_ERROR].</dd> |
| @@ -1644,12 +1646,12 @@ | ||
| 1644 | 1646 | ** the interface to a custom page cache implementation.)^ |
| 1645 | 1647 | ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> |
| 1646 | 1648 | ** |
| 1647 | 1649 | ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> |
| 1648 | 1650 | ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which |
| 1649 | -** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of the current | |
| 1650 | -** page cache implementation into that object.)^ </dd> | |
| 1651 | +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of | |
| 1652 | +** the current page cache implementation into that object.)^ </dd> | |
| 1651 | 1653 | ** |
| 1652 | 1654 | ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> |
| 1653 | 1655 | ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite |
| 1654 | 1656 | ** global [error log]. |
| 1655 | 1657 | ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a |
| @@ -1670,12 +1672,13 @@ | ||
| 1670 | 1672 | ** function must be threadsafe. </dd> |
| 1671 | 1673 | ** |
| 1672 | 1674 | ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI |
| 1673 | 1675 | ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| 1674 | 1676 | ** If non-zero, then URI handling is globally enabled. If the parameter is zero, |
| 1675 | -** then URI handling is globally disabled.)^ ^If URI handling is globally enabled, | |
| 1676 | -** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or | |
| 1677 | +** then URI handling is globally disabled.)^ ^If URI handling is globally | |
| 1678 | +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], | |
| 1679 | +** [sqlite3_open16()] or | |
| 1677 | 1680 | ** specified as part of [ATTACH] commands are interpreted as URIs, regardless |
| 1678 | 1681 | ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database |
| 1679 | 1682 | ** connection is opened. ^If it is globally disabled, filenames are |
| 1680 | 1683 | ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the |
| 1681 | 1684 | ** database connection is opened. ^(By default, URI handling is globally |
| @@ -1733,21 +1736,21 @@ | ||
| 1733 | 1736 | ** changed to its compile-time default. |
| 1734 | 1737 | ** |
| 1735 | 1738 | ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1736 | 1739 | ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1737 | 1740 | ** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is |
| 1738 | -** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. | |
| 1739 | -** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value | |
| 1741 | +** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro | |
| 1742 | +** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value | |
| 1740 | 1743 | ** that specifies the maximum size of the created heap. |
| 1741 | 1744 | ** </dl> |
| 1742 | 1745 | ** |
| 1743 | 1746 | ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] |
| 1744 | 1747 | ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ |
| 1745 | 1748 | ** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which |
| 1746 | 1749 | ** is a pointer to an integer and writes into that integer the number of extra |
| 1747 | -** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of | |
| 1748 | -** extra space required can change depending on the compiler, | |
| 1750 | +** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. | |
| 1751 | +** The amount of extra space required can change depending on the compiler, | |
| 1749 | 1752 | ** target platform, and SQLite version. |
| 1750 | 1753 | ** </dl> |
| 1751 | 1754 | */ |
| 1752 | 1755 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1753 | 1756 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| @@ -2047,10 +2050,11 @@ | ||
| 2047 | 2050 | SQLITE_API int sqlite3_complete(const char *sql); |
| 2048 | 2051 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2049 | 2052 | |
| 2050 | 2053 | /* |
| 2051 | 2054 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2055 | +** KEYWORDS: {busy-handler callback} {busy handler} | |
| 2052 | 2056 | ** |
| 2053 | 2057 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2054 | 2058 | ** that might be invoked with argument P whenever |
| 2055 | 2059 | ** an attempt is made to access a database table associated with |
| 2056 | 2060 | ** [database connection] D when another thread |
| @@ -2063,11 +2067,11 @@ | ||
| 2063 | 2067 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2064 | 2068 | ** |
| 2065 | 2069 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2066 | 2070 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2067 | 2071 | ** the busy handler callback is the number of times that the busy handler has |
| 2068 | -** been invoked for the same locking event. ^If the | |
| 2072 | +** been invoked previously for the same locking event. ^If the | |
| 2069 | 2073 | ** busy callback returns 0, then no additional attempts are made to |
| 2070 | 2074 | ** access the database and [SQLITE_BUSY] is returned |
| 2071 | 2075 | ** to the application. |
| 2072 | 2076 | ** ^If the callback returns non-zero, then another attempt |
| 2073 | 2077 | ** is made to access the database and the cycle repeats. |
| @@ -4518,11 +4522,12 @@ | ||
| 4518 | 4522 | ** If these routines are called from within the different thread |
| 4519 | 4523 | ** than the one containing the application-defined function that received |
| 4520 | 4524 | ** the [sqlite3_context] pointer, the results are undefined. |
| 4521 | 4525 | */ |
| 4522 | 4526 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); |
| 4523 | -SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void(*)(void*)); | |
| 4527 | +SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, | |
| 4528 | + sqlite3_uint64,void(*)(void*)); | |
| 4524 | 4529 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); |
| 4525 | 4530 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); |
| 4526 | 4531 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); |
| 4527 | 4532 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); |
| 4528 | 4533 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); |
| @@ -7244,101 +7249,118 @@ | ||
| 7244 | 7249 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 7245 | 7250 | |
| 7246 | 7251 | /* |
| 7247 | 7252 | ** CAPI3REF: Checkpoint a database |
| 7248 | 7253 | ** |
| 7249 | -** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X | |
| 7250 | -** on [database connection] D to be [checkpointed]. ^If X is NULL or an | |
| 7251 | -** empty string, then a checkpoint is run on all databases of | |
| 7252 | -** connection D. ^If the database connection D is not in | |
| 7253 | -** [WAL | write-ahead log mode] then this interface is a harmless no-op. | |
| 7254 | -** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a | |
| 7255 | -** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. | |
| 7256 | -** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL | |
| 7257 | -** or RESET checkpoint. | |
| 7258 | -** | |
| 7259 | -** ^The [wal_checkpoint pragma] can be used to invoke this interface | |
| 7260 | -** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the | |
| 7261 | -** [wal_autocheckpoint pragma] can be used to cause this interface to be | |
| 7262 | -** run whenever the WAL reaches a certain size threshold. | |
| 7263 | -** | |
| 7264 | -** See also: [sqlite3_wal_checkpoint_v2()] | |
| 7254 | +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to | |
| 7255 | +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ | |
| 7256 | +** | |
| 7257 | +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the | |
| 7258 | +** [write-ahead log] for database X on [database connection] D to be | |
| 7259 | +** transferred into the database file and for the write-ahead log to | |
| 7260 | +** be reset. See the [checkpointing] documentation for addition | |
| 7261 | +** information. | |
| 7262 | +** | |
| 7263 | +** This interface used to be the only way to cause a checkpoint to | |
| 7264 | +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] | |
| 7265 | +** interface was added. This interface is retained for backwards | |
| 7266 | +** compatibility and as a convenience for applications that need to manually | |
| 7267 | +** start a callback but which do not need the full power (and corresponding | |
| 7268 | +** complication) of [sqlite3_wal_checkpoint_v2()]. | |
| 7265 | 7269 | */ |
| 7266 | 7270 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); |
| 7267 | 7271 | |
| 7268 | 7272 | /* |
| 7269 | 7273 | ** CAPI3REF: Checkpoint a database |
| 7270 | 7274 | ** |
| 7271 | -** Run a checkpoint operation on WAL database zDb attached to database | |
| 7272 | -** handle db. The specific operation is determined by the value of the | |
| 7273 | -** eMode parameter: | |
| 7275 | +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint | |
| 7276 | +** operation on database X of [database connection] D in mode M. Status | |
| 7277 | +** information is written back into integers pointed to by L and C.)^ | |
| 7278 | +** ^(The M parameter must be a valid [checkpoint mode]:)^ | |
| 7274 | 7279 | ** |
| 7275 | 7280 | ** <dl> |
| 7276 | 7281 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7277 | -** Checkpoint as many frames as possible without waiting for any database | |
| 7278 | -** readers or writers to finish. Sync the db file if all frames in the log | |
| 7279 | -** are checkpointed. This mode is the same as calling | |
| 7280 | -** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] | |
| 7281 | -** is never invoked. | |
| 7282 | +** ^Checkpoint as many frames as possible without waiting for any database | |
| 7283 | +** readers or writers to finish, then sync the database file if all frames | |
| 7284 | +** in the log were checkpointed. ^The [busy-handler callback] | |
| 7285 | +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. | |
| 7286 | +** ^On the other hand, passive mode might leave the checkpoint unfinished | |
| 7287 | +** if there are concurrent readers or writers. | |
| 7282 | 7288 | ** |
| 7283 | 7289 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7284 | -** This mode blocks (it invokes the | |
| 7290 | +** ^This mode blocks (it invokes the | |
| 7285 | 7291 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7286 | 7292 | ** database writer and all readers are reading from the most recent database |
| 7287 | -** snapshot. It then checkpoints all frames in the log file and syncs the | |
| 7288 | -** database file. This call blocks database writers while it is running, | |
| 7289 | -** but not database readers. | |
| 7293 | +** snapshot. ^It then checkpoints all frames in the log file and syncs the | |
| 7294 | +** database file. ^This mode blocks new database writers while it is pending, | |
| 7295 | +** but new database readers are allowed to continue unimpeded. | |
| 7290 | 7296 | ** |
| 7291 | 7297 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7292 | -** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after | |
| 7293 | -** checkpointing the log file it blocks (calls the | |
| 7294 | -** [sqlite3_busy_handler|busy-handler callback]) | |
| 7295 | -** until all readers are reading from the database file only. This ensures | |
| 7296 | -** that the next client to write to the database file restarts the log file | |
| 7297 | -** from the beginning. This call blocks database writers while it is running, | |
| 7298 | -** but not database readers. | |
| 7298 | +** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition | |
| 7299 | +** that after checkpointing the log file it blocks (calls the | |
| 7300 | +** [busy-handler callback]) | |
| 7301 | +** until all readers are reading from the database file only. ^This ensures | |
| 7302 | +** that the next writer will restart the log file from the beginning. | |
| 7303 | +** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new | |
| 7304 | +** database writer attempts while it is pending, but does not impede readers. | |
| 7305 | +** | |
| 7306 | +** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd> | |
| 7307 | +** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the | |
| 7308 | +** addition that it also truncates the log file to zero bytes just prior | |
| 7309 | +** to a successful return. | |
| 7299 | 7310 | ** </dl> |
| 7300 | 7311 | ** |
| 7301 | -** If pnLog is not NULL, then *pnLog is set to the total number of frames in | |
| 7302 | -** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to | |
| 7303 | -** the total number of checkpointed frames (including any that were already | |
| 7304 | -** checkpointed when this function is called). *pnLog and *pnCkpt may be | |
| 7305 | -** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. | |
| 7306 | -** If no values are available because of an error, they are both set to -1 | |
| 7307 | -** before returning to communicate this to the caller. | |
| 7312 | +** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in | |
| 7313 | +** the log file or to -1 if the checkpoint could not run because | |
| 7314 | +** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not | |
| 7315 | +** NULL,then *pnCkpt is set to the total number of checkpointed frames in the | |
| 7316 | +** log file (including any that were already checkpointed before the function | |
| 7317 | +** was called) or to -1 if the checkpoint could not run due to an error or | |
| 7318 | +** because the database is not in WAL mode. ^Note that upon successful | |
| 7319 | +** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been | |
| 7320 | +** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. | |
| 7308 | 7321 | ** |
| 7309 | -** All calls obtain an exclusive "checkpoint" lock on the database file. If | |
| 7322 | +** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If | |
| 7310 | 7323 | ** any other process is running a checkpoint operation at the same time, the |
| 7311 | -** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a | |
| 7324 | +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a | |
| 7312 | 7325 | ** busy-handler configured, it will not be invoked in this case. |
| 7313 | 7326 | ** |
| 7314 | -** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive | |
| 7315 | -** "writer" lock on the database file. If the writer lock cannot be obtained | |
| 7316 | -** immediately, and a busy-handler is configured, it is invoked and the writer | |
| 7317 | -** lock retried until either the busy-handler returns 0 or the lock is | |
| 7318 | -** successfully obtained. The busy-handler is also invoked while waiting for | |
| 7319 | -** database readers as described above. If the busy-handler returns 0 before | |
| 7327 | +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the | |
| 7328 | +** exclusive "writer" lock on the database file. ^If the writer lock cannot be | |
| 7329 | +** obtained immediately, and a busy-handler is configured, it is invoked and | |
| 7330 | +** the writer lock retried until either the busy-handler returns 0 or the lock | |
| 7331 | +** is successfully obtained. ^The busy-handler is also invoked while waiting for | |
| 7332 | +** database readers as described above. ^If the busy-handler returns 0 before | |
| 7320 | 7333 | ** the writer lock is obtained or while waiting for database readers, the |
| 7321 | 7334 | ** checkpoint operation proceeds from that point in the same way as |
| 7322 | 7335 | ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible |
| 7323 | -** without blocking any further. SQLITE_BUSY is returned in this case. | |
| 7336 | +** without blocking any further. ^SQLITE_BUSY is returned in this case. | |
| 7324 | 7337 | ** |
| 7325 | -** If parameter zDb is NULL or points to a zero length string, then the | |
| 7326 | -** specified operation is attempted on all WAL databases. In this case the | |
| 7327 | -** values written to output parameters *pnLog and *pnCkpt are undefined. If | |
| 7338 | +** ^If parameter zDb is NULL or points to a zero length string, then the | |
| 7339 | +** specified operation is attempted on all WAL databases [attached] to | |
| 7340 | +** [database connection] db. In this case the | |
| 7341 | +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If | |
| 7328 | 7342 | ** an SQLITE_BUSY error is encountered when processing one or more of the |
| 7329 | 7343 | ** attached WAL databases, the operation is still attempted on any remaining |
| 7330 | -** attached databases and SQLITE_BUSY is returned to the caller. If any other | |
| 7344 | +** attached databases and SQLITE_BUSY is returned at the end. ^If any other | |
| 7331 | 7345 | ** error occurs while processing an attached database, processing is abandoned |
| 7332 | -** and the error code returned to the caller immediately. If no error | |
| 7346 | +** and the error code is returned to the caller immediately. ^If no error | |
| 7333 | 7347 | ** (SQLITE_BUSY or otherwise) is encountered while processing the attached |
| 7334 | 7348 | ** databases, SQLITE_OK is returned. |
| 7335 | 7349 | ** |
| 7336 | -** If database zDb is the name of an attached database that is not in WAL | |
| 7337 | -** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If | |
| 7350 | +** ^If database zDb is the name of an attached database that is not in WAL | |
| 7351 | +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If | |
| 7338 | 7352 | ** zDb is not NULL (or a zero length string) and is not the name of any |
| 7339 | 7353 | ** attached database, SQLITE_ERROR is returned to the caller. |
| 7354 | +** | |
| 7355 | +** ^Unless it returns SQLITE_MISUSE, | |
| 7356 | +** the sqlite3_wal_checkpoint_v2() interface | |
| 7357 | +** sets the error information that is queried by | |
| 7358 | +** [sqlite3_errcode()] and [sqlite3_errmsg()]. | |
| 7359 | +** | |
| 7360 | +** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface | |
| 7361 | +** from SQL. | |
| 7340 | 7362 | */ |
| 7341 | 7363 | SQLITE_API int sqlite3_wal_checkpoint_v2( |
| 7342 | 7364 | sqlite3 *db, /* Database handle */ |
| 7343 | 7365 | const char *zDb, /* Name of attached database (or NULL) */ |
| 7344 | 7366 | int eMode, /* SQLITE_CHECKPOINT_* value */ |
| @@ -7345,20 +7367,22 @@ | ||
| 7345 | 7367 | int *pnLog, /* OUT: Size of WAL log in frames */ |
| 7346 | 7368 | int *pnCkpt /* OUT: Total number of frames checkpointed */ |
| 7347 | 7369 | ); |
| 7348 | 7370 | |
| 7349 | 7371 | /* |
| 7350 | -** CAPI3REF: Checkpoint operation parameters | |
| 7372 | +** CAPI3REF: Checkpoint Mode Values | |
| 7373 | +** KEYWORDS: {checkpoint mode} | |
| 7351 | 7374 | ** |
| 7352 | -** These constants can be used as the 3rd parameter to | |
| 7353 | -** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] | |
| 7354 | -** documentation for additional information about the meaning and use of | |
| 7355 | -** each of these values. | |
| 7375 | +** These constants define all valid values for the "checkpoint mode" passed | |
| 7376 | +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. | |
| 7377 | +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the | |
| 7378 | +** meaning of each of these checkpoint modes. | |
| 7356 | 7379 | */ |
| 7357 | -#define SQLITE_CHECKPOINT_PASSIVE 0 | |
| 7358 | -#define SQLITE_CHECKPOINT_FULL 1 | |
| 7359 | -#define SQLITE_CHECKPOINT_RESTART 2 | |
| 7380 | +#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ | |
| 7381 | +#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ | |
| 7382 | +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ | |
| 7383 | +#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ | |
| 7360 | 7384 | |
| 7361 | 7385 | /* |
| 7362 | 7386 | ** CAPI3REF: Virtual Table Interface Configuration |
| 7363 | 7387 | ** |
| 7364 | 7388 | ** This function may be called by either the [xConnect] or [xCreate] method |
| @@ -7453,16 +7477,16 @@ | ||
| 7453 | 7477 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7454 | 7478 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7455 | 7479 | ** |
| 7456 | 7480 | ** <dl> |
| 7457 | 7481 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7458 | -** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the | |
| 7459 | -** total number of times that the X-th loop has run.</dd> | |
| 7482 | +** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be | |
| 7483 | +** set to the total number of times that the X-th loop has run.</dd> | |
| 7460 | 7484 | ** |
| 7461 | 7485 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> |
| 7462 | -** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the | |
| 7463 | -** total number of rows examined by all iterations of the X-th loop.</dd> | |
| 7486 | +** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set | |
| 7487 | +** to the total number of rows examined by all iterations of the X-th loop.</dd> | |
| 7464 | 7488 | ** |
| 7465 | 7489 | ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> |
| 7466 | 7490 | ** <dd>^The "double" variable pointed to by the T parameter will be set to the |
| 7467 | 7491 | ** query planner's estimate for the average number of rows output from each |
| 7468 | 7492 | ** iteration of the X-th loop. If the query planner's estimates was accurate, |
| @@ -7469,18 +7493,18 @@ | ||
| 7469 | 7493 | ** then this value will approximate the quotient NVISIT/NLOOP and the |
| 7470 | 7494 | ** product of this value for all prior loops with the same SELECTID will |
| 7471 | 7495 | ** be the NLOOP value for the current loop. |
| 7472 | 7496 | ** |
| 7473 | 7497 | ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> |
| 7474 | -** <dd>^The "const char *" variable pointed to by the T parameter will be set to | |
| 7475 | -** a zero-terminated UTF-8 string containing the name of the index or table used | |
| 7476 | -** for the X-th loop. | |
| 7498 | +** <dd>^The "const char *" variable pointed to by the T parameter will be set | |
| 7499 | +** to a zero-terminated UTF-8 string containing the name of the index or table | |
| 7500 | +** used for the X-th loop. | |
| 7477 | 7501 | ** |
| 7478 | 7502 | ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> |
| 7479 | -** <dd>^The "const char *" variable pointed to by the T parameter will be set to | |
| 7480 | -** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description | |
| 7481 | -** for the X-th loop. | |
| 7503 | +** <dd>^The "const char *" variable pointed to by the T parameter will be set | |
| 7504 | +** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] | |
| 7505 | +** description for the X-th loop. | |
| 7482 | 7506 | ** |
| 7483 | 7507 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> |
| 7484 | 7508 | ** <dd>^The "int" variable pointed to by the T parameter will be set to the |
| 7485 | 7509 | ** "select-id" for the X-th loop. The select-id identifies which query or |
| 7486 | 7510 | ** subquery the loop is part of. The main query has a select-id of zero. |
| @@ -7499,12 +7523,12 @@ | ||
| 7499 | 7523 | ** CAPI3REF: Prepared Statement Scan Status |
| 7500 | 7524 | ** |
| 7501 | 7525 | ** Return status data for a single loop within query pStmt. |
| 7502 | 7526 | ** |
| 7503 | 7527 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7504 | -** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of | |
| 7505 | -** this interface is undefined. | |
| 7528 | +** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior | |
| 7529 | +** of this interface is undefined. | |
| 7506 | 7530 | ** ^The requested measurement is written into a variable pointed to by |
| 7507 | 7531 | ** the "pOut" parameter. |
| 7508 | 7532 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. |
| 7509 | 7533 | ** Loops are numbered starting from zero. ^If idx is out of range - less than |
| 7510 | 7534 | ** zero or greater than or equal to the total number of loops used to implement |
| 7511 | 7535 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.8" |
| 111 | #define SQLITE_VERSION_NUMBER 3008008 |
| 112 | #define SQLITE_SOURCE_ID "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -1219,11 +1219,11 @@ | |
| 1219 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED |
| 1220 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE |
| 1221 | ** </ul> |
| 1222 | ** |
| 1223 | ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as |
| 1224 | ** was given no the corresponding lock. |
| 1225 | ** |
| 1226 | ** The xShmLock method can transition between unlocked and SHARED or |
| 1227 | ** between unlocked and EXCLUSIVE. It cannot transition between SHARED |
| 1228 | ** and EXCLUSIVE. |
| 1229 | */ |
| @@ -1522,12 +1522,12 @@ | |
| 1522 | ** tracks memory usage, for example. </dd> |
| 1523 | ** |
| 1524 | ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> |
| 1525 | ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, |
| 1526 | ** interpreted as a boolean, which enables or disables the collection of |
| 1527 | ** memory allocation statistics. ^(When memory allocation statistics are disabled, the |
| 1528 | ** following SQLite interfaces become non-operational: |
| 1529 | ** <ul> |
| 1530 | ** <li> [sqlite3_memory_used()] |
| 1531 | ** <li> [sqlite3_memory_highwater()] |
| 1532 | ** <li> [sqlite3_soft_heap_limit64()] |
| 1533 | ** <li> [sqlite3_status()] |
| @@ -1564,11 +1564,12 @@ | |
| 1564 | ** that SQLite can use for the database page cache with the default page |
| 1565 | ** cache implementation. |
| 1566 | ** This configuration should not be used if an application-define page |
| 1567 | ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] |
| 1568 | ** configuration option. |
| 1569 | ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned |
| 1570 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1571 | ** The sz argument should be the size of the largest database page |
| 1572 | ** (a power of two between 512 and 32768) plus some extra bytes for each |
| 1573 | ** page header. ^The number of extra bytes needed by the page header |
| 1574 | ** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option |
| @@ -1584,11 +1585,12 @@ | |
| 1584 | ** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd> |
| 1585 | ** |
| 1586 | ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> |
| 1587 | ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer |
| 1588 | ** that SQLite will use for all of its dynamic memory allocation needs |
| 1589 | ** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE]. |
| 1590 | ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled |
| 1591 | ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns |
| 1592 | ** [SQLITE_ERROR] if invoked otherwise. |
| 1593 | ** ^There are three arguments to SQLITE_CONFIG_HEAP: |
| 1594 | ** An 8-byte aligned pointer to the memory, |
| @@ -1604,13 +1606,13 @@ | |
| 1604 | ** for the minimum allocation size are 2**5 through 2**8.</dd> |
| 1605 | ** |
| 1606 | ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1607 | ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a |
| 1608 | ** pointer to an instance of the [sqlite3_mutex_methods] structure. |
| 1609 | ** The argument specifies alternative low-level mutex routines to be used in place |
| 1610 | ** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the |
| 1611 | ** content of the [sqlite3_mutex_methods] structure before the call to |
| 1612 | ** [sqlite3_config()] returns. ^If SQLite is compiled with |
| 1613 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then |
| 1614 | ** the entire mutexing subsystem is omitted from the build and hence calls to |
| 1615 | ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will |
| 1616 | ** return [SQLITE_ERROR].</dd> |
| @@ -1644,12 +1646,12 @@ | |
| 1644 | ** the interface to a custom page cache implementation.)^ |
| 1645 | ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> |
| 1646 | ** |
| 1647 | ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> |
| 1648 | ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which |
| 1649 | ** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of the current |
| 1650 | ** page cache implementation into that object.)^ </dd> |
| 1651 | ** |
| 1652 | ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> |
| 1653 | ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite |
| 1654 | ** global [error log]. |
| 1655 | ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a |
| @@ -1670,12 +1672,13 @@ | |
| 1670 | ** function must be threadsafe. </dd> |
| 1671 | ** |
| 1672 | ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI |
| 1673 | ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| 1674 | ** If non-zero, then URI handling is globally enabled. If the parameter is zero, |
| 1675 | ** then URI handling is globally disabled.)^ ^If URI handling is globally enabled, |
| 1676 | ** all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or |
| 1677 | ** specified as part of [ATTACH] commands are interpreted as URIs, regardless |
| 1678 | ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database |
| 1679 | ** connection is opened. ^If it is globally disabled, filenames are |
| 1680 | ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the |
| 1681 | ** database connection is opened. ^(By default, URI handling is globally |
| @@ -1733,21 +1736,21 @@ | |
| 1733 | ** changed to its compile-time default. |
| 1734 | ** |
| 1735 | ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1736 | ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1737 | ** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is |
| 1738 | ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. |
| 1739 | ** ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value |
| 1740 | ** that specifies the maximum size of the created heap. |
| 1741 | ** </dl> |
| 1742 | ** |
| 1743 | ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] |
| 1744 | ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ |
| 1745 | ** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which |
| 1746 | ** is a pointer to an integer and writes into that integer the number of extra |
| 1747 | ** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. The amount of |
| 1748 | ** extra space required can change depending on the compiler, |
| 1749 | ** target platform, and SQLite version. |
| 1750 | ** </dl> |
| 1751 | */ |
| 1752 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1753 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| @@ -2047,10 +2050,11 @@ | |
| 2047 | SQLITE_API int sqlite3_complete(const char *sql); |
| 2048 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2049 | |
| 2050 | /* |
| 2051 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2052 | ** |
| 2053 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2054 | ** that might be invoked with argument P whenever |
| 2055 | ** an attempt is made to access a database table associated with |
| 2056 | ** [database connection] D when another thread |
| @@ -2063,11 +2067,11 @@ | |
| 2063 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2064 | ** |
| 2065 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2066 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2067 | ** the busy handler callback is the number of times that the busy handler has |
| 2068 | ** been invoked for the same locking event. ^If the |
| 2069 | ** busy callback returns 0, then no additional attempts are made to |
| 2070 | ** access the database and [SQLITE_BUSY] is returned |
| 2071 | ** to the application. |
| 2072 | ** ^If the callback returns non-zero, then another attempt |
| 2073 | ** is made to access the database and the cycle repeats. |
| @@ -4518,11 +4522,12 @@ | |
| 4518 | ** If these routines are called from within the different thread |
| 4519 | ** than the one containing the application-defined function that received |
| 4520 | ** the [sqlite3_context] pointer, the results are undefined. |
| 4521 | */ |
| 4522 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); |
| 4523 | SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void(*)(void*)); |
| 4524 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); |
| 4525 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); |
| 4526 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); |
| 4527 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); |
| 4528 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); |
| @@ -7244,101 +7249,118 @@ | |
| 7244 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 7245 | |
| 7246 | /* |
| 7247 | ** CAPI3REF: Checkpoint a database |
| 7248 | ** |
| 7249 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X |
| 7250 | ** on [database connection] D to be [checkpointed]. ^If X is NULL or an |
| 7251 | ** empty string, then a checkpoint is run on all databases of |
| 7252 | ** connection D. ^If the database connection D is not in |
| 7253 | ** [WAL | write-ahead log mode] then this interface is a harmless no-op. |
| 7254 | ** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a |
| 7255 | ** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint. |
| 7256 | ** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL |
| 7257 | ** or RESET checkpoint. |
| 7258 | ** |
| 7259 | ** ^The [wal_checkpoint pragma] can be used to invoke this interface |
| 7260 | ** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the |
| 7261 | ** [wal_autocheckpoint pragma] can be used to cause this interface to be |
| 7262 | ** run whenever the WAL reaches a certain size threshold. |
| 7263 | ** |
| 7264 | ** See also: [sqlite3_wal_checkpoint_v2()] |
| 7265 | */ |
| 7266 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); |
| 7267 | |
| 7268 | /* |
| 7269 | ** CAPI3REF: Checkpoint a database |
| 7270 | ** |
| 7271 | ** Run a checkpoint operation on WAL database zDb attached to database |
| 7272 | ** handle db. The specific operation is determined by the value of the |
| 7273 | ** eMode parameter: |
| 7274 | ** |
| 7275 | ** <dl> |
| 7276 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7277 | ** Checkpoint as many frames as possible without waiting for any database |
| 7278 | ** readers or writers to finish. Sync the db file if all frames in the log |
| 7279 | ** are checkpointed. This mode is the same as calling |
| 7280 | ** sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback] |
| 7281 | ** is never invoked. |
| 7282 | ** |
| 7283 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7284 | ** This mode blocks (it invokes the |
| 7285 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7286 | ** database writer and all readers are reading from the most recent database |
| 7287 | ** snapshot. It then checkpoints all frames in the log file and syncs the |
| 7288 | ** database file. This call blocks database writers while it is running, |
| 7289 | ** but not database readers. |
| 7290 | ** |
| 7291 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7292 | ** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after |
| 7293 | ** checkpointing the log file it blocks (calls the |
| 7294 | ** [sqlite3_busy_handler|busy-handler callback]) |
| 7295 | ** until all readers are reading from the database file only. This ensures |
| 7296 | ** that the next client to write to the database file restarts the log file |
| 7297 | ** from the beginning. This call blocks database writers while it is running, |
| 7298 | ** but not database readers. |
| 7299 | ** </dl> |
| 7300 | ** |
| 7301 | ** If pnLog is not NULL, then *pnLog is set to the total number of frames in |
| 7302 | ** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to |
| 7303 | ** the total number of checkpointed frames (including any that were already |
| 7304 | ** checkpointed when this function is called). *pnLog and *pnCkpt may be |
| 7305 | ** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK. |
| 7306 | ** If no values are available because of an error, they are both set to -1 |
| 7307 | ** before returning to communicate this to the caller. |
| 7308 | ** |
| 7309 | ** All calls obtain an exclusive "checkpoint" lock on the database file. If |
| 7310 | ** any other process is running a checkpoint operation at the same time, the |
| 7311 | ** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a |
| 7312 | ** busy-handler configured, it will not be invoked in this case. |
| 7313 | ** |
| 7314 | ** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive |
| 7315 | ** "writer" lock on the database file. If the writer lock cannot be obtained |
| 7316 | ** immediately, and a busy-handler is configured, it is invoked and the writer |
| 7317 | ** lock retried until either the busy-handler returns 0 or the lock is |
| 7318 | ** successfully obtained. The busy-handler is also invoked while waiting for |
| 7319 | ** database readers as described above. If the busy-handler returns 0 before |
| 7320 | ** the writer lock is obtained or while waiting for database readers, the |
| 7321 | ** checkpoint operation proceeds from that point in the same way as |
| 7322 | ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible |
| 7323 | ** without blocking any further. SQLITE_BUSY is returned in this case. |
| 7324 | ** |
| 7325 | ** If parameter zDb is NULL or points to a zero length string, then the |
| 7326 | ** specified operation is attempted on all WAL databases. In this case the |
| 7327 | ** values written to output parameters *pnLog and *pnCkpt are undefined. If |
| 7328 | ** an SQLITE_BUSY error is encountered when processing one or more of the |
| 7329 | ** attached WAL databases, the operation is still attempted on any remaining |
| 7330 | ** attached databases and SQLITE_BUSY is returned to the caller. If any other |
| 7331 | ** error occurs while processing an attached database, processing is abandoned |
| 7332 | ** and the error code returned to the caller immediately. If no error |
| 7333 | ** (SQLITE_BUSY or otherwise) is encountered while processing the attached |
| 7334 | ** databases, SQLITE_OK is returned. |
| 7335 | ** |
| 7336 | ** If database zDb is the name of an attached database that is not in WAL |
| 7337 | ** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If |
| 7338 | ** zDb is not NULL (or a zero length string) and is not the name of any |
| 7339 | ** attached database, SQLITE_ERROR is returned to the caller. |
| 7340 | */ |
| 7341 | SQLITE_API int sqlite3_wal_checkpoint_v2( |
| 7342 | sqlite3 *db, /* Database handle */ |
| 7343 | const char *zDb, /* Name of attached database (or NULL) */ |
| 7344 | int eMode, /* SQLITE_CHECKPOINT_* value */ |
| @@ -7345,20 +7367,22 @@ | |
| 7345 | int *pnLog, /* OUT: Size of WAL log in frames */ |
| 7346 | int *pnCkpt /* OUT: Total number of frames checkpointed */ |
| 7347 | ); |
| 7348 | |
| 7349 | /* |
| 7350 | ** CAPI3REF: Checkpoint operation parameters |
| 7351 | ** |
| 7352 | ** These constants can be used as the 3rd parameter to |
| 7353 | ** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()] |
| 7354 | ** documentation for additional information about the meaning and use of |
| 7355 | ** each of these values. |
| 7356 | */ |
| 7357 | #define SQLITE_CHECKPOINT_PASSIVE 0 |
| 7358 | #define SQLITE_CHECKPOINT_FULL 1 |
| 7359 | #define SQLITE_CHECKPOINT_RESTART 2 |
| 7360 | |
| 7361 | /* |
| 7362 | ** CAPI3REF: Virtual Table Interface Configuration |
| 7363 | ** |
| 7364 | ** This function may be called by either the [xConnect] or [xCreate] method |
| @@ -7453,16 +7477,16 @@ | |
| 7453 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7454 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7455 | ** |
| 7456 | ** <dl> |
| 7457 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7458 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the |
| 7459 | ** total number of times that the X-th loop has run.</dd> |
| 7460 | ** |
| 7461 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> |
| 7462 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set to the |
| 7463 | ** total number of rows examined by all iterations of the X-th loop.</dd> |
| 7464 | ** |
| 7465 | ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> |
| 7466 | ** <dd>^The "double" variable pointed to by the T parameter will be set to the |
| 7467 | ** query planner's estimate for the average number of rows output from each |
| 7468 | ** iteration of the X-th loop. If the query planner's estimates was accurate, |
| @@ -7469,18 +7493,18 @@ | |
| 7469 | ** then this value will approximate the quotient NVISIT/NLOOP and the |
| 7470 | ** product of this value for all prior loops with the same SELECTID will |
| 7471 | ** be the NLOOP value for the current loop. |
| 7472 | ** |
| 7473 | ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> |
| 7474 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set to |
| 7475 | ** a zero-terminated UTF-8 string containing the name of the index or table used |
| 7476 | ** for the X-th loop. |
| 7477 | ** |
| 7478 | ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> |
| 7479 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set to |
| 7480 | ** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description |
| 7481 | ** for the X-th loop. |
| 7482 | ** |
| 7483 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> |
| 7484 | ** <dd>^The "int" variable pointed to by the T parameter will be set to the |
| 7485 | ** "select-id" for the X-th loop. The select-id identifies which query or |
| 7486 | ** subquery the loop is part of. The main query has a select-id of zero. |
| @@ -7499,12 +7523,12 @@ | |
| 7499 | ** CAPI3REF: Prepared Statement Scan Status |
| 7500 | ** |
| 7501 | ** Return status data for a single loop within query pStmt. |
| 7502 | ** |
| 7503 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7504 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of |
| 7505 | ** this interface is undefined. |
| 7506 | ** ^The requested measurement is written into a variable pointed to by |
| 7507 | ** the "pOut" parameter. |
| 7508 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. |
| 7509 | ** Loops are numbered starting from zero. ^If idx is out of range - less than |
| 7510 | ** zero or greater than or equal to the total number of loops used to implement |
| 7511 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.8" |
| 111 | #define SQLITE_VERSION_NUMBER 3008008 |
| 112 | #define SQLITE_SOURCE_ID "2014-12-06 14:56:49 6aeece19a235344be2537e66a3fe08b1febfb5a0" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -1219,11 +1219,11 @@ | |
| 1219 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED |
| 1220 | ** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE |
| 1221 | ** </ul> |
| 1222 | ** |
| 1223 | ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as |
| 1224 | ** was given on the corresponding lock. |
| 1225 | ** |
| 1226 | ** The xShmLock method can transition between unlocked and SHARED or |
| 1227 | ** between unlocked and EXCLUSIVE. It cannot transition between SHARED |
| 1228 | ** and EXCLUSIVE. |
| 1229 | */ |
| @@ -1522,12 +1522,12 @@ | |
| 1522 | ** tracks memory usage, for example. </dd> |
| 1523 | ** |
| 1524 | ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt> |
| 1525 | ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, |
| 1526 | ** interpreted as a boolean, which enables or disables the collection of |
| 1527 | ** memory allocation statistics. ^(When memory allocation statistics are |
| 1528 | ** disabled, the following SQLite interfaces become non-operational: |
| 1529 | ** <ul> |
| 1530 | ** <li> [sqlite3_memory_used()] |
| 1531 | ** <li> [sqlite3_memory_highwater()] |
| 1532 | ** <li> [sqlite3_soft_heap_limit64()] |
| 1533 | ** <li> [sqlite3_status()] |
| @@ -1564,11 +1564,12 @@ | |
| 1564 | ** that SQLite can use for the database page cache with the default page |
| 1565 | ** cache implementation. |
| 1566 | ** This configuration should not be used if an application-define page |
| 1567 | ** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2] |
| 1568 | ** configuration option. |
| 1569 | ** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to |
| 1570 | ** 8-byte aligned |
| 1571 | ** memory, the size of each page buffer (sz), and the number of pages (N). |
| 1572 | ** The sz argument should be the size of the largest database page |
| 1573 | ** (a power of two between 512 and 32768) plus some extra bytes for each |
| 1574 | ** page header. ^The number of extra bytes needed by the page header |
| 1575 | ** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option |
| @@ -1584,11 +1585,12 @@ | |
| 1585 | ** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd> |
| 1586 | ** |
| 1587 | ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt> |
| 1588 | ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer |
| 1589 | ** that SQLite will use for all of its dynamic memory allocation needs |
| 1590 | ** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and |
| 1591 | ** [SQLITE_CONFIG_PAGECACHE]. |
| 1592 | ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled |
| 1593 | ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns |
| 1594 | ** [SQLITE_ERROR] if invoked otherwise. |
| 1595 | ** ^There are three arguments to SQLITE_CONFIG_HEAP: |
| 1596 | ** An 8-byte aligned pointer to the memory, |
| @@ -1604,13 +1606,13 @@ | |
| 1606 | ** for the minimum allocation size are 2**5 through 2**8.</dd> |
| 1607 | ** |
| 1608 | ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt> |
| 1609 | ** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a |
| 1610 | ** pointer to an instance of the [sqlite3_mutex_methods] structure. |
| 1611 | ** The argument specifies alternative low-level mutex routines to be used |
| 1612 | ** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of |
| 1613 | ** the content of the [sqlite3_mutex_methods] structure before the call to |
| 1614 | ** [sqlite3_config()] returns. ^If SQLite is compiled with |
| 1615 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then |
| 1616 | ** the entire mutexing subsystem is omitted from the build and hence calls to |
| 1617 | ** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will |
| 1618 | ** return [SQLITE_ERROR].</dd> |
| @@ -1644,12 +1646,12 @@ | |
| 1646 | ** the interface to a custom page cache implementation.)^ |
| 1647 | ** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd> |
| 1648 | ** |
| 1649 | ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt> |
| 1650 | ** <dd> ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which |
| 1651 | ** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of |
| 1652 | ** the current page cache implementation into that object.)^ </dd> |
| 1653 | ** |
| 1654 | ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt> |
| 1655 | ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite |
| 1656 | ** global [error log]. |
| 1657 | ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a |
| @@ -1670,12 +1672,13 @@ | |
| 1672 | ** function must be threadsafe. </dd> |
| 1673 | ** |
| 1674 | ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI |
| 1675 | ** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int. |
| 1676 | ** If non-zero, then URI handling is globally enabled. If the parameter is zero, |
| 1677 | ** then URI handling is globally disabled.)^ ^If URI handling is globally |
| 1678 | ** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], |
| 1679 | ** [sqlite3_open16()] or |
| 1680 | ** specified as part of [ATTACH] commands are interpreted as URIs, regardless |
| 1681 | ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database |
| 1682 | ** connection is opened. ^If it is globally disabled, filenames are |
| 1683 | ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the |
| 1684 | ** database connection is opened. ^(By default, URI handling is globally |
| @@ -1733,21 +1736,21 @@ | |
| 1736 | ** changed to its compile-time default. |
| 1737 | ** |
| 1738 | ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1739 | ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1740 | ** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is |
| 1741 | ** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro |
| 1742 | ** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value |
| 1743 | ** that specifies the maximum size of the created heap. |
| 1744 | ** </dl> |
| 1745 | ** |
| 1746 | ** [[SQLITE_CONFIG_PCACHE_HDRSZ]] |
| 1747 | ** <dt>SQLITE_CONFIG_PCACHE_HDRSZ |
| 1748 | ** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which |
| 1749 | ** is a pointer to an integer and writes into that integer the number of extra |
| 1750 | ** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. |
| 1751 | ** The amount of extra space required can change depending on the compiler, |
| 1752 | ** target platform, and SQLite version. |
| 1753 | ** </dl> |
| 1754 | */ |
| 1755 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1756 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| @@ -2047,10 +2050,11 @@ | |
| 2050 | SQLITE_API int sqlite3_complete(const char *sql); |
| 2051 | SQLITE_API int sqlite3_complete16(const void *sql); |
| 2052 | |
| 2053 | /* |
| 2054 | ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors |
| 2055 | ** KEYWORDS: {busy-handler callback} {busy handler} |
| 2056 | ** |
| 2057 | ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X |
| 2058 | ** that might be invoked with argument P whenever |
| 2059 | ** an attempt is made to access a database table associated with |
| 2060 | ** [database connection] D when another thread |
| @@ -2063,11 +2067,11 @@ | |
| 2067 | ** is not NULL, then the callback might be invoked with two arguments. |
| 2068 | ** |
| 2069 | ** ^The first argument to the busy handler is a copy of the void* pointer which |
| 2070 | ** is the third argument to sqlite3_busy_handler(). ^The second argument to |
| 2071 | ** the busy handler callback is the number of times that the busy handler has |
| 2072 | ** been invoked previously for the same locking event. ^If the |
| 2073 | ** busy callback returns 0, then no additional attempts are made to |
| 2074 | ** access the database and [SQLITE_BUSY] is returned |
| 2075 | ** to the application. |
| 2076 | ** ^If the callback returns non-zero, then another attempt |
| 2077 | ** is made to access the database and the cycle repeats. |
| @@ -4518,11 +4522,12 @@ | |
| 4522 | ** If these routines are called from within the different thread |
| 4523 | ** than the one containing the application-defined function that received |
| 4524 | ** the [sqlite3_context] pointer, the results are undefined. |
| 4525 | */ |
| 4526 | SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); |
| 4527 | SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, |
| 4528 | sqlite3_uint64,void(*)(void*)); |
| 4529 | SQLITE_API void sqlite3_result_double(sqlite3_context*, double); |
| 4530 | SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); |
| 4531 | SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); |
| 4532 | SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); |
| 4533 | SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); |
| @@ -7244,101 +7249,118 @@ | |
| 7249 | SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); |
| 7250 | |
| 7251 | /* |
| 7252 | ** CAPI3REF: Checkpoint a database |
| 7253 | ** |
| 7254 | ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to |
| 7255 | ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ |
| 7256 | ** |
| 7257 | ** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the |
| 7258 | ** [write-ahead log] for database X on [database connection] D to be |
| 7259 | ** transferred into the database file and for the write-ahead log to |
| 7260 | ** be reset. See the [checkpointing] documentation for addition |
| 7261 | ** information. |
| 7262 | ** |
| 7263 | ** This interface used to be the only way to cause a checkpoint to |
| 7264 | ** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] |
| 7265 | ** interface was added. This interface is retained for backwards |
| 7266 | ** compatibility and as a convenience for applications that need to manually |
| 7267 | ** start a callback but which do not need the full power (and corresponding |
| 7268 | ** complication) of [sqlite3_wal_checkpoint_v2()]. |
| 7269 | */ |
| 7270 | SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); |
| 7271 | |
| 7272 | /* |
| 7273 | ** CAPI3REF: Checkpoint a database |
| 7274 | ** |
| 7275 | ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint |
| 7276 | ** operation on database X of [database connection] D in mode M. Status |
| 7277 | ** information is written back into integers pointed to by L and C.)^ |
| 7278 | ** ^(The M parameter must be a valid [checkpoint mode]:)^ |
| 7279 | ** |
| 7280 | ** <dl> |
| 7281 | ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd> |
| 7282 | ** ^Checkpoint as many frames as possible without waiting for any database |
| 7283 | ** readers or writers to finish, then sync the database file if all frames |
| 7284 | ** in the log were checkpointed. ^The [busy-handler callback] |
| 7285 | ** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. |
| 7286 | ** ^On the other hand, passive mode might leave the checkpoint unfinished |
| 7287 | ** if there are concurrent readers or writers. |
| 7288 | ** |
| 7289 | ** <dt>SQLITE_CHECKPOINT_FULL<dd> |
| 7290 | ** ^This mode blocks (it invokes the |
| 7291 | ** [sqlite3_busy_handler|busy-handler callback]) until there is no |
| 7292 | ** database writer and all readers are reading from the most recent database |
| 7293 | ** snapshot. ^It then checkpoints all frames in the log file and syncs the |
| 7294 | ** database file. ^This mode blocks new database writers while it is pending, |
| 7295 | ** but new database readers are allowed to continue unimpeded. |
| 7296 | ** |
| 7297 | ** <dt>SQLITE_CHECKPOINT_RESTART<dd> |
| 7298 | ** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition |
| 7299 | ** that after checkpointing the log file it blocks (calls the |
| 7300 | ** [busy-handler callback]) |
| 7301 | ** until all readers are reading from the database file only. ^This ensures |
| 7302 | ** that the next writer will restart the log file from the beginning. |
| 7303 | ** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new |
| 7304 | ** database writer attempts while it is pending, but does not impede readers. |
| 7305 | ** |
| 7306 | ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd> |
| 7307 | ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the |
| 7308 | ** addition that it also truncates the log file to zero bytes just prior |
| 7309 | ** to a successful return. |
| 7310 | ** </dl> |
| 7311 | ** |
| 7312 | ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in |
| 7313 | ** the log file or to -1 if the checkpoint could not run because |
| 7314 | ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not |
| 7315 | ** NULL,then *pnCkpt is set to the total number of checkpointed frames in the |
| 7316 | ** log file (including any that were already checkpointed before the function |
| 7317 | ** was called) or to -1 if the checkpoint could not run due to an error or |
| 7318 | ** because the database is not in WAL mode. ^Note that upon successful |
| 7319 | ** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been |
| 7320 | ** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. |
| 7321 | ** |
| 7322 | ** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If |
| 7323 | ** any other process is running a checkpoint operation at the same time, the |
| 7324 | ** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a |
| 7325 | ** busy-handler configured, it will not be invoked in this case. |
| 7326 | ** |
| 7327 | ** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the |
| 7328 | ** exclusive "writer" lock on the database file. ^If the writer lock cannot be |
| 7329 | ** obtained immediately, and a busy-handler is configured, it is invoked and |
| 7330 | ** the writer lock retried until either the busy-handler returns 0 or the lock |
| 7331 | ** is successfully obtained. ^The busy-handler is also invoked while waiting for |
| 7332 | ** database readers as described above. ^If the busy-handler returns 0 before |
| 7333 | ** the writer lock is obtained or while waiting for database readers, the |
| 7334 | ** checkpoint operation proceeds from that point in the same way as |
| 7335 | ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible |
| 7336 | ** without blocking any further. ^SQLITE_BUSY is returned in this case. |
| 7337 | ** |
| 7338 | ** ^If parameter zDb is NULL or points to a zero length string, then the |
| 7339 | ** specified operation is attempted on all WAL databases [attached] to |
| 7340 | ** [database connection] db. In this case the |
| 7341 | ** values written to output parameters *pnLog and *pnCkpt are undefined. ^If |
| 7342 | ** an SQLITE_BUSY error is encountered when processing one or more of the |
| 7343 | ** attached WAL databases, the operation is still attempted on any remaining |
| 7344 | ** attached databases and SQLITE_BUSY is returned at the end. ^If any other |
| 7345 | ** error occurs while processing an attached database, processing is abandoned |
| 7346 | ** and the error code is returned to the caller immediately. ^If no error |
| 7347 | ** (SQLITE_BUSY or otherwise) is encountered while processing the attached |
| 7348 | ** databases, SQLITE_OK is returned. |
| 7349 | ** |
| 7350 | ** ^If database zDb is the name of an attached database that is not in WAL |
| 7351 | ** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If |
| 7352 | ** zDb is not NULL (or a zero length string) and is not the name of any |
| 7353 | ** attached database, SQLITE_ERROR is returned to the caller. |
| 7354 | ** |
| 7355 | ** ^Unless it returns SQLITE_MISUSE, |
| 7356 | ** the sqlite3_wal_checkpoint_v2() interface |
| 7357 | ** sets the error information that is queried by |
| 7358 | ** [sqlite3_errcode()] and [sqlite3_errmsg()]. |
| 7359 | ** |
| 7360 | ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface |
| 7361 | ** from SQL. |
| 7362 | */ |
| 7363 | SQLITE_API int sqlite3_wal_checkpoint_v2( |
| 7364 | sqlite3 *db, /* Database handle */ |
| 7365 | const char *zDb, /* Name of attached database (or NULL) */ |
| 7366 | int eMode, /* SQLITE_CHECKPOINT_* value */ |
| @@ -7345,20 +7367,22 @@ | |
| 7367 | int *pnLog, /* OUT: Size of WAL log in frames */ |
| 7368 | int *pnCkpt /* OUT: Total number of frames checkpointed */ |
| 7369 | ); |
| 7370 | |
| 7371 | /* |
| 7372 | ** CAPI3REF: Checkpoint Mode Values |
| 7373 | ** KEYWORDS: {checkpoint mode} |
| 7374 | ** |
| 7375 | ** These constants define all valid values for the "checkpoint mode" passed |
| 7376 | ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. |
| 7377 | ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the |
| 7378 | ** meaning of each of these checkpoint modes. |
| 7379 | */ |
| 7380 | #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ |
| 7381 | #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ |
| 7382 | #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ |
| 7383 | #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ |
| 7384 | |
| 7385 | /* |
| 7386 | ** CAPI3REF: Virtual Table Interface Configuration |
| 7387 | ** |
| 7388 | ** This function may be called by either the [xConnect] or [xCreate] method |
| @@ -7453,16 +7477,16 @@ | |
| 7477 | ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a |
| 7478 | ** different metric for sqlite3_stmt_scanstatus() to return. |
| 7479 | ** |
| 7480 | ** <dl> |
| 7481 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 7482 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be |
| 7483 | ** set to the total number of times that the X-th loop has run.</dd> |
| 7484 | ** |
| 7485 | ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt> |
| 7486 | ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set |
| 7487 | ** to the total number of rows examined by all iterations of the X-th loop.</dd> |
| 7488 | ** |
| 7489 | ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt> |
| 7490 | ** <dd>^The "double" variable pointed to by the T parameter will be set to the |
| 7491 | ** query planner's estimate for the average number of rows output from each |
| 7492 | ** iteration of the X-th loop. If the query planner's estimates was accurate, |
| @@ -7469,18 +7493,18 @@ | |
| 7493 | ** then this value will approximate the quotient NVISIT/NLOOP and the |
| 7494 | ** product of this value for all prior loops with the same SELECTID will |
| 7495 | ** be the NLOOP value for the current loop. |
| 7496 | ** |
| 7497 | ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt> |
| 7498 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set |
| 7499 | ** to a zero-terminated UTF-8 string containing the name of the index or table |
| 7500 | ** used for the X-th loop. |
| 7501 | ** |
| 7502 | ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt> |
| 7503 | ** <dd>^The "const char *" variable pointed to by the T parameter will be set |
| 7504 | ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] |
| 7505 | ** description for the X-th loop. |
| 7506 | ** |
| 7507 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> |
| 7508 | ** <dd>^The "int" variable pointed to by the T parameter will be set to the |
| 7509 | ** "select-id" for the X-th loop. The select-id identifies which query or |
| 7510 | ** subquery the loop is part of. The main query has a select-id of zero. |
| @@ -7499,12 +7523,12 @@ | |
| 7523 | ** CAPI3REF: Prepared Statement Scan Status |
| 7524 | ** |
| 7525 | ** Return status data for a single loop within query pStmt. |
| 7526 | ** |
| 7527 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 7528 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 7529 | ** of this interface is undefined. |
| 7530 | ** ^The requested measurement is written into a variable pointed to by |
| 7531 | ** the "pOut" parameter. |
| 7532 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. |
| 7533 | ** Loops are numbered starting from zero. ^If idx is out of range - less than |
| 7534 | ** zero or greater than or equal to the total number of loops used to implement |
| 7535 |
+2
-2
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -226,19 +226,19 @@ | ||
| 226 | 226 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 227 | 227 | fossil_print("%*s%d across all branches\n", colWidth, "files:", n); |
| 228 | 228 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 229 | 229 | " WHERE tagname GLOB 'wiki-*'"); |
| 230 | 230 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'"); |
| 231 | - fossil_print("%*s%d (%d changes)\n", colWidth, "wikipages:", n, m); | |
| 231 | + fossil_print("%*s%d (%d changes)\n", colWidth, "wiki-pages:", n, m); | |
| 232 | 232 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 233 | 233 | " WHERE tagname GLOB 'tkt-*'"); |
| 234 | 234 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'"); |
| 235 | 235 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 236 | 236 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 237 | 237 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 238 | 238 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 239 | - fossil_print("%*s%d\n", colWidth, "tagchanges:", n); | |
| 239 | + fossil_print("%*s%d\n", colWidth, "tag-changes:", n); | |
| 240 | 240 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 241 | 241 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 242 | 242 | " || ' days ago' FROM event " |
| 243 | 243 | " ORDER BY mtime DESC LIMIT 1"); |
| 244 | 244 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 245 | 245 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -226,19 +226,19 @@ | |
| 226 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 227 | fossil_print("%*s%d across all branches\n", colWidth, "files:", n); |
| 228 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 229 | " WHERE tagname GLOB 'wiki-*'"); |
| 230 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'"); |
| 231 | fossil_print("%*s%d (%d changes)\n", colWidth, "wikipages:", n, m); |
| 232 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 233 | " WHERE tagname GLOB 'tkt-*'"); |
| 234 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'"); |
| 235 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 236 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 237 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 238 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 239 | fossil_print("%*s%d\n", colWidth, "tagchanges:", n); |
| 240 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 241 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 242 | " || ' days ago' FROM event " |
| 243 | " ORDER BY mtime DESC LIMIT 1"); |
| 244 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 245 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -226,19 +226,19 @@ | |
| 226 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 227 | fossil_print("%*s%d across all branches\n", colWidth, "files:", n); |
| 228 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 229 | " WHERE tagname GLOB 'wiki-*'"); |
| 230 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'"); |
| 231 | fossil_print("%*s%d (%d changes)\n", colWidth, "wiki-pages:", n, m); |
| 232 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 233 | " WHERE tagname GLOB 'tkt-*'"); |
| 234 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'"); |
| 235 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 236 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 237 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 238 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 239 | fossil_print("%*s%d\n", colWidth, "tag-changes:", n); |
| 240 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 241 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 242 | " || ' days ago' FROM event " |
| 243 | " ORDER BY mtime DESC LIMIT 1"); |
| 244 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 245 |
+1
-1
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -561,11 +561,11 @@ | ||
| 561 | 561 | ); |
| 562 | 562 | @ <ul> |
| 563 | 563 | while( db_step(&q)==SQLITE_ROW ){ |
| 564 | 564 | const char *zName = db_column_text(&q, 0); |
| 565 | 565 | if( g.perm.Hyperlink ){ |
| 566 | - @ <li>%z(xhref("class='taglink'","%R/timeline?t=%T",zName)) | |
| 566 | + @ <li>%z(xhref("class='taglink'","%R/timeline?t=%T&n=200",zName)) | |
| 567 | 567 | @ %h(zName)</a></li> |
| 568 | 568 | }else{ |
| 569 | 569 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 570 | 570 | } |
| 571 | 571 | } |
| 572 | 572 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -561,11 +561,11 @@ | |
| 561 | ); |
| 562 | @ <ul> |
| 563 | while( db_step(&q)==SQLITE_ROW ){ |
| 564 | const char *zName = db_column_text(&q, 0); |
| 565 | if( g.perm.Hyperlink ){ |
| 566 | @ <li>%z(xhref("class='taglink'","%R/timeline?t=%T",zName)) |
| 567 | @ %h(zName)</a></li> |
| 568 | }else{ |
| 569 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 570 | } |
| 571 | } |
| 572 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -561,11 +561,11 @@ | |
| 561 | ); |
| 562 | @ <ul> |
| 563 | while( db_step(&q)==SQLITE_ROW ){ |
| 564 | const char *zName = db_column_text(&q, 0); |
| 565 | if( g.perm.Hyperlink ){ |
| 566 | @ <li>%z(xhref("class='taglink'","%R/timeline?t=%T&n=200",zName)) |
| 567 | @ %h(zName)</a></li> |
| 568 | }else{ |
| 569 | @ <li><span class="tagDsp">%h(zName)</span></li> |
| 570 | } |
| 571 | } |
| 572 |
+47
-16
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -20,10 +20,20 @@ | ||
| 20 | 20 | */ |
| 21 | 21 | #include "config.h" |
| 22 | 22 | #include <string.h> |
| 23 | 23 | #include <time.h> |
| 24 | 24 | #include "timeline.h" |
| 25 | + | |
| 26 | +/* | |
| 27 | +** Add an appropriate tag to the output if "rid" is unpublished (private) | |
| 28 | +*/ | |
| 29 | +#define UNPUB_TAG "<em>(unpublished)</em>" | |
| 30 | +void tag_private_status(int rid){ | |
| 31 | + if( content_is_private(rid) ){ | |
| 32 | + cgi_printf("%s", UNPUB_TAG); | |
| 33 | + } | |
| 34 | +} | |
| 25 | 35 | |
| 26 | 36 | /* |
| 27 | 37 | ** Generate a hyperlink to a version. |
| 28 | 38 | */ |
| 29 | 39 | void hyperlink_to_uuid(const char *zUuid){ |
| @@ -417,11 +427,11 @@ | ||
| 417 | 427 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 418 | 428 | ** with a hyperlink to another timeline for that user. |
| 419 | 429 | */ |
| 420 | 430 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 421 | 431 | if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ |
| 422 | - char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); | |
| 432 | + char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate); | |
| 423 | 433 | @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") |
| 424 | 434 | }else{ |
| 425 | 435 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 426 | 436 | } |
| 427 | 437 | |
| @@ -442,11 +452,11 @@ | ||
| 442 | 452 | while( z && z[0] ){ |
| 443 | 453 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 444 | 454 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 445 | 455 | blob_appendf(&links, |
| 446 | 456 | "%z%#h</a>%.2s", |
| 447 | - href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] | |
| 457 | + href("%R/timeline?r=%#t&nd&c=%t&n=200",i,z,zDate), i,z, &z[i] | |
| 448 | 458 | ); |
| 449 | 459 | }else{ |
| 450 | 460 | blob_appendf(&links, "%#h", i+2, z); |
| 451 | 461 | } |
| 452 | 462 | if( z[i]==0 ) break; |
| @@ -456,11 +466,11 @@ | ||
| 456 | 466 | blob_reset(&links); |
| 457 | 467 | }else{ |
| 458 | 468 | @ tags: %h(zTagList)) |
| 459 | 469 | } |
| 460 | 470 | } |
| 461 | - | |
| 471 | + tag_private_status(rid); | |
| 462 | 472 | |
| 463 | 473 | /* Generate extra hyperlinks at the end of the comment */ |
| 464 | 474 | if( xExtra ){ |
| 465 | 475 | xExtra(rid); |
| 466 | 476 | } |
| @@ -471,11 +481,11 @@ | ||
| 471 | 481 | ){ |
| 472 | 482 | int inUl = 0; |
| 473 | 483 | if( !fchngQueryInit ){ |
| 474 | 484 | db_prepare(&fchngQuery, |
| 475 | 485 | "SELECT (pid==0) AS isnew," |
| 476 | - " (fid==0) AS isdel," | |
| 486 | + " fid," | |
| 477 | 487 | " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name," |
| 478 | 488 | " (SELECT uuid FROM blob WHERE rid=fid)," |
| 479 | 489 | " (SELECT uuid FROM blob WHERE rid=pid)," |
| 480 | 490 | " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm" |
| 481 | 491 | " FROM mlink" |
| @@ -488,14 +498,16 @@ | ||
| 488 | 498 | } |
| 489 | 499 | db_bind_int(&fchngQuery, ":mid", rid); |
| 490 | 500 | while( db_step(&fchngQuery)==SQLITE_ROW ){ |
| 491 | 501 | const char *zFilename = db_column_text(&fchngQuery, 2); |
| 492 | 502 | int isNew = db_column_int(&fchngQuery, 0); |
| 493 | - int isDel = db_column_int(&fchngQuery, 1); | |
| 503 | + int fid = db_column_int(&fchngQuery, 1); | |
| 504 | + int isDel = fid==0; | |
| 494 | 505 | const char *zOldName = db_column_text(&fchngQuery, 5); |
| 495 | 506 | const char *zOld = db_column_text(&fchngQuery, 4); |
| 496 | 507 | const char *zNew = db_column_text(&fchngQuery, 3); |
| 508 | + const char *zUnpubTag = ""; | |
| 497 | 509 | if( !inUl ){ |
| 498 | 510 | @ <ul class="filelist"> |
| 499 | 511 | inUl = 1; |
| 500 | 512 | } |
| 501 | 513 | if( (tmFlags & TIMELINE_FRENAMES)!=0 ){ |
| @@ -502,23 +514,26 @@ | ||
| 502 | 514 | if( !isNew && !isDel && zOldName!=0 ){ |
| 503 | 515 | @ <li> %h(zOldName) → %h(zFilename) |
| 504 | 516 | } |
| 505 | 517 | continue; |
| 506 | 518 | } |
| 519 | + if( content_is_private(fid) ){ | |
| 520 | + zUnpubTag = UNPUB_TAG; | |
| 521 | + } | |
| 507 | 522 | if( isNew ){ |
| 508 | - @ <li> %h(zFilename) (new file) | |
| 523 | + @ <li> %h(zFilename) %s(zUnpubTag) (new file) | |
| 509 | 524 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 510 | 525 | }else if( isDel ){ |
| 511 | 526 | @ <li> %h(zFilename) (deleted)</li> |
| 512 | 527 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 513 | - @ <li> %h(zOldName) → %h(zFilename) | |
| 528 | + @ <li> %h(zOldName) → %h(zFilename) %s(zUnpubTag) | |
| 514 | 529 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 515 | 530 | }else{ |
| 516 | 531 | if( zOldName!=0 ){ |
| 517 | - @ <li> %h(zOldName) → %h(zFilename) | |
| 532 | + @ <li> %h(zOldName) → %h(zFilename) %s(zUnpubTag) | |
| 518 | 533 | }else{ |
| 519 | - @ <li> %h(zFilename) | |
| 534 | + @ <li> %h(zFilename) %s(zUnpubTag) | |
| 520 | 535 | } |
| 521 | 536 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li> |
| 522 | 537 | } |
| 523 | 538 | } |
| 524 | 539 | db_reset(&fchngQuery); |
| @@ -1088,16 +1103,22 @@ | ||
| 1088 | 1103 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 1089 | 1104 | zThisTag = zBrName; |
| 1090 | 1105 | }else{ |
| 1091 | 1106 | tagid = 0; |
| 1092 | 1107 | } |
| 1108 | + if( tagid>0 | |
| 1109 | + && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry | |
| 1110 | + ){ | |
| 1111 | + zCirca = zBefore = zAfter = 0; | |
| 1112 | + nEntry = -1; | |
| 1113 | + } | |
| 1093 | 1114 | if( zType[0]=='a' ){ |
| 1094 | 1115 | tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH; |
| 1095 | 1116 | }else{ |
| 1096 | 1117 | tmFlags = TIMELINE_GRAPH; |
| 1097 | 1118 | } |
| 1098 | - url_add_parameter(&url, "n", mprintf("%d", nEntry)); | |
| 1119 | + if( nEntry>0 ) url_add_parameter(&url, "n", mprintf("%d", nEntry)); | |
| 1099 | 1120 | if( P("ng")!=0 || zSearch!=0 ){ |
| 1100 | 1121 | tmFlags &= ~TIMELINE_GRAPH; |
| 1101 | 1122 | url_add_parameter(&url, "ng", 0); |
| 1102 | 1123 | } |
| 1103 | 1124 | if( P("brbg")!=0 ){ |
| @@ -1229,11 +1250,11 @@ | ||
| 1229 | 1250 | url_add_parameter(&url, "d", zUuid); |
| 1230 | 1251 | } |
| 1231 | 1252 | if( nEntry>20 ){ |
| 1232 | 1253 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1233 | 1254 | } |
| 1234 | - if( nEntry<200 ){ | |
| 1255 | + if( nEntry<200 && nEntry>0 ){ | |
| 1235 | 1256 | timeline_submenu(&url, "200 Entries", "n", "200", 0); |
| 1236 | 1257 | } |
| 1237 | 1258 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1238 | 1259 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| 1239 | 1260 | }else{ |
| @@ -1373,10 +1394,16 @@ | ||
| 1373 | 1394 | }else if( zType[0]=='g' ){ |
| 1374 | 1395 | zEType = "tag"; |
| 1375 | 1396 | } |
| 1376 | 1397 | } |
| 1377 | 1398 | if( zUser ){ |
| 1399 | + int n = db_int(0,"SELECT count(*) FROM event" | |
| 1400 | + " WHERE user=%Q OR euser=%Q", zUser, zUser); | |
| 1401 | + if( n<=nEntry ){ | |
| 1402 | + zCirca = zBefore = zAfter = 0; | |
| 1403 | + nEntry = -1; | |
| 1404 | + } | |
| 1378 | 1405 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1379 | 1406 | zUser, zUser); |
| 1380 | 1407 | url_add_parameter(&url, "u", zUser); |
| 1381 | 1408 | zThisUser = zUser; |
| 1382 | 1409 | } |
| @@ -1394,11 +1421,11 @@ | ||
| 1394 | 1421 | blob_append_sql(&sql, |
| 1395 | 1422 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1396 | 1423 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| 1397 | 1424 | url_add_parameter(&url, "a", zAfter); |
| 1398 | 1425 | url_add_parameter(&url, "b", zBefore); |
| 1399 | - nEntry = 1000000; | |
| 1426 | + nEntry = -1; | |
| 1400 | 1427 | }else{ |
| 1401 | 1428 | blob_append_sql(&sql, |
| 1402 | 1429 | " AND event.mtime>=%.17g ORDER BY event.mtime ASC", |
| 1403 | 1430 | rAfter-ONE_SECOND); |
| 1404 | 1431 | url_add_parameter(&url, "a", zAfter); |
| @@ -1425,19 +1452,19 @@ | ||
| 1425 | 1452 | if( useDividers ) timeline_add_dividers(rCirca, 0); |
| 1426 | 1453 | url_add_parameter(&url, "c", zCirca); |
| 1427 | 1454 | }else{ |
| 1428 | 1455 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1429 | 1456 | } |
| 1430 | - blob_append_sql(&sql, " LIMIT %d", nEntry); | |
| 1457 | + if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry); | |
| 1431 | 1458 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1432 | 1459 | |
| 1433 | 1460 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1434 | 1461 | if( zYearMonth ){ |
| 1435 | 1462 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1436 | 1463 | }else if( zYearWeek ){ |
| 1437 | 1464 | blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek); |
| 1438 | - }else if( zAfter==0 && zBefore==0 && zCirca==0 ){ | |
| 1465 | + }else if( zAfter==0 && zBefore==0 && zCirca==0 && nEntry>0 ){ | |
| 1439 | 1466 | blob_appendf(&desc, "%d most recent %ss", n, zEType); |
| 1440 | 1467 | }else{ |
| 1441 | 1468 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1442 | 1469 | } |
| 1443 | 1470 | if( zUses ){ |
| @@ -1507,11 +1534,11 @@ | ||
| 1507 | 1534 | } |
| 1508 | 1535 | } |
| 1509 | 1536 | if( nEntry>20 ){ |
| 1510 | 1537 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1511 | 1538 | } |
| 1512 | - if( nEntry<200 ){ | |
| 1539 | + if( nEntry<200 && nEntry>0 ){ | |
| 1513 | 1540 | timeline_submenu(&url, "200 Entries", "n", "200", 0); |
| 1514 | 1541 | } |
| 1515 | 1542 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1516 | 1543 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1517 | 1544 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| @@ -1617,11 +1644,15 @@ | ||
| 1617 | 1644 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], zBrType); |
| 1618 | 1645 | n = strlen(zPrefix); |
| 1619 | 1646 | } |
| 1620 | 1647 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1621 | 1648 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1622 | - n += strlen(zPrefix); | |
| 1649 | + n += strlen(zPrefix+n); | |
| 1650 | + } | |
| 1651 | + if( content_is_private(rid) ){ | |
| 1652 | + sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*UNPUBLISHED* "); | |
| 1653 | + n += strlen(zPrefix+n); | |
| 1623 | 1654 | } |
| 1624 | 1655 | zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom); |
| 1625 | 1656 | /* record another X lines */ |
| 1626 | 1657 | nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags); |
| 1627 | 1658 | fossil_free(zFree); |
| 1628 | 1659 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -20,10 +20,20 @@ | |
| 20 | */ |
| 21 | #include "config.h" |
| 22 | #include <string.h> |
| 23 | #include <time.h> |
| 24 | #include "timeline.h" |
| 25 | |
| 26 | /* |
| 27 | ** Generate a hyperlink to a version. |
| 28 | */ |
| 29 | void hyperlink_to_uuid(const char *zUuid){ |
| @@ -417,11 +427,11 @@ | |
| 417 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 418 | ** with a hyperlink to another timeline for that user. |
| 419 | */ |
| 420 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 421 | if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ |
| 422 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); |
| 423 | @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") |
| 424 | }else{ |
| 425 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 426 | } |
| 427 | |
| @@ -442,11 +452,11 @@ | |
| 442 | while( z && z[0] ){ |
| 443 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 444 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 445 | blob_appendf(&links, |
| 446 | "%z%#h</a>%.2s", |
| 447 | href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i] |
| 448 | ); |
| 449 | }else{ |
| 450 | blob_appendf(&links, "%#h", i+2, z); |
| 451 | } |
| 452 | if( z[i]==0 ) break; |
| @@ -456,11 +466,11 @@ | |
| 456 | blob_reset(&links); |
| 457 | }else{ |
| 458 | @ tags: %h(zTagList)) |
| 459 | } |
| 460 | } |
| 461 | |
| 462 | |
| 463 | /* Generate extra hyperlinks at the end of the comment */ |
| 464 | if( xExtra ){ |
| 465 | xExtra(rid); |
| 466 | } |
| @@ -471,11 +481,11 @@ | |
| 471 | ){ |
| 472 | int inUl = 0; |
| 473 | if( !fchngQueryInit ){ |
| 474 | db_prepare(&fchngQuery, |
| 475 | "SELECT (pid==0) AS isnew," |
| 476 | " (fid==0) AS isdel," |
| 477 | " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name," |
| 478 | " (SELECT uuid FROM blob WHERE rid=fid)," |
| 479 | " (SELECT uuid FROM blob WHERE rid=pid)," |
| 480 | " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm" |
| 481 | " FROM mlink" |
| @@ -488,14 +498,16 @@ | |
| 488 | } |
| 489 | db_bind_int(&fchngQuery, ":mid", rid); |
| 490 | while( db_step(&fchngQuery)==SQLITE_ROW ){ |
| 491 | const char *zFilename = db_column_text(&fchngQuery, 2); |
| 492 | int isNew = db_column_int(&fchngQuery, 0); |
| 493 | int isDel = db_column_int(&fchngQuery, 1); |
| 494 | const char *zOldName = db_column_text(&fchngQuery, 5); |
| 495 | const char *zOld = db_column_text(&fchngQuery, 4); |
| 496 | const char *zNew = db_column_text(&fchngQuery, 3); |
| 497 | if( !inUl ){ |
| 498 | @ <ul class="filelist"> |
| 499 | inUl = 1; |
| 500 | } |
| 501 | if( (tmFlags & TIMELINE_FRENAMES)!=0 ){ |
| @@ -502,23 +514,26 @@ | |
| 502 | if( !isNew && !isDel && zOldName!=0 ){ |
| 503 | @ <li> %h(zOldName) → %h(zFilename) |
| 504 | } |
| 505 | continue; |
| 506 | } |
| 507 | if( isNew ){ |
| 508 | @ <li> %h(zFilename) (new file) |
| 509 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 510 | }else if( isDel ){ |
| 511 | @ <li> %h(zFilename) (deleted)</li> |
| 512 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 513 | @ <li> %h(zOldName) → %h(zFilename) |
| 514 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 515 | }else{ |
| 516 | if( zOldName!=0 ){ |
| 517 | @ <li> %h(zOldName) → %h(zFilename) |
| 518 | }else{ |
| 519 | @ <li> %h(zFilename) |
| 520 | } |
| 521 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li> |
| 522 | } |
| 523 | } |
| 524 | db_reset(&fchngQuery); |
| @@ -1088,16 +1103,22 @@ | |
| 1088 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 1089 | zThisTag = zBrName; |
| 1090 | }else{ |
| 1091 | tagid = 0; |
| 1092 | } |
| 1093 | if( zType[0]=='a' ){ |
| 1094 | tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH; |
| 1095 | }else{ |
| 1096 | tmFlags = TIMELINE_GRAPH; |
| 1097 | } |
| 1098 | url_add_parameter(&url, "n", mprintf("%d", nEntry)); |
| 1099 | if( P("ng")!=0 || zSearch!=0 ){ |
| 1100 | tmFlags &= ~TIMELINE_GRAPH; |
| 1101 | url_add_parameter(&url, "ng", 0); |
| 1102 | } |
| 1103 | if( P("brbg")!=0 ){ |
| @@ -1229,11 +1250,11 @@ | |
| 1229 | url_add_parameter(&url, "d", zUuid); |
| 1230 | } |
| 1231 | if( nEntry>20 ){ |
| 1232 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1233 | } |
| 1234 | if( nEntry<200 ){ |
| 1235 | timeline_submenu(&url, "200 Entries", "n", "200", 0); |
| 1236 | } |
| 1237 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1238 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| 1239 | }else{ |
| @@ -1373,10 +1394,16 @@ | |
| 1373 | }else if( zType[0]=='g' ){ |
| 1374 | zEType = "tag"; |
| 1375 | } |
| 1376 | } |
| 1377 | if( zUser ){ |
| 1378 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1379 | zUser, zUser); |
| 1380 | url_add_parameter(&url, "u", zUser); |
| 1381 | zThisUser = zUser; |
| 1382 | } |
| @@ -1394,11 +1421,11 @@ | |
| 1394 | blob_append_sql(&sql, |
| 1395 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1396 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| 1397 | url_add_parameter(&url, "a", zAfter); |
| 1398 | url_add_parameter(&url, "b", zBefore); |
| 1399 | nEntry = 1000000; |
| 1400 | }else{ |
| 1401 | blob_append_sql(&sql, |
| 1402 | " AND event.mtime>=%.17g ORDER BY event.mtime ASC", |
| 1403 | rAfter-ONE_SECOND); |
| 1404 | url_add_parameter(&url, "a", zAfter); |
| @@ -1425,19 +1452,19 @@ | |
| 1425 | if( useDividers ) timeline_add_dividers(rCirca, 0); |
| 1426 | url_add_parameter(&url, "c", zCirca); |
| 1427 | }else{ |
| 1428 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1429 | } |
| 1430 | blob_append_sql(&sql, " LIMIT %d", nEntry); |
| 1431 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1432 | |
| 1433 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1434 | if( zYearMonth ){ |
| 1435 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1436 | }else if( zYearWeek ){ |
| 1437 | blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek); |
| 1438 | }else if( zAfter==0 && zBefore==0 && zCirca==0 ){ |
| 1439 | blob_appendf(&desc, "%d most recent %ss", n, zEType); |
| 1440 | }else{ |
| 1441 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1442 | } |
| 1443 | if( zUses ){ |
| @@ -1507,11 +1534,11 @@ | |
| 1507 | } |
| 1508 | } |
| 1509 | if( nEntry>20 ){ |
| 1510 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1511 | } |
| 1512 | if( nEntry<200 ){ |
| 1513 | timeline_submenu(&url, "200 Entries", "n", "200", 0); |
| 1514 | } |
| 1515 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1516 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1517 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| @@ -1617,11 +1644,15 @@ | |
| 1617 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], zBrType); |
| 1618 | n = strlen(zPrefix); |
| 1619 | } |
| 1620 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1621 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1622 | n += strlen(zPrefix); |
| 1623 | } |
| 1624 | zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom); |
| 1625 | /* record another X lines */ |
| 1626 | nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags); |
| 1627 | fossil_free(zFree); |
| 1628 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -20,10 +20,20 @@ | |
| 20 | */ |
| 21 | #include "config.h" |
| 22 | #include <string.h> |
| 23 | #include <time.h> |
| 24 | #include "timeline.h" |
| 25 | |
| 26 | /* |
| 27 | ** Add an appropriate tag to the output if "rid" is unpublished (private) |
| 28 | */ |
| 29 | #define UNPUB_TAG "<em>(unpublished)</em>" |
| 30 | void tag_private_status(int rid){ |
| 31 | if( content_is_private(rid) ){ |
| 32 | cgi_printf("%s", UNPUB_TAG); |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | /* |
| 37 | ** Generate a hyperlink to a version. |
| 38 | */ |
| 39 | void hyperlink_to_uuid(const char *zUuid){ |
| @@ -417,11 +427,11 @@ | |
| 427 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 428 | ** with a hyperlink to another timeline for that user. |
| 429 | */ |
| 430 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 431 | if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ |
| 432 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate); |
| 433 | @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") |
| 434 | }else{ |
| 435 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 436 | } |
| 437 | |
| @@ -442,11 +452,11 @@ | |
| 452 | while( z && z[0] ){ |
| 453 | for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} |
| 454 | if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ |
| 455 | blob_appendf(&links, |
| 456 | "%z%#h</a>%.2s", |
| 457 | href("%R/timeline?r=%#t&nd&c=%t&n=200",i,z,zDate), i,z, &z[i] |
| 458 | ); |
| 459 | }else{ |
| 460 | blob_appendf(&links, "%#h", i+2, z); |
| 461 | } |
| 462 | if( z[i]==0 ) break; |
| @@ -456,11 +466,11 @@ | |
| 466 | blob_reset(&links); |
| 467 | }else{ |
| 468 | @ tags: %h(zTagList)) |
| 469 | } |
| 470 | } |
| 471 | tag_private_status(rid); |
| 472 | |
| 473 | /* Generate extra hyperlinks at the end of the comment */ |
| 474 | if( xExtra ){ |
| 475 | xExtra(rid); |
| 476 | } |
| @@ -471,11 +481,11 @@ | |
| 481 | ){ |
| 482 | int inUl = 0; |
| 483 | if( !fchngQueryInit ){ |
| 484 | db_prepare(&fchngQuery, |
| 485 | "SELECT (pid==0) AS isnew," |
| 486 | " fid," |
| 487 | " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name," |
| 488 | " (SELECT uuid FROM blob WHERE rid=fid)," |
| 489 | " (SELECT uuid FROM blob WHERE rid=pid)," |
| 490 | " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm" |
| 491 | " FROM mlink" |
| @@ -488,14 +498,16 @@ | |
| 498 | } |
| 499 | db_bind_int(&fchngQuery, ":mid", rid); |
| 500 | while( db_step(&fchngQuery)==SQLITE_ROW ){ |
| 501 | const char *zFilename = db_column_text(&fchngQuery, 2); |
| 502 | int isNew = db_column_int(&fchngQuery, 0); |
| 503 | int fid = db_column_int(&fchngQuery, 1); |
| 504 | int isDel = fid==0; |
| 505 | const char *zOldName = db_column_text(&fchngQuery, 5); |
| 506 | const char *zOld = db_column_text(&fchngQuery, 4); |
| 507 | const char *zNew = db_column_text(&fchngQuery, 3); |
| 508 | const char *zUnpubTag = ""; |
| 509 | if( !inUl ){ |
| 510 | @ <ul class="filelist"> |
| 511 | inUl = 1; |
| 512 | } |
| 513 | if( (tmFlags & TIMELINE_FRENAMES)!=0 ){ |
| @@ -502,23 +514,26 @@ | |
| 514 | if( !isNew && !isDel && zOldName!=0 ){ |
| 515 | @ <li> %h(zOldName) → %h(zFilename) |
| 516 | } |
| 517 | continue; |
| 518 | } |
| 519 | if( content_is_private(fid) ){ |
| 520 | zUnpubTag = UNPUB_TAG; |
| 521 | } |
| 522 | if( isNew ){ |
| 523 | @ <li> %h(zFilename) %s(zUnpubTag) (new file) |
| 524 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 525 | }else if( isDel ){ |
| 526 | @ <li> %h(zFilename) (deleted)</li> |
| 527 | }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){ |
| 528 | @ <li> %h(zOldName) → %h(zFilename) %s(zUnpubTag) |
| 529 | @ %z(href("%R/artifact/%s",zNew))[view]</a></li> |
| 530 | }else{ |
| 531 | if( zOldName!=0 ){ |
| 532 | @ <li> %h(zOldName) → %h(zFilename) %s(zUnpubTag) |
| 533 | }else{ |
| 534 | @ <li> %h(zFilename) %s(zUnpubTag) |
| 535 | } |
| 536 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li> |
| 537 | } |
| 538 | } |
| 539 | db_reset(&fchngQuery); |
| @@ -1088,16 +1103,22 @@ | |
| 1103 | tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName); |
| 1104 | zThisTag = zBrName; |
| 1105 | }else{ |
| 1106 | tagid = 0; |
| 1107 | } |
| 1108 | if( tagid>0 |
| 1109 | && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry |
| 1110 | ){ |
| 1111 | zCirca = zBefore = zAfter = 0; |
| 1112 | nEntry = -1; |
| 1113 | } |
| 1114 | if( zType[0]=='a' ){ |
| 1115 | tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH; |
| 1116 | }else{ |
| 1117 | tmFlags = TIMELINE_GRAPH; |
| 1118 | } |
| 1119 | if( nEntry>0 ) url_add_parameter(&url, "n", mprintf("%d", nEntry)); |
| 1120 | if( P("ng")!=0 || zSearch!=0 ){ |
| 1121 | tmFlags &= ~TIMELINE_GRAPH; |
| 1122 | url_add_parameter(&url, "ng", 0); |
| 1123 | } |
| 1124 | if( P("brbg")!=0 ){ |
| @@ -1229,11 +1250,11 @@ | |
| 1250 | url_add_parameter(&url, "d", zUuid); |
| 1251 | } |
| 1252 | if( nEntry>20 ){ |
| 1253 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1254 | } |
| 1255 | if( nEntry<200 && nEntry>0 ){ |
| 1256 | timeline_submenu(&url, "200 Entries", "n", "200", 0); |
| 1257 | } |
| 1258 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1259 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| 1260 | }else{ |
| @@ -1373,10 +1394,16 @@ | |
| 1394 | }else if( zType[0]=='g' ){ |
| 1395 | zEType = "tag"; |
| 1396 | } |
| 1397 | } |
| 1398 | if( zUser ){ |
| 1399 | int n = db_int(0,"SELECT count(*) FROM event" |
| 1400 | " WHERE user=%Q OR euser=%Q", zUser, zUser); |
| 1401 | if( n<=nEntry ){ |
| 1402 | zCirca = zBefore = zAfter = 0; |
| 1403 | nEntry = -1; |
| 1404 | } |
| 1405 | blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)", |
| 1406 | zUser, zUser); |
| 1407 | url_add_parameter(&url, "u", zUser); |
| 1408 | zThisUser = zUser; |
| 1409 | } |
| @@ -1394,11 +1421,11 @@ | |
| 1421 | blob_append_sql(&sql, |
| 1422 | " AND event.mtime>=%.17g AND event.mtime<=%.17g" |
| 1423 | " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND); |
| 1424 | url_add_parameter(&url, "a", zAfter); |
| 1425 | url_add_parameter(&url, "b", zBefore); |
| 1426 | nEntry = -1; |
| 1427 | }else{ |
| 1428 | blob_append_sql(&sql, |
| 1429 | " AND event.mtime>=%.17g ORDER BY event.mtime ASC", |
| 1430 | rAfter-ONE_SECOND); |
| 1431 | url_add_parameter(&url, "a", zAfter); |
| @@ -1425,19 +1452,19 @@ | |
| 1452 | if( useDividers ) timeline_add_dividers(rCirca, 0); |
| 1453 | url_add_parameter(&url, "c", zCirca); |
| 1454 | }else{ |
| 1455 | blob_append_sql(&sql, " ORDER BY event.mtime DESC"); |
| 1456 | } |
| 1457 | if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry); |
| 1458 | db_multi_exec("%s", blob_sql_text(&sql)); |
| 1459 | |
| 1460 | n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/"); |
| 1461 | if( zYearMonth ){ |
| 1462 | blob_appendf(&desc, "%s events for %h", zEType, zYearMonth); |
| 1463 | }else if( zYearWeek ){ |
| 1464 | blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek); |
| 1465 | }else if( zAfter==0 && zBefore==0 && zCirca==0 && nEntry>0 ){ |
| 1466 | blob_appendf(&desc, "%d most recent %ss", n, zEType); |
| 1467 | }else{ |
| 1468 | blob_appendf(&desc, "%d %ss", n, zEType); |
| 1469 | } |
| 1470 | if( zUses ){ |
| @@ -1507,11 +1534,11 @@ | |
| 1534 | } |
| 1535 | } |
| 1536 | if( nEntry>20 ){ |
| 1537 | timeline_submenu(&url, "20 Entries", "n", "20", 0); |
| 1538 | } |
| 1539 | if( nEntry<200 && nEntry>0 ){ |
| 1540 | timeline_submenu(&url, "200 Entries", "n", "200", 0); |
| 1541 | } |
| 1542 | if( zType[0]=='a' || zType[0]=='c' ){ |
| 1543 | if( tmFlags & TIMELINE_FCHANGES ){ |
| 1544 | timeline_submenu(&url, "Hide Files", "v", 0, 0); |
| @@ -1617,11 +1644,15 @@ | |
| 1644 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], zBrType); |
| 1645 | n = strlen(zPrefix); |
| 1646 | } |
| 1647 | if( fossil_strcmp(zCurrentUuid,zId)==0 ){ |
| 1648 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* "); |
| 1649 | n += strlen(zPrefix+n); |
| 1650 | } |
| 1651 | if( content_is_private(rid) ){ |
| 1652 | sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*UNPUBLISHED* "); |
| 1653 | n += strlen(zPrefix+n); |
| 1654 | } |
| 1655 | zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom); |
| 1656 | /* record another X lines */ |
| 1657 | nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags); |
| 1658 | fossil_free(zFree); |
| 1659 |
+22
-4
| --- win/Makefile.dmc | ||
| +++ win/Makefile.dmc | ||
| @@ -28,13 +28,13 @@ | ||
| 28 | 28 | |
| 29 | 29 | 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 |
| 30 | 30 | |
| 31 | 31 | 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 |
| 32 | 32 | |
| 33 | -SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.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 pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.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 | |
| 33 | +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 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 skins_.c sqlcmd_.c stash_.c stat_.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 | |
| 34 | 34 | |
| 35 | -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)\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)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$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)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$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 | |
| 35 | +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)\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)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$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 | |
| 36 | 36 | |
| 37 | 37 | |
| 38 | 38 | RC=$(DMDIR)\bin\rcc |
| 39 | 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | 40 | |
| @@ -49,11 +49,11 @@ | ||
| 49 | 49 | |
| 50 | 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | 52 | |
| 53 | 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | - +echo add allrepo attach bag bisect blob branch browse builtin 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 pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat 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 > $@ | |
| 54 | + +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 pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat 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 > $@ | |
| 55 | 55 | +echo fossil >> $@ |
| 56 | 56 | +echo fossil >> $@ |
| 57 | 57 | +echo $(LIBS) >> $@ |
| 58 | 58 | +echo. >> $@ |
| 59 | 59 | +echo fossil >> $@ |
| @@ -176,10 +176,16 @@ | ||
| 176 | 176 | $(OBJDIR)\builtin$O : builtin_.c builtin.h |
| 177 | 177 | $(TCC) -o$@ -c builtin_.c |
| 178 | 178 | |
| 179 | 179 | builtin_.c : $(SRCDIR)\builtin.c |
| 180 | 180 | +translate$E $** > $@ |
| 181 | + | |
| 182 | +$(OBJDIR)\bundle$O : bundle_.c bundle.h | |
| 183 | + $(TCC) -o$@ -c bundle_.c | |
| 184 | + | |
| 185 | +bundle_.c : $(SRCDIR)\bundle.c | |
| 186 | + +translate$E $** > $@ | |
| 181 | 187 | |
| 182 | 188 | $(OBJDIR)\cache$O : cache_.c cache.h |
| 183 | 189 | $(TCC) -o$@ -c cache_.c |
| 184 | 190 | |
| 185 | 191 | cache_.c : $(SRCDIR)\cache.c |
| @@ -572,10 +578,22 @@ | ||
| 572 | 578 | $(OBJDIR)\printf$O : printf_.c printf.h |
| 573 | 579 | $(TCC) -o$@ -c printf_.c |
| 574 | 580 | |
| 575 | 581 | printf_.c : $(SRCDIR)\printf.c |
| 576 | 582 | +translate$E $** > $@ |
| 583 | + | |
| 584 | +$(OBJDIR)\publish$O : publish_.c publish.h | |
| 585 | + $(TCC) -o$@ -c publish_.c | |
| 586 | + | |
| 587 | +publish_.c : $(SRCDIR)\publish.c | |
| 588 | + +translate$E $** > $@ | |
| 589 | + | |
| 590 | +$(OBJDIR)\purge$O : purge_.c purge.h | |
| 591 | + $(TCC) -o$@ -c purge_.c | |
| 592 | + | |
| 593 | +purge_.c : $(SRCDIR)\purge.c | |
| 594 | + +translate$E $** > $@ | |
| 577 | 595 | |
| 578 | 596 | $(OBJDIR)\rebuild$O : rebuild_.c rebuild.h |
| 579 | 597 | $(TCC) -o$@ -c rebuild_.c |
| 580 | 598 | |
| 581 | 599 | rebuild_.c : $(SRCDIR)\rebuild.c |
| @@ -802,7 +820,7 @@ | ||
| 802 | 820 | |
| 803 | 821 | zip_.c : $(SRCDIR)\zip.c |
| 804 | 822 | +translate$E $** > $@ |
| 805 | 823 | |
| 806 | 824 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 807 | - +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 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 pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.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 skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.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 | |
| 825 | + +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 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 skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.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 | |
| 808 | 826 | @copy /Y nul: headers |
| 809 | 827 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -28,13 +28,13 @@ | |
| 28 | |
| 29 | 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 |
| 30 | |
| 31 | 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 |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.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 pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.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 |
| 34 | |
| 35 | 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)\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)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$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)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$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 |
| 36 | |
| 37 | |
| 38 | RC=$(DMDIR)\bin\rcc |
| 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | |
| @@ -49,11 +49,11 @@ | |
| 49 | |
| 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | |
| 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | +echo add allrepo attach bag bisect blob branch browse builtin 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 pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat 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 > $@ |
| 55 | +echo fossil >> $@ |
| 56 | +echo fossil >> $@ |
| 57 | +echo $(LIBS) >> $@ |
| 58 | +echo. >> $@ |
| 59 | +echo fossil >> $@ |
| @@ -176,10 +176,16 @@ | |
| 176 | $(OBJDIR)\builtin$O : builtin_.c builtin.h |
| 177 | $(TCC) -o$@ -c builtin_.c |
| 178 | |
| 179 | builtin_.c : $(SRCDIR)\builtin.c |
| 180 | +translate$E $** > $@ |
| 181 | |
| 182 | $(OBJDIR)\cache$O : cache_.c cache.h |
| 183 | $(TCC) -o$@ -c cache_.c |
| 184 | |
| 185 | cache_.c : $(SRCDIR)\cache.c |
| @@ -572,10 +578,22 @@ | |
| 572 | $(OBJDIR)\printf$O : printf_.c printf.h |
| 573 | $(TCC) -o$@ -c printf_.c |
| 574 | |
| 575 | printf_.c : $(SRCDIR)\printf.c |
| 576 | +translate$E $** > $@ |
| 577 | |
| 578 | $(OBJDIR)\rebuild$O : rebuild_.c rebuild.h |
| 579 | $(TCC) -o$@ -c rebuild_.c |
| 580 | |
| 581 | rebuild_.c : $(SRCDIR)\rebuild.c |
| @@ -802,7 +820,7 @@ | |
| 802 | |
| 803 | zip_.c : $(SRCDIR)\zip.c |
| 804 | +translate$E $** > $@ |
| 805 | |
| 806 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 807 | +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 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 pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.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 skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.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 |
| 808 | @copy /Y nul: headers |
| 809 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -28,13 +28,13 @@ | |
| 28 | |
| 29 | 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 |
| 30 | |
| 31 | 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 |
| 32 | |
| 33 | 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 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 skins_.c sqlcmd_.c stash_.c stat_.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 |
| 34 | |
| 35 | 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)\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)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$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 |
| 36 | |
| 37 | |
| 38 | RC=$(DMDIR)\bin\rcc |
| 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | |
| @@ -49,11 +49,11 @@ | |
| 49 | |
| 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | |
| 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | +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 pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat 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 > $@ |
| 55 | +echo fossil >> $@ |
| 56 | +echo fossil >> $@ |
| 57 | +echo $(LIBS) >> $@ |
| 58 | +echo. >> $@ |
| 59 | +echo fossil >> $@ |
| @@ -176,10 +176,16 @@ | |
| 176 | $(OBJDIR)\builtin$O : builtin_.c builtin.h |
| 177 | $(TCC) -o$@ -c builtin_.c |
| 178 | |
| 179 | builtin_.c : $(SRCDIR)\builtin.c |
| 180 | +translate$E $** > $@ |
| 181 | |
| 182 | $(OBJDIR)\bundle$O : bundle_.c bundle.h |
| 183 | $(TCC) -o$@ -c bundle_.c |
| 184 | |
| 185 | bundle_.c : $(SRCDIR)\bundle.c |
| 186 | +translate$E $** > $@ |
| 187 | |
| 188 | $(OBJDIR)\cache$O : cache_.c cache.h |
| 189 | $(TCC) -o$@ -c cache_.c |
| 190 | |
| 191 | cache_.c : $(SRCDIR)\cache.c |
| @@ -572,10 +578,22 @@ | |
| 578 | $(OBJDIR)\printf$O : printf_.c printf.h |
| 579 | $(TCC) -o$@ -c printf_.c |
| 580 | |
| 581 | printf_.c : $(SRCDIR)\printf.c |
| 582 | +translate$E $** > $@ |
| 583 | |
| 584 | $(OBJDIR)\publish$O : publish_.c publish.h |
| 585 | $(TCC) -o$@ -c publish_.c |
| 586 | |
| 587 | publish_.c : $(SRCDIR)\publish.c |
| 588 | +translate$E $** > $@ |
| 589 | |
| 590 | $(OBJDIR)\purge$O : purge_.c purge.h |
| 591 | $(TCC) -o$@ -c purge_.c |
| 592 | |
| 593 | purge_.c : $(SRCDIR)\purge.c |
| 594 | +translate$E $** > $@ |
| 595 | |
| 596 | $(OBJDIR)\rebuild$O : rebuild_.c rebuild.h |
| 597 | $(TCC) -o$@ -c rebuild_.c |
| 598 | |
| 599 | rebuild_.c : $(SRCDIR)\rebuild.c |
| @@ -802,7 +820,7 @@ | |
| 820 | |
| 821 | zip_.c : $(SRCDIR)\zip.c |
| 822 | +translate$E $** > $@ |
| 823 | |
| 824 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 825 | +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 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 skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.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 |
| 826 | @copy /Y nul: headers |
| 827 |
+41
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -108,12 +108,17 @@ | ||
| 108 | 108 | endif |
| 109 | 109 | endif |
| 110 | 110 | |
| 111 | 111 | ifndef X64 |
| 112 | 112 | SSLCONFIG = mingw |
| 113 | +ifndef FOSSIL_ENABLE_MINIZ | |
| 113 | 114 | ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o" |
| 114 | 115 | LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o |
| 116 | +else | |
| 117 | +ZLIBCONFIG = | |
| 118 | +LIBTARGETS = | |
| 119 | +endif | |
| 115 | 120 | else |
| 116 | 121 | SSLCONFIG = mingw64 |
| 117 | 122 | ZLIBCONFIG = |
| 118 | 123 | LIBTARGETS = |
| 119 | 124 | endif |
| @@ -352,10 +357,11 @@ | ||
| 352 | 357 | $(SRCDIR)/bisect.c \ |
| 353 | 358 | $(SRCDIR)/blob.c \ |
| 354 | 359 | $(SRCDIR)/branch.c \ |
| 355 | 360 | $(SRCDIR)/browse.c \ |
| 356 | 361 | $(SRCDIR)/builtin.c \ |
| 362 | + $(SRCDIR)/bundle.c \ | |
| 357 | 363 | $(SRCDIR)/cache.c \ |
| 358 | 364 | $(SRCDIR)/captcha.c \ |
| 359 | 365 | $(SRCDIR)/cgi.c \ |
| 360 | 366 | $(SRCDIR)/checkin.c \ |
| 361 | 367 | $(SRCDIR)/checkout.c \ |
| @@ -418,10 +424,12 @@ | ||
| 418 | 424 | $(SRCDIR)/path.c \ |
| 419 | 425 | $(SRCDIR)/pivot.c \ |
| 420 | 426 | $(SRCDIR)/popen.c \ |
| 421 | 427 | $(SRCDIR)/pqueue.c \ |
| 422 | 428 | $(SRCDIR)/printf.c \ |
| 429 | + $(SRCDIR)/publish.c \ | |
| 430 | + $(SRCDIR)/purge.c \ | |
| 423 | 431 | $(SRCDIR)/rebuild.c \ |
| 424 | 432 | $(SRCDIR)/regexp.c \ |
| 425 | 433 | $(SRCDIR)/report.c \ |
| 426 | 434 | $(SRCDIR)/rss.c \ |
| 427 | 435 | $(SRCDIR)/schema.c \ |
| @@ -470,10 +478,11 @@ | ||
| 470 | 478 | $(OBJDIR)/bisect_.c \ |
| 471 | 479 | $(OBJDIR)/blob_.c \ |
| 472 | 480 | $(OBJDIR)/branch_.c \ |
| 473 | 481 | $(OBJDIR)/browse_.c \ |
| 474 | 482 | $(OBJDIR)/builtin_.c \ |
| 483 | + $(OBJDIR)/bundle_.c \ | |
| 475 | 484 | $(OBJDIR)/cache_.c \ |
| 476 | 485 | $(OBJDIR)/captcha_.c \ |
| 477 | 486 | $(OBJDIR)/cgi_.c \ |
| 478 | 487 | $(OBJDIR)/checkin_.c \ |
| 479 | 488 | $(OBJDIR)/checkout_.c \ |
| @@ -536,10 +545,12 @@ | ||
| 536 | 545 | $(OBJDIR)/path_.c \ |
| 537 | 546 | $(OBJDIR)/pivot_.c \ |
| 538 | 547 | $(OBJDIR)/popen_.c \ |
| 539 | 548 | $(OBJDIR)/pqueue_.c \ |
| 540 | 549 | $(OBJDIR)/printf_.c \ |
| 550 | + $(OBJDIR)/publish_.c \ | |
| 551 | + $(OBJDIR)/purge_.c \ | |
| 541 | 552 | $(OBJDIR)/rebuild_.c \ |
| 542 | 553 | $(OBJDIR)/regexp_.c \ |
| 543 | 554 | $(OBJDIR)/report_.c \ |
| 544 | 555 | $(OBJDIR)/rss_.c \ |
| 545 | 556 | $(OBJDIR)/schema_.c \ |
| @@ -585,10 +596,11 @@ | ||
| 585 | 596 | $(OBJDIR)/bisect.o \ |
| 586 | 597 | $(OBJDIR)/blob.o \ |
| 587 | 598 | $(OBJDIR)/branch.o \ |
| 588 | 599 | $(OBJDIR)/browse.o \ |
| 589 | 600 | $(OBJDIR)/builtin.o \ |
| 601 | + $(OBJDIR)/bundle.o \ | |
| 590 | 602 | $(OBJDIR)/cache.o \ |
| 591 | 603 | $(OBJDIR)/captcha.o \ |
| 592 | 604 | $(OBJDIR)/cgi.o \ |
| 593 | 605 | $(OBJDIR)/checkin.o \ |
| 594 | 606 | $(OBJDIR)/checkout.o \ |
| @@ -651,10 +663,12 @@ | ||
| 651 | 663 | $(OBJDIR)/path.o \ |
| 652 | 664 | $(OBJDIR)/pivot.o \ |
| 653 | 665 | $(OBJDIR)/popen.o \ |
| 654 | 666 | $(OBJDIR)/pqueue.o \ |
| 655 | 667 | $(OBJDIR)/printf.o \ |
| 668 | + $(OBJDIR)/publish.o \ | |
| 669 | + $(OBJDIR)/purge.o \ | |
| 656 | 670 | $(OBJDIR)/rebuild.o \ |
| 657 | 671 | $(OBJDIR)/regexp.o \ |
| 658 | 672 | $(OBJDIR)/report.o \ |
| 659 | 673 | $(OBJDIR)/rss.o \ |
| 660 | 674 | $(OBJDIR)/schema.o \ |
| @@ -893,10 +907,11 @@ | ||
| 893 | 907 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 894 | 908 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 895 | 909 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 896 | 910 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 897 | 911 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 912 | + $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \ | |
| 898 | 913 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 899 | 914 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 900 | 915 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 901 | 916 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 902 | 917 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -959,10 +974,12 @@ | ||
| 959 | 974 | $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| 960 | 975 | $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ |
| 961 | 976 | $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ |
| 962 | 977 | $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ |
| 963 | 978 | $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ |
| 979 | + $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ | |
| 980 | + $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ | |
| 964 | 981 | $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| 965 | 982 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ |
| 966 | 983 | $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ |
| 967 | 984 | $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ |
| 968 | 985 | $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ |
| @@ -1077,10 +1094,18 @@ | ||
| 1077 | 1094 | |
| 1078 | 1095 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 1079 | 1096 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 1080 | 1097 | |
| 1081 | 1098 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 1099 | + | |
| 1100 | +$(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(TRANSLATE) | |
| 1101 | + $(TRANSLATE) $(SRCDIR)/bundle.c >$@ | |
| 1102 | + | |
| 1103 | +$(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h | |
| 1104 | + $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c | |
| 1105 | + | |
| 1106 | +$(OBJDIR)/bundle.h: $(OBJDIR)/headers | |
| 1082 | 1107 | |
| 1083 | 1108 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1084 | 1109 | $(TRANSLATE) $(SRCDIR)/cache.c >$@ |
| 1085 | 1110 | |
| 1086 | 1111 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| @@ -1605,10 +1630,26 @@ | ||
| 1605 | 1630 | |
| 1606 | 1631 | $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h |
| 1607 | 1632 | $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c |
| 1608 | 1633 | |
| 1609 | 1634 | $(OBJDIR)/printf.h: $(OBJDIR)/headers |
| 1635 | + | |
| 1636 | +$(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(TRANSLATE) | |
| 1637 | + $(TRANSLATE) $(SRCDIR)/publish.c >$@ | |
| 1638 | + | |
| 1639 | +$(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h | |
| 1640 | + $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c | |
| 1641 | + | |
| 1642 | +$(OBJDIR)/publish.h: $(OBJDIR)/headers | |
| 1643 | + | |
| 1644 | +$(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(TRANSLATE) | |
| 1645 | + $(TRANSLATE) $(SRCDIR)/purge.c >$@ | |
| 1646 | + | |
| 1647 | +$(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h | |
| 1648 | + $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c | |
| 1649 | + | |
| 1650 | +$(OBJDIR)/purge.h: $(OBJDIR)/headers | |
| 1610 | 1651 | |
| 1611 | 1652 | $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE) |
| 1612 | 1653 | $(TRANSLATE) $(SRCDIR)/rebuild.c >$@ |
| 1613 | 1654 | |
| 1614 | 1655 | $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h |
| 1615 | 1656 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -108,12 +108,17 @@ | |
| 108 | endif |
| 109 | endif |
| 110 | |
| 111 | ifndef X64 |
| 112 | SSLCONFIG = mingw |
| 113 | ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o" |
| 114 | LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o |
| 115 | else |
| 116 | SSLCONFIG = mingw64 |
| 117 | ZLIBCONFIG = |
| 118 | LIBTARGETS = |
| 119 | endif |
| @@ -352,10 +357,11 @@ | |
| 352 | $(SRCDIR)/bisect.c \ |
| 353 | $(SRCDIR)/blob.c \ |
| 354 | $(SRCDIR)/branch.c \ |
| 355 | $(SRCDIR)/browse.c \ |
| 356 | $(SRCDIR)/builtin.c \ |
| 357 | $(SRCDIR)/cache.c \ |
| 358 | $(SRCDIR)/captcha.c \ |
| 359 | $(SRCDIR)/cgi.c \ |
| 360 | $(SRCDIR)/checkin.c \ |
| 361 | $(SRCDIR)/checkout.c \ |
| @@ -418,10 +424,12 @@ | |
| 418 | $(SRCDIR)/path.c \ |
| 419 | $(SRCDIR)/pivot.c \ |
| 420 | $(SRCDIR)/popen.c \ |
| 421 | $(SRCDIR)/pqueue.c \ |
| 422 | $(SRCDIR)/printf.c \ |
| 423 | $(SRCDIR)/rebuild.c \ |
| 424 | $(SRCDIR)/regexp.c \ |
| 425 | $(SRCDIR)/report.c \ |
| 426 | $(SRCDIR)/rss.c \ |
| 427 | $(SRCDIR)/schema.c \ |
| @@ -470,10 +478,11 @@ | |
| 470 | $(OBJDIR)/bisect_.c \ |
| 471 | $(OBJDIR)/blob_.c \ |
| 472 | $(OBJDIR)/branch_.c \ |
| 473 | $(OBJDIR)/browse_.c \ |
| 474 | $(OBJDIR)/builtin_.c \ |
| 475 | $(OBJDIR)/cache_.c \ |
| 476 | $(OBJDIR)/captcha_.c \ |
| 477 | $(OBJDIR)/cgi_.c \ |
| 478 | $(OBJDIR)/checkin_.c \ |
| 479 | $(OBJDIR)/checkout_.c \ |
| @@ -536,10 +545,12 @@ | |
| 536 | $(OBJDIR)/path_.c \ |
| 537 | $(OBJDIR)/pivot_.c \ |
| 538 | $(OBJDIR)/popen_.c \ |
| 539 | $(OBJDIR)/pqueue_.c \ |
| 540 | $(OBJDIR)/printf_.c \ |
| 541 | $(OBJDIR)/rebuild_.c \ |
| 542 | $(OBJDIR)/regexp_.c \ |
| 543 | $(OBJDIR)/report_.c \ |
| 544 | $(OBJDIR)/rss_.c \ |
| 545 | $(OBJDIR)/schema_.c \ |
| @@ -585,10 +596,11 @@ | |
| 585 | $(OBJDIR)/bisect.o \ |
| 586 | $(OBJDIR)/blob.o \ |
| 587 | $(OBJDIR)/branch.o \ |
| 588 | $(OBJDIR)/browse.o \ |
| 589 | $(OBJDIR)/builtin.o \ |
| 590 | $(OBJDIR)/cache.o \ |
| 591 | $(OBJDIR)/captcha.o \ |
| 592 | $(OBJDIR)/cgi.o \ |
| 593 | $(OBJDIR)/checkin.o \ |
| 594 | $(OBJDIR)/checkout.o \ |
| @@ -651,10 +663,12 @@ | |
| 651 | $(OBJDIR)/path.o \ |
| 652 | $(OBJDIR)/pivot.o \ |
| 653 | $(OBJDIR)/popen.o \ |
| 654 | $(OBJDIR)/pqueue.o \ |
| 655 | $(OBJDIR)/printf.o \ |
| 656 | $(OBJDIR)/rebuild.o \ |
| 657 | $(OBJDIR)/regexp.o \ |
| 658 | $(OBJDIR)/report.o \ |
| 659 | $(OBJDIR)/rss.o \ |
| 660 | $(OBJDIR)/schema.o \ |
| @@ -893,10 +907,11 @@ | |
| 893 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 894 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 895 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 896 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 897 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 898 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 899 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 900 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 901 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 902 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -959,10 +974,12 @@ | |
| 959 | $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| 960 | $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ |
| 961 | $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ |
| 962 | $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ |
| 963 | $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ |
| 964 | $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| 965 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ |
| 966 | $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ |
| 967 | $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ |
| 968 | $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ |
| @@ -1077,10 +1094,18 @@ | |
| 1077 | |
| 1078 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 1079 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 1080 | |
| 1081 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 1082 | |
| 1083 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1084 | $(TRANSLATE) $(SRCDIR)/cache.c >$@ |
| 1085 | |
| 1086 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| @@ -1605,10 +1630,26 @@ | |
| 1605 | |
| 1606 | $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h |
| 1607 | $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c |
| 1608 | |
| 1609 | $(OBJDIR)/printf.h: $(OBJDIR)/headers |
| 1610 | |
| 1611 | $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE) |
| 1612 | $(TRANSLATE) $(SRCDIR)/rebuild.c >$@ |
| 1613 | |
| 1614 | $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h |
| 1615 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -108,12 +108,17 @@ | |
| 108 | endif |
| 109 | endif |
| 110 | |
| 111 | ifndef X64 |
| 112 | SSLCONFIG = mingw |
| 113 | ifndef FOSSIL_ENABLE_MINIZ |
| 114 | ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o" |
| 115 | LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o |
| 116 | else |
| 117 | ZLIBCONFIG = |
| 118 | LIBTARGETS = |
| 119 | endif |
| 120 | else |
| 121 | SSLCONFIG = mingw64 |
| 122 | ZLIBCONFIG = |
| 123 | LIBTARGETS = |
| 124 | endif |
| @@ -352,10 +357,11 @@ | |
| 357 | $(SRCDIR)/bisect.c \ |
| 358 | $(SRCDIR)/blob.c \ |
| 359 | $(SRCDIR)/branch.c \ |
| 360 | $(SRCDIR)/browse.c \ |
| 361 | $(SRCDIR)/builtin.c \ |
| 362 | $(SRCDIR)/bundle.c \ |
| 363 | $(SRCDIR)/cache.c \ |
| 364 | $(SRCDIR)/captcha.c \ |
| 365 | $(SRCDIR)/cgi.c \ |
| 366 | $(SRCDIR)/checkin.c \ |
| 367 | $(SRCDIR)/checkout.c \ |
| @@ -418,10 +424,12 @@ | |
| 424 | $(SRCDIR)/path.c \ |
| 425 | $(SRCDIR)/pivot.c \ |
| 426 | $(SRCDIR)/popen.c \ |
| 427 | $(SRCDIR)/pqueue.c \ |
| 428 | $(SRCDIR)/printf.c \ |
| 429 | $(SRCDIR)/publish.c \ |
| 430 | $(SRCDIR)/purge.c \ |
| 431 | $(SRCDIR)/rebuild.c \ |
| 432 | $(SRCDIR)/regexp.c \ |
| 433 | $(SRCDIR)/report.c \ |
| 434 | $(SRCDIR)/rss.c \ |
| 435 | $(SRCDIR)/schema.c \ |
| @@ -470,10 +478,11 @@ | |
| 478 | $(OBJDIR)/bisect_.c \ |
| 479 | $(OBJDIR)/blob_.c \ |
| 480 | $(OBJDIR)/branch_.c \ |
| 481 | $(OBJDIR)/browse_.c \ |
| 482 | $(OBJDIR)/builtin_.c \ |
| 483 | $(OBJDIR)/bundle_.c \ |
| 484 | $(OBJDIR)/cache_.c \ |
| 485 | $(OBJDIR)/captcha_.c \ |
| 486 | $(OBJDIR)/cgi_.c \ |
| 487 | $(OBJDIR)/checkin_.c \ |
| 488 | $(OBJDIR)/checkout_.c \ |
| @@ -536,10 +545,12 @@ | |
| 545 | $(OBJDIR)/path_.c \ |
| 546 | $(OBJDIR)/pivot_.c \ |
| 547 | $(OBJDIR)/popen_.c \ |
| 548 | $(OBJDIR)/pqueue_.c \ |
| 549 | $(OBJDIR)/printf_.c \ |
| 550 | $(OBJDIR)/publish_.c \ |
| 551 | $(OBJDIR)/purge_.c \ |
| 552 | $(OBJDIR)/rebuild_.c \ |
| 553 | $(OBJDIR)/regexp_.c \ |
| 554 | $(OBJDIR)/report_.c \ |
| 555 | $(OBJDIR)/rss_.c \ |
| 556 | $(OBJDIR)/schema_.c \ |
| @@ -585,10 +596,11 @@ | |
| 596 | $(OBJDIR)/bisect.o \ |
| 597 | $(OBJDIR)/blob.o \ |
| 598 | $(OBJDIR)/branch.o \ |
| 599 | $(OBJDIR)/browse.o \ |
| 600 | $(OBJDIR)/builtin.o \ |
| 601 | $(OBJDIR)/bundle.o \ |
| 602 | $(OBJDIR)/cache.o \ |
| 603 | $(OBJDIR)/captcha.o \ |
| 604 | $(OBJDIR)/cgi.o \ |
| 605 | $(OBJDIR)/checkin.o \ |
| 606 | $(OBJDIR)/checkout.o \ |
| @@ -651,10 +663,12 @@ | |
| 663 | $(OBJDIR)/path.o \ |
| 664 | $(OBJDIR)/pivot.o \ |
| 665 | $(OBJDIR)/popen.o \ |
| 666 | $(OBJDIR)/pqueue.o \ |
| 667 | $(OBJDIR)/printf.o \ |
| 668 | $(OBJDIR)/publish.o \ |
| 669 | $(OBJDIR)/purge.o \ |
| 670 | $(OBJDIR)/rebuild.o \ |
| 671 | $(OBJDIR)/regexp.o \ |
| 672 | $(OBJDIR)/report.o \ |
| 673 | $(OBJDIR)/rss.o \ |
| 674 | $(OBJDIR)/schema.o \ |
| @@ -893,10 +907,11 @@ | |
| 907 | $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ |
| 908 | $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ |
| 909 | $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
| 910 | $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \ |
| 911 | $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \ |
| 912 | $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \ |
| 913 | $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \ |
| 914 | $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \ |
| 915 | $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \ |
| 916 | $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \ |
| 917 | $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \ |
| @@ -959,10 +974,12 @@ | |
| 974 | $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| 975 | $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \ |
| 976 | $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \ |
| 977 | $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \ |
| 978 | $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \ |
| 979 | $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \ |
| 980 | $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \ |
| 981 | $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \ |
| 982 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ |
| 983 | $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ |
| 984 | $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ |
| 985 | $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ |
| @@ -1077,10 +1094,18 @@ | |
| 1094 | |
| 1095 | $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h |
| 1096 | $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c |
| 1097 | |
| 1098 | $(OBJDIR)/builtin.h: $(OBJDIR)/headers |
| 1099 | |
| 1100 | $(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(TRANSLATE) |
| 1101 | $(TRANSLATE) $(SRCDIR)/bundle.c >$@ |
| 1102 | |
| 1103 | $(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h |
| 1104 | $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c |
| 1105 | |
| 1106 | $(OBJDIR)/bundle.h: $(OBJDIR)/headers |
| 1107 | |
| 1108 | $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE) |
| 1109 | $(TRANSLATE) $(SRCDIR)/cache.c >$@ |
| 1110 | |
| 1111 | $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h |
| @@ -1605,10 +1630,26 @@ | |
| 1630 | |
| 1631 | $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h |
| 1632 | $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c |
| 1633 | |
| 1634 | $(OBJDIR)/printf.h: $(OBJDIR)/headers |
| 1635 | |
| 1636 | $(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(TRANSLATE) |
| 1637 | $(TRANSLATE) $(SRCDIR)/publish.c >$@ |
| 1638 | |
| 1639 | $(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h |
| 1640 | $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c |
| 1641 | |
| 1642 | $(OBJDIR)/publish.h: $(OBJDIR)/headers |
| 1643 | |
| 1644 | $(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(TRANSLATE) |
| 1645 | $(TRANSLATE) $(SRCDIR)/purge.c >$@ |
| 1646 | |
| 1647 | $(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h |
| 1648 | $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c |
| 1649 | |
| 1650 | $(OBJDIR)/purge.h: $(OBJDIR)/headers |
| 1651 | |
| 1652 | $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE) |
| 1653 | $(TRANSLATE) $(SRCDIR)/rebuild.c >$@ |
| 1654 | |
| 1655 | $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h |
| 1656 |
+30
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -204,10 +204,11 @@ | ||
| 204 | 204 | bisect_.c \ |
| 205 | 205 | blob_.c \ |
| 206 | 206 | branch_.c \ |
| 207 | 207 | browse_.c \ |
| 208 | 208 | builtin_.c \ |
| 209 | + bundle_.c \ | |
| 209 | 210 | cache_.c \ |
| 210 | 211 | captcha_.c \ |
| 211 | 212 | cgi_.c \ |
| 212 | 213 | checkin_.c \ |
| 213 | 214 | checkout_.c \ |
| @@ -270,10 +271,12 @@ | ||
| 270 | 271 | path_.c \ |
| 271 | 272 | pivot_.c \ |
| 272 | 273 | popen_.c \ |
| 273 | 274 | pqueue_.c \ |
| 274 | 275 | printf_.c \ |
| 276 | + publish_.c \ | |
| 277 | + purge_.c \ | |
| 275 | 278 | rebuild_.c \ |
| 276 | 279 | regexp_.c \ |
| 277 | 280 | report_.c \ |
| 278 | 281 | rss_.c \ |
| 279 | 282 | schema_.c \ |
| @@ -320,10 +323,11 @@ | ||
| 320 | 323 | $(OX)\bisect$O \ |
| 321 | 324 | $(OX)\blob$O \ |
| 322 | 325 | $(OX)\branch$O \ |
| 323 | 326 | $(OX)\browse$O \ |
| 324 | 327 | $(OX)\builtin$O \ |
| 328 | + $(OX)\bundle$O \ | |
| 325 | 329 | $(OX)\cache$O \ |
| 326 | 330 | $(OX)\captcha$O \ |
| 327 | 331 | $(OX)\cgi$O \ |
| 328 | 332 | $(OX)\checkin$O \ |
| 329 | 333 | $(OX)\checkout$O \ |
| @@ -387,10 +391,12 @@ | ||
| 387 | 391 | $(OX)\path$O \ |
| 388 | 392 | $(OX)\pivot$O \ |
| 389 | 393 | $(OX)\popen$O \ |
| 390 | 394 | $(OX)\pqueue$O \ |
| 391 | 395 | $(OX)\printf$O \ |
| 396 | + $(OX)\publish$O \ | |
| 397 | + $(OX)\purge$O \ | |
| 392 | 398 | $(OX)\rebuild$O \ |
| 393 | 399 | $(OX)\regexp$O \ |
| 394 | 400 | $(OX)\report$O \ |
| 395 | 401 | $(OX)\rss$O \ |
| 396 | 402 | $(OX)\schema$O \ |
| @@ -490,10 +496,11 @@ | ||
| 490 | 496 | echo $(OX)\bisect.obj >> $@ |
| 491 | 497 | echo $(OX)\blob.obj >> $@ |
| 492 | 498 | echo $(OX)\branch.obj >> $@ |
| 493 | 499 | echo $(OX)\browse.obj >> $@ |
| 494 | 500 | echo $(OX)\builtin.obj >> $@ |
| 501 | + echo $(OX)\bundle.obj >> $@ | |
| 495 | 502 | echo $(OX)\cache.obj >> $@ |
| 496 | 503 | echo $(OX)\captcha.obj >> $@ |
| 497 | 504 | echo $(OX)\cgi.obj >> $@ |
| 498 | 505 | echo $(OX)\checkin.obj >> $@ |
| 499 | 506 | echo $(OX)\checkout.obj >> $@ |
| @@ -557,10 +564,12 @@ | ||
| 557 | 564 | echo $(OX)\path.obj >> $@ |
| 558 | 565 | echo $(OX)\pivot.obj >> $@ |
| 559 | 566 | echo $(OX)\popen.obj >> $@ |
| 560 | 567 | echo $(OX)\pqueue.obj >> $@ |
| 561 | 568 | echo $(OX)\printf.obj >> $@ |
| 569 | + echo $(OX)\publish.obj >> $@ | |
| 570 | + echo $(OX)\purge.obj >> $@ | |
| 562 | 571 | echo $(OX)\rebuild.obj >> $@ |
| 563 | 572 | echo $(OX)\regexp.obj >> $@ |
| 564 | 573 | echo $(OX)\report.obj >> $@ |
| 565 | 574 | echo $(OX)\rss.obj >> $@ |
| 566 | 575 | echo $(OX)\schema.obj >> $@ |
| @@ -752,10 +761,16 @@ | ||
| 752 | 761 | $(OX)\builtin$O : builtin_.c builtin.h |
| 753 | 762 | $(TCC) /Fo$@ -c builtin_.c |
| 754 | 763 | |
| 755 | 764 | builtin_.c : $(SRCDIR)\builtin.c |
| 756 | 765 | translate$E $** > $@ |
| 766 | + | |
| 767 | +$(OX)\bundle$O : bundle_.c bundle.h | |
| 768 | + $(TCC) /Fo$@ -c bundle_.c | |
| 769 | + | |
| 770 | +bundle_.c : $(SRCDIR)\bundle.c | |
| 771 | + translate$E $** > $@ | |
| 757 | 772 | |
| 758 | 773 | $(OX)\cache$O : cache_.c cache.h |
| 759 | 774 | $(TCC) /Fo$@ -c cache_.c |
| 760 | 775 | |
| 761 | 776 | cache_.c : $(SRCDIR)\cache.c |
| @@ -1148,10 +1163,22 @@ | ||
| 1148 | 1163 | $(OX)\printf$O : printf_.c printf.h |
| 1149 | 1164 | $(TCC) /Fo$@ -c printf_.c |
| 1150 | 1165 | |
| 1151 | 1166 | printf_.c : $(SRCDIR)\printf.c |
| 1152 | 1167 | translate$E $** > $@ |
| 1168 | + | |
| 1169 | +$(OX)\publish$O : publish_.c publish.h | |
| 1170 | + $(TCC) /Fo$@ -c publish_.c | |
| 1171 | + | |
| 1172 | +publish_.c : $(SRCDIR)\publish.c | |
| 1173 | + translate$E $** > $@ | |
| 1174 | + | |
| 1175 | +$(OX)\purge$O : purge_.c purge.h | |
| 1176 | + $(TCC) /Fo$@ -c purge_.c | |
| 1177 | + | |
| 1178 | +purge_.c : $(SRCDIR)\purge.c | |
| 1179 | + translate$E $** > $@ | |
| 1153 | 1180 | |
| 1154 | 1181 | $(OX)\rebuild$O : rebuild_.c rebuild.h |
| 1155 | 1182 | $(TCC) /Fo$@ -c rebuild_.c |
| 1156 | 1183 | |
| 1157 | 1184 | rebuild_.c : $(SRCDIR)\rebuild.c |
| @@ -1390,10 +1417,11 @@ | ||
| 1390 | 1417 | bisect_.c:bisect.h \ |
| 1391 | 1418 | blob_.c:blob.h \ |
| 1392 | 1419 | branch_.c:branch.h \ |
| 1393 | 1420 | browse_.c:browse.h \ |
| 1394 | 1421 | builtin_.c:builtin.h \ |
| 1422 | + bundle_.c:bundle.h \ | |
| 1395 | 1423 | cache_.c:cache.h \ |
| 1396 | 1424 | captcha_.c:captcha.h \ |
| 1397 | 1425 | cgi_.c:cgi.h \ |
| 1398 | 1426 | checkin_.c:checkin.h \ |
| 1399 | 1427 | checkout_.c:checkout.h \ |
| @@ -1456,10 +1484,12 @@ | ||
| 1456 | 1484 | path_.c:path.h \ |
| 1457 | 1485 | pivot_.c:pivot.h \ |
| 1458 | 1486 | popen_.c:popen.h \ |
| 1459 | 1487 | pqueue_.c:pqueue.h \ |
| 1460 | 1488 | printf_.c:printf.h \ |
| 1489 | + publish_.c:publish.h \ | |
| 1490 | + purge_.c:purge.h \ | |
| 1461 | 1491 | rebuild_.c:rebuild.h \ |
| 1462 | 1492 | regexp_.c:regexp.h \ |
| 1463 | 1493 | report_.c:report.h \ |
| 1464 | 1494 | rss_.c:rss.h \ |
| 1465 | 1495 | schema_.c:schema.h \ |
| 1466 | 1496 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -204,10 +204,11 @@ | |
| 204 | bisect_.c \ |
| 205 | blob_.c \ |
| 206 | branch_.c \ |
| 207 | browse_.c \ |
| 208 | builtin_.c \ |
| 209 | cache_.c \ |
| 210 | captcha_.c \ |
| 211 | cgi_.c \ |
| 212 | checkin_.c \ |
| 213 | checkout_.c \ |
| @@ -270,10 +271,12 @@ | |
| 270 | path_.c \ |
| 271 | pivot_.c \ |
| 272 | popen_.c \ |
| 273 | pqueue_.c \ |
| 274 | printf_.c \ |
| 275 | rebuild_.c \ |
| 276 | regexp_.c \ |
| 277 | report_.c \ |
| 278 | rss_.c \ |
| 279 | schema_.c \ |
| @@ -320,10 +323,11 @@ | |
| 320 | $(OX)\bisect$O \ |
| 321 | $(OX)\blob$O \ |
| 322 | $(OX)\branch$O \ |
| 323 | $(OX)\browse$O \ |
| 324 | $(OX)\builtin$O \ |
| 325 | $(OX)\cache$O \ |
| 326 | $(OX)\captcha$O \ |
| 327 | $(OX)\cgi$O \ |
| 328 | $(OX)\checkin$O \ |
| 329 | $(OX)\checkout$O \ |
| @@ -387,10 +391,12 @@ | |
| 387 | $(OX)\path$O \ |
| 388 | $(OX)\pivot$O \ |
| 389 | $(OX)\popen$O \ |
| 390 | $(OX)\pqueue$O \ |
| 391 | $(OX)\printf$O \ |
| 392 | $(OX)\rebuild$O \ |
| 393 | $(OX)\regexp$O \ |
| 394 | $(OX)\report$O \ |
| 395 | $(OX)\rss$O \ |
| 396 | $(OX)\schema$O \ |
| @@ -490,10 +496,11 @@ | |
| 490 | echo $(OX)\bisect.obj >> $@ |
| 491 | echo $(OX)\blob.obj >> $@ |
| 492 | echo $(OX)\branch.obj >> $@ |
| 493 | echo $(OX)\browse.obj >> $@ |
| 494 | echo $(OX)\builtin.obj >> $@ |
| 495 | echo $(OX)\cache.obj >> $@ |
| 496 | echo $(OX)\captcha.obj >> $@ |
| 497 | echo $(OX)\cgi.obj >> $@ |
| 498 | echo $(OX)\checkin.obj >> $@ |
| 499 | echo $(OX)\checkout.obj >> $@ |
| @@ -557,10 +564,12 @@ | |
| 557 | echo $(OX)\path.obj >> $@ |
| 558 | echo $(OX)\pivot.obj >> $@ |
| 559 | echo $(OX)\popen.obj >> $@ |
| 560 | echo $(OX)\pqueue.obj >> $@ |
| 561 | echo $(OX)\printf.obj >> $@ |
| 562 | echo $(OX)\rebuild.obj >> $@ |
| 563 | echo $(OX)\regexp.obj >> $@ |
| 564 | echo $(OX)\report.obj >> $@ |
| 565 | echo $(OX)\rss.obj >> $@ |
| 566 | echo $(OX)\schema.obj >> $@ |
| @@ -752,10 +761,16 @@ | |
| 752 | $(OX)\builtin$O : builtin_.c builtin.h |
| 753 | $(TCC) /Fo$@ -c builtin_.c |
| 754 | |
| 755 | builtin_.c : $(SRCDIR)\builtin.c |
| 756 | translate$E $** > $@ |
| 757 | |
| 758 | $(OX)\cache$O : cache_.c cache.h |
| 759 | $(TCC) /Fo$@ -c cache_.c |
| 760 | |
| 761 | cache_.c : $(SRCDIR)\cache.c |
| @@ -1148,10 +1163,22 @@ | |
| 1148 | $(OX)\printf$O : printf_.c printf.h |
| 1149 | $(TCC) /Fo$@ -c printf_.c |
| 1150 | |
| 1151 | printf_.c : $(SRCDIR)\printf.c |
| 1152 | translate$E $** > $@ |
| 1153 | |
| 1154 | $(OX)\rebuild$O : rebuild_.c rebuild.h |
| 1155 | $(TCC) /Fo$@ -c rebuild_.c |
| 1156 | |
| 1157 | rebuild_.c : $(SRCDIR)\rebuild.c |
| @@ -1390,10 +1417,11 @@ | |
| 1390 | bisect_.c:bisect.h \ |
| 1391 | blob_.c:blob.h \ |
| 1392 | branch_.c:branch.h \ |
| 1393 | browse_.c:browse.h \ |
| 1394 | builtin_.c:builtin.h \ |
| 1395 | cache_.c:cache.h \ |
| 1396 | captcha_.c:captcha.h \ |
| 1397 | cgi_.c:cgi.h \ |
| 1398 | checkin_.c:checkin.h \ |
| 1399 | checkout_.c:checkout.h \ |
| @@ -1456,10 +1484,12 @@ | |
| 1456 | path_.c:path.h \ |
| 1457 | pivot_.c:pivot.h \ |
| 1458 | popen_.c:popen.h \ |
| 1459 | pqueue_.c:pqueue.h \ |
| 1460 | printf_.c:printf.h \ |
| 1461 | rebuild_.c:rebuild.h \ |
| 1462 | regexp_.c:regexp.h \ |
| 1463 | report_.c:report.h \ |
| 1464 | rss_.c:rss.h \ |
| 1465 | schema_.c:schema.h \ |
| 1466 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -204,10 +204,11 @@ | |
| 204 | bisect_.c \ |
| 205 | blob_.c \ |
| 206 | branch_.c \ |
| 207 | browse_.c \ |
| 208 | builtin_.c \ |
| 209 | bundle_.c \ |
| 210 | cache_.c \ |
| 211 | captcha_.c \ |
| 212 | cgi_.c \ |
| 213 | checkin_.c \ |
| 214 | checkout_.c \ |
| @@ -270,10 +271,12 @@ | |
| 271 | path_.c \ |
| 272 | pivot_.c \ |
| 273 | popen_.c \ |
| 274 | pqueue_.c \ |
| 275 | printf_.c \ |
| 276 | publish_.c \ |
| 277 | purge_.c \ |
| 278 | rebuild_.c \ |
| 279 | regexp_.c \ |
| 280 | report_.c \ |
| 281 | rss_.c \ |
| 282 | schema_.c \ |
| @@ -320,10 +323,11 @@ | |
| 323 | $(OX)\bisect$O \ |
| 324 | $(OX)\blob$O \ |
| 325 | $(OX)\branch$O \ |
| 326 | $(OX)\browse$O \ |
| 327 | $(OX)\builtin$O \ |
| 328 | $(OX)\bundle$O \ |
| 329 | $(OX)\cache$O \ |
| 330 | $(OX)\captcha$O \ |
| 331 | $(OX)\cgi$O \ |
| 332 | $(OX)\checkin$O \ |
| 333 | $(OX)\checkout$O \ |
| @@ -387,10 +391,12 @@ | |
| 391 | $(OX)\path$O \ |
| 392 | $(OX)\pivot$O \ |
| 393 | $(OX)\popen$O \ |
| 394 | $(OX)\pqueue$O \ |
| 395 | $(OX)\printf$O \ |
| 396 | $(OX)\publish$O \ |
| 397 | $(OX)\purge$O \ |
| 398 | $(OX)\rebuild$O \ |
| 399 | $(OX)\regexp$O \ |
| 400 | $(OX)\report$O \ |
| 401 | $(OX)\rss$O \ |
| 402 | $(OX)\schema$O \ |
| @@ -490,10 +496,11 @@ | |
| 496 | echo $(OX)\bisect.obj >> $@ |
| 497 | echo $(OX)\blob.obj >> $@ |
| 498 | echo $(OX)\branch.obj >> $@ |
| 499 | echo $(OX)\browse.obj >> $@ |
| 500 | echo $(OX)\builtin.obj >> $@ |
| 501 | echo $(OX)\bundle.obj >> $@ |
| 502 | echo $(OX)\cache.obj >> $@ |
| 503 | echo $(OX)\captcha.obj >> $@ |
| 504 | echo $(OX)\cgi.obj >> $@ |
| 505 | echo $(OX)\checkin.obj >> $@ |
| 506 | echo $(OX)\checkout.obj >> $@ |
| @@ -557,10 +564,12 @@ | |
| 564 | echo $(OX)\path.obj >> $@ |
| 565 | echo $(OX)\pivot.obj >> $@ |
| 566 | echo $(OX)\popen.obj >> $@ |
| 567 | echo $(OX)\pqueue.obj >> $@ |
| 568 | echo $(OX)\printf.obj >> $@ |
| 569 | echo $(OX)\publish.obj >> $@ |
| 570 | echo $(OX)\purge.obj >> $@ |
| 571 | echo $(OX)\rebuild.obj >> $@ |
| 572 | echo $(OX)\regexp.obj >> $@ |
| 573 | echo $(OX)\report.obj >> $@ |
| 574 | echo $(OX)\rss.obj >> $@ |
| 575 | echo $(OX)\schema.obj >> $@ |
| @@ -752,10 +761,16 @@ | |
| 761 | $(OX)\builtin$O : builtin_.c builtin.h |
| 762 | $(TCC) /Fo$@ -c builtin_.c |
| 763 | |
| 764 | builtin_.c : $(SRCDIR)\builtin.c |
| 765 | translate$E $** > $@ |
| 766 | |
| 767 | $(OX)\bundle$O : bundle_.c bundle.h |
| 768 | $(TCC) /Fo$@ -c bundle_.c |
| 769 | |
| 770 | bundle_.c : $(SRCDIR)\bundle.c |
| 771 | translate$E $** > $@ |
| 772 | |
| 773 | $(OX)\cache$O : cache_.c cache.h |
| 774 | $(TCC) /Fo$@ -c cache_.c |
| 775 | |
| 776 | cache_.c : $(SRCDIR)\cache.c |
| @@ -1148,10 +1163,22 @@ | |
| 1163 | $(OX)\printf$O : printf_.c printf.h |
| 1164 | $(TCC) /Fo$@ -c printf_.c |
| 1165 | |
| 1166 | printf_.c : $(SRCDIR)\printf.c |
| 1167 | translate$E $** > $@ |
| 1168 | |
| 1169 | $(OX)\publish$O : publish_.c publish.h |
| 1170 | $(TCC) /Fo$@ -c publish_.c |
| 1171 | |
| 1172 | publish_.c : $(SRCDIR)\publish.c |
| 1173 | translate$E $** > $@ |
| 1174 | |
| 1175 | $(OX)\purge$O : purge_.c purge.h |
| 1176 | $(TCC) /Fo$@ -c purge_.c |
| 1177 | |
| 1178 | purge_.c : $(SRCDIR)\purge.c |
| 1179 | translate$E $** > $@ |
| 1180 | |
| 1181 | $(OX)\rebuild$O : rebuild_.c rebuild.h |
| 1182 | $(TCC) /Fo$@ -c rebuild_.c |
| 1183 | |
| 1184 | rebuild_.c : $(SRCDIR)\rebuild.c |
| @@ -1390,10 +1417,11 @@ | |
| 1417 | bisect_.c:bisect.h \ |
| 1418 | blob_.c:blob.h \ |
| 1419 | branch_.c:branch.h \ |
| 1420 | browse_.c:browse.h \ |
| 1421 | builtin_.c:builtin.h \ |
| 1422 | bundle_.c:bundle.h \ |
| 1423 | cache_.c:cache.h \ |
| 1424 | captcha_.c:captcha.h \ |
| 1425 | cgi_.c:cgi.h \ |
| 1426 | checkin_.c:checkin.h \ |
| 1427 | checkout_.c:checkout.h \ |
| @@ -1456,10 +1484,12 @@ | |
| 1484 | path_.c:path.h \ |
| 1485 | pivot_.c:pivot.h \ |
| 1486 | popen_.c:popen.h \ |
| 1487 | pqueue_.c:pqueue.h \ |
| 1488 | printf_.c:printf.h \ |
| 1489 | publish_.c:publish.h \ |
| 1490 | purge_.c:purge.h \ |
| 1491 | rebuild_.c:rebuild.h \ |
| 1492 | regexp_.c:regexp.h \ |
| 1493 | report_.c:report.h \ |
| 1494 | rss_.c:rss.h \ |
| 1495 | schema_.c:schema.h \ |
| 1496 |
+21
| --- www/checkin_names.wiki | ||
| +++ www/checkin_names.wiki | ||
| @@ -115,10 +115,31 @@ | ||
| 115 | 115 | |
| 116 | 116 | The "tag:deed2" name will refer to the most recent check-in |
| 117 | 117 | tagged with "deed2" not to the |
| 118 | 118 | check-in whose canonical name begins with "deed2". |
| 119 | 119 | |
| 120 | +<h2>Whole Branches</h2> | |
| 121 | + | |
| 122 | +Usually whan a branch name is specified, it means the latest checkin on | |
| 123 | +that branch. But for some commands (ex: [/help/purge|purge]) a branch name | |
| 124 | +on the argument means the earliest connected checkin on the branch. This | |
| 125 | +seems confusing when being explained here, but it works out to be intuitive | |
| 126 | +in practice. | |
| 127 | + | |
| 128 | +For example, the command "fossil purge XYZ" means to purge the checkin XYZ | |
| 129 | +and all of its descendents. But when XYZ is in the form of a branch name, one | |
| 130 | +generally wants to purge the entire branch, not just the last checkin on the | |
| 131 | +branch. And so for this reason, commands like purge will interpret a branch | |
| 132 | +name to be the first checkin of the branch rather than the last. If there | |
| 133 | +are two or more branches with the same name, then these commands will select | |
| 134 | +the first check-in of the branch that has the most recent checkin. What | |
| 135 | +happens is that Fossil searches for the most recent checkin with the given | |
| 136 | +tag, just as it always does. But if that tag is a branch name, it then walks | |
| 137 | +back down the branch looking for the first check-in of that branch. | |
| 138 | + | |
| 139 | +Again, this behavior only occurs on a few commands where it make sense. | |
| 140 | + | |
| 120 | 141 | <h2>Timestamps</h2> |
| 121 | 142 | |
| 122 | 143 | A timestamp in one of the formats shown below means the most recent |
| 123 | 144 | check-in that occurs no later than the timestamp given: |
| 124 | 145 | |
| 125 | 146 |
| --- www/checkin_names.wiki | |
| +++ www/checkin_names.wiki | |
| @@ -115,10 +115,31 @@ | |
| 115 | |
| 116 | The "tag:deed2" name will refer to the most recent check-in |
| 117 | tagged with "deed2" not to the |
| 118 | check-in whose canonical name begins with "deed2". |
| 119 | |
| 120 | <h2>Timestamps</h2> |
| 121 | |
| 122 | A timestamp in one of the formats shown below means the most recent |
| 123 | check-in that occurs no later than the timestamp given: |
| 124 | |
| 125 |
| --- www/checkin_names.wiki | |
| +++ www/checkin_names.wiki | |
| @@ -115,10 +115,31 @@ | |
| 115 | |
| 116 | The "tag:deed2" name will refer to the most recent check-in |
| 117 | tagged with "deed2" not to the |
| 118 | check-in whose canonical name begins with "deed2". |
| 119 | |
| 120 | <h2>Whole Branches</h2> |
| 121 | |
| 122 | Usually whan a branch name is specified, it means the latest checkin on |
| 123 | that branch. But for some commands (ex: [/help/purge|purge]) a branch name |
| 124 | on the argument means the earliest connected checkin on the branch. This |
| 125 | seems confusing when being explained here, but it works out to be intuitive |
| 126 | in practice. |
| 127 | |
| 128 | For example, the command "fossil purge XYZ" means to purge the checkin XYZ |
| 129 | and all of its descendents. But when XYZ is in the form of a branch name, one |
| 130 | generally wants to purge the entire branch, not just the last checkin on the |
| 131 | branch. And so for this reason, commands like purge will interpret a branch |
| 132 | name to be the first checkin of the branch rather than the last. If there |
| 133 | are two or more branches with the same name, then these commands will select |
| 134 | the first check-in of the branch that has the most recent checkin. What |
| 135 | happens is that Fossil searches for the most recent checkin with the given |
| 136 | tag, just as it always does. But if that tag is a branch name, it then walks |
| 137 | back down the branch looking for the first check-in of that branch. |
| 138 | |
| 139 | Again, this behavior only occurs on a few commands where it make sense. |
| 140 | |
| 141 | <h2>Timestamps</h2> |
| 142 | |
| 143 | A timestamp in one of the formats shown below means the most recent |
| 144 | check-in that occurs no later than the timestamp given: |
| 145 | |
| 146 |