Fossil SCM

merge cleanX

jan.nijtmans 2015-01-08 14:50 UTC cleanX-no-clean-glob merge
Commit 8e94814d8fdab83e038661c8e1fd39a3873fff18
+1 -1
--- src/allrepo.c
+++ src/allrepo.c
@@ -76,11 +76,11 @@
7676
7777
7878
/*
7979
** COMMAND: all
8080
**
81
-** Usage: %fossil all (changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync)
81
+** Usage: %fossil all SUBCOMMAND ...
8282
**
8383
** The ~/.fossil file records the location of all repositories for a
8484
** user. This command performs certain operations on all repositories
8585
** that can be useful before or after a period of disconnected operation.
8686
**
8787
--- src/allrepo.c
+++ src/allrepo.c
@@ -76,11 +76,11 @@
76
77
78 /*
79 ** COMMAND: all
80 **
81 ** Usage: %fossil all (changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync)
82 **
83 ** The ~/.fossil file records the location of all repositories for a
84 ** user. This command performs certain operations on all repositories
85 ** that can be useful before or after a period of disconnected operation.
86 **
87
--- src/allrepo.c
+++ src/allrepo.c
@@ -76,11 +76,11 @@
76
77
78 /*
79 ** COMMAND: all
80 **
81 ** Usage: %fossil all SUBCOMMAND ...
82 **
83 ** The ~/.fossil file records the location of all repositories for a
84 ** user. This command performs certain operations on all repositories
85 ** that can be useful before or after a period of disconnected operation.
86 **
87
+155 -40
--- src/branch.c
+++ src/branch.c
@@ -179,47 +179,67 @@
179179
180180
/* Do an autosync push, if requested */
181181
if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries", 1));
182182
}
183183
184
+#if INTERFACE
185
+/*
186
+** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
187
+*/
188
+#define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
189
+#define BRL_OPEN_ONLY 0x002 /* Show only open branches */
190
+#define BRL_BOTH 0x003 /* Show both open and closed branches */
191
+#define BRL_OPEN_CLOSED_MASK 0x003
192
+#define BRL_MTIME 0x004 /* Include lastest check-in time */
193
+#dfeine BRL_ORDERBY_MTIME 0x008 /* Sort by MTIME. (otherwise sort by name)*/
194
+
195
+#endif /* INTERFACE */
196
+
184197
/*
185198
** Prepare a query that will list branches.
186199
**
187200
** If (which<0) then the query pulls only closed branches. If
188201
** (which>0) then the query pulls all (closed and opened)
189202
** branches. Else the query pulls currently-opened branches.
190203
*/
191
-void branch_prepare_list_query(Stmt *pQuery, int which ){
192
- if( which < 0 ){
193
- db_prepare(pQuery,
194
- "SELECT value FROM tagxref"
195
- " WHERE tagid=%d AND value NOT NULL "
196
- "EXCEPT "
197
- "SELECT value FROM tagxref"
198
- " WHERE tagid=%d"
199
- " AND rid IN leaf"
200
- " AND NOT %z"
201
- " ORDER BY value COLLATE nocase /*sort*/",
202
- TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
203
- );
204
- }else if( which>0 ){
205
- db_prepare(pQuery,
206
- "SELECT DISTINCT value FROM tagxref"
207
- " WHERE tagid=%d AND value NOT NULL"
208
- " AND rid IN leaf"
209
- " ORDER BY value COLLATE nocase /*sort*/",
210
- TAG_BRANCH
211
- );
212
- }else{
213
- db_prepare(pQuery,
214
- "SELECT DISTINCT value FROM tagxref"
215
- " WHERE tagid=%d AND value NOT NULL"
216
- " AND rid IN leaf"
217
- " AND NOT %z"
218
- " ORDER BY value COLLATE nocase /*sort*/",
219
- TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
220
- );
204
+void branch_prepare_list_query(Stmt *pQuery, int brFlags){
205
+ switch( brFlags & BRL_OPEN_CLOSED_MASK ){
206
+ case BRL_CLOSED_ONLY: {
207
+ db_prepare(pQuery,
208
+ "SELECT value FROM tagxref"
209
+ " WHERE tagid=%d AND value NOT NULL "
210
+ "EXCEPT "
211
+ "SELECT value FROM tagxref"
212
+ " WHERE tagid=%d"
213
+ " AND rid IN leaf"
214
+ " AND NOT %z"
215
+ " ORDER BY value COLLATE nocase /*sort*/",
216
+ TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
217
+ );
218
+ break;
219
+ }
220
+ case BRL_BOTH: {
221
+ db_prepare(pQuery,
222
+ "SELECT DISTINCT value FROM tagxref"
223
+ " WHERE tagid=%d AND value NOT NULL"
224
+ " AND rid IN leaf"
225
+ " ORDER BY value COLLATE nocase /*sort*/",
226
+ TAG_BRANCH
227
+ );
228
+ break;
229
+ }
230
+ case BRL_OPEN_ONLY: {
231
+ db_prepare(pQuery,
232
+ "SELECT DISTINCT value FROM tagxref"
233
+ " WHERE tagid=%d AND value NOT NULL"
234
+ " AND rid IN leaf"
235
+ " AND NOT %z"
236
+ " ORDER BY value COLLATE nocase /*sort*/",
237
+ TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
238
+ );
239
+ break;
240
+ }
221241
}
222242
}
223243
224244
225245
/*
@@ -260,19 +280,20 @@
260280
branch_new();
261281
}else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){
262282
Stmt q;
263283
int vid;
264284
char *zCurrent = 0;
265
- int showAll = find_option("all","a",0)!=0;
266
- int showClosed = find_option("closed","c",0)!=0;
285
+ int brFlags = BRL_OPEN_ONLY;
286
+ if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
287
+ if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
267288
268289
if( g.localOpen ){
269290
vid = db_lget_int("checkout", 0);
270291
zCurrent = db_text(0, "SELECT value FROM tagxref"
271292
" WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
272293
}
273
- branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
294
+ branch_prepare_list_query(&q, brFlags);
274295
while( db_step(&q)==SQLITE_ROW ){
275296
const char *zBr = db_column_text(&q, 0);
276297
int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
277298
fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
278299
}
@@ -280,36 +301,130 @@
280301
}else{
281302
fossil_fatal("branch subcommand should be one of: "
282303
"new list ls");
283304
}
284305
}
306
+
307
+static char brlistQuery[] =
308
+@ SELECT
309
+@ tagxref.value,
310
+@ max(event.mtime),
311
+@ EXISTS(SELECT 1 FROM tagxref AS tx
312
+@ WHERE tx.rid=tagxref.rid
313
+@ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
314
+@ AND tx.tagtype>0),
315
+@ (SELECT tagxref.value
316
+@ FROM plink CROSS JOIN tagxref
317
+@ WHERE plink.pid=event.objid
318
+@ AND tagxref.rid=plink.cid
319
+@ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
320
+@ AND tagtype>0),
321
+@ count(*),
322
+@ (SELECT uuid FROM blob WHERE rid=tagxref.rid)
323
+@ FROM tagxref, tag, event
324
+@ WHERE tagxref.tagid=tag.tagid
325
+@ AND tagxref.tagtype>0
326
+@ AND tag.tagname='branch'
327
+@ AND event.objid=tagxref.rid
328
+@ GROUP BY 1
329
+@ ORDER BY 2 DESC;
330
+;
331
+
332
+/*
333
+** This is the new-style branch-list page that shows the branch names
334
+** together with their ages (time of last check-in) and whether or not
335
+** they are closed or merged to another branch.
336
+**
337
+** Control jumps to this routine from brlist_page() (the /brlist handler)
338
+** if there are no query parameters.
339
+*/
340
+static void new_brlist_page(void){
341
+ Stmt q;
342
+ double rNow;
343
+ login_check_credentials();
344
+ if( !g.perm.Read ){ login_needed(); return; }
345
+ style_header("Branches");
346
+ login_anonymous_available();
347
+
348
+ db_prepare(&q, brlistQuery/*works-like:""*/);
349
+ rNow = db_double(0.0, "SELECT julianday('now')");
350
+ @ <div class="brlist"><table id="branchlisttable">
351
+ @ <thead><tr>
352
+ @ <th>Branch Name</th>
353
+ @ <th>Age</th>
354
+ @ <th>Checkins</th>
355
+ @ <th>Status</th>
356
+ @ <th>Resolution</th>
357
+ @ </tr></thead><tbody>
358
+ while( db_step(&q)==SQLITE_ROW ){
359
+ const char *zBranch = db_column_text(&q, 0);
360
+ double rMtime = db_column_double(&q, 1);
361
+ int isClosed = db_column_int(&q, 2);
362
+ const char *zMergeTo = db_column_text(&q, 3);
363
+ int nCkin = db_column_int(&q, 4);
364
+ const char *zLastCkin = db_column_text(&q, 5);
365
+ char *zAge = human_readable_age(rNow - rMtime);
366
+ sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
367
+ if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
368
+ @ <tr>
369
+ @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
370
+ @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
371
+ @ <td data-sortkey="%08x(-nCkin)">%d(nCkin)</td>
372
+ fossil_free(zAge);
373
+ @ <td>%s(isClosed?"closed":"")</td>
374
+ if( zMergeTo ){
375
+ @ <td>merged into
376
+ @ %z(href("%R/timeline?f=%s",zLastCkin))%h(zMergeTo)</a></td>
377
+ }else{
378
+ @ <td></td>
379
+ }
380
+ @ </tr>
381
+ }
382
+ @ </tbody></table></div>
383
+ db_finalize(&q);
384
+ output_table_sorting_javascript("branchlisttable","tkktt",2);
385
+ style_footer();
386
+}
285387
286388
/*
287389
** WEBPAGE: brlist
390
+** Show a list of branches
391
+** Query parameters:
288392
**
289
-** Show a timeline of all branches
393
+** all Show all branches
394
+** closed Show only closed branches
395
+** open Show only open branches (default behavior)
396
+** colortest Show all branches with automatic color
290397
*/
291398
void brlist_page(void){
292399
Stmt q;
293400
int cnt;
294401
int showClosed = P("closed")!=0;
295402
int showAll = P("all")!=0;
403
+ int showOpen = P("open")!=0;
296404
int colorTest = P("colortest")!=0;
405
+ int brFlags = BRL_OPEN_ONLY;
297406
407
+ if( showClosed==0 && showAll==0 && showOpen==0 && colorTest==0 ){
408
+ new_brlist_page();
409
+ return;
410
+ }
298411
login_check_credentials();
299412
if( !g.perm.Read ){ login_needed(); return; }
300413
if( colorTest ){
301414
showClosed = 0;
302415
showAll = 1;
303416
}
417
+ if( showAll ) brFlags = BRL_BOTH;
418
+ if( showClosed ) brFlags = BRL_CLOSED_ONLY;
304419
305420
style_header("%s", showClosed ? "Closed Branches" :
306421
showAll ? "All Branches" : "Open Branches");
307422
style_submenu_element("Timeline", "Timeline", "brtimeline");
308423
if( showClosed ){
309424
style_submenu_element("All", "All", "brlist?all");
310
- style_submenu_element("Open","Open","brlist");
425
+ style_submenu_element("Open","Open","brlist?open");
311426
}else if( showAll ){
312427
style_submenu_element("Closed", "Closed", "brlist?closed");
313428
style_submenu_element("Open","Open","brlist");
314429
}else{
315430
style_submenu_element("All", "All", "brlist?all");
@@ -335,21 +450,21 @@
335450
@ Closed branches are fixed and do not change (unless they are first
336451
@ reopened).</li>
337452
@ </ol>
338453
style_sidebox_end();
339454
340
- branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
455
+ branch_prepare_list_query(&q, brFlags);
341456
cnt = 0;
342457
while( db_step(&q)==SQLITE_ROW ){
343458
const char *zBr = db_column_text(&q, 0);
344459
if( cnt==0 ){
345460
if( colorTest ){
346461
@ <h2>Default background colors for all branches:</h2>
462
+ }else if( showClosed ){
463
+ @ <h2>Closed Branches:</h2>
347464
}else if( showAll ){
348465
@ <h2>All Branches:</h2>
349
- }else if( showClosed ){
350
- @ <h2>Closed Branches:</h2>
351466
}else{
352467
@ <h2>Open Branches:</h2>
353468
}
354469
@ <ul>
355470
cnt++;
@@ -357,11 +472,11 @@
357472
if( colorTest ){
358473
const char *zColor = hash_color(zBr);
359474
@ <li><span style="background-color: %s(zColor)">
360475
@ %h(zBr) &rarr; %s(zColor)</span></li>
361476
}else{
362
- @ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li>
477
+ @ <li>%z(href("%R/timeline?r=%T&n=200",zBr))%h(zBr)</a></li>
363478
}
364479
}
365480
if( cnt ){
366481
@ </ul>
367482
}
@@ -385,11 +500,11 @@
385500
" AND tag.tagname GLOB 'sym-*'",
386501
rid
387502
);
388503
while( db_step(&q)==SQLITE_ROW ){
389504
const char *zTagName = db_column_text(&q, 0);
390
- @ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a>
505
+ @ %z(href("%R/timeline?r=%T&n=200",zTagName))[timeline]</a>
391506
}
392507
db_finalize(&q);
393508
}
394509
395510
/*
396511
--- src/branch.c
+++ src/branch.c
@@ -179,47 +179,67 @@
179
180 /* Do an autosync push, if requested */
181 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries", 1));
182 }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
184 /*
185 ** Prepare a query that will list branches.
186 **
187 ** If (which<0) then the query pulls only closed branches. If
188 ** (which>0) then the query pulls all (closed and opened)
189 ** branches. Else the query pulls currently-opened branches.
190 */
191 void branch_prepare_list_query(Stmt *pQuery, int which ){
192 if( which < 0 ){
193 db_prepare(pQuery,
194 "SELECT value FROM tagxref"
195 " WHERE tagid=%d AND value NOT NULL "
196 "EXCEPT "
197 "SELECT value FROM tagxref"
198 " WHERE tagid=%d"
199 " AND rid IN leaf"
200 " AND NOT %z"
201 " ORDER BY value COLLATE nocase /*sort*/",
202 TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
203 );
204 }else if( which>0 ){
205 db_prepare(pQuery,
206 "SELECT DISTINCT value FROM tagxref"
207 " WHERE tagid=%d AND value NOT NULL"
208 " AND rid IN leaf"
209 " ORDER BY value COLLATE nocase /*sort*/",
210 TAG_BRANCH
211 );
212 }else{
213 db_prepare(pQuery,
214 "SELECT DISTINCT value FROM tagxref"
215 " WHERE tagid=%d AND value NOT NULL"
216 " AND rid IN leaf"
217 " AND NOT %z"
218 " ORDER BY value COLLATE nocase /*sort*/",
219 TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
220 );
 
 
 
 
 
 
 
221 }
222 }
223
224
225 /*
@@ -260,19 +280,20 @@
260 branch_new();
261 }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){
262 Stmt q;
263 int vid;
264 char *zCurrent = 0;
265 int showAll = find_option("all","a",0)!=0;
266 int showClosed = find_option("closed","c",0)!=0;
 
267
268 if( g.localOpen ){
269 vid = db_lget_int("checkout", 0);
270 zCurrent = db_text(0, "SELECT value FROM tagxref"
271 " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
272 }
273 branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
274 while( db_step(&q)==SQLITE_ROW ){
275 const char *zBr = db_column_text(&q, 0);
276 int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
277 fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
278 }
@@ -280,36 +301,130 @@
280 }else{
281 fossil_fatal("branch subcommand should be one of: "
282 "new list ls");
283 }
284 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
286 /*
287 ** WEBPAGE: brlist
 
 
288 **
289 ** Show a timeline of all branches
 
 
 
290 */
291 void brlist_page(void){
292 Stmt q;
293 int cnt;
294 int showClosed = P("closed")!=0;
295 int showAll = P("all")!=0;
 
296 int colorTest = P("colortest")!=0;
 
297
 
 
 
 
298 login_check_credentials();
299 if( !g.perm.Read ){ login_needed(); return; }
300 if( colorTest ){
301 showClosed = 0;
302 showAll = 1;
303 }
 
 
304
305 style_header("%s", showClosed ? "Closed Branches" :
306 showAll ? "All Branches" : "Open Branches");
307 style_submenu_element("Timeline", "Timeline", "brtimeline");
308 if( showClosed ){
309 style_submenu_element("All", "All", "brlist?all");
310 style_submenu_element("Open","Open","brlist");
311 }else if( showAll ){
312 style_submenu_element("Closed", "Closed", "brlist?closed");
313 style_submenu_element("Open","Open","brlist");
314 }else{
315 style_submenu_element("All", "All", "brlist?all");
@@ -335,21 +450,21 @@
335 @ Closed branches are fixed and do not change (unless they are first
336 @ reopened).</li>
337 @ </ol>
338 style_sidebox_end();
339
340 branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
341 cnt = 0;
342 while( db_step(&q)==SQLITE_ROW ){
343 const char *zBr = db_column_text(&q, 0);
344 if( cnt==0 ){
345 if( colorTest ){
346 @ <h2>Default background colors for all branches:</h2>
 
 
347 }else if( showAll ){
348 @ <h2>All Branches:</h2>
349 }else if( showClosed ){
350 @ <h2>Closed Branches:</h2>
351 }else{
352 @ <h2>Open Branches:</h2>
353 }
354 @ <ul>
355 cnt++;
@@ -357,11 +472,11 @@
357 if( colorTest ){
358 const char *zColor = hash_color(zBr);
359 @ <li><span style="background-color: %s(zColor)">
360 @ %h(zBr) &rarr; %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 +500,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
--- src/branch.c
+++ src/branch.c
@@ -179,47 +179,67 @@
179
180 /* Do an autosync push, if requested */
181 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries", 1));
182 }
183
184 #if INTERFACE
185 /*
186 ** Allows bits in the mBplqFlags parameter to branch_prepare_list_query().
187 */
188 #define BRL_CLOSED_ONLY 0x001 /* Show only closed branches */
189 #define BRL_OPEN_ONLY 0x002 /* Show only open branches */
190 #define BRL_BOTH 0x003 /* Show both open and closed branches */
191 #define BRL_OPEN_CLOSED_MASK 0x003
192 #define BRL_MTIME 0x004 /* Include lastest check-in time */
193 #dfeine BRL_ORDERBY_MTIME 0x008 /* Sort by MTIME. (otherwise sort by name)*/
194
195 #endif /* INTERFACE */
196
197 /*
198 ** Prepare a query that will list branches.
199 **
200 ** If (which<0) then the query pulls only closed branches. If
201 ** (which>0) then the query pulls all (closed and opened)
202 ** branches. Else the query pulls currently-opened branches.
203 */
204 void branch_prepare_list_query(Stmt *pQuery, int brFlags){
205 switch( brFlags & BRL_OPEN_CLOSED_MASK ){
206 case BRL_CLOSED_ONLY: {
207 db_prepare(pQuery,
208 "SELECT value FROM tagxref"
209 " WHERE tagid=%d AND value NOT NULL "
210 "EXCEPT "
211 "SELECT value FROM tagxref"
212 " WHERE tagid=%d"
213 " AND rid IN leaf"
214 " AND NOT %z"
215 " ORDER BY value COLLATE nocase /*sort*/",
216 TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
217 );
218 break;
219 }
220 case BRL_BOTH: {
221 db_prepare(pQuery,
222 "SELECT DISTINCT value FROM tagxref"
223 " WHERE tagid=%d AND value NOT NULL"
224 " AND rid IN leaf"
225 " ORDER BY value COLLATE nocase /*sort*/",
226 TAG_BRANCH
227 );
228 break;
229 }
230 case BRL_OPEN_ONLY: {
231 db_prepare(pQuery,
232 "SELECT DISTINCT value FROM tagxref"
233 " WHERE tagid=%d AND value NOT NULL"
234 " AND rid IN leaf"
235 " AND NOT %z"
236 " ORDER BY value COLLATE nocase /*sort*/",
237 TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
238 );
239 break;
240 }
241 }
242 }
243
244
245 /*
@@ -260,19 +280,20 @@
280 branch_new();
281 }else if( (strncmp(zCmd,"list",n)==0)||(strncmp(zCmd, "ls", n)==0) ){
282 Stmt q;
283 int vid;
284 char *zCurrent = 0;
285 int brFlags = BRL_OPEN_ONLY;
286 if( find_option("all","a",0)!=0 ) brFlags = BRL_BOTH;
287 if( find_option("closed","c",0)!=0 ) brFlags = BRL_CLOSED_ONLY;
288
289 if( g.localOpen ){
290 vid = db_lget_int("checkout", 0);
291 zCurrent = db_text(0, "SELECT value FROM tagxref"
292 " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
293 }
294 branch_prepare_list_query(&q, brFlags);
295 while( db_step(&q)==SQLITE_ROW ){
296 const char *zBr = db_column_text(&q, 0);
297 int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
298 fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
299 }
@@ -280,36 +301,130 @@
301 }else{
302 fossil_fatal("branch subcommand should be one of: "
303 "new list ls");
304 }
305 }
306
307 static char brlistQuery[] =
308 @ SELECT
309 @ tagxref.value,
310 @ max(event.mtime),
311 @ EXISTS(SELECT 1 FROM tagxref AS tx
312 @ WHERE tx.rid=tagxref.rid
313 @ AND tx.tagid=(SELECT tagid FROM tag WHERE tagname='closed')
314 @ AND tx.tagtype>0),
315 @ (SELECT tagxref.value
316 @ FROM plink CROSS JOIN tagxref
317 @ WHERE plink.pid=event.objid
318 @ AND tagxref.rid=plink.cid
319 @ AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='branch')
320 @ AND tagtype>0),
321 @ count(*),
322 @ (SELECT uuid FROM blob WHERE rid=tagxref.rid)
323 @ FROM tagxref, tag, event
324 @ WHERE tagxref.tagid=tag.tagid
325 @ AND tagxref.tagtype>0
326 @ AND tag.tagname='branch'
327 @ AND event.objid=tagxref.rid
328 @ GROUP BY 1
329 @ ORDER BY 2 DESC;
330 ;
331
332 /*
333 ** This is the new-style branch-list page that shows the branch names
334 ** together with their ages (time of last check-in) and whether or not
335 ** they are closed or merged to another branch.
336 **
337 ** Control jumps to this routine from brlist_page() (the /brlist handler)
338 ** if there are no query parameters.
339 */
340 static void new_brlist_page(void){
341 Stmt q;
342 double rNow;
343 login_check_credentials();
344 if( !g.perm.Read ){ login_needed(); return; }
345 style_header("Branches");
346 login_anonymous_available();
347
348 db_prepare(&q, brlistQuery/*works-like:""*/);
349 rNow = db_double(0.0, "SELECT julianday('now')");
350 @ <div class="brlist"><table id="branchlisttable">
351 @ <thead><tr>
352 @ <th>Branch Name</th>
353 @ <th>Age</th>
354 @ <th>Checkins</th>
355 @ <th>Status</th>
356 @ <th>Resolution</th>
357 @ </tr></thead><tbody>
358 while( db_step(&q)==SQLITE_ROW ){
359 const char *zBranch = db_column_text(&q, 0);
360 double rMtime = db_column_double(&q, 1);
361 int isClosed = db_column_int(&q, 2);
362 const char *zMergeTo = db_column_text(&q, 3);
363 int nCkin = db_column_int(&q, 4);
364 const char *zLastCkin = db_column_text(&q, 5);
365 char *zAge = human_readable_age(rNow - rMtime);
366 sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
367 if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
368 @ <tr>
369 @ <td>%z(href("%R/timeline?n=100&r=%T",zBranch))%h(zBranch)</a></td>
370 @ <td data-sortkey="%016llx(-iMtime)">%s(zAge)</td>
371 @ <td data-sortkey="%08x(-nCkin)">%d(nCkin)</td>
372 fossil_free(zAge);
373 @ <td>%s(isClosed?"closed":"")</td>
374 if( zMergeTo ){
375 @ <td>merged into
376 @ %z(href("%R/timeline?f=%s",zLastCkin))%h(zMergeTo)</a></td>
377 }else{
378 @ <td></td>
379 }
380 @ </tr>
381 }
382 @ </tbody></table></div>
383 db_finalize(&q);
384 output_table_sorting_javascript("branchlisttable","tkktt",2);
385 style_footer();
386 }
387
388 /*
389 ** WEBPAGE: brlist
390 ** Show a list of branches
391 ** Query parameters:
392 **
393 ** all Show all branches
394 ** closed Show only closed branches
395 ** open Show only open branches (default behavior)
396 ** colortest Show all branches with automatic color
397 */
398 void brlist_page(void){
399 Stmt q;
400 int cnt;
401 int showClosed = P("closed")!=0;
402 int showAll = P("all")!=0;
403 int showOpen = P("open")!=0;
404 int colorTest = P("colortest")!=0;
405 int brFlags = BRL_OPEN_ONLY;
406
407 if( showClosed==0 && showAll==0 && showOpen==0 && colorTest==0 ){
408 new_brlist_page();
409 return;
410 }
411 login_check_credentials();
412 if( !g.perm.Read ){ login_needed(); return; }
413 if( colorTest ){
414 showClosed = 0;
415 showAll = 1;
416 }
417 if( showAll ) brFlags = BRL_BOTH;
418 if( showClosed ) brFlags = BRL_CLOSED_ONLY;
419
420 style_header("%s", showClosed ? "Closed Branches" :
421 showAll ? "All Branches" : "Open Branches");
422 style_submenu_element("Timeline", "Timeline", "brtimeline");
423 if( showClosed ){
424 style_submenu_element("All", "All", "brlist?all");
425 style_submenu_element("Open","Open","brlist?open");
426 }else if( showAll ){
427 style_submenu_element("Closed", "Closed", "brlist?closed");
428 style_submenu_element("Open","Open","brlist");
429 }else{
430 style_submenu_element("All", "All", "brlist?all");
@@ -335,21 +450,21 @@
450 @ Closed branches are fixed and do not change (unless they are first
451 @ reopened).</li>
452 @ </ol>
453 style_sidebox_end();
454
455 branch_prepare_list_query(&q, brFlags);
456 cnt = 0;
457 while( db_step(&q)==SQLITE_ROW ){
458 const char *zBr = db_column_text(&q, 0);
459 if( cnt==0 ){
460 if( colorTest ){
461 @ <h2>Default background colors for all branches:</h2>
462 }else if( showClosed ){
463 @ <h2>Closed Branches:</h2>
464 }else if( showAll ){
465 @ <h2>All Branches:</h2>
 
 
466 }else{
467 @ <h2>Open Branches:</h2>
468 }
469 @ <ul>
470 cnt++;
@@ -357,11 +472,11 @@
472 if( colorTest ){
473 const char *zColor = hash_color(zBr);
474 @ <li><span style="background-color: %s(zColor)">
475 @ %h(zBr) &rarr; %s(zColor)</span></li>
476 }else{
477 @ <li>%z(href("%R/timeline?r=%T&n=200",zBr))%h(zBr)</a></li>
478 }
479 }
480 if( cnt ){
481 @ </ul>
482 }
@@ -385,11 +500,11 @@
500 " AND tag.tagname GLOB 'sym-*'",
501 rid
502 );
503 while( db_step(&q)==SQLITE_ROW ){
504 const char *zTagName = db_column_text(&q, 0);
505 @ %z(href("%R/timeline?r=%T&n=200",zTagName))[timeline]</a>
506 }
507 db_finalize(&q);
508 }
509
510 /*
511
+394 -192
--- src/browse.c
+++ src/browse.c
@@ -304,89 +304,206 @@
304304
305305
/*
306306
** A single line of the file hierarchy
307307
*/
308308
struct FileTreeNode {
309
- FileTreeNode *pNext; /* Next line in sequence */
310
- FileTreeNode *pPrev; /* Previous line */
311
- FileTreeNode *pParent; /* Directory containing this line */
309
+ FileTreeNode *pNext; /* Next entry in an ordered list of them all */
310
+ FileTreeNode *pParent; /* Directory containing this entry */
311
+ FileTreeNode *pSibling; /* Next element in the same subdirectory */
312
+ FileTreeNode *pChild; /* List of child nodes */
313
+ FileTreeNode *pLastChild; /* Last child on the pChild list */
312314
char *zName; /* Name of this entry. The "tail" */
313315
char *zFullName; /* Full pathname of this entry */
314316
char *zUuid; /* SHA1 hash of this file. May be NULL. */
317
+ double mtime; /* Modification time for this entry */
315318
unsigned nFullName; /* Length of zFullName */
316319
unsigned iLevel; /* Levels of parent directories */
317
- u8 isDir; /* True if there are children */
318
- u8 isLast; /* True if this is the last child of its parent */
319320
};
320321
321322
/*
322323
** A complete file hierarchy
323324
*/
324325
struct FileTree {
325326
FileTreeNode *pFirst; /* First line of the list */
326327
FileTreeNode *pLast; /* Last line of the list */
328
+ FileTreeNode *pLastTop; /* Last top-level node */
327329
};
328330
329331
/*
330332
** Add one or more new FileTreeNodes to the FileTree object so that the
331
-** leaf object zPathname is at the end of the node list
333
+** leaf object zPathname is at the end of the node list.
334
+**
335
+** The caller invokes this routine once for each leaf node (each file
336
+** as opposed to each directory). This routine fills in any missing
337
+** intermediate nodes automatically.
338
+**
339
+** When constructing a list of FileTreeNodes, all entries that have
340
+** a common directory prefix must be added consecutively in order for
341
+** the tree to be constructed properly.
332342
*/
333343
static void tree_add_node(
334344
FileTree *pTree, /* Tree into which nodes are added */
335345
const char *zPath, /* The full pathname of file to add */
336
- const char *zUuid /* UUID of the file. Might be NULL. */
346
+ const char *zUuid, /* UUID of the file. Might be NULL. */
347
+ double mtime /* Modification time for this entry */
337348
){
338349
int i;
339
- FileTreeNode *pParent;
340
- FileTreeNode *pChild;
350
+ FileTreeNode *pParent; /* Parent (directory) of the next node to insert */
341351
342
- pChild = pTree->pLast;
343
- pParent = pChild ? pChild->pParent : 0;
352
+ /* Make pParent point to the most recent ancestor of zPath, or
353
+ ** NULL if there are no prior entires that are a container for zPath.
354
+ */
355
+ pParent = pTree->pLast;
344356
while( pParent!=0 &&
345357
( strncmp(pParent->zFullName, zPath, pParent->nFullName)!=0
346358
|| zPath[pParent->nFullName]!='/' )
347359
){
348
- pChild = pParent;
349
- pParent = pChild->pParent;
360
+ pParent = pParent->pParent;
350361
}
351362
i = pParent ? pParent->nFullName+1 : 0;
352
- if( pChild ) pChild->isLast = 0;
353363
while( zPath[i] ){
354364
FileTreeNode *pNew;
355365
int iStart = i;
356366
int nByte;
357367
while( zPath[i] && zPath[i]!='/' ){ i++; }
358368
nByte = sizeof(*pNew) + i + 1;
359369
if( zUuid!=0 && zPath[i]==0 ) nByte += UUID_SIZE+1;
360370
pNew = fossil_malloc( nByte );
371
+ memset(pNew, 0, sizeof(*pNew));
361372
pNew->zFullName = (char*)&pNew[1];
362373
memcpy(pNew->zFullName, zPath, i);
363374
pNew->zFullName[i] = 0;
364375
pNew->nFullName = i;
365376
if( zUuid!=0 && zPath[i]==0 ){
366377
pNew->zUuid = pNew->zFullName + i + 1;
367378
memcpy(pNew->zUuid, zUuid, UUID_SIZE+1);
368
- }else{
369
- pNew->zUuid = 0;
370379
}
371380
pNew->zName = pNew->zFullName + iStart;
372381
if( pTree->pLast ){
373382
pTree->pLast->pNext = pNew;
374383
}else{
375384
pTree->pFirst = pNew;
376385
}
377
- pNew->pPrev = pTree->pLast;
378
- pNew->pNext = 0;
386
+ pTree->pLast = pNew;
379387
pNew->pParent = pParent;
380
- pTree->pLast = pNew;
381
- pNew->iLevel = pParent ? pParent->iLevel+1 : 0;
382
- pNew->isDir = zPath[i]=='/';
383
- pNew->isLast = 1;
388
+ if( pParent ){
389
+ if( pParent->pChild ){
390
+ pParent->pLastChild->pSibling = pNew;
391
+ }else{
392
+ pParent->pChild = pNew;
393
+ }
394
+ pNew->iLevel = pParent->iLevel + 1;
395
+ pParent->pLastChild = pNew;
396
+ }else{
397
+ if( pTree->pLastTop ) pTree->pLastTop->pSibling = pNew;
398
+ pTree->pLastTop = pNew;
399
+ }
400
+ pNew->mtime = mtime;
384401
while( zPath[i]=='/' ){ i++; }
385402
pParent = pNew;
386403
}
404
+ while( pParent && pParent->pParent ){
405
+ if( pParent->pParent->mtime < pParent->mtime ){
406
+ pParent->pParent->mtime = pParent->mtime;
407
+ }
408
+ pParent = pParent->pParent;
409
+ }
410
+}
411
+
412
+/* Comparison function for two FileTreeNode objects. Sort first by
413
+** mtime (larger numbers first) and then by zName (smaller names first).
414
+**
415
+** Return negative if pLeft<pRight.
416
+** Return positive if pLeft>pRight.
417
+** Return zero if pLeft==pRight.
418
+*/
419
+static int compareNodes(FileTreeNode *pLeft, FileTreeNode *pRight){
420
+ if( pLeft->mtime>pRight->mtime ) return -1;
421
+ if( pLeft->mtime<pRight->mtime ) return +1;
422
+ return fossil_stricmp(pLeft->zName, pRight->zName);
423
+}
424
+
425
+/* Merge together two sorted lists of FileTreeNode objects */
426
+static FileTreeNode *mergeNodes(FileTreeNode *pLeft, FileTreeNode *pRight){
427
+ FileTreeNode *pEnd;
428
+ FileTreeNode base;
429
+ pEnd = &base;
430
+ while( pLeft && pRight ){
431
+ if( compareNodes(pLeft,pRight)<=0 ){
432
+ pEnd = pEnd->pSibling = pLeft;
433
+ pLeft = pLeft->pSibling;
434
+ }else{
435
+ pEnd = pEnd->pSibling = pRight;
436
+ pRight = pRight->pSibling;
437
+ }
438
+ }
439
+ if( pLeft ){
440
+ pEnd->pSibling = pLeft;
441
+ }else{
442
+ pEnd->pSibling = pRight;
443
+ }
444
+ return base.pSibling;
445
+}
446
+
447
+/* Sort a list of FileTreeNode objects in mtime order. */
448
+static FileTreeNode *sortNodesByMtime(FileTreeNode *p){
449
+ FileTreeNode *a[30];
450
+ FileTreeNode *pX;
451
+ int i;
452
+
453
+ memset(a, 0, sizeof(a));
454
+ while( p ){
455
+ pX = p;
456
+ p = pX->pSibling;
457
+ pX->pSibling = 0;
458
+ for(i=0; i<count(a)-1 && a[i]!=0; i++){
459
+ pX = mergeNodes(a[i], pX);
460
+ a[i] = 0;
461
+ }
462
+ a[i] = mergeNodes(a[i], pX);
463
+ }
464
+ pX = 0;
465
+ for(i=0; i<count(a); i++){
466
+ pX = mergeNodes(a[i], pX);
467
+ }
468
+ return pX;
469
+}
470
+
471
+/* Sort an entire FileTreeNode tree by mtime
472
+**
473
+** This routine invalidates the following fields:
474
+**
475
+** FileTreeNode.pLastChild
476
+** FileTreeNode.pNext
477
+**
478
+** Use relinkTree to reconnect the pNext pointers.
479
+*/
480
+static FileTreeNode *sortTreeByMtime(FileTreeNode *p){
481
+ FileTreeNode *pX;
482
+ for(pX=p; pX; pX=pX->pSibling){
483
+ if( pX->pChild ) pX->pChild = sortTreeByMtime(pX->pChild);
484
+ }
485
+ return sortNodesByMtime(p);
486
+}
487
+
488
+/* Reconstruct the FileTree by reconnecting the FileTreeNode.pNext
489
+** fields in sequential order.
490
+*/
491
+static void relinkTree(FileTree *pTree, FileTreeNode *pRoot){
492
+ while( pRoot ){
493
+ if( pTree->pLast ){
494
+ pTree->pLast->pNext = pRoot;
495
+ }else{
496
+ pTree->pFirst = pRoot;
497
+ }
498
+ pTree->pLast = pRoot;
499
+ if( pRoot->pChild ) relinkTree(pTree, pRoot->pChild);
500
+ pRoot = pRoot->pSibling;
501
+ }
502
+ if( pTree->pLast ) pTree->pLast->pNext = 0;
387503
}
504
+
388505
389506
/*
390507
** WEBPAGE: tree
391508
**
392509
** Query parameters:
@@ -394,19 +511,23 @@
394511
** name=PATH Directory to display. Optional
395512
** ci=LABEL Show only files in this check-in. Optional.
396513
** re=REGEXP Show only files matching REGEXP. Optional.
397514
** expand Begin with the tree fully expanded.
398515
** nofiles Show directories (folders) only. Omit files.
516
+** mtime Order directory elements by decreasing mtime
399517
*/
400518
void page_tree(void){
401519
char *zD = fossil_strdup(P("name"));
402520
int nD = zD ? strlen(zD)+1 : 0;
403521
const char *zCI = P("ci");
404522
int rid = 0;
405523
char *zUuid = 0;
406524
Blob dirname;
407525
Manifest *pM = 0;
526
+ double rNow = 0;
527
+ char *zNow = 0;
528
+ int useMtime = atoi(PD("mtime","0"));
408529
int nFile = 0; /* Number of files (or folders with "nofiles") */
409530
int linkTrunk = 1; /* include link to "trunk" */
410531
int linkTip = 1; /* include link to "tip" */
411532
const char *zRE; /* the value for the re=REGEXP query parameter */
412533
const char *zObjType; /* "files" by default or "folders" for "nofiles" */
@@ -464,14 +585,21 @@
464585
int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
465586
linkTrunk = trunkRid && rid != trunkRid;
466587
linkTip = rid != symbolic_name_to_rid("tip", "ci");
467588
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
468589
url_add_parameter(&sURI, "ci", zCI);
590
+ rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
591
+ zNow = db_text("", "SELECT datetime(mtime,'localtime')"
592
+ " FROM event WHERE objid=%d", rid);
469593
}else{
470594
zCI = 0;
471595
}
472596
}
597
+ if( zCI==0 ){
598
+ rNow = db_double(0.0, "SELECT max(mtime) FROM event");
599
+ zNow = db_text("", "SELECT datetime(max(mtime),'localtime') FROM event");
600
+ }
473601
474602
/* Compute the title of the page */
475603
blob_zero(&dirname);
476604
if( zD ){
477605
url_add_parameter(&sURI, "name", zD);
@@ -483,10 +611,18 @@
483611
}else{
484612
if( zRE ){
485613
blob_appendf(&dirname, "matching \"%s\"", zRE);
486614
}
487615
}
616
+ if( useMtime ){
617
+ style_submenu_element("Sort By Filename","Sort By Filename", "%s",
618
+ url_render(&sURI, 0, 0, 0, 0));
619
+ url_add_parameter(&sURI, "mtime", "1");
620
+ }else{
621
+ style_submenu_element("Sort By Time","Sort By Time", "%s",
622
+ url_render(&sURI, "mtime", "1", 0, 0));
623
+ }
488624
if( zCI ){
489625
style_submenu_element("All", "All", "%s",
490626
url_render(&sURI, "ci", 0, 0, 0));
491627
if( nD==0 && !showDirOnly ){
492628
style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s",
@@ -499,87 +635,82 @@
499635
}
500636
if( linkTip ){
501637
style_submenu_element("Tip", "Tip", "%s",
502638
url_render(&sURI, "ci", "tip", 0, 0));
503639
}
504
- if( !showDirOnly ){
505
- style_submenu_element("Flat-View", "Flat-View", "%s",
506
- url_render(&sURI, "type", "flat", 0, 0));
507
- }
508640
509641
/* Compute the file hierarchy.
510642
*/
511643
if( zCI ){
512
- Stmt ins, q;
513
- ManifestFile *pFile;
514
-
515
- db_multi_exec(
516
- "CREATE TEMP TABLE filelist("
517
- " x TEXT PRIMARY KEY COLLATE nocase,"
518
- " uuid TEXT"
519
- ") WITHOUT ROWID;"
644
+ Stmt q;
645
+ compute_fileage(rid, 0);
646
+ db_prepare(&q,
647
+ "SELECT filename.name, blob.uuid, fileage.mtime\n"
648
+ " FROM fileage, filename, blob\n"
649
+ " WHERE filename.fnid=fileage.fnid\n"
650
+ " AND blob.rid=fileage.fid\n"
651
+ " ORDER BY filename.name COLLATE nocase;"
520652
);
521
- db_prepare(&ins, "INSERT OR IGNORE INTO filelist VALUES(:f,:u)");
522
- manifest_file_rewind(pM);
523
- while( (pFile = manifest_file_next(pM,0))!=0 ){
524
- if( nD>0
525
- && (fossil_strncmp(pFile->zName, zD, nD-1)!=0
526
- || pFile->zName[nD-1]!='/')
527
- ){
528
- continue;
529
- }
530
- if( pRE && re_match(pRE, (const u8*)pFile->zName, -1)==0 ) continue;
531
- db_bind_text(&ins, ":f", pFile->zName);
532
- db_bind_text(&ins, ":u", pFile->zUuid);
533
- db_step(&ins);
534
- db_reset(&ins);
535
- }
536
- db_finalize(&ins);
537
- db_prepare(&q, "SELECT x, uuid FROM filelist ORDER BY x");
538653
while( db_step(&q)==SQLITE_ROW ){
539
- tree_add_node(&sTree, db_column_text(&q,0), db_column_text(&q,1));
654
+ const char *zFile = db_column_text(&q,0);
655
+ const char *zUuid = db_column_text(&q,1);
656
+ double mtime = db_column_double(&q,2);
657
+ if( pRE && re_match(pRE, (const unsigned char*)zFile, -1)==0 ) continue;
658
+ tree_add_node(&sTree, zFile, zUuid, mtime);
540659
nFile++;
541660
}
542661
db_finalize(&q);
543662
}else{
544663
Stmt q;
545
- db_prepare(&q, "SELECT name FROM filename ORDER BY name COLLATE nocase");
664
+ db_prepare(&q,
665
+ "SELECT filename.name, blob.uuid, max(event.mtime)\n"
666
+ " FROM filename, mlink, blob, event\n"
667
+ " WHERE mlink.fnid=filename.fnid\n"
668
+ " AND event.objid=mlink.mid\n"
669
+ " AND blob.rid=mlink.fid\n"
670
+ " GROUP BY 1 ORDER BY 1 COLLATE nocase");
546671
while( db_step(&q)==SQLITE_ROW ){
547
- const char *z = db_column_text(&q, 0);
548
- if( nD>0 && (fossil_strncmp(z, zD, nD-1)!=0 || z[nD-1]!='/') ){
672
+ const char *zName = db_column_text(&q, 0);
673
+ const char *zUuid = db_column_text(&q,1);
674
+ double mtime = db_column_double(&q,2);
675
+ if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
549676
continue;
550677
}
551
- if( pRE && re_match(pRE, (const u8*)z, -1)==0 ) continue;
552
- tree_add_node(&sTree, z, 0);
678
+ if( pRE && re_match(pRE, (const u8*)zName, -1)==0 ) continue;
679
+ tree_add_node(&sTree, zName, zUuid, mtime);
553680
nFile++;
554681
}
555682
db_finalize(&q);
556683
}
557684
558685
if( showDirOnly ){
559686
for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
560
- if( p->isDir && p->nFullName>nD ) nFile++;
687
+ if( p->pChild!=0 && p->nFullName>nD ) nFile++;
561688
}
562
- zObjType = "folders";
689
+ zObjType = "Folders";
563690
style_submenu_element("Files","Files","%s",
564691
url_render(&sURI,"nofiles",0,0,0));
565692
}else{
566
- zObjType = "files";
693
+ zObjType = "Files";
567694
style_submenu_element("Folders","Folders","%s",
568695
url_render(&sURI,"nofiles","1",0,0));
569696
}
570697
571698
if( zCI ){
572
- @ <h2>%d(nFile) %s(zObjType) of check-in
699
+ @ <h2>%s(zObjType) from
573700
if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
574701
@ "%h(zCI)"
575702
}
576
- @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2>
703
+ @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))
577704
}else{
578705
int n = db_int(0, "SELECT count(*) FROM plink");
579
- @ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins
580
- @ %s(blob_str(&dirname))</h2>
706
+ @ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))
707
+ }
708
+ if( useMtime ){
709
+ @ sorted by modification time</h2>
710
+ }else{
711
+ @ sorted by filename</h2>
581712
}
582713
583714
584715
/* Generate tree of lists.
585716
**
@@ -596,18 +727,33 @@
596727
if( nD ){
597728
@ <li class="dir last">
598729
}else{
599730
@ <li class="dir subdir last">
600731
}
732
+ @ <div class="filetreeline">
601733
@ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
734
+ if( zNow ){
735
+ @ <div class="filetreeage">%s(zNow)</div>
736
+ }
737
+ @ </div>
602738
@ <ul>
739
+ if( useMtime ){
740
+ p = sortTreeByMtime(sTree.pFirst);
741
+ memset(&sTree, 0, sizeof(sTree));
742
+ relinkTree(&sTree, p);
743
+ }
603744
for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
604
- const char *zLastClass = p->isLast ? " last" : "";
605
- if( p->isDir ){
745
+ const char *zLastClass = p->pSibling==0 ? " last" : "";
746
+ if( p->pChild ){
606747
const char *zSubdirClass = p->nFullName==nD-1 ? " subdir" : "";
607
- @ <li class="dir%s(zSubdirClass)%s(zLastClass)">
748
+ @ <li class="dir%s(zSubdirClass)%s(zLastClass)"><div class="filetreeline">
608749
@ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
750
+ if( p->mtime>0.0 ){
751
+ char *zAge = human_readable_age(rNow - p->mtime);
752
+ @ <div class="filetreeage">%s(zAge)</div>
753
+ }
754
+ @ </div>
609755
if( startExpanded || p->nFullName<=nD ){
610756
@ <ul id="dir%d(nDir)">
611757
}else{
612758
@ <ul id="dir%d(nDir)" class="collapsed">
613759
}
@@ -614,17 +760,23 @@
614760
nDir++;
615761
}else if( !showDirOnly ){
616762
const char *zFileClass = fileext_class(p->zName);
617763
char *zLink;
618764
if( zCI ){
619
- zLink = href("%R/artifact/%s",p->zUuid);
765
+ zLink = href("%R/artifact/%.16s",p->zUuid);
620766
}else{
621767
zLink = href("%R/finfo?name=%T",p->zFullName);
622768
}
623
- @ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a>
769
+ @ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
770
+ @ %z(zLink)%h(p->zName)</a>
771
+ if( p->mtime>0 ){
772
+ char *zAge = human_readable_age(rNow - p->mtime);
773
+ @ <div class="filetreeage">%s(zAge)</div>
774
+ }
775
+ @ </div>
624776
}
625
- if( p->isLast ){
777
+ if( p->pSibling==0 ){
626778
int nClose = p->iLevel - (p->pNext ? p->pNext->iLevel : 0);
627779
while( nClose-- > 0 ){
628780
@ </ul>
629781
}
630782
}
@@ -687,16 +839,16 @@
687839
@ checkState();
688840
@ outer_ul.onclick = function(e){
689841
@ e = e || window.event;
690842
@ var a = e.target || e.srcElement;
691843
@ if( a.nodeName!='A' ) return true;
692
- @ if( a.parentNode==subdir ){
844
+ @ if( a.parentNode.parentNode==subdir ){
693845
@ toggleAll(outer_ul);
694846
@ return false;
695847
@ }
696848
@ if( !belowSubdir(a) ) return true;
697
- @ var ul = a.nextSibling;
849
+ @ var ul = a.parentNode.nextSibling;
698850
@ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
699851
@ if( !ul ) return true; /* This is a file link, not a directory */
700852
@ toggleDir(ul);
701853
@ return false;
702854
@ }
@@ -724,87 +876,115 @@
724876
}else{
725877
zClass = mprintf("file");
726878
}
727879
return zClass;
728880
}
881
+
882
+/*
883
+** SQL used to compute the age of all files in checkin :ckin whose
884
+** names match :glob
885
+*/
886
+static const char zComputeFileAgeSetup[] =
887
+@ CREATE TABLE IF NOT EXISTS temp.fileage(
888
+@ fnid INTEGER PRIMARY KEY,
889
+@ fid INTEGER,
890
+@ mid INTEGER,
891
+@ mtime DATETIME,
892
+@ pathname TEXT
893
+@ );
894
+@ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;
895
+;
896
+
897
+static const char zComputeFileAgeRun[] =
898
+@ WITH RECURSIVE
899
+@ ckin(x) AS (VALUES(:ckin) UNION ALL
900
+@ SELECT pid FROM ckin, plink WHERE cid=x AND isprim)
901
+@ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname)
902
+@ SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name
903
+@ FROM ckin, mlink, event, filename
904
+@ WHERE mlink.mid=ckin.x
905
+@ AND mlink.fnid IN (SELECT fnid FROM foci, filename
906
+@ WHERE foci.checkinID=:ckin
907
+@ AND filename.name=foci.filename
908
+@ AND filename.name GLOB :glob)
909
+@ AND filename.fnid=mlink.fnid
910
+@ AND event.objid=mlink.mid;
911
+;
912
+
729913
730914
/*
731915
** Look at all file containing in the version "vid". Construct a
732916
** temporary table named "fileage" that contains the file-id for each
733917
** files, the pathname, the check-in where the file was added, and the
734918
** mtime on that checkin. If zGlob and *zGlob then only files matching
735919
** the given glob are computed.
736920
*/
737921
int compute_fileage(int vid, const char* zGlob){
738
- Manifest *pManifest;
739
- ManifestFile *pFile;
740
- int nFile = 0;
741
- double vmtime;
742
- Stmt ins;
743
- Stmt q1, q2, q3;
744
- Stmt upd;
745
- if(zGlob && !*zGlob) zGlob = NULL;
746
- db_multi_exec(
747
- /*"DROP TABLE IF EXISTS temp.fileage;"*/
748
- "CREATE TEMP TABLE fileage("
749
- " fid INTEGER,"
750
- " mid INTEGER,"
751
- " mtime DATETIME,"
752
- " pathname TEXT"
753
- ");"
754
- "CREATE INDEX fileage_fid ON fileage(fid);"
755
- );
756
- pManifest = manifest_get(vid, CFTYPE_MANIFEST, 0);
757
- if( pManifest==0 ) return 1;
758
- manifest_file_rewind(pManifest);
759
- db_prepare(&ins,
760
- "INSERT INTO temp.fileage(fid, pathname)"
761
- " SELECT rid, :path FROM blob WHERE uuid=:uuid"
762
- );
763
- while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764
- if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
765
- db_bind_text(&ins, ":uuid", pFile->zUuid);
766
- db_bind_text(&ins, ":path", pFile->zName);
767
- db_step(&ins);
768
- db_reset(&ins);
769
- nFile++;
770
- }
771
- db_finalize(&ins);
772
- manifest_destroy(pManifest);
773
- db_prepare(&q1,"SELECT fid FROM mlink WHERE mid=:mid");
774
- db_prepare(&upd, "UPDATE fileage SET mid=:mid, mtime=:vmtime"
775
- " WHERE fid=:fid AND mid IS NULL");
776
- db_prepare(&q2,"SELECT pid FROM plink WHERE cid=:vid AND isprim");
777
- db_prepare(&q3,"SELECT mtime FROM event WHERE objid=:vid");
778
- while( nFile>0 && vid>0 ){
779
- db_bind_int(&q3, ":vid", vid);
780
- if( db_step(&q3)==SQLITE_ROW ){
781
- vmtime = db_column_double(&q3, 0);
782
- }else{
783
- break;
784
- }
785
- db_reset(&q3);
786
- db_bind_int(&q1, ":mid", vid);
787
- db_bind_int(&upd, ":mid", vid);
788
- db_bind_double(&upd, ":vmtime", vmtime);
789
- while( db_step(&q1)==SQLITE_ROW ){
790
- db_bind_int(&upd, ":fid", db_column_int(&q1, 0));
791
- db_step(&upd);
792
- nFile -= db_changes();
793
- db_reset(&upd);
794
- }
795
- db_reset(&q1);
796
- db_bind_int(&q2, ":vid", vid);
797
- if( db_step(&q2)!=SQLITE_ROW ) break;
798
- vid = db_column_int(&q2, 0);
799
- db_reset(&q2);
800
- }
801
- db_finalize(&q1);
802
- db_finalize(&upd);
803
- db_finalize(&q2);
804
- db_finalize(&q3);
805
- return 0;
922
+ Stmt q;
923
+ db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/);
924
+ db_prepare(&q, zComputeFileAgeRun /*works-like:"constant"*/);
925
+ db_bind_int(&q, ":ckin", vid);
926
+ db_bind_text(&q, ":glob", zGlob && zGlob[0] ? zGlob : "*");
927
+ db_exec(&q);
928
+ db_finalize(&q);
929
+ return 0;
930
+}
931
+
932
+/*
933
+** Render the number of days in rAge as a more human-readable time span.
934
+** Different units (seconds, minutes, hours, days, months, years) are
935
+** selected depending on the magnitude of rAge.
936
+**
937
+** The string returned is obtained from fossil_malloc() and should be
938
+** freed by the caller.
939
+*/
940
+char *human_readable_age(double rAge){
941
+ if( rAge*86400.0<120 ){
942
+ if( rAge*86400.0<1.0 ){
943
+ return mprintf("current");
944
+ }else{
945
+ return mprintf("%d seconds", (int)(rAge*86400.0));
946
+ }
947
+ }else if( rAge*1440.0<90 ){
948
+ return mprintf("%.1f minutes", rAge*1440.0);
949
+ }else if( rAge*24.0<36 ){
950
+ return mprintf("%.1f hours", rAge*24.0);
951
+ }else if( rAge<365.0 ){
952
+ return mprintf("%.1f days", rAge);
953
+ }else{
954
+ return mprintf("%.2f years", rAge/365.0);
955
+ }
956
+}
957
+
958
+/*
959
+** COMMAND: test-fileage
960
+**
961
+** Usage: %fossil test-fileage CHECKIN
962
+*/
963
+void test_fileage_cmd(void){
964
+ int mid;
965
+ Stmt q;
966
+ const char *zGlob = find_option("glob",0,1);
967
+ db_find_and_open_repository(0,0);
968
+ verify_all_options();
969
+ if( g.argc!=3 ) usage("test-fileage CHECKIN");
970
+ mid = name_to_typed_rid(g.argv[2],"ci");
971
+ compute_fileage(mid, zGlob);
972
+ db_prepare(&q,
973
+ "SELECT fid, mid, julianday('now') - mtime, pathname"
974
+ " FROM fileage"
975
+ );
976
+ while( db_step(&q)==SQLITE_ROW ){
977
+ char *zAge = human_readable_age(db_column_double(&q,2));
978
+ fossil_print("%8d %8d %16s %s\n",
979
+ db_column_int(&q,0),
980
+ db_column_int(&q,1),
981
+ zAge,
982
+ db_column_text(&q,3));
983
+ fossil_free(zAge);
984
+ }
985
+ db_finalize(&q);
806986
}
807987
808988
/*
809989
** WEBPAGE: fileage
810990
**
@@ -814,72 +994,94 @@
814994
** (e.g. *.c or *.txt).
815995
*/
816996
void fileage_page(void){
817997
int rid;
818998
const char *zName;
819
- char *zBaseTime;
820999
const char *zGlob;
821
- Stmt q;
1000
+ const char *zUuid;
1001
+ const char *zNow; /* Time of checkin */
1002
+ Stmt q1, q2;
8221003
double baseTime;
823
- int lastMid = -1;
8241004
login_check_credentials();
8251005
if( !g.perm.Read ){ login_needed(); return; }
8261006
zName = P("name");
8271007
if( zName==0 ) zName = "tip";
8281008
rid = symbolic_name_to_rid(zName, "ci");
8291009
if( rid==0 ){
8301010
fossil_fatal("not a valid check-in: %s", zName);
8311011
}
832
- style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
1012
+ zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1013
+ baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
1014
+ zNow = db_text("", "SELECT datetime(mtime,'localtime') FROM event"
1015
+ " WHERE objid=%d", rid);
1016
+ style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T&mtime=1",
1017
+ zName);
8331018
style_header("File Ages");
8341019
zGlob = P("glob");
8351020
compute_fileage(rid,zGlob);
836
- baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837
- zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838
- @ <h2>File Ages For Check-in
839
- @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
840
- @
841
- @ <p>The times given are relative to
842
- @ %z(href("%R/timeline?c=%T",zBaseTime))%s(zBaseTime)</a>, which is the
843
- @ check-in time for
844
- @ %z(href("%R/info?name=%T",zName))%h(zName)</a></p>
845
- @
846
- @ <table border=0 cellspacing=0 cellpadding=0>
847
- db_prepare(&q,
848
- "SELECT mtime, (SELECT uuid FROM blob WHERE rid=fid), mid, pathname"
849
- " FROM fileage"
850
- " ORDER BY mtime DESC, mid, pathname"
851
- );
852
- while( db_step(&q)==SQLITE_ROW ){
853
- double age = baseTime - db_column_double(&q, 0);
854
- int mid = db_column_int(&q, 2);
855
- const char *zFUuid = db_column_text(&q, 1);
856
- char zAge[200];
857
- if( lastMid!=mid ){
858
- @ <tr><td colspan=3><hr></tr>
859
- lastMid = mid;
860
- if( age*86400.0<120 ){
861
- sqlite3_snprintf(sizeof(zAge), zAge, "%d seconds", (int)(age*86400.0));
862
- }else if( age*1440.0<90 ){
863
- sqlite3_snprintf(sizeof(zAge), zAge, "%.1f minutes", age*1440.0);
864
- }else if( age*24.0<36 ){
865
- sqlite3_snprintf(sizeof(zAge), zAge, "%.1f hours", age*24.0);
866
- }else if( age<365.0 ){
867
- sqlite3_snprintf(sizeof(zAge), zAge, "%.1f days", age);
868
- }else{
869
- sqlite3_snprintf(sizeof(zAge), zAge, "%.2f years", age/365.0);
870
- }
871
- }else{
872
- zAge[0] = 0;
873
- }
874
- @ <tr>
875
- @ <td>%s(zAge)
876
- @ <td width="25">
877
- @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a>
878
- @ </tr>
879
- @
880
- }
881
- @ <tr><td colspan=3><hr></tr>
882
- @ </table>
883
- db_finalize(&q);
1021
+ db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
1022
+
1023
+ @ <h2>Files in
1024
+ @ %z(href("%R/info?name=%T",zUuid))[%S(zUuid)]</a>
1025
+ if( zGlob && zGlob[0] ){
1026
+ @ that match "%h(zGlob)" and
1027
+ }
1028
+ @ ordered by check-in time</h2>
1029
+ @
1030
+ @ <p>Times are relative to the checkin time for
1031
+ @ %z(href("%R/ci/%s",zUuid))[%S(zUuid)]</a> which is
1032
+ @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
1033
+ @
1034
+ @ <div class='fileage'><table>
1035
+ @ <tr><th>Time</th><th>Files</th><th>Checkin</th></tr>
1036
+ db_prepare(&q1,
1037
+ "SELECT event.mtime, event.objid, blob.uuid,\n"
1038
+ " coalesce(event.ecomment,event.comment),\n"
1039
+ " coalesce(event.euser,event.user),\n"
1040
+ " coalesce((SELECT value FROM tagxref\n"
1041
+ " WHERE tagtype>0 AND tagid=%d\n"
1042
+ " AND rid=event.objid),'trunk')\n"
1043
+ " FROM event, blob\n"
1044
+ " WHERE event.objid IN (SELECT mid FROM fileage)\n"
1045
+ " AND blob.rid=event.objid\n"
1046
+ " ORDER BY event.mtime DESC;",
1047
+ TAG_BRANCH
1048
+ );
1049
+ db_prepare(&q2,
1050
+ "SELECT blob.uuid, filename.name\n"
1051
+ " FROM fileage, blob, filename\n"
1052
+ " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
1053
+ " AND blob.rid=fileage.fid;"
1054
+ );
1055
+ while( db_step(&q1)==SQLITE_ROW ){
1056
+ double age = baseTime - db_column_double(&q1, 0);
1057
+ int mid = db_column_int(&q1, 1);
1058
+ const char *zUuid = db_column_text(&q1, 2);
1059
+ const char *zComment = db_column_text(&q1, 3);
1060
+ const char *zUser = db_column_text(&q1, 4);
1061
+ const char *zBranch = db_column_text(&q1, 5);
1062
+ char *zAge = human_readable_age(age);
1063
+ @ <tr><td>%s(zAge)</td>
1064
+ @ <td>
1065
+ db_bind_int(&q2, ":mid", mid);
1066
+ while( db_step(&q2)==SQLITE_ROW ){
1067
+ const char *zFUuid = db_column_text(&q2,0);
1068
+ const char *zFile = db_column_text(&q2,1);
1069
+ @ %z(href("%R/artifact/%s",zFUuid))%h(zFile)</a><br>
1070
+ }
1071
+ db_reset(&q2);
1072
+ @ </td>
1073
+ @ <td>
1074
+ @ %z(href("%R/info/%s",zUuid))[%S(zUuid)]</a>
1075
+ @ %W(zComment) (user:
1076
+ @ %z(href("%R/timeline?u=%t&c=%t&nd&n=200",zUser,zUuid))%h(zUser)</a>,
1077
+ @ branch:
1078
+ @ %z(href("%R/timeline?r=%t&c=%t&nd&n=200",zBranch,zUuid))%h(zBranch)</a>)
1079
+ @ </td></tr>
1080
+ @
1081
+ fossil_free(zAge);
1082
+ }
1083
+ @ </table></div>
1084
+ db_finalize(&q1);
1085
+ db_finalize(&q2);
8841086
style_footer();
8851087
}
8861088
8871089
ADDED src/bundle.c
--- src/browse.c
+++ src/browse.c
@@ -304,89 +304,206 @@
304
305 /*
306 ** A single line of the file hierarchy
307 */
308 struct FileTreeNode {
309 FileTreeNode *pNext; /* Next line in sequence */
310 FileTreeNode *pPrev; /* Previous line */
311 FileTreeNode *pParent; /* Directory containing this line */
 
 
312 char *zName; /* Name of this entry. The "tail" */
313 char *zFullName; /* Full pathname of this entry */
314 char *zUuid; /* SHA1 hash of this file. May be NULL. */
 
315 unsigned nFullName; /* Length of zFullName */
316 unsigned iLevel; /* Levels of parent directories */
317 u8 isDir; /* True if there are children */
318 u8 isLast; /* True if this is the last child of its parent */
319 };
320
321 /*
322 ** A complete file hierarchy
323 */
324 struct FileTree {
325 FileTreeNode *pFirst; /* First line of the list */
326 FileTreeNode *pLast; /* Last line of the list */
 
327 };
328
329 /*
330 ** Add one or more new FileTreeNodes to the FileTree object so that the
331 ** leaf object zPathname is at the end of the node list
 
 
 
 
 
 
 
 
332 */
333 static void tree_add_node(
334 FileTree *pTree, /* Tree into which nodes are added */
335 const char *zPath, /* The full pathname of file to add */
336 const char *zUuid /* UUID of the file. Might be NULL. */
 
337 ){
338 int i;
339 FileTreeNode *pParent;
340 FileTreeNode *pChild;
341
342 pChild = pTree->pLast;
343 pParent = pChild ? pChild->pParent : 0;
 
 
344 while( pParent!=0 &&
345 ( strncmp(pParent->zFullName, zPath, pParent->nFullName)!=0
346 || zPath[pParent->nFullName]!='/' )
347 ){
348 pChild = pParent;
349 pParent = pChild->pParent;
350 }
351 i = pParent ? pParent->nFullName+1 : 0;
352 if( pChild ) pChild->isLast = 0;
353 while( zPath[i] ){
354 FileTreeNode *pNew;
355 int iStart = i;
356 int nByte;
357 while( zPath[i] && zPath[i]!='/' ){ i++; }
358 nByte = sizeof(*pNew) + i + 1;
359 if( zUuid!=0 && zPath[i]==0 ) nByte += UUID_SIZE+1;
360 pNew = fossil_malloc( nByte );
 
361 pNew->zFullName = (char*)&pNew[1];
362 memcpy(pNew->zFullName, zPath, i);
363 pNew->zFullName[i] = 0;
364 pNew->nFullName = i;
365 if( zUuid!=0 && zPath[i]==0 ){
366 pNew->zUuid = pNew->zFullName + i + 1;
367 memcpy(pNew->zUuid, zUuid, UUID_SIZE+1);
368 }else{
369 pNew->zUuid = 0;
370 }
371 pNew->zName = pNew->zFullName + iStart;
372 if( pTree->pLast ){
373 pTree->pLast->pNext = pNew;
374 }else{
375 pTree->pFirst = pNew;
376 }
377 pNew->pPrev = pTree->pLast;
378 pNew->pNext = 0;
379 pNew->pParent = pParent;
380 pTree->pLast = pNew;
381 pNew->iLevel = pParent ? pParent->iLevel+1 : 0;
382 pNew->isDir = zPath[i]=='/';
383 pNew->isLast = 1;
 
 
 
 
 
 
 
 
 
384 while( zPath[i]=='/' ){ i++; }
385 pParent = pNew;
386 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387 }
 
388
389 /*
390 ** WEBPAGE: tree
391 **
392 ** Query parameters:
@@ -394,19 +511,23 @@
394 ** name=PATH Directory to display. Optional
395 ** ci=LABEL Show only files in this check-in. Optional.
396 ** re=REGEXP Show only files matching REGEXP. Optional.
397 ** expand Begin with the tree fully expanded.
398 ** nofiles Show directories (folders) only. Omit files.
 
399 */
400 void page_tree(void){
401 char *zD = fossil_strdup(P("name"));
402 int nD = zD ? strlen(zD)+1 : 0;
403 const char *zCI = P("ci");
404 int rid = 0;
405 char *zUuid = 0;
406 Blob dirname;
407 Manifest *pM = 0;
 
 
 
408 int nFile = 0; /* Number of files (or folders with "nofiles") */
409 int linkTrunk = 1; /* include link to "trunk" */
410 int linkTip = 1; /* include link to "tip" */
411 const char *zRE; /* the value for the re=REGEXP query parameter */
412 const char *zObjType; /* "files" by default or "folders" for "nofiles" */
@@ -464,14 +585,21 @@
464 int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
465 linkTrunk = trunkRid && rid != trunkRid;
466 linkTip = rid != symbolic_name_to_rid("tip", "ci");
467 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
468 url_add_parameter(&sURI, "ci", zCI);
 
 
 
469 }else{
470 zCI = 0;
471 }
472 }
 
 
 
 
473
474 /* Compute the title of the page */
475 blob_zero(&dirname);
476 if( zD ){
477 url_add_parameter(&sURI, "name", zD);
@@ -483,10 +611,18 @@
483 }else{
484 if( zRE ){
485 blob_appendf(&dirname, "matching \"%s\"", zRE);
486 }
487 }
 
 
 
 
 
 
 
 
488 if( zCI ){
489 style_submenu_element("All", "All", "%s",
490 url_render(&sURI, "ci", 0, 0, 0));
491 if( nD==0 && !showDirOnly ){
492 style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s",
@@ -499,87 +635,82 @@
499 }
500 if( linkTip ){
501 style_submenu_element("Tip", "Tip", "%s",
502 url_render(&sURI, "ci", "tip", 0, 0));
503 }
504 if( !showDirOnly ){
505 style_submenu_element("Flat-View", "Flat-View", "%s",
506 url_render(&sURI, "type", "flat", 0, 0));
507 }
508
509 /* Compute the file hierarchy.
510 */
511 if( zCI ){
512 Stmt ins, q;
513 ManifestFile *pFile;
514
515 db_multi_exec(
516 "CREATE TEMP TABLE filelist("
517 " x TEXT PRIMARY KEY COLLATE nocase,"
518 " uuid TEXT"
519 ") WITHOUT ROWID;"
520 );
521 db_prepare(&ins, "INSERT OR IGNORE INTO filelist VALUES(:f,:u)");
522 manifest_file_rewind(pM);
523 while( (pFile = manifest_file_next(pM,0))!=0 ){
524 if( nD>0
525 && (fossil_strncmp(pFile->zName, zD, nD-1)!=0
526 || pFile->zName[nD-1]!='/')
527 ){
528 continue;
529 }
530 if( pRE && re_match(pRE, (const u8*)pFile->zName, -1)==0 ) continue;
531 db_bind_text(&ins, ":f", pFile->zName);
532 db_bind_text(&ins, ":u", pFile->zUuid);
533 db_step(&ins);
534 db_reset(&ins);
535 }
536 db_finalize(&ins);
537 db_prepare(&q, "SELECT x, uuid FROM filelist ORDER BY x");
538 while( db_step(&q)==SQLITE_ROW ){
539 tree_add_node(&sTree, db_column_text(&q,0), db_column_text(&q,1));
 
 
 
 
540 nFile++;
541 }
542 db_finalize(&q);
543 }else{
544 Stmt q;
545 db_prepare(&q, "SELECT name FROM filename ORDER BY name COLLATE nocase");
 
 
 
 
 
 
546 while( db_step(&q)==SQLITE_ROW ){
547 const char *z = db_column_text(&q, 0);
548 if( nD>0 && (fossil_strncmp(z, zD, nD-1)!=0 || z[nD-1]!='/') ){
 
 
549 continue;
550 }
551 if( pRE && re_match(pRE, (const u8*)z, -1)==0 ) continue;
552 tree_add_node(&sTree, z, 0);
553 nFile++;
554 }
555 db_finalize(&q);
556 }
557
558 if( showDirOnly ){
559 for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
560 if( p->isDir && p->nFullName>nD ) nFile++;
561 }
562 zObjType = "folders";
563 style_submenu_element("Files","Files","%s",
564 url_render(&sURI,"nofiles",0,0,0));
565 }else{
566 zObjType = "files";
567 style_submenu_element("Folders","Folders","%s",
568 url_render(&sURI,"nofiles","1",0,0));
569 }
570
571 if( zCI ){
572 @ <h2>%d(nFile) %s(zObjType) of check-in
573 if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
574 @ "%h(zCI)"
575 }
576 @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2>
577 }else{
578 int n = db_int(0, "SELECT count(*) FROM plink");
579 @ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins
580 @ %s(blob_str(&dirname))</h2>
 
 
 
 
581 }
582
583
584 /* Generate tree of lists.
585 **
@@ -596,18 +727,33 @@
596 if( nD ){
597 @ <li class="dir last">
598 }else{
599 @ <li class="dir subdir last">
600 }
 
601 @ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
 
 
 
 
602 @ <ul>
 
 
 
 
 
603 for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
604 const char *zLastClass = p->isLast ? " last" : "";
605 if( p->isDir ){
606 const char *zSubdirClass = p->nFullName==nD-1 ? " subdir" : "";
607 @ <li class="dir%s(zSubdirClass)%s(zLastClass)">
608 @ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
 
 
 
 
 
609 if( startExpanded || p->nFullName<=nD ){
610 @ <ul id="dir%d(nDir)">
611 }else{
612 @ <ul id="dir%d(nDir)" class="collapsed">
613 }
@@ -614,17 +760,23 @@
614 nDir++;
615 }else if( !showDirOnly ){
616 const char *zFileClass = fileext_class(p->zName);
617 char *zLink;
618 if( zCI ){
619 zLink = href("%R/artifact/%s",p->zUuid);
620 }else{
621 zLink = href("%R/finfo?name=%T",p->zFullName);
622 }
623 @ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a>
 
 
 
 
 
 
624 }
625 if( p->isLast ){
626 int nClose = p->iLevel - (p->pNext ? p->pNext->iLevel : 0);
627 while( nClose-- > 0 ){
628 @ </ul>
629 }
630 }
@@ -687,16 +839,16 @@
687 @ checkState();
688 @ outer_ul.onclick = function(e){
689 @ e = e || window.event;
690 @ var a = e.target || e.srcElement;
691 @ if( a.nodeName!='A' ) return true;
692 @ if( a.parentNode==subdir ){
693 @ toggleAll(outer_ul);
694 @ return false;
695 @ }
696 @ if( !belowSubdir(a) ) return true;
697 @ var ul = a.nextSibling;
698 @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
699 @ if( !ul ) return true; /* This is a file link, not a directory */
700 @ toggleDir(ul);
701 @ return false;
702 @ }
@@ -724,87 +876,115 @@
724 }else{
725 zClass = mprintf("file");
726 }
727 return zClass;
728 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
729
730 /*
731 ** Look at all file containing in the version "vid". Construct a
732 ** temporary table named "fileage" that contains the file-id for each
733 ** files, the pathname, the check-in where the file was added, and the
734 ** mtime on that checkin. If zGlob and *zGlob then only files matching
735 ** the given glob are computed.
736 */
737 int compute_fileage(int vid, const char* zGlob){
738 Manifest *pManifest;
739 ManifestFile *pFile;
740 int nFile = 0;
741 double vmtime;
742 Stmt ins;
743 Stmt q1, q2, q3;
744 Stmt upd;
745 if(zGlob && !*zGlob) zGlob = NULL;
746 db_multi_exec(
747 /*"DROP TABLE IF EXISTS temp.fileage;"*/
748 "CREATE TEMP TABLE fileage("
749 " fid INTEGER,"
750 " mid INTEGER,"
751 " mtime DATETIME,"
752 " pathname TEXT"
753 ");"
754 "CREATE INDEX fileage_fid ON fileage(fid);"
755 );
756 pManifest = manifest_get(vid, CFTYPE_MANIFEST, 0);
757 if( pManifest==0 ) return 1;
758 manifest_file_rewind(pManifest);
759 db_prepare(&ins,
760 "INSERT INTO temp.fileage(fid, pathname)"
761 " SELECT rid, :path FROM blob WHERE uuid=:uuid"
762 );
763 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
764 if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
765 db_bind_text(&ins, ":uuid", pFile->zUuid);
766 db_bind_text(&ins, ":path", pFile->zName);
767 db_step(&ins);
768 db_reset(&ins);
769 nFile++;
770 }
771 db_finalize(&ins);
772 manifest_destroy(pManifest);
773 db_prepare(&q1,"SELECT fid FROM mlink WHERE mid=:mid");
774 db_prepare(&upd, "UPDATE fileage SET mid=:mid, mtime=:vmtime"
775 " WHERE fid=:fid AND mid IS NULL");
776 db_prepare(&q2,"SELECT pid FROM plink WHERE cid=:vid AND isprim");
777 db_prepare(&q3,"SELECT mtime FROM event WHERE objid=:vid");
778 while( nFile>0 && vid>0 ){
779 db_bind_int(&q3, ":vid", vid);
780 if( db_step(&q3)==SQLITE_ROW ){
781 vmtime = db_column_double(&q3, 0);
782 }else{
783 break;
784 }
785 db_reset(&q3);
786 db_bind_int(&q1, ":mid", vid);
787 db_bind_int(&upd, ":mid", vid);
788 db_bind_double(&upd, ":vmtime", vmtime);
789 while( db_step(&q1)==SQLITE_ROW ){
790 db_bind_int(&upd, ":fid", db_column_int(&q1, 0));
791 db_step(&upd);
792 nFile -= db_changes();
793 db_reset(&upd);
794 }
795 db_reset(&q1);
796 db_bind_int(&q2, ":vid", vid);
797 if( db_step(&q2)!=SQLITE_ROW ) break;
798 vid = db_column_int(&q2, 0);
799 db_reset(&q2);
800 }
801 db_finalize(&q1);
802 db_finalize(&upd);
803 db_finalize(&q2);
804 db_finalize(&q3);
805 return 0;
806 }
807
808 /*
809 ** WEBPAGE: fileage
810 **
@@ -814,72 +994,94 @@
814 ** (e.g. *.c or *.txt).
815 */
816 void fileage_page(void){
817 int rid;
818 const char *zName;
819 char *zBaseTime;
820 const char *zGlob;
821 Stmt q;
 
 
822 double baseTime;
823 int lastMid = -1;
824 login_check_credentials();
825 if( !g.perm.Read ){ login_needed(); return; }
826 zName = P("name");
827 if( zName==0 ) zName = "tip";
828 rid = symbolic_name_to_rid(zName, "ci");
829 if( rid==0 ){
830 fossil_fatal("not a valid check-in: %s", zName);
831 }
832 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);
 
 
 
 
 
833 style_header("File Ages");
834 zGlob = P("glob");
835 compute_fileage(rid,zGlob);
836 baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
837 zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
838 @ <h2>File Ages For Check-in
839 @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
840 @
841 @ <p>The times given are relative to
842 @ %z(href("%R/timeline?c=%T",zBaseTime))%s(zBaseTime)</a>, which is the
843 @ check-in time for
844 @ %z(href("%R/info?name=%T",zName))%h(zName)</a></p>
845 @
846 @ <table border=0 cellspacing=0 cellpadding=0>
847 db_prepare(&q,
848 "SELECT mtime, (SELECT uuid FROM blob WHERE rid=fid), mid, pathname"
849 " FROM fileage"
850 " ORDER BY mtime DESC, mid, pathname"
851 );
852 while( db_step(&q)==SQLITE_ROW ){
853 double age = baseTime - db_column_double(&q, 0);
854 int mid = db_column_int(&q, 2);
855 const char *zFUuid = db_column_text(&q, 1);
856 char zAge[200];
857 if( lastMid!=mid ){
858 @ <tr><td colspan=3><hr></tr>
859 lastMid = mid;
860 if( age*86400.0<120 ){
861 sqlite3_snprintf(sizeof(zAge), zAge, "%d seconds", (int)(age*86400.0));
862 }else if( age*1440.0<90 ){
863 sqlite3_snprintf(sizeof(zAge), zAge, "%.1f minutes", age*1440.0);
864 }else if( age*24.0<36 ){
865 sqlite3_snprintf(sizeof(zAge), zAge, "%.1f hours", age*24.0);
866 }else if( age<365.0 ){
867 sqlite3_snprintf(sizeof(zAge), zAge, "%.1f days", age);
868 }else{
869 sqlite3_snprintf(sizeof(zAge), zAge, "%.2f years", age/365.0);
870 }
871 }else{
872 zAge[0] = 0;
873 }
874 @ <tr>
875 @ <td>%s(zAge)
876 @ <td width="25">
877 @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a>
878 @ </tr>
879 @
880 }
881 @ <tr><td colspan=3><hr></tr>
882 @ </table>
883 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
884 style_footer();
885 }
886
887 DDED src/bundle.c
--- src/browse.c
+++ src/browse.c
@@ -304,89 +304,206 @@
304
305 /*
306 ** A single line of the file hierarchy
307 */
308 struct FileTreeNode {
309 FileTreeNode *pNext; /* Next entry in an ordered list of them all */
310 FileTreeNode *pParent; /* Directory containing this entry */
311 FileTreeNode *pSibling; /* Next element in the same subdirectory */
312 FileTreeNode *pChild; /* List of child nodes */
313 FileTreeNode *pLastChild; /* Last child on the pChild list */
314 char *zName; /* Name of this entry. The "tail" */
315 char *zFullName; /* Full pathname of this entry */
316 char *zUuid; /* SHA1 hash of this file. May be NULL. */
317 double mtime; /* Modification time for this entry */
318 unsigned nFullName; /* Length of zFullName */
319 unsigned iLevel; /* Levels of parent directories */
 
 
320 };
321
322 /*
323 ** A complete file hierarchy
324 */
325 struct FileTree {
326 FileTreeNode *pFirst; /* First line of the list */
327 FileTreeNode *pLast; /* Last line of the list */
328 FileTreeNode *pLastTop; /* Last top-level node */
329 };
330
331 /*
332 ** Add one or more new FileTreeNodes to the FileTree object so that the
333 ** leaf object zPathname is at the end of the node list.
334 **
335 ** The caller invokes this routine once for each leaf node (each file
336 ** as opposed to each directory). This routine fills in any missing
337 ** intermediate nodes automatically.
338 **
339 ** When constructing a list of FileTreeNodes, all entries that have
340 ** a common directory prefix must be added consecutively in order for
341 ** the tree to be constructed properly.
342 */
343 static void tree_add_node(
344 FileTree *pTree, /* Tree into which nodes are added */
345 const char *zPath, /* The full pathname of file to add */
346 const char *zUuid, /* UUID of the file. Might be NULL. */
347 double mtime /* Modification time for this entry */
348 ){
349 int i;
350 FileTreeNode *pParent; /* Parent (directory) of the next node to insert */
 
351
352 /* Make pParent point to the most recent ancestor of zPath, or
353 ** NULL if there are no prior entires that are a container for zPath.
354 */
355 pParent = pTree->pLast;
356 while( pParent!=0 &&
357 ( strncmp(pParent->zFullName, zPath, pParent->nFullName)!=0
358 || zPath[pParent->nFullName]!='/' )
359 ){
360 pParent = pParent->pParent;
 
361 }
362 i = pParent ? pParent->nFullName+1 : 0;
 
363 while( zPath[i] ){
364 FileTreeNode *pNew;
365 int iStart = i;
366 int nByte;
367 while( zPath[i] && zPath[i]!='/' ){ i++; }
368 nByte = sizeof(*pNew) + i + 1;
369 if( zUuid!=0 && zPath[i]==0 ) nByte += UUID_SIZE+1;
370 pNew = fossil_malloc( nByte );
371 memset(pNew, 0, sizeof(*pNew));
372 pNew->zFullName = (char*)&pNew[1];
373 memcpy(pNew->zFullName, zPath, i);
374 pNew->zFullName[i] = 0;
375 pNew->nFullName = i;
376 if( zUuid!=0 && zPath[i]==0 ){
377 pNew->zUuid = pNew->zFullName + i + 1;
378 memcpy(pNew->zUuid, zUuid, UUID_SIZE+1);
 
 
379 }
380 pNew->zName = pNew->zFullName + iStart;
381 if( pTree->pLast ){
382 pTree->pLast->pNext = pNew;
383 }else{
384 pTree->pFirst = pNew;
385 }
386 pTree->pLast = pNew;
 
387 pNew->pParent = pParent;
388 if( pParent ){
389 if( pParent->pChild ){
390 pParent->pLastChild->pSibling = pNew;
391 }else{
392 pParent->pChild = pNew;
393 }
394 pNew->iLevel = pParent->iLevel + 1;
395 pParent->pLastChild = pNew;
396 }else{
397 if( pTree->pLastTop ) pTree->pLastTop->pSibling = pNew;
398 pTree->pLastTop = pNew;
399 }
400 pNew->mtime = mtime;
401 while( zPath[i]=='/' ){ i++; }
402 pParent = pNew;
403 }
404 while( pParent && pParent->pParent ){
405 if( pParent->pParent->mtime < pParent->mtime ){
406 pParent->pParent->mtime = pParent->mtime;
407 }
408 pParent = pParent->pParent;
409 }
410 }
411
412 /* Comparison function for two FileTreeNode objects. Sort first by
413 ** mtime (larger numbers first) and then by zName (smaller names first).
414 **
415 ** Return negative if pLeft<pRight.
416 ** Return positive if pLeft>pRight.
417 ** Return zero if pLeft==pRight.
418 */
419 static int compareNodes(FileTreeNode *pLeft, FileTreeNode *pRight){
420 if( pLeft->mtime>pRight->mtime ) return -1;
421 if( pLeft->mtime<pRight->mtime ) return +1;
422 return fossil_stricmp(pLeft->zName, pRight->zName);
423 }
424
425 /* Merge together two sorted lists of FileTreeNode objects */
426 static FileTreeNode *mergeNodes(FileTreeNode *pLeft, FileTreeNode *pRight){
427 FileTreeNode *pEnd;
428 FileTreeNode base;
429 pEnd = &base;
430 while( pLeft && pRight ){
431 if( compareNodes(pLeft,pRight)<=0 ){
432 pEnd = pEnd->pSibling = pLeft;
433 pLeft = pLeft->pSibling;
434 }else{
435 pEnd = pEnd->pSibling = pRight;
436 pRight = pRight->pSibling;
437 }
438 }
439 if( pLeft ){
440 pEnd->pSibling = pLeft;
441 }else{
442 pEnd->pSibling = pRight;
443 }
444 return base.pSibling;
445 }
446
447 /* Sort a list of FileTreeNode objects in mtime order. */
448 static FileTreeNode *sortNodesByMtime(FileTreeNode *p){
449 FileTreeNode *a[30];
450 FileTreeNode *pX;
451 int i;
452
453 memset(a, 0, sizeof(a));
454 while( p ){
455 pX = p;
456 p = pX->pSibling;
457 pX->pSibling = 0;
458 for(i=0; i<count(a)-1 && a[i]!=0; i++){
459 pX = mergeNodes(a[i], pX);
460 a[i] = 0;
461 }
462 a[i] = mergeNodes(a[i], pX);
463 }
464 pX = 0;
465 for(i=0; i<count(a); i++){
466 pX = mergeNodes(a[i], pX);
467 }
468 return pX;
469 }
470
471 /* Sort an entire FileTreeNode tree by mtime
472 **
473 ** This routine invalidates the following fields:
474 **
475 ** FileTreeNode.pLastChild
476 ** FileTreeNode.pNext
477 **
478 ** Use relinkTree to reconnect the pNext pointers.
479 */
480 static FileTreeNode *sortTreeByMtime(FileTreeNode *p){
481 FileTreeNode *pX;
482 for(pX=p; pX; pX=pX->pSibling){
483 if( pX->pChild ) pX->pChild = sortTreeByMtime(pX->pChild);
484 }
485 return sortNodesByMtime(p);
486 }
487
488 /* Reconstruct the FileTree by reconnecting the FileTreeNode.pNext
489 ** fields in sequential order.
490 */
491 static void relinkTree(FileTree *pTree, FileTreeNode *pRoot){
492 while( pRoot ){
493 if( pTree->pLast ){
494 pTree->pLast->pNext = pRoot;
495 }else{
496 pTree->pFirst = pRoot;
497 }
498 pTree->pLast = pRoot;
499 if( pRoot->pChild ) relinkTree(pTree, pRoot->pChild);
500 pRoot = pRoot->pSibling;
501 }
502 if( pTree->pLast ) pTree->pLast->pNext = 0;
503 }
504
505
506 /*
507 ** WEBPAGE: tree
508 **
509 ** Query parameters:
@@ -394,19 +511,23 @@
511 ** name=PATH Directory to display. Optional
512 ** ci=LABEL Show only files in this check-in. Optional.
513 ** re=REGEXP Show only files matching REGEXP. Optional.
514 ** expand Begin with the tree fully expanded.
515 ** nofiles Show directories (folders) only. Omit files.
516 ** mtime Order directory elements by decreasing mtime
517 */
518 void page_tree(void){
519 char *zD = fossil_strdup(P("name"));
520 int nD = zD ? strlen(zD)+1 : 0;
521 const char *zCI = P("ci");
522 int rid = 0;
523 char *zUuid = 0;
524 Blob dirname;
525 Manifest *pM = 0;
526 double rNow = 0;
527 char *zNow = 0;
528 int useMtime = atoi(PD("mtime","0"));
529 int nFile = 0; /* Number of files (or folders with "nofiles") */
530 int linkTrunk = 1; /* include link to "trunk" */
531 int linkTip = 1; /* include link to "tip" */
532 const char *zRE; /* the value for the re=REGEXP query parameter */
533 const char *zObjType; /* "files" by default or "folders" for "nofiles" */
@@ -464,14 +585,21 @@
585 int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
586 linkTrunk = trunkRid && rid != trunkRid;
587 linkTip = rid != symbolic_name_to_rid("tip", "ci");
588 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
589 url_add_parameter(&sURI, "ci", zCI);
590 rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
591 zNow = db_text("", "SELECT datetime(mtime,'localtime')"
592 " FROM event WHERE objid=%d", rid);
593 }else{
594 zCI = 0;
595 }
596 }
597 if( zCI==0 ){
598 rNow = db_double(0.0, "SELECT max(mtime) FROM event");
599 zNow = db_text("", "SELECT datetime(max(mtime),'localtime') FROM event");
600 }
601
602 /* Compute the title of the page */
603 blob_zero(&dirname);
604 if( zD ){
605 url_add_parameter(&sURI, "name", zD);
@@ -483,10 +611,18 @@
611 }else{
612 if( zRE ){
613 blob_appendf(&dirname, "matching \"%s\"", zRE);
614 }
615 }
616 if( useMtime ){
617 style_submenu_element("Sort By Filename","Sort By Filename", "%s",
618 url_render(&sURI, 0, 0, 0, 0));
619 url_add_parameter(&sURI, "mtime", "1");
620 }else{
621 style_submenu_element("Sort By Time","Sort By Time", "%s",
622 url_render(&sURI, "mtime", "1", 0, 0));
623 }
624 if( zCI ){
625 style_submenu_element("All", "All", "%s",
626 url_render(&sURI, "ci", 0, 0, 0));
627 if( nD==0 && !showDirOnly ){
628 style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s",
@@ -499,87 +635,82 @@
635 }
636 if( linkTip ){
637 style_submenu_element("Tip", "Tip", "%s",
638 url_render(&sURI, "ci", "tip", 0, 0));
639 }
 
 
 
 
640
641 /* Compute the file hierarchy.
642 */
643 if( zCI ){
644 Stmt q;
645 compute_fileage(rid, 0);
646 db_prepare(&q,
647 "SELECT filename.name, blob.uuid, fileage.mtime\n"
648 " FROM fileage, filename, blob\n"
649 " WHERE filename.fnid=fileage.fnid\n"
650 " AND blob.rid=fileage.fid\n"
651 " ORDER BY filename.name COLLATE nocase;"
652 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653 while( db_step(&q)==SQLITE_ROW ){
654 const char *zFile = db_column_text(&q,0);
655 const char *zUuid = db_column_text(&q,1);
656 double mtime = db_column_double(&q,2);
657 if( pRE && re_match(pRE, (const unsigned char*)zFile, -1)==0 ) continue;
658 tree_add_node(&sTree, zFile, zUuid, mtime);
659 nFile++;
660 }
661 db_finalize(&q);
662 }else{
663 Stmt q;
664 db_prepare(&q,
665 "SELECT filename.name, blob.uuid, max(event.mtime)\n"
666 " FROM filename, mlink, blob, event\n"
667 " WHERE mlink.fnid=filename.fnid\n"
668 " AND event.objid=mlink.mid\n"
669 " AND blob.rid=mlink.fid\n"
670 " GROUP BY 1 ORDER BY 1 COLLATE nocase");
671 while( db_step(&q)==SQLITE_ROW ){
672 const char *zName = db_column_text(&q, 0);
673 const char *zUuid = db_column_text(&q,1);
674 double mtime = db_column_double(&q,2);
675 if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
676 continue;
677 }
678 if( pRE && re_match(pRE, (const u8*)zName, -1)==0 ) continue;
679 tree_add_node(&sTree, zName, zUuid, mtime);
680 nFile++;
681 }
682 db_finalize(&q);
683 }
684
685 if( showDirOnly ){
686 for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
687 if( p->pChild!=0 && p->nFullName>nD ) nFile++;
688 }
689 zObjType = "Folders";
690 style_submenu_element("Files","Files","%s",
691 url_render(&sURI,"nofiles",0,0,0));
692 }else{
693 zObjType = "Files";
694 style_submenu_element("Folders","Folders","%s",
695 url_render(&sURI,"nofiles","1",0,0));
696 }
697
698 if( zCI ){
699 @ <h2>%s(zObjType) from
700 if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
701 @ "%h(zCI)"
702 }
703 @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))
704 }else{
705 int n = db_int(0, "SELECT count(*) FROM plink");
706 @ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))
707 }
708 if( useMtime ){
709 @ sorted by modification time</h2>
710 }else{
711 @ sorted by filename</h2>
712 }
713
714
715 /* Generate tree of lists.
716 **
@@ -596,18 +727,33 @@
727 if( nD ){
728 @ <li class="dir last">
729 }else{
730 @ <li class="dir subdir last">
731 }
732 @ <div class="filetreeline">
733 @ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
734 if( zNow ){
735 @ <div class="filetreeage">%s(zNow)</div>
736 }
737 @ </div>
738 @ <ul>
739 if( useMtime ){
740 p = sortTreeByMtime(sTree.pFirst);
741 memset(&sTree, 0, sizeof(sTree));
742 relinkTree(&sTree, p);
743 }
744 for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
745 const char *zLastClass = p->pSibling==0 ? " last" : "";
746 if( p->pChild ){
747 const char *zSubdirClass = p->nFullName==nD-1 ? " subdir" : "";
748 @ <li class="dir%s(zSubdirClass)%s(zLastClass)"><div class="filetreeline">
749 @ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
750 if( p->mtime>0.0 ){
751 char *zAge = human_readable_age(rNow - p->mtime);
752 @ <div class="filetreeage">%s(zAge)</div>
753 }
754 @ </div>
755 if( startExpanded || p->nFullName<=nD ){
756 @ <ul id="dir%d(nDir)">
757 }else{
758 @ <ul id="dir%d(nDir)" class="collapsed">
759 }
@@ -614,17 +760,23 @@
760 nDir++;
761 }else if( !showDirOnly ){
762 const char *zFileClass = fileext_class(p->zName);
763 char *zLink;
764 if( zCI ){
765 zLink = href("%R/artifact/%.16s",p->zUuid);
766 }else{
767 zLink = href("%R/finfo?name=%T",p->zFullName);
768 }
769 @ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
770 @ %z(zLink)%h(p->zName)</a>
771 if( p->mtime>0 ){
772 char *zAge = human_readable_age(rNow - p->mtime);
773 @ <div class="filetreeage">%s(zAge)</div>
774 }
775 @ </div>
776 }
777 if( p->pSibling==0 ){
778 int nClose = p->iLevel - (p->pNext ? p->pNext->iLevel : 0);
779 while( nClose-- > 0 ){
780 @ </ul>
781 }
782 }
@@ -687,16 +839,16 @@
839 @ checkState();
840 @ outer_ul.onclick = function(e){
841 @ e = e || window.event;
842 @ var a = e.target || e.srcElement;
843 @ if( a.nodeName!='A' ) return true;
844 @ if( a.parentNode.parentNode==subdir ){
845 @ toggleAll(outer_ul);
846 @ return false;
847 @ }
848 @ if( !belowSubdir(a) ) return true;
849 @ var ul = a.parentNode.nextSibling;
850 @ while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
851 @ if( !ul ) return true; /* This is a file link, not a directory */
852 @ toggleDir(ul);
853 @ return false;
854 @ }
@@ -724,87 +876,115 @@
876 }else{
877 zClass = mprintf("file");
878 }
879 return zClass;
880 }
881
882 /*
883 ** SQL used to compute the age of all files in checkin :ckin whose
884 ** names match :glob
885 */
886 static const char zComputeFileAgeSetup[] =
887 @ CREATE TABLE IF NOT EXISTS temp.fileage(
888 @ fnid INTEGER PRIMARY KEY,
889 @ fid INTEGER,
890 @ mid INTEGER,
891 @ mtime DATETIME,
892 @ pathname TEXT
893 @ );
894 @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;
895 ;
896
897 static const char zComputeFileAgeRun[] =
898 @ WITH RECURSIVE
899 @ ckin(x) AS (VALUES(:ckin) UNION ALL
900 @ SELECT pid FROM ckin, plink WHERE cid=x AND isprim)
901 @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname)
902 @ SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name
903 @ FROM ckin, mlink, event, filename
904 @ WHERE mlink.mid=ckin.x
905 @ AND mlink.fnid IN (SELECT fnid FROM foci, filename
906 @ WHERE foci.checkinID=:ckin
907 @ AND filename.name=foci.filename
908 @ AND filename.name GLOB :glob)
909 @ AND filename.fnid=mlink.fnid
910 @ AND event.objid=mlink.mid;
911 ;
912
913
914 /*
915 ** Look at all file containing in the version "vid". Construct a
916 ** temporary table named "fileage" that contains the file-id for each
917 ** files, the pathname, the check-in where the file was added, and the
918 ** mtime on that checkin. If zGlob and *zGlob then only files matching
919 ** the given glob are computed.
920 */
921 int compute_fileage(int vid, const char* zGlob){
922 Stmt q;
923 db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/);
924 db_prepare(&q, zComputeFileAgeRun /*works-like:"constant"*/);
925 db_bind_int(&q, ":ckin", vid);
926 db_bind_text(&q, ":glob", zGlob && zGlob[0] ? zGlob : "*");
927 db_exec(&q);
928 db_finalize(&q);
929 return 0;
930 }
931
932 /*
933 ** Render the number of days in rAge as a more human-readable time span.
934 ** Different units (seconds, minutes, hours, days, months, years) are
935 ** selected depending on the magnitude of rAge.
936 **
937 ** The string returned is obtained from fossil_malloc() and should be
938 ** freed by the caller.
939 */
940 char *human_readable_age(double rAge){
941 if( rAge*86400.0<120 ){
942 if( rAge*86400.0<1.0 ){
943 return mprintf("current");
944 }else{
945 return mprintf("%d seconds", (int)(rAge*86400.0));
946 }
947 }else if( rAge*1440.0<90 ){
948 return mprintf("%.1f minutes", rAge*1440.0);
949 }else if( rAge*24.0<36 ){
950 return mprintf("%.1f hours", rAge*24.0);
951 }else if( rAge<365.0 ){
952 return mprintf("%.1f days", rAge);
953 }else{
954 return mprintf("%.2f years", rAge/365.0);
955 }
956 }
957
958 /*
959 ** COMMAND: test-fileage
960 **
961 ** Usage: %fossil test-fileage CHECKIN
962 */
963 void test_fileage_cmd(void){
964 int mid;
965 Stmt q;
966 const char *zGlob = find_option("glob",0,1);
967 db_find_and_open_repository(0,0);
968 verify_all_options();
969 if( g.argc!=3 ) usage("test-fileage CHECKIN");
970 mid = name_to_typed_rid(g.argv[2],"ci");
971 compute_fileage(mid, zGlob);
972 db_prepare(&q,
973 "SELECT fid, mid, julianday('now') - mtime, pathname"
974 " FROM fileage"
975 );
976 while( db_step(&q)==SQLITE_ROW ){
977 char *zAge = human_readable_age(db_column_double(&q,2));
978 fossil_print("%8d %8d %16s %s\n",
979 db_column_int(&q,0),
980 db_column_int(&q,1),
981 zAge,
982 db_column_text(&q,3));
983 fossil_free(zAge);
984 }
985 db_finalize(&q);
 
 
 
 
986 }
987
988 /*
989 ** WEBPAGE: fileage
990 **
@@ -814,72 +994,94 @@
994 ** (e.g. *.c or *.txt).
995 */
996 void fileage_page(void){
997 int rid;
998 const char *zName;
 
999 const char *zGlob;
1000 const char *zUuid;
1001 const char *zNow; /* Time of checkin */
1002 Stmt q1, q2;
1003 double baseTime;
 
1004 login_check_credentials();
1005 if( !g.perm.Read ){ login_needed(); return; }
1006 zName = P("name");
1007 if( zName==0 ) zName = "tip";
1008 rid = symbolic_name_to_rid(zName, "ci");
1009 if( rid==0 ){
1010 fossil_fatal("not a valid check-in: %s", zName);
1011 }
1012 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1013 baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
1014 zNow = db_text("", "SELECT datetime(mtime,'localtime') FROM event"
1015 " WHERE objid=%d", rid);
1016 style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T&mtime=1",
1017 zName);
1018 style_header("File Ages");
1019 zGlob = P("glob");
1020 compute_fileage(rid,zGlob);
1021 db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
1022
1023 @ <h2>Files in
1024 @ %z(href("%R/info?name=%T",zUuid))[%S(zUuid)]</a>
1025 if( zGlob && zGlob[0] ){
1026 @ that match "%h(zGlob)" and
1027 }
1028 @ ordered by check-in time</h2>
1029 @
1030 @ <p>Times are relative to the checkin time for
1031 @ %z(href("%R/ci/%s",zUuid))[%S(zUuid)]</a> which is
1032 @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
1033 @
1034 @ <div class='fileage'><table>
1035 @ <tr><th>Time</th><th>Files</th><th>Checkin</th></tr>
1036 db_prepare(&q1,
1037 "SELECT event.mtime, event.objid, blob.uuid,\n"
1038 " coalesce(event.ecomment,event.comment),\n"
1039 " coalesce(event.euser,event.user),\n"
1040 " coalesce((SELECT value FROM tagxref\n"
1041 " WHERE tagtype>0 AND tagid=%d\n"
1042 " AND rid=event.objid),'trunk')\n"
1043 " FROM event, blob\n"
1044 " WHERE event.objid IN (SELECT mid FROM fileage)\n"
1045 " AND blob.rid=event.objid\n"
1046 " ORDER BY event.mtime DESC;",
1047 TAG_BRANCH
1048 );
1049 db_prepare(&q2,
1050 "SELECT blob.uuid, filename.name\n"
1051 " FROM fileage, blob, filename\n"
1052 " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
1053 " AND blob.rid=fileage.fid;"
1054 );
1055 while( db_step(&q1)==SQLITE_ROW ){
1056 double age = baseTime - db_column_double(&q1, 0);
1057 int mid = db_column_int(&q1, 1);
1058 const char *zUuid = db_column_text(&q1, 2);
1059 const char *zComment = db_column_text(&q1, 3);
1060 const char *zUser = db_column_text(&q1, 4);
1061 const char *zBranch = db_column_text(&q1, 5);
1062 char *zAge = human_readable_age(age);
1063 @ <tr><td>%s(zAge)</td>
1064 @ <td>
1065 db_bind_int(&q2, ":mid", mid);
1066 while( db_step(&q2)==SQLITE_ROW ){
1067 const char *zFUuid = db_column_text(&q2,0);
1068 const char *zFile = db_column_text(&q2,1);
1069 @ %z(href("%R/artifact/%s",zFUuid))%h(zFile)</a><br>
1070 }
1071 db_reset(&q2);
1072 @ </td>
1073 @ <td>
1074 @ %z(href("%R/info/%s",zUuid))[%S(zUuid)]</a>
1075 @ %W(zComment) (user:
1076 @ %z(href("%R/timeline?u=%t&c=%t&nd&n=200",zUser,zUuid))%h(zUser)</a>,
1077 @ branch:
1078 @ %z(href("%R/timeline?r=%t&c=%t&nd&n=200",zBranch,zUuid))%h(zBranch)</a>)
1079 @ </td></tr>
1080 @
1081 fossil_free(zAge);
1082 }
1083 @ </table></div>
1084 db_finalize(&q1);
1085 db_finalize(&q2);
1086 style_footer();
1087 }
1088
1089 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
+1 -3
--- src/cgi.c
+++ src/cgi.c
@@ -342,13 +342,11 @@
342342
** case of most /getfile calls for specific versions, the only way the
343343
** content changes is if someone breaks the SCM. And if that happens, a
344344
** stale cache is the least of the problem. So we provide an Expires
345345
** header set to a reasonable period (default: one week).
346346
*/
347
- /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
348
- time_t expires = time(0) + 604800;
349
- fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
347
+ fprintf(g.httpOut, "Cache-control: max-age=28800\r\n");
350348
}else{
351349
fprintf(g.httpOut, "Cache-control: no-cache\r\n");
352350
}
353351
354352
/* Content intended for logged in users should only be cached in
355353
--- src/cgi.c
+++ src/cgi.c
@@ -342,13 +342,11 @@
342 ** case of most /getfile calls for specific versions, the only way the
343 ** content changes is if someone breaks the SCM. And if that happens, a
344 ** stale cache is the least of the problem. So we provide an Expires
345 ** header set to a reasonable period (default: one week).
346 */
347 /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
348 time_t expires = time(0) + 604800;
349 fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
350 }else{
351 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
352 }
353
354 /* Content intended for logged in users should only be cached in
355
--- src/cgi.c
+++ src/cgi.c
@@ -342,13 +342,11 @@
342 ** case of most /getfile calls for specific versions, the only way the
343 ** content changes is if someone breaks the SCM. And if that happens, a
344 ** stale cache is the least of the problem. So we provide an Expires
345 ** header set to a reasonable period (default: one week).
346 */
347 fprintf(g.httpOut, "Cache-control: max-age=28800\r\n");
 
 
348 }else{
349 fprintf(g.httpOut, "Cache-control: no-cache\r\n");
350 }
351
352 /* Content intended for logged in users should only be cached in
353
+9 -1
--- src/checkin.c
+++ src/checkin.c
@@ -65,11 +65,11 @@
6565
6666
db_prepare(&q,
6767
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
6868
" FROM vfile "
6969
" WHERE is_selected(id) %s"
70
- " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
70
+ " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1 /*scan*/",
7171
blob_sql_text(&where)
7272
);
7373
blob_zero(&rewrittenPathname);
7474
while( db_step(&q)==SQLITE_ROW ){
7575
const char *zPathname = db_column_text(&q,0);
@@ -497,10 +497,11 @@
497497
" ORDER BY 1",
498498
fossil_all_reserved_names(0)
499499
);
500500
db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
501501
blob_zero(&rewrittenPathname);
502
+ g.allowSymlinks = 1; /* Report on symbolic links */
502503
while( db_step(&q)==SQLITE_ROW ){
503504
zDisplayName = zPathname = db_column_text(&q, 0);
504505
if( cwdRelative ) {
505506
char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
506507
file_relative_name(zFullName, &rewrittenPathname, 0);
@@ -567,10 +568,11 @@
567568
** argument. Matching files, if any, are removed
568569
** prior to checking for any empty directories;
569570
** therefore, directories that contain only files
570571
** that were removed will be removed as well.
571572
** -f|--force Remove files without prompting.
573
+** --verily Shorthand for: -f --emptydirs --dotfiles
572574
** --ignore <CSG> Ignore files matching patterns from the
573575
** comma separated list of glob patterns.
574576
** --keep <CSG> Keep files matching this comma separated
575577
** list of glob patterns.
576578
** -n|--dry-run If given, display instead of run actions.
@@ -608,10 +610,15 @@
608610
if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
609611
zIgnoreFlag = find_option("ignore",0,1);
610612
verboseFlag = find_option("verbose","v",0)!=0;
611613
zKeepFlag = find_option("keep",0,1);
612614
db_must_be_within_tree();
615
+ if( find_option("verily",0,0)!=0 ){
616
+ allFileFlag = allDirFlag = 1;
617
+ emptyDirsFlag = 1;
618
+ scanFlags |= SCAN_ALL;
619
+ }
613620
if( zIgnoreFlag==0 ){
614621
zIgnoreFlag = db_get("ignore-glob", 0);
615622
}
616623
if( zKeepFlag==0 ){
617624
zKeepFlag = db_get("keep-glob", 0);
@@ -637,10 +644,11 @@
637644
blob_reset(&extremeAnswer);
638645
}
639646
pIgnore = glob_create(zIgnoreFlag);
640647
pKeep = glob_create(zKeepFlag);
641648
nRoot = (int)strlen(g.zLocalRoot);
649
+ g.allowSymlinks = 1; /* Find symlinks too */
642650
if( !dirsOnlyFlag ){
643651
Stmt q;
644652
Blob repo;
645653
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags,
646654
extremeFlag ? 0 : pIgnore);
647655
--- src/checkin.c
+++ src/checkin.c
@@ -65,11 +65,11 @@
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
@@ -497,10 +497,11 @@
497 " ORDER BY 1",
498 fossil_all_reserved_names(0)
499 );
500 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
501 blob_zero(&rewrittenPathname);
 
502 while( db_step(&q)==SQLITE_ROW ){
503 zDisplayName = zPathname = db_column_text(&q, 0);
504 if( cwdRelative ) {
505 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
506 file_relative_name(zFullName, &rewrittenPathname, 0);
@@ -567,10 +568,11 @@
567 ** argument. Matching files, if any, are removed
568 ** prior to checking for any empty directories;
569 ** therefore, directories that contain only files
570 ** that were removed will be removed as well.
571 ** -f|--force Remove files without prompting.
 
572 ** --ignore <CSG> Ignore files matching patterns from the
573 ** comma separated list of glob patterns.
574 ** --keep <CSG> Keep files matching this comma separated
575 ** list of glob patterns.
576 ** -n|--dry-run If given, display instead of run actions.
@@ -608,10 +610,15 @@
608 if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
609 zIgnoreFlag = find_option("ignore",0,1);
610 verboseFlag = find_option("verbose","v",0)!=0;
611 zKeepFlag = find_option("keep",0,1);
612 db_must_be_within_tree();
 
 
 
 
 
613 if( zIgnoreFlag==0 ){
614 zIgnoreFlag = db_get("ignore-glob", 0);
615 }
616 if( zKeepFlag==0 ){
617 zKeepFlag = db_get("keep-glob", 0);
@@ -637,10 +644,11 @@
637 blob_reset(&extremeAnswer);
638 }
639 pIgnore = glob_create(zIgnoreFlag);
640 pKeep = glob_create(zKeepFlag);
641 nRoot = (int)strlen(g.zLocalRoot);
 
642 if( !dirsOnlyFlag ){
643 Stmt q;
644 Blob repo;
645 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags,
646 extremeFlag ? 0 : pIgnore);
647
--- src/checkin.c
+++ src/checkin.c
@@ -65,11 +65,11 @@
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1 /*scan*/",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
@@ -497,10 +497,11 @@
497 " ORDER BY 1",
498 fossil_all_reserved_names(0)
499 );
500 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
501 blob_zero(&rewrittenPathname);
502 g.allowSymlinks = 1; /* Report on symbolic links */
503 while( db_step(&q)==SQLITE_ROW ){
504 zDisplayName = zPathname = db_column_text(&q, 0);
505 if( cwdRelative ) {
506 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
507 file_relative_name(zFullName, &rewrittenPathname, 0);
@@ -567,10 +568,11 @@
568 ** argument. Matching files, if any, are removed
569 ** prior to checking for any empty directories;
570 ** therefore, directories that contain only files
571 ** that were removed will be removed as well.
572 ** -f|--force Remove files without prompting.
573 ** --verily Shorthand for: -f --emptydirs --dotfiles
574 ** --ignore <CSG> Ignore files matching patterns from the
575 ** comma separated list of glob patterns.
576 ** --keep <CSG> Keep files matching this comma separated
577 ** list of glob patterns.
578 ** -n|--dry-run If given, display instead of run actions.
@@ -608,10 +610,15 @@
610 if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
611 zIgnoreFlag = find_option("ignore",0,1);
612 verboseFlag = find_option("verbose","v",0)!=0;
613 zKeepFlag = find_option("keep",0,1);
614 db_must_be_within_tree();
615 if( find_option("verily",0,0)!=0 ){
616 allFileFlag = allDirFlag = 1;
617 emptyDirsFlag = 1;
618 scanFlags |= SCAN_ALL;
619 }
620 if( zIgnoreFlag==0 ){
621 zIgnoreFlag = db_get("ignore-glob", 0);
622 }
623 if( zKeepFlag==0 ){
624 zKeepFlag = db_get("keep-glob", 0);
@@ -637,10 +644,11 @@
644 blob_reset(&extremeAnswer);
645 }
646 pIgnore = glob_create(zIgnoreFlag);
647 pKeep = glob_create(zKeepFlag);
648 nRoot = (int)strlen(g.zLocalRoot);
649 g.allowSymlinks = 1; /* Find symlinks too */
650 if( !dirsOnlyFlag ){
651 Stmt q;
652 Blob repo;
653 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags,
654 extremeFlag ? 0 : pIgnore);
655
+9 -1
--- src/checkin.c
+++ src/checkin.c
@@ -65,11 +65,11 @@
6565
6666
db_prepare(&q,
6767
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
6868
" FROM vfile "
6969
" WHERE is_selected(id) %s"
70
- " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
70
+ " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1 /*scan*/",
7171
blob_sql_text(&where)
7272
);
7373
blob_zero(&rewrittenPathname);
7474
while( db_step(&q)==SQLITE_ROW ){
7575
const char *zPathname = db_column_text(&q,0);
@@ -497,10 +497,11 @@
497497
" ORDER BY 1",
498498
fossil_all_reserved_names(0)
499499
);
500500
db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
501501
blob_zero(&rewrittenPathname);
502
+ g.allowSymlinks = 1; /* Report on symbolic links */
502503
while( db_step(&q)==SQLITE_ROW ){
503504
zDisplayName = zPathname = db_column_text(&q, 0);
504505
if( cwdRelative ) {
505506
char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
506507
file_relative_name(zFullName, &rewrittenPathname, 0);
@@ -567,10 +568,11 @@
567568
** argument. Matching files, if any, are removed
568569
** prior to checking for any empty directories;
569570
** therefore, directories that contain only files
570571
** that were removed will be removed as well.
571572
** -f|--force Remove files without prompting.
573
+** --verily Shorthand for: -f --emptydirs --dotfiles
572574
** --ignore <CSG> Ignore files matching patterns from the
573575
** comma separated list of glob patterns.
574576
** --keep <CSG> Keep files matching this comma separated
575577
** list of glob patterns.
576578
** -n|--dry-run If given, display instead of run actions.
@@ -608,10 +610,15 @@
608610
if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
609611
zIgnoreFlag = find_option("ignore",0,1);
610612
verboseFlag = find_option("verbose","v",0)!=0;
611613
zKeepFlag = find_option("keep",0,1);
612614
db_must_be_within_tree();
615
+ if( find_option("verily",0,0)!=0 ){
616
+ allFileFlag = allDirFlag = 1;
617
+ emptyDirsFlag = 1;
618
+ scanFlags |= SCAN_ALL;
619
+ }
613620
if( zIgnoreFlag==0 ){
614621
zIgnoreFlag = db_get("ignore-glob", 0);
615622
}
616623
if( zKeepFlag==0 ){
617624
zKeepFlag = db_get("keep-glob", 0);
@@ -637,10 +644,11 @@
637644
blob_reset(&extremeAnswer);
638645
}
639646
pIgnore = glob_create(zIgnoreFlag);
640647
pKeep = glob_create(zKeepFlag);
641648
nRoot = (int)strlen(g.zLocalRoot);
649
+ g.allowSymlinks = 1; /* Find symlinks too */
642650
if( !dirsOnlyFlag ){
643651
Stmt q;
644652
Blob repo;
645653
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags,
646654
extremeFlag ? 0 : pIgnore);
647655
--- src/checkin.c
+++ src/checkin.c
@@ -65,11 +65,11 @@
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
@@ -497,10 +497,11 @@
497 " ORDER BY 1",
498 fossil_all_reserved_names(0)
499 );
500 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
501 blob_zero(&rewrittenPathname);
 
502 while( db_step(&q)==SQLITE_ROW ){
503 zDisplayName = zPathname = db_column_text(&q, 0);
504 if( cwdRelative ) {
505 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
506 file_relative_name(zFullName, &rewrittenPathname, 0);
@@ -567,10 +568,11 @@
567 ** argument. Matching files, if any, are removed
568 ** prior to checking for any empty directories;
569 ** therefore, directories that contain only files
570 ** that were removed will be removed as well.
571 ** -f|--force Remove files without prompting.
 
572 ** --ignore <CSG> Ignore files matching patterns from the
573 ** comma separated list of glob patterns.
574 ** --keep <CSG> Keep files matching this comma separated
575 ** list of glob patterns.
576 ** -n|--dry-run If given, display instead of run actions.
@@ -608,10 +610,15 @@
608 if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
609 zIgnoreFlag = find_option("ignore",0,1);
610 verboseFlag = find_option("verbose","v",0)!=0;
611 zKeepFlag = find_option("keep",0,1);
612 db_must_be_within_tree();
 
 
 
 
 
613 if( zIgnoreFlag==0 ){
614 zIgnoreFlag = db_get("ignore-glob", 0);
615 }
616 if( zKeepFlag==0 ){
617 zKeepFlag = db_get("keep-glob", 0);
@@ -637,10 +644,11 @@
637 blob_reset(&extremeAnswer);
638 }
639 pIgnore = glob_create(zIgnoreFlag);
640 pKeep = glob_create(zKeepFlag);
641 nRoot = (int)strlen(g.zLocalRoot);
 
642 if( !dirsOnlyFlag ){
643 Stmt q;
644 Blob repo;
645 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags,
646 extremeFlag ? 0 : pIgnore);
647
--- src/checkin.c
+++ src/checkin.c
@@ -65,11 +65,11 @@
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
68 " FROM vfile "
69 " WHERE is_selected(id) %s"
70 " AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1 /*scan*/",
71 blob_sql_text(&where)
72 );
73 blob_zero(&rewrittenPathname);
74 while( db_step(&q)==SQLITE_ROW ){
75 const char *zPathname = db_column_text(&q,0);
@@ -497,10 +497,11 @@
497 " ORDER BY 1",
498 fossil_all_reserved_names(0)
499 );
500 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
501 blob_zero(&rewrittenPathname);
502 g.allowSymlinks = 1; /* Report on symbolic links */
503 while( db_step(&q)==SQLITE_ROW ){
504 zDisplayName = zPathname = db_column_text(&q, 0);
505 if( cwdRelative ) {
506 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
507 file_relative_name(zFullName, &rewrittenPathname, 0);
@@ -567,10 +568,11 @@
568 ** argument. Matching files, if any, are removed
569 ** prior to checking for any empty directories;
570 ** therefore, directories that contain only files
571 ** that were removed will be removed as well.
572 ** -f|--force Remove files without prompting.
573 ** --verily Shorthand for: -f --emptydirs --dotfiles
574 ** --ignore <CSG> Ignore files matching patterns from the
575 ** comma separated list of glob patterns.
576 ** --keep <CSG> Keep files matching this comma separated
577 ** list of glob patterns.
578 ** -n|--dry-run If given, display instead of run actions.
@@ -608,10 +610,15 @@
610 if( find_option("allckouts",0,0)!=0 ) scanFlags |= SCAN_NESTED;
611 zIgnoreFlag = find_option("ignore",0,1);
612 verboseFlag = find_option("verbose","v",0)!=0;
613 zKeepFlag = find_option("keep",0,1);
614 db_must_be_within_tree();
615 if( find_option("verily",0,0)!=0 ){
616 allFileFlag = allDirFlag = 1;
617 emptyDirsFlag = 1;
618 scanFlags |= SCAN_ALL;
619 }
620 if( zIgnoreFlag==0 ){
621 zIgnoreFlag = db_get("ignore-glob", 0);
622 }
623 if( zKeepFlag==0 ){
624 zKeepFlag = db_get("keep-glob", 0);
@@ -637,10 +644,11 @@
644 blob_reset(&extremeAnswer);
645 }
646 pIgnore = glob_create(zIgnoreFlag);
647 pKeep = glob_create(zKeepFlag);
648 nRoot = (int)strlen(g.zLocalRoot);
649 g.allowSymlinks = 1; /* Find symlinks too */
650 if( !dirsOnlyFlag ){
651 Stmt q;
652 Blob repo;
653 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags,
654 extremeFlag ? 0 : pIgnore);
655
+1 -2
--- src/checkout.c
+++ src/checkout.c
@@ -305,12 +305,11 @@
305305
306306
if( !forceFlag && unsaved_changes(0) ){
307307
fossil_fatal("there are unsaved changes in the current checkout");
308308
}
309309
if( !forceFlag
310
- && db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'",
311
- db_name("localdb"))
310
+ && db_table_exists("localdb","stash")
312311
&& db_exists("SELECT 1 FROM %s.stash", db_name("localdb"))
313312
){
314313
fossil_fatal("closing the checkout will delete your stash");
315314
}
316315
if( db_is_writeable("repository") ){
317316
--- src/checkout.c
+++ src/checkout.c
@@ -305,12 +305,11 @@
305
306 if( !forceFlag && unsaved_changes(0) ){
307 fossil_fatal("there are unsaved changes in the current checkout");
308 }
309 if( !forceFlag
310 && db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'",
311 db_name("localdb"))
312 && db_exists("SELECT 1 FROM %s.stash", db_name("localdb"))
313 ){
314 fossil_fatal("closing the checkout will delete your stash");
315 }
316 if( db_is_writeable("repository") ){
317
--- src/checkout.c
+++ src/checkout.c
@@ -305,12 +305,11 @@
305
306 if( !forceFlag && unsaved_changes(0) ){
307 fossil_fatal("there are unsaved changes in the current checkout");
308 }
309 if( !forceFlag
310 && db_table_exists("localdb","stash")
 
311 && db_exists("SELECT 1 FROM %s.stash", db_name("localdb"))
312 ){
313 fossil_fatal("closing the checkout will delete your stash");
314 }
315 if( db_is_writeable("repository") ){
316
+7 -4
--- src/clone.c
+++ src/clone.c
@@ -110,23 +110,26 @@
110110
** --once Don't save url.
111111
** --private Also clone private branches
112112
** --ssl-identity=filename Use the SSL identity if requested by the server
113113
** --ssh-command|-c 'command' Use this SSH command
114114
** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests
115
+** --verbose Show more statistics in output
115116
**
116117
** See also: init
117118
*/
118119
void clone_cmd(void){
119120
char *zPassword;
120121
const char *zDefaultUser; /* Optional name of the default user */
121122
const char *zHttpAuth; /* HTTP Authorization user:pass information */
122123
int nErr = 0;
123
- int bPrivate = 0; /* Also clone private branches */
124124
int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
125
+ int syncFlags = SYNC_CLONE;
125126
126
- if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
127
+ /* Also clone private branches */
128
+ if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE;
127129
if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
130
+ if( find_option("verbose",0,0)!=0) syncFlags |= SYNC_VERBOSE;
128131
zHttpAuth = find_option("httpauth","B",1);
129132
zDefaultUser = find_option("admin-user","A",1);
130133
clone_ssh_find_options();
131134
url_proxy_options();
132135
@@ -147,11 +150,11 @@
147150
file_copy(g.url.name, g.argv[3]);
148151
db_close(1);
149152
db_open_repository(g.argv[3]);
150153
db_record_repository_filename(g.argv[3]);
151154
url_remember();
152
- if( !bPrivate ) delete_private_content();
155
+ if( !(syncFlags & SYNC_PRIVATE) ) delete_private_content();
153156
shun_artifacts();
154157
db_create_default_users(1, zDefaultUser);
155158
if( zDefaultUser ){
156159
g.zLogin = zDefaultUser;
157160
}else{
@@ -184,11 +187,11 @@
184187
);
185188
url_enable_proxy(0);
186189
clone_ssh_db_set_options();
187190
url_get_password_if_needed();
188191
g.xlinkClusterOnly = 1;
189
- nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0);
192
+ nErr = client_sync(syncFlags,CONFIGSET_ALL,0);
190193
g.xlinkClusterOnly = 0;
191194
verify_cancel();
192195
db_end_transaction(0);
193196
db_close(1);
194197
if( nErr ){
195198
--- src/clone.c
+++ src/clone.c
@@ -110,23 +110,26 @@
110 ** --once Don't save url.
111 ** --private Also clone private branches
112 ** --ssl-identity=filename Use the SSL identity if requested by the server
113 ** --ssh-command|-c 'command' Use this SSH command
114 ** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests
 
115 **
116 ** See also: init
117 */
118 void clone_cmd(void){
119 char *zPassword;
120 const char *zDefaultUser; /* Optional name of the default user */
121 const char *zHttpAuth; /* HTTP Authorization user:pass information */
122 int nErr = 0;
123 int bPrivate = 0; /* Also clone private branches */
124 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
 
125
126 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
 
127 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
 
128 zHttpAuth = find_option("httpauth","B",1);
129 zDefaultUser = find_option("admin-user","A",1);
130 clone_ssh_find_options();
131 url_proxy_options();
132
@@ -147,11 +150,11 @@
147 file_copy(g.url.name, g.argv[3]);
148 db_close(1);
149 db_open_repository(g.argv[3]);
150 db_record_repository_filename(g.argv[3]);
151 url_remember();
152 if( !bPrivate ) delete_private_content();
153 shun_artifacts();
154 db_create_default_users(1, zDefaultUser);
155 if( zDefaultUser ){
156 g.zLogin = zDefaultUser;
157 }else{
@@ -184,11 +187,11 @@
184 );
185 url_enable_proxy(0);
186 clone_ssh_db_set_options();
187 url_get_password_if_needed();
188 g.xlinkClusterOnly = 1;
189 nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0);
190 g.xlinkClusterOnly = 0;
191 verify_cancel();
192 db_end_transaction(0);
193 db_close(1);
194 if( nErr ){
195
--- src/clone.c
+++ src/clone.c
@@ -110,23 +110,26 @@
110 ** --once Don't save url.
111 ** --private Also clone private branches
112 ** --ssl-identity=filename Use the SSL identity if requested by the server
113 ** --ssh-command|-c 'command' Use this SSH command
114 ** --httpauth|-B 'user:pass' Add HTTP Basic Authorization to requests
115 ** --verbose Show more statistics in output
116 **
117 ** See also: init
118 */
119 void clone_cmd(void){
120 char *zPassword;
121 const char *zDefaultUser; /* Optional name of the default user */
122 const char *zHttpAuth; /* HTTP Authorization user:pass information */
123 int nErr = 0;
 
124 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
125 int syncFlags = SYNC_CLONE;
126
127 /* Also clone private branches */
128 if( find_option("private",0,0)!=0 ) syncFlags |= SYNC_PRIVATE;
129 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
130 if( find_option("verbose",0,0)!=0) syncFlags |= SYNC_VERBOSE;
131 zHttpAuth = find_option("httpauth","B",1);
132 zDefaultUser = find_option("admin-user","A",1);
133 clone_ssh_find_options();
134 url_proxy_options();
135
@@ -147,11 +150,11 @@
150 file_copy(g.url.name, g.argv[3]);
151 db_close(1);
152 db_open_repository(g.argv[3]);
153 db_record_repository_filename(g.argv[3]);
154 url_remember();
155 if( !(syncFlags & SYNC_PRIVATE) ) delete_private_content();
156 shun_artifacts();
157 db_create_default_users(1, zDefaultUser);
158 if( zDefaultUser ){
159 g.zLogin = zDefaultUser;
160 }else{
@@ -184,11 +187,11 @@
187 );
188 url_enable_proxy(0);
189 clone_ssh_db_set_options();
190 url_get_password_if_needed();
191 g.xlinkClusterOnly = 1;
192 nErr = client_sync(syncFlags,CONFIGSET_ALL,0);
193 g.xlinkClusterOnly = 0;
194 verify_cancel();
195 db_end_transaction(0);
196 db_close(1);
197 if( nErr ){
198
+4 -4
--- src/content.c
+++ src/content.c
@@ -567,14 +567,14 @@
567567
db_exec(&s1);
568568
rid = db_last_insert_rowid();
569569
if( !pBlob ){
570570
db_multi_exec("INSERT OR IGNORE INTO phantom VALUES(%d)", rid);
571571
}
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;
576576
}
577577
if( nBlob==0 ) blob_reset(&cmpr);
578578
579579
/* If the srcId is specified, then the data we just added is
580580
** really a delta. Record this fact in the delta table.
581581
--- 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
+73 -33
--- src/db.c
+++ src/db.c
@@ -424,10 +424,13 @@
424424
425425
/*
426426
** Extract text, integer, or blob values from the N-th column of the
427427
** current row.
428428
*/
429
+int db_column_type(Stmt *pStmt, int N){
430
+ return sqlite3_column_type(pStmt->pStmt, N);
431
+}
429432
int db_column_bytes(Stmt *pStmt, int N){
430433
return sqlite3_column_bytes(pStmt->pStmt, N);
431434
}
432435
int db_column_int(Stmt *pStmt, int N){
433436
return sqlite3_column_int(pStmt->pStmt, N);
@@ -486,10 +489,50 @@
486489
while( (rc = db_step(pStmt))==SQLITE_ROW ){}
487490
rc = db_reset(pStmt);
488491
db_check_result(rc);
489492
return rc;
490493
}
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
+}
491534
492535
/*
493536
** Execute multiple SQL statements.
494537
*/
495538
int db_multi_exec(const char *zSql, ...){
@@ -722,11 +765,11 @@
722765
arg = (const char*)sqlite3_value_text(argv[0]);
723766
if(!arg){
724767
sqlite3_result_error(context, "Expecting a STRING argument", -1);
725768
}else{
726769
int rid;
727
- type = (2==argc) ? sqlite3_value_text(argv[1]) : 0;
770
+ type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0;
728771
if(!type) type = "ci";
729772
rid = symbolic_name_to_rid( arg, type );
730773
if(rid<0){
731774
sqlite3_result_error(context, "Symbolic name is ambiguous.", -1);
732775
}else if(0==rid){
@@ -915,30 +958,47 @@
915958
g.zConfigDbType = "configdb";
916959
}
917960
g.zConfigDbName = zDbName;
918961
}
919962
963
+/*
964
+** Return TRUE if zTable exists.
965
+*/
966
+int db_table_exists(
967
+ const char *zDb, /* One of: NULL, "configdb", "localdb", "repository" */
968
+ const char *zTable /* Name of table */
969
+){
970
+ return sqlite3_table_column_metadata(g.db,
971
+ zDb ? db_name(zDb) : 0, zTable, 0,
972
+ 0, 0, 0, 0, 0)==SQLITE_OK;
973
+}
974
+
975
+/*
976
+** Return TRUE if zTable exists and contains column zColumn.
977
+** Return FALSE if zTable does not exist or if zTable exists
978
+** but lacks zColumn.
979
+*/
980
+int db_table_has_column(
981
+ const char *zDb, /* One of: NULL, "config", "localdb", "repository" */
982
+ const char *zTable, /* Name of table */
983
+ const char *zColumn /* Name of column in table */
984
+){
985
+ return sqlite3_table_column_metadata(g.db,
986
+ zDb ? db_name(zDb) : 0, zTable, zColumn,
987
+ 0, 0, 0, 0, 0)==SQLITE_OK;
988
+}
920989
921990
/*
922991
** Returns TRUE if zTable exists in the local database but lacks column
923992
** zColumn
924993
*/
925994
static int db_local_table_exists_but_lacks_column(
926995
const char *zTable,
927996
const char *zColumn
928997
){
929
- char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
930
- " WHERE name==%Q /*scan*/",
931
- db_name("localdb"), zTable);
932
- int rc = 0;
933
- if( zDef ){
934
- char *zPattern = mprintf("* %s *", zColumn);
935
- rc = sqlite3_strglob(zPattern, zDef)!=0;
936
- fossil_free(zPattern);
937
- fossil_free(zDef);
938
- }
939
- return rc;
998
+ return db_table_exists(db_name("localdb"), zTable)
999
+ && !db_table_has_column(db_name("localdb"), zTable, zColumn);
9401000
}
9411001
9421002
/*
9431003
** If zDbName is a valid local database file, open it and return
9441004
** true. If it is not a valid local database file, return 0.
@@ -1212,10 +1272,11 @@
12121272
fossil_fatal("not in a local checkout");
12131273
return;
12141274
}
12151275
db_open_or_attach(zRepo, "test_repo", 0);
12161276
db_lset("repository", blob_str(&repo));
1277
+ db_record_repository_filename(blob_str(&repo));
12171278
db_close(1);
12181279
}
12191280
12201281
12211282
/*
@@ -2004,31 +2065,10 @@
20042065
}
20052066
void db_lset_int(const char *zName, int value){
20062067
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
20072068
}
20082069
2009
-/*
2010
-** Returns non-0 if the database (which must be open) table identified
2011
-** by zTableName has a column named zColName (case-sensitive), else
2012
-** returns 0.
2013
-*/
2014
-int db_table_has_column(const char *zTableName, const char *zColName){
2015
- Stmt q = empty_Stmt;
2016
- int rc = 0;
2017
- db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
2018
- while(SQLITE_ROW == db_step(&q)){
2019
- /* Columns: (cid, name, type, notnull, dflt_value, pk) */
2020
- const char *zCol = db_column_text(&q, 1);
2021
- if( 0==fossil_strcmp(zColName, zCol) ){
2022
- rc = 1;
2023
- break;
2024
- }
2025
- }
2026
- db_finalize(&q);
2027
- return rc;
2028
-}
2029
-
20302070
/*
20312071
** Record the name of a local repository in the global_config() database.
20322072
** The repository filename %s is recorded as an entry with a "name" field
20332073
** of the following form:
20342074
**
20352075
--- 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){
@@ -915,30 +958,47 @@
915 g.zConfigDbType = "configdb";
916 }
917 g.zConfigDbName = zDbName;
918 }
919
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
920
921 /*
922 ** Returns TRUE if zTable exists in the local database but lacks column
923 ** zColumn
924 */
925 static int db_local_table_exists_but_lacks_column(
926 const char *zTable,
927 const char *zColumn
928 ){
929 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
930 " WHERE name==%Q /*scan*/",
931 db_name("localdb"), zTable);
932 int rc = 0;
933 if( zDef ){
934 char *zPattern = mprintf("* %s *", zColumn);
935 rc = sqlite3_strglob(zPattern, zDef)!=0;
936 fossil_free(zPattern);
937 fossil_free(zDef);
938 }
939 return rc;
940 }
941
942 /*
943 ** If zDbName is a valid local database file, open it and return
944 ** true. If it is not a valid local database file, return 0.
@@ -1212,10 +1272,11 @@
1212 fossil_fatal("not in a local checkout");
1213 return;
1214 }
1215 db_open_or_attach(zRepo, "test_repo", 0);
1216 db_lset("repository", blob_str(&repo));
 
1217 db_close(1);
1218 }
1219
1220
1221 /*
@@ -2004,31 +2065,10 @@
2004 }
2005 void db_lset_int(const char *zName, int value){
2006 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
2007 }
2008
2009 /*
2010 ** Returns non-0 if the database (which must be open) table identified
2011 ** by zTableName has a column named zColName (case-sensitive), else
2012 ** returns 0.
2013 */
2014 int db_table_has_column(const char *zTableName, const char *zColName){
2015 Stmt q = empty_Stmt;
2016 int rc = 0;
2017 db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
2018 while(SQLITE_ROW == db_step(&q)){
2019 /* Columns: (cid, name, type, notnull, dflt_value, pk) */
2020 const char *zCol = db_column_text(&q, 1);
2021 if( 0==fossil_strcmp(zColName, zCol) ){
2022 rc = 1;
2023 break;
2024 }
2025 }
2026 db_finalize(&q);
2027 return rc;
2028 }
2029
2030 /*
2031 ** Record the name of a local repository in the global_config() database.
2032 ** The repository filename %s is recorded as an entry with a "name" field
2033 ** of the following form:
2034 **
2035
--- 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){
@@ -915,30 +958,47 @@
958 g.zConfigDbType = "configdb";
959 }
960 g.zConfigDbName = zDbName;
961 }
962
963 /*
964 ** Return TRUE if zTable exists.
965 */
966 int db_table_exists(
967 const char *zDb, /* One of: NULL, "configdb", "localdb", "repository" */
968 const char *zTable /* Name of table */
969 ){
970 return sqlite3_table_column_metadata(g.db,
971 zDb ? db_name(zDb) : 0, zTable, 0,
972 0, 0, 0, 0, 0)==SQLITE_OK;
973 }
974
975 /*
976 ** Return TRUE if zTable exists and contains column zColumn.
977 ** Return FALSE if zTable does not exist or if zTable exists
978 ** but lacks zColumn.
979 */
980 int db_table_has_column(
981 const char *zDb, /* One of: NULL, "config", "localdb", "repository" */
982 const char *zTable, /* Name of table */
983 const char *zColumn /* Name of column in table */
984 ){
985 return sqlite3_table_column_metadata(g.db,
986 zDb ? db_name(zDb) : 0, zTable, zColumn,
987 0, 0, 0, 0, 0)==SQLITE_OK;
988 }
989
990 /*
991 ** Returns TRUE if zTable exists in the local database but lacks column
992 ** zColumn
993 */
994 static int db_local_table_exists_but_lacks_column(
995 const char *zTable,
996 const char *zColumn
997 ){
998 return db_table_exists(db_name("localdb"), zTable)
999 && !db_table_has_column(db_name("localdb"), zTable, zColumn);
 
 
 
 
 
 
 
 
 
1000 }
1001
1002 /*
1003 ** If zDbName is a valid local database file, open it and return
1004 ** true. If it is not a valid local database file, return 0.
@@ -1212,10 +1272,11 @@
1272 fossil_fatal("not in a local checkout");
1273 return;
1274 }
1275 db_open_or_attach(zRepo, "test_repo", 0);
1276 db_lset("repository", blob_str(&repo));
1277 db_record_repository_filename(blob_str(&repo));
1278 db_close(1);
1279 }
1280
1281
1282 /*
@@ -2004,31 +2065,10 @@
2065 }
2066 void db_lset_int(const char *zName, int value){
2067 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
2068 }
2069
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2070 /*
2071 ** Record the name of a local repository in the global_config() database.
2072 ** The repository filename %s is recorded as an entry with a "name" field
2073 ** of the following form:
2074 **
2075
+73 -33
--- src/db.c
+++ src/db.c
@@ -424,10 +424,13 @@
424424
425425
/*
426426
** Extract text, integer, or blob values from the N-th column of the
427427
** current row.
428428
*/
429
+int db_column_type(Stmt *pStmt, int N){
430
+ return sqlite3_column_type(pStmt->pStmt, N);
431
+}
429432
int db_column_bytes(Stmt *pStmt, int N){
430433
return sqlite3_column_bytes(pStmt->pStmt, N);
431434
}
432435
int db_column_int(Stmt *pStmt, int N){
433436
return sqlite3_column_int(pStmt->pStmt, N);
@@ -486,10 +489,50 @@
486489
while( (rc = db_step(pStmt))==SQLITE_ROW ){}
487490
rc = db_reset(pStmt);
488491
db_check_result(rc);
489492
return rc;
490493
}
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
+}
491534
492535
/*
493536
** Execute multiple SQL statements.
494537
*/
495538
int db_multi_exec(const char *zSql, ...){
@@ -722,11 +765,11 @@
722765
arg = (const char*)sqlite3_value_text(argv[0]);
723766
if(!arg){
724767
sqlite3_result_error(context, "Expecting a STRING argument", -1);
725768
}else{
726769
int rid;
727
- type = (2==argc) ? sqlite3_value_text(argv[1]) : 0;
770
+ type = (2==argc) ? (const char*)sqlite3_value_text(argv[1]) : 0;
728771
if(!type) type = "ci";
729772
rid = symbolic_name_to_rid( arg, type );
730773
if(rid<0){
731774
sqlite3_result_error(context, "Symbolic name is ambiguous.", -1);
732775
}else if(0==rid){
@@ -915,30 +958,47 @@
915958
g.zConfigDbType = "configdb";
916959
}
917960
g.zConfigDbName = zDbName;
918961
}
919962
963
+/*
964
+** Return TRUE if zTable exists.
965
+*/
966
+int db_table_exists(
967
+ const char *zDb, /* One of: NULL, "configdb", "localdb", "repository" */
968
+ const char *zTable /* Name of table */
969
+){
970
+ return sqlite3_table_column_metadata(g.db,
971
+ zDb ? db_name(zDb) : 0, zTable, 0,
972
+ 0, 0, 0, 0, 0)==SQLITE_OK;
973
+}
974
+
975
+/*
976
+** Return TRUE if zTable exists and contains column zColumn.
977
+** Return FALSE if zTable does not exist or if zTable exists
978
+** but lacks zColumn.
979
+*/
980
+int db_table_has_column(
981
+ const char *zDb, /* One of: NULL, "config", "localdb", "repository" */
982
+ const char *zTable, /* Name of table */
983
+ const char *zColumn /* Name of column in table */
984
+){
985
+ return sqlite3_table_column_metadata(g.db,
986
+ zDb ? db_name(zDb) : 0, zTable, zColumn,
987
+ 0, 0, 0, 0, 0)==SQLITE_OK;
988
+}
920989
921990
/*
922991
** Returns TRUE if zTable exists in the local database but lacks column
923992
** zColumn
924993
*/
925994
static int db_local_table_exists_but_lacks_column(
926995
const char *zTable,
927996
const char *zColumn
928997
){
929
- char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
930
- " WHERE name==%Q /*scan*/",
931
- db_name("localdb"), zTable);
932
- int rc = 0;
933
- if( zDef ){
934
- char *zPattern = mprintf("* %s *", zColumn);
935
- rc = sqlite3_strglob(zPattern, zDef)!=0;
936
- fossil_free(zPattern);
937
- fossil_free(zDef);
938
- }
939
- return rc;
998
+ return db_table_exists(db_name("localdb"), zTable)
999
+ && !db_table_has_column(db_name("localdb"), zTable, zColumn);
9401000
}
9411001
9421002
/*
9431003
** If zDbName is a valid local database file, open it and return
9441004
** true. If it is not a valid local database file, return 0.
@@ -1212,10 +1272,11 @@
12121272
fossil_fatal("not in a local checkout");
12131273
return;
12141274
}
12151275
db_open_or_attach(zRepo, "test_repo", 0);
12161276
db_lset("repository", blob_str(&repo));
1277
+ db_record_repository_filename(blob_str(&repo));
12171278
db_close(1);
12181279
}
12191280
12201281
12211282
/*
@@ -2004,31 +2065,10 @@
20042065
}
20052066
void db_lset_int(const char *zName, int value){
20062067
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
20072068
}
20082069
2009
-/*
2010
-** Returns non-0 if the database (which must be open) table identified
2011
-** by zTableName has a column named zColName (case-sensitive), else
2012
-** returns 0.
2013
-*/
2014
-int db_table_has_column(const char *zTableName, const char *zColName){
2015
- Stmt q = empty_Stmt;
2016
- int rc = 0;
2017
- db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
2018
- while(SQLITE_ROW == db_step(&q)){
2019
- /* Columns: (cid, name, type, notnull, dflt_value, pk) */
2020
- const char *zCol = db_column_text(&q, 1);
2021
- if( 0==fossil_strcmp(zColName, zCol) ){
2022
- rc = 1;
2023
- break;
2024
- }
2025
- }
2026
- db_finalize(&q);
2027
- return rc;
2028
-}
2029
-
20302070
/*
20312071
** Record the name of a local repository in the global_config() database.
20322072
** The repository filename %s is recorded as an entry with a "name" field
20332073
** of the following form:
20342074
**
20352075
--- 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){
@@ -915,30 +958,47 @@
915 g.zConfigDbType = "configdb";
916 }
917 g.zConfigDbName = zDbName;
918 }
919
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
920
921 /*
922 ** Returns TRUE if zTable exists in the local database but lacks column
923 ** zColumn
924 */
925 static int db_local_table_exists_but_lacks_column(
926 const char *zTable,
927 const char *zColumn
928 ){
929 char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
930 " WHERE name==%Q /*scan*/",
931 db_name("localdb"), zTable);
932 int rc = 0;
933 if( zDef ){
934 char *zPattern = mprintf("* %s *", zColumn);
935 rc = sqlite3_strglob(zPattern, zDef)!=0;
936 fossil_free(zPattern);
937 fossil_free(zDef);
938 }
939 return rc;
940 }
941
942 /*
943 ** If zDbName is a valid local database file, open it and return
944 ** true. If it is not a valid local database file, return 0.
@@ -1212,10 +1272,11 @@
1212 fossil_fatal("not in a local checkout");
1213 return;
1214 }
1215 db_open_or_attach(zRepo, "test_repo", 0);
1216 db_lset("repository", blob_str(&repo));
 
1217 db_close(1);
1218 }
1219
1220
1221 /*
@@ -2004,31 +2065,10 @@
2004 }
2005 void db_lset_int(const char *zName, int value){
2006 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
2007 }
2008
2009 /*
2010 ** Returns non-0 if the database (which must be open) table identified
2011 ** by zTableName has a column named zColName (case-sensitive), else
2012 ** returns 0.
2013 */
2014 int db_table_has_column(const char *zTableName, const char *zColName){
2015 Stmt q = empty_Stmt;
2016 int rc = 0;
2017 db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
2018 while(SQLITE_ROW == db_step(&q)){
2019 /* Columns: (cid, name, type, notnull, dflt_value, pk) */
2020 const char *zCol = db_column_text(&q, 1);
2021 if( 0==fossil_strcmp(zColName, zCol) ){
2022 rc = 1;
2023 break;
2024 }
2025 }
2026 db_finalize(&q);
2027 return rc;
2028 }
2029
2030 /*
2031 ** Record the name of a local repository in the global_config() database.
2032 ** The repository filename %s is recorded as an entry with a "name" field
2033 ** of the following form:
2034 **
2035
--- 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){
@@ -915,30 +958,47 @@
958 g.zConfigDbType = "configdb";
959 }
960 g.zConfigDbName = zDbName;
961 }
962
963 /*
964 ** Return TRUE if zTable exists.
965 */
966 int db_table_exists(
967 const char *zDb, /* One of: NULL, "configdb", "localdb", "repository" */
968 const char *zTable /* Name of table */
969 ){
970 return sqlite3_table_column_metadata(g.db,
971 zDb ? db_name(zDb) : 0, zTable, 0,
972 0, 0, 0, 0, 0)==SQLITE_OK;
973 }
974
975 /*
976 ** Return TRUE if zTable exists and contains column zColumn.
977 ** Return FALSE if zTable does not exist or if zTable exists
978 ** but lacks zColumn.
979 */
980 int db_table_has_column(
981 const char *zDb, /* One of: NULL, "config", "localdb", "repository" */
982 const char *zTable, /* Name of table */
983 const char *zColumn /* Name of column in table */
984 ){
985 return sqlite3_table_column_metadata(g.db,
986 zDb ? db_name(zDb) : 0, zTable, zColumn,
987 0, 0, 0, 0, 0)==SQLITE_OK;
988 }
989
990 /*
991 ** Returns TRUE if zTable exists in the local database but lacks column
992 ** zColumn
993 */
994 static int db_local_table_exists_but_lacks_column(
995 const char *zTable,
996 const char *zColumn
997 ){
998 return db_table_exists(db_name("localdb"), zTable)
999 && !db_table_has_column(db_name("localdb"), zTable, zColumn);
 
 
 
 
 
 
 
 
 
1000 }
1001
1002 /*
1003 ** If zDbName is a valid local database file, open it and return
1004 ** true. If it is not a valid local database file, return 0.
@@ -1212,10 +1272,11 @@
1272 fossil_fatal("not in a local checkout");
1273 return;
1274 }
1275 db_open_or_attach(zRepo, "test_repo", 0);
1276 db_lset("repository", blob_str(&repo));
1277 db_record_repository_filename(blob_str(&repo));
1278 db_close(1);
1279 }
1280
1281
1282 /*
@@ -2004,31 +2065,10 @@
2065 }
2066 void db_lset_int(const char *zName, int value){
2067 db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
2068 }
2069
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2070 /*
2071 ** Record the name of a local repository in the global_config() database.
2072 ** The repository filename %s is recorded as an entry with a "name" field
2073 ** of the following form:
2074 **
2075
--- src/descendants.c
+++ src/descendants.c
@@ -289,14 +289,14 @@
289289
}
290290
291291
/*
292292
** COMMAND: descendants*
293293
**
294
-** Usage: %fossil descendants ?BASELINE-ID? ?OPTIONS?
294
+** Usage: %fossil descendants ?CHECKIN? ?OPTIONS?
295295
**
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.
298298
**
299299
** Options:
300300
** -R|--repository FILE Extract info from repository FILE
301301
** -W|--width <num> Width of lines (default is to auto-detect).
302302
** Must be >20 or 0 (= no limit, resulting in a
@@ -334,11 +334,11 @@
334334
"%s"
335335
" AND event.objid IN (SELECT rid FROM leaves)"
336336
" ORDER BY event.mtime DESC",
337337
timeline_query_for_tty()
338338
);
339
- print_timeline(&q, -20, width, 0);
339
+ print_timeline(&q, 0, width, 0);
340340
db_finalize(&q);
341341
}
342342
343343
/*
344344
** COMMAND: leaves*
345345
--- 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
+2 -2
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -363,20 +363,20 @@
363363
"SELECT pathname, 0, 0, 1, 0, islink"
364364
" FROM vfile v2"
365365
" WHERE v2.vid=%d"
366366
" AND NOT EXISTS(SELECT 1 FROM vfile v1"
367367
" WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368
- " ORDER BY 1",
368
+ " ORDER BY 1 /*scan*/",
369369
rid, vid, rid, vid, vid, rid
370370
);
371371
}else{
372372
blob_append_sql(&sql,
373373
"SELECT pathname, deleted, chnged , rid==0, rid, islink"
374374
" FROM vfile"
375375
" WHERE vid=%d"
376376
" AND (deleted OR chnged OR rid==0)"
377
- " ORDER BY pathname",
377
+ " ORDER BY pathname /*scan*/",
378378
vid
379379
);
380380
}
381381
db_prepare(&q, "%s", blob_sql_text(&sql));
382382
while( db_step(&q)==SQLITE_ROW ){
383383
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -363,20 +363,20 @@
363 "SELECT pathname, 0, 0, 1, 0, islink"
364 " FROM vfile v2"
365 " WHERE v2.vid=%d"
366 " AND NOT EXISTS(SELECT 1 FROM vfile v1"
367 " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368 " ORDER BY 1",
369 rid, vid, rid, vid, vid, rid
370 );
371 }else{
372 blob_append_sql(&sql,
373 "SELECT pathname, deleted, chnged , rid==0, rid, islink"
374 " FROM vfile"
375 " WHERE vid=%d"
376 " AND (deleted OR chnged OR rid==0)"
377 " ORDER BY pathname",
378 vid
379 );
380 }
381 db_prepare(&q, "%s", blob_sql_text(&sql));
382 while( db_step(&q)==SQLITE_ROW ){
383
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -363,20 +363,20 @@
363 "SELECT pathname, 0, 0, 1, 0, islink"
364 " FROM vfile v2"
365 " WHERE v2.vid=%d"
366 " AND NOT EXISTS(SELECT 1 FROM vfile v1"
367 " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
368 " ORDER BY 1 /*scan*/",
369 rid, vid, rid, vid, vid, rid
370 );
371 }else{
372 blob_append_sql(&sql,
373 "SELECT pathname, deleted, chnged , rid==0, rid, islink"
374 " FROM vfile"
375 " WHERE vid=%d"
376 " AND (deleted OR chnged OR rid==0)"
377 " ORDER BY pathname /*scan*/",
378 vid
379 );
380 }
381 db_prepare(&q, "%s", blob_sql_text(&sql));
382 while( db_step(&q)==SQLITE_ROW ){
383
--- src/finfo.c
+++ src/finfo.c
@@ -495,10 +495,11 @@
495495
@ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) sz=%d(sz)
496496
if( srcid ){
497497
@ srcid=%d(srcid)
498498
}
499499
}
500
+ tag_private_status(frid);
500501
@ </td></tr>
501502
}
502503
db_finalize(&q);
503504
if( pGraph ){
504505
graph_finish(pGraph, 0);
505506
--- 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
+10 -9
--- src/foci.c
+++ src/foci.c
@@ -46,11 +46,12 @@
4646
sqlite3_vtab base; /* Base class - must be first */
4747
};
4848
struct FociCursor {
4949
sqlite3_vtab_cursor base; /* Base class - must be first */
5050
Manifest *pMan; /* Current manifest */
51
- int iFile; /* Index of current file */
51
+ ManifestFile *pFile; /* Current file */
52
+ int iFile; /* File index */
5253
};
5354
#endif /* INTERFACE */
5455
5556
5657
/*
@@ -104,14 +105,11 @@
104105
105106
/*
106107
** Open a new focivfs cursor.
107108
*/
108109
static int fociOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
109
- FociTable *pTab = (FociTable *)pVTab;
110110
FociCursor *pCsr;
111
- int rc;
112
-
113111
pCsr = (FociCursor *)sqlite3_malloc(sizeof(FociCursor));
114112
memset(pCsr, 0, sizeof(FociCursor));
115113
pCsr->base.pVtab = pVTab;
116114
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
117115
return SQLITE_OK;
@@ -130,17 +128,18 @@
130128
/*
131129
** Move a focivfs cursor to the next entry in the file.
132130
*/
133131
static int fociNext(sqlite3_vtab_cursor *pCursor){
134132
FociCursor *pCsr = (FociCursor *)pCursor;
133
+ pCsr->pFile = manifest_file_next(pCsr->pMan, 0);
135134
pCsr->iFile++;
136135
return SQLITE_OK;
137136
}
138137
139138
static int fociEof(sqlite3_vtab_cursor *pCursor){
140139
FociCursor *pCsr = (FociCursor *)pCursor;
141
- return pCsr->pMan==0 || pCsr->iFile>=pCsr->pMan->nFile;
140
+ return pCsr->pFile==0;
142141
}
143142
144143
static int fociFilter(
145144
sqlite3_vtab_cursor *pCursor,
146145
int idxNum, const char *idxStr,
@@ -149,10 +148,12 @@
149148
FociCursor *pCur = (FociCursor *)pCursor;
150149
manifest_destroy(pCur->pMan);
151150
if( idxNum ){
152151
pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0);
153152
pCur->iFile = 0;
153
+ manifest_file_rewind(pCur->pMan);
154
+ pCur->pFile = manifest_file_next(pCur->pMan, 0);
154155
}else{
155156
pCur->pMan = 0;
156157
pCur->iFile = 0;
157158
}
158159
return SQLITE_OK;
@@ -167,23 +168,23 @@
167168
switch( i ){
168169
case 0: /* checkinID */
169170
sqlite3_result_int(ctx, pCsr->pMan->rid);
170171
break;
171172
case 1: /* filename */
172
- sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zName, -1,
173
+ sqlite3_result_text(ctx, pCsr->pFile->zName, -1,
173174
SQLITE_TRANSIENT);
174175
break;
175176
case 2: /* uuid */
176
- sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zUuid, -1,
177
+ sqlite3_result_text(ctx, pCsr->pFile->zUuid, -1,
177178
SQLITE_TRANSIENT);
178179
break;
179180
case 3: /* previousName */
180
- sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPrior, -1,
181
+ sqlite3_result_text(ctx, pCsr->pFile->zPrior, -1,
181182
SQLITE_TRANSIENT);
182183
break;
183184
case 4: /* perm */
184
- sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPerm, -1,
185
+ sqlite3_result_text(ctx, pCsr->pFile->zPerm, -1,
185186
SQLITE_TRANSIENT);
186187
break;
187188
}
188189
return SQLITE_OK;
189190
}
190191
--- src/foci.c
+++ src/foci.c
@@ -46,11 +46,12 @@
46 sqlite3_vtab base; /* Base class - must be first */
47 };
48 struct FociCursor {
49 sqlite3_vtab_cursor base; /* Base class - must be first */
50 Manifest *pMan; /* Current manifest */
51 int iFile; /* Index of current file */
 
52 };
53 #endif /* INTERFACE */
54
55
56 /*
@@ -104,14 +105,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;
@@ -130,17 +128,18 @@
130 /*
131 ** Move a focivfs cursor to the next entry in the file.
132 */
133 static int fociNext(sqlite3_vtab_cursor *pCursor){
134 FociCursor *pCsr = (FociCursor *)pCursor;
 
135 pCsr->iFile++;
136 return SQLITE_OK;
137 }
138
139 static int fociEof(sqlite3_vtab_cursor *pCursor){
140 FociCursor *pCsr = (FociCursor *)pCursor;
141 return pCsr->pMan==0 || pCsr->iFile>=pCsr->pMan->nFile;
142 }
143
144 static int fociFilter(
145 sqlite3_vtab_cursor *pCursor,
146 int idxNum, const char *idxStr,
@@ -149,10 +148,12 @@
149 FociCursor *pCur = (FociCursor *)pCursor;
150 manifest_destroy(pCur->pMan);
151 if( idxNum ){
152 pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0);
153 pCur->iFile = 0;
 
 
154 }else{
155 pCur->pMan = 0;
156 pCur->iFile = 0;
157 }
158 return SQLITE_OK;
@@ -167,23 +168,23 @@
167 switch( i ){
168 case 0: /* checkinID */
169 sqlite3_result_int(ctx, pCsr->pMan->rid);
170 break;
171 case 1: /* filename */
172 sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zName, -1,
173 SQLITE_TRANSIENT);
174 break;
175 case 2: /* uuid */
176 sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zUuid, -1,
177 SQLITE_TRANSIENT);
178 break;
179 case 3: /* previousName */
180 sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPrior, -1,
181 SQLITE_TRANSIENT);
182 break;
183 case 4: /* perm */
184 sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPerm, -1,
185 SQLITE_TRANSIENT);
186 break;
187 }
188 return SQLITE_OK;
189 }
190
--- src/foci.c
+++ src/foci.c
@@ -46,11 +46,12 @@
46 sqlite3_vtab base; /* Base class - must be first */
47 };
48 struct FociCursor {
49 sqlite3_vtab_cursor base; /* Base class - must be first */
50 Manifest *pMan; /* Current manifest */
51 ManifestFile *pFile; /* Current file */
52 int iFile; /* File index */
53 };
54 #endif /* INTERFACE */
55
56
57 /*
@@ -104,14 +105,11 @@
105
106 /*
107 ** Open a new focivfs cursor.
108 */
109 static int fociOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
 
110 FociCursor *pCsr;
 
 
111 pCsr = (FociCursor *)sqlite3_malloc(sizeof(FociCursor));
112 memset(pCsr, 0, sizeof(FociCursor));
113 pCsr->base.pVtab = pVTab;
114 *ppCursor = (sqlite3_vtab_cursor *)pCsr;
115 return SQLITE_OK;
@@ -130,17 +128,18 @@
128 /*
129 ** Move a focivfs cursor to the next entry in the file.
130 */
131 static int fociNext(sqlite3_vtab_cursor *pCursor){
132 FociCursor *pCsr = (FociCursor *)pCursor;
133 pCsr->pFile = manifest_file_next(pCsr->pMan, 0);
134 pCsr->iFile++;
135 return SQLITE_OK;
136 }
137
138 static int fociEof(sqlite3_vtab_cursor *pCursor){
139 FociCursor *pCsr = (FociCursor *)pCursor;
140 return pCsr->pFile==0;
141 }
142
143 static int fociFilter(
144 sqlite3_vtab_cursor *pCursor,
145 int idxNum, const char *idxStr,
@@ -149,10 +148,12 @@
148 FociCursor *pCur = (FociCursor *)pCursor;
149 manifest_destroy(pCur->pMan);
150 if( idxNum ){
151 pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0);
152 pCur->iFile = 0;
153 manifest_file_rewind(pCur->pMan);
154 pCur->pFile = manifest_file_next(pCur->pMan, 0);
155 }else{
156 pCur->pMan = 0;
157 pCur->iFile = 0;
158 }
159 return SQLITE_OK;
@@ -167,23 +168,23 @@
168 switch( i ){
169 case 0: /* checkinID */
170 sqlite3_result_int(ctx, pCsr->pMan->rid);
171 break;
172 case 1: /* filename */
173 sqlite3_result_text(ctx, pCsr->pFile->zName, -1,
174 SQLITE_TRANSIENT);
175 break;
176 case 2: /* uuid */
177 sqlite3_result_text(ctx, pCsr->pFile->zUuid, -1,
178 SQLITE_TRANSIENT);
179 break;
180 case 3: /* previousName */
181 sqlite3_result_text(ctx, pCsr->pFile->zPrior, -1,
182 SQLITE_TRANSIENT);
183 break;
184 case 4: /* perm */
185 sqlite3_result_text(ctx, pCsr->pFile->zPerm, -1,
186 SQLITE_TRANSIENT);
187 break;
188 }
189 return SQLITE_OK;
190 }
191
--- src/fusefs.c
+++ src/fusefs.c
@@ -319,11 +319,10 @@
319319
#ifndef FOSSIL_HAVE_FUSEFS
320320
fossil_fatal("this build of fossil does not support the fuse filesystem");
321321
#else
322322
char *zMountPoint;
323323
char *azNewArgv[5];
324
- int i;
325324
int doDebug = find_option("debug","d",0)!=0;
326325
327326
db_find_and_open_repository(0,0);
328327
verify_all_options();
329328
blob_init(&fusefs.content, 0, 0);
330329
--- 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
+8 -6
--- src/http.c
+++ src/http.c
@@ -285,11 +285,11 @@
285285
g.zHttpAuth = prompt_for_httpauth_creds();
286286
transport_close(&g.url);
287287
return http_exchange(pSend, pReply, useLogin, maxRedirect);
288288
}
289289
}
290
- if( rc!=200 && rc!=302 ){
290
+ if( rc!=200 && rc!=301 && rc!=302 ){
291291
int ii;
292292
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
293293
while( zLine[ii]==' ' ) ii++;
294294
fossil_warning("server says: %s", &zLine[ii]);
295295
goto write_err;
@@ -299,11 +299,11 @@
299299
}else{
300300
closeConnection = 0;
301301
}
302302
}else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
303303
if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
304
- if( rc!=200 && rc!=302 ){
304
+ if( rc!=200 && rc!=301 && rc!=302 ){
305305
int ii;
306306
for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
307307
while( zLine[ii]==' ' ) ii++;
308308
fossil_warning("server says: %s", &zLine[ii]);
309309
goto write_err;
@@ -319,11 +319,12 @@
319319
if( c=='c' || c=='C' ){
320320
closeConnection = 1;
321321
}else if( c=='k' || c=='K' ){
322322
closeConnection = 0;
323323
}
324
- }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){
324
+ }else if( ( rc==301 || rc==302 ) &&
325
+ fossil_strnicmp(zLine, "location:", 9)==0 ){
325326
int i, j;
326327
327328
if ( --maxRedirect == 0){
328329
fossil_warning("redirect limit exceeded");
329330
goto write_err;
@@ -336,16 +337,17 @@
336337
j = strlen(zLine) - 1;
337338
while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
338339
j -= 4;
339340
zLine[j] = 0;
340341
}
341
- fossil_print("redirect to %s\n", &zLine[i]);
342
+ transport_close(&g.url);
343
+ transport_global_shutdown(&g.url);
344
+ fossil_print("redirect with status %d to %s\n", rc, &zLine[i]);
342345
url_parse(&zLine[i], 0);
343346
fSeenHttpAuth = 0;
344347
if( g.zHttpAuth ) free(g.zHttpAuth);
345348
g.zHttpAuth = get_httpauth();
346
- transport_close(&g.url);
347349
return http_exchange(pSend, pReply, useLogin, maxRedirect);
348350
}else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
349351
if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
350352
isCompressed = 0;
351353
}else if( fossil_strnicmp(&zLine[14],
@@ -359,11 +361,11 @@
359361
if( iLength<0 ){
360362
fossil_warning("server did not reply");
361363
goto write_err;
362364
}
363365
if( rc!=200 ){
364
- fossil_warning("\"location:\" missing from 302 redirect reply");
366
+ fossil_warning("\"location:\" missing from %d redirect reply", rc);
365367
goto write_err;
366368
}
367369
368370
/*
369371
** Extract the reply payload that follows the header
370372
--- src/http.c
+++ src/http.c
@@ -285,11 +285,11 @@
285 g.zHttpAuth = prompt_for_httpauth_creds();
286 transport_close(&g.url);
287 return http_exchange(pSend, pReply, useLogin, maxRedirect);
288 }
289 }
290 if( rc!=200 && rc!=302 ){
291 int ii;
292 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
293 while( zLine[ii]==' ' ) ii++;
294 fossil_warning("server says: %s", &zLine[ii]);
295 goto write_err;
@@ -299,11 +299,11 @@
299 }else{
300 closeConnection = 0;
301 }
302 }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
303 if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
304 if( rc!=200 && rc!=302 ){
305 int ii;
306 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
307 while( zLine[ii]==' ' ) ii++;
308 fossil_warning("server says: %s", &zLine[ii]);
309 goto write_err;
@@ -319,11 +319,12 @@
319 if( c=='c' || c=='C' ){
320 closeConnection = 1;
321 }else if( c=='k' || c=='K' ){
322 closeConnection = 0;
323 }
324 }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){
 
325 int i, j;
326
327 if ( --maxRedirect == 0){
328 fossil_warning("redirect limit exceeded");
329 goto write_err;
@@ -336,16 +337,17 @@
336 j = strlen(zLine) - 1;
337 while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
338 j -= 4;
339 zLine[j] = 0;
340 }
341 fossil_print("redirect to %s\n", &zLine[i]);
 
 
342 url_parse(&zLine[i], 0);
343 fSeenHttpAuth = 0;
344 if( g.zHttpAuth ) free(g.zHttpAuth);
345 g.zHttpAuth = get_httpauth();
346 transport_close(&g.url);
347 return http_exchange(pSend, pReply, useLogin, maxRedirect);
348 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
349 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
350 isCompressed = 0;
351 }else if( fossil_strnicmp(&zLine[14],
@@ -359,11 +361,11 @@
359 if( iLength<0 ){
360 fossil_warning("server did not reply");
361 goto write_err;
362 }
363 if( rc!=200 ){
364 fossil_warning("\"location:\" missing from 302 redirect reply");
365 goto write_err;
366 }
367
368 /*
369 ** Extract the reply payload that follows the header
370
--- src/http.c
+++ src/http.c
@@ -285,11 +285,11 @@
285 g.zHttpAuth = prompt_for_httpauth_creds();
286 transport_close(&g.url);
287 return http_exchange(pSend, pReply, useLogin, maxRedirect);
288 }
289 }
290 if( rc!=200 && rc!=301 && rc!=302 ){
291 int ii;
292 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
293 while( zLine[ii]==' ' ) ii++;
294 fossil_warning("server says: %s", &zLine[ii]);
295 goto write_err;
@@ -299,11 +299,11 @@
299 }else{
300 closeConnection = 0;
301 }
302 }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
303 if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
304 if( rc!=200 && rc!=301 && rc!=302 ){
305 int ii;
306 for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
307 while( zLine[ii]==' ' ) ii++;
308 fossil_warning("server says: %s", &zLine[ii]);
309 goto write_err;
@@ -319,11 +319,12 @@
319 if( c=='c' || c=='C' ){
320 closeConnection = 1;
321 }else if( c=='k' || c=='K' ){
322 closeConnection = 0;
323 }
324 }else if( ( rc==301 || rc==302 ) &&
325 fossil_strnicmp(zLine, "location:", 9)==0 ){
326 int i, j;
327
328 if ( --maxRedirect == 0){
329 fossil_warning("redirect limit exceeded");
330 goto write_err;
@@ -336,16 +337,17 @@
337 j = strlen(zLine) - 1;
338 while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
339 j -= 4;
340 zLine[j] = 0;
341 }
342 transport_close(&g.url);
343 transport_global_shutdown(&g.url);
344 fossil_print("redirect with status %d to %s\n", rc, &zLine[i]);
345 url_parse(&zLine[i], 0);
346 fSeenHttpAuth = 0;
347 if( g.zHttpAuth ) free(g.zHttpAuth);
348 g.zHttpAuth = get_httpauth();
 
349 return http_exchange(pSend, pReply, useLogin, maxRedirect);
350 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
351 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
352 isCompressed = 0;
353 }else if( fossil_strnicmp(&zLine[14],
@@ -359,11 +361,11 @@
361 if( iLength<0 ){
362 fossil_warning("server did not reply");
363 goto write_err;
364 }
365 if( rc!=200 ){
366 fossil_warning("\"location:\" missing from %d redirect reply", rc);
367 goto write_err;
368 }
369
370 /*
371 ** Extract the reply payload that follows the header
372
--- src/http_socket.c
+++ src/http_socket.c
@@ -45,10 +45,11 @@
4545
** There can only be a single socket connection open at a time.
4646
** State information about that socket is stored in the following
4747
** local variables:
4848
*/
4949
static int socketIsInit = 0; /* True after global initialization */
50
+static int addrIsInit = 0; /* True once addr is initialized */
5051
#if defined(_WIN32)
5152
static WSADATA socketInfo; /* Windows socket initialize data */
5253
#endif
5354
static int iSocket = -1; /* The socket on which we talk to the server */
5455
static char *socketErrMsg = 0; /* Text of most recent socket error */
@@ -105,10 +106,11 @@
105106
WSACleanup();
106107
#endif
107108
socket_clear_errmsg();
108109
socketIsInit = 0;
109110
}
111
+ addrIsInit = 0;
110112
}
111113
112114
/*
113115
** Close the currently open socket. If no socket is open, this routine
114116
** is a no-op.
@@ -133,14 +135,14 @@
133135
**
134136
** Return the number of errors.
135137
*/
136138
int socket_open(UrlData *pUrlData){
137139
static struct sockaddr_in addr; /* The server address */
138
- static int addrIsInit = 0; /* True once addr is initialized */
139140
140141
socket_global_init();
141142
if( !addrIsInit ){
143
+ memset(&addr, 0, sizeof(addr));
142144
addr.sin_family = AF_INET;
143145
addr.sin_port = htons(pUrlData->port);
144146
*(int*)&addr.sin_addr = inet_addr(pUrlData->name);
145147
if( -1 == *(int*)&addr.sin_addr ){
146148
#ifndef FOSSIL_STATIC_LINK
147149
--- src/http_socket.c
+++ src/http_socket.c
@@ -45,10 +45,11 @@
45 ** There can only be a single socket connection open at a time.
46 ** State information about that socket is stored in the following
47 ** local variables:
48 */
49 static int socketIsInit = 0; /* True after global initialization */
 
50 #if defined(_WIN32)
51 static WSADATA socketInfo; /* Windows socket initialize data */
52 #endif
53 static int iSocket = -1; /* The socket on which we talk to the server */
54 static char *socketErrMsg = 0; /* Text of most recent socket error */
@@ -105,10 +106,11 @@
105 WSACleanup();
106 #endif
107 socket_clear_errmsg();
108 socketIsInit = 0;
109 }
 
110 }
111
112 /*
113 ** Close the currently open socket. If no socket is open, this routine
114 ** is a no-op.
@@ -133,14 +135,14 @@
133 **
134 ** Return the number of errors.
135 */
136 int socket_open(UrlData *pUrlData){
137 static struct sockaddr_in addr; /* The server address */
138 static int addrIsInit = 0; /* True once addr is initialized */
139
140 socket_global_init();
141 if( !addrIsInit ){
 
142 addr.sin_family = AF_INET;
143 addr.sin_port = htons(pUrlData->port);
144 *(int*)&addr.sin_addr = inet_addr(pUrlData->name);
145 if( -1 == *(int*)&addr.sin_addr ){
146 #ifndef FOSSIL_STATIC_LINK
147
--- src/http_socket.c
+++ src/http_socket.c
@@ -45,10 +45,11 @@
45 ** There can only be a single socket connection open at a time.
46 ** State information about that socket is stored in the following
47 ** local variables:
48 */
49 static int socketIsInit = 0; /* True after global initialization */
50 static int addrIsInit = 0; /* True once addr is initialized */
51 #if defined(_WIN32)
52 static WSADATA socketInfo; /* Windows socket initialize data */
53 #endif
54 static int iSocket = -1; /* The socket on which we talk to the server */
55 static char *socketErrMsg = 0; /* Text of most recent socket error */
@@ -105,10 +106,11 @@
106 WSACleanup();
107 #endif
108 socket_clear_errmsg();
109 socketIsInit = 0;
110 }
111 addrIsInit = 0;
112 }
113
114 /*
115 ** Close the currently open socket. If no socket is open, this routine
116 ** is a no-op.
@@ -133,14 +135,14 @@
135 **
136 ** Return the number of errors.
137 */
138 int socket_open(UrlData *pUrlData){
139 static struct sockaddr_in addr; /* The server address */
 
140
141 socket_global_init();
142 if( !addrIsInit ){
143 memset(&addr, 0, sizeof(addr));
144 addr.sin_family = AF_INET;
145 addr.sin_port = htons(pUrlData->port);
146 *(int*)&addr.sin_addr = inet_addr(pUrlData->name);
147 if( -1 == *(int*)&addr.sin_addr ){
148 #ifndef FOSSIL_STATIC_LINK
149
+4 -3
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -41,11 +41,11 @@
4141
** There can only be a single OpenSSL IO connection open at a time.
4242
** State information about that IO is stored in the following
4343
** local variables:
4444
*/
4545
static int sslIsInit = 0; /* True after global initialization */
46
-static BIO *iBio; /* OpenSSL I/O abstraction */
46
+static BIO *iBio = 0; /* OpenSSL I/O abstraction */
4747
static char *sslErrMsg = 0; /* Text of most recent OpenSSL error */
4848
static SSL_CTX *sslCtx; /* SSL context */
4949
static SSL *ssl;
5050
5151
@@ -99,12 +99,12 @@
9999
SSL_library_init();
100100
SSL_load_error_strings();
101101
ERR_load_BIO_strings();
102102
OpenSSL_add_all_algorithms();
103103
sslCtx = SSL_CTX_new(SSLv23_client_method());
104
- /* Disable SSLv2 */
105
- SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2);
104
+ /* Disable SSLv2 and SSLv3 */
105
+ SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
106106
107107
/* Set up acceptable CA root certificates */
108108
zCaSetting = db_get("ssl-ca-location", 0);
109109
if( zCaSetting==0 || zCaSetting[0]=='\0' ){
110110
/* CA location not specified, use platform's default certificate store */
@@ -171,10 +171,11 @@
171171
*/
172172
void ssl_close(void){
173173
if( iBio!=NULL ){
174174
(void)BIO_reset(iBio);
175175
BIO_free_all(iBio);
176
+ iBio = NULL;
176177
}
177178
}
178179
179180
/* See RFC2817 for details */
180181
static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
181182
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -41,11 +41,11 @@
41 ** There can only be a single OpenSSL IO connection open at a time.
42 ** State information about that IO is stored in the following
43 ** local variables:
44 */
45 static int sslIsInit = 0; /* True after global initialization */
46 static BIO *iBio; /* OpenSSL I/O abstraction */
47 static char *sslErrMsg = 0; /* Text of most recent OpenSSL error */
48 static SSL_CTX *sslCtx; /* SSL context */
49 static SSL *ssl;
50
51
@@ -99,12 +99,12 @@
99 SSL_library_init();
100 SSL_load_error_strings();
101 ERR_load_BIO_strings();
102 OpenSSL_add_all_algorithms();
103 sslCtx = SSL_CTX_new(SSLv23_client_method());
104 /* Disable SSLv2 */
105 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2);
106
107 /* Set up acceptable CA root certificates */
108 zCaSetting = db_get("ssl-ca-location", 0);
109 if( zCaSetting==0 || zCaSetting[0]=='\0' ){
110 /* CA location not specified, use platform's default certificate store */
@@ -171,10 +171,11 @@
171 */
172 void ssl_close(void){
173 if( iBio!=NULL ){
174 (void)BIO_reset(iBio);
175 BIO_free_all(iBio);
 
176 }
177 }
178
179 /* See RFC2817 for details */
180 static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
181
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -41,11 +41,11 @@
41 ** There can only be a single OpenSSL IO connection open at a time.
42 ** State information about that IO is stored in the following
43 ** local variables:
44 */
45 static int sslIsInit = 0; /* True after global initialization */
46 static BIO *iBio = 0; /* OpenSSL I/O abstraction */
47 static char *sslErrMsg = 0; /* Text of most recent OpenSSL error */
48 static SSL_CTX *sslCtx; /* SSL context */
49 static SSL *ssl;
50
51
@@ -99,12 +99,12 @@
99 SSL_library_init();
100 SSL_load_error_strings();
101 ERR_load_BIO_strings();
102 OpenSSL_add_all_algorithms();
103 sslCtx = SSL_CTX_new(SSLv23_client_method());
104 /* Disable SSLv2 and SSLv3 */
105 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
106
107 /* Set up acceptable CA root certificates */
108 zCaSetting = db_get("ssl-ca-location", 0);
109 if( zCaSetting==0 || zCaSetting[0]=='\0' ){
110 /* CA location not specified, use platform's default certificate store */
@@ -171,10 +171,11 @@
171 */
172 void ssl_close(void){
173 if( iBio!=NULL ){
174 (void)BIO_reset(iBio);
175 BIO_free_all(iBio);
176 iBio = NULL;
177 }
178 }
179
180 /* See RFC2817 for details */
181 static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
182
+7 -2
--- src/info.c
+++ src/info.c
@@ -931,10 +931,11 @@
931931
}else{
932932
@ tags: %h(zTagList),
933933
}
934934
@ date:
935935
hyperlink_to_date(zDate, ")");
936
+ tag_private_status(rid);
936937
}
937938
db_finalize(&q);
938939
}
939940
940941
@@ -1203,19 +1204,20 @@
12031204
}else{
12041205
@ <li>File
12051206
}
12061207
objType |= OBJTYPE_CONTENT;
12071208
@ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
1209
+ tag_private_status(rid);
12081210
if( showDetail ){
12091211
@ <ul>
12101212
}
12111213
prevName = fossil_strdup(zName);
12121214
}
12131215
if( showDetail ){
12141216
@ <li>
12151217
hyperlink_to_date(zDate,"");
1216
- @ &mdash; part of check-in
1218
+ @ &mdash; part of checkin
12171219
hyperlink_to_uuid(zVers);
12181220
}else{
12191221
@ &mdash; part of checkin
12201222
hyperlink_to_uuid(zVers);
12211223
@ at
@@ -1314,10 +1316,11 @@
13141316
hyperlink_to_user(zUser,zDate," on");
13151317
hyperlink_to_date(zDate, ".");
13161318
if( pDownloadName && blob_size(pDownloadName)==0 ){
13171319
blob_appendf(pDownloadName, "%.10s.txt", zUuid);
13181320
}
1321
+ tag_private_status(rid);
13191322
cnt++;
13201323
}
13211324
db_finalize(&q);
13221325
}
13231326
db_prepare(&q,
@@ -1357,17 +1360,19 @@
13571360
hyperlink_to_date(zDate,".");
13581361
cnt++;
13591362
if( pDownloadName && blob_size(pDownloadName)==0 ){
13601363
blob_append(pDownloadName, zFilename, -1);
13611364
}
1365
+ tag_private_status(rid);
13621366
}
13631367
db_finalize(&q);
13641368
if( cnt==0 ){
13651369
@ Control artifact.
13661370
if( pDownloadName && blob_size(pDownloadName)==0 ){
13671371
blob_appendf(pDownloadName, "%.10s.txt", zUuid);
13681372
}
1373
+ tag_private_status(rid);
13691374
}
13701375
return objType;
13711376
}
13721377
13731378
@@ -1914,11 +1919,11 @@
19141919
}
19151920
if( strcmp(zModAction,"approve")==0 ){
19161921
moderation_approve(rid);
19171922
}
19181923
}
1919
- zTktTitle = db_table_has_column( "ticket", "title" )
1924
+ zTktTitle = db_table_has_column("repository", "ticket", "title" )
19201925
? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
19211926
: 0;
19221927
style_header("Ticket Change Details");
19231928
style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid);
19241929
style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
19251930
--- 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 @ &mdash; part of check-in
1217 hyperlink_to_uuid(zVers);
1218 }else{
1219 @ &mdash; 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
@@ -1914,11 +1919,11 @@
1914 }
1915 if( strcmp(zModAction,"approve")==0 ){
1916 moderation_approve(rid);
1917 }
1918 }
1919 zTktTitle = db_table_has_column( "ticket", "title" )
1920 ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
1921 : 0;
1922 style_header("Ticket Change Details");
1923 style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid);
1924 style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
1925
--- 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 @ &mdash; part of checkin
1219 hyperlink_to_uuid(zVers);
1220 }else{
1221 @ &mdash; 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
@@ -1914,11 +1919,11 @@
1919 }
1920 if( strcmp(zModAction,"approve")==0 ){
1921 moderation_approve(rid);
1922 }
1923 }
1924 zTktTitle = db_table_has_column("repository", "ticket", "title" )
1925 ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
1926 : 0;
1927 style_header("Ticket Change Details");
1928 style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid);
1929 style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
1930
--- src/json_branch.c
+++ src/json_branch.c
@@ -66,11 +66,11 @@
6666
cson_value * payV;
6767
cson_object * pay;
6868
cson_value * listV;
6969
cson_array * list;
7070
char const * range = NULL;
71
- int which = 0;
71
+ int branchListFlags = BRL_OPEN_ONLY;
7272
char * sawConversionError = NULL;
7373
Stmt q;
7474
if( !g.perm.Read ){
7575
json_set_err(FSL_JSON_E_DENIED,
7676
"Requires 'o' permissions.");
@@ -102,19 +102,19 @@
102102
}
103103
/* Normalize range values... */
104104
switch(*range){
105105
case 'c':
106106
range = "closed";
107
- which = -1;
107
+ branchListFlags = BRL_CLOSED_ONLY;
108108
break;
109109
case 'a':
110110
range = "all";
111
- which = 1;
111
+ branchListFlags = BRL_BOTH;
112112
break;
113113
default:
114114
range = "open";
115
- which = 0;
115
+ branchListFlags = BRL_OPEN_ONLY;
116116
break;
117117
};
118118
cson_object_set(pay,"range",json_new_string(range));
119119
120120
if( g.localOpen ){ /* add "current" property (branch name). */
@@ -128,11 +128,11 @@
128128
cson_object_set(pay,"current",json_new_string(zCurrent));
129129
}
130130
}
131131
132132
133
- branch_prepare_list_query(&q, which);
133
+ branch_prepare_list_query(&q, branchListFlags);
134134
cson_object_set(pay,"branches",listV);
135135
while((SQLITE_ROW==db_step(&q))){
136136
cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
137137
if(v){
138138
cson_array_append(list,v);
139139
--- src/json_branch.c
+++ src/json_branch.c
@@ -66,11 +66,11 @@
66 cson_value * payV;
67 cson_object * pay;
68 cson_value * listV;
69 cson_array * list;
70 char const * range = NULL;
71 int which = 0;
72 char * sawConversionError = NULL;
73 Stmt q;
74 if( !g.perm.Read ){
75 json_set_err(FSL_JSON_E_DENIED,
76 "Requires 'o' permissions.");
@@ -102,19 +102,19 @@
102 }
103 /* Normalize range values... */
104 switch(*range){
105 case 'c':
106 range = "closed";
107 which = -1;
108 break;
109 case 'a':
110 range = "all";
111 which = 1;
112 break;
113 default:
114 range = "open";
115 which = 0;
116 break;
117 };
118 cson_object_set(pay,"range",json_new_string(range));
119
120 if( g.localOpen ){ /* add "current" property (branch name). */
@@ -128,11 +128,11 @@
128 cson_object_set(pay,"current",json_new_string(zCurrent));
129 }
130 }
131
132
133 branch_prepare_list_query(&q, which);
134 cson_object_set(pay,"branches",listV);
135 while((SQLITE_ROW==db_step(&q))){
136 cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
137 if(v){
138 cson_array_append(list,v);
139
--- src/json_branch.c
+++ src/json_branch.c
@@ -66,11 +66,11 @@
66 cson_value * payV;
67 cson_object * pay;
68 cson_value * listV;
69 cson_array * list;
70 char const * range = NULL;
71 int branchListFlags = BRL_OPEN_ONLY;
72 char * sawConversionError = NULL;
73 Stmt q;
74 if( !g.perm.Read ){
75 json_set_err(FSL_JSON_E_DENIED,
76 "Requires 'o' permissions.");
@@ -102,19 +102,19 @@
102 }
103 /* Normalize range values... */
104 switch(*range){
105 case 'c':
106 range = "closed";
107 branchListFlags = BRL_CLOSED_ONLY;
108 break;
109 case 'a':
110 range = "all";
111 branchListFlags = BRL_BOTH;
112 break;
113 default:
114 range = "open";
115 branchListFlags = BRL_OPEN_ONLY;
116 break;
117 };
118 cson_object_set(pay,"range",json_new_string(range));
119
120 if( g.localOpen ){ /* add "current" property (branch name). */
@@ -128,11 +128,11 @@
128 cson_object_set(pay,"current",json_new_string(zCurrent));
129 }
130 }
131
132
133 branch_prepare_list_query(&q, branchListFlags);
134 cson_object_set(pay,"branches",listV);
135 while((SQLITE_ROW==db_step(&q))){
136 cson_value * v = cson_sqlite3_column_to_value(q.pStmt,0);
137 if(v){
138 cson_array_append(list,v);
139
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -88,20 +88,21 @@
8888
db_multi_exec("%s", zSql /*safe-for-%s*/);
8989
}
9090
9191
/*
9292
** Return a pointer to a constant string that forms the basis
93
-** for a timeline query for the JSON interface.
93
+** for a timeline query for the JSON interface. It MUST NOT
94
+** be used in a formatted string argument.
9495
*/
9596
char const * json_timeline_query(void){
9697
/* Field order MUST match that from json_timeline_temp_table()!!! */
9798
static const char zBaseSql[] =
9899
@ SELECT
99100
@ NULL,
100101
@ blob.rid,
101102
@ uuid,
102
- @ CAST(strftime('%%s',event.mtime) AS INTEGER),
103
+ @ CAST(strftime('%s',event.mtime) AS INTEGER),
103104
@ datetime(event.mtime),
104105
@ coalesce(ecomment, comment),
105106
@ coalesce(euser, user),
106107
@ blob.rid IN leaf,
107108
@ bgcolor,
@@ -544,12 +545,11 @@
544545
goto error;
545546
}
546547
547548
#if 0
548549
/* only for testing! */
549
- tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550
- SET("timelineSql");
550
+ cson_object_set(pay, "timelineSql", cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))));
551551
#endif
552552
db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553553
blob_reset(&sql);
554554
db_prepare(&q, "SELECT"
555555
" uuid AS uuid,"
556556
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -88,20 +88,21 @@
88 db_multi_exec("%s", zSql /*safe-for-%s*/);
89 }
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
 
94 */
95 char const * json_timeline_query(void){
96 /* Field order MUST match that from json_timeline_temp_table()!!! */
97 static const char zBaseSql[] =
98 @ SELECT
99 @ NULL,
100 @ blob.rid,
101 @ uuid,
102 @ CAST(strftime('%%s',event.mtime) AS INTEGER),
103 @ datetime(event.mtime),
104 @ coalesce(ecomment, comment),
105 @ coalesce(euser, user),
106 @ blob.rid IN leaf,
107 @ bgcolor,
@@ -544,12 +545,11 @@
544 goto error;
545 }
546
547 #if 0
548 /* only for testing! */
549 tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
550 SET("timelineSql");
551 #endif
552 db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553 blob_reset(&sql);
554 db_prepare(&q, "SELECT"
555 " uuid AS uuid,"
556
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -88,20 +88,21 @@
88 db_multi_exec("%s", zSql /*safe-for-%s*/);
89 }
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface. It MUST NOT
94 ** be used in a formatted string argument.
95 */
96 char const * json_timeline_query(void){
97 /* Field order MUST match that from json_timeline_temp_table()!!! */
98 static const char zBaseSql[] =
99 @ SELECT
100 @ NULL,
101 @ blob.rid,
102 @ uuid,
103 @ CAST(strftime('%s',event.mtime) AS INTEGER),
104 @ datetime(event.mtime),
105 @ coalesce(ecomment, comment),
106 @ coalesce(euser, user),
107 @ blob.rid IN leaf,
108 @ bgcolor,
@@ -544,12 +545,11 @@
545 goto error;
546 }
547
548 #if 0
549 /* only for testing! */
550 cson_object_set(pay, "timelineSql", cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))));
 
551 #endif
552 db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
553 blob_reset(&sql);
554 db_prepare(&q, "SELECT"
555 " uuid AS uuid,"
556
+48
--- src/main.mk
+++ src/main.mk
@@ -21,10 +21,11 @@
2121
$(SRCDIR)/bisect.c \
2222
$(SRCDIR)/blob.c \
2323
$(SRCDIR)/branch.c \
2424
$(SRCDIR)/browse.c \
2525
$(SRCDIR)/builtin.c \
26
+ $(SRCDIR)/bundle.c \
2627
$(SRCDIR)/cache.c \
2728
$(SRCDIR)/captcha.c \
2829
$(SRCDIR)/cgi.c \
2930
$(SRCDIR)/checkin.c \
3031
$(SRCDIR)/checkout.c \
@@ -87,19 +88,22 @@
8788
$(SRCDIR)/path.c \
8889
$(SRCDIR)/pivot.c \
8990
$(SRCDIR)/popen.c \
9091
$(SRCDIR)/pqueue.c \
9192
$(SRCDIR)/printf.c \
93
+ $(SRCDIR)/publish.c \
94
+ $(SRCDIR)/purge.c \
9295
$(SRCDIR)/rebuild.c \
9396
$(SRCDIR)/regexp.c \
9497
$(SRCDIR)/report.c \
9598
$(SRCDIR)/rss.c \
9699
$(SRCDIR)/schema.c \
97100
$(SRCDIR)/search.c \
98101
$(SRCDIR)/setup.c \
99102
$(SRCDIR)/sha1.c \
100103
$(SRCDIR)/shun.c \
104
+ $(SRCDIR)/sitemap.c \
101105
$(SRCDIR)/skins.c \
102106
$(SRCDIR)/sqlcmd.c \
103107
$(SRCDIR)/stash.c \
104108
$(SRCDIR)/stat.c \
105109
$(SRCDIR)/style.c \
@@ -139,10 +143,11 @@
139143
$(OBJDIR)/bisect_.c \
140144
$(OBJDIR)/blob_.c \
141145
$(OBJDIR)/branch_.c \
142146
$(OBJDIR)/browse_.c \
143147
$(OBJDIR)/builtin_.c \
148
+ $(OBJDIR)/bundle_.c \
144149
$(OBJDIR)/cache_.c \
145150
$(OBJDIR)/captcha_.c \
146151
$(OBJDIR)/cgi_.c \
147152
$(OBJDIR)/checkin_.c \
148153
$(OBJDIR)/checkout_.c \
@@ -205,19 +210,22 @@
205210
$(OBJDIR)/path_.c \
206211
$(OBJDIR)/pivot_.c \
207212
$(OBJDIR)/popen_.c \
208213
$(OBJDIR)/pqueue_.c \
209214
$(OBJDIR)/printf_.c \
215
+ $(OBJDIR)/publish_.c \
216
+ $(OBJDIR)/purge_.c \
210217
$(OBJDIR)/rebuild_.c \
211218
$(OBJDIR)/regexp_.c \
212219
$(OBJDIR)/report_.c \
213220
$(OBJDIR)/rss_.c \
214221
$(OBJDIR)/schema_.c \
215222
$(OBJDIR)/search_.c \
216223
$(OBJDIR)/setup_.c \
217224
$(OBJDIR)/sha1_.c \
218225
$(OBJDIR)/shun_.c \
226
+ $(OBJDIR)/sitemap_.c \
219227
$(OBJDIR)/skins_.c \
220228
$(OBJDIR)/sqlcmd_.c \
221229
$(OBJDIR)/stash_.c \
222230
$(OBJDIR)/stat_.c \
223231
$(OBJDIR)/style_.c \
@@ -254,10 +262,11 @@
254262
$(OBJDIR)/bisect.o \
255263
$(OBJDIR)/blob.o \
256264
$(OBJDIR)/branch.o \
257265
$(OBJDIR)/browse.o \
258266
$(OBJDIR)/builtin.o \
267
+ $(OBJDIR)/bundle.o \
259268
$(OBJDIR)/cache.o \
260269
$(OBJDIR)/captcha.o \
261270
$(OBJDIR)/cgi.o \
262271
$(OBJDIR)/checkin.o \
263272
$(OBJDIR)/checkout.o \
@@ -320,19 +329,22 @@
320329
$(OBJDIR)/path.o \
321330
$(OBJDIR)/pivot.o \
322331
$(OBJDIR)/popen.o \
323332
$(OBJDIR)/pqueue.o \
324333
$(OBJDIR)/printf.o \
334
+ $(OBJDIR)/publish.o \
335
+ $(OBJDIR)/purge.o \
325336
$(OBJDIR)/rebuild.o \
326337
$(OBJDIR)/regexp.o \
327338
$(OBJDIR)/report.o \
328339
$(OBJDIR)/rss.o \
329340
$(OBJDIR)/schema.o \
330341
$(OBJDIR)/search.o \
331342
$(OBJDIR)/setup.o \
332343
$(OBJDIR)/sha1.o \
333344
$(OBJDIR)/shun.o \
345
+ $(OBJDIR)/sitemap.o \
334346
$(OBJDIR)/skins.o \
335347
$(OBJDIR)/sqlcmd.o \
336348
$(OBJDIR)/stash.o \
337349
$(OBJDIR)/stat.o \
338350
$(OBJDIR)/style.o \
@@ -478,10 +490,11 @@
478490
$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
479491
$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
480492
$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
481493
$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
482494
$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
495
+ $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
483496
$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
484497
$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
485498
$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
486499
$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
487500
$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -544,19 +557,22 @@
544557
$(OBJDIR)/path_.c:$(OBJDIR)/path.h \
545558
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
546559
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
547560
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
548561
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
562
+ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
563
+ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
549564
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
550565
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
551566
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
552567
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
553568
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
554569
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
555570
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
556571
$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
557572
$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
573
+ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
558574
$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
559575
$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
560576
$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
561577
$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
562578
$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -660,10 +676,18 @@
660676
661677
$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
662678
$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
663679
664680
$(OBJDIR)/builtin.h: $(OBJDIR)/headers
681
+
682
+$(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(OBJDIR)/translate
683
+ $(OBJDIR)/translate $(SRCDIR)/bundle.c >$@
684
+
685
+$(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
686
+ $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c
687
+
688
+$(OBJDIR)/bundle.h: $(OBJDIR)/headers
665689
666690
$(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate
667691
$(OBJDIR)/translate $(SRCDIR)/cache.c >$@
668692
669693
$(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1188,10 +1212,26 @@
11881212
11891213
$(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
11901214
$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
11911215
11921216
$(OBJDIR)/printf.h: $(OBJDIR)/headers
1217
+
1218
+$(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(OBJDIR)/translate
1219
+ $(OBJDIR)/translate $(SRCDIR)/publish.c >$@
1220
+
1221
+$(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
1222
+ $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c
1223
+
1224
+$(OBJDIR)/publish.h: $(OBJDIR)/headers
1225
+
1226
+$(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(OBJDIR)/translate
1227
+ $(OBJDIR)/translate $(SRCDIR)/purge.c >$@
1228
+
1229
+$(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
1230
+ $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c
1231
+
1232
+$(OBJDIR)/purge.h: $(OBJDIR)/headers
11931233
11941234
$(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(OBJDIR)/translate
11951235
$(OBJDIR)/translate $(SRCDIR)/rebuild.c >$@
11961236
11971237
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1260,10 +1300,18 @@
12601300
12611301
$(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
12621302
$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
12631303
12641304
$(OBJDIR)/shun.h: $(OBJDIR)/headers
1305
+
1306
+$(OBJDIR)/sitemap_.c: $(SRCDIR)/sitemap.c $(OBJDIR)/translate
1307
+ $(OBJDIR)/translate $(SRCDIR)/sitemap.c >$@
1308
+
1309
+$(OBJDIR)/sitemap.o: $(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
1310
+ $(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c
1311
+
1312
+$(OBJDIR)/sitemap.h: $(OBJDIR)/headers
12651313
12661314
$(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(OBJDIR)/translate
12671315
$(OBJDIR)/translate $(SRCDIR)/skins.c >$@
12681316
12691317
$(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
12701318
--- 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,19 +88,22 @@
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 \
97 $(SRCDIR)/search.c \
98 $(SRCDIR)/setup.c \
99 $(SRCDIR)/sha1.c \
100 $(SRCDIR)/shun.c \
 
101 $(SRCDIR)/skins.c \
102 $(SRCDIR)/sqlcmd.c \
103 $(SRCDIR)/stash.c \
104 $(SRCDIR)/stat.c \
105 $(SRCDIR)/style.c \
@@ -139,10 +143,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,19 +210,22 @@
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 \
215 $(OBJDIR)/search_.c \
216 $(OBJDIR)/setup_.c \
217 $(OBJDIR)/sha1_.c \
218 $(OBJDIR)/shun_.c \
 
219 $(OBJDIR)/skins_.c \
220 $(OBJDIR)/sqlcmd_.c \
221 $(OBJDIR)/stash_.c \
222 $(OBJDIR)/stat_.c \
223 $(OBJDIR)/style_.c \
@@ -254,10 +262,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,19 +329,22 @@
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 \
330 $(OBJDIR)/search.o \
331 $(OBJDIR)/setup.o \
332 $(OBJDIR)/sha1.o \
333 $(OBJDIR)/shun.o \
 
334 $(OBJDIR)/skins.o \
335 $(OBJDIR)/sqlcmd.o \
336 $(OBJDIR)/stash.o \
337 $(OBJDIR)/stat.o \
338 $(OBJDIR)/style.o \
@@ -478,10 +490,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,19 +557,22 @@
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 \
554 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
555 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
556 $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
557 $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
 
558 $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
559 $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
560 $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
561 $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
562 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -660,10 +676,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 +1212,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
@@ -1260,10 +1300,18 @@
1260
1261 $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
1262 $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
1263
1264 $(OBJDIR)/shun.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1265
1266 $(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(OBJDIR)/translate
1267 $(OBJDIR)/translate $(SRCDIR)/skins.c >$@
1268
1269 $(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
1270
--- 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,19 +88,22 @@
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 \
100 $(SRCDIR)/search.c \
101 $(SRCDIR)/setup.c \
102 $(SRCDIR)/sha1.c \
103 $(SRCDIR)/shun.c \
104 $(SRCDIR)/sitemap.c \
105 $(SRCDIR)/skins.c \
106 $(SRCDIR)/sqlcmd.c \
107 $(SRCDIR)/stash.c \
108 $(SRCDIR)/stat.c \
109 $(SRCDIR)/style.c \
@@ -139,10 +143,11 @@
143 $(OBJDIR)/bisect_.c \
144 $(OBJDIR)/blob_.c \
145 $(OBJDIR)/branch_.c \
146 $(OBJDIR)/browse_.c \
147 $(OBJDIR)/builtin_.c \
148 $(OBJDIR)/bundle_.c \
149 $(OBJDIR)/cache_.c \
150 $(OBJDIR)/captcha_.c \
151 $(OBJDIR)/cgi_.c \
152 $(OBJDIR)/checkin_.c \
153 $(OBJDIR)/checkout_.c \
@@ -205,19 +210,22 @@
210 $(OBJDIR)/path_.c \
211 $(OBJDIR)/pivot_.c \
212 $(OBJDIR)/popen_.c \
213 $(OBJDIR)/pqueue_.c \
214 $(OBJDIR)/printf_.c \
215 $(OBJDIR)/publish_.c \
216 $(OBJDIR)/purge_.c \
217 $(OBJDIR)/rebuild_.c \
218 $(OBJDIR)/regexp_.c \
219 $(OBJDIR)/report_.c \
220 $(OBJDIR)/rss_.c \
221 $(OBJDIR)/schema_.c \
222 $(OBJDIR)/search_.c \
223 $(OBJDIR)/setup_.c \
224 $(OBJDIR)/sha1_.c \
225 $(OBJDIR)/shun_.c \
226 $(OBJDIR)/sitemap_.c \
227 $(OBJDIR)/skins_.c \
228 $(OBJDIR)/sqlcmd_.c \
229 $(OBJDIR)/stash_.c \
230 $(OBJDIR)/stat_.c \
231 $(OBJDIR)/style_.c \
@@ -254,10 +262,11 @@
262 $(OBJDIR)/bisect.o \
263 $(OBJDIR)/blob.o \
264 $(OBJDIR)/branch.o \
265 $(OBJDIR)/browse.o \
266 $(OBJDIR)/builtin.o \
267 $(OBJDIR)/bundle.o \
268 $(OBJDIR)/cache.o \
269 $(OBJDIR)/captcha.o \
270 $(OBJDIR)/cgi.o \
271 $(OBJDIR)/checkin.o \
272 $(OBJDIR)/checkout.o \
@@ -320,19 +329,22 @@
329 $(OBJDIR)/path.o \
330 $(OBJDIR)/pivot.o \
331 $(OBJDIR)/popen.o \
332 $(OBJDIR)/pqueue.o \
333 $(OBJDIR)/printf.o \
334 $(OBJDIR)/publish.o \
335 $(OBJDIR)/purge.o \
336 $(OBJDIR)/rebuild.o \
337 $(OBJDIR)/regexp.o \
338 $(OBJDIR)/report.o \
339 $(OBJDIR)/rss.o \
340 $(OBJDIR)/schema.o \
341 $(OBJDIR)/search.o \
342 $(OBJDIR)/setup.o \
343 $(OBJDIR)/sha1.o \
344 $(OBJDIR)/shun.o \
345 $(OBJDIR)/sitemap.o \
346 $(OBJDIR)/skins.o \
347 $(OBJDIR)/sqlcmd.o \
348 $(OBJDIR)/stash.o \
349 $(OBJDIR)/stat.o \
350 $(OBJDIR)/style.o \
@@ -478,10 +490,11 @@
490 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
491 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
492 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
493 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
494 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
495 $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
496 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
497 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
498 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
499 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
500 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -544,19 +557,22 @@
557 $(OBJDIR)/path_.c:$(OBJDIR)/path.h \
558 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
559 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
560 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
561 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
562 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
563 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
564 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
565 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
566 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
567 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
568 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
569 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
570 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
571 $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
572 $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
573 $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
574 $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
575 $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
576 $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
577 $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
578 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -660,10 +676,18 @@
676
677 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
678 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
679
680 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
681
682 $(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(OBJDIR)/translate
683 $(OBJDIR)/translate $(SRCDIR)/bundle.c >$@
684
685 $(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
686 $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c
687
688 $(OBJDIR)/bundle.h: $(OBJDIR)/headers
689
690 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(OBJDIR)/translate
691 $(OBJDIR)/translate $(SRCDIR)/cache.c >$@
692
693 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1188,10 +1212,26 @@
1212
1213 $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
1214 $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
1215
1216 $(OBJDIR)/printf.h: $(OBJDIR)/headers
1217
1218 $(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(OBJDIR)/translate
1219 $(OBJDIR)/translate $(SRCDIR)/publish.c >$@
1220
1221 $(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
1222 $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c
1223
1224 $(OBJDIR)/publish.h: $(OBJDIR)/headers
1225
1226 $(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(OBJDIR)/translate
1227 $(OBJDIR)/translate $(SRCDIR)/purge.c >$@
1228
1229 $(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
1230 $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c
1231
1232 $(OBJDIR)/purge.h: $(OBJDIR)/headers
1233
1234 $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(OBJDIR)/translate
1235 $(OBJDIR)/translate $(SRCDIR)/rebuild.c >$@
1236
1237 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1260,10 +1300,18 @@
1300
1301 $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
1302 $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
1303
1304 $(OBJDIR)/shun.h: $(OBJDIR)/headers
1305
1306 $(OBJDIR)/sitemap_.c: $(SRCDIR)/sitemap.c $(OBJDIR)/translate
1307 $(OBJDIR)/translate $(SRCDIR)/sitemap.c >$@
1308
1309 $(OBJDIR)/sitemap.o: $(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
1310 $(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c
1311
1312 $(OBJDIR)/sitemap.h: $(OBJDIR)/headers
1313
1314 $(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(OBJDIR)/translate
1315 $(OBJDIR)/translate $(SRCDIR)/skins.c >$@
1316
1317 $(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
1318
+41 -7
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -28,10 +28,11 @@
2828
bisect
2929
blob
3030
branch
3131
browse
3232
builtin
33
+ bundle
3334
cache
3435
captcha
3536
cgi
3637
checkin
3738
checkout
@@ -93,19 +94,22 @@
9394
path
9495
pivot
9596
popen
9697
pqueue
9798
printf
99
+ publish
100
+ purge
98101
rebuild
99102
regexp
100103
report
101104
rss
102105
schema
103106
search
104107
setup
105108
sha1
106109
shun
110
+ sitemap
107111
skins
108112
sqlcmd
109113
stash
110114
stat
111115
style
@@ -510,11 +514,12 @@
510514
# This is useful when Tcl has been compiled statically with MinGW.
511515
#
512516
FOSSIL_TCL_SOURCE = 1
513517
514518
#### Check if the workaround for the MinGW command line handling needs to
515
-# be enabled by default.
519
+# be enabled by default. This check may be somewhat fragile due to the
520
+# use of "findstring".
516521
#
517522
ifndef MINGW_IS_32BIT_ONLY
518523
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
519524
MINGW_IS_32BIT_ONLY = 1
520525
endif
@@ -523,26 +528,46 @@
523528
#### The directories where the zlib include and library files are located.
524529
#
525530
ZINCDIR = $(SRCDIR)/../compat/zlib
526531
ZLIBDIR = $(SRCDIR)/../compat/zlib
527532
533
+#### Make an attempt to detect if Fossil is being built for the x64 processor
534
+# architecture. This check may be somewhat fragile due to "findstring".
535
+#
528536
ifndef X64
529537
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
530538
X64 = 1
531539
endif
532540
endif
533541
542
+#### Determine if the optimized assembly routines provided with zlib should be
543
+# used, taking into account whether zlib is actually enabled and the target
544
+# processor architecture.
545
+#
534546
ifndef X64
535547
SSLCONFIG = mingw
548
+ifndef FOSSIL_ENABLE_MINIZ
536549
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
537550
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
551
+else
552
+ZLIBCONFIG =
553
+LIBTARGETS =
554
+endif
538555
else
539556
SSLCONFIG = mingw64
540
-ZLIBCONFIG =
557
+ZLIBCONFIG =
541558
LIBTARGETS =
542559
endif
543560
561
+#### Disable creation of the OpenSSL shared libraries. Also, disable support
562
+# for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
563
+#
564
+SSLCONFIG += no-ssl2 no-ssl3 no-shared
565
+
566
+#### When using zlib, make sure that OpenSSL is configured to use the zlib
567
+# that Fossil knows about (i.e. the one within the source tree).
568
+#
544569
ifndef FOSSIL_ENABLE_MINIZ
545570
SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
546571
endif
547572
548573
#### The directories where the OpenSSL include and library files are located.
@@ -1287,23 +1312,32 @@
12871312
SSLLIBDIR = $(SSLDIR)\out32
12881313
SSLLFLAGS = /nologo /opt:ref /debug
12891314
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
12901315
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
12911316
!message Using 'x64' platform for OpenSSL...
1292
-SSLCONFIG = VC-WIN64A no-asm
1317
+# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
1318
+# SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-shared
1319
+SSLCONFIG = VC-WIN64A no-asm no-shared
12931320
SSLSETUP = ms\do_win64a.bat
12941321
SSLNMAKE = ms\nt.mak all
1322
+SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
12951323
!elseif "$(PLATFORM)"=="ia64"
12961324
!message Using 'ia64' platform for OpenSSL...
1297
-SSLCONFIG = VC-WIN64I no-asm
1325
+# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
1326
+# SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-shared
1327
+SSLCONFIG = VC-WIN64I no-asm no-shared
12981328
SSLSETUP = ms\do_win64i.bat
12991329
SSLNMAKE = ms\nt.mak all
1330
+SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
13001331
!else
13011332
!message Assuming 'x86' platform for OpenSSL...
1302
-SSLCONFIG = VC-WIN32 no-asm
1333
+# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
1334
+# SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-shared
1335
+SSLCONFIG = VC-WIN32 no-asm no-shared
13031336
SSLSETUP = ms\do_ms.bat
13041337
SSLNMAKE = ms\nt.mak all
1338
+SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
13051339
!endif
13061340
!endif
13071341
13081342
!ifdef FOSSIL_ENABLE_TCL
13091343
TCLDIR = $(B)\compat\tcl-8.6
@@ -1472,13 +1506,13 @@
14721506
@set PATH=$(PERLDIR);$(PATH)
14731507
!endif
14741508
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
14751509
@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
14761510
!ifdef FOSSIL_ENABLE_WINXP
1477
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1511
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
14781512
!else
1479
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
1513
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
14801514
!endif
14811515
!endif
14821516
14831517
!ifndef FOSSIL_ENABLE_MINIZ
14841518
APPTARGETS = $(APPTARGETS) zlib
14851519
--- 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,19 +94,22 @@
93 path
94 pivot
95 popen
96 pqueue
97 printf
 
 
98 rebuild
99 regexp
100 report
101 rss
102 schema
103 search
104 setup
105 sha1
106 shun
 
107 skins
108 sqlcmd
109 stash
110 stat
111 style
@@ -510,11 +514,12 @@
510 # This is useful when Tcl has been compiled statically with MinGW.
511 #
512 FOSSIL_TCL_SOURCE = 1
513
514 #### Check if the workaround for the MinGW command line handling needs to
515 # be enabled by default.
 
516 #
517 ifndef MINGW_IS_32BIT_ONLY
518 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
519 MINGW_IS_32BIT_ONLY = 1
520 endif
@@ -523,26 +528,46 @@
523 #### The directories where the zlib include and library files are located.
524 #
525 ZINCDIR = $(SRCDIR)/../compat/zlib
526 ZLIBDIR = $(SRCDIR)/../compat/zlib
527
 
 
 
528 ifndef X64
529 ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
530 X64 = 1
531 endif
532 endif
533
 
 
 
 
534 ifndef X64
535 SSLCONFIG = mingw
 
536 ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
537 LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
 
 
 
 
538 else
539 SSLCONFIG = mingw64
540 ZLIBCONFIG =
541 LIBTARGETS =
542 endif
543
 
 
 
 
 
 
 
 
544 ifndef FOSSIL_ENABLE_MINIZ
545 SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
546 endif
547
548 #### The directories where the OpenSSL include and library files are located.
@@ -1287,23 +1312,32 @@
1287 SSLLIBDIR = $(SSLDIR)\out32
1288 SSLLFLAGS = /nologo /opt:ref /debug
1289 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1290 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1291 !message Using 'x64' platform for OpenSSL...
1292 SSLCONFIG = VC-WIN64A no-asm
 
 
1293 SSLSETUP = ms\do_win64a.bat
1294 SSLNMAKE = ms\nt.mak all
 
1295 !elseif "$(PLATFORM)"=="ia64"
1296 !message Using 'ia64' platform for OpenSSL...
1297 SSLCONFIG = VC-WIN64I no-asm
 
 
1298 SSLSETUP = ms\do_win64i.bat
1299 SSLNMAKE = ms\nt.mak all
 
1300 !else
1301 !message Assuming 'x86' platform for OpenSSL...
1302 SSLCONFIG = VC-WIN32 no-asm
 
 
1303 SSLSETUP = ms\do_ms.bat
1304 SSLNMAKE = ms\nt.mak all
 
1305 !endif
1306 !endif
1307
1308 !ifdef FOSSIL_ENABLE_TCL
1309 TCLDIR = $(B)\compat\tcl-8.6
@@ -1472,13 +1506,13 @@
1472 @set PATH=$(PERLDIR);$(PATH)
1473 !endif
1474 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1475 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1476 !ifdef FOSSIL_ENABLE_WINXP
1477 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1478 !else
1479 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
1480 !endif
1481 !endif
1482
1483 !ifndef FOSSIL_ENABLE_MINIZ
1484 APPTARGETS = $(APPTARGETS) zlib
1485
--- 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,19 +94,22 @@
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 search
107 setup
108 sha1
109 shun
110 sitemap
111 skins
112 sqlcmd
113 stash
114 stat
115 style
@@ -510,11 +514,12 @@
514 # This is useful when Tcl has been compiled statically with MinGW.
515 #
516 FOSSIL_TCL_SOURCE = 1
517
518 #### Check if the workaround for the MinGW command line handling needs to
519 # be enabled by default. This check may be somewhat fragile due to the
520 # use of "findstring".
521 #
522 ifndef MINGW_IS_32BIT_ONLY
523 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
524 MINGW_IS_32BIT_ONLY = 1
525 endif
@@ -523,26 +528,46 @@
528 #### The directories where the zlib include and library files are located.
529 #
530 ZINCDIR = $(SRCDIR)/../compat/zlib
531 ZLIBDIR = $(SRCDIR)/../compat/zlib
532
533 #### Make an attempt to detect if Fossil is being built for the x64 processor
534 # architecture. This check may be somewhat fragile due to "findstring".
535 #
536 ifndef X64
537 ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
538 X64 = 1
539 endif
540 endif
541
542 #### Determine if the optimized assembly routines provided with zlib should be
543 # used, taking into account whether zlib is actually enabled and the target
544 # processor architecture.
545 #
546 ifndef X64
547 SSLCONFIG = mingw
548 ifndef FOSSIL_ENABLE_MINIZ
549 ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
550 LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
551 else
552 ZLIBCONFIG =
553 LIBTARGETS =
554 endif
555 else
556 SSLCONFIG = mingw64
557 ZLIBCONFIG =
558 LIBTARGETS =
559 endif
560
561 #### Disable creation of the OpenSSL shared libraries. Also, disable support
562 # for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
563 #
564 SSLCONFIG += no-ssl2 no-ssl3 no-shared
565
566 #### When using zlib, make sure that OpenSSL is configured to use the zlib
567 # that Fossil knows about (i.e. the one within the source tree).
568 #
569 ifndef FOSSIL_ENABLE_MINIZ
570 SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
571 endif
572
573 #### The directories where the OpenSSL include and library files are located.
@@ -1287,23 +1312,32 @@
1312 SSLLIBDIR = $(SSLDIR)\out32
1313 SSLLFLAGS = /nologo /opt:ref /debug
1314 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1315 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1316 !message Using 'x64' platform for OpenSSL...
1317 # BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
1318 # SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-shared
1319 SSLCONFIG = VC-WIN64A no-asm no-shared
1320 SSLSETUP = ms\do_win64a.bat
1321 SSLNMAKE = ms\nt.mak all
1322 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
1323 !elseif "$(PLATFORM)"=="ia64"
1324 !message Using 'ia64' platform for OpenSSL...
1325 # BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
1326 # SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-shared
1327 SSLCONFIG = VC-WIN64I no-asm no-shared
1328 SSLSETUP = ms\do_win64i.bat
1329 SSLNMAKE = ms\nt.mak all
1330 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
1331 !else
1332 !message Assuming 'x86' platform for OpenSSL...
1333 # BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
1334 # SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-shared
1335 SSLCONFIG = VC-WIN32 no-asm no-shared
1336 SSLSETUP = ms\do_ms.bat
1337 SSLNMAKE = ms\nt.mak all
1338 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
1339 !endif
1340 !endif
1341
1342 !ifdef FOSSIL_ENABLE_TCL
1343 TCLDIR = $(B)\compat\tcl-8.6
@@ -1472,13 +1506,13 @@
1506 @set PATH=$(PERLDIR);$(PATH)
1507 !endif
1508 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
1509 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
1510 !ifdef FOSSIL_ENABLE_WINXP
1511 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
1512 !else
1513 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
1514 !endif
1515 !endif
1516
1517 !ifndef FOSSIL_ENABLE_MINIZ
1518 APPTARGETS = $(APPTARGETS) zlib
1519
+1 -1
--- src/markdown.c
+++ src/markdown.c
@@ -2155,11 +2155,11 @@
21552155
struct Blob *ib, /* input blob in markdown */
21562156
const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
21572157
){
21582158
struct link_ref *lr;
21592159
struct Blob text = BLOB_INITIALIZER;
2160
- size_t i, beg, end;
2160
+ size_t i, beg, end = 0;
21612161
struct render rndr;
21622162
char *ib_data;
21632163
21642164
/* filling the render structure */
21652165
if( !rndrer ) return;
21662166
--- src/markdown.c
+++ src/markdown.c
@@ -2155,11 +2155,11 @@
2155 struct Blob *ib, /* input blob in markdown */
2156 const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
2157 ){
2158 struct link_ref *lr;
2159 struct Blob text = BLOB_INITIALIZER;
2160 size_t i, beg, end;
2161 struct render rndr;
2162 char *ib_data;
2163
2164 /* filling the render structure */
2165 if( !rndrer ) return;
2166
--- src/markdown.c
+++ src/markdown.c
@@ -2155,11 +2155,11 @@
2155 struct Blob *ib, /* input blob in markdown */
2156 const struct mkd_renderer *rndrer /* renderer descriptor (callbacks) */
2157 ){
2158 struct link_ref *lr;
2159 struct Blob text = BLOB_INITIALIZER;
2160 size_t i, beg, end = 0;
2161 struct render rndr;
2162 char *ib_data;
2163
2164 /* filling the render structure */
2165 if( !rndrer ) return;
2166
+9 -2
--- src/mkversion.c
+++ src/mkversion.c
@@ -7,10 +7,11 @@
77
**
88
** Note that the manifest.uuid and manifest files are generated by Fossil.
99
*/
1010
#include <stdio.h>
1111
#include <string.h>
12
+#include <stdlib.h>
1213
1314
int main(int argc, char *argv[]){
1415
FILE *m,*u,*v;
1516
char *z;
1617
int i, x, d;
@@ -17,11 +18,14 @@
1718
char b[1000];
1819
char vx[1000];
1920
memset(b,0,sizeof(b));
2021
memset(vx,0,sizeof(vx));
2122
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
+ }
2327
fclose(u);
2428
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
2529
*z = 0;
2630
printf("#define MANIFEST_UUID \"%s\"\n",b);
2731
printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
@@ -32,11 +36,14 @@
3236
printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2);
3337
}
3438
}
3539
fclose(m);
3640
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
+ }
3845
fclose(v);
3946
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
4047
*z = 0;
4148
printf("#define RELEASE_VERSION \"%s\"\n", b);
4249
x=0;
4350
--- 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
+1 -6
--- src/moderate.c
+++ src/moderate.c
@@ -38,16 +38,11 @@
3838
3939
/*
4040
** Return TRUE if the modreq table exists
4141
*/
4242
int moderation_table_exists(void){
43
- static int modreqExists = -1;
44
- if( modreqExists<0 ){
45
- modreqExists = db_exists("SELECT 1 FROM %s.sqlite_master"
46
- " WHERE name='modreq'", db_name("repository"));
47
- }
48
- return modreqExists;
43
+ return db_table_exists("repository", "modreq");
4944
}
5045
5146
/*
5247
** Return TRUE if the object specified is being held for moderation.
5348
*/
5449
--- src/moderate.c
+++ src/moderate.c
@@ -38,16 +38,11 @@
38
39 /*
40 ** Return TRUE if the modreq table exists
41 */
42 int moderation_table_exists(void){
43 static int modreqExists = -1;
44 if( modreqExists<0 ){
45 modreqExists = db_exists("SELECT 1 FROM %s.sqlite_master"
46 " WHERE name='modreq'", db_name("repository"));
47 }
48 return modreqExists;
49 }
50
51 /*
52 ** Return TRUE if the object specified is being held for moderation.
53 */
54
--- src/moderate.c
+++ src/moderate.c
@@ -38,16 +38,11 @@
38
39 /*
40 ** Return TRUE if the modreq table exists
41 */
42 int moderation_table_exists(void){
43 return db_table_exists("repository", "modreq");
 
 
 
 
 
44 }
45
46 /*
47 ** Return TRUE if the object specified is being held for moderation.
48 */
49
+352 -51
--- src/name.c
+++ src/name.c
@@ -42,10 +42,44 @@
4242
if( z[7]!='-') return 0;
4343
if( !fossil_isdigit(z[8]) ) return 0;
4444
if( !fossil_isdigit(z[9]) ) return 0;
4545
return 1;
4646
}
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
+}
4781
4882
/*
4983
** Convert a symbolic name into a RID. Acceptable forms:
5084
**
5185
** * SHA1 hash
@@ -66,20 +100,28 @@
66100
** Return the RID of the matching artifact. Or return 0 if the name does not
67101
** match any known object. Or return -1 if the name is ambiguous.
68102
**
69103
** The zType parameter specifies the type of artifact: ci, t, w, e, g.
70104
** 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.
71107
** zType is "ci" in most use cases since we are usually searching for
72108
** a check-in.
73109
*/
74110
int symbolic_name_to_rid(const char *zTag, const char *zType){
75111
int vid;
76112
int rid = 0;
77113
int nTag;
78114
int i;
115
+ int startOfBranch = 0;
79116
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
+ }
81123
if( zTag==0 || zTag[0]==0 ) return 0;
82124
83125
/* special keyword: "tip" */
84126
if( fossil_strcmp(zTag, "tip")==0 && (zType[0]=='*' || zType[0]=='c') ){
85127
rid = db_int(0,
@@ -151,41 +193,18 @@
151193
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
152194
" AND event.objid=tagxref.rid "
153195
" AND event.type GLOB '%q'",
154196
&zTag[4], zType
155197
);
198
+ if( startOfBranch ) rid = start_of_branch(rid,1);
156199
return rid;
157200
}
158201
159202
/* root:TAG -> The origin of the branch */
160203
if( memcmp(zTag, "root:", 5)==0 ){
161
- Stmt q;
162
- int rc;
163
- char *zBr;
164204
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);
187206
}
188207
189208
/* symbolic-name ":" date-time */
190209
nTag = strlen(zTag);
191210
for(i=0; i<nTag-10 && zTag[i]!=':'; i++){}
@@ -245,11 +264,14 @@
245264
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
246265
" AND event.objid=tagxref.rid "
247266
" AND event.type GLOB '%q'",
248267
zTag, zType
249268
);
250
- if( rid>0 ) return rid;
269
+ if( rid>0 ){
270
+ if( startOfBranch ) rid = start_of_branch(rid,1);
271
+ return rid;
272
+ }
251273
252274
/* Undocumented: numeric tags get translated directly into the RID */
253275
if( memcmp(zTag, "rid:", 4)==0 ){
254276
zTag += 4;
255277
for(i=0; fossil_isdigit(zTag[i]); i++){}
@@ -324,30 +346,25 @@
324346
** name_collisions searches through events, blobs, and tickets for
325347
** collisions of a given UUID based on its length on UUIDs no shorter
326348
** than 4 characters in length.
327349
*/
328350
int name_collisions(const char *zName){
329
- Stmt q;
330351
int c = 0; /* count of collisions for zName */
331352
int nLen; /* length of zName */
332353
nLen = strlen(zName);
333354
if( nLen>=4 && nLen<=UUID_SIZE && validate16(zName, nLen) ){
334
- db_prepare(&q,
335
- "SELECT count(uuid) FROM"
336
- " (SELECT substr(tkt_uuid, 1, %d) AS uuid FROM ticket"
337
- " UNION ALL SELECT * FROM"
338
- " (SELECT substr(tagname, 7, %d) FROM"
339
- " tag WHERE tagname GLOB 'event-*')"
340
- " UNION ALL SELECT * FROM"
341
- " (SELECT substr(uuid, 1, %d) FROM blob))"
342
- " WHERE uuid GLOB '%q*'"
343
- " GROUP BY uuid HAVING count(uuid) > 1;",
344
- nLen, nLen, nLen, zName);
345
- if( db_step(&q)==SQLITE_ROW ){
346
- c = db_column_int(&q, 0);
347
- }
348
- db_finalize(&q);
355
+ c = db_int(0,
356
+ "SELECT"
357
+ " (SELECT count(*) FROM ticket"
358
+ " WHERE tkt_uuid GLOB '%q*') +"
359
+ " (SELECT count(*) FROM tag"
360
+ " WHERE tagname GLOB 'event-%q*') +"
361
+ " (SELECT count(*) FROM blob"
362
+ " WHERE uuid GLOB '%q*');",
363
+ zName, zName, zName
364
+ );
365
+ if( c<2 ) c = 0;
349366
}
350367
return c;
351368
}
352369
353370
/*
@@ -391,18 +408,15 @@
391408
int rid;
392409
393410
if( zName==0 || zName[0]==0 ) return 0;
394411
rid = symbolic_name_to_rid(zName, zType);
395412
if( rid<0 ){
396
- fossil_error(1, "ambiguous name: %s", zName);
397
- return 0;
413
+ fossil_fatal("ambiguous name: %s", zName);
398414
}else if( rid==0 ){
399
- fossil_error(1, "not found: %s", zName);
400
- return 0;
401
- }else{
402
- return rid;
415
+ fossil_fatal("not found: %s", zName);
403416
}
417
+ return rid;
404418
}
405419
int name_to_rid(const char *zName){
406420
return name_to_typed_rid(zName, "*");
407421
}
408422
@@ -505,11 +519,11 @@
505519
}
506520
507521
/*
508522
** Generate a description of artifact "rid"
509523
*/
510
-static void whatis_rid(int rid, int verboseFlag){
524
+void whatis_rid(int rid, int verboseFlag){
511525
Stmt q;
512526
int cnt;
513527
514528
/* Basic information about the object. */
515529
db_prepare(&q,
@@ -657,21 +671,23 @@
657671
void whatis_cmd(void){
658672
int rid;
659673
const char *zName;
660674
int verboseFlag;
661675
int i;
676
+ const char *zType = 0;
662677
db_find_and_open_repository(0,0);
663678
verboseFlag = find_option("verbose","v",0)!=0;
679
+ zType = find_option("type",0,1);
664680
665681
/* We should be done with options.. */
666682
verify_all_options();
667683
668684
if( g.argc<3 ) usage("whatis NAME ...");
669685
for(i=2; i<g.argc; i++){
670686
zName = g.argv[i];
671687
if( i>2 ) fossil_print("%.79c\n",'-');
672
- rid = symbolic_name_to_rid(zName, 0);
688
+ rid = symbolic_name_to_rid(zName, zType);
673689
if( rid<0 ){
674690
Stmt q;
675691
int cnt = 0;
676692
fossil_print("name: %s (ambiguous)\n", zName);
677693
db_prepare(&q,
@@ -757,5 +773,290 @@
757773
while( db_step(&q)==SQLITE_ROW ){
758774
fossil_print("%s\n", db_column_text(&q, 0));
759775
}
760776
db_finalize(&q);
761777
}
778
+
779
+/*
780
+** Schema for the description table
781
+*/
782
+static const char zDescTab[] =
783
+@ CREATE TEMP TABLE IF NOT EXISTS description(
784
+@ rid INTEGER PRIMARY KEY, -- RID of the object
785
+@ uuid TEXT, -- SHA1 hash of the object
786
+@ ctime DATETIME, -- Time of creation
787
+@ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts
788
+@ type TEXT, -- file, checkin, wiki, ticket, etc.
789
+@ summary TEXT, -- Summary comment for the object
790
+@ detail TEXT -- filename, checkin comment, etc
791
+@ );
792
+;
793
+
794
+/*
795
+** Create the description table if it does not already exists.
796
+** Populate fields of this table with descriptions for all artifacts
797
+** whose RID matches the SQL expression in zWhere.
798
+*/
799
+void describe_artifacts(const char *zWhere){
800
+ db_multi_exec("%s", zDescTab/*safe-for-%s*/);
801
+
802
+ /* Describe checkins */
803
+ db_multi_exec(
804
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
805
+ "SELECT blob.rid, blob.uuid, event.mtime, 'checkin',\n"
806
+ " 'checkin on ' || strftime('%%Y-%%m-%%d %%H:%%M',event.mtime)\n"
807
+ " FROM event, blob\n"
808
+ " WHERE (event.objid %s) AND event.type='ci'\n"
809
+ " AND event.objid=blob.rid;",
810
+ zWhere /*safe-for-%s*/
811
+ );
812
+
813
+ /* Describe files */
814
+ db_multi_exec(
815
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
816
+ "SELECT blob.rid, blob.uuid, event.mtime, 'file', 'file '||filename.name\n"
817
+ " FROM mlink, blob, event, filename\n"
818
+ " WHERE (mlink.fid %s)\n"
819
+ " AND mlink.mid=event.objid\n"
820
+ " AND filename.fnid=mlink.fnid\n"
821
+ " AND mlink.fid=blob.rid;",
822
+ zWhere /*safe-for-%s*/
823
+ );
824
+
825
+ /* Describe tags */
826
+ db_multi_exec(
827
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
828
+ "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n"
829
+ " 'tag '||substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n"
830
+ " FROM tagxref, blob\n"
831
+ " WHERE (tagxref.srcid %s) AND tagxref.srcid!=tagxref.rid\n"
832
+ " AND tagxref.srcid=blob.rid;",
833
+ zWhere /*safe-for-%s*/
834
+ );
835
+
836
+ /* Cluster artifacts */
837
+ db_multi_exec(
838
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
839
+ "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster', 'cluster'\n"
840
+ " FROM tagxref, blob\n"
841
+ " WHERE (tagxref.rid %s)\n"
842
+ " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n"
843
+ " AND blob.rid=tagxref.rid;",
844
+ zWhere /*safe-for-%s*/
845
+ );
846
+
847
+ /* Ticket change artifacts */
848
+ db_multi_exec(
849
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
850
+ "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n"
851
+ " 'ticket '||substr(tag.tagname,5,21)\n"
852
+ " FROM tagxref, tag, blob\n"
853
+ " WHERE (tagxref.rid %s)\n"
854
+ " AND tag.tagid=tagxref.tagid\n"
855
+ " AND tag.tagname GLOB 'tkt-*'"
856
+ " AND blob.rid=tagxref.rid;",
857
+ zWhere /*safe-for-%s*/
858
+ );
859
+
860
+ /* Wiki edit artifacts */
861
+ db_multi_exec(
862
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
863
+ "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n"
864
+ " printf('wiki \"%%s\"',substr(tag.tagname,6))\n"
865
+ " FROM tagxref, tag, blob\n"
866
+ " WHERE (tagxref.rid %s)\n"
867
+ " AND tag.tagid=tagxref.tagid\n"
868
+ " AND tag.tagname GLOB 'wiki-*'"
869
+ " AND blob.rid=tagxref.rid;",
870
+ zWhere /*safe-for-%s*/
871
+ );
872
+
873
+ /* Event edit artifacts */
874
+ db_multi_exec(
875
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
876
+ "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n"
877
+ " 'event '||substr(tag.tagname,7)\n"
878
+ " FROM tagxref, tag, blob\n"
879
+ " WHERE (tagxref.rid %s)\n"
880
+ " AND tag.tagid=tagxref.tagid\n"
881
+ " AND tag.tagname GLOB 'event-*'"
882
+ " AND blob.rid=tagxref.rid;",
883
+ zWhere /*safe-for-%s*/
884
+ );
885
+
886
+ /* Attachments */
887
+ db_multi_exec(
888
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
889
+ "SELECT blob.rid, blob.uuid, attachment.mtime, 'attach-control',\n"
890
+ " 'attachment-control for '||attachment.filename\n"
891
+ " FROM attachment, blob\n"
892
+ " WHERE (attachment.attachid %s)\n"
893
+ " AND blob.rid=attachment.attachid",
894
+ zWhere /*safe-for-%s*/
895
+ );
896
+ db_multi_exec(
897
+ "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
898
+ "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n"
899
+ " 'attachment '||attachment.filename\n"
900
+ " FROM attachment, blob\n"
901
+ " WHERE (blob.rid %s)\n"
902
+ " AND blob.rid NOT IN (SELECT rid FROM description)\n"
903
+ " AND blob.uuid=attachment.src",
904
+ zWhere /*safe-for-%s*/
905
+ );
906
+
907
+ /* Everything else */
908
+ db_multi_exec(
909
+ "INSERT OR IGNORE INTO description(rid,uuid,type,summary)\n"
910
+ "SELECT blob.rid, blob.uuid,"
911
+ " CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n"
912
+ " 'unknown'\n"
913
+ " FROM blob WHERE (blob.rid %s);",
914
+ zWhere /*safe-for-%s*/
915
+ );
916
+
917
+ /* Mark private elements */
918
+ db_multi_exec(
919
+ "UPDATE description SET isPrivate=1 WHERE rid IN private"
920
+ );
921
+}
922
+
923
+/*
924
+** Print the content of the description table on stdout
925
+*/
926
+int describe_artifacts_to_stdout(const char *zWhere, const char *zLabel){
927
+ Stmt q;
928
+ int cnt = 0;
929
+ describe_artifacts(zWhere);
930
+ db_prepare(&q,
931
+ "SELECT uuid, summary, isPrivate\n"
932
+ " FROM description\n"
933
+ " ORDER BY ctime, type;"
934
+ );
935
+ while( db_step(&q)==SQLITE_ROW ){
936
+ if( zLabel ){
937
+ fossil_print("%s\n", zLabel);
938
+ zLabel = 0;
939
+ }
940
+ fossil_print(" %.16s %s", db_column_text(&q,0), db_column_text(&q,1));
941
+ if( db_column_int(&q,2) ) fossil_print(" (unpublished)");
942
+ fossil_print("\n");
943
+ cnt++;
944
+ }
945
+ db_finalize(&q);
946
+ db_multi_exec("DELETE FROM description;");
947
+ return cnt;
948
+}
949
+
950
+/*
951
+** COMMAND: test-describe-artifacts
952
+**
953
+** Usage: %fossil test-describe-artifacts [--from S] [--count N]
954
+**
955
+** Display a one-line description of every artifact.
956
+*/
957
+void test_describe_artifacts_cmd(void){
958
+ int iFrom = 0;
959
+ int iCnt = 1000000;
960
+ const char *z;
961
+ char *zRange;
962
+ db_find_and_open_repository(0,0);
963
+ z = find_option("from",0,1);
964
+ if( z ) iFrom = atoi(z);
965
+ z = find_option("count",0,1);
966
+ if( z ) iCnt = atoi(z);
967
+ zRange = mprintf("BETWEEN %d AND %d", iFrom, iFrom+iCnt-1);
968
+ describe_artifacts_to_stdout(zRange, 0);
969
+}
970
+
971
+/*
972
+** WEBPAGE: bloblist
973
+**
974
+** Return a page showing all artifacts in the repository. Query parameters:
975
+**
976
+** n=N Show N artifacts
977
+** s=S Start with artifact number S
978
+*/
979
+void bloblist_page(void){
980
+ Stmt q;
981
+ int s = atoi(PD("s","0"));
982
+ int n = atoi(PD("n","5000"));
983
+ int mx = db_int(0, "SELECT max(rid) FROM blob");
984
+ char *zRange;
985
+
986
+ login_check_credentials();
987
+ if( !g.perm.Read ){ login_needed(); return; }
988
+ style_header("List Of Artifacts");
989
+ if( mx>n && P("s")==0 ){
990
+ int i;
991
+ @ <p>Select a range of artifacts to view:</p>
992
+ @ <ul>
993
+ for(i=1; i<=mx; i+=n){
994
+ @ <li> %z(href("%R/bloblist?s=%d&n=%d",i,n))
995
+ @ %d(i)..%d(i+n-1<mx?i+n-1:mx)</a>
996
+ }
997
+ @ </ul>
998
+ style_footer();
999
+ return;
1000
+ }
1001
+ if( mx>n ){
1002
+ style_submenu_element("Index", "Index", "bloblist");
1003
+ }
1004
+ zRange = mprintf("BETWEEN %d AND %d", s, s+n-1);
1005
+ describe_artifacts(zRange);
1006
+ db_prepare(&q,
1007
+ "SELECT rid, uuid, summary, isPrivate FROM description ORDER BY rid"
1008
+ );
1009
+ @ <table cellpadding="0" cellspacing="0">
1010
+ while( db_step(&q)==SQLITE_ROW ){
1011
+ int rid = db_column_int(&q,0);
1012
+ const char *zUuid = db_column_text(&q, 1);
1013
+ const char *zDesc = db_column_text(&q, 2);
1014
+ int isPriv = db_column_int(&q,2);
1015
+ @ <tr><td align="right">%d(rid)</td>
1016
+ @ <td>&nbsp;%z(href("%R/info/%s",zUuid))%s(zUuid)</a>&nbsp;</td>
1017
+ @ <td align="left">%h(zDesc)</td>
1018
+ if( isPriv ){
1019
+ @ <td>(unpublished)</td>
1020
+ }
1021
+ @ </tr>
1022
+ }
1023
+ @ </table>
1024
+ db_finalize(&q);
1025
+ style_footer();
1026
+}
1027
+
1028
+/*
1029
+** COMMAND: test-unsent
1030
+**
1031
+** Usage: %fossil test-unsent
1032
+**
1033
+** Show all artifacts in the unsent table
1034
+*/
1035
+void test_unsent_cmd(void){
1036
+ db_find_and_open_repository(0,0);
1037
+ describe_artifacts_to_stdout("IN unsent", 0);
1038
+}
1039
+
1040
+/*
1041
+** COMMAND: test-unclustered
1042
+**
1043
+** Usage: %fossil test-unclustered
1044
+**
1045
+** Show all artifacts in the unclustered table
1046
+*/
1047
+void test_unclusterd_cmd(void){
1048
+ db_find_and_open_repository(0,0);
1049
+ describe_artifacts_to_stdout("IN unclustered", 0);
1050
+}
1051
+
1052
+/*
1053
+** COMMAND: test-phantoms
1054
+**
1055
+** Usage: %fossil test-phantoms
1056
+**
1057
+** Show all phantom artifacts
1058
+*/
1059
+void test_phatoms_cmd(void){
1060
+ db_find_and_open_repository(0,0);
1061
+ describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0);
1062
+}
7621063
7631064
ADDED src/publish.c
7641065
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++){}
@@ -324,30 +346,25 @@
324 ** name_collisions searches through events, blobs, and tickets for
325 ** collisions of a given UUID based on its length on UUIDs no shorter
326 ** than 4 characters in length.
327 */
328 int name_collisions(const char *zName){
329 Stmt q;
330 int c = 0; /* count of collisions for zName */
331 int nLen; /* length of zName */
332 nLen = strlen(zName);
333 if( nLen>=4 && nLen<=UUID_SIZE && validate16(zName, nLen) ){
334 db_prepare(&q,
335 "SELECT count(uuid) FROM"
336 " (SELECT substr(tkt_uuid, 1, %d) AS uuid FROM ticket"
337 " UNION ALL SELECT * FROM"
338 " (SELECT substr(tagname, 7, %d) FROM"
339 " tag WHERE tagname GLOB 'event-*')"
340 " UNION ALL SELECT * FROM"
341 " (SELECT substr(uuid, 1, %d) FROM blob))"
342 " WHERE uuid GLOB '%q*'"
343 " GROUP BY uuid HAVING count(uuid) > 1;",
344 nLen, nLen, nLen, zName);
345 if( db_step(&q)==SQLITE_ROW ){
346 c = db_column_int(&q, 0);
347 }
348 db_finalize(&q);
349 }
350 return c;
351 }
352
353 /*
@@ -391,18 +408,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 +519,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 +671,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 +773,290 @@
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++){}
@@ -324,30 +346,25 @@
346 ** name_collisions searches through events, blobs, and tickets for
347 ** collisions of a given UUID based on its length on UUIDs no shorter
348 ** than 4 characters in length.
349 */
350 int name_collisions(const char *zName){
 
351 int c = 0; /* count of collisions for zName */
352 int nLen; /* length of zName */
353 nLen = strlen(zName);
354 if( nLen>=4 && nLen<=UUID_SIZE && validate16(zName, nLen) ){
355 c = db_int(0,
356 "SELECT"
357 " (SELECT count(*) FROM ticket"
358 " WHERE tkt_uuid GLOB '%q*') +"
359 " (SELECT count(*) FROM tag"
360 " WHERE tagname GLOB 'event-%q*') +"
361 " (SELECT count(*) FROM blob"
362 " WHERE uuid GLOB '%q*');",
363 zName, zName, zName
364 );
365 if( c<2 ) c = 0;
 
 
 
 
366 }
367 return c;
368 }
369
370 /*
@@ -391,18 +408,15 @@
408 int rid;
409
410 if( zName==0 || zName[0]==0 ) return 0;
411 rid = symbolic_name_to_rid(zName, zType);
412 if( rid<0 ){
413 fossil_fatal("ambiguous name: %s", zName);
 
414 }else if( rid==0 ){
415 fossil_fatal("not found: %s", zName);
 
 
 
416 }
417 return rid;
418 }
419 int name_to_rid(const char *zName){
420 return name_to_typed_rid(zName, "*");
421 }
422
@@ -505,11 +519,11 @@
519 }
520
521 /*
522 ** Generate a description of artifact "rid"
523 */
524 void whatis_rid(int rid, int verboseFlag){
525 Stmt q;
526 int cnt;
527
528 /* Basic information about the object. */
529 db_prepare(&q,
@@ -657,21 +671,23 @@
671 void whatis_cmd(void){
672 int rid;
673 const char *zName;
674 int verboseFlag;
675 int i;
676 const char *zType = 0;
677 db_find_and_open_repository(0,0);
678 verboseFlag = find_option("verbose","v",0)!=0;
679 zType = find_option("type",0,1);
680
681 /* We should be done with options.. */
682 verify_all_options();
683
684 if( g.argc<3 ) usage("whatis NAME ...");
685 for(i=2; i<g.argc; i++){
686 zName = g.argv[i];
687 if( i>2 ) fossil_print("%.79c\n",'-');
688 rid = symbolic_name_to_rid(zName, zType);
689 if( rid<0 ){
690 Stmt q;
691 int cnt = 0;
692 fossil_print("name: %s (ambiguous)\n", zName);
693 db_prepare(&q,
@@ -757,5 +773,290 @@
773 while( db_step(&q)==SQLITE_ROW ){
774 fossil_print("%s\n", db_column_text(&q, 0));
775 }
776 db_finalize(&q);
777 }
778
779 /*
780 ** Schema for the description table
781 */
782 static const char zDescTab[] =
783 @ CREATE TEMP TABLE IF NOT EXISTS description(
784 @ rid INTEGER PRIMARY KEY, -- RID of the object
785 @ uuid TEXT, -- SHA1 hash of the object
786 @ ctime DATETIME, -- Time of creation
787 @ isPrivate BOOLEAN DEFAULT 0, -- True for unpublished artifacts
788 @ type TEXT, -- file, checkin, wiki, ticket, etc.
789 @ summary TEXT, -- Summary comment for the object
790 @ detail TEXT -- filename, checkin comment, etc
791 @ );
792 ;
793
794 /*
795 ** Create the description table if it does not already exists.
796 ** Populate fields of this table with descriptions for all artifacts
797 ** whose RID matches the SQL expression in zWhere.
798 */
799 void describe_artifacts(const char *zWhere){
800 db_multi_exec("%s", zDescTab/*safe-for-%s*/);
801
802 /* Describe checkins */
803 db_multi_exec(
804 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
805 "SELECT blob.rid, blob.uuid, event.mtime, 'checkin',\n"
806 " 'checkin on ' || strftime('%%Y-%%m-%%d %%H:%%M',event.mtime)\n"
807 " FROM event, blob\n"
808 " WHERE (event.objid %s) AND event.type='ci'\n"
809 " AND event.objid=blob.rid;",
810 zWhere /*safe-for-%s*/
811 );
812
813 /* Describe files */
814 db_multi_exec(
815 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
816 "SELECT blob.rid, blob.uuid, event.mtime, 'file', 'file '||filename.name\n"
817 " FROM mlink, blob, event, filename\n"
818 " WHERE (mlink.fid %s)\n"
819 " AND mlink.mid=event.objid\n"
820 " AND filename.fnid=mlink.fnid\n"
821 " AND mlink.fid=blob.rid;",
822 zWhere /*safe-for-%s*/
823 );
824
825 /* Describe tags */
826 db_multi_exec(
827 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
828 "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n"
829 " 'tag '||substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n"
830 " FROM tagxref, blob\n"
831 " WHERE (tagxref.srcid %s) AND tagxref.srcid!=tagxref.rid\n"
832 " AND tagxref.srcid=blob.rid;",
833 zWhere /*safe-for-%s*/
834 );
835
836 /* Cluster artifacts */
837 db_multi_exec(
838 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
839 "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster', 'cluster'\n"
840 " FROM tagxref, blob\n"
841 " WHERE (tagxref.rid %s)\n"
842 " AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n"
843 " AND blob.rid=tagxref.rid;",
844 zWhere /*safe-for-%s*/
845 );
846
847 /* Ticket change artifacts */
848 db_multi_exec(
849 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
850 "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n"
851 " 'ticket '||substr(tag.tagname,5,21)\n"
852 " FROM tagxref, tag, blob\n"
853 " WHERE (tagxref.rid %s)\n"
854 " AND tag.tagid=tagxref.tagid\n"
855 " AND tag.tagname GLOB 'tkt-*'"
856 " AND blob.rid=tagxref.rid;",
857 zWhere /*safe-for-%s*/
858 );
859
860 /* Wiki edit artifacts */
861 db_multi_exec(
862 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
863 "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n"
864 " printf('wiki \"%%s\"',substr(tag.tagname,6))\n"
865 " FROM tagxref, tag, blob\n"
866 " WHERE (tagxref.rid %s)\n"
867 " AND tag.tagid=tagxref.tagid\n"
868 " AND tag.tagname GLOB 'wiki-*'"
869 " AND blob.rid=tagxref.rid;",
870 zWhere /*safe-for-%s*/
871 );
872
873 /* Event edit artifacts */
874 db_multi_exec(
875 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
876 "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n"
877 " 'event '||substr(tag.tagname,7)\n"
878 " FROM tagxref, tag, blob\n"
879 " WHERE (tagxref.rid %s)\n"
880 " AND tag.tagid=tagxref.tagid\n"
881 " AND tag.tagname GLOB 'event-*'"
882 " AND blob.rid=tagxref.rid;",
883 zWhere /*safe-for-%s*/
884 );
885
886 /* Attachments */
887 db_multi_exec(
888 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
889 "SELECT blob.rid, blob.uuid, attachment.mtime, 'attach-control',\n"
890 " 'attachment-control for '||attachment.filename\n"
891 " FROM attachment, blob\n"
892 " WHERE (attachment.attachid %s)\n"
893 " AND blob.rid=attachment.attachid",
894 zWhere /*safe-for-%s*/
895 );
896 db_multi_exec(
897 "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
898 "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n"
899 " 'attachment '||attachment.filename\n"
900 " FROM attachment, blob\n"
901 " WHERE (blob.rid %s)\n"
902 " AND blob.rid NOT IN (SELECT rid FROM description)\n"
903 " AND blob.uuid=attachment.src",
904 zWhere /*safe-for-%s*/
905 );
906
907 /* Everything else */
908 db_multi_exec(
909 "INSERT OR IGNORE INTO description(rid,uuid,type,summary)\n"
910 "SELECT blob.rid, blob.uuid,"
911 " CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n"
912 " 'unknown'\n"
913 " FROM blob WHERE (blob.rid %s);",
914 zWhere /*safe-for-%s*/
915 );
916
917 /* Mark private elements */
918 db_multi_exec(
919 "UPDATE description SET isPrivate=1 WHERE rid IN private"
920 );
921 }
922
923 /*
924 ** Print the content of the description table on stdout
925 */
926 int describe_artifacts_to_stdout(const char *zWhere, const char *zLabel){
927 Stmt q;
928 int cnt = 0;
929 describe_artifacts(zWhere);
930 db_prepare(&q,
931 "SELECT uuid, summary, isPrivate\n"
932 " FROM description\n"
933 " ORDER BY ctime, type;"
934 );
935 while( db_step(&q)==SQLITE_ROW ){
936 if( zLabel ){
937 fossil_print("%s\n", zLabel);
938 zLabel = 0;
939 }
940 fossil_print(" %.16s %s", db_column_text(&q,0), db_column_text(&q,1));
941 if( db_column_int(&q,2) ) fossil_print(" (unpublished)");
942 fossil_print("\n");
943 cnt++;
944 }
945 db_finalize(&q);
946 db_multi_exec("DELETE FROM description;");
947 return cnt;
948 }
949
950 /*
951 ** COMMAND: test-describe-artifacts
952 **
953 ** Usage: %fossil test-describe-artifacts [--from S] [--count N]
954 **
955 ** Display a one-line description of every artifact.
956 */
957 void test_describe_artifacts_cmd(void){
958 int iFrom = 0;
959 int iCnt = 1000000;
960 const char *z;
961 char *zRange;
962 db_find_and_open_repository(0,0);
963 z = find_option("from",0,1);
964 if( z ) iFrom = atoi(z);
965 z = find_option("count",0,1);
966 if( z ) iCnt = atoi(z);
967 zRange = mprintf("BETWEEN %d AND %d", iFrom, iFrom+iCnt-1);
968 describe_artifacts_to_stdout(zRange, 0);
969 }
970
971 /*
972 ** WEBPAGE: bloblist
973 **
974 ** Return a page showing all artifacts in the repository. Query parameters:
975 **
976 ** n=N Show N artifacts
977 ** s=S Start with artifact number S
978 */
979 void bloblist_page(void){
980 Stmt q;
981 int s = atoi(PD("s","0"));
982 int n = atoi(PD("n","5000"));
983 int mx = db_int(0, "SELECT max(rid) FROM blob");
984 char *zRange;
985
986 login_check_credentials();
987 if( !g.perm.Read ){ login_needed(); return; }
988 style_header("List Of Artifacts");
989 if( mx>n && P("s")==0 ){
990 int i;
991 @ <p>Select a range of artifacts to view:</p>
992 @ <ul>
993 for(i=1; i<=mx; i+=n){
994 @ <li> %z(href("%R/bloblist?s=%d&n=%d",i,n))
995 @ %d(i)..%d(i+n-1<mx?i+n-1:mx)</a>
996 }
997 @ </ul>
998 style_footer();
999 return;
1000 }
1001 if( mx>n ){
1002 style_submenu_element("Index", "Index", "bloblist");
1003 }
1004 zRange = mprintf("BETWEEN %d AND %d", s, s+n-1);
1005 describe_artifacts(zRange);
1006 db_prepare(&q,
1007 "SELECT rid, uuid, summary, isPrivate FROM description ORDER BY rid"
1008 );
1009 @ <table cellpadding="0" cellspacing="0">
1010 while( db_step(&q)==SQLITE_ROW ){
1011 int rid = db_column_int(&q,0);
1012 const char *zUuid = db_column_text(&q, 1);
1013 const char *zDesc = db_column_text(&q, 2);
1014 int isPriv = db_column_int(&q,2);
1015 @ <tr><td align="right">%d(rid)</td>
1016 @ <td>&nbsp;%z(href("%R/info/%s",zUuid))%s(zUuid)</a>&nbsp;</td>
1017 @ <td align="left">%h(zDesc)</td>
1018 if( isPriv ){
1019 @ <td>(unpublished)</td>
1020 }
1021 @ </tr>
1022 }
1023 @ </table>
1024 db_finalize(&q);
1025 style_footer();
1026 }
1027
1028 /*
1029 ** COMMAND: test-unsent
1030 **
1031 ** Usage: %fossil test-unsent
1032 **
1033 ** Show all artifacts in the unsent table
1034 */
1035 void test_unsent_cmd(void){
1036 db_find_and_open_repository(0,0);
1037 describe_artifacts_to_stdout("IN unsent", 0);
1038 }
1039
1040 /*
1041 ** COMMAND: test-unclustered
1042 **
1043 ** Usage: %fossil test-unclustered
1044 **
1045 ** Show all artifacts in the unclustered table
1046 */
1047 void test_unclusterd_cmd(void){
1048 db_find_and_open_repository(0,0);
1049 describe_artifacts_to_stdout("IN unclustered", 0);
1050 }
1051
1052 /*
1053 ** COMMAND: test-phantoms
1054 **
1055 ** Usage: %fossil test-phantoms
1056 **
1057 ** Show all phantom artifacts
1058 */
1059 void test_phatoms_cmd(void){
1060 db_find_and_open_repository(0,0);
1061 describe_artifacts_to_stdout("IN (SELECT rid FROM blob WHERE size<0)", 0);
1062 }
1063
1064 DDED src/publish.c
1065 DDED src/purge.c
--- 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
--- a/src/purge.c
+++ b/src/purge.c
@@ -0,0 +1 @@
1
+db_n
--- 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
+10 -5
--- src/rebuild.c
+++ src/rebuild.c
@@ -348,11 +348,12 @@
348348
zTable = db_text(0,
349349
"SELECT name FROM sqlite_master /*scan*/"
350350
" WHERE type='table'"
351351
" AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user',"
352352
"'config','shun','private','reportfmt',"
353
- "'concealed','accesslog','modreq')"
353
+ "'concealed','accesslog','modreq',"
354
+ "'purgeevent','purgeitem')"
354355
" AND name NOT GLOB 'sqlite_*'"
355356
" AND name NOT GLOB 'fx_*'"
356357
);
357358
if( zTable==0 ) break;
358359
db_multi_exec("DROP TABLE %Q", zTable);
@@ -829,14 +830,18 @@
829830
"DELETE FROM config WHERE name GLOB 'skin:*';"
830831
"DELETE FROM config WHERE name GLOB 'subrepo:*';"
831832
);
832833
if( bVerily ){
833834
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"
838843
);
839844
}
840845
}
841846
if( !bNeedRebuild ){
842847
db_end_transaction(0);
843848
--- 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
+77 -21
--- src/report.c
+++ src/report.c
@@ -922,42 +922,85 @@
922922
923923
/*
924924
** Output Javascript code that will enables sorting of the table with
925925
** the id zTableId by clicking.
926926
**
927
-** The javascript is derived from:
927
+** The javascript was originally derived from:
928928
**
929929
** http://www.webtoolkit.info/sortable-html-table.html
930
+**
931
+** But there have been extensive modifications.
930932
**
931933
** This variation allows column types to be expressed using the second
932934
** argument. Each character of the second argument represent a column.
933
-** "t" means sort as text. "n" means sort numerically. "x" means do not
934
-** sort on this column. If there are fewer characters in zColumnTypes[] than
935
-** their are columns, the all extra columns assume type "t" (text).
935
+**
936
+** t Sort by text
937
+** n Sort numerically
938
+** k Sort by the data-sortkey property
939
+** x This column is not sortable
940
+**
941
+** If there are fewer characters in zColumnTypes[] than their are columns,
942
+** the all extra columns assume type "t" (text).
943
+**
944
+** The third parameter is the column that was initially sorted (using 1-based
945
+** column numbers, like SQL). Make this value 0 if none of the columns are
946
+** initially sorted. Make the value negative if the column is initially sorted
947
+** in reverse order.
948
+**
949
+** Clicking on the same column header twice in a row inverts the sort.
936950
*/
937
-void output_table_sorting_javascript(const char *zTableId, const char *zColumnTypes){
951
+void output_table_sorting_javascript(
952
+ const char *zTableId, /* ID of table to sort */
953
+ const char *zColumnTypes, /* String for column types */
954
+ int iInitSort /* Initially sorted column. Leftmost is 1. 0 for NONE */
955
+){
938956
@ <script>
939
- @ function SortableTable(tableEl,columnTypes){
957
+ @ function SortableTable(tableEl,columnTypes,initSort){
940958
@ this.tbody = tableEl.getElementsByTagName('tbody');
959
+ @ this.columnTypes = columnTypes;
941960
@ this.sort = function (cell) {
942961
@ var column = cell.cellIndex;
943
- @ var sortFn = cell.sortType=="n" ? this.sortNumeric : this.sortText;
962
+ @ var sortFn;
963
+ @ switch( cell.sortType ){
964
+ @ case "n": sortFn = this.sortNumeric; break;
965
+ @ case "t": sortFn = this.sortText; break;
966
+ @ case "k": sortFn = this.sortKey; break;
967
+ @ case "x": return;
968
+ @ }
944969
@ this.sortIndex = column;
945970
@ var newRows = new Array();
946971
@ for (j = 0; j < this.tbody[0].rows.length; j++) {
947972
@ newRows[j] = this.tbody[0].rows[j];
948973
@ }
949
- @ newRows.sort(sortFn);
950
- @ if (cell.getAttribute("sortdir") == 'down') {
951
- @ newRows.reverse();
952
- @ cell.setAttribute('sortdir','up');
953
- @ } else {
954
- @ cell.setAttribute('sortdir','down');
974
+ @ if( this.sortIndex==Math.abs(this.prevColumn)-1 ){
975
+ @ newRows.reverse();
976
+ @ this.prevColumn = -this.prevColumn;
977
+ @ }else{
978
+ @ newRows.sort(sortFn);
979
+ @ this.prevColumn = this.sortIndex+1;
955980
@ }
956981
@ for (i=0;i<newRows.length;i++) {
957982
@ this.tbody[0].appendChild(newRows[i]);
958983
@ }
984
+ @ this.setHdrIcons();
985
+ @ }
986
+ @ this.setHdrIcons = function() {
987
+ @ for (var i=0; i<this.hdrRow.cells.length; i++) {
988
+ @ if( this.columnTypes[i]=='x' ) continue;
989
+ @ var sortType;
990
+ @ if( this.prevColumn==i+1 ){
991
+ @ sortType = 'asc';
992
+ @ }else if( this.prevColumn==(-1-i) ){
993
+ @ sortType = 'desc'
994
+ @ }else{
995
+ @ sortType = 'none';
996
+ @ }
997
+ @ var hdrCell = this.hdrRow.cells[i];
998
+ @ var clsName = hdrCell.className.replace(/\s*\bsort\s*\w+/, '');
999
+ @ clsName += ' sort ' + sortType;
1000
+ @ hdrCell.className = clsName;
1001
+ @ }
9591002
@ }
9601003
@ this.sortText = function(a,b) {
9611004
@ var i = thisObject.sortIndex;
9621005
@ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
9631006
@ bb = b.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
@@ -971,30 +1014,43 @@
9711014
@ if (isNaN(aa)) aa = 0;
9721015
@ bb = parseFloat(b.cells[i].textContent);
9731016
@ if (isNaN(bb)) bb = 0;
9741017
@ return aa-bb;
9751018
@ }
976
- @ var thisObject = this;
1019
+ @ this.sortKey = function(a,b) {
1020
+ @ var i = thisObject.sortIndex;
1021
+ @ aa = a.cells[i].getAttribute("data-sortkey");
1022
+ @ bb = b.cells[i].getAttribute("data-sortkey");
1023
+ @ if(aa==bb) return 0;
1024
+ @ if(aa<bb) return -1;
1025
+ @ return 1;
1026
+ @ }
9771027
@ var x = tableEl.getElementsByTagName('thead');
9781028
@ if(!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length>0)){
9791029
@ return;
9801030
@ }
9811031
@ if(x && x[0].rows && x[0].rows.length > 0) {
982
- @ var sortRow = x[0].rows[0];
1032
+ @ this.hdrRow = x[0].rows[0];
9831033
@ } else {
9841034
@ return;
9851035
@ }
986
- @ for (var i=0; i<sortRow.cells.length; i++) {
987
- @ sortRow.cells[i].sTable = this;
988
- @ sortRow.cells[i].sortType = columnTypes[i] || 't';
989
- @ sortRow.cells[i].onclick = function () {
1036
+ @ var thisObject = this;
1037
+ @ this.prevColumn = initSort;
1038
+ @ for (var i=0; i<this.hdrRow.cells.length; i++) {
1039
+ @ if( columnTypes[i]=='x' ) continue;
1040
+ @ var hdrcell = this.hdrRow.cells[i];
1041
+ @ hdrcell.sTable = this;
1042
+ @ hdrcell.style.cursor = "pointer";
1043
+ @ hdrcell.sortType = columnTypes[i] || 't';
1044
+ @ hdrcell.onclick = function () {
9901045
@ this.sTable.sort(this);
9911046
@ return false;
9921047
@ }
9931048
@ }
1049
+ @ this.setHdrIcons()
9941050
@ }
995
- @ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)");
1051
+ @ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)",%d(iInitSort));
9961052
@ </script>
9971053
}
9981054
9991055
10001056
/*
@@ -1086,11 +1142,11 @@
10861142
if( zErr1 ){
10871143
@ <p class="reportError">Error: %h(zErr1)</p>
10881144
}else if( zErr2 ){
10891145
@ <p class="reportError">Error: %h(zErr2)</p>
10901146
}
1091
- output_table_sorting_javascript("reportTable","");
1147
+ output_table_sorting_javascript("reportTable","",0);
10921148
style_footer();
10931149
}else{
10941150
report_restrict_sql(&zErr1);
10951151
db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
10961152
report_unrestrict_sql();
10971153
--- src/report.c
+++ src/report.c
@@ -922,42 +922,85 @@
922
923 /*
924 ** Output Javascript code that will enables sorting of the table with
925 ** the id zTableId by clicking.
926 **
927 ** The javascript is derived from:
928 **
929 ** http://www.webtoolkit.info/sortable-html-table.html
 
 
930 **
931 ** This variation allows column types to be expressed using the second
932 ** argument. Each character of the second argument represent a column.
933 ** "t" means sort as text. "n" means sort numerically. "x" means do not
934 ** sort on this column. If there are fewer characters in zColumnTypes[] than
935 ** their are columns, the all extra columns assume type "t" (text).
 
 
 
 
 
 
 
 
 
 
 
 
936 */
937 void output_table_sorting_javascript(const char *zTableId, const char *zColumnTypes){
 
 
 
 
938 @ <script>
939 @ function SortableTable(tableEl,columnTypes){
940 @ this.tbody = tableEl.getElementsByTagName('tbody');
 
941 @ this.sort = function (cell) {
942 @ var column = cell.cellIndex;
943 @ var sortFn = cell.sortType=="n" ? this.sortNumeric : this.sortText;
 
 
 
 
 
 
944 @ this.sortIndex = column;
945 @ var newRows = new Array();
946 @ for (j = 0; j < this.tbody[0].rows.length; j++) {
947 @ newRows[j] = this.tbody[0].rows[j];
948 @ }
949 @ newRows.sort(sortFn);
950 @ if (cell.getAttribute("sortdir") == 'down') {
951 @ newRows.reverse();
952 @ cell.setAttribute('sortdir','up');
953 @ } else {
954 @ cell.setAttribute('sortdir','down');
955 @ }
956 @ for (i=0;i<newRows.length;i++) {
957 @ this.tbody[0].appendChild(newRows[i]);
958 @ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
959 @ }
960 @ this.sortText = function(a,b) {
961 @ var i = thisObject.sortIndex;
962 @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
963 @ bb = b.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
@@ -971,30 +1014,43 @@
971 @ if (isNaN(aa)) aa = 0;
972 @ bb = parseFloat(b.cells[i].textContent);
973 @ if (isNaN(bb)) bb = 0;
974 @ return aa-bb;
975 @ }
976 @ var thisObject = this;
 
 
 
 
 
 
 
977 @ var x = tableEl.getElementsByTagName('thead');
978 @ if(!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length>0)){
979 @ return;
980 @ }
981 @ if(x && x[0].rows && x[0].rows.length > 0) {
982 @ var sortRow = x[0].rows[0];
983 @ } else {
984 @ return;
985 @ }
986 @ for (var i=0; i<sortRow.cells.length; i++) {
987 @ sortRow.cells[i].sTable = this;
988 @ sortRow.cells[i].sortType = columnTypes[i] || 't';
989 @ sortRow.cells[i].onclick = function () {
 
 
 
 
 
990 @ this.sTable.sort(this);
991 @ return false;
992 @ }
993 @ }
 
994 @ }
995 @ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)");
996 @ </script>
997 }
998
999
1000 /*
@@ -1086,11 +1142,11 @@
1086 if( zErr1 ){
1087 @ <p class="reportError">Error: %h(zErr1)</p>
1088 }else if( zErr2 ){
1089 @ <p class="reportError">Error: %h(zErr2)</p>
1090 }
1091 output_table_sorting_javascript("reportTable","");
1092 style_footer();
1093 }else{
1094 report_restrict_sql(&zErr1);
1095 db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
1096 report_unrestrict_sql();
1097
--- src/report.c
+++ src/report.c
@@ -922,42 +922,85 @@
922
923 /*
924 ** Output Javascript code that will enables sorting of the table with
925 ** the id zTableId by clicking.
926 **
927 ** The javascript was originally derived from:
928 **
929 ** http://www.webtoolkit.info/sortable-html-table.html
930 **
931 ** But there have been extensive modifications.
932 **
933 ** This variation allows column types to be expressed using the second
934 ** argument. Each character of the second argument represent a column.
935 **
936 ** t Sort by text
937 ** n Sort numerically
938 ** k Sort by the data-sortkey property
939 ** x This column is not sortable
940 **
941 ** If there are fewer characters in zColumnTypes[] than their are columns,
942 ** the all extra columns assume type "t" (text).
943 **
944 ** The third parameter is the column that was initially sorted (using 1-based
945 ** column numbers, like SQL). Make this value 0 if none of the columns are
946 ** initially sorted. Make the value negative if the column is initially sorted
947 ** in reverse order.
948 **
949 ** Clicking on the same column header twice in a row inverts the sort.
950 */
951 void output_table_sorting_javascript(
952 const char *zTableId, /* ID of table to sort */
953 const char *zColumnTypes, /* String for column types */
954 int iInitSort /* Initially sorted column. Leftmost is 1. 0 for NONE */
955 ){
956 @ <script>
957 @ function SortableTable(tableEl,columnTypes,initSort){
958 @ this.tbody = tableEl.getElementsByTagName('tbody');
959 @ this.columnTypes = columnTypes;
960 @ this.sort = function (cell) {
961 @ var column = cell.cellIndex;
962 @ var sortFn;
963 @ switch( cell.sortType ){
964 @ case "n": sortFn = this.sortNumeric; break;
965 @ case "t": sortFn = this.sortText; break;
966 @ case "k": sortFn = this.sortKey; break;
967 @ case "x": return;
968 @ }
969 @ this.sortIndex = column;
970 @ var newRows = new Array();
971 @ for (j = 0; j < this.tbody[0].rows.length; j++) {
972 @ newRows[j] = this.tbody[0].rows[j];
973 @ }
974 @ if( this.sortIndex==Math.abs(this.prevColumn)-1 ){
975 @ newRows.reverse();
976 @ this.prevColumn = -this.prevColumn;
977 @ }else{
978 @ newRows.sort(sortFn);
979 @ this.prevColumn = this.sortIndex+1;
980 @ }
981 @ for (i=0;i<newRows.length;i++) {
982 @ this.tbody[0].appendChild(newRows[i]);
983 @ }
984 @ this.setHdrIcons();
985 @ }
986 @ this.setHdrIcons = function() {
987 @ for (var i=0; i<this.hdrRow.cells.length; i++) {
988 @ if( this.columnTypes[i]=='x' ) continue;
989 @ var sortType;
990 @ if( this.prevColumn==i+1 ){
991 @ sortType = 'asc';
992 @ }else if( this.prevColumn==(-1-i) ){
993 @ sortType = 'desc'
994 @ }else{
995 @ sortType = 'none';
996 @ }
997 @ var hdrCell = this.hdrRow.cells[i];
998 @ var clsName = hdrCell.className.replace(/\s*\bsort\s*\w+/, '');
999 @ clsName += ' sort ' + sortType;
1000 @ hdrCell.className = clsName;
1001 @ }
1002 @ }
1003 @ this.sortText = function(a,b) {
1004 @ var i = thisObject.sortIndex;
1005 @ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
1006 @ bb = b.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
@@ -971,30 +1014,43 @@
1014 @ if (isNaN(aa)) aa = 0;
1015 @ bb = parseFloat(b.cells[i].textContent);
1016 @ if (isNaN(bb)) bb = 0;
1017 @ return aa-bb;
1018 @ }
1019 @ this.sortKey = function(a,b) {
1020 @ var i = thisObject.sortIndex;
1021 @ aa = a.cells[i].getAttribute("data-sortkey");
1022 @ bb = b.cells[i].getAttribute("data-sortkey");
1023 @ if(aa==bb) return 0;
1024 @ if(aa<bb) return -1;
1025 @ return 1;
1026 @ }
1027 @ var x = tableEl.getElementsByTagName('thead');
1028 @ if(!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length>0)){
1029 @ return;
1030 @ }
1031 @ if(x && x[0].rows && x[0].rows.length > 0) {
1032 @ this.hdrRow = x[0].rows[0];
1033 @ } else {
1034 @ return;
1035 @ }
1036 @ var thisObject = this;
1037 @ this.prevColumn = initSort;
1038 @ for (var i=0; i<this.hdrRow.cells.length; i++) {
1039 @ if( columnTypes[i]=='x' ) continue;
1040 @ var hdrcell = this.hdrRow.cells[i];
1041 @ hdrcell.sTable = this;
1042 @ hdrcell.style.cursor = "pointer";
1043 @ hdrcell.sortType = columnTypes[i] || 't';
1044 @ hdrcell.onclick = function () {
1045 @ this.sTable.sort(this);
1046 @ return false;
1047 @ }
1048 @ }
1049 @ this.setHdrIcons()
1050 @ }
1051 @ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)",%d(iInitSort));
1052 @ </script>
1053 }
1054
1055
1056 /*
@@ -1086,11 +1142,11 @@
1142 if( zErr1 ){
1143 @ <p class="reportError">Error: %h(zErr1)</p>
1144 }else if( zErr2 ){
1145 @ <p class="reportError">Error: %h(zErr2)</p>
1146 }
1147 output_table_sorting_javascript("reportTable","",0);
1148 style_footer();
1149 }else{
1150 report_restrict_sql(&zErr1);
1151 db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
1152 report_unrestrict_sql();
1153
+2 -2
--- src/schema.c
+++ src/schema.c
@@ -81,12 +81,12 @@
8181
@ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content
8282
@ content BLOB, -- Compressed content of this record
8383
@ CHECK( length(uuid)==40 AND rid>0 )
8484
@ );
8585
@ 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
8888
@ );
8989
@ CREATE INDEX delta_i1 ON delta(srcid);
9090
@
9191
@ -------------------------------------------------------------------------
9292
@ -- The BLOB and DELTA tables above hold the "global state" of a Fossil
9393
--- 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
+53 -37
--- src/search.c
+++ src/search.c
@@ -13,27 +13,32 @@
1313
** [email protected]
1414
** http://www.hwaci.com/drh/
1515
**
1616
*******************************************************************************
1717
**
18
-** This file contains code to implement the "/doc" web page and related
19
-** pages.
18
+** This file contains code to implement a very simple search function
19
+** against timeline comments, checkin content, wiki pages, and/or tickets.
20
+**
21
+** The search is full-text like in that it is looking for words and ignores
22
+** punctuation and capitalization. But it is more akin to "grep" in that
23
+** it scans the entire corpus for the search, and it does not support the
24
+** full functionality of FTS4.
2025
*/
2126
#include "config.h"
2227
#include "search.h"
2328
#include <assert.h>
2429
2530
#if INTERFACE
2631
/*
27
-** A compiled search patter
32
+** A compiled search pattern
2833
*/
2934
struct Search {
30
- int nTerm;
31
- struct srchTerm {
32
- char *z;
33
- int n;
34
- } a[8];
35
+ int nTerm; /* Number of search terms */
36
+ struct srchTerm { /* For each search term */
37
+ char *z; /* Text */
38
+ int n; /* length */
39
+ } a[8];
3540
};
3641
#endif
3742
3843
/*
3944
** Compile a search pattern
@@ -98,43 +103,47 @@
98103
** * 10 bonus points if the first occurrence is an exact match
99104
** * 1 additional point for each subsequent match of the same word
100105
** * Extra points of two consecutive words of the pattern are consecutive
101106
** in the document
102107
*/
103
-int search_score(Search *p, const char *zDoc){
108
+int search_score(Search *p, int nDoc, const char **azDoc){
104109
int iPrev = 999;
105110
int score = 10;
106111
int iBonus = 0;
107
- int i, j;
112
+ int i, j, k;
113
+ const char *zDoc;
108114
unsigned char seen[8];
109115
110116
memset(seen, 0, sizeof(seen));
111
- if( zDoc==0 ) return score;
112
- for(i=0; zDoc[i]; i++){
113
- char c = zDoc[i];
114
- if( isBoundary[c&0xff] ) continue;
115
- for(j=0; j<p->nTerm; j++){
116
- int n = p->a[j].n;
117
- if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){
118
- score += 1;
119
- if( !seen[j] ){
120
- if( isBoundary[zDoc[i+n]&0xff] ) score += 10;
121
- seen[j] = 1;
122
- }
123
- if( j==iPrev+1 ){
124
- score += iBonus;
125
- }
126
- i += n-1;
127
- iPrev = j;
128
- iBonus = 50;
129
- break;
130
- }
131
- }
132
- iBonus /= 2;
133
- while( !isBoundary[zDoc[i]&0xff] ){ i++; }
134
- }
135
-
117
+ for(k=0; k<nDoc; k++){
118
+ zDoc = azDoc[k];
119
+ if( zDoc==0 ) continue;
120
+ for(i=0; zDoc[i]; i++){
121
+ char c = zDoc[i];
122
+ if( isBoundary[c&0xff] ) continue;
123
+ for(j=0; j<p->nTerm; j++){
124
+ int n = p->a[j].n;
125
+ if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){
126
+ score += 1;
127
+ if( !seen[j] ){
128
+ if( isBoundary[zDoc[i+n]&0xff] ) score += 10;
129
+ seen[j] = 1;
130
+ }
131
+ if( j==iPrev+1 ){
132
+ score += iBonus;
133
+ }
134
+ i += n-1;
135
+ iPrev = j;
136
+ iBonus = 50;
137
+ break;
138
+ }
139
+ }
140
+ iBonus /= 2;
141
+ while( !isBoundary[zDoc[i]&0xff] ){ i++; }
142
+ }
143
+ }
144
+
136145
/* Every term must be seen or else the score is zero */
137146
for(j=0; j<p->nTerm; j++){
138147
if( !seen[j] ) return 0;
139148
}
140149
@@ -149,21 +158,28 @@
149158
sqlite3_context *context,
150159
int argc,
151160
sqlite3_value **argv
152161
){
153162
Search *p = (Search*)sqlite3_user_data(context);
154
- int score = search_score(p, (const char*)sqlite3_value_text(argv[0]));
163
+ const char **azDoc;
164
+ int score;
165
+ int i;
166
+
167
+ azDoc = fossil_malloc( sizeof(const char*)*(argc+1) );
168
+ for(i=0; i<argc; i++) azDoc[i] = (const char*)sqlite3_value_text(argv[i]);
169
+ score = search_score(p, argc, azDoc);
170
+ fossil_free(azDoc);
155171
sqlite3_result_int(context, score);
156172
}
157173
158174
/*
159175
** Register the "score()" SQL function to score its input text
160176
** using the given Search object. Once this function is registered,
161177
** do not delete the Search object.
162178
*/
163179
void search_sql_setup(Search *p){
164
- sqlite3_create_function(g.db, "score", 1, SQLITE_UTF8, p,
180
+ sqlite3_create_function(g.db, "score", -1, SQLITE_UTF8, p,
165181
search_score_sqlfunc, 0, 0);
166182
}
167183
168184
/*
169185
** Testing the search function.
170186
--- src/search.c
+++ src/search.c
@@ -13,27 +13,32 @@
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** This file contains code to implement the "/doc" web page and related
19 ** pages.
 
 
 
 
 
20 */
21 #include "config.h"
22 #include "search.h"
23 #include <assert.h>
24
25 #if INTERFACE
26 /*
27 ** A compiled search patter
28 */
29 struct Search {
30 int nTerm;
31 struct srchTerm {
32 char *z;
33 int n;
34 } a[8];
35 };
36 #endif
37
38 /*
39 ** Compile a search pattern
@@ -98,43 +103,47 @@
98 ** * 10 bonus points if the first occurrence is an exact match
99 ** * 1 additional point for each subsequent match of the same word
100 ** * Extra points of two consecutive words of the pattern are consecutive
101 ** in the document
102 */
103 int search_score(Search *p, const char *zDoc){
104 int iPrev = 999;
105 int score = 10;
106 int iBonus = 0;
107 int i, j;
 
108 unsigned char seen[8];
109
110 memset(seen, 0, sizeof(seen));
111 if( zDoc==0 ) return score;
112 for(i=0; zDoc[i]; i++){
113 char c = zDoc[i];
114 if( isBoundary[c&0xff] ) continue;
115 for(j=0; j<p->nTerm; j++){
116 int n = p->a[j].n;
117 if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){
118 score += 1;
119 if( !seen[j] ){
120 if( isBoundary[zDoc[i+n]&0xff] ) score += 10;
121 seen[j] = 1;
122 }
123 if( j==iPrev+1 ){
124 score += iBonus;
125 }
126 i += n-1;
127 iPrev = j;
128 iBonus = 50;
129 break;
130 }
131 }
132 iBonus /= 2;
133 while( !isBoundary[zDoc[i]&0xff] ){ i++; }
134 }
135
 
 
 
136 /* Every term must be seen or else the score is zero */
137 for(j=0; j<p->nTerm; j++){
138 if( !seen[j] ) return 0;
139 }
140
@@ -149,21 +158,28 @@
149 sqlite3_context *context,
150 int argc,
151 sqlite3_value **argv
152 ){
153 Search *p = (Search*)sqlite3_user_data(context);
154 int score = search_score(p, (const char*)sqlite3_value_text(argv[0]));
 
 
 
 
 
 
 
155 sqlite3_result_int(context, score);
156 }
157
158 /*
159 ** Register the "score()" SQL function to score its input text
160 ** using the given Search object. Once this function is registered,
161 ** do not delete the Search object.
162 */
163 void search_sql_setup(Search *p){
164 sqlite3_create_function(g.db, "score", 1, SQLITE_UTF8, p,
165 search_score_sqlfunc, 0, 0);
166 }
167
168 /*
169 ** Testing the search function.
170
--- src/search.c
+++ src/search.c
@@ -13,27 +13,32 @@
13 ** [email protected]
14 ** http://www.hwaci.com/drh/
15 **
16 *******************************************************************************
17 **
18 ** This file contains code to implement a very simple search function
19 ** against timeline comments, checkin content, wiki pages, and/or tickets.
20 **
21 ** The search is full-text like in that it is looking for words and ignores
22 ** punctuation and capitalization. But it is more akin to "grep" in that
23 ** it scans the entire corpus for the search, and it does not support the
24 ** full functionality of FTS4.
25 */
26 #include "config.h"
27 #include "search.h"
28 #include <assert.h>
29
30 #if INTERFACE
31 /*
32 ** A compiled search pattern
33 */
34 struct Search {
35 int nTerm; /* Number of search terms */
36 struct srchTerm { /* For each search term */
37 char *z; /* Text */
38 int n; /* length */
39 } a[8];
40 };
41 #endif
42
43 /*
44 ** Compile a search pattern
@@ -98,43 +103,47 @@
103 ** * 10 bonus points if the first occurrence is an exact match
104 ** * 1 additional point for each subsequent match of the same word
105 ** * Extra points of two consecutive words of the pattern are consecutive
106 ** in the document
107 */
108 int search_score(Search *p, int nDoc, const char **azDoc){
109 int iPrev = 999;
110 int score = 10;
111 int iBonus = 0;
112 int i, j, k;
113 const char *zDoc;
114 unsigned char seen[8];
115
116 memset(seen, 0, sizeof(seen));
117 for(k=0; k<nDoc; k++){
118 zDoc = azDoc[k];
119 if( zDoc==0 ) continue;
120 for(i=0; zDoc[i]; i++){
121 char c = zDoc[i];
122 if( isBoundary[c&0xff] ) continue;
123 for(j=0; j<p->nTerm; j++){
124 int n = p->a[j].n;
125 if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){
126 score += 1;
127 if( !seen[j] ){
128 if( isBoundary[zDoc[i+n]&0xff] ) score += 10;
129 seen[j] = 1;
130 }
131 if( j==iPrev+1 ){
132 score += iBonus;
133 }
134 i += n-1;
135 iPrev = j;
136 iBonus = 50;
137 break;
138 }
139 }
140 iBonus /= 2;
141 while( !isBoundary[zDoc[i]&0xff] ){ i++; }
142 }
143 }
144
145 /* Every term must be seen or else the score is zero */
146 for(j=0; j<p->nTerm; j++){
147 if( !seen[j] ) return 0;
148 }
149
@@ -149,21 +158,28 @@
158 sqlite3_context *context,
159 int argc,
160 sqlite3_value **argv
161 ){
162 Search *p = (Search*)sqlite3_user_data(context);
163 const char **azDoc;
164 int score;
165 int i;
166
167 azDoc = fossil_malloc( sizeof(const char*)*(argc+1) );
168 for(i=0; i<argc; i++) azDoc[i] = (const char*)sqlite3_value_text(argv[i]);
169 score = search_score(p, argc, azDoc);
170 fossil_free(azDoc);
171 sqlite3_result_int(context, score);
172 }
173
174 /*
175 ** Register the "score()" SQL function to score its input text
176 ** using the given Search object. Once this function is registered,
177 ** do not delete the Search object.
178 */
179 void search_sql_setup(Search *p){
180 sqlite3_create_function(g.db, "score", -1, SQLITE_UTF8, p,
181 search_score_sqlfunc, 0, 0);
182 }
183
184 /*
185 ** Testing the search function.
186
+3 -3
--- src/setup.c
+++ src/setup.c
@@ -105,15 +105,15 @@
105105
"Edit HTML text for an ad unit inserted after the menu bar");
106106
setup_menu_entry("Logo", "setup_logo",
107107
"Change the logo and background images for the server");
108108
setup_menu_entry("Shunned", "shun",
109109
"Show artifacts that are shunned by this repository");
110
- setup_menu_entry("Log", "rcvfromlist",
110
+ setup_menu_entry("Artifact Receipts Log", "rcvfromlist",
111111
"A record of received artifacts and their sources");
112
- setup_menu_entry("User-Log", "access_log",
112
+ setup_menu_entry("User Log", "access_log",
113113
"A record of login attempts");
114
- setup_menu_entry("Admin-Log", "admin_log",
114
+ setup_menu_entry("Administrative Log", "admin_log",
115115
"View the admin_log entries");
116116
setup_menu_entry("Stats", "stat",
117117
"Display repository statistics");
118118
setup_menu_entry("SQL", "admin_sql",
119119
"Enter raw SQL commands");
120120
--- 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 @@
295295
**
296296
** Show a listing of RCVFROM table entries.
297297
*/
298298
void rcvfromlist_page(void){
299299
int ofst = atoi(PD("ofst","0"));
300
+ int showAll = P("all")!=0;
300301
int cnt;
301302
Stmt q;
302303
303304
login_check_credentials();
304305
if( !g.perm.Admin ){
305306
login_needed();
306307
}
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
+ }
308314
if( ofst>0 ){
309315
style_submenu_element("Newer", "Newer", "rcvfromlist?ofst=%d",
310316
ofst>30 ? ofst-30 : 0);
311317
}
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
+ );
312322
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)"
314325
" 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
317328
);
318329
@ <p>Whenever new artifacts are added to the repository, either by
319330
@ push or using the web interface, an entry is made in the RCVFROM table
320331
@ to record the source of that artifact. This log facilitates
321332
@ finding and fixing attempts to inject illicit content into the
322333
@ repository.</p>
323334
@
324335
@ <p>Click on the "rcvid" to show a list of specific artifacts received
325336
@ 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>
327340
@
328341
@ <table cellpadding="0" cellspacing="0" border="0">
329342
@ <tr><th style="padding-right: 15px;text-align: right;">rcvid</th>
330343
@ <th style="padding-right: 15px;text-align: left;">Date</th>
331344
@ <th style="padding-right: 15px;text-align: left;">User</th>
@@ -334,17 +347,22 @@
334347
while( db_step(&q)==SQLITE_ROW ){
335348
int rcvid = db_column_int(&q, 0);
336349
const char *zUser = db_column_text(&q, 1);
337350
const char *zDate = db_column_text(&q, 2);
338351
const char *zIpAddr = db_column_text(&q, 3);
339
- if( cnt==30 ){
352
+ if( cnt==30 && !showAll ){
340353
style_submenu_element("Older", "Older",
341354
"rcvfromlist?ofst=%d", ofst+30);
342355
}else{
343356
cnt++;
344357
@ <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
+ }
346364
@ <td style="padding-right: 15px;text-align: left;">%s(zDate)</td>
347365
@ <td style="padding-right: 15px;text-align: left;">%h(zUser)</td>
348366
@ <td style="text-align: left;">%s(zIpAddr)</td>
349367
@ </tr>
350368
}
@@ -365,22 +383,24 @@
365383
366384
login_check_credentials();
367385
if( !g.perm.Admin ){
368386
login_needed();
369387
}
370
- style_header("Content Source %d", rcvid);
388
+ style_header("Artifact Receipt %d", rcvid);
371389
if( db_exists(
372390
"SELECT 1 FROM blob WHERE rcvid=%d AND"
373391
" NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
374392
){
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);
376395
}
377396
if( db_exists(
378397
"SELECT 1 FROM blob WHERE rcvid=%d AND"
379398
" EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
380399
){
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);
382402
}
383403
db_prepare(&q,
384404
"SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
385405
" FROM rcvfrom LEFT JOIN user USING(uid)"
386406
" WHERE rcvid=%d",
@@ -399,22 +419,30 @@
399419
@ <td valign="top">%s(zDate)</td></tr>
400420
@ <tr><th valign="top" align="right">IP&nbsp;Address:</th>
401421
@ <td valign="top">%s(zIpAddr)</td></tr>
402422
}
403423
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");
404429
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
406433
);
407434
@ <tr><th valign="top" align="right">Artifacts:</th>
408435
@ <td valign="top">
409436
while( db_step(&q)==SQLITE_ROW ){
410
- int rid = db_column_int(&q, 0);
411437
const char *zUuid = db_column_text(&q, 1);
412438
int size = db_column_int(&q, 2);
439
+ const char *zDesc = db_column_text(&q, 3);
440
+ if( zDesc==0 ) zDesc = "";
413441
@ <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 />
415443
}
416444
@ </td></tr>
417445
@ </table>
418446
db_finalize(&q);
419447
style_footer();
420448
}
421449
422450
ADDED src/sitemap.c
--- 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&nbsp;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
422 DDED src/sitemap.c
--- 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&nbsp;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
450 DDED src/sitemap.c
--- a/src/sitemap.c
+++ b/src/sitemap.c
@@ -0,0 +1,43 @@
1
+avtimeline?n=all&imeline?n=all& @ warps"))List of "Timewarp" Check-inTest Pages </ul></li>body_and_footer("sitemap");
2
+ }
3
+}
4
+footer();
5
+ }
6
+}
7
+?name=Sandbox"))SandboxHelphelp"))List of All Commands and Web@mimetype map1style_header("Site Map");
8
+style_footer();
9
+}
10
+divul id="sitemap">
11
+</div>
12
+ style_footer();
13
+}
14
+</librlist"))Branchesaglist"))TagsdTktli>
15
+ style_footer();
16
+}
17
+?n=200}
18
+line?n=all& @ warps"))List of "Timewarp" Check-inTest Pages </ul></li>body_and_footer("sitemap");
19
+ }
20
+}
21
+footer();
22
+ }
23
+}
24
+?name=Sandboxavtimeline?n=all&imeline?n=all& @ warps"))List of "Timewarp" Check-inTest Pages </ul></li>body_and_footer("sitemap");
25
+ }
26
+}
27
+footer();
28
+ @ </p>
29
+ @
30
+#endifq@N6,W@Rh,X@1B~,b:docsrch"))Search Project DocumeShow an incomplete list of@Uy,q@gW,7O@aw,c@linkest_li>
31
+ @ <ul>docsrc@ </@@ @ warps"))List of "Timewaavtimeline?n=all&imeline?n=aln=all&namechng"))All check-in@ </@@ </ul>
32
+ @ </liwi</a>
33
+ @ <ul>
34
+q@N6,W@Rh,X@1B~,b:docsrch"))Se@ omplete list o@ @ warps"))List of "avtimelinew@ @ @ @ @ </ul>
35
+ @ </li@ </ul>
36
+ @ </liblobrtifacts</a></li>
37
+ in<ultree?Branches and Tags</a>
38
+ @ <uls"))List of "avtimelinew@ @ @ @ @ </ul>
39
+ @ </li@ </ul>
40
+ @ </liblobrtifactseline?n=aln=all&namechng"))All cul>
41
+q@N6,W@Rh,X@1B~,b:docsrch"))Se@ omplete list o@ @ warps"))List of "avtimelinew@ @ @ @ @ </ul>
42
+ @ </li@ </ul>
43
+ @ </liblobrtifactsstat"))Status SummaAdministration0
--- a/src/sitemap.c
+++ b/src/sitemap.c
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/sitemap.c
+++ b/src/sitemap.c
@@ -0,0 +1,43 @@
1 avtimeline?n=all&imeline?n=all& @ warps"))List of "Timewarp" Check-inTest Pages </ul></li>body_and_footer("sitemap");
2 }
3 }
4 footer();
5 }
6 }
7 ?name=Sandbox"))SandboxHelphelp"))List of All Commands and Web@mimetype map1style_header("Site Map");
8 style_footer();
9 }
10 divul id="sitemap">
11 </div>
12 style_footer();
13 }
14 </librlist"))Branchesaglist"))TagsdTktli>
15 style_footer();
16 }
17 ?n=200}
18 line?n=all& @ warps"))List of "Timewarp" Check-inTest Pages </ul></li>body_and_footer("sitemap");
19 }
20 }
21 footer();
22 }
23 }
24 ?name=Sandboxavtimeline?n=all&imeline?n=all& @ warps"))List of "Timewarp" Check-inTest Pages </ul></li>body_and_footer("sitemap");
25 }
26 }
27 footer();
28 @ </p>
29 @
30 #endifq@N6,W@Rh,X@1B~,b:docsrch"))Search Project DocumeShow an incomplete list of@Uy,q@gW,7O@aw,c@linkest_li>
31 @ <ul>docsrc@ </@@ @ warps"))List of "Timewaavtimeline?n=all&imeline?n=aln=all&namechng"))All check-in@ </@@ </ul>
32 @ </liwi</a>
33 @ <ul>
34 q@N6,W@Rh,X@1B~,b:docsrch"))Se@ omplete list o@ @ warps"))List of "avtimelinew@ @ @ @ @ </ul>
35 @ </li@ </ul>
36 @ </liblobrtifacts</a></li>
37 in<ultree?Branches and Tags</a>
38 @ <uls"))List of "avtimelinew@ @ @ @ @ </ul>
39 @ </li@ </ul>
40 @ </liblobrtifactseline?n=aln=all&namechng"))All cul>
41 q@N6,W@Rh,X@1B~,b:docsrch"))Se@ omplete list o@ @ warps"))List of "avtimelinew@ @ @ @ @ </ul>
42 @ </li@ </ul>
43 @ </liblobrtifactsstat"))Status SummaAdministration0
+21 -20
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -106,10 +106,24 @@
106106
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
107107
}else{
108108
sqlite3_result_error(context, "input is not zlib compressed", -1);
109109
}
110110
}
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
+}
111125
112126
/*
113127
** This is the "automatic extension" initializer that runs right after
114128
** the connection to the repository database is opened. Set up the
115129
** database connection to be more useful to the human operator.
@@ -117,40 +131,27 @@
117131
static int sqlcmd_autoinit(
118132
sqlite3 *db,
119133
const char **pzErrMsg,
120134
const void *notUsed
121135
){
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);
130137
re_add_sql_func(db);
131
- foci_register(db);
132138
g.zMainDbType = "repository";
139
+ foci_register(db);
133140
g.repositoryOpen = 1;
134141
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;
142143
}
143144
144145
/*
145146
** COMMAND: sqlite3
146147
**
147
-** Usage: %fossil sqlite3 ?SQL-COMMANDS? ?OPTIONS?
148
+** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS?
148149
**
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.
152153
**
153154
** WARNING: Careless use of this command can corrupt a Fossil repository
154155
** in ways that are unrecoverable. Be sure you know what you are doing before
155156
** running any SQL commands that modifies the repository database.
156157
*/
157158
--- 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
+580 -379
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -231,11 +231,11 @@
231231
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
232232
** [sqlite_version()] and [sqlite_source_id()].
233233
*/
234234
#define SQLITE_VERSION "3.8.8"
235235
#define SQLITE_VERSION_NUMBER 3008008
236
-#define SQLITE_SOURCE_ID "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e"
236
+#define SQLITE_SOURCE_ID "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6"
237237
238238
/*
239239
** CAPI3REF: Run-Time Library Version Numbers
240240
** KEYWORDS: sqlite3_version, sqlite3_sourceid
241241
**
@@ -323,11 +323,11 @@
323323
** This interface only reports on the compile-time mutex setting
324324
** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
325325
** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
326326
** can be fully or partially disabled using a call to [sqlite3_config()]
327327
** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
328
-** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the
328
+** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the
329329
** sqlite3_threadsafe() function shows only the compile-time setting of
330330
** thread safety, not any run-time changes to that setting made by
331331
** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
332332
** is unchanged by calls to sqlite3_config().)^
333333
**
@@ -1343,11 +1343,11 @@
13431343
** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
13441344
** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
13451345
** </ul>
13461346
**
13471347
** 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.
13491349
**
13501350
** The xShmLock method can transition between unlocked and SHARED or
13511351
** between unlocked and EXCLUSIVE. It cannot transition between SHARED
13521352
** and EXCLUSIVE.
13531353
*/
@@ -1646,12 +1646,12 @@
16461646
** tracks memory usage, for example. </dd>
16471647
**
16481648
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
16491649
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
16501650
** 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:
16531653
** <ul>
16541654
** <li> [sqlite3_memory_used()]
16551655
** <li> [sqlite3_memory_highwater()]
16561656
** <li> [sqlite3_soft_heap_limit64()]
16571657
** <li> [sqlite3_status()]
@@ -1688,14 +1688,15 @@
16881688
** that SQLite can use for the database page cache with the default page
16891689
** cache implementation.
16901690
** This configuration should not be used if an application-define page
16911691
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
16921692
** 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
16941695
** memory, the size of each page buffer (sz), and the number of pages (N).
16951696
** 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
+** (a power of two between 512 and 65536) plus some extra bytes for each
16971698
** page header. ^The number of extra bytes needed by the page header
16981699
** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option
16991700
** to [sqlite3_config()].
17001701
** ^It is harmless, apart from the wasted memory,
17011702
** for the sz parameter to be larger than necessary. The first
@@ -1708,11 +1709,12 @@
17081709
** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
17091710
**
17101711
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
17111712
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
17121713
** 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].
17141716
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
17151717
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
17161718
** [SQLITE_ERROR] if invoked otherwise.
17171719
** ^There are three arguments to SQLITE_CONFIG_HEAP:
17181720
** An 8-byte aligned pointer to the memory,
@@ -1728,13 +1730,13 @@
17281730
** for the minimum allocation size are 2**5 through 2**8.</dd>
17291731
**
17301732
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
17311733
** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
17321734
** 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
17361738
** [sqlite3_config()] returns. ^If SQLite is compiled with
17371739
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
17381740
** the entire mutexing subsystem is omitted from the build and hence calls to
17391741
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
17401742
** return [SQLITE_ERROR].</dd>
@@ -1768,12 +1770,12 @@
17681770
** the interface to a custom page cache implementation.)^
17691771
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
17701772
**
17711773
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
17721774
** <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>
17751777
**
17761778
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
17771779
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
17781780
** global [error log].
17791781
** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
@@ -1794,12 +1796,13 @@
17941796
** function must be threadsafe. </dd>
17951797
**
17961798
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
17971799
** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
17981800
** 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
18011804
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
18021805
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
18031806
** connection is opened. ^If it is globally disabled, filenames are
18041807
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
18051808
** database connection is opened. ^(By default, URI handling is globally
@@ -1857,22 +1860,33 @@
18571860
** changed to its compile-time default.
18581861
**
18591862
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
18601863
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
18611864
** <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
18641867
** that specifies the maximum size of the created heap.
18651868
** </dl>
18661869
**
18671870
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
18681871
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
18691872
** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
18701873
** 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,
18731876
** target platform, and SQLite version.
1877
+**
1878
+** [[SQLITE_CONFIG_PMASZ]]
1879
+** <dt>SQLITE_CONFIG_PMASZ
1880
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
1881
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
1882
+** sorter to that integer. The default minimum PMA Size is set by the
1883
+** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched
1884
+** to help with sort operations when multithreaded sorting
1885
+** is enabled (using the [PRAGMA threads] command) and the amount of content
1886
+** to be sorted exceeds the page size times the minimum of the
1887
+** [PRAGMA cache_size] setting and this value.
18741888
** </dl>
18751889
*/
18761890
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
18771891
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
18781892
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1895,10 +1909,11 @@
18951909
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
18961910
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
18971911
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
18981912
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
18991913
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
1914
+#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
19001915
19011916
/*
19021917
** CAPI3REF: Database Connection Configuration Options
19031918
**
19041919
** These constants are the available integer configuration options that
@@ -2171,10 +2186,11 @@
21712186
SQLITE_API int sqlite3_complete(const char *sql);
21722187
SQLITE_API int sqlite3_complete16(const void *sql);
21732188
21742189
/*
21752190
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
2191
+** KEYWORDS: {busy-handler callback} {busy handler}
21762192
**
21772193
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
21782194
** that might be invoked with argument P whenever
21792195
** an attempt is made to access a database table associated with
21802196
** [database connection] D when another thread
@@ -2187,11 +2203,11 @@
21872203
** is not NULL, then the callback might be invoked with two arguments.
21882204
**
21892205
** ^The first argument to the busy handler is a copy of the void* pointer which
21902206
** is the third argument to sqlite3_busy_handler(). ^The second argument to
21912207
** the busy handler callback is the number of times that the busy handler has
2192
-** been invoked for the same locking event. ^If the
2208
+** been invoked previously for the same locking event. ^If the
21932209
** busy callback returns 0, then no additional attempts are made to
21942210
** access the database and [SQLITE_BUSY] is returned
21952211
** to the application.
21962212
** ^If the callback returns non-zero, then another attempt
21972213
** is made to access the database and the cycle repeats.
@@ -4642,11 +4658,12 @@
46424658
** If these routines are called from within the different thread
46434659
** than the one containing the application-defined function that received
46444660
** the [sqlite3_context] pointer, the results are undefined.
46454661
*/
46464662
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*));
4663
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
4664
+ sqlite3_uint64,void(*)(void*));
46484665
SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
46494666
SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
46504667
SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
46514668
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
46524669
SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
@@ -5274,24 +5291,31 @@
52745291
52755292
52765293
/*
52775294
** CAPI3REF: Extract Metadata About A Column Of A Table
52785295
**
5279
-** ^This routine returns metadata about a specific column of a specific
5280
-** database table accessible using the [database connection] handle
5281
-** passed as the first function argument.
5296
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
5297
+** information about column C of table T in database D
5298
+** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
5299
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
5300
+** the final five arguments with appropriate values if the specified
5301
+** column exists. ^The sqlite3_table_column_metadata() interface returns
5302
+** SQLITE_ERROR and if the specified column does not exist.
5303
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
5304
+** NULL pointer, then this routine simply checks for the existance of the
5305
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
5306
+** does not.
52825307
**
52835308
** ^The column is identified by the second, third and fourth parameters to
5284
-** this function. ^The second parameter is either the name of the database
5309
+** this function. ^(The second parameter is either the name of the database
52855310
** (i.e. "main", "temp", or an attached database) containing the specified
5286
-** table or NULL. ^If it is NULL, then all attached databases are searched
5311
+** table or NULL.)^ ^If it is NULL, then all attached databases are searched
52875312
** for the table using the same algorithm used by the database engine to
52885313
** resolve unqualified table references.
52895314
**
52905315
** ^The third and fourth parameters to this function are the table and column
5291
-** name of the desired column, respectively. Neither of these parameters
5292
-** may be NULL.
5316
+** name of the desired column, respectively.
52935317
**
52945318
** ^Metadata is returned by writing to the memory locations passed as the 5th
52955319
** and subsequent parameters to this function. ^Any of these arguments may be
52965320
** NULL, in which case the corresponding element of metadata is omitted.
52975321
**
@@ -5306,36 +5330,33 @@
53065330
** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
53075331
** </table>
53085332
** </blockquote>)^
53095333
**
53105334
** ^The memory pointed to by the character pointers returned for the
5311
-** declaration type and collation sequence is valid only until the next
5335
+** declaration type and collation sequence is valid until the next
53125336
** call to any SQLite API function.
53135337
**
53145338
** ^If the specified table is actually a view, an [error code] is returned.
53155339
**
5316
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
5340
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table
5341
+** is not a [WITHOUT ROWID] table and an
53175342
** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
53185343
** parameters are set for the explicitly declared column. ^(If there is no
5319
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
5320
-** parameters are set as follows:
5344
+** [INTEGER PRIMARY KEY] column, then the outputs
5345
+** for the [rowid] are set as follows:
53215346
**
53225347
** <pre>
53235348
** data type: "INTEGER"
53245349
** collation sequence: "BINARY"
53255350
** not null: 0
53265351
** primary key: 1
53275352
** auto increment: 0
53285353
** </pre>)^
53295354
**
5330
-** ^(This function may load one or more schemas from database files. If an
5331
-** error occurs during this process, or if the requested table or column
5332
-** cannot be found, an [error code] is returned and an error message left
5333
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
5334
-**
5335
-** ^This API is only available if the library was compiled with the
5336
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
5355
+** ^This function causes all database schemas to be read from disk and
5356
+** parsed, if that has not already been done, and returns an error if
5357
+** any errors are encountered while loading the schema.
53375358
*/
53385359
SQLITE_API int sqlite3_table_column_metadata(
53395360
sqlite3 *db, /* Connection handle */
53405361
const char *zDbName, /* Database name or NULL */
53415362
const char *zTableName, /* Table name */
@@ -7298,16 +7319,14 @@
72987319
72997320
/*
73007321
** CAPI3REF: Write-Ahead Log Commit Hook
73017322
**
73027323
** ^The [sqlite3_wal_hook()] function is used to register a callback that
7303
-** will be invoked each time a database connection commits data to a
7304
-** [write-ahead log] (i.e. whenever a transaction is committed in
7305
-** [journal_mode | journal_mode=WAL mode]).
7324
+** is invoked each time data is committed to a database in wal mode.
73067325
**
7307
-** ^The callback is invoked by SQLite after the commit has taken place and
7308
-** the associated write-lock on the database released, so the implementation
7326
+** ^(The callback is invoked by SQLite after the commit has taken place and
7327
+** the associated write-lock on the database released)^, so the implementation
73097328
** may read, write or [checkpoint] the database as required.
73107329
**
73117330
** ^The first parameter passed to the callback function when it is invoked
73127331
** is a copy of the third parameter passed to sqlite3_wal_hook() when
73137332
** registering the callback. ^The second is a copy of the database handle.
@@ -7368,101 +7387,118 @@
73687387
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
73697388
73707389
/*
73717390
** CAPI3REF: Checkpoint a database
73727391
**
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()]
7392
+** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
7393
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
7394
+**
7395
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
7396
+** [write-ahead log] for database X on [database connection] D to be
7397
+** transferred into the database file and for the write-ahead log to
7398
+** be reset. See the [checkpointing] documentation for addition
7399
+** information.
7400
+**
7401
+** This interface used to be the only way to cause a checkpoint to
7402
+** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
7403
+** interface was added. This interface is retained for backwards
7404
+** compatibility and as a convenience for applications that need to manually
7405
+** start a callback but which do not need the full power (and corresponding
7406
+** complication) of [sqlite3_wal_checkpoint_v2()].
73897407
*/
73907408
SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
73917409
73927410
/*
73937411
** CAPI3REF: Checkpoint a database
73947412
**
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:
7413
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
7414
+** operation on database X of [database connection] D in mode M. Status
7415
+** information is written back into integers pointed to by L and C.)^
7416
+** ^(The M parameter must be a valid [checkpoint mode]:)^
73987417
**
73997418
** <dl>
74007419
** <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.
7420
+** ^Checkpoint as many frames as possible without waiting for any database
7421
+** readers or writers to finish, then sync the database file if all frames
7422
+** in the log were checkpointed. ^The [busy-handler callback]
7423
+** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
7424
+** ^On the other hand, passive mode might leave the checkpoint unfinished
7425
+** if there are concurrent readers or writers.
74067426
**
74077427
** <dt>SQLITE_CHECKPOINT_FULL<dd>
7408
-** This mode blocks (it invokes the
7428
+** ^This mode blocks (it invokes the
74097429
** [sqlite3_busy_handler|busy-handler callback]) until there is no
74107430
** 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.
7431
+** snapshot. ^It then checkpoints all frames in the log file and syncs the
7432
+** database file. ^This mode blocks new database writers while it is pending,
7433
+** but new database readers are allowed to continue unimpeded.
74147434
**
74157435
** <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.
7436
+** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
7437
+** that after checkpointing the log file it blocks (calls the
7438
+** [busy-handler callback])
7439
+** until all readers are reading from the database file only. ^This ensures
7440
+** that the next writer will restart the log file from the beginning.
7441
+** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
7442
+** database writer attempts while it is pending, but does not impede readers.
7443
+**
7444
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
7445
+** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
7446
+** addition that it also truncates the log file to zero bytes just prior
7447
+** to a successful return.
74237448
** </dl>
74247449
**
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.
7450
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
7451
+** the log file or to -1 if the checkpoint could not run because
7452
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
7453
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
7454
+** log file (including any that were already checkpointed before the function
7455
+** was called) or to -1 if the checkpoint could not run due to an error or
7456
+** because the database is not in WAL mode. ^Note that upon successful
7457
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
7458
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
74327459
**
7433
-** All calls obtain an exclusive "checkpoint" lock on the database file. If
7460
+** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
74347461
** 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
7462
+** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a
74367463
** busy-handler configured, it will not be invoked in this case.
74377464
**
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
7465
+** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the
7466
+** exclusive "writer" lock on the database file. ^If the writer lock cannot be
7467
+** obtained immediately, and a busy-handler is configured, it is invoked and
7468
+** the writer lock retried until either the busy-handler returns 0 or the lock
7469
+** is successfully obtained. ^The busy-handler is also invoked while waiting for
7470
+** database readers as described above. ^If the busy-handler returns 0 before
74447471
** the writer lock is obtained or while waiting for database readers, the
74457472
** checkpoint operation proceeds from that point in the same way as
74467473
** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
7447
-** without blocking any further. SQLITE_BUSY is returned in this case.
7474
+** without blocking any further. ^SQLITE_BUSY is returned in this case.
74487475
**
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
7476
+** ^If parameter zDb is NULL or points to a zero length string, then the
7477
+** specified operation is attempted on all WAL databases [attached] to
7478
+** [database connection] db. In this case the
7479
+** values written to output parameters *pnLog and *pnCkpt are undefined. ^If
74527480
** an SQLITE_BUSY error is encountered when processing one or more of the
74537481
** 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
7482
+** attached databases and SQLITE_BUSY is returned at the end. ^If any other
74557483
** error occurs while processing an attached database, processing is abandoned
7456
-** and the error code returned to the caller immediately. If no error
7484
+** and the error code is returned to the caller immediately. ^If no error
74577485
** (SQLITE_BUSY or otherwise) is encountered while processing the attached
74587486
** databases, SQLITE_OK is returned.
74597487
**
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
7488
+** ^If database zDb is the name of an attached database that is not in WAL
7489
+** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
74627490
** zDb is not NULL (or a zero length string) and is not the name of any
74637491
** attached database, SQLITE_ERROR is returned to the caller.
7492
+**
7493
+** ^Unless it returns SQLITE_MISUSE,
7494
+** the sqlite3_wal_checkpoint_v2() interface
7495
+** sets the error information that is queried by
7496
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
7497
+**
7498
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
7499
+** from SQL.
74647500
*/
74657501
SQLITE_API int sqlite3_wal_checkpoint_v2(
74667502
sqlite3 *db, /* Database handle */
74677503
const char *zDb, /* Name of attached database (or NULL) */
74687504
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7469,20 +7505,22 @@
74697505
int *pnLog, /* OUT: Size of WAL log in frames */
74707506
int *pnCkpt /* OUT: Total number of frames checkpointed */
74717507
);
74727508
74737509
/*
7474
-** CAPI3REF: Checkpoint operation parameters
7510
+** CAPI3REF: Checkpoint Mode Values
7511
+** KEYWORDS: {checkpoint mode}
74757512
**
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.
7513
+** These constants define all valid values for the "checkpoint mode" passed
7514
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
7515
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
7516
+** meaning of each of these checkpoint modes.
74807517
*/
7481
-#define SQLITE_CHECKPOINT_PASSIVE 0
7482
-#define SQLITE_CHECKPOINT_FULL 1
7483
-#define SQLITE_CHECKPOINT_RESTART 2
7518
+#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
7519
+#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
7520
+#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
7521
+#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
74847522
74857523
/*
74867524
** CAPI3REF: Virtual Table Interface Configuration
74877525
**
74887526
** This function may be called by either the [xConnect] or [xCreate] method
@@ -7577,16 +7615,16 @@
75777615
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
75787616
** different metric for sqlite3_stmt_scanstatus() to return.
75797617
**
75807618
** <dl>
75817619
** [[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>
7620
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
7621
+** set to the total number of times that the X-th loop has run.</dd>
75847622
**
75857623
** [[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>
7624
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
7625
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
75887626
**
75897627
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
75907628
** <dd>^The "double" variable pointed to by the T parameter will be set to the
75917629
** query planner's estimate for the average number of rows output from each
75927630
** iteration of the X-th loop. If the query planner's estimates was accurate,
@@ -7593,18 +7631,18 @@
75937631
** then this value will approximate the quotient NVISIT/NLOOP and the
75947632
** product of this value for all prior loops with the same SELECTID will
75957633
** be the NLOOP value for the current loop.
75967634
**
75977635
** [[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.
7636
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
7637
+** to a zero-terminated UTF-8 string containing the name of the index or table
7638
+** used for the X-th loop.
76017639
**
76027640
** [[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.
7641
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
7642
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
7643
+** description for the X-th loop.
76067644
**
76077645
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
76087646
** <dd>^The "int" variable pointed to by the T parameter will be set to the
76097647
** "select-id" for the X-th loop. The select-id identifies which query or
76107648
** subquery the loop is part of. The main query has a select-id of zero.
@@ -7623,12 +7661,12 @@
76237661
** CAPI3REF: Prepared Statement Scan Status
76247662
**
76257663
** Return status data for a single loop within query pStmt.
76267664
**
76277665
** 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.
7666
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
7667
+** of this interface is undefined.
76307668
** ^The requested measurement is written into a variable pointed to by
76317669
** the "pOut" parameter.
76327670
** Parameter "idx" identifies the specific loop to retrieve statistics for.
76337671
** Loops are numbered starting from zero. ^If idx is out of range - less than
76347672
** zero or greater than or equal to the total number of loops used to implement
@@ -9072,11 +9110,11 @@
90729110
#define _BTREE_H_
90739111
90749112
/* TODO: This definition is just included so other modules compile. It
90759113
** needs to be revisited.
90769114
*/
9077
-#define SQLITE_N_BTREE_META 10
9115
+#define SQLITE_N_BTREE_META 16
90789116
90799117
/*
90809118
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
90819119
** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
90829120
*/
@@ -9187,10 +9225,15 @@
91879225
** offset = 36 + (idx * 4)
91889226
**
91899227
** For example, the free-page-count field is located at byte offset 36 of
91909228
** the database file header. The incr-vacuum-flag field is located at
91919229
** byte offset 64 (== 36+4*7).
9230
+**
9231
+** The BTREE_DATA_VERSION value is not really a value stored in the header.
9232
+** It is a read-only number computed by the pager. But we merge it with
9233
+** the header value access routines since its access pattern is the same.
9234
+** Call it a "virtual meta value".
91929235
*/
91939236
#define BTREE_FREE_PAGE_COUNT 0
91949237
#define BTREE_SCHEMA_VERSION 1
91959238
#define BTREE_FILE_FORMAT 2
91969239
#define BTREE_DEFAULT_CACHE_SIZE 3
@@ -9197,10 +9240,11 @@
91979240
#define BTREE_LARGEST_ROOT_PAGE 4
91989241
#define BTREE_TEXT_ENCODING 5
91999242
#define BTREE_USER_VERSION 6
92009243
#define BTREE_INCR_VACUUM 7
92019244
#define BTREE_APPLICATION_ID 8
9245
+#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
92029246
92039247
/*
92049248
** Values that may be OR'd together to form the second argument of an
92059249
** sqlite3BtreeCursorHints() call.
92069250
*/
@@ -9978,10 +10022,11 @@
997810022
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
997910023
#endif
998010024
998110025
/* Functions used to query pager state and configuration. */
998210026
SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
10027
+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*);
998310028
SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
998410029
SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
998510030
SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
998610031
SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
998710032
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
@@ -10719,10 +10764,11 @@
1071910764
i64 szMmap; /* Default mmap_size setting */
1072010765
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
1072110766
int errCode; /* Most recent error code (SQLITE_*) */
1072210767
int errMask; /* & result codes with this before returning */
1072310768
u16 dbOptFlags; /* Flags to enable/disable optimizations */
10769
+ u8 enc; /* Text encoding */
1072410770
u8 autoCommit; /* The auto-commit flag. */
1072510771
u8 temp_store; /* 1: file 2: memory 0: default */
1072610772
u8 mallocFailed; /* True if we have seen a malloc failure */
1072710773
u8 dfltLockMode; /* Default locking-mode for attached dbs */
1072810774
signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
@@ -10820,11 +10866,12 @@
1082010866
};
1082110867
1082210868
/*
1082310869
** A macro to discover the encoding of a database.
1082410870
*/
10825
-#define ENC(db) ((db)->aDb[0].pSchema->enc)
10871
+#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
10872
+#define ENC(db) ((db)->enc)
1082610873
1082710874
/*
1082810875
** Possible values for the sqlite3.flags.
1082910876
*/
1083010877
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
@@ -11444,11 +11491,10 @@
1144411491
Index *pNext; /* The next index associated with the same table */
1144511492
Schema *pSchema; /* Schema containing this index */
1144611493
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
1144711494
char **azColl; /* Array of collation sequence names for index */
1144811495
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
11449
- KeyInfo *pKeyInfo; /* A KeyInfo object suitable for this index */
1145011496
int tnum; /* DB Page containing root of this index */
1145111497
LogEst szIdxRow; /* Estimated average row size in bytes */
1145211498
u16 nKeyCol; /* Number of columns forming the key */
1145311499
u16 nColumn; /* Number of columns stored in the index */
1145411500
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
@@ -11675,11 +11721,11 @@
1167511721
};
1167611722
1167711723
/*
1167811724
** The following are the meanings of bits in the Expr.flags field.
1167911725
*/
11680
-#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
11726
+#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
1168111727
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
1168211728
#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
1168311729
#define EP_Error 0x000008 /* Expression contains one or more errors */
1168411730
#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
1168511731
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
@@ -11695,10 +11741,11 @@
1169511741
#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
1169611742
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
1169711743
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
1169811744
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
1169911745
#define EP_Constant 0x080000 /* Node is a constant */
11746
+#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
1170011747
1170111748
/*
1170211749
** These macros can be used to test, set, or clear bits in the
1170311750
** Expr.flags field.
1170411751
*/
@@ -12497,10 +12544,11 @@
1249712544
void *pPage; /* Page cache memory */
1249812545
int szPage; /* Size of each page in pPage[] */
1249912546
int nPage; /* Number of pages in pPage[] */
1250012547
int mxParserStack; /* maximum depth of the parser stack */
1250112548
int sharedCacheEnabled; /* true if shared-cache mode enabled */
12549
+ u32 szPma; /* Maximum Sorter PMA size */
1250212550
/* The above might be initialized to non-zero. The following need to always
1250312551
** initially be zero, however. */
1250412552
int isInit; /* True after initialization has finished */
1250512553
int inProgress; /* True while initialization in progress */
1250612554
int isMutexInit; /* True after mutexes are initialized */
@@ -13419,11 +13467,11 @@
1341913467
** print I/O tracing messages.
1342013468
*/
1342113469
#ifdef SQLITE_ENABLE_IOTRACE
1342213470
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
1342313471
SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
13424
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
13472
+void (*sqlite3IoTrace)(const char*,...);
1342513473
#else
1342613474
# define IOTRACE(A)
1342713475
# define sqlite3VdbeIOTraceSql(X)
1342813476
#endif
1342913477
@@ -13632,10 +13680,17 @@
1363213680
*/
1363313681
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
1363413682
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
1363513683
#endif
1363613684
13685
+/* The minimum PMA size is set to this value multiplied by the database
13686
+** page size in bytes.
13687
+*/
13688
+#ifndef SQLITE_SORTER_PMASZ
13689
+# define SQLITE_SORTER_PMASZ 250
13690
+#endif
13691
+
1363713692
/*
1363813693
** The following singleton contains the global configuration for
1363913694
** the SQLite library.
1364013695
*/
1364113696
SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
@@ -13662,10 +13717,11 @@
1366213717
(void*)0, /* pPage */
1366313718
0, /* szPage */
1366413719
0, /* nPage */
1366513720
0, /* mxParserStack */
1366613721
0, /* sharedCacheEnabled */
13722
+ SQLITE_SORTER_PMASZ, /* szPma */
1366713723
/* All the rest should always be initialized to zero */
1366813724
0, /* isInit */
1366913725
0, /* inProgress */
1367013726
0, /* isMutexInit */
1367113727
0, /* isMallocInit */
@@ -19947,10 +20003,16 @@
1994720003
#endif
1994820004
}
1994920005
break;
1995020006
}
1995120007
default: {
20008
+#ifdef SQLITE_ENABLE_API_ARMOR
20009
+ if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
20010
+ (void)SQLITE_MISUSE_BKPT;
20011
+ return 0;
20012
+ }
20013
+#endif
1995220014
assert( iType-2 >= 0 );
1995320015
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
1995420016
assert( winMutex_isInit==1 );
1995520017
p = &winMutex_staticMutexes[iType-2];
1995620018
#ifdef SQLITE_DEBUG
@@ -28754,28 +28816,31 @@
2875428816
do{
2875528817
err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
2875628818
}while( err==EINTR );
2875728819
if( err ) return SQLITE_IOERR_WRITE;
2875828820
#else
28759
- /* If the OS does not have posix_fallocate(), fake it. First use
28760
- ** ftruncate() to set the file size, then write a single byte to
28761
- ** the last byte in each block within the extended region. This
28762
- ** is the same technique used by glibc to implement posix_fallocate()
28763
- ** on systems that do not have a real fallocate() system call.
28821
+ /* If the OS does not have posix_fallocate(), fake it. Write a
28822
+ ** single byte to the last byte in each block that falls entirely
28823
+ ** within the extended region. Then, if required, a single byte
28824
+ ** at offset (nSize-1), to set the size of the file correctly.
28825
+ ** This is a similar technique to that used by glibc on systems
28826
+ ** that do not have a real fallocate() call.
2876428827
*/
2876528828
int nBlk = buf.st_blksize; /* File-system block size */
2876628829
i64 iWrite; /* Next offset to write to */
2876728830
28768
- if( robust_ftruncate(pFile->h, nSize) ){
28769
- pFile->lastErrno = errno;
28770
- return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
28771
- }
2877228831
iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
28773
- while( iWrite<nSize ){
28832
+ assert( iWrite>=buf.st_size );
28833
+ assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
28834
+ assert( ((iWrite+1)%nBlk)==0 );
28835
+ for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
2877428836
int nWrite = seekAndWrite(pFile, iWrite, "", 1);
2877528837
if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
28776
- iWrite += nBlk;
28838
+ }
28839
+ if( nSize%nBlk ){
28840
+ int nWrite = seekAndWrite(pFile, nSize-1, "", 1);
28841
+ if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
2877728842
}
2877828843
#endif
2877928844
}
2878028845
}
2878128846
@@ -33989,12 +34054,12 @@
3398934054
*/
3399034055
SQLITE_API int sqlite3_win32_reset_heap(){
3399134056
int rc;
3399234057
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
3399334058
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
33994
- MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
33995
- MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
34059
+ MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
34060
+ MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
3399634061
sqlite3_mutex_enter(pMaster);
3399734062
sqlite3_mutex_enter(pMem);
3399834063
winMemAssertMagic();
3399934064
if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
3400034065
/*
@@ -35265,11 +35330,11 @@
3526535330
sqlite3_file *id, /* File to read from */
3526635331
void *pBuf, /* Write content into this buffer */
3526735332
int amt, /* Number of bytes to read */
3526835333
sqlite3_int64 offset /* Begin reading at this offset */
3526935334
){
35270
-#if !SQLITE_OS_WINCE
35335
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
3527135336
OVERLAPPED overlapped; /* The offset for ReadFile. */
3527235337
#endif
3527335338
winFile *pFile = (winFile*)id; /* file handle */
3527435339
DWORD nRead; /* Number of bytes actually read from file */
3527535340
int nRetry = 0; /* Number of retrys */
@@ -35297,11 +35362,11 @@
3529735362
offset += nCopy;
3529835363
}
3529935364
}
3530035365
#endif
3530135366
35302
-#if SQLITE_OS_WINCE
35367
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
3530335368
if( winSeekFile(pFile, offset) ){
3530435369
OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
3530535370
return SQLITE_FULL;
3530635371
}
3530735372
while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
@@ -35369,32 +35434,32 @@
3536935434
offset += nCopy;
3537035435
}
3537135436
}
3537235437
#endif
3537335438
35374
-#if SQLITE_OS_WINCE
35439
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
3537535440
rc = winSeekFile(pFile, offset);
3537635441
if( rc==0 ){
3537735442
#else
3537835443
{
3537935444
#endif
35380
-#if !SQLITE_OS_WINCE
35445
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
3538135446
OVERLAPPED overlapped; /* The offset for WriteFile. */
3538235447
#endif
3538335448
u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
3538435449
int nRem = amt; /* Number of bytes yet to be written */
3538535450
DWORD nWrite; /* Bytes written by each WriteFile() call */
3538635451
DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */
3538735452
35388
-#if !SQLITE_OS_WINCE
35453
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
3538935454
memset(&overlapped, 0, sizeof(OVERLAPPED));
3539035455
overlapped.Offset = (LONG)(offset & 0xffffffff);
3539135456
overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
3539235457
#endif
3539335458
3539435459
while( nRem>0 ){
35395
-#if SQLITE_OS_WINCE
35460
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
3539635461
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
3539735462
#else
3539835463
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
3539935464
#endif
3540035465
if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
@@ -35403,11 +35468,11 @@
3540335468
assert( nWrite==0 || nWrite<=(DWORD)nRem );
3540435469
if( nWrite==0 || nWrite>(DWORD)nRem ){
3540535470
lastErrno = osGetLastError();
3540635471
break;
3540735472
}
35408
-#if !SQLITE_OS_WINCE
35473
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
3540935474
offset += nWrite;
3541035475
overlapped.Offset = (LONG)(offset & 0xffffffff);
3541135476
overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
3541235477
#endif
3541335478
aRem += nWrite;
@@ -38949,11 +39014,12 @@
3894939014
SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
3895039015
assert( pCache->nRef==0 && pCache->pDirty==0 );
3895139016
if( pCache->szPage ){
3895239017
sqlite3_pcache *pNew;
3895339018
pNew = sqlite3GlobalConfig.pcache2.xCreate(
38954
- szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
39019
+ szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
39020
+ pCache->bPurgeable
3895539021
);
3895639022
if( pNew==0 ) return SQLITE_NOMEM;
3895739023
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
3895839024
if( pCache->pCache ){
3895939025
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
@@ -39408,11 +39474,11 @@
3940839474
3940939475
/*
3941039476
** Return the size of the header added by this middleware layer
3941139477
** in the page-cache hierarchy.
3941239478
*/
39413
-SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return sizeof(PgHdr); }
39479
+SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
3941439480
3941539481
3941639482
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
3941739483
/*
3941839484
** For all dirty pages currently in the cache, invoke the specified
@@ -39724,11 +39790,11 @@
3972439790
pcache1Free(pPg);
3972539791
sqlite3_free(p);
3972639792
pPg = 0;
3972739793
}
3972839794
#else
39729
- pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
39795
+ pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
3973039796
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
3973139797
#endif
3973239798
pcache1EnterMutex(pCache->pGroup);
3973339799
3973439800
if( pPg ){
@@ -40412,11 +40478,11 @@
4041240478
}
4041340479
4041440480
/*
4041540481
** Return the size of the header on each page of this PCACHE implementation.
4041640482
*/
40417
-SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return sizeof(PgHdr1); }
40483
+SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
4041840484
4041940485
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
4042040486
/*
4042140487
** This function is called to free superfluous dynamically allocated memory
4042240488
** held by the pager system. Memory in use by any SQLite pager allocated
@@ -41770,10 +41836,12 @@
4177041836
u8 eLock; /* Current lock held on database file */
4177141837
u8 changeCountDone; /* Set after incrementing the change-counter */
4177241838
u8 setMaster; /* True if a m-j name has been written to jrnl */
4177341839
u8 doNotSpill; /* Do not spill the cache when non-zero */
4177441840
u8 subjInMemory; /* True to use in-memory sub-journals */
41841
+ u8 bUseFetch; /* True to use xFetch() */
41842
+ u8 hasBeenUsed; /* True if any content previously read from this pager*/
4177541843
Pgno dbSize; /* Number of pages in the database */
4177641844
Pgno dbOrigSize; /* dbSize before the current transaction */
4177741845
Pgno dbFileSize; /* Number of pages in the database file */
4177841846
Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */
4177941847
int errCode; /* One of several kinds of errors */
@@ -41787,13 +41855,13 @@
4178741855
i64 journalOff; /* Current write offset in the journal file */
4178841856
i64 journalHdr; /* Byte offset to previous journal header */
4178941857
sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
4179041858
PagerSavepoint *aSavepoint; /* Array of active savepoints */
4179141859
int nSavepoint; /* Number of elements in aSavepoint[] */
41860
+ u32 iDataVersion; /* Changes whenever database content changes */
4179241861
char dbFileVers[16]; /* Changes whenever database file changes */
4179341862
41794
- u8 bUseFetch; /* True to use xFetch() */
4179541863
int nMmapOut; /* Number of mmap pages currently outstanding */
4179641864
sqlite3_int64 szMmap; /* Desired maximum mmap size */
4179741865
PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
4179841866
/*
4179941867
** End of the routinely-changing class members
@@ -42805,13 +42873,22 @@
4280542873
4280642874
/*
4280742875
** Discard the entire contents of the in-memory page-cache.
4280842876
*/
4280942877
static void pager_reset(Pager *pPager){
42878
+ pPager->iDataVersion++;
4281042879
sqlite3BackupRestart(pPager->pBackup);
4281142880
sqlite3PcacheClear(pPager->pPCache);
4281242881
}
42882
+
42883
+/*
42884
+** Return the pPager->iDataVersion value
42885
+*/
42886
+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
42887
+ assert( pPager->eState>PAGER_OPEN );
42888
+ return pPager->iDataVersion;
42889
+}
4281342890
4281442891
/*
4281542892
** Free all structures in the Pager.aSavepoint[] array and set both
4281642893
** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
4281742894
** if it is open and the pager is not in exclusive mode.
@@ -45011,11 +45088,11 @@
4501145088
Pgno pgno, /* Page number */
4501245089
void *pData, /* xFetch()'d data for this page */
4501345090
PgHdr **ppPage /* OUT: Acquired page object */
4501445091
){
4501545092
PgHdr *p; /* Memory mapped page to return */
45016
-
45093
+
4501745094
if( pPager->pMmapFreelist ){
4501845095
*ppPage = p = pPager->pMmapFreelist;
4501945096
pPager->pMmapFreelist = p->pDirty;
4502045097
p->pDirty = 0;
4502145098
memset(p->pExtra, 0, pPager->nExtra);
@@ -46242,20 +46319,16 @@
4624246319
assert( (pPager->eLock==SHARED_LOCK)
4624346320
|| (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
4624446321
);
4624546322
}
4624646323
46247
- if( !pPager->tempFile && (
46248
- pPager->pBackup
46249
- || sqlite3PcachePagecount(pPager->pPCache)>0
46250
- || USEFETCH(pPager)
46251
- )){
46252
- /* The shared-lock has just been acquired on the database file
46253
- ** and there are already pages in the cache (from a previous
46254
- ** read or write transaction). Check to see if the database
46255
- ** has been modified. If the database has changed, flush the
46256
- ** cache.
46324
+ if( !pPager->tempFile && pPager->hasBeenUsed ){
46325
+ /* The shared-lock has just been acquired then check to
46326
+ ** see if the database has been modified. If the database has changed,
46327
+ ** flush the cache. The pPager->hasBeenUsed flag prevents this from
46328
+ ** occurring on the very first access to a file, in order to save a
46329
+ ** single unnecessary sqlite3OsRead() call at the start-up.
4625746330
**
4625846331
** Database changes is detected by looking at 15 bytes beginning
4625946332
** at offset 24 into the file. The first 4 of these 16 bytes are
4626046333
** a 32-bit counter that is incremented with each change. The
4626146334
** other bytes change randomly with each file change when
@@ -46416,10 +46489,11 @@
4641646489
assert( noContent==0 || bMmapOk==0 );
4641746490
4641846491
if( pgno==0 ){
4641946492
return SQLITE_CORRUPT_BKPT;
4642046493
}
46494
+ pPager->hasBeenUsed = 1;
4642146495
4642246496
/* If the pager is in the error state, return an error immediately.
4642346497
** Otherwise, request the page from the PCache layer. */
4642446498
if( pPager->errCode!=SQLITE_OK ){
4642546499
rc = pPager->errCode;
@@ -46565,10 +46639,11 @@
4656546639
sqlite3_pcache_page *pPage;
4656646640
assert( pPager!=0 );
4656746641
assert( pgno!=0 );
4656846642
assert( pPager->pPCache!=0 );
4656946643
pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
46644
+ assert( pPage==0 || pPager->hasBeenUsed );
4657046645
return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
4657146646
}
4657246647
4657346648
/*
4657446649
** Release a page reference.
@@ -47431,10 +47506,11 @@
4743147506
pPager->eState = PAGER_READER;
4743247507
return SQLITE_OK;
4743347508
}
4743447509
4743547510
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
47511
+ pPager->iDataVersion++;
4743647512
rc = pager_end_transaction(pPager, pPager->setMaster, 1);
4743747513
return pager_error(pPager, rc);
4743847514
}
4743947515
4744047516
/*
@@ -48199,11 +48275,12 @@
4819948275
*/
4820048276
SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
4820148277
int rc = SQLITE_OK;
4820248278
if( pPager->pWal ){
4820348279
rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
48204
- pPager->xBusyHandler, pPager->pBusyHandlerArg,
48280
+ (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
48281
+ pPager->pBusyHandlerArg,
4820548282
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
4820648283
pnLog, pnCkpt
4820748284
);
4820848285
}
4820948286
return rc;
@@ -50009,10 +50086,42 @@
5000950086
** Return the page-size in bytes used by the database.
5001050087
*/
5001150088
static int walPagesize(Wal *pWal){
5001250089
return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
5001350090
}
50091
+
50092
+/*
50093
+** The following is guaranteed when this function is called:
50094
+**
50095
+** a) the WRITER lock is held,
50096
+** b) the entire log file has been checkpointed, and
50097
+** c) any existing readers are reading exclusively from the database
50098
+** file - there are no readers that may attempt to read a frame from
50099
+** the log file.
50100
+**
50101
+** This function updates the shared-memory structures so that the next
50102
+** client to write to the database (which may be this one) does so by
50103
+** writing frames into the start of the log file.
50104
+**
50105
+** The value of parameter salt1 is used as the aSalt[1] value in the
50106
+** new wal-index header. It should be passed a pseudo-random value (i.e.
50107
+** one obtained from sqlite3_randomness()).
50108
+*/
50109
+static void walRestartHdr(Wal *pWal, u32 salt1){
50110
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
50111
+ int i; /* Loop counter */
50112
+ u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
50113
+ pWal->nCkpt++;
50114
+ pWal->hdr.mxFrame = 0;
50115
+ sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
50116
+ memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
50117
+ walIndexWriteHdr(pWal);
50118
+ pInfo->nBackfill = 0;
50119
+ pInfo->aReadMark[1] = 0;
50120
+ for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
50121
+ assert( pInfo->aReadMark[0]==0 );
50122
+}
5001450123
5001550124
/*
5001650125
** Copy as much content as we can from the WAL back into the database file
5001750126
** in response to an sqlite3_wal_checkpoint() request or the equivalent.
5001850127
**
@@ -50044,11 +50153,11 @@
5004450153
** time.
5004550154
*/
5004650155
static int walCheckpoint(
5004750156
Wal *pWal, /* Wal connection */
5004850157
int eMode, /* One of PASSIVE, FULL or RESTART */
50049
- int (*xBusyCall)(void*), /* Function to call when busy */
50158
+ int (*xBusy)(void*), /* Function to call when busy */
5005050159
void *pBusyArg, /* Context argument for xBusyHandler */
5005150160
int sync_flags, /* Flags for OsSync() (or 0) */
5005250161
u8 *zBuf /* Temporary buffer to use */
5005350162
){
5005450163
int rc; /* Return code */
@@ -50058,11 +50167,10 @@
5005850167
u32 iFrame = 0; /* Wal frame containing data for iDbpage */
5005950168
u32 mxSafeFrame; /* Max frame that can be backfilled */
5006050169
u32 mxPage; /* Max database page to write */
5006150170
int i; /* Loop counter */
5006250171
volatile WalCkptInfo *pInfo; /* The checkpoint status information */
50063
- int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */
5006450172
5006550173
szPage = walPagesize(pWal);
5006650174
testcase( szPage<=32768 );
5006750175
testcase( szPage>=65536 );
5006850176
pInfo = walCkptInfo(pWal);
@@ -50073,11 +50181,13 @@
5007350181
if( rc!=SQLITE_OK ){
5007450182
return rc;
5007550183
}
5007650184
assert( pIter );
5007750185
50078
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
50186
+ /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
50187
+ ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
50188
+ assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
5007950189
5008050190
/* Compute in mxSafeFrame the index of the last frame of the WAL that is
5008150191
** safe to write into the database. Frames beyond mxSafeFrame might
5008250192
** overwrite database pages that are in use by active readers and thus
5008350193
** cannot be backfilled from the WAL.
@@ -50162,23 +50272,42 @@
5016250272
/* Reset the return code so as not to report a checkpoint failure
5016350273
** just because there are active readers. */
5016450274
rc = SQLITE_OK;
5016550275
}
5016650276
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.
50277
+ /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
50278
+ ** entire wal file has been copied into the database file, then block
50279
+ ** until all readers have finished using the wal file. This ensures that
50280
+ ** the next process to write to the database restarts the wal file.
5017150281
*/
5017250282
if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
5017350283
assert( pWal->writeLock );
5017450284
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
5017550285
rc = SQLITE_BUSY;
50176
- }else if( eMode==SQLITE_CHECKPOINT_RESTART ){
50286
+ }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
50287
+ u32 salt1;
50288
+ sqlite3_randomness(4, &salt1);
5017750289
assert( mxSafeFrame==pWal->hdr.mxFrame );
5017850290
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
5017950291
if( rc==SQLITE_OK ){
50292
+ if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
50293
+ /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
50294
+ ** SQLITE_CHECKPOINT_RESTART with the addition that it also
50295
+ ** truncates the log file to zero bytes just prior to a
50296
+ ** successful return.
50297
+ **
50298
+ ** In theory, it might be safe to do this without updating the
50299
+ ** wal-index header in shared memory, as all subsequent reader or
50300
+ ** writer clients should see that the entire log file has been
50301
+ ** checkpointed and behave accordingly. This seems unsafe though,
50302
+ ** as it would leave the system in a state where the contents of
50303
+ ** the wal-index header do not match the contents of the
50304
+ ** file-system. To avoid this, update the wal-index header to
50305
+ ** indicate that the log file contains zero valid frames. */
50306
+ walRestartHdr(pWal, salt1);
50307
+ rc = sqlite3OsTruncate(pWal->pWalFd, 0);
50308
+ }
5018050309
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
5018150310
}
5018250311
}
5018350312
}
5018450313
@@ -50747,11 +50876,11 @@
5074750876
}
5074850877
nCollide = HASHTABLE_NSLOT;
5074950878
for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
5075050879
u32 iFrame = aHash[iKey] + iZero;
5075150880
if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
50752
- /* assert( iFrame>iRead ); -- not true if there is corruption */
50881
+ assert( iFrame>iRead || CORRUPT_DB );
5075350882
iRead = iFrame;
5075450883
}
5075550884
if( (nCollide--)==0 ){
5075650885
return SQLITE_CORRUPT_BKPT;
5075750886
}
@@ -50960,11 +51089,10 @@
5096051089
}
5096151090
5096251091
return rc;
5096351092
}
5096451093
50965
-
5096651094
/*
5096751095
** This function is called just before writing a set of frames to the log
5096851096
** file (see sqlite3WalFrames()). It checks to see if, instead of appending
5096951097
** to the current log file, it is possible to overwrite the start of the
5097051098
** existing log file with the new frames (i.e. "reset" the log). If so,
@@ -50993,24 +51121,12 @@
5099351121
** wal-index header to reflect this.
5099451122
**
5099551123
** In theory it would be Ok to update the cache of the header only
5099651124
** at this point. But updating the actual wal-index header is also
5099751125
** 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 );
51126
+ ** to handle if this transaction is rolled back. */
51127
+ walRestartHdr(pWal, salt1);
5101251128
walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
5101351129
}else if( rc!=SQLITE_BUSY ){
5101451130
return rc;
5101551131
}
5101651132
}
@@ -51294,11 +51410,11 @@
5129451410
** If parameter xBusy is not NULL, it is a pointer to a busy-handler
5129551411
** callback. In this case this function runs a blocking checkpoint.
5129651412
*/
5129751413
SQLITE_PRIVATE int sqlite3WalCheckpoint(
5129851414
Wal *pWal, /* Wal connection */
51299
- int eMode, /* PASSIVE, FULL or RESTART */
51415
+ int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
5130051416
int (*xBusy)(void*), /* Function to call when busy */
5130151417
void *pBusyArg, /* Context argument for xBusyHandler */
5130251418
int sync_flags, /* Flags to sync db file with (or 0) */
5130351419
int nBuf, /* Size of temporary buffer */
5130451420
u8 *zBuf, /* Temporary buffer to use */
@@ -51306,40 +51422,54 @@
5130651422
int *pnCkpt /* OUT: Number of backfilled frames in WAL */
5130751423
){
5130851424
int rc; /* Return code */
5130951425
int isChanged = 0; /* True if a new wal-index header is loaded */
5131051426
int eMode2 = eMode; /* Mode to pass to walCheckpoint() */
51427
+ int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */
5131151428
5131251429
assert( pWal->ckptLock==0 );
5131351430
assert( pWal->writeLock==0 );
5131451431
51432
+ /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
51433
+ ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
51434
+ assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
51435
+
5131551436
if( pWal->readOnly ) return SQLITE_READONLY;
5131651437
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
51438
+
51439
+ /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
51440
+ ** "checkpoint" lock on the database file. */
5131751441
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
5131851442
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. */
51443
+ /* EVIDENCE-OF: R-10421-19736 If any other process is running a
51444
+ ** checkpoint operation at the same time, the lock cannot be obtained and
51445
+ ** SQLITE_BUSY is returned.
51446
+ ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
51447
+ ** it will not be invoked in this case.
51448
+ */
51449
+ testcase( rc==SQLITE_BUSY );
51450
+ testcase( xBusy!=0 );
5132251451
return rc;
5132351452
}
5132451453
pWal->ckptLock = 1;
5132551454
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.
51455
+ /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
51456
+ ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
51457
+ ** file.
5132951458
**
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.
51459
+ ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
51460
+ ** immediately, and a busy-handler is configured, it is invoked and the
51461
+ ** writer lock retried until either the busy-handler returns 0 or the
51462
+ ** lock is successfully obtained.
5133451463
*/
5133551464
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
5133651465
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
5133751466
if( rc==SQLITE_OK ){
5133851467
pWal->writeLock = 1;
5133951468
}else if( rc==SQLITE_BUSY ){
5134051469
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
51470
+ xBusy2 = 0;
5134151471
rc = SQLITE_OK;
5134251472
}
5134351473
}
5134451474
5134551475
/* Read the wal-index header. */
@@ -51353,11 +51483,11 @@
5135351483
/* Copy data from the log to the database file. */
5135451484
if( rc==SQLITE_OK ){
5135551485
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
5135651486
rc = SQLITE_CORRUPT_BKPT;
5135751487
}else{
51358
- rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
51488
+ rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
5135951489
}
5136051490
5136151491
/* If no error occurred, set the output variables. */
5136251492
if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
5136351493
if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
@@ -51852,10 +51982,11 @@
5185251982
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
5185351983
u8 sharable; /* True if we can share pBt with another db */
5185451984
u8 locked; /* True if db currently has pBt locked */
5185551985
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
5185651986
int nBackup; /* Number of backup operations reading this btree */
51987
+ u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
5185751988
Btree *pNext; /* List of other sharable Btrees from the same db */
5185851989
Btree *pPrev; /* Back pointer of the same list */
5185951990
#ifndef SQLITE_OMIT_SHARED_CACHE
5186051991
BtLock lock; /* Object used to lock page 1 */
5186151992
#endif
@@ -53821,11 +53952,11 @@
5382153952
** to see if defragmentation is necessary.
5382253953
*/
5382353954
testcase( gap+2+nByte==top );
5382453955
if( gap+2+nByte>top ){
5382553956
defragment_page:
53826
- testcase( pPage->nCell==0 );
53957
+ assert( pPage->nCell>0 || CORRUPT_DB );
5382753958
rc = defragmentPage(pPage);
5382853959
if( rc ) return rc;
5382953960
top = get2byteNotZero(&data[hdr+5]);
5383053961
assert( gap+nByte<=top );
5383153962
}
@@ -56015,10 +56146,11 @@
5601556146
rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
5601656147
if( rc!=SQLITE_OK && bCleanup==0 ){
5601756148
sqlite3BtreeLeave(p);
5601856149
return rc;
5601956150
}
56151
+ p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */
5602056152
pBt->inTransaction = TRANS_READ;
5602156153
btreeClearHasContent(pBt);
5602256154
}
5602356155
5602456156
btreeEndTransaction(p);
@@ -56378,11 +56510,11 @@
5637856510
}
5637956511
for(i=0; i<=pCur->iPage; i++){
5638056512
releasePage(pCur->apPage[i]);
5638156513
}
5638256514
unlockBtreeIfUnused(pBt);
56383
- sqlite3DbFree(pBtree->db, pCur->aOverflow);
56515
+ sqlite3_free(pCur->aOverflow);
5638456516
/* sqlite3_free(pCur); */
5638556517
sqlite3BtreeLeave(pBtree);
5638656518
}
5638756519
return SQLITE_OK;
5638856520
}
@@ -56672,10 +56804,11 @@
5667256804
pBuf += a;
5667356805
amt -= a;
5667456806
}else{
5667556807
offset -= pCur->info.nLocal;
5667656808
}
56809
+
5667756810
5667856811
if( rc==SQLITE_OK && amt>0 ){
5667956812
const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */
5668056813
Pgno nextPage;
5668156814
@@ -56690,12 +56823,12 @@
5669056823
** means "not yet known" (the cache is lazily populated).
5669156824
*/
5669256825
if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
5669356826
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
5669456827
if( nOvfl>pCur->nOvflAlloc ){
56695
- Pgno *aNew = (Pgno*)sqlite3DbRealloc(
56696
- pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno)
56828
+ Pgno *aNew = (Pgno*)sqlite3Realloc(
56829
+ pCur->aOverflow, nOvfl*2*sizeof(Pgno)
5669756830
);
5669856831
if( aNew==0 ){
5669956832
rc = SQLITE_NOMEM;
5670056833
}else{
5670156834
pCur->nOvflAlloc = nOvfl*2;
@@ -56738,10 +56871,11 @@
5673856871
** Note that the aOverflow[] array must be allocated because eOp!=2
5673956872
** here. If eOp==2, then offset==0 and this branch is never taken.
5674056873
*/
5674156874
assert( eOp!=2 );
5674256875
assert( pCur->curFlags & BTCF_ValidOvfl );
56876
+ assert( pCur->pBtree->db==pBt->db );
5674356877
if( pCur->aOverflow[iIdx+1] ){
5674456878
nextPage = pCur->aOverflow[iIdx+1];
5674556879
}else{
5674656880
rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
5674756881
}
@@ -58881,11 +59015,11 @@
5888159015
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5888259016
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
5888359017
assert( pPage->nOverflow==1 );
5888459018
5888559019
/* This error condition is now caught prior to reaching this function */
58886
- if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
59020
+ if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
5888759021
5888859022
/* Allocate a new page. This page will become the right-sibling of
5888959023
** pPage. Make the parent page writable, so that the new divider cell
5889059024
** may be inserted. If both these operations are successful, proceed.
5889159025
*/
@@ -59250,11 +59384,11 @@
5925059384
+ nMaxCells*sizeof(u16) /* szCell */
5925159385
+ pBt->pageSize; /* aSpace1 */
5925259386
5925359387
/* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
5925459388
** that is more than 6 times the database page size. */
59255
- assert( szScratch<=6*pBt->pageSize );
59389
+ assert( szScratch<=6*(int)pBt->pageSize );
5925659390
apCell = sqlite3ScratchMalloc( szScratch );
5925759391
if( apCell==0 ){
5925859392
rc = SQLITE_NOMEM;
5925959393
goto balance_cleanup;
5926059394
}
@@ -59324,11 +59458,15 @@
5932459458
** pointer of the divider cell */
5932559459
memcpy(apCell[nCell], &pOld->aData[8], 4);
5932659460
}else{
5932759461
assert( leafCorrection==4 );
5932859462
if( szCell[nCell]<4 ){
59329
- /* Do not allow any cells smaller than 4 bytes. */
59463
+ /* Do not allow any cells smaller than 4 bytes. If a smaller cell
59464
+ ** does exist, pad it with 0x00 bytes. */
59465
+ assert( szCell[nCell]==3 );
59466
+ assert( apCell[nCell]==&aSpace1[iSpace1-3] );
59467
+ aSpace1[iSpace1++] = 0x00;
5933059468
szCell[nCell] = 4;
5933159469
}
5933259470
}
5933359471
nCell++;
5933459472
}
@@ -59559,11 +59697,15 @@
5955959697
** was either part of sibling page iOld (possibly an overflow cell),
5956059698
** or else the divider cell to the left of sibling page iOld. So,
5956159699
** if sibling page iOld had the same page number as pNew, and if
5956259700
** pCell really was a part of sibling page iOld (not a divider or
5956359701
** overflow cell), we can skip updating the pointer map entries. */
59564
- if( pNew->pgno!=aPgno[iOld] || pCell<aOld || pCell>=&aOld[usableSize] ){
59702
+ if( iOld>=nNew
59703
+ || pNew->pgno!=aPgno[iOld]
59704
+ || pCell<aOld
59705
+ || pCell>=&aOld[usableSize]
59706
+ ){
5956559707
if( !leafCorrection ){
5956659708
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
5956759709
}
5956859710
if( szCell[i]>pNew->minLocal ){
5956959711
ptrmapPutOvflPtr(pNew, pCell, &rc);
@@ -60632,10 +60774,17 @@
6063260774
** is read-only, the others are read/write.
6063360775
**
6063460776
** The schema layer numbers meta values differently. At the schema
6063560777
** layer (and the SetCookie and ReadCookie opcodes) the number of
6063660778
** free pages is not visible. So Cookie[0] is the same as Meta[1].
60779
+**
60780
+** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead
60781
+** of reading the value out of the header, it instead loads the "DataVersion"
60782
+** from the pager. The BTREE_DATA_VERSION value is not actually stored in the
60783
+** database file. It is a number computed by the pager. But its access
60784
+** pattern is the same as header meta values, and so it is convenient to
60785
+** read it from this routine.
6063760786
*/
6063860787
SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
6063960788
BtShared *pBt = p->pBt;
6064060789
6064160790
sqlite3BtreeEnter(p);
@@ -60642,11 +60791,15 @@
6064260791
assert( p->inTrans>TRANS_NONE );
6064360792
assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
6064460793
assert( pBt->pPage1 );
6064560794
assert( idx>=0 && idx<=15 );
6064660795
60647
- *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
60796
+ if( idx==BTREE_DATA_VERSION ){
60797
+ *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion;
60798
+ }else{
60799
+ *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
60800
+ }
6064860801
6064960802
/* If auto-vacuum is disabled in this build and this is an auto-vacuum
6065060803
** database, mark the database as read-only. */
6065160804
#ifdef SQLITE_OMIT_AUTOVACUUM
6065260805
if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){
@@ -60733,11 +60886,11 @@
6073360886
if( pPage->leaf ){
6073460887
do {
6073560888
if( pCur->iPage==0 ){
6073660889
/* All pages of the b-tree have been visited. Return successfully. */
6073760890
*pnEntry = nEntry;
60738
- return SQLITE_OK;
60891
+ return moveToRoot(pCur);
6073960892
}
6074060893
moveToParent(pCur);
6074160894
}while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
6074260895
6074360896
pCur->aiIdx[pCur->iPage]++;
@@ -61589,11 +61742,11 @@
6158961742
}
6159061743
6159161744
/*
6159261745
** Return the size of the header added to each page by this module.
6159361746
*/
61594
-SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return sizeof(MemPage); }
61747
+SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
6159561748
6159661749
/************** End of btree.c ***********************************************/
6159761750
/************** Begin file backup.c ******************************************/
6159861751
/*
6159961752
** 2009 January 28
@@ -64353,36 +64506,39 @@
6435364506
**
6435464507
** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
6435564508
*/
6435664509
SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
6435764510
int hasAbort = 0;
64511
+ int hasFkCounter = 0;
6435864512
Op *pOp;
6435964513
VdbeOpIter sIter;
6436064514
memset(&sIter, 0, sizeof(sIter));
6436164515
sIter.v = v;
6436264516
6436364517
while( (pOp = opIterNext(&sIter))!=0 ){
6436464518
int opcode = pOp->opcode;
6436564519
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
64366
-#ifndef SQLITE_OMIT_FOREIGN_KEY
64367
- || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
64368
-#endif
6436964520
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
6437064521
&& ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
6437164522
){
6437264523
hasAbort = 1;
6437364524
break;
6437464525
}
64526
+#ifndef SQLITE_OMIT_FOREIGN_KEY
64527
+ if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
64528
+ hasFkCounter = 1;
64529
+ }
64530
+#endif
6437564531
}
6437664532
sqlite3DbFree(v->db, sIter.apSub);
6437764533
6437864534
/* Return true if hasAbort==mayAbort. Or if a malloc failure occurred.
6437964535
** If malloc failed, then the while() loop above may not have iterated
6438064536
** through all opcodes and hasAbort may be set incorrectly. Return
6438164537
** true for this case to prevent the assert() in the callers frame
6438264538
** from failing. */
64383
- return ( v->db->mallocFailed || hasAbort==mayAbort );
64539
+ return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter );
6438464540
}
6438564541
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
6438664542
6438764543
/*
6438864544
** Loop through the program looking for P2 values that are negative
@@ -65699,11 +65855,11 @@
6569965855
for(n=0; n<nVar; n++){
6570065856
p->aVar[n].flags = MEM_Null;
6570165857
p->aVar[n].db = db;
6570265858
}
6570365859
}
65704
- if( p->azVar ){
65860
+ if( p->azVar && pParse->nzVar>0 ){
6570565861
p->nzVar = pParse->nzVar;
6570665862
memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
6570765863
memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
6570865864
}
6570965865
if( p->aMem ){
@@ -68502,11 +68658,14 @@
6850268658
#ifndef SQLITE_OMIT_WAL
6850368659
int i;
6850468660
for(i=0; i<db->nDb; i++){
6850568661
Btree *pBt = db->aDb[i].pBt;
6850668662
if( pBt ){
68507
- int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
68663
+ int nEntry;
68664
+ sqlite3BtreeEnter(pBt);
68665
+ nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
68666
+ sqlite3BtreeLeave(pBt);
6850868667
if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
6850968668
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
6851068669
}
6851168670
}
6851268671
}
@@ -68682,11 +68841,10 @@
6868268841
** program counter to 0 to ensure that when the statement is
6868368842
** finalized or reset the parser error message is available via
6868468843
** sqlite3_errmsg() and sqlite3_errcode().
6868568844
*/
6868668845
const char *zErr = (const char *)sqlite3_value_text(db->pErr);
68687
- assert( zErr!=0 || db->mallocFailed );
6868868846
sqlite3DbFree(db, v->zErrMsg);
6868968847
if( !db->mallocFailed ){
6869068848
v->zErrMsg = sqlite3DbStrDup(db, zErr);
6869168849
v->rc = rc2;
6869268850
} else {
@@ -75629,12 +75787,12 @@
7562975787
7563075788
#ifndef SQLITE_OMIT_WAL
7563175789
/* Opcode: Checkpoint P1 P2 P3 * *
7563275790
**
7563375791
** 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
75792
+** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL,
75793
+** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns
7563675794
** SQLITE_BUSY or not, respectively. Write the number of pages in the
7563775795
** WAL after the checkpoint into mem[P3+1] and the number of pages
7563875796
** in the WAL that have been checkpointed after the checkpoint
7563975797
** completes into mem[P3+2]. However on an error, mem[P3+1] and
7564075798
** mem[P3+2] are initialized to -1.
@@ -75648,10 +75806,11 @@
7564875806
aRes[0] = 0;
7564975807
aRes[1] = aRes[2] = -1;
7565075808
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
7565175809
|| pOp->p2==SQLITE_CHECKPOINT_FULL
7565275810
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
75811
+ || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
7565375812
);
7565475813
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
7565575814
if( rc==SQLITE_BUSY ){
7565675815
rc = SQLITE_OK;
7565775816
aRes[0] = 1;
@@ -77043,11 +77202,11 @@
7704377202
/*
7704477203
** Hard-coded maximum amount of data to accumulate in memory before flushing
7704577204
** to a level 0 PMA. The purpose of this limit is to prevent various integer
7704677205
** overflows. 512MiB.
7704777206
*/
77048
-#define SQLITE_MAX_MXPMASIZE (1<<29)
77207
+#define SQLITE_MAX_PMASZ (1<<29)
7704977208
7705077209
/*
7705177210
** Private objects used by the sorter
7705277211
*/
7705377212
typedef struct MergeEngine MergeEngine; /* Merge PMAs together */
@@ -77339,13 +77498,10 @@
7733977498
**
7734077499
** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
7734177500
*/
7734277501
#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
7734377502
77344
-/* The minimum PMA size is set to this value multiplied by the database
77345
-** page size in bytes. */
77346
-#define SORTER_MIN_WORKING 10
7734777503
7734877504
/* Maximum number of PMAs that a single MergeEngine can merge */
7734977505
#define SORTER_MAX_MERGE_COUNT 16
7735077506
7735177507
static int vdbeIncrSwap(IncrMerger*);
@@ -77740,14 +77896,15 @@
7774077896
SortSubtask *pTask = &pSorter->aTask[i];
7774177897
pTask->pSorter = pSorter;
7774277898
}
7774377899
7774477900
if( !sqlite3TempInMemory(db) ){
77745
- pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
77901
+ u32 szPma = sqlite3GlobalConfig.szPma;
77902
+ pSorter->mnPmaSize = szPma * pgsz;
7774677903
mxCache = db->aDb[0].pSchema->cache_size;
77747
- if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
77748
- pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);
77904
+ if( mxCache<(int)szPma ) mxCache = (int)szPma;
77905
+ pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
7774977906
7775077907
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
7775177908
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
7775277909
** large heap allocations.
7775377910
*/
@@ -78021,16 +78178,16 @@
7802178178
** Whether or not the file does end up memory mapped of course depends on
7802278179
** the specific VFS implementation.
7802378180
*/
7802478181
static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
7802578182
if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){
78026
- int rc = sqlite3OsTruncate(pFd, nByte);
78027
- if( rc==SQLITE_OK ){
78028
- void *p = 0;
78029
- sqlite3OsFetch(pFd, 0, (int)nByte, &p);
78030
- sqlite3OsUnfetch(pFd, 0, p);
78031
- }
78183
+ void *p = 0;
78184
+ int chunksize = 4*1024;
78185
+ sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
78186
+ sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
78187
+ sqlite3OsFetch(pFd, 0, (int)nByte, &p);
78188
+ sqlite3OsUnfetch(pFd, 0, p);
7803278189
}
7803378190
}
7803478191
#else
7803578192
# define vdbeSorterExtendFile(x,y,z)
7803678193
#endif
@@ -80411,10 +80568,14 @@
8041180568
}
8041280569
}
8041380570
if( pMatch ){
8041480571
pExpr->iTable = pMatch->iCursor;
8041580572
pExpr->pTab = pMatch->pTab;
80573
+ assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
80574
+ if( (pMatch->jointype & JT_LEFT)!=0 ){
80575
+ ExprSetProperty(pExpr, EP_CanBeNull);
80576
+ }
8041680577
pSchema = pExpr->pTab->pSchema;
8041780578
}
8041880579
} /* if( pSrcList ) */
8041980580
8042080581
#ifndef SQLITE_OMIT_TRIGGER
@@ -82968,11 +83129,12 @@
8296883129
case TK_FLOAT:
8296983130
case TK_BLOB:
8297083131
return 0;
8297183132
case TK_COLUMN:
8297283133
assert( p->pTab!=0 );
82973
- return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
83134
+ return ExprHasProperty(p, EP_CanBeNull) ||
83135
+ (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
8297483136
default:
8297583137
return 1;
8297683138
}
8297783139
}
8297883140
@@ -87203,11 +87365,11 @@
8720387365
8720487366
p->iGet = -1;
8720587367
p->mxSample = mxSample;
8720687368
p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
8720787369
p->current.anLt = &p->current.anEq[nColUp];
87208
- p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565;
87370
+ p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
8720987371
8721087372
/* Set up the Stat4Accum.a[] and aBest[] arrays */
8721187373
p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
8721287374
p->aBest = &p->a[mxSample];
8721387375
pSpace = (u8*)(&p->a[mxSample+nCol]);
@@ -88351,11 +88513,11 @@
8835188513
tRowcnt avgEq = 0;
8835288514
tRowcnt nRow; /* Number of rows in index */
8835388515
i64 nSum100 = 0; /* Number of terms contributing to sumEq */
8835488516
i64 nDist100; /* Number of distinct values in index */
8835588517
88356
- if( pIdx->aiRowEst==0 || pIdx->aiRowEst[iCol+1]==0 ){
88518
+ if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
8835788519
nRow = pFinal->anLt[iCol];
8835888520
nDist100 = (i64)100 * pFinal->anDLt[iCol];
8835988521
nSample--;
8836088522
}else{
8836188523
nRow = pIdx->aiRowEst[0];
@@ -88796,17 +88958,19 @@
8879688958
}else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
8879788959
zErrDyn = sqlite3MPrintf(db,
8879888960
"attached databases must use the same text encoding as main database");
8879988961
rc = SQLITE_ERROR;
8880088962
}
88963
+ sqlite3BtreeEnter(aNew->pBt);
8880188964
pPager = sqlite3BtreePager(aNew->pBt);
8880288965
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
8880388966
sqlite3BtreeSecureDelete(aNew->pBt,
8880488967
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
8880588968
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
8880688969
sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
8880788970
#endif
88971
+ sqlite3BtreeLeave(aNew->pBt);
8880888972
}
8880988973
aNew->safety_level = 3;
8881088974
aNew->zName = sqlite3DbStrDup(db, zName);
8881188975
if( rc==SQLITE_OK && aNew->zName==0 ){
8881288976
rc = SQLITE_NOMEM;
@@ -89928,11 +90092,10 @@
8992890092
*/
8992990093
static void freeIndex(sqlite3 *db, Index *p){
8993090094
#ifndef SQLITE_OMIT_ANALYZE
8993190095
sqlite3DeleteIndexSamples(db, p);
8993290096
#endif
89933
- if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
8993490097
sqlite3ExprDelete(db, p->pPartIdxWhere);
8993590098
sqlite3DbFree(db, p->zColAff);
8993690099
if( p->isResized ) sqlite3DbFree(db, p->azColl);
8993790100
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
8993890101
sqlite3_free(p->aiRowEst);
@@ -91207,10 +91370,23 @@
9120791370
if( pPk==0 ) return;
9120891371
pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
9120991372
pTab->iPKey = -1;
9121091373
}else{
9121191374
pPk = sqlite3PrimaryKeyIndex(pTab);
91375
+ /*
91376
+ ** Remove all redundant columns from the PRIMARY KEY. For example, change
91377
+ ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
91378
+ ** code assumes the PRIMARY KEY contains no repeated columns.
91379
+ */
91380
+ for(i=j=1; i<pPk->nKeyCol; i++){
91381
+ if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
91382
+ pPk->nColumn--;
91383
+ }else{
91384
+ pPk->aiColumn[j++] = pPk->aiColumn[i];
91385
+ }
91386
+ }
91387
+ pPk->nKeyCol = j;
9121291388
}
9121391389
pPk->isCovering = 1;
9121491390
assert( pPk!=0 );
9121591391
nPk = pPk->nKeyCol;
9121691392
@@ -93683,44 +93859,35 @@
9368393859
**
9368493860
** The caller should invoke sqlite3KeyInfoUnref() on the returned object
9368593861
** when it has finished using it.
9368693862
*/
9368793863
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
93864
+ int i;
93865
+ int nCol = pIdx->nColumn;
93866
+ int nKey = pIdx->nKeyCol;
93867
+ KeyInfo *pKey;
9368893868
if( pParse->nErr ) return 0;
93689
-#ifndef SQLITE_OMIT_SHARED_CACHE
93690
- if( pIdx->pKeyInfo && pIdx->pKeyInfo->db!=pParse->db ){
93691
- sqlite3KeyInfoUnref(pIdx->pKeyInfo);
93692
- pIdx->pKeyInfo = 0;
93693
- }
93694
-#endif
93695
- if( pIdx->pKeyInfo==0 ){
93696
- int i;
93697
- int nCol = pIdx->nColumn;
93698
- int nKey = pIdx->nKeyCol;
93699
- KeyInfo *pKey;
93700
- if( pIdx->uniqNotNull ){
93701
- pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
93702
- }else{
93703
- pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
93704
- }
93705
- if( pKey ){
93706
- assert( sqlite3KeyInfoIsWriteable(pKey) );
93707
- for(i=0; i<nCol; i++){
93708
- char *zColl = pIdx->azColl[i];
93709
- assert( zColl!=0 );
93710
- pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
93711
- sqlite3LocateCollSeq(pParse, zColl);
93712
- pKey->aSortOrder[i] = pIdx->aSortOrder[i];
93713
- }
93714
- if( pParse->nErr ){
93715
- sqlite3KeyInfoUnref(pKey);
93716
- }else{
93717
- pIdx->pKeyInfo = pKey;
93718
- }
93719
- }
93720
- }
93721
- return sqlite3KeyInfoRef(pIdx->pKeyInfo);
93869
+ if( pIdx->uniqNotNull ){
93870
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
93871
+ }else{
93872
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
93873
+ }
93874
+ if( pKey ){
93875
+ assert( sqlite3KeyInfoIsWriteable(pKey) );
93876
+ for(i=0; i<nCol; i++){
93877
+ char *zColl = pIdx->azColl[i];
93878
+ assert( zColl!=0 );
93879
+ pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
93880
+ sqlite3LocateCollSeq(pParse, zColl);
93881
+ pKey->aSortOrder[i] = pIdx->aSortOrder[i];
93882
+ }
93883
+ if( pParse->nErr ){
93884
+ sqlite3KeyInfoUnref(pKey);
93885
+ pKey = 0;
93886
+ }
93887
+ }
93888
+ return pKey;
9372293889
}
9372393890
9372493891
#ifndef SQLITE_OMIT_CTE
9372593892
/*
9372693893
** This routine is invoked once per CTE by the parser while parsing a
@@ -97337,11 +97504,11 @@
9733797504
assert( nIncr==1 );
9733897505
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
9733997506
OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
9734097507
}else{
9734197508
if( nIncr>0 && pFKey->isDeferred==0 ){
97342
- sqlite3ParseToplevel(pParse)->mayAbort = 1;
97509
+ sqlite3MayAbort(pParse);
9734397510
}
9734497511
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
9734597512
}
9734697513
9734797514
sqlite3VdbeResolveLabel(v, iOk);
@@ -97408,10 +97575,14 @@
9740897575
** This function is called to generate code executed when a row is deleted
9740997576
** from the parent table of foreign key constraint pFKey and, if pFKey is
9741097577
** deferred, when a row is inserted into the same table. When generating
9741197578
** code for an SQL UPDATE operation, this function may be called twice -
9741297579
** once to "delete" the old row and once to "insert" the new row.
97580
+**
97581
+** Parameter nIncr is passed -1 when inserting a row (as this may decrease
97582
+** the number of FK violations in the db) or +1 when deleting one (as this
97583
+** may increase the number of FK constraint problems).
9741397584
**
9741497585
** The code generated by this function scans through the rows in the child
9741597586
** table that correspond to the parent table row being deleted or inserted.
9741697587
** For each child row found, one of the following actions is taken:
9741797588
**
@@ -97525,17 +97696,13 @@
9752597696
sNameContext.pSrcList = pSrc;
9752697697
sNameContext.pParse = pParse;
9752797698
sqlite3ResolveExprNames(&sNameContext, pWhere);
9752897699
9752997700
/* Create VDBE to loop through the entries in pSrc that match the WHERE
97530
- ** clause. If the constraint is not deferred, throw an exception for
97531
- ** each row found. Otherwise, for deferred constraints, increment the
97532
- ** deferred constraint counter by nIncr for each row selected. */
97701
+ ** clause. For each row found, increment either the deferred or immediate
97702
+ ** foreign key constraint counter. */
9753397703
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
97534
- if( nIncr>0 && pFKey->isDeferred==0 ){
97535
- sqlite3ParseToplevel(pParse)->mayAbort = 1;
97536
- }
9753797704
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
9753897705
if( pWInfo ){
9753997706
sqlite3WhereEnd(pWInfo);
9754097707
}
9754197708
@@ -97709,10 +97876,28 @@
9770997876
}
9771097877
}
9771197878
}
9771297879
return 0;
9771397880
}
97881
+
97882
+/*
97883
+** Return true if the parser passed as the first argument is being
97884
+** used to code a trigger that is really a "SET NULL" action belonging
97885
+** to trigger pFKey.
97886
+*/
97887
+static int isSetNullAction(Parse *pParse, FKey *pFKey){
97888
+ Parse *pTop = sqlite3ParseToplevel(pParse);
97889
+ if( pTop->pTriggerPrg ){
97890
+ Trigger *p = pTop->pTriggerPrg->pTrigger;
97891
+ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
97892
+ || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
97893
+ ){
97894
+ return 1;
97895
+ }
97896
+ }
97897
+ return 0;
97898
+}
9771497899
9771597900
/*
9771697901
** This function is called when inserting, deleting or updating a row of
9771797902
** table pTab to generate VDBE code to perform foreign key constraint
9771897903
** processing for the operation.
@@ -97762,11 +97947,11 @@
9776297947
Index *pIdx = 0; /* Index on key columns in pTo */
9776397948
int *aiFree = 0;
9776497949
int *aiCol;
9776597950
int iCol;
9776697951
int i;
97767
- int isIgnore = 0;
97952
+ int bIgnore = 0;
9776897953
9776997954
if( aChange
9777097955
&& sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
9777197956
&& fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
9777297957
){
@@ -97821,11 +98006,11 @@
9782198006
** values read from the parent table are NULL. */
9782298007
if( db->xAuth ){
9782398008
int rcauth;
9782498009
char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
9782598010
rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
97826
- isIgnore = (rcauth==SQLITE_IGNORE);
98011
+ bIgnore = (rcauth==SQLITE_IGNORE);
9782798012
}
9782898013
#endif
9782998014
}
9783098015
9783198016
/* Take a shared-cache advisory read-lock on the parent table. Allocate
@@ -97836,16 +98021,22 @@
9783698021
9783798022
if( regOld!=0 ){
9783898023
/* A row is being removed from the child table. Search for the parent.
9783998024
** If the parent does not exist, removing the child row resolves an
9784098025
** outstanding foreign key constraint violation. */
97841
- fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
98026
+ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
9784298027
}
97843
- if( regNew!=0 ){
98028
+ if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
9784498029
/* A row is being added to the child table. If a parent row cannot
97845
- ** be found, adding the child row has violated the FK constraint. */
97846
- fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
98030
+ ** be found, adding the child row has violated the FK constraint.
98031
+ **
98032
+ ** If this operation is being performed as part of a trigger program
98033
+ ** that is actually a "SET NULL" action belonging to this very
98034
+ ** foreign key, then omit this scan altogether. As all child key
98035
+ ** values are guaranteed to be NULL, it is not possible for adding
98036
+ ** this row to cause an FK violation. */
98037
+ fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
9784798038
}
9784898039
9784998040
sqlite3DbFree(db, aiFree);
9785098041
}
9785198042
@@ -97862,12 +98053,12 @@
9786298053
9786398054
if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
9786498055
&& !pParse->pToplevel && !pParse->isMultiWrite
9786598056
){
9786698057
assert( regOld==0 && regNew!=0 );
97867
- /* Inserting a single row into a parent table cannot cause an immediate
97868
- ** foreign key violation. So do nothing in this case. */
98058
+ /* Inserting a single row into a parent table cannot cause (or fix)
98059
+ ** an immediate foreign key violation. So do nothing in this case. */
9786998060
continue;
9787098061
}
9787198062
9787298063
if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
9787398064
if( !isIgnoreErrors || db->mallocFailed ) return;
@@ -97887,17 +98078,32 @@
9788798078
9788898079
if( regNew!=0 ){
9788998080
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
9789098081
}
9789198082
if( regOld!=0 ){
97892
- /* If there is a RESTRICT action configured for the current operation
97893
- ** on the parent table of this FK, then throw an exception
97894
- ** immediately if the FK constraint is violated, even if this is a
97895
- ** deferred trigger. That's what RESTRICT means. To defer checking
97896
- ** the constraint, the FK should specify NO ACTION (represented
97897
- ** using OE_None). NO ACTION is the default. */
98083
+ int eAction = pFKey->aAction[aChange!=0];
9789898084
fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
98085
+ /* If this is a deferred FK constraint, or a CASCADE or SET NULL
98086
+ ** action applies, then any foreign key violations caused by
98087
+ ** removing the parent key will be rectified by the action trigger.
98088
+ ** So do not set the "may-abort" flag in this case.
98089
+ **
98090
+ ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
98091
+ ** may-abort flag will eventually be set on this statement anyway
98092
+ ** (when this function is called as part of processing the UPDATE
98093
+ ** within the action trigger).
98094
+ **
98095
+ ** Note 2: At first glance it may seem like SQLite could simply omit
98096
+ ** all OP_FkCounter related scans when either CASCADE or SET NULL
98097
+ ** applies. The trouble starts if the CASCADE or SET NULL action
98098
+ ** trigger causes other triggers or action rules attached to the
98099
+ ** child table to fire. In these cases the fk constraint counters
98100
+ ** might be set incorrectly if any OP_FkCounter related scans are
98101
+ ** omitted. */
98102
+ if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
98103
+ sqlite3MayAbort(pParse);
98104
+ }
9789998105
}
9790098106
pItem->zName = 0;
9790198107
sqlite3SrcListDelete(db, pSrc);
9790298108
}
9790398109
sqlite3DbFree(db, aiCol);
@@ -100987,11 +101193,10 @@
100987101193
# define sqlite3_column_database_name16 0
100988101194
# define sqlite3_column_table_name 0
100989101195
# define sqlite3_column_table_name16 0
100990101196
# define sqlite3_column_origin_name 0
100991101197
# define sqlite3_column_origin_name16 0
100992
-# define sqlite3_table_column_metadata 0
100993101198
#endif
100994101199
100995101200
#ifdef SQLITE_OMIT_AUTHORIZATION
100996101201
# define sqlite3_set_authorizer 0
100997101202
#endif
@@ -101797,10 +102002,11 @@
101797102002
#define PragTyp_KEY 38
101798102003
#define PragTyp_REKEY 39
101799102004
#define PragTyp_LOCK_STATUS 40
101800102005
#define PragTyp_PARSER_TRACE 41
101801102006
#define PragFlag_NeedSchema 0x01
102007
+#define PragFlag_ReadOnly 0x02
101802102008
static const struct sPragmaNames {
101803102009
const char *const zName; /* Name of pragma */
101804102010
u8 ePragTyp; /* PragTyp_XXX value */
101805102011
u8 mPragFlag; /* Zero or more PragFlag_XXX values */
101806102012
u32 iArg; /* Extra argument */
@@ -101813,11 +102019,11 @@
101813102019
#endif
101814102020
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
101815102021
{ /* zName: */ "application_id",
101816102022
/* ePragTyp: */ PragTyp_HEADER_VALUE,
101817102023
/* ePragFlag: */ 0,
101818
- /* iArg: */ 0 },
102024
+ /* iArg: */ BTREE_APPLICATION_ID },
101819102025
#endif
101820102026
#if !defined(SQLITE_OMIT_AUTOVACUUM)
101821102027
{ /* zName: */ "auto_vacuum",
101822102028
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
101823102029
/* ePragFlag: */ PragFlag_NeedSchema,
@@ -101879,10 +102085,16 @@
101879102085
{ /* zName: */ "data_store_directory",
101880102086
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
101881102087
/* ePragFlag: */ 0,
101882102088
/* iArg: */ 0 },
101883102089
#endif
102090
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102091
+ { /* zName: */ "data_version",
102092
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
102093
+ /* ePragFlag: */ PragFlag_ReadOnly,
102094
+ /* iArg: */ BTREE_DATA_VERSION },
102095
+#endif
101884102096
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
101885102097
{ /* zName: */ "database_list",
101886102098
/* ePragTyp: */ PragTyp_DATABASE_LIST,
101887102099
/* ePragFlag: */ PragFlag_NeedSchema,
101888102100
/* iArg: */ 0 },
@@ -101934,12 +102146,12 @@
101934102146
#endif
101935102147
#endif
101936102148
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
101937102149
{ /* zName: */ "freelist_count",
101938102150
/* ePragTyp: */ PragTyp_HEADER_VALUE,
101939
- /* ePragFlag: */ 0,
101940
- /* iArg: */ 0 },
102151
+ /* ePragFlag: */ PragFlag_ReadOnly,
102152
+ /* iArg: */ BTREE_FREE_PAGE_COUNT },
101941102153
#endif
101942102154
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
101943102155
{ /* zName: */ "full_column_names",
101944102156
/* ePragTyp: */ PragTyp_FLAG,
101945102157
/* ePragFlag: */ 0,
@@ -102087,11 +102299,11 @@
102087102299
#endif
102088102300
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102089102301
{ /* zName: */ "schema_version",
102090102302
/* ePragTyp: */ PragTyp_HEADER_VALUE,
102091102303
/* ePragFlag: */ 0,
102092
- /* iArg: */ 0 },
102304
+ /* iArg: */ BTREE_SCHEMA_VERSION },
102093102305
#endif
102094102306
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
102095102307
{ /* zName: */ "secure_delete",
102096102308
/* ePragTyp: */ PragTyp_SECURE_DELETE,
102097102309
/* ePragFlag: */ 0,
@@ -102153,11 +102365,11 @@
102153102365
/* iArg: */ 0 },
102154102366
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102155102367
{ /* zName: */ "user_version",
102156102368
/* ePragTyp: */ PragTyp_HEADER_VALUE,
102157102369
/* ePragFlag: */ 0,
102158
- /* iArg: */ 0 },
102370
+ /* iArg: */ BTREE_USER_VERSION },
102159102371
#endif
102160102372
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
102161102373
#if defined(SQLITE_DEBUG)
102162102374
{ /* zName: */ "vdbe_addoptrace",
102163102375
/* ePragTyp: */ PragTyp_FLAG,
@@ -102196,11 +102408,11 @@
102196102408
/* ePragTyp: */ PragTyp_FLAG,
102197102409
/* ePragFlag: */ 0,
102198102410
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
102199102411
#endif
102200102412
};
102201
-/* Number of pragmas: 57 on by default, 70 total. */
102413
+/* Number of pragmas: 58 on by default, 71 total. */
102202102414
/* End of the automatically generated pragma table.
102203102415
***************************************************************************/
102204102416
102205102417
/*
102206102418
** Interpret the given string as a safety level. Return 0 for OFF,
@@ -103806,11 +104018,12 @@
103806104018
!(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
103807104019
DbHasProperty(db, 0, DB_Empty)
103808104020
){
103809104021
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
103810104022
if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
103811
- ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
104023
+ SCHEMA_ENC(db) = ENC(db) =
104024
+ pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
103812104025
break;
103813104026
}
103814104027
}
103815104028
if( !pEnc->zName ){
103816104029
sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
@@ -103851,28 +104064,13 @@
103851104064
**
103852104065
** The user-version is not used internally by SQLite. It may be used by
103853104066
** applications for any purpose.
103854104067
*/
103855104068
case PragTyp_HEADER_VALUE: {
103856
- int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
104069
+ int iCookie = aPragmaNames[mid].iArg; /* Which cookie to read or write */
103857104070
sqlite3VdbeUsesBtree(v, iDb);
103858
- switch( zLeft[0] ){
103859
- case 'a': case 'A':
103860
- iCookie = BTREE_APPLICATION_ID;
103861
- break;
103862
- case 'f': case 'F':
103863
- iCookie = BTREE_FREE_PAGE_COUNT;
103864
- break;
103865
- case 's': case 'S':
103866
- iCookie = BTREE_SCHEMA_VERSION;
103867
- break;
103868
- default:
103869
- iCookie = BTREE_USER_VERSION;
103870
- break;
103871
- }
103872
-
103873
- if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
104071
+ if( zRight && (aPragmaNames[mid].mPragFlag & PragFlag_ReadOnly)==0 ){
103874104072
/* Write the specified cookie value */
103875104073
static const VdbeOpList setCookie[] = {
103876104074
{ OP_Transaction, 0, 1, 0}, /* 0 */
103877104075
{ OP_Integer, 0, 1, 0}, /* 1 */
103878104076
{ OP_SetCookie, 0, 0, 1}, /* 2 */
@@ -103921,11 +104119,11 @@
103921104119
break;
103922104120
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
103923104121
103924104122
#ifndef SQLITE_OMIT_WAL
103925104123
/*
103926
- ** PRAGMA [database.]wal_checkpoint = passive|full|restart
104124
+ ** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
103927104125
**
103928104126
** Checkpoint the database.
103929104127
*/
103930104128
case PragTyp_WAL_CHECKPOINT: {
103931104129
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
@@ -103933,10 +104131,12 @@
103933104131
if( zRight ){
103934104132
if( sqlite3StrICmp(zRight, "full")==0 ){
103935104133
eMode = SQLITE_CHECKPOINT_FULL;
103936104134
}else if( sqlite3StrICmp(zRight, "restart")==0 ){
103937104135
eMode = SQLITE_CHECKPOINT_RESTART;
104136
+ }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
104137
+ eMode = SQLITE_CHECKPOINT_TRUNCATE;
103938104138
}
103939104139
}
103940104140
sqlite3VdbeSetNumCols(v, 3);
103941104141
pParse->nMem = 3;
103942104142
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
@@ -104512,13 +104712,15 @@
104512104712
SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
104513104713
int i, rc;
104514104714
int commit_internal = !(db->flags&SQLITE_InternChanges);
104515104715
104516104716
assert( sqlite3_mutex_held(db->mutex) );
104717
+ assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
104517104718
assert( db->init.busy==0 );
104518104719
rc = SQLITE_OK;
104519104720
db->init.busy = 1;
104721
+ ENC(db) = SCHEMA_ENC(db);
104520104722
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
104521104723
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
104522104724
rc = sqlite3InitOne(db, i, pzErrMsg);
104523104725
if( rc ){
104524104726
sqlite3ResetOneSchema(db, i);
@@ -109840,11 +110042,11 @@
109840110042
**
109841110043
** SELECT DISTINCT xyz FROM ... ORDER BY xyz
109842110044
**
109843110045
** is transformed to:
109844110046
**
109845
- ** SELECT xyz FROM ... GROUP BY xyz
110047
+ ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
109846110048
**
109847110049
** The second form is preferred as a single index (or temp-table) may be
109848110050
** used for both the ORDER BY and DISTINCT processing. As originally
109849110051
** written the query must use a temp-table for at least one of the ORDER
109850110052
** BY and DISTINCT, and an index or separate temp-table for the other.
@@ -109853,11 +110055,10 @@
109853110055
&& sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0
109854110056
){
109855110057
p->selFlags &= ~SF_Distinct;
109856110058
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
109857110059
pGroupBy = p->pGroupBy;
109858
- sSort.pOrderBy = 0;
109859110060
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
109860110061
** the sDistinct.isTnct is still set. Hence, isTnct represents the
109861110062
** original setting of the SF_Distinct flag, not the current setting */
109862110063
assert( sDistinct.isTnct );
109863110064
}
@@ -110657,11 +110858,11 @@
110657110858
){
110658110859
int rc;
110659110860
TabResult res;
110660110861
110661110862
#ifdef SQLITE_ENABLE_API_ARMOR
110662
- if( pazResult==0 ) return SQLITE_MISUSE_BKPT;
110863
+ if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT;
110663110864
#endif
110664110865
*pazResult = 0;
110665110866
if( pnColumn ) *pnColumn = 0;
110666110867
if( pnRow ) *pnRow = 0;
110667110868
if( pzErrMsg ) *pzErrMsg = 0;
@@ -114808,10 +115009,11 @@
114808115009
memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
114809115010
if( pOld!=pWC->aStatic ){
114810115011
sqlite3DbFree(db, pOld);
114811115012
}
114812115013
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
115014
+ memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
114813115015
}
114814115016
pTerm = &pWC->a[idx = pWC->nTerm++];
114815115017
if( p && ExprHasProperty(p, EP_Unlikely) ){
114816115018
pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
114817115019
}else{
@@ -117533,11 +117735,11 @@
117533117735
WhereLevel *pLvl, /* Level to add scanstatus() entry for */
117534117736
int addrExplain /* Address of OP_Explain (or 0) */
117535117737
){
117536117738
const char *zObj = 0;
117537117739
WhereLoop *pLoop = pLvl->pWLoop;
117538
- if( (pLoop->wsFlags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
117740
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
117539117741
zObj = pLoop->u.btree.pIndex->zName;
117540117742
}else{
117541117743
zObj = pSrclist->a[pLvl->iFrom].zName;
117542117744
}
117543117745
sqlite3VdbeScanStatus(
@@ -118177,14 +118379,13 @@
118177118379
int iTerm;
118178118380
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
118179118381
Expr *pExpr = pWC->a[iTerm].pExpr;
118180118382
if( &pWC->a[iTerm] == pTerm ) continue;
118181118383
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;
118384
+ if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
118185118385
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
118386
+ testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
118186118387
pExpr = sqlite3ExprDup(db, pExpr, 0);
118187118388
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
118188118389
}
118189118390
if( pAndExpr ){
118190118391
pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
@@ -118527,11 +118728,10 @@
118527118728
sqlite3_free(p->u.vtab.idxStr);
118528118729
p->u.vtab.needFree = 0;
118529118730
p->u.vtab.idxStr = 0;
118530118731
}else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
118531118732
sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
118532
- sqlite3KeyInfoUnref(p->u.btree.pIndex->pKeyInfo);
118533118733
sqlite3DbFree(db, p->u.btree.pIndex);
118534118734
p->u.btree.pIndex = 0;
118535118735
}
118536118736
}
118537118737
}
@@ -125534,10 +125734,13 @@
125534125734
u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
125535125735
sqlite3 *db = pParse->db; /* The database connection */
125536125736
int mxSqlLen; /* Max length of an SQL string */
125537125737
125538125738
125739
+#ifdef SQLITE_ENABLE_API_ARMOR
125740
+ if( zSql==0 || pzErrMsg==0 ) return SQLITE_MISUSE_BKPT;
125741
+#endif
125539125742
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
125540125743
if( db->nVdbeActive==0 ){
125541125744
db->u1.isInterrupted = 0;
125542125745
}
125543125746
pParse->rc = SQLITE_OK;
@@ -125772,17 +125975,10 @@
125772125975
*/
125773125976
SQLITE_API int sqlite3_complete(const char *zSql){
125774125977
u8 state = 0; /* Current state, using numbers defined in header comment */
125775125978
u8 token; /* Value of the next token */
125776125979
125777
-#ifdef SQLITE_ENABLE_API_ARMOR
125778
- if( zSql==0 ){
125779
- (void)SQLITE_MISUSE_BKPT;
125780
- return 0;
125781
- }
125782
-#endif
125783
-
125784125980
#ifndef SQLITE_OMIT_TRIGGER
125785125981
/* A complex statement machine used to detect the end of a CREATE TRIGGER
125786125982
** statement. This is the normal case.
125787125983
*/
125788125984
static const u8 trans[8][8] = {
@@ -125807,10 +126003,17 @@
125807126003
/* 0 INVALID: */ { 1, 0, 2, },
125808126004
/* 1 START: */ { 1, 1, 2, },
125809126005
/* 2 NORMAL: */ { 1, 2, 2, },
125810126006
};
125811126007
#endif /* SQLITE_OMIT_TRIGGER */
126008
+
126009
+#ifdef SQLITE_ENABLE_API_ARMOR
126010
+ if( zSql==0 ){
126011
+ (void)SQLITE_MISUSE_BKPT;
126012
+ return 0;
126013
+ }
126014
+#endif
125812126015
125813126016
while( *zSql ){
125814126017
switch( *zSql ){
125815126018
case ';': { /* A semicolon */
125816126019
token = tkSEMI;
@@ -126109,11 +126312,11 @@
126109126312
** If the following function pointer is not NULL and if
126110126313
** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
126111126314
** I/O active are written using this function. These messages
126112126315
** are intended for debugging activity only.
126113126316
*/
126114
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0;
126317
+/* not-private */ void (*sqlite3IoTrace)(const char*, ...) = 0;
126115126318
#endif
126116126319
126117126320
/*
126118126321
** If the following global variable points to a string which is the
126119126322
** name of a directory, then that directory will be used to store
@@ -126318,10 +126521,17 @@
126318126521
** routine is not threadsafe. But it is safe to invoke this routine
126319126522
** on when SQLite is already shut down. If SQLite is already shut down
126320126523
** when this routine is invoked, then this routine is a harmless no-op.
126321126524
*/
126322126525
SQLITE_API int sqlite3_shutdown(void){
126526
+#ifdef SQLITE_OMIT_WSD
126527
+ int rc = sqlite3_wsd_init(4096, 24);
126528
+ if( rc!=SQLITE_OK ){
126529
+ return rc;
126530
+ }
126531
+#endif
126532
+
126323126533
if( sqlite3GlobalConfig.isInit ){
126324126534
#ifdef SQLITE_EXTRA_SHUTDOWN
126325126535
void SQLITE_EXTRA_SHUTDOWN(void);
126326126536
SQLITE_EXTRA_SHUTDOWN();
126327126537
#endif
@@ -126633,10 +126843,15 @@
126633126843
** heap. */
126634126844
sqlite3GlobalConfig.nHeap = va_arg(ap, int);
126635126845
break;
126636126846
}
126637126847
#endif
126848
+
126849
+ case SQLITE_CONFIG_PMASZ: {
126850
+ sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int);
126851
+ break;
126852
+ }
126638126853
126639126854
default: {
126640126855
rc = SQLITE_ERROR;
126641126856
break;
126642126857
}
@@ -127983,14 +128198,17 @@
127983128198
127984128199
/* Initialize the output variables to -1 in case an error occurs. */
127985128200
if( pnLog ) *pnLog = -1;
127986128201
if( pnCkpt ) *pnCkpt = -1;
127987128202
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 ){
128203
+ assert( SQLITE_CHECKPOINT_PASSIVE==0 );
128204
+ assert( SQLITE_CHECKPOINT_FULL==1 );
128205
+ assert( SQLITE_CHECKPOINT_RESTART==2 );
128206
+ assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
128207
+ if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
128208
+ /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
128209
+ ** mode: */
127992128210
return SQLITE_MISUSE;
127993128211
}
127994128212
127995128213
sqlite3_mutex_enter(db->mutex);
127996128214
if( zDb && zDb[0] ){
@@ -128014,11 +128232,13 @@
128014128232
** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
128015128233
** to contains a zero-length string, all attached databases are
128016128234
** checkpointed.
128017128235
*/
128018128236
SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
128019
- return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
128237
+ /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
128238
+ ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
128239
+ return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
128020128240
}
128021128241
128022128242
#ifndef SQLITE_OMIT_WAL
128023128243
/*
128024128244
** Run a checkpoint on database iDb. This is a no-op if database iDb is
@@ -128201,36 +128421,10 @@
128201128421
*/
128202128422
SQLITE_API const char *sqlite3_errstr(int rc){
128203128423
return sqlite3ErrStr(rc);
128204128424
}
128205128425
128206
-/*
128207
-** Invalidate all cached KeyInfo objects for database connection "db"
128208
-*/
128209
-static void invalidateCachedKeyInfo(sqlite3 *db){
128210
- Db *pDb; /* A single database */
128211
- int iDb; /* The database index number */
128212
- HashElem *k; /* For looping over tables in pDb */
128213
- Table *pTab; /* A table in the database */
128214
- Index *pIdx; /* Each index */
128215
-
128216
- for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
128217
- if( pDb->pBt==0 ) continue;
128218
- sqlite3BtreeEnter(pDb->pBt);
128219
- for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
128220
- pTab = (Table*)sqliteHashData(k);
128221
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
128222
- if( pIdx->pKeyInfo && pIdx->pKeyInfo->db==db ){
128223
- sqlite3KeyInfoUnref(pIdx->pKeyInfo);
128224
- pIdx->pKeyInfo = 0;
128225
- }
128226
- }
128227
- }
128228
- sqlite3BtreeLeave(pDb->pBt);
128229
- }
128230
-}
128231
-
128232128426
/*
128233128427
** Create a new collating function for database "db". The name is zName
128234128428
** and the encoding is enc.
128235128429
*/
128236128430
static int createCollation(
@@ -128270,11 +128464,10 @@
128270128464
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
128271128465
"unable to delete/modify collation sequence due to active statements");
128272128466
return SQLITE_BUSY;
128273128467
}
128274128468
sqlite3ExpirePreparedStatements(db);
128275
- invalidateCachedKeyInfo(db);
128276128469
128277128470
/* If collation sequence pColl was created directly by a call to
128278128471
** sqlite3_create_collation, and not generated by synthCollSeq(),
128279128472
** then any copies made by synthCollSeq() need to be invalidated.
128280128473
** Also, collation destructor - CollSeq.xDel() - function may need
@@ -128775,10 +128968,13 @@
128775128968
| SQLITE_RecTriggers
128776128969
#endif
128777128970
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
128778128971
| SQLITE_ForeignKeys
128779128972
#endif
128973
+#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
128974
+ | SQLITE_ReverseOrder
128975
+#endif
128780128976
;
128781128977
sqlite3HashInit(&db->aCollSeq);
128782128978
#ifndef SQLITE_OMIT_VIRTUALTABLE
128783128979
sqlite3HashInit(&db->aModule);
128784128980
#endif
@@ -128822,11 +129018,14 @@
128822129018
rc = SQLITE_NOMEM;
128823129019
}
128824129020
sqlite3Error(db, rc);
128825129021
goto opendb_out;
128826129022
}
129023
+ sqlite3BtreeEnter(db->aDb[0].pBt);
128827129024
db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
129025
+ if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
129026
+ sqlite3BtreeLeave(db->aDb[0].pBt);
128828129027
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
128829129028
128830129029
/* The default safety_level for the main database is 'full'; for the temp
128831129030
** database it is 'NONE'. This matches the pager layer defaults.
128832129031
*/
@@ -128980,11 +129179,11 @@
128980129179
if( zFilename8 ){
128981129180
rc = openDatabase(zFilename8, ppDb,
128982129181
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
128983129182
assert( *ppDb || rc==SQLITE_NOMEM );
128984129183
if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
128985
- ENC(*ppDb) = SQLITE_UTF16NATIVE;
129184
+ SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
128986129185
}
128987129186
}else{
128988129187
rc = SQLITE_NOMEM;
128989129188
}
128990129189
sqlite3ValueFree(pVal);
@@ -129176,11 +129375,10 @@
129176129375
129177129376
/*
129178129377
** Return meta information about a specific column of a database table.
129179129378
** See comment in sqlite3.h (sqlite.h.in) for details.
129180129379
*/
129181
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
129182129380
SQLITE_API int sqlite3_table_column_metadata(
129183129381
sqlite3 *db, /* Connection handle */
129184129382
const char *zDbName, /* Database name or NULL */
129185129383
const char *zTableName, /* Table name */
129186129384
const char *zColumnName, /* Column name */
@@ -129216,25 +129414,27 @@
129216129414
pTab = 0;
129217129415
goto error_out;
129218129416
}
129219129417
129220129418
/* Find the column for which info is requested */
129221
- if( sqlite3IsRowid(zColumnName) ){
129222
- iCol = pTab->iPKey;
129223
- if( iCol>=0 ){
129224
- pCol = &pTab->aCol[iCol];
129225
- }
129419
+ if( zColumnName==0 ){
129420
+ /* Query for existance of table only */
129226129421
}else{
129227129422
for(iCol=0; iCol<pTab->nCol; iCol++){
129228129423
pCol = &pTab->aCol[iCol];
129229129424
if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
129230129425
break;
129231129426
}
129232129427
}
129233129428
if( iCol==pTab->nCol ){
129234
- pTab = 0;
129235
- goto error_out;
129429
+ if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
129430
+ iCol = pTab->iPKey;
129431
+ pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
129432
+ }else{
129433
+ pTab = 0;
129434
+ goto error_out;
129435
+ }
129236129436
}
129237129437
}
129238129438
129239129439
/* The following block stores the meta information that will be returned
129240129440
** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
@@ -129283,11 +129483,10 @@
129283129483
sqlite3DbFree(db, zErrMsg);
129284129484
rc = sqlite3ApiExit(db, rc);
129285129485
sqlite3_mutex_leave(db->mutex);
129286129486
return rc;
129287129487
}
129288
-#endif
129289129488
129290129489
/*
129291129490
** Sleep for a little while. Return the amount of time slept.
129292129491
*/
129293129492
SQLITE_API int sqlite3_sleep(int ms){
@@ -129722,32 +129921,34 @@
129722129921
/*
129723129922
** Return the filename of the database associated with a database
129724129923
** connection.
129725129924
*/
129726129925
SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
129926
+ Btree *pBt;
129727129927
#ifdef SQLITE_ENABLE_API_ARMOR
129728129928
if( !sqlite3SafetyCheckOk(db) ){
129729129929
(void)SQLITE_MISUSE_BKPT;
129730129930
return 0;
129731129931
}
129732129932
#endif
129733
- Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
129933
+ pBt = sqlite3DbNameToBtree(db, zDbName);
129734129934
return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
129735129935
}
129736129936
129737129937
/*
129738129938
** Return 1 if database is read-only or 0 if read/write. Return -1 if
129739129939
** no such database exists.
129740129940
*/
129741129941
SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
129942
+ Btree *pBt;
129742129943
#ifdef SQLITE_ENABLE_API_ARMOR
129743129944
if( !sqlite3SafetyCheckOk(db) ){
129744129945
(void)SQLITE_MISUSE_BKPT;
129745129946
return -1;
129746129947
}
129747129948
#endif
129748
- Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
129949
+ pBt = sqlite3DbNameToBtree(db, zDbName);
129749129950
return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
129750129951
}
129751129952
129752129953
/************** End of main.c ************************************************/
129753129954
/************** Begin file notify.c ******************************************/
@@ -139164,11 +139365,11 @@
139164139365
** Return true if the m-value for z is 1 or more. In other words,
139165139366
** return true if z contains at least one vowel that is followed
139166139367
** by a consonant.
139167139368
**
139168139369
** 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.
139370
+** for an instance of a consonant followed by a vowel.
139170139371
*/
139171139372
static int m_gt_0(const char *z){
139172139373
while( isVowel(z) ){ z++; }
139173139374
if( *z==0 ) return 0;
139174139375
while( isConsonant(z) ){ z++; }
@@ -149954,11 +150155,11 @@
149954150155
}
149955150156
i = pCur->nPoint++;
149956150157
pNew = pCur->aPoint + i;
149957150158
pNew->rScore = rScore;
149958150159
pNew->iLevel = iLevel;
149959
- assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH );
150160
+ assert( iLevel<=RTREE_MAX_DEPTH );
149960150161
while( i>0 ){
149961150162
RtreeSearchPoint *pParent;
149962150163
j = (i-1)/2;
149963150164
pParent = pCur->aPoint + j;
149964150165
if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break;
149965150166
--- 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 **
@@ -323,11 +323,11 @@
323 ** This interface only reports on the compile-time mutex setting
324 ** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
325 ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
326 ** can be fully or partially disabled using a call to [sqlite3_config()]
327 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
328 ** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the
329 ** sqlite3_threadsafe() function shows only the compile-time setting of
330 ** thread safety, not any run-time changes to that setting made by
331 ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
332 ** is unchanged by calls to sqlite3_config().)^
333 **
@@ -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,14 +1688,15 @@
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
1699 ** to [sqlite3_config()].
1700 ** ^It is harmless, apart from the wasted memory,
1701 ** for the sz parameter to be larger than necessary. The first
@@ -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,22 +1860,33 @@
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 */
1878 #define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1895,10 +1909,11 @@
1895 #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
1896 #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
1897 #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
1898 #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
1899 #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
 
1900
1901 /*
1902 ** CAPI3REF: Database Connection Configuration Options
1903 **
1904 ** These constants are the available integer configuration options that
@@ -2171,10 +2186,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 +2203,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 +4658,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*);
@@ -5274,24 +5291,31 @@
5274
5275
5276 /*
5277 ** CAPI3REF: Extract Metadata About A Column Of A Table
5278 **
5279 ** ^This routine returns metadata about a specific column of a specific
5280 ** database table accessible using the [database connection] handle
5281 ** passed as the first function argument.
 
 
 
 
 
 
 
 
5282 **
5283 ** ^The column is identified by the second, third and fourth parameters to
5284 ** this function. ^The second parameter is either the name of the database
5285 ** (i.e. "main", "temp", or an attached database) containing the specified
5286 ** table or NULL. ^If it is NULL, then all attached databases are searched
5287 ** for the table using the same algorithm used by the database engine to
5288 ** resolve unqualified table references.
5289 **
5290 ** ^The third and fourth parameters to this function are the table and column
5291 ** name of the desired column, respectively. Neither of these parameters
5292 ** may be NULL.
5293 **
5294 ** ^Metadata is returned by writing to the memory locations passed as the 5th
5295 ** and subsequent parameters to this function. ^Any of these arguments may be
5296 ** NULL, in which case the corresponding element of metadata is omitted.
5297 **
@@ -5306,36 +5330,33 @@
5306 ** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
5307 ** </table>
5308 ** </blockquote>)^
5309 **
5310 ** ^The memory pointed to by the character pointers returned for the
5311 ** declaration type and collation sequence is valid only until the next
5312 ** call to any SQLite API function.
5313 **
5314 ** ^If the specified table is actually a view, an [error code] is returned.
5315 **
5316 ** ^If the specified column is "rowid", "oid" or "_rowid_" and an
 
5317 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
5318 ** parameters are set for the explicitly declared column. ^(If there is no
5319 ** explicitly declared [INTEGER PRIMARY KEY] column, then the output
5320 ** parameters are set as follows:
5321 **
5322 ** <pre>
5323 ** data type: "INTEGER"
5324 ** collation sequence: "BINARY"
5325 ** not null: 0
5326 ** primary key: 1
5327 ** auto increment: 0
5328 ** </pre>)^
5329 **
5330 ** ^(This function may load one or more schemas from database files. If an
5331 ** error occurs during this process, or if the requested table or column
5332 ** cannot be found, an [error code] is returned and an error message left
5333 ** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
5334 **
5335 ** ^This API is only available if the library was compiled with the
5336 ** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
5337 */
5338 SQLITE_API int sqlite3_table_column_metadata(
5339 sqlite3 *db, /* Connection handle */
5340 const char *zDbName, /* Database name or NULL */
5341 const char *zTableName, /* Table name */
@@ -7298,16 +7319,14 @@
7298
7299 /*
7300 ** CAPI3REF: Write-Ahead Log Commit Hook
7301 **
7302 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
7303 ** will be invoked each time a database connection commits data to a
7304 ** [write-ahead log] (i.e. whenever a transaction is committed in
7305 ** [journal_mode | journal_mode=WAL mode]).
7306 **
7307 ** ^The callback is invoked by SQLite after the commit has taken place and
7308 ** the associated write-lock on the database released, so the implementation
7309 ** may read, write or [checkpoint] the database as required.
7310 **
7311 ** ^The first parameter passed to the callback function when it is invoked
7312 ** is a copy of the third parameter passed to sqlite3_wal_hook() when
7313 ** registering the callback. ^The second is a copy of the database handle.
@@ -7368,101 +7387,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 +7505,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 +7615,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 +7631,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 +7661,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
@@ -9072,11 +9110,11 @@
9072 #define _BTREE_H_
9073
9074 /* TODO: This definition is just included so other modules compile. It
9075 ** needs to be revisited.
9076 */
9077 #define SQLITE_N_BTREE_META 10
9078
9079 /*
9080 ** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
9081 ** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
9082 */
@@ -9187,10 +9225,15 @@
9187 ** offset = 36 + (idx * 4)
9188 **
9189 ** For example, the free-page-count field is located at byte offset 36 of
9190 ** the database file header. The incr-vacuum-flag field is located at
9191 ** byte offset 64 (== 36+4*7).
 
 
 
 
 
9192 */
9193 #define BTREE_FREE_PAGE_COUNT 0
9194 #define BTREE_SCHEMA_VERSION 1
9195 #define BTREE_FILE_FORMAT 2
9196 #define BTREE_DEFAULT_CACHE_SIZE 3
@@ -9197,10 +9240,11 @@
9197 #define BTREE_LARGEST_ROOT_PAGE 4
9198 #define BTREE_TEXT_ENCODING 5
9199 #define BTREE_USER_VERSION 6
9200 #define BTREE_INCR_VACUUM 7
9201 #define BTREE_APPLICATION_ID 8
 
9202
9203 /*
9204 ** Values that may be OR'd together to form the second argument of an
9205 ** sqlite3BtreeCursorHints() call.
9206 */
@@ -9978,10 +10022,11 @@
9978 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
9979 #endif
9980
9981 /* Functions used to query pager state and configuration. */
9982 SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
 
9983 SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
9984 SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
9985 SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
9986 SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
9987 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
@@ -10719,10 +10764,11 @@
10719 i64 szMmap; /* Default mmap_size setting */
10720 unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
10721 int errCode; /* Most recent error code (SQLITE_*) */
10722 int errMask; /* & result codes with this before returning */
10723 u16 dbOptFlags; /* Flags to enable/disable optimizations */
 
10724 u8 autoCommit; /* The auto-commit flag. */
10725 u8 temp_store; /* 1: file 2: memory 0: default */
10726 u8 mallocFailed; /* True if we have seen a malloc failure */
10727 u8 dfltLockMode; /* Default locking-mode for attached dbs */
10728 signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
@@ -10820,11 +10866,12 @@
10820 };
10821
10822 /*
10823 ** A macro to discover the encoding of a database.
10824 */
10825 #define ENC(db) ((db)->aDb[0].pSchema->enc)
 
10826
10827 /*
10828 ** Possible values for the sqlite3.flags.
10829 */
10830 #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
@@ -11444,11 +11491,10 @@
11444 Index *pNext; /* The next index associated with the same table */
11445 Schema *pSchema; /* Schema containing this index */
11446 u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
11447 char **azColl; /* Array of collation sequence names for index */
11448 Expr *pPartIdxWhere; /* WHERE clause for partial indices */
11449 KeyInfo *pKeyInfo; /* A KeyInfo object suitable for this index */
11450 int tnum; /* DB Page containing root of this index */
11451 LogEst szIdxRow; /* Estimated average row size in bytes */
11452 u16 nKeyCol; /* Number of columns forming the key */
11453 u16 nColumn; /* Number of columns stored in the index */
11454 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
@@ -11675,11 +11721,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 +11741,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 */
@@ -12497,10 +12544,11 @@
12497 void *pPage; /* Page cache memory */
12498 int szPage; /* Size of each page in pPage[] */
12499 int nPage; /* Number of pages in pPage[] */
12500 int mxParserStack; /* maximum depth of the parser stack */
12501 int sharedCacheEnabled; /* true if shared-cache mode enabled */
 
12502 /* The above might be initialized to non-zero. The following need to always
12503 ** initially be zero, however. */
12504 int isInit; /* True after initialization has finished */
12505 int inProgress; /* True while initialization in progress */
12506 int isMutexInit; /* True after mutexes are initialized */
@@ -13419,11 +13467,11 @@
13419 ** print I/O tracing messages.
13420 */
13421 #ifdef SQLITE_ENABLE_IOTRACE
13422 # define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
13423 SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
13424 SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
13425 #else
13426 # define IOTRACE(A)
13427 # define sqlite3VdbeIOTraceSql(X)
13428 #endif
13429
@@ -13632,10 +13680,17 @@
13632 */
13633 #ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
13634 # define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
13635 #endif
13636
 
 
 
 
 
 
 
13637 /*
13638 ** The following singleton contains the global configuration for
13639 ** the SQLite library.
13640 */
13641 SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
@@ -13662,10 +13717,11 @@
13662 (void*)0, /* pPage */
13663 0, /* szPage */
13664 0, /* nPage */
13665 0, /* mxParserStack */
13666 0, /* sharedCacheEnabled */
 
13667 /* All the rest should always be initialized to zero */
13668 0, /* isInit */
13669 0, /* inProgress */
13670 0, /* isMutexInit */
13671 0, /* isMallocInit */
@@ -19947,10 +20003,16 @@
19947 #endif
19948 }
19949 break;
19950 }
19951 default: {
 
 
 
 
 
 
19952 assert( iType-2 >= 0 );
19953 assert( iType-2 < ArraySize(winMutex_staticMutexes) );
19954 assert( winMutex_isInit==1 );
19955 p = &winMutex_staticMutexes[iType-2];
19956 #ifdef SQLITE_DEBUG
@@ -28754,28 +28816,31 @@
28754 do{
28755 err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
28756 }while( err==EINTR );
28757 if( err ) return SQLITE_IOERR_WRITE;
28758 #else
28759 /* If the OS does not have posix_fallocate(), fake it. First use
28760 ** ftruncate() to set the file size, then write a single byte to
28761 ** the last byte in each block within the extended region. This
28762 ** is the same technique used by glibc to implement posix_fallocate()
28763 ** on systems that do not have a real fallocate() system call.
 
28764 */
28765 int nBlk = buf.st_blksize; /* File-system block size */
28766 i64 iWrite; /* Next offset to write to */
28767
28768 if( robust_ftruncate(pFile->h, nSize) ){
28769 pFile->lastErrno = errno;
28770 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
28771 }
28772 iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
28773 while( iWrite<nSize ){
 
 
 
28774 int nWrite = seekAndWrite(pFile, iWrite, "", 1);
28775 if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
28776 iWrite += nBlk;
 
 
 
28777 }
28778 #endif
28779 }
28780 }
28781
@@ -33989,12 +34054,12 @@
33989 */
33990 SQLITE_API int sqlite3_win32_reset_heap(){
33991 int rc;
33992 MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
33993 MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
33994 MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
33995 MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
33996 sqlite3_mutex_enter(pMaster);
33997 sqlite3_mutex_enter(pMem);
33998 winMemAssertMagic();
33999 if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
34000 /*
@@ -35265,11 +35330,11 @@
35265 sqlite3_file *id, /* File to read from */
35266 void *pBuf, /* Write content into this buffer */
35267 int amt, /* Number of bytes to read */
35268 sqlite3_int64 offset /* Begin reading at this offset */
35269 ){
35270 #if !SQLITE_OS_WINCE
35271 OVERLAPPED overlapped; /* The offset for ReadFile. */
35272 #endif
35273 winFile *pFile = (winFile*)id; /* file handle */
35274 DWORD nRead; /* Number of bytes actually read from file */
35275 int nRetry = 0; /* Number of retrys */
@@ -35297,11 +35362,11 @@
35297 offset += nCopy;
35298 }
35299 }
35300 #endif
35301
35302 #if SQLITE_OS_WINCE
35303 if( winSeekFile(pFile, offset) ){
35304 OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
35305 return SQLITE_FULL;
35306 }
35307 while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
@@ -35369,32 +35434,32 @@
35369 offset += nCopy;
35370 }
35371 }
35372 #endif
35373
35374 #if SQLITE_OS_WINCE
35375 rc = winSeekFile(pFile, offset);
35376 if( rc==0 ){
35377 #else
35378 {
35379 #endif
35380 #if !SQLITE_OS_WINCE
35381 OVERLAPPED overlapped; /* The offset for WriteFile. */
35382 #endif
35383 u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
35384 int nRem = amt; /* Number of bytes yet to be written */
35385 DWORD nWrite; /* Bytes written by each WriteFile() call */
35386 DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */
35387
35388 #if !SQLITE_OS_WINCE
35389 memset(&overlapped, 0, sizeof(OVERLAPPED));
35390 overlapped.Offset = (LONG)(offset & 0xffffffff);
35391 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
35392 #endif
35393
35394 while( nRem>0 ){
35395 #if SQLITE_OS_WINCE
35396 if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
35397 #else
35398 if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
35399 #endif
35400 if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
@@ -35403,11 +35468,11 @@
35403 assert( nWrite==0 || nWrite<=(DWORD)nRem );
35404 if( nWrite==0 || nWrite>(DWORD)nRem ){
35405 lastErrno = osGetLastError();
35406 break;
35407 }
35408 #if !SQLITE_OS_WINCE
35409 offset += nWrite;
35410 overlapped.Offset = (LONG)(offset & 0xffffffff);
35411 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
35412 #endif
35413 aRem += nWrite;
@@ -38949,11 +39014,12 @@
38949 SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
38950 assert( pCache->nRef==0 && pCache->pDirty==0 );
38951 if( pCache->szPage ){
38952 sqlite3_pcache *pNew;
38953 pNew = sqlite3GlobalConfig.pcache2.xCreate(
38954 szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
 
38955 );
38956 if( pNew==0 ) return SQLITE_NOMEM;
38957 sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
38958 if( pCache->pCache ){
38959 sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
@@ -39408,11 +39474,11 @@
39408
39409 /*
39410 ** Return the size of the header added by this middleware layer
39411 ** in the page-cache hierarchy.
39412 */
39413 SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return sizeof(PgHdr); }
39414
39415
39416 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
39417 /*
39418 ** For all dirty pages currently in the cache, invoke the specified
@@ -39724,11 +39790,11 @@
39724 pcache1Free(pPg);
39725 sqlite3_free(p);
39726 pPg = 0;
39727 }
39728 #else
39729 pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
39730 p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
39731 #endif
39732 pcache1EnterMutex(pCache->pGroup);
39733
39734 if( pPg ){
@@ -40412,11 +40478,11 @@
40412 }
40413
40414 /*
40415 ** Return the size of the header on each page of this PCACHE implementation.
40416 */
40417 SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return sizeof(PgHdr1); }
40418
40419 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
40420 /*
40421 ** This function is called to free superfluous dynamically allocated memory
40422 ** held by the pager system. Memory in use by any SQLite pager allocated
@@ -41770,10 +41836,12 @@
41770 u8 eLock; /* Current lock held on database file */
41771 u8 changeCountDone; /* Set after incrementing the change-counter */
41772 u8 setMaster; /* True if a m-j name has been written to jrnl */
41773 u8 doNotSpill; /* Do not spill the cache when non-zero */
41774 u8 subjInMemory; /* True to use in-memory sub-journals */
 
 
41775 Pgno dbSize; /* Number of pages in the database */
41776 Pgno dbOrigSize; /* dbSize before the current transaction */
41777 Pgno dbFileSize; /* Number of pages in the database file */
41778 Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */
41779 int errCode; /* One of several kinds of errors */
@@ -41787,13 +41855,13 @@
41787 i64 journalOff; /* Current write offset in the journal file */
41788 i64 journalHdr; /* Byte offset to previous journal header */
41789 sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
41790 PagerSavepoint *aSavepoint; /* Array of active savepoints */
41791 int nSavepoint; /* Number of elements in aSavepoint[] */
 
41792 char dbFileVers[16]; /* Changes whenever database file changes */
41793
41794 u8 bUseFetch; /* True to use xFetch() */
41795 int nMmapOut; /* Number of mmap pages currently outstanding */
41796 sqlite3_int64 szMmap; /* Desired maximum mmap size */
41797 PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
41798 /*
41799 ** End of the routinely-changing class members
@@ -42805,13 +42873,22 @@
42805
42806 /*
42807 ** Discard the entire contents of the in-memory page-cache.
42808 */
42809 static void pager_reset(Pager *pPager){
 
42810 sqlite3BackupRestart(pPager->pBackup);
42811 sqlite3PcacheClear(pPager->pPCache);
42812 }
 
 
 
 
 
 
 
 
42813
42814 /*
42815 ** Free all structures in the Pager.aSavepoint[] array and set both
42816 ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
42817 ** if it is open and the pager is not in exclusive mode.
@@ -45011,11 +45088,11 @@
45011 Pgno pgno, /* Page number */
45012 void *pData, /* xFetch()'d data for this page */
45013 PgHdr **ppPage /* OUT: Acquired page object */
45014 ){
45015 PgHdr *p; /* Memory mapped page to return */
45016
45017 if( pPager->pMmapFreelist ){
45018 *ppPage = p = pPager->pMmapFreelist;
45019 pPager->pMmapFreelist = p->pDirty;
45020 p->pDirty = 0;
45021 memset(p->pExtra, 0, pPager->nExtra);
@@ -46242,20 +46319,16 @@
46242 assert( (pPager->eLock==SHARED_LOCK)
46243 || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
46244 );
46245 }
46246
46247 if( !pPager->tempFile && (
46248 pPager->pBackup
46249 || sqlite3PcachePagecount(pPager->pPCache)>0
46250 || USEFETCH(pPager)
46251 )){
46252 /* The shared-lock has just been acquired on the database file
46253 ** and there are already pages in the cache (from a previous
46254 ** read or write transaction). Check to see if the database
46255 ** has been modified. If the database has changed, flush the
46256 ** cache.
46257 **
46258 ** Database changes is detected by looking at 15 bytes beginning
46259 ** at offset 24 into the file. The first 4 of these 16 bytes are
46260 ** a 32-bit counter that is incremented with each change. The
46261 ** other bytes change randomly with each file change when
@@ -46416,10 +46489,11 @@
46416 assert( noContent==0 || bMmapOk==0 );
46417
46418 if( pgno==0 ){
46419 return SQLITE_CORRUPT_BKPT;
46420 }
 
46421
46422 /* If the pager is in the error state, return an error immediately.
46423 ** Otherwise, request the page from the PCache layer. */
46424 if( pPager->errCode!=SQLITE_OK ){
46425 rc = pPager->errCode;
@@ -46565,10 +46639,11 @@
46565 sqlite3_pcache_page *pPage;
46566 assert( pPager!=0 );
46567 assert( pgno!=0 );
46568 assert( pPager->pPCache!=0 );
46569 pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
 
46570 return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
46571 }
46572
46573 /*
46574 ** Release a page reference.
@@ -47431,10 +47506,11 @@
47431 pPager->eState = PAGER_READER;
47432 return SQLITE_OK;
47433 }
47434
47435 PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
 
47436 rc = pager_end_transaction(pPager, pPager->setMaster, 1);
47437 return pager_error(pPager, rc);
47438 }
47439
47440 /*
@@ -48199,11 +48275,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 +50086,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 +50153,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 +50167,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 +50181,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 +50272,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
@@ -50747,11 +50876,11 @@
50747 }
50748 nCollide = HASHTABLE_NSLOT;
50749 for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
50750 u32 iFrame = aHash[iKey] + iZero;
50751 if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
50752 /* assert( iFrame>iRead ); -- not true if there is corruption */
50753 iRead = iFrame;
50754 }
50755 if( (nCollide--)==0 ){
50756 return SQLITE_CORRUPT_BKPT;
50757 }
@@ -50960,11 +51089,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 +51121,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 +51410,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 +51422,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 +51483,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;
@@ -51852,10 +51982,11 @@
51852 u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
51853 u8 sharable; /* True if we can share pBt with another db */
51854 u8 locked; /* True if db currently has pBt locked */
51855 int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
51856 int nBackup; /* Number of backup operations reading this btree */
 
51857 Btree *pNext; /* List of other sharable Btrees from the same db */
51858 Btree *pPrev; /* Back pointer of the same list */
51859 #ifndef SQLITE_OMIT_SHARED_CACHE
51860 BtLock lock; /* Object used to lock page 1 */
51861 #endif
@@ -53821,11 +53952,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 }
@@ -56015,10 +56146,11 @@
56015 rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
56016 if( rc!=SQLITE_OK && bCleanup==0 ){
56017 sqlite3BtreeLeave(p);
56018 return rc;
56019 }
 
56020 pBt->inTransaction = TRANS_READ;
56021 btreeClearHasContent(pBt);
56022 }
56023
56024 btreeEndTransaction(p);
@@ -56378,11 +56510,11 @@
56378 }
56379 for(i=0; i<=pCur->iPage; i++){
56380 releasePage(pCur->apPage[i]);
56381 }
56382 unlockBtreeIfUnused(pBt);
56383 sqlite3DbFree(pBtree->db, pCur->aOverflow);
56384 /* sqlite3_free(pCur); */
56385 sqlite3BtreeLeave(pBtree);
56386 }
56387 return SQLITE_OK;
56388 }
@@ -56672,10 +56804,11 @@
56672 pBuf += a;
56673 amt -= a;
56674 }else{
56675 offset -= pCur->info.nLocal;
56676 }
 
56677
56678 if( rc==SQLITE_OK && amt>0 ){
56679 const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */
56680 Pgno nextPage;
56681
@@ -56690,12 +56823,12 @@
56690 ** means "not yet known" (the cache is lazily populated).
56691 */
56692 if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
56693 int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
56694 if( nOvfl>pCur->nOvflAlloc ){
56695 Pgno *aNew = (Pgno*)sqlite3DbRealloc(
56696 pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno)
56697 );
56698 if( aNew==0 ){
56699 rc = SQLITE_NOMEM;
56700 }else{
56701 pCur->nOvflAlloc = nOvfl*2;
@@ -56738,10 +56871,11 @@
56738 ** Note that the aOverflow[] array must be allocated because eOp!=2
56739 ** here. If eOp==2, then offset==0 and this branch is never taken.
56740 */
56741 assert( eOp!=2 );
56742 assert( pCur->curFlags & BTCF_ValidOvfl );
 
56743 if( pCur->aOverflow[iIdx+1] ){
56744 nextPage = pCur->aOverflow[iIdx+1];
56745 }else{
56746 rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
56747 }
@@ -58881,11 +59015,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 */
@@ -59250,11 +59384,11 @@
59250 + nMaxCells*sizeof(u16) /* szCell */
59251 + pBt->pageSize; /* aSpace1 */
59252
59253 /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
59254 ** that is more than 6 times the database page size. */
59255 assert( szScratch<=6*pBt->pageSize );
59256 apCell = sqlite3ScratchMalloc( szScratch );
59257 if( apCell==0 ){
59258 rc = SQLITE_NOMEM;
59259 goto balance_cleanup;
59260 }
@@ -59324,11 +59458,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 +59697,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);
@@ -60632,10 +60774,17 @@
60632 ** is read-only, the others are read/write.
60633 **
60634 ** The schema layer numbers meta values differently. At the schema
60635 ** layer (and the SetCookie and ReadCookie opcodes) the number of
60636 ** free pages is not visible. So Cookie[0] is the same as Meta[1].
 
 
 
 
 
 
 
60637 */
60638 SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
60639 BtShared *pBt = p->pBt;
60640
60641 sqlite3BtreeEnter(p);
@@ -60642,11 +60791,15 @@
60642 assert( p->inTrans>TRANS_NONE );
60643 assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
60644 assert( pBt->pPage1 );
60645 assert( idx>=0 && idx<=15 );
60646
60647 *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
 
 
 
 
60648
60649 /* If auto-vacuum is disabled in this build and this is an auto-vacuum
60650 ** database, mark the database as read-only. */
60651 #ifdef SQLITE_OMIT_AUTOVACUUM
60652 if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){
@@ -60733,11 +60886,11 @@
60733 if( pPage->leaf ){
60734 do {
60735 if( pCur->iPage==0 ){
60736 /* All pages of the b-tree have been visited. Return successfully. */
60737 *pnEntry = nEntry;
60738 return SQLITE_OK;
60739 }
60740 moveToParent(pCur);
60741 }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
60742
60743 pCur->aiIdx[pCur->iPage]++;
@@ -61589,11 +61742,11 @@
61589 }
61590
61591 /*
61592 ** Return the size of the header added to each page by this module.
61593 */
61594 SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return sizeof(MemPage); }
61595
61596 /************** End of btree.c ***********************************************/
61597 /************** Begin file backup.c ******************************************/
61598 /*
61599 ** 2009 January 28
@@ -64353,36 +64506,39 @@
64353 **
64354 ** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
64355 */
64356 SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
64357 int hasAbort = 0;
 
64358 Op *pOp;
64359 VdbeOpIter sIter;
64360 memset(&sIter, 0, sizeof(sIter));
64361 sIter.v = v;
64362
64363 while( (pOp = opIterNext(&sIter))!=0 ){
64364 int opcode = pOp->opcode;
64365 if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
64366 #ifndef SQLITE_OMIT_FOREIGN_KEY
64367 || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
64368 #endif
64369 || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
64370 && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
64371 ){
64372 hasAbort = 1;
64373 break;
64374 }
 
 
 
 
 
64375 }
64376 sqlite3DbFree(v->db, sIter.apSub);
64377
64378 /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred.
64379 ** If malloc failed, then the while() loop above may not have iterated
64380 ** through all opcodes and hasAbort may be set incorrectly. Return
64381 ** true for this case to prevent the assert() in the callers frame
64382 ** from failing. */
64383 return ( v->db->mallocFailed || hasAbort==mayAbort );
64384 }
64385 #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
64386
64387 /*
64388 ** Loop through the program looking for P2 values that are negative
@@ -65699,11 +65855,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 ){
@@ -68502,11 +68658,14 @@
68502 #ifndef SQLITE_OMIT_WAL
68503 int i;
68504 for(i=0; i<db->nDb; i++){
68505 Btree *pBt = db->aDb[i].pBt;
68506 if( pBt ){
68507 int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
 
 
 
68508 if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
68509 rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
68510 }
68511 }
68512 }
@@ -68682,11 +68841,10 @@
68682 ** program counter to 0 to ensure that when the statement is
68683 ** finalized or reset the parser error message is available via
68684 ** sqlite3_errmsg() and sqlite3_errcode().
68685 */
68686 const char *zErr = (const char *)sqlite3_value_text(db->pErr);
68687 assert( zErr!=0 || db->mallocFailed );
68688 sqlite3DbFree(db, v->zErrMsg);
68689 if( !db->mallocFailed ){
68690 v->zErrMsg = sqlite3DbStrDup(db, zErr);
68691 v->rc = rc2;
68692 } else {
@@ -75629,12 +75787,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 +75806,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;
@@ -77043,11 +77202,11 @@
77043 /*
77044 ** Hard-coded maximum amount of data to accumulate in memory before flushing
77045 ** to a level 0 PMA. The purpose of this limit is to prevent various integer
77046 ** overflows. 512MiB.
77047 */
77048 #define SQLITE_MAX_MXPMASIZE (1<<29)
77049
77050 /*
77051 ** Private objects used by the sorter
77052 */
77053 typedef struct MergeEngine MergeEngine; /* Merge PMAs together */
@@ -77339,13 +77498,10 @@
77339 **
77340 ** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
77341 */
77342 #define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
77343
77344 /* The minimum PMA size is set to this value multiplied by the database
77345 ** page size in bytes. */
77346 #define SORTER_MIN_WORKING 10
77347
77348 /* Maximum number of PMAs that a single MergeEngine can merge */
77349 #define SORTER_MAX_MERGE_COUNT 16
77350
77351 static int vdbeIncrSwap(IncrMerger*);
@@ -77740,14 +77896,15 @@
77740 SortSubtask *pTask = &pSorter->aTask[i];
77741 pTask->pSorter = pSorter;
77742 }
77743
77744 if( !sqlite3TempInMemory(db) ){
77745 pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
 
77746 mxCache = db->aDb[0].pSchema->cache_size;
77747 if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
77748 pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);
77749
77750 /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
77751 ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
77752 ** large heap allocations.
77753 */
@@ -78021,16 +78178,16 @@
78021 ** Whether or not the file does end up memory mapped of course depends on
78022 ** the specific VFS implementation.
78023 */
78024 static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
78025 if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){
78026 int rc = sqlite3OsTruncate(pFd, nByte);
78027 if( rc==SQLITE_OK ){
78028 void *p = 0;
78029 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
78030 sqlite3OsUnfetch(pFd, 0, p);
78031 }
78032 }
78033 }
78034 #else
78035 # define vdbeSorterExtendFile(x,y,z)
78036 #endif
@@ -80411,10 +80568,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 +83129,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
@@ -87203,11 +87365,11 @@
87203
87204 p->iGet = -1;
87205 p->mxSample = mxSample;
87206 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
87207 p->current.anLt = &p->current.anEq[nColUp];
87208 p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565;
87209
87210 /* Set up the Stat4Accum.a[] and aBest[] arrays */
87211 p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
87212 p->aBest = &p->a[mxSample];
87213 pSpace = (u8*)(&p->a[mxSample+nCol]);
@@ -88351,11 +88513,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];
@@ -88796,17 +88958,19 @@
88796 }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
88797 zErrDyn = sqlite3MPrintf(db,
88798 "attached databases must use the same text encoding as main database");
88799 rc = SQLITE_ERROR;
88800 }
 
88801 pPager = sqlite3BtreePager(aNew->pBt);
88802 sqlite3PagerLockingMode(pPager, db->dfltLockMode);
88803 sqlite3BtreeSecureDelete(aNew->pBt,
88804 sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
88805 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
88806 sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
88807 #endif
 
88808 }
88809 aNew->safety_level = 3;
88810 aNew->zName = sqlite3DbStrDup(db, zName);
88811 if( rc==SQLITE_OK && aNew->zName==0 ){
88812 rc = SQLITE_NOMEM;
@@ -89928,11 +90092,10 @@
89928 */
89929 static void freeIndex(sqlite3 *db, Index *p){
89930 #ifndef SQLITE_OMIT_ANALYZE
89931 sqlite3DeleteIndexSamples(db, p);
89932 #endif
89933 if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
89934 sqlite3ExprDelete(db, p->pPartIdxWhere);
89935 sqlite3DbFree(db, p->zColAff);
89936 if( p->isResized ) sqlite3DbFree(db, p->azColl);
89937 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
89938 sqlite3_free(p->aiRowEst);
@@ -91207,10 +91370,23 @@
91207 if( pPk==0 ) return;
91208 pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
91209 pTab->iPKey = -1;
91210 }else{
91211 pPk = sqlite3PrimaryKeyIndex(pTab);
 
 
 
 
 
 
 
 
 
 
 
 
 
91212 }
91213 pPk->isCovering = 1;
91214 assert( pPk!=0 );
91215 nPk = pPk->nKeyCol;
91216
@@ -93683,44 +93859,35 @@
93683 **
93684 ** The caller should invoke sqlite3KeyInfoUnref() on the returned object
93685 ** when it has finished using it.
93686 */
93687 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
 
 
 
 
93688 if( pParse->nErr ) return 0;
93689 #ifndef SQLITE_OMIT_SHARED_CACHE
93690 if( pIdx->pKeyInfo && pIdx->pKeyInfo->db!=pParse->db ){
93691 sqlite3KeyInfoUnref(pIdx->pKeyInfo);
93692 pIdx->pKeyInfo = 0;
93693 }
93694 #endif
93695 if( pIdx->pKeyInfo==0 ){
93696 int i;
93697 int nCol = pIdx->nColumn;
93698 int nKey = pIdx->nKeyCol;
93699 KeyInfo *pKey;
93700 if( pIdx->uniqNotNull ){
93701 pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
93702 }else{
93703 pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
93704 }
93705 if( pKey ){
93706 assert( sqlite3KeyInfoIsWriteable(pKey) );
93707 for(i=0; i<nCol; i++){
93708 char *zColl = pIdx->azColl[i];
93709 assert( zColl!=0 );
93710 pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
93711 sqlite3LocateCollSeq(pParse, zColl);
93712 pKey->aSortOrder[i] = pIdx->aSortOrder[i];
93713 }
93714 if( pParse->nErr ){
93715 sqlite3KeyInfoUnref(pKey);
93716 }else{
93717 pIdx->pKeyInfo = pKey;
93718 }
93719 }
93720 }
93721 return sqlite3KeyInfoRef(pIdx->pKeyInfo);
93722 }
93723
93724 #ifndef SQLITE_OMIT_CTE
93725 /*
93726 ** This routine is invoked once per CTE by the parser while parsing a
@@ -97337,11 +97504,11 @@
97337 assert( nIncr==1 );
97338 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
97339 OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
97340 }else{
97341 if( nIncr>0 && pFKey->isDeferred==0 ){
97342 sqlite3ParseToplevel(pParse)->mayAbort = 1;
97343 }
97344 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
97345 }
97346
97347 sqlite3VdbeResolveLabel(v, iOk);
@@ -97408,10 +97575,14 @@
97408 ** This function is called to generate code executed when a row is deleted
97409 ** from the parent table of foreign key constraint pFKey and, if pFKey is
97410 ** deferred, when a row is inserted into the same table. When generating
97411 ** code for an SQL UPDATE operation, this function may be called twice -
97412 ** once to "delete" the old row and once to "insert" the new row.
 
 
 
 
97413 **
97414 ** The code generated by this function scans through the rows in the child
97415 ** table that correspond to the parent table row being deleted or inserted.
97416 ** For each child row found, one of the following actions is taken:
97417 **
@@ -97525,17 +97696,13 @@
97525 sNameContext.pSrcList = pSrc;
97526 sNameContext.pParse = pParse;
97527 sqlite3ResolveExprNames(&sNameContext, pWhere);
97528
97529 /* Create VDBE to loop through the entries in pSrc that match the WHERE
97530 ** clause. If the constraint is not deferred, throw an exception for
97531 ** each row found. Otherwise, for deferred constraints, increment the
97532 ** deferred constraint counter by nIncr for each row selected. */
97533 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
97534 if( nIncr>0 && pFKey->isDeferred==0 ){
97535 sqlite3ParseToplevel(pParse)->mayAbort = 1;
97536 }
97537 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
97538 if( pWInfo ){
97539 sqlite3WhereEnd(pWInfo);
97540 }
97541
@@ -97709,10 +97876,28 @@
97709 }
97710 }
97711 }
97712 return 0;
97713 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97714
97715 /*
97716 ** This function is called when inserting, deleting or updating a row of
97717 ** table pTab to generate VDBE code to perform foreign key constraint
97718 ** processing for the operation.
@@ -97762,11 +97947,11 @@
97762 Index *pIdx = 0; /* Index on key columns in pTo */
97763 int *aiFree = 0;
97764 int *aiCol;
97765 int iCol;
97766 int i;
97767 int isIgnore = 0;
97768
97769 if( aChange
97770 && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
97771 && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
97772 ){
@@ -97821,11 +98006,11 @@
97821 ** values read from the parent table are NULL. */
97822 if( db->xAuth ){
97823 int rcauth;
97824 char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
97825 rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
97826 isIgnore = (rcauth==SQLITE_IGNORE);
97827 }
97828 #endif
97829 }
97830
97831 /* Take a shared-cache advisory read-lock on the parent table. Allocate
@@ -97836,16 +98021,22 @@
97836
97837 if( regOld!=0 ){
97838 /* A row is being removed from the child table. Search for the parent.
97839 ** If the parent does not exist, removing the child row resolves an
97840 ** outstanding foreign key constraint violation. */
97841 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
97842 }
97843 if( regNew!=0 ){
97844 /* A row is being added to the child table. If a parent row cannot
97845 ** be found, adding the child row has violated the FK constraint. */
97846 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
 
 
 
 
 
 
97847 }
97848
97849 sqlite3DbFree(db, aiFree);
97850 }
97851
@@ -97862,12 +98053,12 @@
97862
97863 if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
97864 && !pParse->pToplevel && !pParse->isMultiWrite
97865 ){
97866 assert( regOld==0 && regNew!=0 );
97867 /* Inserting a single row into a parent table cannot cause an immediate
97868 ** foreign key violation. So do nothing in this case. */
97869 continue;
97870 }
97871
97872 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
97873 if( !isIgnoreErrors || db->mallocFailed ) return;
@@ -97887,17 +98078,32 @@
97887
97888 if( regNew!=0 ){
97889 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
97890 }
97891 if( regOld!=0 ){
97892 /* If there is a RESTRICT action configured for the current operation
97893 ** on the parent table of this FK, then throw an exception
97894 ** immediately if the FK constraint is violated, even if this is a
97895 ** deferred trigger. That's what RESTRICT means. To defer checking
97896 ** the constraint, the FK should specify NO ACTION (represented
97897 ** using OE_None). NO ACTION is the default. */
97898 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97899 }
97900 pItem->zName = 0;
97901 sqlite3SrcListDelete(db, pSrc);
97902 }
97903 sqlite3DbFree(db, aiCol);
@@ -100987,11 +101193,10 @@
100987 # define sqlite3_column_database_name16 0
100988 # define sqlite3_column_table_name 0
100989 # define sqlite3_column_table_name16 0
100990 # define sqlite3_column_origin_name 0
100991 # define sqlite3_column_origin_name16 0
100992 # define sqlite3_table_column_metadata 0
100993 #endif
100994
100995 #ifdef SQLITE_OMIT_AUTHORIZATION
100996 # define sqlite3_set_authorizer 0
100997 #endif
@@ -101797,10 +102002,11 @@
101797 #define PragTyp_KEY 38
101798 #define PragTyp_REKEY 39
101799 #define PragTyp_LOCK_STATUS 40
101800 #define PragTyp_PARSER_TRACE 41
101801 #define PragFlag_NeedSchema 0x01
 
101802 static const struct sPragmaNames {
101803 const char *const zName; /* Name of pragma */
101804 u8 ePragTyp; /* PragTyp_XXX value */
101805 u8 mPragFlag; /* Zero or more PragFlag_XXX values */
101806 u32 iArg; /* Extra argument */
@@ -101813,11 +102019,11 @@
101813 #endif
101814 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
101815 { /* zName: */ "application_id",
101816 /* ePragTyp: */ PragTyp_HEADER_VALUE,
101817 /* ePragFlag: */ 0,
101818 /* iArg: */ 0 },
101819 #endif
101820 #if !defined(SQLITE_OMIT_AUTOVACUUM)
101821 { /* zName: */ "auto_vacuum",
101822 /* ePragTyp: */ PragTyp_AUTO_VACUUM,
101823 /* ePragFlag: */ PragFlag_NeedSchema,
@@ -101879,10 +102085,16 @@
101879 { /* zName: */ "data_store_directory",
101880 /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
101881 /* ePragFlag: */ 0,
101882 /* iArg: */ 0 },
101883 #endif
 
 
 
 
 
 
101884 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
101885 { /* zName: */ "database_list",
101886 /* ePragTyp: */ PragTyp_DATABASE_LIST,
101887 /* ePragFlag: */ PragFlag_NeedSchema,
101888 /* iArg: */ 0 },
@@ -101934,12 +102146,12 @@
101934 #endif
101935 #endif
101936 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
101937 { /* zName: */ "freelist_count",
101938 /* ePragTyp: */ PragTyp_HEADER_VALUE,
101939 /* ePragFlag: */ 0,
101940 /* iArg: */ 0 },
101941 #endif
101942 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
101943 { /* zName: */ "full_column_names",
101944 /* ePragTyp: */ PragTyp_FLAG,
101945 /* ePragFlag: */ 0,
@@ -102087,11 +102299,11 @@
102087 #endif
102088 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102089 { /* zName: */ "schema_version",
102090 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102091 /* ePragFlag: */ 0,
102092 /* iArg: */ 0 },
102093 #endif
102094 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
102095 { /* zName: */ "secure_delete",
102096 /* ePragTyp: */ PragTyp_SECURE_DELETE,
102097 /* ePragFlag: */ 0,
@@ -102153,11 +102365,11 @@
102153 /* iArg: */ 0 },
102154 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102155 { /* zName: */ "user_version",
102156 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102157 /* ePragFlag: */ 0,
102158 /* iArg: */ 0 },
102159 #endif
102160 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
102161 #if defined(SQLITE_DEBUG)
102162 { /* zName: */ "vdbe_addoptrace",
102163 /* ePragTyp: */ PragTyp_FLAG,
@@ -102196,11 +102408,11 @@
102196 /* ePragTyp: */ PragTyp_FLAG,
102197 /* ePragFlag: */ 0,
102198 /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
102199 #endif
102200 };
102201 /* Number of pragmas: 57 on by default, 70 total. */
102202 /* End of the automatically generated pragma table.
102203 ***************************************************************************/
102204
102205 /*
102206 ** Interpret the given string as a safety level. Return 0 for OFF,
@@ -103806,11 +104018,12 @@
103806 !(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
103807 DbHasProperty(db, 0, DB_Empty)
103808 ){
103809 for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
103810 if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
103811 ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
 
103812 break;
103813 }
103814 }
103815 if( !pEnc->zName ){
103816 sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
@@ -103851,28 +104064,13 @@
103851 **
103852 ** The user-version is not used internally by SQLite. It may be used by
103853 ** applications for any purpose.
103854 */
103855 case PragTyp_HEADER_VALUE: {
103856 int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
103857 sqlite3VdbeUsesBtree(v, iDb);
103858 switch( zLeft[0] ){
103859 case 'a': case 'A':
103860 iCookie = BTREE_APPLICATION_ID;
103861 break;
103862 case 'f': case 'F':
103863 iCookie = BTREE_FREE_PAGE_COUNT;
103864 break;
103865 case 's': case 'S':
103866 iCookie = BTREE_SCHEMA_VERSION;
103867 break;
103868 default:
103869 iCookie = BTREE_USER_VERSION;
103870 break;
103871 }
103872
103873 if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
103874 /* Write the specified cookie value */
103875 static const VdbeOpList setCookie[] = {
103876 { OP_Transaction, 0, 1, 0}, /* 0 */
103877 { OP_Integer, 0, 1, 0}, /* 1 */
103878 { OP_SetCookie, 0, 0, 1}, /* 2 */
@@ -103921,11 +104119,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 +104131,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);
@@ -104512,13 +104712,15 @@
104512 SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
104513 int i, rc;
104514 int commit_internal = !(db->flags&SQLITE_InternChanges);
104515
104516 assert( sqlite3_mutex_held(db->mutex) );
 
104517 assert( db->init.busy==0 );
104518 rc = SQLITE_OK;
104519 db->init.busy = 1;
 
104520 for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
104521 if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
104522 rc = sqlite3InitOne(db, i, pzErrMsg);
104523 if( rc ){
104524 sqlite3ResetOneSchema(db, i);
@@ -109840,11 +110042,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 +110055,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 }
@@ -110657,11 +110858,11 @@
110657 ){
110658 int rc;
110659 TabResult res;
110660
110661 #ifdef SQLITE_ENABLE_API_ARMOR
110662 if( pazResult==0 ) return SQLITE_MISUSE_BKPT;
110663 #endif
110664 *pazResult = 0;
110665 if( pnColumn ) *pnColumn = 0;
110666 if( pnRow ) *pnRow = 0;
110667 if( pzErrMsg ) *pzErrMsg = 0;
@@ -114808,10 +115009,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 +117735,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 +118379,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);
@@ -118527,11 +118728,10 @@
118527 sqlite3_free(p->u.vtab.idxStr);
118528 p->u.vtab.needFree = 0;
118529 p->u.vtab.idxStr = 0;
118530 }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
118531 sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
118532 sqlite3KeyInfoUnref(p->u.btree.pIndex->pKeyInfo);
118533 sqlite3DbFree(db, p->u.btree.pIndex);
118534 p->u.btree.pIndex = 0;
118535 }
118536 }
118537 }
@@ -125534,10 +125734,13 @@
125534 u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
125535 sqlite3 *db = pParse->db; /* The database connection */
125536 int mxSqlLen; /* Max length of an SQL string */
125537
125538
 
 
 
125539 mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
125540 if( db->nVdbeActive==0 ){
125541 db->u1.isInterrupted = 0;
125542 }
125543 pParse->rc = SQLITE_OK;
@@ -125772,17 +125975,10 @@
125772 */
125773 SQLITE_API int sqlite3_complete(const char *zSql){
125774 u8 state = 0; /* Current state, using numbers defined in header comment */
125775 u8 token; /* Value of the next token */
125776
125777 #ifdef SQLITE_ENABLE_API_ARMOR
125778 if( zSql==0 ){
125779 (void)SQLITE_MISUSE_BKPT;
125780 return 0;
125781 }
125782 #endif
125783
125784 #ifndef SQLITE_OMIT_TRIGGER
125785 /* A complex statement machine used to detect the end of a CREATE TRIGGER
125786 ** statement. This is the normal case.
125787 */
125788 static const u8 trans[8][8] = {
@@ -125807,10 +126003,17 @@
125807 /* 0 INVALID: */ { 1, 0, 2, },
125808 /* 1 START: */ { 1, 1, 2, },
125809 /* 2 NORMAL: */ { 1, 2, 2, },
125810 };
125811 #endif /* SQLITE_OMIT_TRIGGER */
 
 
 
 
 
 
 
125812
125813 while( *zSql ){
125814 switch( *zSql ){
125815 case ';': { /* A semicolon */
125816 token = tkSEMI;
@@ -126109,11 +126312,11 @@
126109 ** If the following function pointer is not NULL and if
126110 ** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
126111 ** I/O active are written using this function. These messages
126112 ** are intended for debugging activity only.
126113 */
126114 SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0;
126115 #endif
126116
126117 /*
126118 ** If the following global variable points to a string which is the
126119 ** name of a directory, then that directory will be used to store
@@ -126318,10 +126521,17 @@
126318 ** routine is not threadsafe. But it is safe to invoke this routine
126319 ** on when SQLite is already shut down. If SQLite is already shut down
126320 ** when this routine is invoked, then this routine is a harmless no-op.
126321 */
126322 SQLITE_API int sqlite3_shutdown(void){
 
 
 
 
 
 
 
126323 if( sqlite3GlobalConfig.isInit ){
126324 #ifdef SQLITE_EXTRA_SHUTDOWN
126325 void SQLITE_EXTRA_SHUTDOWN(void);
126326 SQLITE_EXTRA_SHUTDOWN();
126327 #endif
@@ -126633,10 +126843,15 @@
126633 ** heap. */
126634 sqlite3GlobalConfig.nHeap = va_arg(ap, int);
126635 break;
126636 }
126637 #endif
 
 
 
 
 
126638
126639 default: {
126640 rc = SQLITE_ERROR;
126641 break;
126642 }
@@ -127983,14 +128198,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 +128232,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
@@ -128201,36 +128421,10 @@
128201 */
128202 SQLITE_API const char *sqlite3_errstr(int rc){
128203 return sqlite3ErrStr(rc);
128204 }
128205
128206 /*
128207 ** Invalidate all cached KeyInfo objects for database connection "db"
128208 */
128209 static void invalidateCachedKeyInfo(sqlite3 *db){
128210 Db *pDb; /* A single database */
128211 int iDb; /* The database index number */
128212 HashElem *k; /* For looping over tables in pDb */
128213 Table *pTab; /* A table in the database */
128214 Index *pIdx; /* Each index */
128215
128216 for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
128217 if( pDb->pBt==0 ) continue;
128218 sqlite3BtreeEnter(pDb->pBt);
128219 for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
128220 pTab = (Table*)sqliteHashData(k);
128221 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
128222 if( pIdx->pKeyInfo && pIdx->pKeyInfo->db==db ){
128223 sqlite3KeyInfoUnref(pIdx->pKeyInfo);
128224 pIdx->pKeyInfo = 0;
128225 }
128226 }
128227 }
128228 sqlite3BtreeLeave(pDb->pBt);
128229 }
128230 }
128231
128232 /*
128233 ** Create a new collating function for database "db". The name is zName
128234 ** and the encoding is enc.
128235 */
128236 static int createCollation(
@@ -128270,11 +128464,10 @@
128270 sqlite3ErrorWithMsg(db, SQLITE_BUSY,
128271 "unable to delete/modify collation sequence due to active statements");
128272 return SQLITE_BUSY;
128273 }
128274 sqlite3ExpirePreparedStatements(db);
128275 invalidateCachedKeyInfo(db);
128276
128277 /* If collation sequence pColl was created directly by a call to
128278 ** sqlite3_create_collation, and not generated by synthCollSeq(),
128279 ** then any copies made by synthCollSeq() need to be invalidated.
128280 ** Also, collation destructor - CollSeq.xDel() - function may need
@@ -128775,10 +128968,13 @@
128775 | SQLITE_RecTriggers
128776 #endif
128777 #if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
128778 | SQLITE_ForeignKeys
128779 #endif
 
 
 
128780 ;
128781 sqlite3HashInit(&db->aCollSeq);
128782 #ifndef SQLITE_OMIT_VIRTUALTABLE
128783 sqlite3HashInit(&db->aModule);
128784 #endif
@@ -128822,11 +129018,14 @@
128822 rc = SQLITE_NOMEM;
128823 }
128824 sqlite3Error(db, rc);
128825 goto opendb_out;
128826 }
 
128827 db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
 
 
128828 db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
128829
128830 /* The default safety_level for the main database is 'full'; for the temp
128831 ** database it is 'NONE'. This matches the pager layer defaults.
128832 */
@@ -128980,11 +129179,11 @@
128980 if( zFilename8 ){
128981 rc = openDatabase(zFilename8, ppDb,
128982 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
128983 assert( *ppDb || rc==SQLITE_NOMEM );
128984 if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
128985 ENC(*ppDb) = SQLITE_UTF16NATIVE;
128986 }
128987 }else{
128988 rc = SQLITE_NOMEM;
128989 }
128990 sqlite3ValueFree(pVal);
@@ -129176,11 +129375,10 @@
129176
129177 /*
129178 ** Return meta information about a specific column of a database table.
129179 ** See comment in sqlite3.h (sqlite.h.in) for details.
129180 */
129181 #ifdef SQLITE_ENABLE_COLUMN_METADATA
129182 SQLITE_API int sqlite3_table_column_metadata(
129183 sqlite3 *db, /* Connection handle */
129184 const char *zDbName, /* Database name or NULL */
129185 const char *zTableName, /* Table name */
129186 const char *zColumnName, /* Column name */
@@ -129216,25 +129414,27 @@
129216 pTab = 0;
129217 goto error_out;
129218 }
129219
129220 /* Find the column for which info is requested */
129221 if( sqlite3IsRowid(zColumnName) ){
129222 iCol = pTab->iPKey;
129223 if( iCol>=0 ){
129224 pCol = &pTab->aCol[iCol];
129225 }
129226 }else{
129227 for(iCol=0; iCol<pTab->nCol; iCol++){
129228 pCol = &pTab->aCol[iCol];
129229 if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
129230 break;
129231 }
129232 }
129233 if( iCol==pTab->nCol ){
129234 pTab = 0;
129235 goto error_out;
 
 
 
 
 
129236 }
129237 }
129238
129239 /* The following block stores the meta information that will be returned
129240 ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
@@ -129283,11 +129483,10 @@
129283 sqlite3DbFree(db, zErrMsg);
129284 rc = sqlite3ApiExit(db, rc);
129285 sqlite3_mutex_leave(db->mutex);
129286 return rc;
129287 }
129288 #endif
129289
129290 /*
129291 ** Sleep for a little while. Return the amount of time slept.
129292 */
129293 SQLITE_API int sqlite3_sleep(int ms){
@@ -129722,32 +129921,34 @@
129722 /*
129723 ** Return the filename of the database associated with a database
129724 ** connection.
129725 */
129726 SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
 
129727 #ifdef SQLITE_ENABLE_API_ARMOR
129728 if( !sqlite3SafetyCheckOk(db) ){
129729 (void)SQLITE_MISUSE_BKPT;
129730 return 0;
129731 }
129732 #endif
129733 Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
129734 return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
129735 }
129736
129737 /*
129738 ** Return 1 if database is read-only or 0 if read/write. Return -1 if
129739 ** no such database exists.
129740 */
129741 SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
 
129742 #ifdef SQLITE_ENABLE_API_ARMOR
129743 if( !sqlite3SafetyCheckOk(db) ){
129744 (void)SQLITE_MISUSE_BKPT;
129745 return -1;
129746 }
129747 #endif
129748 Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
129749 return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
129750 }
129751
129752 /************** End of main.c ************************************************/
129753 /************** Begin file notify.c ******************************************/
@@ -139164,11 +139365,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++; }
@@ -149954,11 +150155,11 @@
149954 }
149955 i = pCur->nPoint++;
149956 pNew = pCur->aPoint + i;
149957 pNew->rScore = rScore;
149958 pNew->iLevel = iLevel;
149959 assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH );
149960 while( i>0 ){
149961 RtreeSearchPoint *pParent;
149962 j = (i-1)/2;
149963 pParent = pCur->aPoint + j;
149964 if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break;
149965
--- 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 "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6"
237
238 /*
239 ** CAPI3REF: Run-Time Library Version Numbers
240 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
241 **
@@ -323,11 +323,11 @@
323 ** This interface only reports on the compile-time mutex setting
324 ** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
325 ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
326 ** can be fully or partially disabled using a call to [sqlite3_config()]
327 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
328 ** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the
329 ** sqlite3_threadsafe() function shows only the compile-time setting of
330 ** thread safety, not any run-time changes to that setting made by
331 ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
332 ** is unchanged by calls to sqlite3_config().)^
333 **
@@ -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,14 +1688,15 @@
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 65536) 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
1700 ** to [sqlite3_config()].
1701 ** ^It is harmless, apart from the wasted memory,
1702 ** for the sz parameter to be larger than necessary. The first
@@ -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,22 +1860,33 @@
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 **
1878 ** [[SQLITE_CONFIG_PMASZ]]
1879 ** <dt>SQLITE_CONFIG_PMASZ
1880 ** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
1881 ** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
1882 ** sorter to that integer. The default minimum PMA Size is set by the
1883 ** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched
1884 ** to help with sort operations when multithreaded sorting
1885 ** is enabled (using the [PRAGMA threads] command) and the amount of content
1886 ** to be sorted exceeds the page size times the minimum of the
1887 ** [PRAGMA cache_size] setting and this value.
1888 ** </dl>
1889 */
1890 #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
1891 #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
1892 #define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1895,10 +1909,11 @@
1909 #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
1910 #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
1911 #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
1912 #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
1913 #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
1914 #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
1915
1916 /*
1917 ** CAPI3REF: Database Connection Configuration Options
1918 **
1919 ** These constants are the available integer configuration options that
@@ -2171,10 +2186,11 @@
2186 SQLITE_API int sqlite3_complete(const char *sql);
2187 SQLITE_API int sqlite3_complete16(const void *sql);
2188
2189 /*
2190 ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
2191 ** KEYWORDS: {busy-handler callback} {busy handler}
2192 **
2193 ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
2194 ** that might be invoked with argument P whenever
2195 ** an attempt is made to access a database table associated with
2196 ** [database connection] D when another thread
@@ -2187,11 +2203,11 @@
2203 ** is not NULL, then the callback might be invoked with two arguments.
2204 **
2205 ** ^The first argument to the busy handler is a copy of the void* pointer which
2206 ** is the third argument to sqlite3_busy_handler(). ^The second argument to
2207 ** the busy handler callback is the number of times that the busy handler has
2208 ** been invoked previously for the same locking event. ^If the
2209 ** busy callback returns 0, then no additional attempts are made to
2210 ** access the database and [SQLITE_BUSY] is returned
2211 ** to the application.
2212 ** ^If the callback returns non-zero, then another attempt
2213 ** is made to access the database and the cycle repeats.
@@ -4642,11 +4658,12 @@
4658 ** If these routines are called from within the different thread
4659 ** than the one containing the application-defined function that received
4660 ** the [sqlite3_context] pointer, the results are undefined.
4661 */
4662 SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
4663 SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
4664 sqlite3_uint64,void(*)(void*));
4665 SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
4666 SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
4667 SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
4668 SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
4669 SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
@@ -5274,24 +5291,31 @@
5291
5292
5293 /*
5294 ** CAPI3REF: Extract Metadata About A Column Of A Table
5295 **
5296 ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
5297 ** information about column C of table T in database D
5298 ** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
5299 ** interface returns SQLITE_OK and fills in the non-NULL pointers in
5300 ** the final five arguments with appropriate values if the specified
5301 ** column exists. ^The sqlite3_table_column_metadata() interface returns
5302 ** SQLITE_ERROR and if the specified column does not exist.
5303 ** ^If the column-name parameter to sqlite3_table_column_metadata() is a
5304 ** NULL pointer, then this routine simply checks for the existance of the
5305 ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
5306 ** does not.
5307 **
5308 ** ^The column is identified by the second, third and fourth parameters to
5309 ** this function. ^(The second parameter is either the name of the database
5310 ** (i.e. "main", "temp", or an attached database) containing the specified
5311 ** table or NULL.)^ ^If it is NULL, then all attached databases are searched
5312 ** for the table using the same algorithm used by the database engine to
5313 ** resolve unqualified table references.
5314 **
5315 ** ^The third and fourth parameters to this function are the table and column
5316 ** name of the desired column, respectively.
 
5317 **
5318 ** ^Metadata is returned by writing to the memory locations passed as the 5th
5319 ** and subsequent parameters to this function. ^Any of these arguments may be
5320 ** NULL, in which case the corresponding element of metadata is omitted.
5321 **
@@ -5306,36 +5330,33 @@
5330 ** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
5331 ** </table>
5332 ** </blockquote>)^
5333 **
5334 ** ^The memory pointed to by the character pointers returned for the
5335 ** declaration type and collation sequence is valid until the next
5336 ** call to any SQLite API function.
5337 **
5338 ** ^If the specified table is actually a view, an [error code] is returned.
5339 **
5340 ** ^If the specified column is "rowid", "oid" or "_rowid_" and the table
5341 ** is not a [WITHOUT ROWID] table and an
5342 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
5343 ** parameters are set for the explicitly declared column. ^(If there is no
5344 ** [INTEGER PRIMARY KEY] column, then the outputs
5345 ** for the [rowid] are set as follows:
5346 **
5347 ** <pre>
5348 ** data type: "INTEGER"
5349 ** collation sequence: "BINARY"
5350 ** not null: 0
5351 ** primary key: 1
5352 ** auto increment: 0
5353 ** </pre>)^
5354 **
5355 ** ^This function causes all database schemas to be read from disk and
5356 ** parsed, if that has not already been done, and returns an error if
5357 ** any errors are encountered while loading the schema.
 
 
 
 
5358 */
5359 SQLITE_API int sqlite3_table_column_metadata(
5360 sqlite3 *db, /* Connection handle */
5361 const char *zDbName, /* Database name or NULL */
5362 const char *zTableName, /* Table name */
@@ -7298,16 +7319,14 @@
7319
7320 /*
7321 ** CAPI3REF: Write-Ahead Log Commit Hook
7322 **
7323 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
7324 ** is invoked each time data is committed to a database in wal mode.
 
 
7325 **
7326 ** ^(The callback is invoked by SQLite after the commit has taken place and
7327 ** the associated write-lock on the database released)^, so the implementation
7328 ** may read, write or [checkpoint] the database as required.
7329 **
7330 ** ^The first parameter passed to the callback function when it is invoked
7331 ** is a copy of the third parameter passed to sqlite3_wal_hook() when
7332 ** registering the callback. ^The second is a copy of the database handle.
@@ -7368,101 +7387,118 @@
7387 SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
7388
7389 /*
7390 ** CAPI3REF: Checkpoint a database
7391 **
7392 ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
7393 ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
7394 **
7395 ** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
7396 ** [write-ahead log] for database X on [database connection] D to be
7397 ** transferred into the database file and for the write-ahead log to
7398 ** be reset. See the [checkpointing] documentation for addition
7399 ** information.
7400 **
7401 ** This interface used to be the only way to cause a checkpoint to
7402 ** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
7403 ** interface was added. This interface is retained for backwards
7404 ** compatibility and as a convenience for applications that need to manually
7405 ** start a callback but which do not need the full power (and corresponding
7406 ** complication) of [sqlite3_wal_checkpoint_v2()].
 
7407 */
7408 SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
7409
7410 /*
7411 ** CAPI3REF: Checkpoint a database
7412 **
7413 ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
7414 ** operation on database X of [database connection] D in mode M. Status
7415 ** information is written back into integers pointed to by L and C.)^
7416 ** ^(The M parameter must be a valid [checkpoint mode]:)^
7417 **
7418 ** <dl>
7419 ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
7420 ** ^Checkpoint as many frames as possible without waiting for any database
7421 ** readers or writers to finish, then sync the database file if all frames
7422 ** in the log were checkpointed. ^The [busy-handler callback]
7423 ** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
7424 ** ^On the other hand, passive mode might leave the checkpoint unfinished
7425 ** if there are concurrent readers or writers.
7426 **
7427 ** <dt>SQLITE_CHECKPOINT_FULL<dd>
7428 ** ^This mode blocks (it invokes the
7429 ** [sqlite3_busy_handler|busy-handler callback]) until there is no
7430 ** database writer and all readers are reading from the most recent database
7431 ** snapshot. ^It then checkpoints all frames in the log file and syncs the
7432 ** database file. ^This mode blocks new database writers while it is pending,
7433 ** but new database readers are allowed to continue unimpeded.
7434 **
7435 ** <dt>SQLITE_CHECKPOINT_RESTART<dd>
7436 ** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
7437 ** that after checkpointing the log file it blocks (calls the
7438 ** [busy-handler callback])
7439 ** until all readers are reading from the database file only. ^This ensures
7440 ** that the next writer will restart the log file from the beginning.
7441 ** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
7442 ** database writer attempts while it is pending, but does not impede readers.
7443 **
7444 ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
7445 ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
7446 ** addition that it also truncates the log file to zero bytes just prior
7447 ** to a successful return.
7448 ** </dl>
7449 **
7450 ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
7451 ** the log file or to -1 if the checkpoint could not run because
7452 ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
7453 ** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
7454 ** log file (including any that were already checkpointed before the function
7455 ** was called) or to -1 if the checkpoint could not run due to an error or
7456 ** because the database is not in WAL mode. ^Note that upon successful
7457 ** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
7458 ** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
7459 **
7460 ** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
7461 ** any other process is running a checkpoint operation at the same time, the
7462 ** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a
7463 ** busy-handler configured, it will not be invoked in this case.
7464 **
7465 ** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the
7466 ** exclusive "writer" lock on the database file. ^If the writer lock cannot be
7467 ** obtained immediately, and a busy-handler is configured, it is invoked and
7468 ** the writer lock retried until either the busy-handler returns 0 or the lock
7469 ** is successfully obtained. ^The busy-handler is also invoked while waiting for
7470 ** database readers as described above. ^If the busy-handler returns 0 before
7471 ** the writer lock is obtained or while waiting for database readers, the
7472 ** checkpoint operation proceeds from that point in the same way as
7473 ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
7474 ** without blocking any further. ^SQLITE_BUSY is returned in this case.
7475 **
7476 ** ^If parameter zDb is NULL or points to a zero length string, then the
7477 ** specified operation is attempted on all WAL databases [attached] to
7478 ** [database connection] db. In this case the
7479 ** values written to output parameters *pnLog and *pnCkpt are undefined. ^If
7480 ** an SQLITE_BUSY error is encountered when processing one or more of the
7481 ** attached WAL databases, the operation is still attempted on any remaining
7482 ** attached databases and SQLITE_BUSY is returned at the end. ^If any other
7483 ** error occurs while processing an attached database, processing is abandoned
7484 ** and the error code is returned to the caller immediately. ^If no error
7485 ** (SQLITE_BUSY or otherwise) is encountered while processing the attached
7486 ** databases, SQLITE_OK is returned.
7487 **
7488 ** ^If database zDb is the name of an attached database that is not in WAL
7489 ** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
7490 ** zDb is not NULL (or a zero length string) and is not the name of any
7491 ** attached database, SQLITE_ERROR is returned to the caller.
7492 **
7493 ** ^Unless it returns SQLITE_MISUSE,
7494 ** the sqlite3_wal_checkpoint_v2() interface
7495 ** sets the error information that is queried by
7496 ** [sqlite3_errcode()] and [sqlite3_errmsg()].
7497 **
7498 ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
7499 ** from SQL.
7500 */
7501 SQLITE_API int sqlite3_wal_checkpoint_v2(
7502 sqlite3 *db, /* Database handle */
7503 const char *zDb, /* Name of attached database (or NULL) */
7504 int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7469,20 +7505,22 @@
7505 int *pnLog, /* OUT: Size of WAL log in frames */
7506 int *pnCkpt /* OUT: Total number of frames checkpointed */
7507 );
7508
7509 /*
7510 ** CAPI3REF: Checkpoint Mode Values
7511 ** KEYWORDS: {checkpoint mode}
7512 **
7513 ** These constants define all valid values for the "checkpoint mode" passed
7514 ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
7515 ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
7516 ** meaning of each of these checkpoint modes.
7517 */
7518 #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
7519 #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
7520 #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
7521 #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
7522
7523 /*
7524 ** CAPI3REF: Virtual Table Interface Configuration
7525 **
7526 ** This function may be called by either the [xConnect] or [xCreate] method
@@ -7577,16 +7615,16 @@
7615 ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
7616 ** different metric for sqlite3_stmt_scanstatus() to return.
7617 **
7618 ** <dl>
7619 ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
7620 ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
7621 ** set to the total number of times that the X-th loop has run.</dd>
7622 **
7623 ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
7624 ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
7625 ** to the total number of rows examined by all iterations of the X-th loop.</dd>
7626 **
7627 ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
7628 ** <dd>^The "double" variable pointed to by the T parameter will be set to the
7629 ** query planner's estimate for the average number of rows output from each
7630 ** iteration of the X-th loop. If the query planner's estimates was accurate,
@@ -7593,18 +7631,18 @@
7631 ** then this value will approximate the quotient NVISIT/NLOOP and the
7632 ** product of this value for all prior loops with the same SELECTID will
7633 ** be the NLOOP value for the current loop.
7634 **
7635 ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
7636 ** <dd>^The "const char *" variable pointed to by the T parameter will be set
7637 ** to a zero-terminated UTF-8 string containing the name of the index or table
7638 ** used for the X-th loop.
7639 **
7640 ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
7641 ** <dd>^The "const char *" variable pointed to by the T parameter will be set
7642 ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
7643 ** description for the X-th loop.
7644 **
7645 ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
7646 ** <dd>^The "int" variable pointed to by the T parameter will be set to the
7647 ** "select-id" for the X-th loop. The select-id identifies which query or
7648 ** subquery the loop is part of. The main query has a select-id of zero.
@@ -7623,12 +7661,12 @@
7661 ** CAPI3REF: Prepared Statement Scan Status
7662 **
7663 ** Return status data for a single loop within query pStmt.
7664 **
7665 ** The "iScanStatusOp" parameter determines which status information to return.
7666 ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
7667 ** of this interface is undefined.
7668 ** ^The requested measurement is written into a variable pointed to by
7669 ** the "pOut" parameter.
7670 ** Parameter "idx" identifies the specific loop to retrieve statistics for.
7671 ** Loops are numbered starting from zero. ^If idx is out of range - less than
7672 ** zero or greater than or equal to the total number of loops used to implement
@@ -9072,11 +9110,11 @@
9110 #define _BTREE_H_
9111
9112 /* TODO: This definition is just included so other modules compile. It
9113 ** needs to be revisited.
9114 */
9115 #define SQLITE_N_BTREE_META 16
9116
9117 /*
9118 ** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
9119 ** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
9120 */
@@ -9187,10 +9225,15 @@
9225 ** offset = 36 + (idx * 4)
9226 **
9227 ** For example, the free-page-count field is located at byte offset 36 of
9228 ** the database file header. The incr-vacuum-flag field is located at
9229 ** byte offset 64 (== 36+4*7).
9230 **
9231 ** The BTREE_DATA_VERSION value is not really a value stored in the header.
9232 ** It is a read-only number computed by the pager. But we merge it with
9233 ** the header value access routines since its access pattern is the same.
9234 ** Call it a "virtual meta value".
9235 */
9236 #define BTREE_FREE_PAGE_COUNT 0
9237 #define BTREE_SCHEMA_VERSION 1
9238 #define BTREE_FILE_FORMAT 2
9239 #define BTREE_DEFAULT_CACHE_SIZE 3
@@ -9197,10 +9240,11 @@
9240 #define BTREE_LARGEST_ROOT_PAGE 4
9241 #define BTREE_TEXT_ENCODING 5
9242 #define BTREE_USER_VERSION 6
9243 #define BTREE_INCR_VACUUM 7
9244 #define BTREE_APPLICATION_ID 8
9245 #define BTREE_DATA_VERSION 15 /* A virtual meta-value */
9246
9247 /*
9248 ** Values that may be OR'd together to form the second argument of an
9249 ** sqlite3BtreeCursorHints() call.
9250 */
@@ -9978,10 +10022,11 @@
10022 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
10023 #endif
10024
10025 /* Functions used to query pager state and configuration. */
10026 SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
10027 SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*);
10028 SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
10029 SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
10030 SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
10031 SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
10032 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
@@ -10719,10 +10764,11 @@
10764 i64 szMmap; /* Default mmap_size setting */
10765 unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
10766 int errCode; /* Most recent error code (SQLITE_*) */
10767 int errMask; /* & result codes with this before returning */
10768 u16 dbOptFlags; /* Flags to enable/disable optimizations */
10769 u8 enc; /* Text encoding */
10770 u8 autoCommit; /* The auto-commit flag. */
10771 u8 temp_store; /* 1: file 2: memory 0: default */
10772 u8 mallocFailed; /* True if we have seen a malloc failure */
10773 u8 dfltLockMode; /* Default locking-mode for attached dbs */
10774 signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
@@ -10820,11 +10866,12 @@
10866 };
10867
10868 /*
10869 ** A macro to discover the encoding of a database.
10870 */
10871 #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
10872 #define ENC(db) ((db)->enc)
10873
10874 /*
10875 ** Possible values for the sqlite3.flags.
10876 */
10877 #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
@@ -11444,11 +11491,10 @@
11491 Index *pNext; /* The next index associated with the same table */
11492 Schema *pSchema; /* Schema containing this index */
11493 u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
11494 char **azColl; /* Array of collation sequence names for index */
11495 Expr *pPartIdxWhere; /* WHERE clause for partial indices */
 
11496 int tnum; /* DB Page containing root of this index */
11497 LogEst szIdxRow; /* Estimated average row size in bytes */
11498 u16 nKeyCol; /* Number of columns forming the key */
11499 u16 nColumn; /* Number of columns stored in the index */
11500 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
@@ -11675,11 +11721,11 @@
11721 };
11722
11723 /*
11724 ** The following are the meanings of bits in the Expr.flags field.
11725 */
11726 #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
11727 #define EP_Agg 0x000002 /* Contains one or more aggregate functions */
11728 #define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
11729 #define EP_Error 0x000008 /* Expression contains one or more errors */
11730 #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
11731 #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
@@ -11695,10 +11741,11 @@
11741 #define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
11742 #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
11743 #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
11744 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
11745 #define EP_Constant 0x080000 /* Node is a constant */
11746 #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
11747
11748 /*
11749 ** These macros can be used to test, set, or clear bits in the
11750 ** Expr.flags field.
11751 */
@@ -12497,10 +12544,11 @@
12544 void *pPage; /* Page cache memory */
12545 int szPage; /* Size of each page in pPage[] */
12546 int nPage; /* Number of pages in pPage[] */
12547 int mxParserStack; /* maximum depth of the parser stack */
12548 int sharedCacheEnabled; /* true if shared-cache mode enabled */
12549 u32 szPma; /* Maximum Sorter PMA size */
12550 /* The above might be initialized to non-zero. The following need to always
12551 ** initially be zero, however. */
12552 int isInit; /* True after initialization has finished */
12553 int inProgress; /* True while initialization in progress */
12554 int isMutexInit; /* True after mutexes are initialized */
@@ -13419,11 +13467,11 @@
13467 ** print I/O tracing messages.
13468 */
13469 #ifdef SQLITE_ENABLE_IOTRACE
13470 # define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
13471 SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
13472 void (*sqlite3IoTrace)(const char*,...);
13473 #else
13474 # define IOTRACE(A)
13475 # define sqlite3VdbeIOTraceSql(X)
13476 #endif
13477
@@ -13632,10 +13680,17 @@
13680 */
13681 #ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
13682 # define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
13683 #endif
13684
13685 /* The minimum PMA size is set to this value multiplied by the database
13686 ** page size in bytes.
13687 */
13688 #ifndef SQLITE_SORTER_PMASZ
13689 # define SQLITE_SORTER_PMASZ 250
13690 #endif
13691
13692 /*
13693 ** The following singleton contains the global configuration for
13694 ** the SQLite library.
13695 */
13696 SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
@@ -13662,10 +13717,11 @@
13717 (void*)0, /* pPage */
13718 0, /* szPage */
13719 0, /* nPage */
13720 0, /* mxParserStack */
13721 0, /* sharedCacheEnabled */
13722 SQLITE_SORTER_PMASZ, /* szPma */
13723 /* All the rest should always be initialized to zero */
13724 0, /* isInit */
13725 0, /* inProgress */
13726 0, /* isMutexInit */
13727 0, /* isMallocInit */
@@ -19947,10 +20003,16 @@
20003 #endif
20004 }
20005 break;
20006 }
20007 default: {
20008 #ifdef SQLITE_ENABLE_API_ARMOR
20009 if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
20010 (void)SQLITE_MISUSE_BKPT;
20011 return 0;
20012 }
20013 #endif
20014 assert( iType-2 >= 0 );
20015 assert( iType-2 < ArraySize(winMutex_staticMutexes) );
20016 assert( winMutex_isInit==1 );
20017 p = &winMutex_staticMutexes[iType-2];
20018 #ifdef SQLITE_DEBUG
@@ -28754,28 +28816,31 @@
28816 do{
28817 err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
28818 }while( err==EINTR );
28819 if( err ) return SQLITE_IOERR_WRITE;
28820 #else
28821 /* If the OS does not have posix_fallocate(), fake it. Write a
28822 ** single byte to the last byte in each block that falls entirely
28823 ** within the extended region. Then, if required, a single byte
28824 ** at offset (nSize-1), to set the size of the file correctly.
28825 ** This is a similar technique to that used by glibc on systems
28826 ** that do not have a real fallocate() call.
28827 */
28828 int nBlk = buf.st_blksize; /* File-system block size */
28829 i64 iWrite; /* Next offset to write to */
28830
 
 
 
 
28831 iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
28832 assert( iWrite>=buf.st_size );
28833 assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
28834 assert( ((iWrite+1)%nBlk)==0 );
28835 for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
28836 int nWrite = seekAndWrite(pFile, iWrite, "", 1);
28837 if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
28838 }
28839 if( nSize%nBlk ){
28840 int nWrite = seekAndWrite(pFile, nSize-1, "", 1);
28841 if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
28842 }
28843 #endif
28844 }
28845 }
28846
@@ -33989,12 +34054,12 @@
34054 */
34055 SQLITE_API int sqlite3_win32_reset_heap(){
34056 int rc;
34057 MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
34058 MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
34059 MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
34060 MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
34061 sqlite3_mutex_enter(pMaster);
34062 sqlite3_mutex_enter(pMem);
34063 winMemAssertMagic();
34064 if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
34065 /*
@@ -35265,11 +35330,11 @@
35330 sqlite3_file *id, /* File to read from */
35331 void *pBuf, /* Write content into this buffer */
35332 int amt, /* Number of bytes to read */
35333 sqlite3_int64 offset /* Begin reading at this offset */
35334 ){
35335 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
35336 OVERLAPPED overlapped; /* The offset for ReadFile. */
35337 #endif
35338 winFile *pFile = (winFile*)id; /* file handle */
35339 DWORD nRead; /* Number of bytes actually read from file */
35340 int nRetry = 0; /* Number of retrys */
@@ -35297,11 +35362,11 @@
35362 offset += nCopy;
35363 }
35364 }
35365 #endif
35366
35367 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
35368 if( winSeekFile(pFile, offset) ){
35369 OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
35370 return SQLITE_FULL;
35371 }
35372 while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
@@ -35369,32 +35434,32 @@
35434 offset += nCopy;
35435 }
35436 }
35437 #endif
35438
35439 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
35440 rc = winSeekFile(pFile, offset);
35441 if( rc==0 ){
35442 #else
35443 {
35444 #endif
35445 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
35446 OVERLAPPED overlapped; /* The offset for WriteFile. */
35447 #endif
35448 u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
35449 int nRem = amt; /* Number of bytes yet to be written */
35450 DWORD nWrite; /* Bytes written by each WriteFile() call */
35451 DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */
35452
35453 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
35454 memset(&overlapped, 0, sizeof(OVERLAPPED));
35455 overlapped.Offset = (LONG)(offset & 0xffffffff);
35456 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
35457 #endif
35458
35459 while( nRem>0 ){
35460 #if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
35461 if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
35462 #else
35463 if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
35464 #endif
35465 if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
@@ -35403,11 +35468,11 @@
35468 assert( nWrite==0 || nWrite<=(DWORD)nRem );
35469 if( nWrite==0 || nWrite>(DWORD)nRem ){
35470 lastErrno = osGetLastError();
35471 break;
35472 }
35473 #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
35474 offset += nWrite;
35475 overlapped.Offset = (LONG)(offset & 0xffffffff);
35476 overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
35477 #endif
35478 aRem += nWrite;
@@ -38949,11 +39014,12 @@
39014 SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
39015 assert( pCache->nRef==0 && pCache->pDirty==0 );
39016 if( pCache->szPage ){
39017 sqlite3_pcache *pNew;
39018 pNew = sqlite3GlobalConfig.pcache2.xCreate(
39019 szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
39020 pCache->bPurgeable
39021 );
39022 if( pNew==0 ) return SQLITE_NOMEM;
39023 sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
39024 if( pCache->pCache ){
39025 sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
@@ -39408,11 +39474,11 @@
39474
39475 /*
39476 ** Return the size of the header added by this middleware layer
39477 ** in the page-cache hierarchy.
39478 */
39479 SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
39480
39481
39482 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
39483 /*
39484 ** For all dirty pages currently in the cache, invoke the specified
@@ -39724,11 +39790,11 @@
39790 pcache1Free(pPg);
39791 sqlite3_free(p);
39792 pPg = 0;
39793 }
39794 #else
39795 pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
39796 p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
39797 #endif
39798 pcache1EnterMutex(pCache->pGroup);
39799
39800 if( pPg ){
@@ -40412,11 +40478,11 @@
40478 }
40479
40480 /*
40481 ** Return the size of the header on each page of this PCACHE implementation.
40482 */
40483 SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
40484
40485 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
40486 /*
40487 ** This function is called to free superfluous dynamically allocated memory
40488 ** held by the pager system. Memory in use by any SQLite pager allocated
@@ -41770,10 +41836,12 @@
41836 u8 eLock; /* Current lock held on database file */
41837 u8 changeCountDone; /* Set after incrementing the change-counter */
41838 u8 setMaster; /* True if a m-j name has been written to jrnl */
41839 u8 doNotSpill; /* Do not spill the cache when non-zero */
41840 u8 subjInMemory; /* True to use in-memory sub-journals */
41841 u8 bUseFetch; /* True to use xFetch() */
41842 u8 hasBeenUsed; /* True if any content previously read from this pager*/
41843 Pgno dbSize; /* Number of pages in the database */
41844 Pgno dbOrigSize; /* dbSize before the current transaction */
41845 Pgno dbFileSize; /* Number of pages in the database file */
41846 Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */
41847 int errCode; /* One of several kinds of errors */
@@ -41787,13 +41855,13 @@
41855 i64 journalOff; /* Current write offset in the journal file */
41856 i64 journalHdr; /* Byte offset to previous journal header */
41857 sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
41858 PagerSavepoint *aSavepoint; /* Array of active savepoints */
41859 int nSavepoint; /* Number of elements in aSavepoint[] */
41860 u32 iDataVersion; /* Changes whenever database content changes */
41861 char dbFileVers[16]; /* Changes whenever database file changes */
41862
 
41863 int nMmapOut; /* Number of mmap pages currently outstanding */
41864 sqlite3_int64 szMmap; /* Desired maximum mmap size */
41865 PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
41866 /*
41867 ** End of the routinely-changing class members
@@ -42805,13 +42873,22 @@
42873
42874 /*
42875 ** Discard the entire contents of the in-memory page-cache.
42876 */
42877 static void pager_reset(Pager *pPager){
42878 pPager->iDataVersion++;
42879 sqlite3BackupRestart(pPager->pBackup);
42880 sqlite3PcacheClear(pPager->pPCache);
42881 }
42882
42883 /*
42884 ** Return the pPager->iDataVersion value
42885 */
42886 SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
42887 assert( pPager->eState>PAGER_OPEN );
42888 return pPager->iDataVersion;
42889 }
42890
42891 /*
42892 ** Free all structures in the Pager.aSavepoint[] array and set both
42893 ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
42894 ** if it is open and the pager is not in exclusive mode.
@@ -45011,11 +45088,11 @@
45088 Pgno pgno, /* Page number */
45089 void *pData, /* xFetch()'d data for this page */
45090 PgHdr **ppPage /* OUT: Acquired page object */
45091 ){
45092 PgHdr *p; /* Memory mapped page to return */
45093
45094 if( pPager->pMmapFreelist ){
45095 *ppPage = p = pPager->pMmapFreelist;
45096 pPager->pMmapFreelist = p->pDirty;
45097 p->pDirty = 0;
45098 memset(p->pExtra, 0, pPager->nExtra);
@@ -46242,20 +46319,16 @@
46319 assert( (pPager->eLock==SHARED_LOCK)
46320 || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
46321 );
46322 }
46323
46324 if( !pPager->tempFile && pPager->hasBeenUsed ){
46325 /* The shared-lock has just been acquired then check to
46326 ** see if the database has been modified. If the database has changed,
46327 ** flush the cache. The pPager->hasBeenUsed flag prevents this from
46328 ** occurring on the very first access to a file, in order to save a
46329 ** single unnecessary sqlite3OsRead() call at the start-up.
 
 
 
 
46330 **
46331 ** Database changes is detected by looking at 15 bytes beginning
46332 ** at offset 24 into the file. The first 4 of these 16 bytes are
46333 ** a 32-bit counter that is incremented with each change. The
46334 ** other bytes change randomly with each file change when
@@ -46416,10 +46489,11 @@
46489 assert( noContent==0 || bMmapOk==0 );
46490
46491 if( pgno==0 ){
46492 return SQLITE_CORRUPT_BKPT;
46493 }
46494 pPager->hasBeenUsed = 1;
46495
46496 /* If the pager is in the error state, return an error immediately.
46497 ** Otherwise, request the page from the PCache layer. */
46498 if( pPager->errCode!=SQLITE_OK ){
46499 rc = pPager->errCode;
@@ -46565,10 +46639,11 @@
46639 sqlite3_pcache_page *pPage;
46640 assert( pPager!=0 );
46641 assert( pgno!=0 );
46642 assert( pPager->pPCache!=0 );
46643 pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
46644 assert( pPage==0 || pPager->hasBeenUsed );
46645 return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
46646 }
46647
46648 /*
46649 ** Release a page reference.
@@ -47431,10 +47506,11 @@
47506 pPager->eState = PAGER_READER;
47507 return SQLITE_OK;
47508 }
47509
47510 PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
47511 pPager->iDataVersion++;
47512 rc = pager_end_transaction(pPager, pPager->setMaster, 1);
47513 return pager_error(pPager, rc);
47514 }
47515
47516 /*
@@ -48199,11 +48275,12 @@
48275 */
48276 SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
48277 int rc = SQLITE_OK;
48278 if( pPager->pWal ){
48279 rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
48280 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
48281 pPager->pBusyHandlerArg,
48282 pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
48283 pnLog, pnCkpt
48284 );
48285 }
48286 return rc;
@@ -50009,10 +50086,42 @@
50086 ** Return the page-size in bytes used by the database.
50087 */
50088 static int walPagesize(Wal *pWal){
50089 return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
50090 }
50091
50092 /*
50093 ** The following is guaranteed when this function is called:
50094 **
50095 ** a) the WRITER lock is held,
50096 ** b) the entire log file has been checkpointed, and
50097 ** c) any existing readers are reading exclusively from the database
50098 ** file - there are no readers that may attempt to read a frame from
50099 ** the log file.
50100 **
50101 ** This function updates the shared-memory structures so that the next
50102 ** client to write to the database (which may be this one) does so by
50103 ** writing frames into the start of the log file.
50104 **
50105 ** The value of parameter salt1 is used as the aSalt[1] value in the
50106 ** new wal-index header. It should be passed a pseudo-random value (i.e.
50107 ** one obtained from sqlite3_randomness()).
50108 */
50109 static void walRestartHdr(Wal *pWal, u32 salt1){
50110 volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
50111 int i; /* Loop counter */
50112 u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
50113 pWal->nCkpt++;
50114 pWal->hdr.mxFrame = 0;
50115 sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
50116 memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
50117 walIndexWriteHdr(pWal);
50118 pInfo->nBackfill = 0;
50119 pInfo->aReadMark[1] = 0;
50120 for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
50121 assert( pInfo->aReadMark[0]==0 );
50122 }
50123
50124 /*
50125 ** Copy as much content as we can from the WAL back into the database file
50126 ** in response to an sqlite3_wal_checkpoint() request or the equivalent.
50127 **
@@ -50044,11 +50153,11 @@
50153 ** time.
50154 */
50155 static int walCheckpoint(
50156 Wal *pWal, /* Wal connection */
50157 int eMode, /* One of PASSIVE, FULL or RESTART */
50158 int (*xBusy)(void*), /* Function to call when busy */
50159 void *pBusyArg, /* Context argument for xBusyHandler */
50160 int sync_flags, /* Flags for OsSync() (or 0) */
50161 u8 *zBuf /* Temporary buffer to use */
50162 ){
50163 int rc; /* Return code */
@@ -50058,11 +50167,10 @@
50167 u32 iFrame = 0; /* Wal frame containing data for iDbpage */
50168 u32 mxSafeFrame; /* Max frame that can be backfilled */
50169 u32 mxPage; /* Max database page to write */
50170 int i; /* Loop counter */
50171 volatile WalCkptInfo *pInfo; /* The checkpoint status information */
 
50172
50173 szPage = walPagesize(pWal);
50174 testcase( szPage<=32768 );
50175 testcase( szPage>=65536 );
50176 pInfo = walCkptInfo(pWal);
@@ -50073,11 +50181,13 @@
50181 if( rc!=SQLITE_OK ){
50182 return rc;
50183 }
50184 assert( pIter );
50185
50186 /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
50187 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
50188 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
50189
50190 /* Compute in mxSafeFrame the index of the last frame of the WAL that is
50191 ** safe to write into the database. Frames beyond mxSafeFrame might
50192 ** overwrite database pages that are in use by active readers and thus
50193 ** cannot be backfilled from the WAL.
@@ -50162,23 +50272,42 @@
50272 /* Reset the return code so as not to report a checkpoint failure
50273 ** just because there are active readers. */
50274 rc = SQLITE_OK;
50275 }
50276
50277 /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
50278 ** entire wal file has been copied into the database file, then block
50279 ** until all readers have finished using the wal file. This ensures that
50280 ** the next process to write to the database restarts the wal file.
50281 */
50282 if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
50283 assert( pWal->writeLock );
50284 if( pInfo->nBackfill<pWal->hdr.mxFrame ){
50285 rc = SQLITE_BUSY;
50286 }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
50287 u32 salt1;
50288 sqlite3_randomness(4, &salt1);
50289 assert( mxSafeFrame==pWal->hdr.mxFrame );
50290 rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
50291 if( rc==SQLITE_OK ){
50292 if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
50293 /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
50294 ** SQLITE_CHECKPOINT_RESTART with the addition that it also
50295 ** truncates the log file to zero bytes just prior to a
50296 ** successful return.
50297 **
50298 ** In theory, it might be safe to do this without updating the
50299 ** wal-index header in shared memory, as all subsequent reader or
50300 ** writer clients should see that the entire log file has been
50301 ** checkpointed and behave accordingly. This seems unsafe though,
50302 ** as it would leave the system in a state where the contents of
50303 ** the wal-index header do not match the contents of the
50304 ** file-system. To avoid this, update the wal-index header to
50305 ** indicate that the log file contains zero valid frames. */
50306 walRestartHdr(pWal, salt1);
50307 rc = sqlite3OsTruncate(pWal->pWalFd, 0);
50308 }
50309 walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
50310 }
50311 }
50312 }
50313
@@ -50747,11 +50876,11 @@
50876 }
50877 nCollide = HASHTABLE_NSLOT;
50878 for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
50879 u32 iFrame = aHash[iKey] + iZero;
50880 if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
50881 assert( iFrame>iRead || CORRUPT_DB );
50882 iRead = iFrame;
50883 }
50884 if( (nCollide--)==0 ){
50885 return SQLITE_CORRUPT_BKPT;
50886 }
@@ -50960,11 +51089,10 @@
51089 }
51090
51091 return rc;
51092 }
51093
 
51094 /*
51095 ** This function is called just before writing a set of frames to the log
51096 ** file (see sqlite3WalFrames()). It checks to see if, instead of appending
51097 ** to the current log file, it is possible to overwrite the start of the
51098 ** existing log file with the new frames (i.e. "reset" the log). If so,
@@ -50993,24 +51121,12 @@
51121 ** wal-index header to reflect this.
51122 **
51123 ** In theory it would be Ok to update the cache of the header only
51124 ** at this point. But updating the actual wal-index header is also
51125 ** safe and means there is no special case for sqlite3WalUndo()
51126 ** to handle if this transaction is rolled back. */
51127 walRestartHdr(pWal, salt1);
 
 
 
 
 
 
 
 
 
 
 
 
51128 walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
51129 }else if( rc!=SQLITE_BUSY ){
51130 return rc;
51131 }
51132 }
@@ -51294,11 +51410,11 @@
51410 ** If parameter xBusy is not NULL, it is a pointer to a busy-handler
51411 ** callback. In this case this function runs a blocking checkpoint.
51412 */
51413 SQLITE_PRIVATE int sqlite3WalCheckpoint(
51414 Wal *pWal, /* Wal connection */
51415 int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
51416 int (*xBusy)(void*), /* Function to call when busy */
51417 void *pBusyArg, /* Context argument for xBusyHandler */
51418 int sync_flags, /* Flags to sync db file with (or 0) */
51419 int nBuf, /* Size of temporary buffer */
51420 u8 *zBuf, /* Temporary buffer to use */
@@ -51306,40 +51422,54 @@
51422 int *pnCkpt /* OUT: Number of backfilled frames in WAL */
51423 ){
51424 int rc; /* Return code */
51425 int isChanged = 0; /* True if a new wal-index header is loaded */
51426 int eMode2 = eMode; /* Mode to pass to walCheckpoint() */
51427 int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */
51428
51429 assert( pWal->ckptLock==0 );
51430 assert( pWal->writeLock==0 );
51431
51432 /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
51433 ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
51434 assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
51435
51436 if( pWal->readOnly ) return SQLITE_READONLY;
51437 WALTRACE(("WAL%p: checkpoint begins\n", pWal));
51438
51439 /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
51440 ** "checkpoint" lock on the database file. */
51441 rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
51442 if( rc ){
51443 /* EVIDENCE-OF: R-10421-19736 If any other process is running a
51444 ** checkpoint operation at the same time, the lock cannot be obtained and
51445 ** SQLITE_BUSY is returned.
51446 ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
51447 ** it will not be invoked in this case.
51448 */
51449 testcase( rc==SQLITE_BUSY );
51450 testcase( xBusy!=0 );
51451 return rc;
51452 }
51453 pWal->ckptLock = 1;
51454
51455 /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
51456 ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
51457 ** file.
51458 **
51459 ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
51460 ** immediately, and a busy-handler is configured, it is invoked and the
51461 ** writer lock retried until either the busy-handler returns 0 or the
51462 ** lock is successfully obtained.
51463 */
51464 if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
51465 rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
51466 if( rc==SQLITE_OK ){
51467 pWal->writeLock = 1;
51468 }else if( rc==SQLITE_BUSY ){
51469 eMode2 = SQLITE_CHECKPOINT_PASSIVE;
51470 xBusy2 = 0;
51471 rc = SQLITE_OK;
51472 }
51473 }
51474
51475 /* Read the wal-index header. */
@@ -51353,11 +51483,11 @@
51483 /* Copy data from the log to the database file. */
51484 if( rc==SQLITE_OK ){
51485 if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
51486 rc = SQLITE_CORRUPT_BKPT;
51487 }else{
51488 rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
51489 }
51490
51491 /* If no error occurred, set the output variables. */
51492 if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
51493 if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
@@ -51852,10 +51982,11 @@
51982 u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
51983 u8 sharable; /* True if we can share pBt with another db */
51984 u8 locked; /* True if db currently has pBt locked */
51985 int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
51986 int nBackup; /* Number of backup operations reading this btree */
51987 u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
51988 Btree *pNext; /* List of other sharable Btrees from the same db */
51989 Btree *pPrev; /* Back pointer of the same list */
51990 #ifndef SQLITE_OMIT_SHARED_CACHE
51991 BtLock lock; /* Object used to lock page 1 */
51992 #endif
@@ -53821,11 +53952,11 @@
53952 ** to see if defragmentation is necessary.
53953 */
53954 testcase( gap+2+nByte==top );
53955 if( gap+2+nByte>top ){
53956 defragment_page:
53957 assert( pPage->nCell>0 || CORRUPT_DB );
53958 rc = defragmentPage(pPage);
53959 if( rc ) return rc;
53960 top = get2byteNotZero(&data[hdr+5]);
53961 assert( gap+nByte<=top );
53962 }
@@ -56015,10 +56146,11 @@
56146 rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
56147 if( rc!=SQLITE_OK && bCleanup==0 ){
56148 sqlite3BtreeLeave(p);
56149 return rc;
56150 }
56151 p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */
56152 pBt->inTransaction = TRANS_READ;
56153 btreeClearHasContent(pBt);
56154 }
56155
56156 btreeEndTransaction(p);
@@ -56378,11 +56510,11 @@
56510 }
56511 for(i=0; i<=pCur->iPage; i++){
56512 releasePage(pCur->apPage[i]);
56513 }
56514 unlockBtreeIfUnused(pBt);
56515 sqlite3_free(pCur->aOverflow);
56516 /* sqlite3_free(pCur); */
56517 sqlite3BtreeLeave(pBtree);
56518 }
56519 return SQLITE_OK;
56520 }
@@ -56672,10 +56804,11 @@
56804 pBuf += a;
56805 amt -= a;
56806 }else{
56807 offset -= pCur->info.nLocal;
56808 }
56809
56810
56811 if( rc==SQLITE_OK && amt>0 ){
56812 const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */
56813 Pgno nextPage;
56814
@@ -56690,12 +56823,12 @@
56823 ** means "not yet known" (the cache is lazily populated).
56824 */
56825 if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
56826 int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
56827 if( nOvfl>pCur->nOvflAlloc ){
56828 Pgno *aNew = (Pgno*)sqlite3Realloc(
56829 pCur->aOverflow, nOvfl*2*sizeof(Pgno)
56830 );
56831 if( aNew==0 ){
56832 rc = SQLITE_NOMEM;
56833 }else{
56834 pCur->nOvflAlloc = nOvfl*2;
@@ -56738,10 +56871,11 @@
56871 ** Note that the aOverflow[] array must be allocated because eOp!=2
56872 ** here. If eOp==2, then offset==0 and this branch is never taken.
56873 */
56874 assert( eOp!=2 );
56875 assert( pCur->curFlags & BTCF_ValidOvfl );
56876 assert( pCur->pBtree->db==pBt->db );
56877 if( pCur->aOverflow[iIdx+1] ){
56878 nextPage = pCur->aOverflow[iIdx+1];
56879 }else{
56880 rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
56881 }
@@ -58881,11 +59015,11 @@
59015 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
59016 assert( sqlite3PagerIswriteable(pParent->pDbPage) );
59017 assert( pPage->nOverflow==1 );
59018
59019 /* This error condition is now caught prior to reaching this function */
59020 if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
59021
59022 /* Allocate a new page. This page will become the right-sibling of
59023 ** pPage. Make the parent page writable, so that the new divider cell
59024 ** may be inserted. If both these operations are successful, proceed.
59025 */
@@ -59250,11 +59384,11 @@
59384 + nMaxCells*sizeof(u16) /* szCell */
59385 + pBt->pageSize; /* aSpace1 */
59386
59387 /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
59388 ** that is more than 6 times the database page size. */
59389 assert( szScratch<=6*(int)pBt->pageSize );
59390 apCell = sqlite3ScratchMalloc( szScratch );
59391 if( apCell==0 ){
59392 rc = SQLITE_NOMEM;
59393 goto balance_cleanup;
59394 }
@@ -59324,11 +59458,15 @@
59458 ** pointer of the divider cell */
59459 memcpy(apCell[nCell], &pOld->aData[8], 4);
59460 }else{
59461 assert( leafCorrection==4 );
59462 if( szCell[nCell]<4 ){
59463 /* Do not allow any cells smaller than 4 bytes. If a smaller cell
59464 ** does exist, pad it with 0x00 bytes. */
59465 assert( szCell[nCell]==3 );
59466 assert( apCell[nCell]==&aSpace1[iSpace1-3] );
59467 aSpace1[iSpace1++] = 0x00;
59468 szCell[nCell] = 4;
59469 }
59470 }
59471 nCell++;
59472 }
@@ -59559,11 +59697,15 @@
59697 ** was either part of sibling page iOld (possibly an overflow cell),
59698 ** or else the divider cell to the left of sibling page iOld. So,
59699 ** if sibling page iOld had the same page number as pNew, and if
59700 ** pCell really was a part of sibling page iOld (not a divider or
59701 ** overflow cell), we can skip updating the pointer map entries. */
59702 if( iOld>=nNew
59703 || pNew->pgno!=aPgno[iOld]
59704 || pCell<aOld
59705 || pCell>=&aOld[usableSize]
59706 ){
59707 if( !leafCorrection ){
59708 ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
59709 }
59710 if( szCell[i]>pNew->minLocal ){
59711 ptrmapPutOvflPtr(pNew, pCell, &rc);
@@ -60632,10 +60774,17 @@
60774 ** is read-only, the others are read/write.
60775 **
60776 ** The schema layer numbers meta values differently. At the schema
60777 ** layer (and the SetCookie and ReadCookie opcodes) the number of
60778 ** free pages is not visible. So Cookie[0] is the same as Meta[1].
60779 **
60780 ** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead
60781 ** of reading the value out of the header, it instead loads the "DataVersion"
60782 ** from the pager. The BTREE_DATA_VERSION value is not actually stored in the
60783 ** database file. It is a number computed by the pager. But its access
60784 ** pattern is the same as header meta values, and so it is convenient to
60785 ** read it from this routine.
60786 */
60787 SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
60788 BtShared *pBt = p->pBt;
60789
60790 sqlite3BtreeEnter(p);
@@ -60642,11 +60791,15 @@
60791 assert( p->inTrans>TRANS_NONE );
60792 assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
60793 assert( pBt->pPage1 );
60794 assert( idx>=0 && idx<=15 );
60795
60796 if( idx==BTREE_DATA_VERSION ){
60797 *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion;
60798 }else{
60799 *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
60800 }
60801
60802 /* If auto-vacuum is disabled in this build and this is an auto-vacuum
60803 ** database, mark the database as read-only. */
60804 #ifdef SQLITE_OMIT_AUTOVACUUM
60805 if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){
@@ -60733,11 +60886,11 @@
60886 if( pPage->leaf ){
60887 do {
60888 if( pCur->iPage==0 ){
60889 /* All pages of the b-tree have been visited. Return successfully. */
60890 *pnEntry = nEntry;
60891 return moveToRoot(pCur);
60892 }
60893 moveToParent(pCur);
60894 }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
60895
60896 pCur->aiIdx[pCur->iPage]++;
@@ -61589,11 +61742,11 @@
61742 }
61743
61744 /*
61745 ** Return the size of the header added to each page by this module.
61746 */
61747 SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
61748
61749 /************** End of btree.c ***********************************************/
61750 /************** Begin file backup.c ******************************************/
61751 /*
61752 ** 2009 January 28
@@ -64353,36 +64506,39 @@
64506 **
64507 ** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
64508 */
64509 SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
64510 int hasAbort = 0;
64511 int hasFkCounter = 0;
64512 Op *pOp;
64513 VdbeOpIter sIter;
64514 memset(&sIter, 0, sizeof(sIter));
64515 sIter.v = v;
64516
64517 while( (pOp = opIterNext(&sIter))!=0 ){
64518 int opcode = pOp->opcode;
64519 if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
 
 
 
64520 || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
64521 && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
64522 ){
64523 hasAbort = 1;
64524 break;
64525 }
64526 #ifndef SQLITE_OMIT_FOREIGN_KEY
64527 if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
64528 hasFkCounter = 1;
64529 }
64530 #endif
64531 }
64532 sqlite3DbFree(v->db, sIter.apSub);
64533
64534 /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred.
64535 ** If malloc failed, then the while() loop above may not have iterated
64536 ** through all opcodes and hasAbort may be set incorrectly. Return
64537 ** true for this case to prevent the assert() in the callers frame
64538 ** from failing. */
64539 return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter );
64540 }
64541 #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
64542
64543 /*
64544 ** Loop through the program looking for P2 values that are negative
@@ -65699,11 +65855,11 @@
65855 for(n=0; n<nVar; n++){
65856 p->aVar[n].flags = MEM_Null;
65857 p->aVar[n].db = db;
65858 }
65859 }
65860 if( p->azVar && pParse->nzVar>0 ){
65861 p->nzVar = pParse->nzVar;
65862 memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
65863 memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
65864 }
65865 if( p->aMem ){
@@ -68502,11 +68658,14 @@
68658 #ifndef SQLITE_OMIT_WAL
68659 int i;
68660 for(i=0; i<db->nDb; i++){
68661 Btree *pBt = db->aDb[i].pBt;
68662 if( pBt ){
68663 int nEntry;
68664 sqlite3BtreeEnter(pBt);
68665 nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
68666 sqlite3BtreeLeave(pBt);
68667 if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
68668 rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
68669 }
68670 }
68671 }
@@ -68682,11 +68841,10 @@
68841 ** program counter to 0 to ensure that when the statement is
68842 ** finalized or reset the parser error message is available via
68843 ** sqlite3_errmsg() and sqlite3_errcode().
68844 */
68845 const char *zErr = (const char *)sqlite3_value_text(db->pErr);
 
68846 sqlite3DbFree(db, v->zErrMsg);
68847 if( !db->mallocFailed ){
68848 v->zErrMsg = sqlite3DbStrDup(db, zErr);
68849 v->rc = rc2;
68850 } else {
@@ -75629,12 +75787,12 @@
75787
75788 #ifndef SQLITE_OMIT_WAL
75789 /* Opcode: Checkpoint P1 P2 P3 * *
75790 **
75791 ** Checkpoint database P1. This is a no-op if P1 is not currently in
75792 ** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL,
75793 ** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns
75794 ** SQLITE_BUSY or not, respectively. Write the number of pages in the
75795 ** WAL after the checkpoint into mem[P3+1] and the number of pages
75796 ** in the WAL that have been checkpointed after the checkpoint
75797 ** completes into mem[P3+2]. However on an error, mem[P3+1] and
75798 ** mem[P3+2] are initialized to -1.
@@ -75648,10 +75806,11 @@
75806 aRes[0] = 0;
75807 aRes[1] = aRes[2] = -1;
75808 assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
75809 || pOp->p2==SQLITE_CHECKPOINT_FULL
75810 || pOp->p2==SQLITE_CHECKPOINT_RESTART
75811 || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
75812 );
75813 rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
75814 if( rc==SQLITE_BUSY ){
75815 rc = SQLITE_OK;
75816 aRes[0] = 1;
@@ -77043,11 +77202,11 @@
77202 /*
77203 ** Hard-coded maximum amount of data to accumulate in memory before flushing
77204 ** to a level 0 PMA. The purpose of this limit is to prevent various integer
77205 ** overflows. 512MiB.
77206 */
77207 #define SQLITE_MAX_PMASZ (1<<29)
77208
77209 /*
77210 ** Private objects used by the sorter
77211 */
77212 typedef struct MergeEngine MergeEngine; /* Merge PMAs together */
@@ -77339,13 +77498,10 @@
77498 **
77499 ** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
77500 */
77501 #define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
77502
 
 
 
77503
77504 /* Maximum number of PMAs that a single MergeEngine can merge */
77505 #define SORTER_MAX_MERGE_COUNT 16
77506
77507 static int vdbeIncrSwap(IncrMerger*);
@@ -77740,14 +77896,15 @@
77896 SortSubtask *pTask = &pSorter->aTask[i];
77897 pTask->pSorter = pSorter;
77898 }
77899
77900 if( !sqlite3TempInMemory(db) ){
77901 u32 szPma = sqlite3GlobalConfig.szPma;
77902 pSorter->mnPmaSize = szPma * pgsz;
77903 mxCache = db->aDb[0].pSchema->cache_size;
77904 if( mxCache<(int)szPma ) mxCache = (int)szPma;
77905 pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
77906
77907 /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
77908 ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
77909 ** large heap allocations.
77910 */
@@ -78021,16 +78178,16 @@
78178 ** Whether or not the file does end up memory mapped of course depends on
78179 ** the specific VFS implementation.
78180 */
78181 static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
78182 if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){
78183 void *p = 0;
78184 int chunksize = 4*1024;
78185 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
78186 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
78187 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
78188 sqlite3OsUnfetch(pFd, 0, p);
78189 }
78190 }
78191 #else
78192 # define vdbeSorterExtendFile(x,y,z)
78193 #endif
@@ -80411,10 +80568,14 @@
80568 }
80569 }
80570 if( pMatch ){
80571 pExpr->iTable = pMatch->iCursor;
80572 pExpr->pTab = pMatch->pTab;
80573 assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
80574 if( (pMatch->jointype & JT_LEFT)!=0 ){
80575 ExprSetProperty(pExpr, EP_CanBeNull);
80576 }
80577 pSchema = pExpr->pTab->pSchema;
80578 }
80579 } /* if( pSrcList ) */
80580
80581 #ifndef SQLITE_OMIT_TRIGGER
@@ -82968,11 +83129,12 @@
83129 case TK_FLOAT:
83130 case TK_BLOB:
83131 return 0;
83132 case TK_COLUMN:
83133 assert( p->pTab!=0 );
83134 return ExprHasProperty(p, EP_CanBeNull) ||
83135 (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
83136 default:
83137 return 1;
83138 }
83139 }
83140
@@ -87203,11 +87365,11 @@
87365
87366 p->iGet = -1;
87367 p->mxSample = mxSample;
87368 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
87369 p->current.anLt = &p->current.anEq[nColUp];
87370 p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
87371
87372 /* Set up the Stat4Accum.a[] and aBest[] arrays */
87373 p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
87374 p->aBest = &p->a[mxSample];
87375 pSpace = (u8*)(&p->a[mxSample+nCol]);
@@ -88351,11 +88513,11 @@
88513 tRowcnt avgEq = 0;
88514 tRowcnt nRow; /* Number of rows in index */
88515 i64 nSum100 = 0; /* Number of terms contributing to sumEq */
88516 i64 nDist100; /* Number of distinct values in index */
88517
88518 if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
88519 nRow = pFinal->anLt[iCol];
88520 nDist100 = (i64)100 * pFinal->anDLt[iCol];
88521 nSample--;
88522 }else{
88523 nRow = pIdx->aiRowEst[0];
@@ -88796,17 +88958,19 @@
88958 }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
88959 zErrDyn = sqlite3MPrintf(db,
88960 "attached databases must use the same text encoding as main database");
88961 rc = SQLITE_ERROR;
88962 }
88963 sqlite3BtreeEnter(aNew->pBt);
88964 pPager = sqlite3BtreePager(aNew->pBt);
88965 sqlite3PagerLockingMode(pPager, db->dfltLockMode);
88966 sqlite3BtreeSecureDelete(aNew->pBt,
88967 sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
88968 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
88969 sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
88970 #endif
88971 sqlite3BtreeLeave(aNew->pBt);
88972 }
88973 aNew->safety_level = 3;
88974 aNew->zName = sqlite3DbStrDup(db, zName);
88975 if( rc==SQLITE_OK && aNew->zName==0 ){
88976 rc = SQLITE_NOMEM;
@@ -89928,11 +90092,10 @@
90092 */
90093 static void freeIndex(sqlite3 *db, Index *p){
90094 #ifndef SQLITE_OMIT_ANALYZE
90095 sqlite3DeleteIndexSamples(db, p);
90096 #endif
 
90097 sqlite3ExprDelete(db, p->pPartIdxWhere);
90098 sqlite3DbFree(db, p->zColAff);
90099 if( p->isResized ) sqlite3DbFree(db, p->azColl);
90100 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
90101 sqlite3_free(p->aiRowEst);
@@ -91207,10 +91370,23 @@
91370 if( pPk==0 ) return;
91371 pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
91372 pTab->iPKey = -1;
91373 }else{
91374 pPk = sqlite3PrimaryKeyIndex(pTab);
91375 /*
91376 ** Remove all redundant columns from the PRIMARY KEY. For example, change
91377 ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
91378 ** code assumes the PRIMARY KEY contains no repeated columns.
91379 */
91380 for(i=j=1; i<pPk->nKeyCol; i++){
91381 if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
91382 pPk->nColumn--;
91383 }else{
91384 pPk->aiColumn[j++] = pPk->aiColumn[i];
91385 }
91386 }
91387 pPk->nKeyCol = j;
91388 }
91389 pPk->isCovering = 1;
91390 assert( pPk!=0 );
91391 nPk = pPk->nKeyCol;
91392
@@ -93683,44 +93859,35 @@
93859 **
93860 ** The caller should invoke sqlite3KeyInfoUnref() on the returned object
93861 ** when it has finished using it.
93862 */
93863 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
93864 int i;
93865 int nCol = pIdx->nColumn;
93866 int nKey = pIdx->nKeyCol;
93867 KeyInfo *pKey;
93868 if( pParse->nErr ) return 0;
93869 if( pIdx->uniqNotNull ){
93870 pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
93871 }else{
93872 pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
93873 }
93874 if( pKey ){
93875 assert( sqlite3KeyInfoIsWriteable(pKey) );
93876 for(i=0; i<nCol; i++){
93877 char *zColl = pIdx->azColl[i];
93878 assert( zColl!=0 );
93879 pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
93880 sqlite3LocateCollSeq(pParse, zColl);
93881 pKey->aSortOrder[i] = pIdx->aSortOrder[i];
93882 }
93883 if( pParse->nErr ){
93884 sqlite3KeyInfoUnref(pKey);
93885 pKey = 0;
93886 }
93887 }
93888 return pKey;
 
 
 
 
 
 
 
 
 
 
 
 
 
93889 }
93890
93891 #ifndef SQLITE_OMIT_CTE
93892 /*
93893 ** This routine is invoked once per CTE by the parser while parsing a
@@ -97337,11 +97504,11 @@
97504 assert( nIncr==1 );
97505 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
97506 OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
97507 }else{
97508 if( nIncr>0 && pFKey->isDeferred==0 ){
97509 sqlite3MayAbort(pParse);
97510 }
97511 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
97512 }
97513
97514 sqlite3VdbeResolveLabel(v, iOk);
@@ -97408,10 +97575,14 @@
97575 ** This function is called to generate code executed when a row is deleted
97576 ** from the parent table of foreign key constraint pFKey and, if pFKey is
97577 ** deferred, when a row is inserted into the same table. When generating
97578 ** code for an SQL UPDATE operation, this function may be called twice -
97579 ** once to "delete" the old row and once to "insert" the new row.
97580 **
97581 ** Parameter nIncr is passed -1 when inserting a row (as this may decrease
97582 ** the number of FK violations in the db) or +1 when deleting one (as this
97583 ** may increase the number of FK constraint problems).
97584 **
97585 ** The code generated by this function scans through the rows in the child
97586 ** table that correspond to the parent table row being deleted or inserted.
97587 ** For each child row found, one of the following actions is taken:
97588 **
@@ -97525,17 +97696,13 @@
97696 sNameContext.pSrcList = pSrc;
97697 sNameContext.pParse = pParse;
97698 sqlite3ResolveExprNames(&sNameContext, pWhere);
97699
97700 /* Create VDBE to loop through the entries in pSrc that match the WHERE
97701 ** clause. For each row found, increment either the deferred or immediate
97702 ** foreign key constraint counter. */
 
97703 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
 
 
 
97704 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
97705 if( pWInfo ){
97706 sqlite3WhereEnd(pWInfo);
97707 }
97708
@@ -97709,10 +97876,28 @@
97876 }
97877 }
97878 }
97879 return 0;
97880 }
97881
97882 /*
97883 ** Return true if the parser passed as the first argument is being
97884 ** used to code a trigger that is really a "SET NULL" action belonging
97885 ** to trigger pFKey.
97886 */
97887 static int isSetNullAction(Parse *pParse, FKey *pFKey){
97888 Parse *pTop = sqlite3ParseToplevel(pParse);
97889 if( pTop->pTriggerPrg ){
97890 Trigger *p = pTop->pTriggerPrg->pTrigger;
97891 if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
97892 || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
97893 ){
97894 return 1;
97895 }
97896 }
97897 return 0;
97898 }
97899
97900 /*
97901 ** This function is called when inserting, deleting or updating a row of
97902 ** table pTab to generate VDBE code to perform foreign key constraint
97903 ** processing for the operation.
@@ -97762,11 +97947,11 @@
97947 Index *pIdx = 0; /* Index on key columns in pTo */
97948 int *aiFree = 0;
97949 int *aiCol;
97950 int iCol;
97951 int i;
97952 int bIgnore = 0;
97953
97954 if( aChange
97955 && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
97956 && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
97957 ){
@@ -97821,11 +98006,11 @@
98006 ** values read from the parent table are NULL. */
98007 if( db->xAuth ){
98008 int rcauth;
98009 char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
98010 rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
98011 bIgnore = (rcauth==SQLITE_IGNORE);
98012 }
98013 #endif
98014 }
98015
98016 /* Take a shared-cache advisory read-lock on the parent table. Allocate
@@ -97836,16 +98021,22 @@
98021
98022 if( regOld!=0 ){
98023 /* A row is being removed from the child table. Search for the parent.
98024 ** If the parent does not exist, removing the child row resolves an
98025 ** outstanding foreign key constraint violation. */
98026 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
98027 }
98028 if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
98029 /* A row is being added to the child table. If a parent row cannot
98030 ** be found, adding the child row has violated the FK constraint.
98031 **
98032 ** If this operation is being performed as part of a trigger program
98033 ** that is actually a "SET NULL" action belonging to this very
98034 ** foreign key, then omit this scan altogether. As all child key
98035 ** values are guaranteed to be NULL, it is not possible for adding
98036 ** this row to cause an FK violation. */
98037 fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
98038 }
98039
98040 sqlite3DbFree(db, aiFree);
98041 }
98042
@@ -97862,12 +98053,12 @@
98053
98054 if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
98055 && !pParse->pToplevel && !pParse->isMultiWrite
98056 ){
98057 assert( regOld==0 && regNew!=0 );
98058 /* Inserting a single row into a parent table cannot cause (or fix)
98059 ** an immediate foreign key violation. So do nothing in this case. */
98060 continue;
98061 }
98062
98063 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
98064 if( !isIgnoreErrors || db->mallocFailed ) return;
@@ -97887,17 +98078,32 @@
98078
98079 if( regNew!=0 ){
98080 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
98081 }
98082 if( regOld!=0 ){
98083 int eAction = pFKey->aAction[aChange!=0];
 
 
 
 
 
98084 fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
98085 /* If this is a deferred FK constraint, or a CASCADE or SET NULL
98086 ** action applies, then any foreign key violations caused by
98087 ** removing the parent key will be rectified by the action trigger.
98088 ** So do not set the "may-abort" flag in this case.
98089 **
98090 ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
98091 ** may-abort flag will eventually be set on this statement anyway
98092 ** (when this function is called as part of processing the UPDATE
98093 ** within the action trigger).
98094 **
98095 ** Note 2: At first glance it may seem like SQLite could simply omit
98096 ** all OP_FkCounter related scans when either CASCADE or SET NULL
98097 ** applies. The trouble starts if the CASCADE or SET NULL action
98098 ** trigger causes other triggers or action rules attached to the
98099 ** child table to fire. In these cases the fk constraint counters
98100 ** might be set incorrectly if any OP_FkCounter related scans are
98101 ** omitted. */
98102 if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
98103 sqlite3MayAbort(pParse);
98104 }
98105 }
98106 pItem->zName = 0;
98107 sqlite3SrcListDelete(db, pSrc);
98108 }
98109 sqlite3DbFree(db, aiCol);
@@ -100987,11 +101193,10 @@
101193 # define sqlite3_column_database_name16 0
101194 # define sqlite3_column_table_name 0
101195 # define sqlite3_column_table_name16 0
101196 # define sqlite3_column_origin_name 0
101197 # define sqlite3_column_origin_name16 0
 
101198 #endif
101199
101200 #ifdef SQLITE_OMIT_AUTHORIZATION
101201 # define sqlite3_set_authorizer 0
101202 #endif
@@ -101797,10 +102002,11 @@
102002 #define PragTyp_KEY 38
102003 #define PragTyp_REKEY 39
102004 #define PragTyp_LOCK_STATUS 40
102005 #define PragTyp_PARSER_TRACE 41
102006 #define PragFlag_NeedSchema 0x01
102007 #define PragFlag_ReadOnly 0x02
102008 static const struct sPragmaNames {
102009 const char *const zName; /* Name of pragma */
102010 u8 ePragTyp; /* PragTyp_XXX value */
102011 u8 mPragFlag; /* Zero or more PragFlag_XXX values */
102012 u32 iArg; /* Extra argument */
@@ -101813,11 +102019,11 @@
102019 #endif
102020 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102021 { /* zName: */ "application_id",
102022 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102023 /* ePragFlag: */ 0,
102024 /* iArg: */ BTREE_APPLICATION_ID },
102025 #endif
102026 #if !defined(SQLITE_OMIT_AUTOVACUUM)
102027 { /* zName: */ "auto_vacuum",
102028 /* ePragTyp: */ PragTyp_AUTO_VACUUM,
102029 /* ePragFlag: */ PragFlag_NeedSchema,
@@ -101879,10 +102085,16 @@
102085 { /* zName: */ "data_store_directory",
102086 /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
102087 /* ePragFlag: */ 0,
102088 /* iArg: */ 0 },
102089 #endif
102090 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102091 { /* zName: */ "data_version",
102092 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102093 /* ePragFlag: */ PragFlag_ReadOnly,
102094 /* iArg: */ BTREE_DATA_VERSION },
102095 #endif
102096 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
102097 { /* zName: */ "database_list",
102098 /* ePragTyp: */ PragTyp_DATABASE_LIST,
102099 /* ePragFlag: */ PragFlag_NeedSchema,
102100 /* iArg: */ 0 },
@@ -101934,12 +102146,12 @@
102146 #endif
102147 #endif
102148 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102149 { /* zName: */ "freelist_count",
102150 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102151 /* ePragFlag: */ PragFlag_ReadOnly,
102152 /* iArg: */ BTREE_FREE_PAGE_COUNT },
102153 #endif
102154 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
102155 { /* zName: */ "full_column_names",
102156 /* ePragTyp: */ PragTyp_FLAG,
102157 /* ePragFlag: */ 0,
@@ -102087,11 +102299,11 @@
102299 #endif
102300 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102301 { /* zName: */ "schema_version",
102302 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102303 /* ePragFlag: */ 0,
102304 /* iArg: */ BTREE_SCHEMA_VERSION },
102305 #endif
102306 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
102307 { /* zName: */ "secure_delete",
102308 /* ePragTyp: */ PragTyp_SECURE_DELETE,
102309 /* ePragFlag: */ 0,
@@ -102153,11 +102365,11 @@
102365 /* iArg: */ 0 },
102366 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
102367 { /* zName: */ "user_version",
102368 /* ePragTyp: */ PragTyp_HEADER_VALUE,
102369 /* ePragFlag: */ 0,
102370 /* iArg: */ BTREE_USER_VERSION },
102371 #endif
102372 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
102373 #if defined(SQLITE_DEBUG)
102374 { /* zName: */ "vdbe_addoptrace",
102375 /* ePragTyp: */ PragTyp_FLAG,
@@ -102196,11 +102408,11 @@
102408 /* ePragTyp: */ PragTyp_FLAG,
102409 /* ePragFlag: */ 0,
102410 /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
102411 #endif
102412 };
102413 /* Number of pragmas: 58 on by default, 71 total. */
102414 /* End of the automatically generated pragma table.
102415 ***************************************************************************/
102416
102417 /*
102418 ** Interpret the given string as a safety level. Return 0 for OFF,
@@ -103806,11 +104018,12 @@
104018 !(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
104019 DbHasProperty(db, 0, DB_Empty)
104020 ){
104021 for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
104022 if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
104023 SCHEMA_ENC(db) = ENC(db) =
104024 pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
104025 break;
104026 }
104027 }
104028 if( !pEnc->zName ){
104029 sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
@@ -103851,28 +104064,13 @@
104064 **
104065 ** The user-version is not used internally by SQLite. It may be used by
104066 ** applications for any purpose.
104067 */
104068 case PragTyp_HEADER_VALUE: {
104069 int iCookie = aPragmaNames[mid].iArg; /* Which cookie to read or write */
104070 sqlite3VdbeUsesBtree(v, iDb);
104071 if( zRight && (aPragmaNames[mid].mPragFlag & PragFlag_ReadOnly)==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104072 /* Write the specified cookie value */
104073 static const VdbeOpList setCookie[] = {
104074 { OP_Transaction, 0, 1, 0}, /* 0 */
104075 { OP_Integer, 0, 1, 0}, /* 1 */
104076 { OP_SetCookie, 0, 0, 1}, /* 2 */
@@ -103921,11 +104119,11 @@
104119 break;
104120 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
104121
104122 #ifndef SQLITE_OMIT_WAL
104123 /*
104124 ** PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
104125 **
104126 ** Checkpoint the database.
104127 */
104128 case PragTyp_WAL_CHECKPOINT: {
104129 int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
@@ -103933,10 +104131,12 @@
104131 if( zRight ){
104132 if( sqlite3StrICmp(zRight, "full")==0 ){
104133 eMode = SQLITE_CHECKPOINT_FULL;
104134 }else if( sqlite3StrICmp(zRight, "restart")==0 ){
104135 eMode = SQLITE_CHECKPOINT_RESTART;
104136 }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
104137 eMode = SQLITE_CHECKPOINT_TRUNCATE;
104138 }
104139 }
104140 sqlite3VdbeSetNumCols(v, 3);
104141 pParse->nMem = 3;
104142 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
@@ -104512,13 +104712,15 @@
104712 SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
104713 int i, rc;
104714 int commit_internal = !(db->flags&SQLITE_InternChanges);
104715
104716 assert( sqlite3_mutex_held(db->mutex) );
104717 assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
104718 assert( db->init.busy==0 );
104719 rc = SQLITE_OK;
104720 db->init.busy = 1;
104721 ENC(db) = SCHEMA_ENC(db);
104722 for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
104723 if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
104724 rc = sqlite3InitOne(db, i, pzErrMsg);
104725 if( rc ){
104726 sqlite3ResetOneSchema(db, i);
@@ -109840,11 +110042,11 @@
110042 **
110043 ** SELECT DISTINCT xyz FROM ... ORDER BY xyz
110044 **
110045 ** is transformed to:
110046 **
110047 ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
110048 **
110049 ** The second form is preferred as a single index (or temp-table) may be
110050 ** used for both the ORDER BY and DISTINCT processing. As originally
110051 ** written the query must use a temp-table for at least one of the ORDER
110052 ** BY and DISTINCT, and an index or separate temp-table for the other.
@@ -109853,11 +110055,10 @@
110055 && sqlite3ExprListCompare(sSort.pOrderBy, p->pEList, -1)==0
110056 ){
110057 p->selFlags &= ~SF_Distinct;
110058 p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
110059 pGroupBy = p->pGroupBy;
 
110060 /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
110061 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
110062 ** original setting of the SF_Distinct flag, not the current setting */
110063 assert( sDistinct.isTnct );
110064 }
@@ -110657,11 +110858,11 @@
110858 ){
110859 int rc;
110860 TabResult res;
110861
110862 #ifdef SQLITE_ENABLE_API_ARMOR
110863 if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT;
110864 #endif
110865 *pazResult = 0;
110866 if( pnColumn ) *pnColumn = 0;
110867 if( pnRow ) *pnRow = 0;
110868 if( pzErrMsg ) *pzErrMsg = 0;
@@ -114808,10 +115009,11 @@
115009 memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
115010 if( pOld!=pWC->aStatic ){
115011 sqlite3DbFree(db, pOld);
115012 }
115013 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
115014 memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
115015 }
115016 pTerm = &pWC->a[idx = pWC->nTerm++];
115017 if( p && ExprHasProperty(p, EP_Unlikely) ){
115018 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
115019 }else{
@@ -117533,11 +117735,11 @@
117735 WhereLevel *pLvl, /* Level to add scanstatus() entry for */
117736 int addrExplain /* Address of OP_Explain (or 0) */
117737 ){
117738 const char *zObj = 0;
117739 WhereLoop *pLoop = pLvl->pWLoop;
117740 if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
117741 zObj = pLoop->u.btree.pIndex->zName;
117742 }else{
117743 zObj = pSrclist->a[pLvl->iFrom].zName;
117744 }
117745 sqlite3VdbeScanStatus(
@@ -118177,14 +118379,13 @@
118379 int iTerm;
118380 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
118381 Expr *pExpr = pWC->a[iTerm].pExpr;
118382 if( &pWC->a[iTerm] == pTerm ) continue;
118383 if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
118384 if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
 
 
118385 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
118386 testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
118387 pExpr = sqlite3ExprDup(db, pExpr, 0);
118388 pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
118389 }
118390 if( pAndExpr ){
118391 pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
@@ -118527,11 +118728,10 @@
118728 sqlite3_free(p->u.vtab.idxStr);
118729 p->u.vtab.needFree = 0;
118730 p->u.vtab.idxStr = 0;
118731 }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
118732 sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
 
118733 sqlite3DbFree(db, p->u.btree.pIndex);
118734 p->u.btree.pIndex = 0;
118735 }
118736 }
118737 }
@@ -125534,10 +125734,13 @@
125734 u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
125735 sqlite3 *db = pParse->db; /* The database connection */
125736 int mxSqlLen; /* Max length of an SQL string */
125737
125738
125739 #ifdef SQLITE_ENABLE_API_ARMOR
125740 if( zSql==0 || pzErrMsg==0 ) return SQLITE_MISUSE_BKPT;
125741 #endif
125742 mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
125743 if( db->nVdbeActive==0 ){
125744 db->u1.isInterrupted = 0;
125745 }
125746 pParse->rc = SQLITE_OK;
@@ -125772,17 +125975,10 @@
125975 */
125976 SQLITE_API int sqlite3_complete(const char *zSql){
125977 u8 state = 0; /* Current state, using numbers defined in header comment */
125978 u8 token; /* Value of the next token */
125979
 
 
 
 
 
 
 
125980 #ifndef SQLITE_OMIT_TRIGGER
125981 /* A complex statement machine used to detect the end of a CREATE TRIGGER
125982 ** statement. This is the normal case.
125983 */
125984 static const u8 trans[8][8] = {
@@ -125807,10 +126003,17 @@
126003 /* 0 INVALID: */ { 1, 0, 2, },
126004 /* 1 START: */ { 1, 1, 2, },
126005 /* 2 NORMAL: */ { 1, 2, 2, },
126006 };
126007 #endif /* SQLITE_OMIT_TRIGGER */
126008
126009 #ifdef SQLITE_ENABLE_API_ARMOR
126010 if( zSql==0 ){
126011 (void)SQLITE_MISUSE_BKPT;
126012 return 0;
126013 }
126014 #endif
126015
126016 while( *zSql ){
126017 switch( *zSql ){
126018 case ';': { /* A semicolon */
126019 token = tkSEMI;
@@ -126109,11 +126312,11 @@
126312 ** If the following function pointer is not NULL and if
126313 ** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
126314 ** I/O active are written using this function. These messages
126315 ** are intended for debugging activity only.
126316 */
126317 /* not-private */ void (*sqlite3IoTrace)(const char*, ...) = 0;
126318 #endif
126319
126320 /*
126321 ** If the following global variable points to a string which is the
126322 ** name of a directory, then that directory will be used to store
@@ -126318,10 +126521,17 @@
126521 ** routine is not threadsafe. But it is safe to invoke this routine
126522 ** on when SQLite is already shut down. If SQLite is already shut down
126523 ** when this routine is invoked, then this routine is a harmless no-op.
126524 */
126525 SQLITE_API int sqlite3_shutdown(void){
126526 #ifdef SQLITE_OMIT_WSD
126527 int rc = sqlite3_wsd_init(4096, 24);
126528 if( rc!=SQLITE_OK ){
126529 return rc;
126530 }
126531 #endif
126532
126533 if( sqlite3GlobalConfig.isInit ){
126534 #ifdef SQLITE_EXTRA_SHUTDOWN
126535 void SQLITE_EXTRA_SHUTDOWN(void);
126536 SQLITE_EXTRA_SHUTDOWN();
126537 #endif
@@ -126633,10 +126843,15 @@
126843 ** heap. */
126844 sqlite3GlobalConfig.nHeap = va_arg(ap, int);
126845 break;
126846 }
126847 #endif
126848
126849 case SQLITE_CONFIG_PMASZ: {
126850 sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int);
126851 break;
126852 }
126853
126854 default: {
126855 rc = SQLITE_ERROR;
126856 break;
126857 }
@@ -127983,14 +128198,17 @@
128198
128199 /* Initialize the output variables to -1 in case an error occurs. */
128200 if( pnLog ) *pnLog = -1;
128201 if( pnCkpt ) *pnCkpt = -1;
128202
128203 assert( SQLITE_CHECKPOINT_PASSIVE==0 );
128204 assert( SQLITE_CHECKPOINT_FULL==1 );
128205 assert( SQLITE_CHECKPOINT_RESTART==2 );
128206 assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
128207 if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
128208 /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
128209 ** mode: */
128210 return SQLITE_MISUSE;
128211 }
128212
128213 sqlite3_mutex_enter(db->mutex);
128214 if( zDb && zDb[0] ){
@@ -128014,11 +128232,13 @@
128232 ** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
128233 ** to contains a zero-length string, all attached databases are
128234 ** checkpointed.
128235 */
128236 SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
128237 /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
128238 ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
128239 return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
128240 }
128241
128242 #ifndef SQLITE_OMIT_WAL
128243 /*
128244 ** Run a checkpoint on database iDb. This is a no-op if database iDb is
@@ -128201,36 +128421,10 @@
128421 */
128422 SQLITE_API const char *sqlite3_errstr(int rc){
128423 return sqlite3ErrStr(rc);
128424 }
128425
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128426 /*
128427 ** Create a new collating function for database "db". The name is zName
128428 ** and the encoding is enc.
128429 */
128430 static int createCollation(
@@ -128270,11 +128464,10 @@
128464 sqlite3ErrorWithMsg(db, SQLITE_BUSY,
128465 "unable to delete/modify collation sequence due to active statements");
128466 return SQLITE_BUSY;
128467 }
128468 sqlite3ExpirePreparedStatements(db);
 
128469
128470 /* If collation sequence pColl was created directly by a call to
128471 ** sqlite3_create_collation, and not generated by synthCollSeq(),
128472 ** then any copies made by synthCollSeq() need to be invalidated.
128473 ** Also, collation destructor - CollSeq.xDel() - function may need
@@ -128775,10 +128968,13 @@
128968 | SQLITE_RecTriggers
128969 #endif
128970 #if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
128971 | SQLITE_ForeignKeys
128972 #endif
128973 #if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
128974 | SQLITE_ReverseOrder
128975 #endif
128976 ;
128977 sqlite3HashInit(&db->aCollSeq);
128978 #ifndef SQLITE_OMIT_VIRTUALTABLE
128979 sqlite3HashInit(&db->aModule);
128980 #endif
@@ -128822,11 +129018,14 @@
129018 rc = SQLITE_NOMEM;
129019 }
129020 sqlite3Error(db, rc);
129021 goto opendb_out;
129022 }
129023 sqlite3BtreeEnter(db->aDb[0].pBt);
129024 db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
129025 if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
129026 sqlite3BtreeLeave(db->aDb[0].pBt);
129027 db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
129028
129029 /* The default safety_level for the main database is 'full'; for the temp
129030 ** database it is 'NONE'. This matches the pager layer defaults.
129031 */
@@ -128980,11 +129179,11 @@
129179 if( zFilename8 ){
129180 rc = openDatabase(zFilename8, ppDb,
129181 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
129182 assert( *ppDb || rc==SQLITE_NOMEM );
129183 if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
129184 SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
129185 }
129186 }else{
129187 rc = SQLITE_NOMEM;
129188 }
129189 sqlite3ValueFree(pVal);
@@ -129176,11 +129375,10 @@
129375
129376 /*
129377 ** Return meta information about a specific column of a database table.
129378 ** See comment in sqlite3.h (sqlite.h.in) for details.
129379 */
 
129380 SQLITE_API int sqlite3_table_column_metadata(
129381 sqlite3 *db, /* Connection handle */
129382 const char *zDbName, /* Database name or NULL */
129383 const char *zTableName, /* Table name */
129384 const char *zColumnName, /* Column name */
@@ -129216,25 +129414,27 @@
129414 pTab = 0;
129415 goto error_out;
129416 }
129417
129418 /* Find the column for which info is requested */
129419 if( zColumnName==0 ){
129420 /* Query for existance of table only */
 
 
 
129421 }else{
129422 for(iCol=0; iCol<pTab->nCol; iCol++){
129423 pCol = &pTab->aCol[iCol];
129424 if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
129425 break;
129426 }
129427 }
129428 if( iCol==pTab->nCol ){
129429 if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
129430 iCol = pTab->iPKey;
129431 pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
129432 }else{
129433 pTab = 0;
129434 goto error_out;
129435 }
129436 }
129437 }
129438
129439 /* The following block stores the meta information that will be returned
129440 ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
@@ -129283,11 +129483,10 @@
129483 sqlite3DbFree(db, zErrMsg);
129484 rc = sqlite3ApiExit(db, rc);
129485 sqlite3_mutex_leave(db->mutex);
129486 return rc;
129487 }
 
129488
129489 /*
129490 ** Sleep for a little while. Return the amount of time slept.
129491 */
129492 SQLITE_API int sqlite3_sleep(int ms){
@@ -129722,32 +129921,34 @@
129921 /*
129922 ** Return the filename of the database associated with a database
129923 ** connection.
129924 */
129925 SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
129926 Btree *pBt;
129927 #ifdef SQLITE_ENABLE_API_ARMOR
129928 if( !sqlite3SafetyCheckOk(db) ){
129929 (void)SQLITE_MISUSE_BKPT;
129930 return 0;
129931 }
129932 #endif
129933 pBt = sqlite3DbNameToBtree(db, zDbName);
129934 return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
129935 }
129936
129937 /*
129938 ** Return 1 if database is read-only or 0 if read/write. Return -1 if
129939 ** no such database exists.
129940 */
129941 SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
129942 Btree *pBt;
129943 #ifdef SQLITE_ENABLE_API_ARMOR
129944 if( !sqlite3SafetyCheckOk(db) ){
129945 (void)SQLITE_MISUSE_BKPT;
129946 return -1;
129947 }
129948 #endif
129949 pBt = sqlite3DbNameToBtree(db, zDbName);
129950 return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
129951 }
129952
129953 /************** End of main.c ************************************************/
129954 /************** Begin file notify.c ******************************************/
@@ -139164,11 +139365,11 @@
139365 ** Return true if the m-value for z is 1 or more. In other words,
139366 ** return true if z contains at least one vowel that is followed
139367 ** by a consonant.
139368 **
139369 ** In this routine z[] is in reverse order. So we are really looking
139370 ** for an instance of a consonant followed by a vowel.
139371 */
139372 static int m_gt_0(const char *z){
139373 while( isVowel(z) ){ z++; }
139374 if( *z==0 ) return 0;
139375 while( isConsonant(z) ){ z++; }
@@ -149954,11 +150155,11 @@
150155 }
150156 i = pCur->nPoint++;
150157 pNew = pCur->aPoint + i;
150158 pNew->rScore = rScore;
150159 pNew->iLevel = iLevel;
150160 assert( iLevel<=RTREE_MAX_DEPTH );
150161 while( i>0 ){
150162 RtreeSearchPoint *pParent;
150163 j = (i-1)/2;
150164 pParent = pCur->aPoint + j;
150165 if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break;
150166
+160 -122
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.8.8"
111111
#define SQLITE_VERSION_NUMBER 3008008
112
-#define SQLITE_SOURCE_ID "2014-11-28 13:35:03 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e"
112
+#define SQLITE_SOURCE_ID "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -199,11 +199,11 @@
199199
** This interface only reports on the compile-time mutex setting
200200
** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
201201
** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
202202
** can be fully or partially disabled using a call to [sqlite3_config()]
203203
** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
204
-** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the
204
+** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the
205205
** sqlite3_threadsafe() function shows only the compile-time setting of
206206
** thread safety, not any run-time changes to that setting made by
207207
** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
208208
** is unchanged by calls to sqlite3_config().)^
209209
**
@@ -1219,11 +1219,11 @@
12191219
** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
12201220
** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
12211221
** </ul>
12221222
**
12231223
** 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.
12251225
**
12261226
** The xShmLock method can transition between unlocked and SHARED or
12271227
** between unlocked and EXCLUSIVE. It cannot transition between SHARED
12281228
** and EXCLUSIVE.
12291229
*/
@@ -1522,12 +1522,12 @@
15221522
** tracks memory usage, for example. </dd>
15231523
**
15241524
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
15251525
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
15261526
** 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:
15291529
** <ul>
15301530
** <li> [sqlite3_memory_used()]
15311531
** <li> [sqlite3_memory_highwater()]
15321532
** <li> [sqlite3_soft_heap_limit64()]
15331533
** <li> [sqlite3_status()]
@@ -1564,14 +1564,15 @@
15641564
** that SQLite can use for the database page cache with the default page
15651565
** cache implementation.
15661566
** This configuration should not be used if an application-define page
15671567
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
15681568
** 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
15701571
** memory, the size of each page buffer (sz), and the number of pages (N).
15711572
** 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
+** (a power of two between 512 and 65536) plus some extra bytes for each
15731574
** page header. ^The number of extra bytes needed by the page header
15741575
** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option
15751576
** to [sqlite3_config()].
15761577
** ^It is harmless, apart from the wasted memory,
15771578
** for the sz parameter to be larger than necessary. The first
@@ -1584,11 +1585,12 @@
15841585
** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
15851586
**
15861587
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
15871588
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
15881589
** 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].
15901592
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
15911593
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
15921594
** [SQLITE_ERROR] if invoked otherwise.
15931595
** ^There are three arguments to SQLITE_CONFIG_HEAP:
15941596
** An 8-byte aligned pointer to the memory,
@@ -1604,13 +1606,13 @@
16041606
** for the minimum allocation size are 2**5 through 2**8.</dd>
16051607
**
16061608
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
16071609
** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
16081610
** 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
16121614
** [sqlite3_config()] returns. ^If SQLite is compiled with
16131615
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
16141616
** the entire mutexing subsystem is omitted from the build and hence calls to
16151617
** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
16161618
** return [SQLITE_ERROR].</dd>
@@ -1644,12 +1646,12 @@
16441646
** the interface to a custom page cache implementation.)^
16451647
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
16461648
**
16471649
** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
16481650
** <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>
16511653
**
16521654
** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
16531655
** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
16541656
** global [error log].
16551657
** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
@@ -1670,12 +1672,13 @@
16701672
** function must be threadsafe. </dd>
16711673
**
16721674
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
16731675
** <dd>^(The SQLITE_CONFIG_URI option takes a single argument of type int.
16741676
** 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
16771680
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
16781681
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
16791682
** connection is opened. ^If it is globally disabled, filenames are
16801683
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
16811684
** database connection is opened. ^(By default, URI handling is globally
@@ -1733,22 +1736,33 @@
17331736
** changed to its compile-time default.
17341737
**
17351738
** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
17361739
** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
17371740
** <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
17401743
** that specifies the maximum size of the created heap.
17411744
** </dl>
17421745
**
17431746
** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
17441747
** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
17451748
** <dd>^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which
17461749
** 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,
17491752
** target platform, and SQLite version.
1753
+**
1754
+** [[SQLITE_CONFIG_PMASZ]]
1755
+** <dt>SQLITE_CONFIG_PMASZ
1756
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
1757
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
1758
+** sorter to that integer. The default minimum PMA Size is set by the
1759
+** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched
1760
+** to help with sort operations when multithreaded sorting
1761
+** is enabled (using the [PRAGMA threads] command) and the amount of content
1762
+** to be sorted exceeds the page size times the minimum of the
1763
+** [PRAGMA cache_size] setting and this value.
17501764
** </dl>
17511765
*/
17521766
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
17531767
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
17541768
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1771,10 +1785,11 @@
17711785
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
17721786
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
17731787
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
17741788
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
17751789
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
1790
+#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
17761791
17771792
/*
17781793
** CAPI3REF: Database Connection Configuration Options
17791794
**
17801795
** These constants are the available integer configuration options that
@@ -2047,10 +2062,11 @@
20472062
SQLITE_API int sqlite3_complete(const char *sql);
20482063
SQLITE_API int sqlite3_complete16(const void *sql);
20492064
20502065
/*
20512066
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
2067
+** KEYWORDS: {busy-handler callback} {busy handler}
20522068
**
20532069
** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
20542070
** that might be invoked with argument P whenever
20552071
** an attempt is made to access a database table associated with
20562072
** [database connection] D when another thread
@@ -2063,11 +2079,11 @@
20632079
** is not NULL, then the callback might be invoked with two arguments.
20642080
**
20652081
** ^The first argument to the busy handler is a copy of the void* pointer which
20662082
** is the third argument to sqlite3_busy_handler(). ^The second argument to
20672083
** the busy handler callback is the number of times that the busy handler has
2068
-** been invoked for the same locking event. ^If the
2084
+** been invoked previously for the same locking event. ^If the
20692085
** busy callback returns 0, then no additional attempts are made to
20702086
** access the database and [SQLITE_BUSY] is returned
20712087
** to the application.
20722088
** ^If the callback returns non-zero, then another attempt
20732089
** is made to access the database and the cycle repeats.
@@ -4518,11 +4534,12 @@
45184534
** If these routines are called from within the different thread
45194535
** than the one containing the application-defined function that received
45204536
** the [sqlite3_context] pointer, the results are undefined.
45214537
*/
45224538
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*));
4539
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
4540
+ sqlite3_uint64,void(*)(void*));
45244541
SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
45254542
SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
45264543
SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
45274544
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
45284545
SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
@@ -5150,24 +5167,31 @@
51505167
51515168
51525169
/*
51535170
** CAPI3REF: Extract Metadata About A Column Of A Table
51545171
**
5155
-** ^This routine returns metadata about a specific column of a specific
5156
-** database table accessible using the [database connection] handle
5157
-** passed as the first function argument.
5172
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
5173
+** information about column C of table T in database D
5174
+** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
5175
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
5176
+** the final five arguments with appropriate values if the specified
5177
+** column exists. ^The sqlite3_table_column_metadata() interface returns
5178
+** SQLITE_ERROR and if the specified column does not exist.
5179
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
5180
+** NULL pointer, then this routine simply checks for the existance of the
5181
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
5182
+** does not.
51585183
**
51595184
** ^The column is identified by the second, third and fourth parameters to
5160
-** this function. ^The second parameter is either the name of the database
5185
+** this function. ^(The second parameter is either the name of the database
51615186
** (i.e. "main", "temp", or an attached database) containing the specified
5162
-** table or NULL. ^If it is NULL, then all attached databases are searched
5187
+** table or NULL.)^ ^If it is NULL, then all attached databases are searched
51635188
** for the table using the same algorithm used by the database engine to
51645189
** resolve unqualified table references.
51655190
**
51665191
** ^The third and fourth parameters to this function are the table and column
5167
-** name of the desired column, respectively. Neither of these parameters
5168
-** may be NULL.
5192
+** name of the desired column, respectively.
51695193
**
51705194
** ^Metadata is returned by writing to the memory locations passed as the 5th
51715195
** and subsequent parameters to this function. ^Any of these arguments may be
51725196
** NULL, in which case the corresponding element of metadata is omitted.
51735197
**
@@ -5182,36 +5206,33 @@
51825206
** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
51835207
** </table>
51845208
** </blockquote>)^
51855209
**
51865210
** ^The memory pointed to by the character pointers returned for the
5187
-** declaration type and collation sequence is valid only until the next
5211
+** declaration type and collation sequence is valid until the next
51885212
** call to any SQLite API function.
51895213
**
51905214
** ^If the specified table is actually a view, an [error code] is returned.
51915215
**
5192
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
5216
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table
5217
+** is not a [WITHOUT ROWID] table and an
51935218
** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
51945219
** parameters are set for the explicitly declared column. ^(If there is no
5195
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
5196
-** parameters are set as follows:
5220
+** [INTEGER PRIMARY KEY] column, then the outputs
5221
+** for the [rowid] are set as follows:
51975222
**
51985223
** <pre>
51995224
** data type: "INTEGER"
52005225
** collation sequence: "BINARY"
52015226
** not null: 0
52025227
** primary key: 1
52035228
** auto increment: 0
52045229
** </pre>)^
52055230
**
5206
-** ^(This function may load one or more schemas from database files. If an
5207
-** error occurs during this process, or if the requested table or column
5208
-** cannot be found, an [error code] is returned and an error message left
5209
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
5210
-**
5211
-** ^This API is only available if the library was compiled with the
5212
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
5231
+** ^This function causes all database schemas to be read from disk and
5232
+** parsed, if that has not already been done, and returns an error if
5233
+** any errors are encountered while loading the schema.
52135234
*/
52145235
SQLITE_API int sqlite3_table_column_metadata(
52155236
sqlite3 *db, /* Connection handle */
52165237
const char *zDbName, /* Database name or NULL */
52175238
const char *zTableName, /* Table name */
@@ -7174,16 +7195,14 @@
71747195
71757196
/*
71767197
** CAPI3REF: Write-Ahead Log Commit Hook
71777198
**
71787199
** ^The [sqlite3_wal_hook()] function is used to register a callback that
7179
-** will be invoked each time a database connection commits data to a
7180
-** [write-ahead log] (i.e. whenever a transaction is committed in
7181
-** [journal_mode | journal_mode=WAL mode]).
7200
+** is invoked each time data is committed to a database in wal mode.
71827201
**
7183
-** ^The callback is invoked by SQLite after the commit has taken place and
7184
-** the associated write-lock on the database released, so the implementation
7202
+** ^(The callback is invoked by SQLite after the commit has taken place and
7203
+** the associated write-lock on the database released)^, so the implementation
71857204
** may read, write or [checkpoint] the database as required.
71867205
**
71877206
** ^The first parameter passed to the callback function when it is invoked
71887207
** is a copy of the third parameter passed to sqlite3_wal_hook() when
71897208
** registering the callback. ^The second is a copy of the database handle.
@@ -7244,101 +7263,118 @@
72447263
SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
72457264
72467265
/*
72477266
** CAPI3REF: Checkpoint a database
72487267
**
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()]
7268
+** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
7269
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
7270
+**
7271
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
7272
+** [write-ahead log] for database X on [database connection] D to be
7273
+** transferred into the database file and for the write-ahead log to
7274
+** be reset. See the [checkpointing] documentation for addition
7275
+** information.
7276
+**
7277
+** This interface used to be the only way to cause a checkpoint to
7278
+** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
7279
+** interface was added. This interface is retained for backwards
7280
+** compatibility and as a convenience for applications that need to manually
7281
+** start a callback but which do not need the full power (and corresponding
7282
+** complication) of [sqlite3_wal_checkpoint_v2()].
72657283
*/
72667284
SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
72677285
72687286
/*
72697287
** CAPI3REF: Checkpoint a database
72707288
**
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:
7289
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
7290
+** operation on database X of [database connection] D in mode M. Status
7291
+** information is written back into integers pointed to by L and C.)^
7292
+** ^(The M parameter must be a valid [checkpoint mode]:)^
72747293
**
72757294
** <dl>
72767295
** <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.
7296
+** ^Checkpoint as many frames as possible without waiting for any database
7297
+** readers or writers to finish, then sync the database file if all frames
7298
+** in the log were checkpointed. ^The [busy-handler callback]
7299
+** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
7300
+** ^On the other hand, passive mode might leave the checkpoint unfinished
7301
+** if there are concurrent readers or writers.
72827302
**
72837303
** <dt>SQLITE_CHECKPOINT_FULL<dd>
7284
-** This mode blocks (it invokes the
7304
+** ^This mode blocks (it invokes the
72857305
** [sqlite3_busy_handler|busy-handler callback]) until there is no
72867306
** 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.
7307
+** snapshot. ^It then checkpoints all frames in the log file and syncs the
7308
+** database file. ^This mode blocks new database writers while it is pending,
7309
+** but new database readers are allowed to continue unimpeded.
72907310
**
72917311
** <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.
7312
+** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
7313
+** that after checkpointing the log file it blocks (calls the
7314
+** [busy-handler callback])
7315
+** until all readers are reading from the database file only. ^This ensures
7316
+** that the next writer will restart the log file from the beginning.
7317
+** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
7318
+** database writer attempts while it is pending, but does not impede readers.
7319
+**
7320
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
7321
+** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
7322
+** addition that it also truncates the log file to zero bytes just prior
7323
+** to a successful return.
72997324
** </dl>
73007325
**
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.
7326
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
7327
+** the log file or to -1 if the checkpoint could not run because
7328
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
7329
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
7330
+** log file (including any that were already checkpointed before the function
7331
+** was called) or to -1 if the checkpoint could not run due to an error or
7332
+** because the database is not in WAL mode. ^Note that upon successful
7333
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
7334
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
73087335
**
7309
-** All calls obtain an exclusive "checkpoint" lock on the database file. If
7336
+** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
73107337
** 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
7338
+** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a
73127339
** busy-handler configured, it will not be invoked in this case.
73137340
**
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
7341
+** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the
7342
+** exclusive "writer" lock on the database file. ^If the writer lock cannot be
7343
+** obtained immediately, and a busy-handler is configured, it is invoked and
7344
+** the writer lock retried until either the busy-handler returns 0 or the lock
7345
+** is successfully obtained. ^The busy-handler is also invoked while waiting for
7346
+** database readers as described above. ^If the busy-handler returns 0 before
73207347
** the writer lock is obtained or while waiting for database readers, the
73217348
** checkpoint operation proceeds from that point in the same way as
73227349
** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
7323
-** without blocking any further. SQLITE_BUSY is returned in this case.
7350
+** without blocking any further. ^SQLITE_BUSY is returned in this case.
73247351
**
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
7352
+** ^If parameter zDb is NULL or points to a zero length string, then the
7353
+** specified operation is attempted on all WAL databases [attached] to
7354
+** [database connection] db. In this case the
7355
+** values written to output parameters *pnLog and *pnCkpt are undefined. ^If
73287356
** an SQLITE_BUSY error is encountered when processing one or more of the
73297357
** 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
7358
+** attached databases and SQLITE_BUSY is returned at the end. ^If any other
73317359
** error occurs while processing an attached database, processing is abandoned
7332
-** and the error code returned to the caller immediately. If no error
7360
+** and the error code is returned to the caller immediately. ^If no error
73337361
** (SQLITE_BUSY or otherwise) is encountered while processing the attached
73347362
** databases, SQLITE_OK is returned.
73357363
**
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
7364
+** ^If database zDb is the name of an attached database that is not in WAL
7365
+** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
73387366
** zDb is not NULL (or a zero length string) and is not the name of any
73397367
** attached database, SQLITE_ERROR is returned to the caller.
7368
+**
7369
+** ^Unless it returns SQLITE_MISUSE,
7370
+** the sqlite3_wal_checkpoint_v2() interface
7371
+** sets the error information that is queried by
7372
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
7373
+**
7374
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
7375
+** from SQL.
73407376
*/
73417377
SQLITE_API int sqlite3_wal_checkpoint_v2(
73427378
sqlite3 *db, /* Database handle */
73437379
const char *zDb, /* Name of attached database (or NULL) */
73447380
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7345,20 +7381,22 @@
73457381
int *pnLog, /* OUT: Size of WAL log in frames */
73467382
int *pnCkpt /* OUT: Total number of frames checkpointed */
73477383
);
73487384
73497385
/*
7350
-** CAPI3REF: Checkpoint operation parameters
7386
+** CAPI3REF: Checkpoint Mode Values
7387
+** KEYWORDS: {checkpoint mode}
73517388
**
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.
7389
+** These constants define all valid values for the "checkpoint mode" passed
7390
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
7391
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
7392
+** meaning of each of these checkpoint modes.
73567393
*/
7357
-#define SQLITE_CHECKPOINT_PASSIVE 0
7358
-#define SQLITE_CHECKPOINT_FULL 1
7359
-#define SQLITE_CHECKPOINT_RESTART 2
7394
+#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
7395
+#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
7396
+#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
7397
+#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
73607398
73617399
/*
73627400
** CAPI3REF: Virtual Table Interface Configuration
73637401
**
73647402
** This function may be called by either the [xConnect] or [xCreate] method
@@ -7453,16 +7491,16 @@
74537491
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
74547492
** different metric for sqlite3_stmt_scanstatus() to return.
74557493
**
74567494
** <dl>
74577495
** [[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>
7496
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
7497
+** set to the total number of times that the X-th loop has run.</dd>
74607498
**
74617499
** [[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>
7500
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
7501
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
74647502
**
74657503
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
74667504
** <dd>^The "double" variable pointed to by the T parameter will be set to the
74677505
** query planner's estimate for the average number of rows output from each
74687506
** iteration of the X-th loop. If the query planner's estimates was accurate,
@@ -7469,18 +7507,18 @@
74697507
** then this value will approximate the quotient NVISIT/NLOOP and the
74707508
** product of this value for all prior loops with the same SELECTID will
74717509
** be the NLOOP value for the current loop.
74727510
**
74737511
** [[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.
7512
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
7513
+** to a zero-terminated UTF-8 string containing the name of the index or table
7514
+** used for the X-th loop.
74777515
**
74787516
** [[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.
7517
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
7518
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
7519
+** description for the X-th loop.
74827520
**
74837521
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
74847522
** <dd>^The "int" variable pointed to by the T parameter will be set to the
74857523
** "select-id" for the X-th loop. The select-id identifies which query or
74867524
** subquery the loop is part of. The main query has a select-id of zero.
@@ -7499,12 +7537,12 @@
74997537
** CAPI3REF: Prepared Statement Scan Status
75007538
**
75017539
** Return status data for a single loop within query pStmt.
75027540
**
75037541
** 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.
7542
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
7543
+** of this interface is undefined.
75067544
** ^The requested measurement is written into a variable pointed to by
75077545
** the "pOut" parameter.
75087546
** Parameter "idx" identifies the specific loop to retrieve statistics for.
75097547
** Loops are numbered starting from zero. ^If idx is out of range - less than
75107548
** zero or greater than or equal to the total number of loops used to implement
75117549
--- 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 **
@@ -199,11 +199,11 @@
199 ** This interface only reports on the compile-time mutex setting
200 ** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
201 ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
202 ** can be fully or partially disabled using a call to [sqlite3_config()]
203 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
204 ** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the
205 ** sqlite3_threadsafe() function shows only the compile-time setting of
206 ** thread safety, not any run-time changes to that setting made by
207 ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
208 ** is unchanged by calls to sqlite3_config().)^
209 **
@@ -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,14 +1564,15 @@
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
1575 ** to [sqlite3_config()].
1576 ** ^It is harmless, apart from the wasted memory,
1577 ** for the sz parameter to be larger than necessary. The first
@@ -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,22 +1736,33 @@
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 */
1754 #define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1771,10 +1785,11 @@
1771 #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
1772 #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
1773 #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
1774 #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
1775 #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
 
1776
1777 /*
1778 ** CAPI3REF: Database Connection Configuration Options
1779 **
1780 ** These constants are the available integer configuration options that
@@ -2047,10 +2062,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 +2079,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 +4534,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*);
@@ -5150,24 +5167,31 @@
5150
5151
5152 /*
5153 ** CAPI3REF: Extract Metadata About A Column Of A Table
5154 **
5155 ** ^This routine returns metadata about a specific column of a specific
5156 ** database table accessible using the [database connection] handle
5157 ** passed as the first function argument.
 
 
 
 
 
 
 
 
5158 **
5159 ** ^The column is identified by the second, third and fourth parameters to
5160 ** this function. ^The second parameter is either the name of the database
5161 ** (i.e. "main", "temp", or an attached database) containing the specified
5162 ** table or NULL. ^If it is NULL, then all attached databases are searched
5163 ** for the table using the same algorithm used by the database engine to
5164 ** resolve unqualified table references.
5165 **
5166 ** ^The third and fourth parameters to this function are the table and column
5167 ** name of the desired column, respectively. Neither of these parameters
5168 ** may be NULL.
5169 **
5170 ** ^Metadata is returned by writing to the memory locations passed as the 5th
5171 ** and subsequent parameters to this function. ^Any of these arguments may be
5172 ** NULL, in which case the corresponding element of metadata is omitted.
5173 **
@@ -5182,36 +5206,33 @@
5182 ** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
5183 ** </table>
5184 ** </blockquote>)^
5185 **
5186 ** ^The memory pointed to by the character pointers returned for the
5187 ** declaration type and collation sequence is valid only until the next
5188 ** call to any SQLite API function.
5189 **
5190 ** ^If the specified table is actually a view, an [error code] is returned.
5191 **
5192 ** ^If the specified column is "rowid", "oid" or "_rowid_" and an
 
5193 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
5194 ** parameters are set for the explicitly declared column. ^(If there is no
5195 ** explicitly declared [INTEGER PRIMARY KEY] column, then the output
5196 ** parameters are set as follows:
5197 **
5198 ** <pre>
5199 ** data type: "INTEGER"
5200 ** collation sequence: "BINARY"
5201 ** not null: 0
5202 ** primary key: 1
5203 ** auto increment: 0
5204 ** </pre>)^
5205 **
5206 ** ^(This function may load one or more schemas from database files. If an
5207 ** error occurs during this process, or if the requested table or column
5208 ** cannot be found, an [error code] is returned and an error message left
5209 ** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
5210 **
5211 ** ^This API is only available if the library was compiled with the
5212 ** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
5213 */
5214 SQLITE_API int sqlite3_table_column_metadata(
5215 sqlite3 *db, /* Connection handle */
5216 const char *zDbName, /* Database name or NULL */
5217 const char *zTableName, /* Table name */
@@ -7174,16 +7195,14 @@
7174
7175 /*
7176 ** CAPI3REF: Write-Ahead Log Commit Hook
7177 **
7178 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
7179 ** will be invoked each time a database connection commits data to a
7180 ** [write-ahead log] (i.e. whenever a transaction is committed in
7181 ** [journal_mode | journal_mode=WAL mode]).
7182 **
7183 ** ^The callback is invoked by SQLite after the commit has taken place and
7184 ** the associated write-lock on the database released, so the implementation
7185 ** may read, write or [checkpoint] the database as required.
7186 **
7187 ** ^The first parameter passed to the callback function when it is invoked
7188 ** is a copy of the third parameter passed to sqlite3_wal_hook() when
7189 ** registering the callback. ^The second is a copy of the database handle.
@@ -7244,101 +7263,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 +7381,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 +7491,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 +7507,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 +7537,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 "2015-01-03 18:59:17 23d4c07eb81db5a5c6beb56b5820f0b6501f1fb6"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -199,11 +199,11 @@
199 ** This interface only reports on the compile-time mutex setting
200 ** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
201 ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
202 ** can be fully or partially disabled using a call to [sqlite3_config()]
203 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
204 ** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the
205 ** sqlite3_threadsafe() function shows only the compile-time setting of
206 ** thread safety, not any run-time changes to that setting made by
207 ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
208 ** is unchanged by calls to sqlite3_config().)^
209 **
@@ -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,14 +1564,15 @@
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 65536) 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
1576 ** to [sqlite3_config()].
1577 ** ^It is harmless, apart from the wasted memory,
1578 ** for the sz parameter to be larger than necessary. The first
@@ -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,22 +1736,33 @@
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 **
1754 ** [[SQLITE_CONFIG_PMASZ]]
1755 ** <dt>SQLITE_CONFIG_PMASZ
1756 ** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
1757 ** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
1758 ** sorter to that integer. The default minimum PMA Size is set by the
1759 ** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched
1760 ** to help with sort operations when multithreaded sorting
1761 ** is enabled (using the [PRAGMA threads] command) and the amount of content
1762 ** to be sorted exceeds the page size times the minimum of the
1763 ** [PRAGMA cache_size] setting and this value.
1764 ** </dl>
1765 */
1766 #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
1767 #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
1768 #define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1771,10 +1785,11 @@
1785 #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
1786 #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
1787 #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
1788 #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
1789 #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
1790 #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
1791
1792 /*
1793 ** CAPI3REF: Database Connection Configuration Options
1794 **
1795 ** These constants are the available integer configuration options that
@@ -2047,10 +2062,11 @@
2062 SQLITE_API int sqlite3_complete(const char *sql);
2063 SQLITE_API int sqlite3_complete16(const void *sql);
2064
2065 /*
2066 ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
2067 ** KEYWORDS: {busy-handler callback} {busy handler}
2068 **
2069 ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
2070 ** that might be invoked with argument P whenever
2071 ** an attempt is made to access a database table associated with
2072 ** [database connection] D when another thread
@@ -2063,11 +2079,11 @@
2079 ** is not NULL, then the callback might be invoked with two arguments.
2080 **
2081 ** ^The first argument to the busy handler is a copy of the void* pointer which
2082 ** is the third argument to sqlite3_busy_handler(). ^The second argument to
2083 ** the busy handler callback is the number of times that the busy handler has
2084 ** been invoked previously for the same locking event. ^If the
2085 ** busy callback returns 0, then no additional attempts are made to
2086 ** access the database and [SQLITE_BUSY] is returned
2087 ** to the application.
2088 ** ^If the callback returns non-zero, then another attempt
2089 ** is made to access the database and the cycle repeats.
@@ -4518,11 +4534,12 @@
4534 ** If these routines are called from within the different thread
4535 ** than the one containing the application-defined function that received
4536 ** the [sqlite3_context] pointer, the results are undefined.
4537 */
4538 SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
4539 SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
4540 sqlite3_uint64,void(*)(void*));
4541 SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
4542 SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
4543 SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
4544 SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
4545 SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
@@ -5150,24 +5167,31 @@
5167
5168
5169 /*
5170 ** CAPI3REF: Extract Metadata About A Column Of A Table
5171 **
5172 ** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
5173 ** information about column C of table T in database D
5174 ** on [database connection] X.)^ ^The sqlite3_table_column_metadata()
5175 ** interface returns SQLITE_OK and fills in the non-NULL pointers in
5176 ** the final five arguments with appropriate values if the specified
5177 ** column exists. ^The sqlite3_table_column_metadata() interface returns
5178 ** SQLITE_ERROR and if the specified column does not exist.
5179 ** ^If the column-name parameter to sqlite3_table_column_metadata() is a
5180 ** NULL pointer, then this routine simply checks for the existance of the
5181 ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
5182 ** does not.
5183 **
5184 ** ^The column is identified by the second, third and fourth parameters to
5185 ** this function. ^(The second parameter is either the name of the database
5186 ** (i.e. "main", "temp", or an attached database) containing the specified
5187 ** table or NULL.)^ ^If it is NULL, then all attached databases are searched
5188 ** for the table using the same algorithm used by the database engine to
5189 ** resolve unqualified table references.
5190 **
5191 ** ^The third and fourth parameters to this function are the table and column
5192 ** name of the desired column, respectively.
 
5193 **
5194 ** ^Metadata is returned by writing to the memory locations passed as the 5th
5195 ** and subsequent parameters to this function. ^Any of these arguments may be
5196 ** NULL, in which case the corresponding element of metadata is omitted.
5197 **
@@ -5182,36 +5206,33 @@
5206 ** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
5207 ** </table>
5208 ** </blockquote>)^
5209 **
5210 ** ^The memory pointed to by the character pointers returned for the
5211 ** declaration type and collation sequence is valid until the next
5212 ** call to any SQLite API function.
5213 **
5214 ** ^If the specified table is actually a view, an [error code] is returned.
5215 **
5216 ** ^If the specified column is "rowid", "oid" or "_rowid_" and the table
5217 ** is not a [WITHOUT ROWID] table and an
5218 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
5219 ** parameters are set for the explicitly declared column. ^(If there is no
5220 ** [INTEGER PRIMARY KEY] column, then the outputs
5221 ** for the [rowid] are set as follows:
5222 **
5223 ** <pre>
5224 ** data type: "INTEGER"
5225 ** collation sequence: "BINARY"
5226 ** not null: 0
5227 ** primary key: 1
5228 ** auto increment: 0
5229 ** </pre>)^
5230 **
5231 ** ^This function causes all database schemas to be read from disk and
5232 ** parsed, if that has not already been done, and returns an error if
5233 ** any errors are encountered while loading the schema.
 
 
 
 
5234 */
5235 SQLITE_API int sqlite3_table_column_metadata(
5236 sqlite3 *db, /* Connection handle */
5237 const char *zDbName, /* Database name or NULL */
5238 const char *zTableName, /* Table name */
@@ -7174,16 +7195,14 @@
7195
7196 /*
7197 ** CAPI3REF: Write-Ahead Log Commit Hook
7198 **
7199 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
7200 ** is invoked each time data is committed to a database in wal mode.
 
 
7201 **
7202 ** ^(The callback is invoked by SQLite after the commit has taken place and
7203 ** the associated write-lock on the database released)^, so the implementation
7204 ** may read, write or [checkpoint] the database as required.
7205 **
7206 ** ^The first parameter passed to the callback function when it is invoked
7207 ** is a copy of the third parameter passed to sqlite3_wal_hook() when
7208 ** registering the callback. ^The second is a copy of the database handle.
@@ -7244,101 +7263,118 @@
7263 SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
7264
7265 /*
7266 ** CAPI3REF: Checkpoint a database
7267 **
7268 ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
7269 ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
7270 **
7271 ** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the
7272 ** [write-ahead log] for database X on [database connection] D to be
7273 ** transferred into the database file and for the write-ahead log to
7274 ** be reset. See the [checkpointing] documentation for addition
7275 ** information.
7276 **
7277 ** This interface used to be the only way to cause a checkpoint to
7278 ** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
7279 ** interface was added. This interface is retained for backwards
7280 ** compatibility and as a convenience for applications that need to manually
7281 ** start a callback but which do not need the full power (and corresponding
7282 ** complication) of [sqlite3_wal_checkpoint_v2()].
 
7283 */
7284 SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
7285
7286 /*
7287 ** CAPI3REF: Checkpoint a database
7288 **
7289 ** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
7290 ** operation on database X of [database connection] D in mode M. Status
7291 ** information is written back into integers pointed to by L and C.)^
7292 ** ^(The M parameter must be a valid [checkpoint mode]:)^
7293 **
7294 ** <dl>
7295 ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
7296 ** ^Checkpoint as many frames as possible without waiting for any database
7297 ** readers or writers to finish, then sync the database file if all frames
7298 ** in the log were checkpointed. ^The [busy-handler callback]
7299 ** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.
7300 ** ^On the other hand, passive mode might leave the checkpoint unfinished
7301 ** if there are concurrent readers or writers.
7302 **
7303 ** <dt>SQLITE_CHECKPOINT_FULL<dd>
7304 ** ^This mode blocks (it invokes the
7305 ** [sqlite3_busy_handler|busy-handler callback]) until there is no
7306 ** database writer and all readers are reading from the most recent database
7307 ** snapshot. ^It then checkpoints all frames in the log file and syncs the
7308 ** database file. ^This mode blocks new database writers while it is pending,
7309 ** but new database readers are allowed to continue unimpeded.
7310 **
7311 ** <dt>SQLITE_CHECKPOINT_RESTART<dd>
7312 ** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
7313 ** that after checkpointing the log file it blocks (calls the
7314 ** [busy-handler callback])
7315 ** until all readers are reading from the database file only. ^This ensures
7316 ** that the next writer will restart the log file from the beginning.
7317 ** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
7318 ** database writer attempts while it is pending, but does not impede readers.
7319 **
7320 ** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
7321 ** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
7322 ** addition that it also truncates the log file to zero bytes just prior
7323 ** to a successful return.
7324 ** </dl>
7325 **
7326 ** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
7327 ** the log file or to -1 if the checkpoint could not run because
7328 ** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
7329 ** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
7330 ** log file (including any that were already checkpointed before the function
7331 ** was called) or to -1 if the checkpoint could not run due to an error or
7332 ** because the database is not in WAL mode. ^Note that upon successful
7333 ** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
7334 ** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
7335 **
7336 ** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
7337 ** any other process is running a checkpoint operation at the same time, the
7338 ** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a
7339 ** busy-handler configured, it will not be invoked in this case.
7340 **
7341 ** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the
7342 ** exclusive "writer" lock on the database file. ^If the writer lock cannot be
7343 ** obtained immediately, and a busy-handler is configured, it is invoked and
7344 ** the writer lock retried until either the busy-handler returns 0 or the lock
7345 ** is successfully obtained. ^The busy-handler is also invoked while waiting for
7346 ** database readers as described above. ^If the busy-handler returns 0 before
7347 ** the writer lock is obtained or while waiting for database readers, the
7348 ** checkpoint operation proceeds from that point in the same way as
7349 ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
7350 ** without blocking any further. ^SQLITE_BUSY is returned in this case.
7351 **
7352 ** ^If parameter zDb is NULL or points to a zero length string, then the
7353 ** specified operation is attempted on all WAL databases [attached] to
7354 ** [database connection] db. In this case the
7355 ** values written to output parameters *pnLog and *pnCkpt are undefined. ^If
7356 ** an SQLITE_BUSY error is encountered when processing one or more of the
7357 ** attached WAL databases, the operation is still attempted on any remaining
7358 ** attached databases and SQLITE_BUSY is returned at the end. ^If any other
7359 ** error occurs while processing an attached database, processing is abandoned
7360 ** and the error code is returned to the caller immediately. ^If no error
7361 ** (SQLITE_BUSY or otherwise) is encountered while processing the attached
7362 ** databases, SQLITE_OK is returned.
7363 **
7364 ** ^If database zDb is the name of an attached database that is not in WAL
7365 ** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
7366 ** zDb is not NULL (or a zero length string) and is not the name of any
7367 ** attached database, SQLITE_ERROR is returned to the caller.
7368 **
7369 ** ^Unless it returns SQLITE_MISUSE,
7370 ** the sqlite3_wal_checkpoint_v2() interface
7371 ** sets the error information that is queried by
7372 ** [sqlite3_errcode()] and [sqlite3_errmsg()].
7373 **
7374 ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
7375 ** from SQL.
7376 */
7377 SQLITE_API int sqlite3_wal_checkpoint_v2(
7378 sqlite3 *db, /* Database handle */
7379 const char *zDb, /* Name of attached database (or NULL) */
7380 int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7345,20 +7381,22 @@
7381 int *pnLog, /* OUT: Size of WAL log in frames */
7382 int *pnCkpt /* OUT: Total number of frames checkpointed */
7383 );
7384
7385 /*
7386 ** CAPI3REF: Checkpoint Mode Values
7387 ** KEYWORDS: {checkpoint mode}
7388 **
7389 ** These constants define all valid values for the "checkpoint mode" passed
7390 ** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
7391 ** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
7392 ** meaning of each of these checkpoint modes.
7393 */
7394 #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
7395 #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
7396 #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
7397 #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
7398
7399 /*
7400 ** CAPI3REF: Virtual Table Interface Configuration
7401 **
7402 ** This function may be called by either the [xConnect] or [xCreate] method
@@ -7453,16 +7491,16 @@
7491 ** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
7492 ** different metric for sqlite3_stmt_scanstatus() to return.
7493 **
7494 ** <dl>
7495 ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
7496 ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
7497 ** set to the total number of times that the X-th loop has run.</dd>
7498 **
7499 ** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
7500 ** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
7501 ** to the total number of rows examined by all iterations of the X-th loop.</dd>
7502 **
7503 ** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
7504 ** <dd>^The "double" variable pointed to by the T parameter will be set to the
7505 ** query planner's estimate for the average number of rows output from each
7506 ** iteration of the X-th loop. If the query planner's estimates was accurate,
@@ -7469,18 +7507,18 @@
7507 ** then this value will approximate the quotient NVISIT/NLOOP and the
7508 ** product of this value for all prior loops with the same SELECTID will
7509 ** be the NLOOP value for the current loop.
7510 **
7511 ** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
7512 ** <dd>^The "const char *" variable pointed to by the T parameter will be set
7513 ** to a zero-terminated UTF-8 string containing the name of the index or table
7514 ** used for the X-th loop.
7515 **
7516 ** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
7517 ** <dd>^The "const char *" variable pointed to by the T parameter will be set
7518 ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
7519 ** description for the X-th loop.
7520 **
7521 ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
7522 ** <dd>^The "int" variable pointed to by the T parameter will be set to the
7523 ** "select-id" for the X-th loop. The select-id identifies which query or
7524 ** subquery the loop is part of. The main query has a select-id of zero.
@@ -7499,12 +7537,12 @@
7537 ** CAPI3REF: Prepared Statement Scan Status
7538 **
7539 ** Return status data for a single loop within query pStmt.
7540 **
7541 ** The "iScanStatusOp" parameter determines which status information to return.
7542 ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
7543 ** of this interface is undefined.
7544 ** ^The requested measurement is written into a variable pointed to by
7545 ** the "pOut" parameter.
7546 ** Parameter "idx" identifies the specific loop to retrieve statistics for.
7547 ** Loops are numbered starting from zero. ^If idx is out of range - less than
7548 ** zero or greater than or equal to the total number of loops used to implement
7549
+3 -3
--- src/stat.c
+++ src/stat.c
@@ -77,11 +77,11 @@
7777
if( n>0 ){
7878
int a, b;
7979
Stmt q;
8080
@ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
8181
db_prepare(&q, "SELECT total(size), avg(size), max(size)"
82
- " FROM blob WHERE size>0");
82
+ " FROM blob WHERE size>0 /*scan*/");
8383
db_step(&q);
8484
t = db_column_int64(&q, 0);
8585
szAvg = db_column_int(&q, 1);
8686
szMax = db_column_int(&q, 2);
8787
db_finalize(&q);
@@ -226,19 +226,19 @@
226226
n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
227227
fossil_print("%*s%d across all branches\n", colWidth, "files:", n);
228228
n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
229229
" WHERE tagname GLOB 'wiki-*'");
230230
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);
232232
n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
233233
" WHERE tagname GLOB 'tkt-*'");
234234
m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'");
235235
fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m);
236236
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
237237
fossil_print("%*s%d\n", colWidth, "events:", n);
238238
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);
240240
z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
241241
" CAST(julianday('now') - mtime AS INTEGER)"
242242
" || ' days ago' FROM event "
243243
" ORDER BY mtime DESC LIMIT 1");
244244
fossil_print("%*s%s\n", colWidth, "latest-change:", z);
245245
--- src/stat.c
+++ src/stat.c
@@ -77,11 +77,11 @@
77 if( n>0 ){
78 int a, b;
79 Stmt q;
80 @ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
81 db_prepare(&q, "SELECT total(size), avg(size), max(size)"
82 " FROM blob WHERE size>0");
83 db_step(&q);
84 t = db_column_int64(&q, 0);
85 szAvg = db_column_int(&q, 1);
86 szMax = db_column_int(&q, 2);
87 db_finalize(&q);
@@ -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
@@ -77,11 +77,11 @@
77 if( n>0 ){
78 int a, b;
79 Stmt q;
80 @ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
81 db_prepare(&q, "SELECT total(size), avg(size), max(size)"
82 " FROM blob WHERE size>0 /*scan*/");
83 db_step(&q);
84 t = db_column_int64(&q, 0);
85 szAvg = db_column_int(&q, 1);
86 szMax = db_column_int(&q, 2);
87 db_finalize(&q);
@@ -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
+79 -4
--- src/style.c
+++ src/style.c
@@ -783,10 +783,15 @@
783783
{ ".filetree",
784784
"tree-view file browser",
785785
@ margin: 1em 0;
786786
@ line-height: 1.5;
787787
},
788
+ {
789
+ ".filetree > ul",
790
+ "tree-view top-level list",
791
+ @ display: inline-block;
792
+ },
788793
{ ".filetree ul",
789794
"tree-view lists",
790795
@ margin: 0;
791796
@ padding: 0;
792797
@ list-style: none;
@@ -832,21 +837,37 @@
832837
},
833838
{ ".filetree a",
834839
"tree-view links",
835840
@ position: relative;
836841
@ z-index: 1;
837
- @ display: inline-block;
842
+ @ display: table-cell;
838843
@ min-height: 16px;
839844
@ padding-left: 21px;
840845
@ background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP\/\/\/yEhIf\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAIvlIKpxqcfmgOUvoaqDSCxrEEfF14GqFXImJZsu73wepJzVMNxrtNTj3NATMKhpwAAOw==);
841846
@ background-position: center left;
842847
@ background-repeat: no-repeat;
843848
},
844
- { ".filetree .dir > a",
849
+ { "div.filetreeline",
850
+ "line of a file tree",
851
+ @ display: table;
852
+ @ width: 100%;
853
+ @ white-space: nowrap;
854
+ },
855
+ { ".filetree .dir > div.filetreeline > a",
845856
"tree-view directory links",
846857
@ background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP/WVCIiIv\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAInlI9pwa3XYniCgQtkrAFfLXkiFo1jaXpo+jUs6b5Z/K4siDu5RPUFADs=);
847858
},
859
+ { "div.filetreeage",
860
+ "Last change floating display on the right",
861
+ @ display: table-cell;
862
+ @ padding-left: 3em;
863
+ @ text-align: right;
864
+ },
865
+ { "div.filetreeline:hover",
866
+ "Highlight the line of a file tree",
867
+ @ background-color: #eee;
868
+ },
848869
{ "table.login_out",
849870
"table format for login/out label/input table",
850871
@ text-align: left;
851872
@ margin-right: 10px;
852873
@ margin-left: 10px;
@@ -1211,17 +1232,71 @@
12111232
@ color: black;
12121233
@ background-color: white;
12131234
},
12141235
{ "table.adminLogTable",
12151236
"Class for the /admin_log table",
1216
- @ text-align: left
1237
+ @ text-align: left;
12171238
},
12181239
{ ".adminLogTable .adminTime",
12191240
"Class for the /admin_log table",
1220
- @ text-align: left
1241
+ @ text-align: left;
1242
+ @ vertical-align: top;
1243
+ @ white-space: nowrap;
1244
+ },
1245
+ { ".fileage table",
1246
+ "The fileage table",
1247
+ @ border-spacing: 0;
1248
+ },
1249
+ { ".fileage tr:hover",
1250
+ "Mouse-over effects for the file-age table",
1251
+ @ background-color: #eee;
1252
+ },
1253
+ { ".fileage td",
1254
+ "fileage table cells",
12211255
@ vertical-align: top;
1256
+ @ text-align: left;
1257
+ @ border-top: 1px solid #ddd;
1258
+ @ padding-top: 3px;
1259
+ },
1260
+ { ".fileage td:first-child",
1261
+ "fileage first column (the age)",
12221262
@ white-space: nowrap;
1263
+ },
1264
+ { ".fileage td:nth-child(2)",
1265
+ "fileage second column (the filename)",
1266
+ @ padding-left: 1em;
1267
+ @ padding-right: 1em;
1268
+ },
1269
+ { ".fileage td:nth-child(3)",
1270
+ "fileage third column (the check-in comment)",
1271
+ @ word-break: break-all;
1272
+ @ word-wrap: break-word;
1273
+ @ max-width: 50%;
1274
+ },
1275
+ { ".brlist table", "The list of branches",
1276
+ @ border-spacing: 0;
1277
+ },
1278
+ { ".brlist table th", "Branch list table headers",
1279
+ @ text-align: left;
1280
+ @ padding: 0px 1em 0.5ex 0px;
1281
+ },
1282
+ { ".brlist table td", "Branch list table headers",
1283
+ @ padding: 0px 2em 0px 0px;
1284
+ },
1285
+ { "th.sort:after",
1286
+ "General styles for sortable column marker",
1287
+ @ margin-left: .4em;
1288
+ @ cursor: pointer;
1289
+ @ text-shadow: 0 0 0 #000; /* Makes arrow darker */
1290
+ },
1291
+ { "th.sort.asc:after",
1292
+ "Ascending sort column marker",
1293
+ @ content: '\2193';
1294
+ },
1295
+ { "th.sort.desc:after",
1296
+ "Descending sort column marker",
1297
+ @ content: '\2191';
12231298
},
12241299
{ 0,
12251300
0,
12261301
0
12271302
}
12281303
--- src/style.c
+++ src/style.c
@@ -783,10 +783,15 @@
783 { ".filetree",
784 "tree-view file browser",
785 @ margin: 1em 0;
786 @ line-height: 1.5;
787 },
 
 
 
 
 
788 { ".filetree ul",
789 "tree-view lists",
790 @ margin: 0;
791 @ padding: 0;
792 @ list-style: none;
@@ -832,21 +837,37 @@
832 },
833 { ".filetree a",
834 "tree-view links",
835 @ position: relative;
836 @ z-index: 1;
837 @ display: inline-block;
838 @ min-height: 16px;
839 @ padding-left: 21px;
840 @ background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP\/\/\/yEhIf\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAIvlIKpxqcfmgOUvoaqDSCxrEEfF14GqFXImJZsu73wepJzVMNxrtNTj3NATMKhpwAAOw==);
841 @ background-position: center left;
842 @ background-repeat: no-repeat;
843 },
844 { ".filetree .dir > a",
 
 
 
 
 
 
845 "tree-view directory links",
846 @ background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP/WVCIiIv\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAInlI9pwa3XYniCgQtkrAFfLXkiFo1jaXpo+jUs6b5Z/K4siDu5RPUFADs=);
847 },
 
 
 
 
 
 
 
 
 
 
848 { "table.login_out",
849 "table format for login/out label/input table",
850 @ text-align: left;
851 @ margin-right: 10px;
852 @ margin-left: 10px;
@@ -1211,17 +1232,71 @@
1211 @ color: black;
1212 @ background-color: white;
1213 },
1214 { "table.adminLogTable",
1215 "Class for the /admin_log table",
1216 @ text-align: left
1217 },
1218 { ".adminLogTable .adminTime",
1219 "Class for the /admin_log table",
1220 @ text-align: left
 
 
 
 
 
 
 
 
 
 
 
 
 
1221 @ vertical-align: top;
 
 
 
 
 
 
1222 @ white-space: nowrap;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1223 },
1224 { 0,
1225 0,
1226 0
1227 }
1228
--- src/style.c
+++ src/style.c
@@ -783,10 +783,15 @@
783 { ".filetree",
784 "tree-view file browser",
785 @ margin: 1em 0;
786 @ line-height: 1.5;
787 },
788 {
789 ".filetree > ul",
790 "tree-view top-level list",
791 @ display: inline-block;
792 },
793 { ".filetree ul",
794 "tree-view lists",
795 @ margin: 0;
796 @ padding: 0;
797 @ list-style: none;
@@ -832,21 +837,37 @@
837 },
838 { ".filetree a",
839 "tree-view links",
840 @ position: relative;
841 @ z-index: 1;
842 @ display: table-cell;
843 @ min-height: 16px;
844 @ padding-left: 21px;
845 @ background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP\/\/\/yEhIf\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAIvlIKpxqcfmgOUvoaqDSCxrEEfF14GqFXImJZsu73wepJzVMNxrtNTj3NATMKhpwAAOw==);
846 @ background-position: center left;
847 @ background-repeat: no-repeat;
848 },
849 { "div.filetreeline",
850 "line of a file tree",
851 @ display: table;
852 @ width: 100%;
853 @ white-space: nowrap;
854 },
855 { ".filetree .dir > div.filetreeline > a",
856 "tree-view directory links",
857 @ background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP/WVCIiIv\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAInlI9pwa3XYniCgQtkrAFfLXkiFo1jaXpo+jUs6b5Z/K4siDu5RPUFADs=);
858 },
859 { "div.filetreeage",
860 "Last change floating display on the right",
861 @ display: table-cell;
862 @ padding-left: 3em;
863 @ text-align: right;
864 },
865 { "div.filetreeline:hover",
866 "Highlight the line of a file tree",
867 @ background-color: #eee;
868 },
869 { "table.login_out",
870 "table format for login/out label/input table",
871 @ text-align: left;
872 @ margin-right: 10px;
873 @ margin-left: 10px;
@@ -1211,17 +1232,71 @@
1232 @ color: black;
1233 @ background-color: white;
1234 },
1235 { "table.adminLogTable",
1236 "Class for the /admin_log table",
1237 @ text-align: left;
1238 },
1239 { ".adminLogTable .adminTime",
1240 "Class for the /admin_log table",
1241 @ text-align: left;
1242 @ vertical-align: top;
1243 @ white-space: nowrap;
1244 },
1245 { ".fileage table",
1246 "The fileage table",
1247 @ border-spacing: 0;
1248 },
1249 { ".fileage tr:hover",
1250 "Mouse-over effects for the file-age table",
1251 @ background-color: #eee;
1252 },
1253 { ".fileage td",
1254 "fileage table cells",
1255 @ vertical-align: top;
1256 @ text-align: left;
1257 @ border-top: 1px solid #ddd;
1258 @ padding-top: 3px;
1259 },
1260 { ".fileage td:first-child",
1261 "fileage first column (the age)",
1262 @ white-space: nowrap;
1263 },
1264 { ".fileage td:nth-child(2)",
1265 "fileage second column (the filename)",
1266 @ padding-left: 1em;
1267 @ padding-right: 1em;
1268 },
1269 { ".fileage td:nth-child(3)",
1270 "fileage third column (the check-in comment)",
1271 @ word-break: break-all;
1272 @ word-wrap: break-word;
1273 @ max-width: 50%;
1274 },
1275 { ".brlist table", "The list of branches",
1276 @ border-spacing: 0;
1277 },
1278 { ".brlist table th", "Branch list table headers",
1279 @ text-align: left;
1280 @ padding: 0px 1em 0.5ex 0px;
1281 },
1282 { ".brlist table td", "Branch list table headers",
1283 @ padding: 0px 2em 0px 0px;
1284 },
1285 { "th.sort:after",
1286 "General styles for sortable column marker",
1287 @ margin-left: .4em;
1288 @ cursor: pointer;
1289 @ text-shadow: 0 0 0 #000; /* Makes arrow darker */
1290 },
1291 { "th.sort.asc:after",
1292 "Ascending sort column marker",
1293 @ content: '\2193';
1294 },
1295 { "th.sort.desc:after",
1296 "Descending sort column marker",
1297 @ content: '\2191';
1298 },
1299 { 0,
1300 0,
1301 0
1302 }
1303
+1 -1
--- src/tag.c
+++ src/tag.c
@@ -561,11 +561,11 @@
561561
);
562562
@ <ul>
563563
while( db_step(&q)==SQLITE_ROW ){
564564
const char *zName = db_column_text(&q, 0);
565565
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))
567567
@ %h(zName)</a></li>
568568
}else{
569569
@ <li><span class="tagDsp">%h(zName)</span></li>
570570
}
571571
}
572572
--- 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
+64 -27
--- src/timeline.c
+++ src/timeline.c
@@ -20,10 +20,20 @@
2020
*/
2121
#include "config.h"
2222
#include <string.h>
2323
#include <time.h>
2424
#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
+}
2535
2636
/*
2737
** Generate a hyperlink to a version.
2838
*/
2939
void hyperlink_to_uuid(const char *zUuid){
@@ -77,10 +87,11 @@
7787
#define TIMELINE_FCHANGES 0x0020 /* Detail file changes */
7888
#define TIMELINE_BRCOLOR 0x0040 /* Background color by branch name */
7989
#define TIMELINE_UCOLOR 0x0080 /* Background color by user */
8090
#define TIMELINE_FRENAMES 0x0100 /* Detail only file name changes */
8191
#define TIMELINE_UNHIDE 0x0200 /* Unhide check-ins with "hidden" tag */
92
+#define TIMELINE_SHOWRID 0x0400 /* Show RID values in addition to UUIDs */
8293
#endif
8394
8495
/*
8596
** Hash a string and use the hash to determine a background color.
8697
*/
@@ -394,10 +405,13 @@
394405
}
395406
}else if( zType[0]=='e' && tagid ){
396407
hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
397408
}else if( (tmFlags & TIMELINE_ARTID)!=0 ){
398409
hyperlink_to_uuid(zUuid);
410
+ }
411
+ if( tmFlags & TIMELINE_SHOWRID ){
412
+ @ (%d(rid))
399413
}
400414
db_column_blob(pQuery, commentColumn, &comment);
401415
if( zType[0]!='c' ){
402416
/* Comments for anything other than a check-in are generated by
403417
** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
@@ -417,11 +431,11 @@
417431
/* Generate the "user: USERNAME" at the end of the comment, together
418432
** with a hyperlink to another timeline for that user.
419433
*/
420434
if( zTagList && zTagList[0]==0 ) zTagList = 0;
421435
if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
422
- char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate);
436
+ char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
423437
@ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051")
424438
}else{
425439
@ (user: %h(zDispUser)%s(zTagList?",":"\051")
426440
}
427441
@@ -442,11 +456,11 @@
442456
while( z && z[0] ){
443457
for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
444458
if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
445459
blob_appendf(&links,
446460
"%z%#h</a>%.2s",
447
- href("%R/timeline?r=%#t&nd&c=%t",i,z,zDate), i,z, &z[i]
461
+ href("%R/timeline?r=%#t&nd&c=%t&n=200",i,z,zDate), i,z, &z[i]
448462
);
449463
}else{
450464
blob_appendf(&links, "%#h", i+2, z);
451465
}
452466
if( z[i]==0 ) break;
@@ -456,11 +470,11 @@
456470
blob_reset(&links);
457471
}else{
458472
@ tags: %h(zTagList))
459473
}
460474
}
461
-
475
+ tag_private_status(rid);
462476
463477
/* Generate extra hyperlinks at the end of the comment */
464478
if( xExtra ){
465479
xExtra(rid);
466480
}
@@ -471,11 +485,11 @@
471485
){
472486
int inUl = 0;
473487
if( !fchngQueryInit ){
474488
db_prepare(&fchngQuery,
475489
"SELECT (pid==0) AS isnew,"
476
- " (fid==0) AS isdel,"
490
+ " fid,"
477491
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
478492
" (SELECT uuid FROM blob WHERE rid=fid),"
479493
" (SELECT uuid FROM blob WHERE rid=pid),"
480494
" (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
481495
" FROM mlink"
@@ -488,14 +502,16 @@
488502
}
489503
db_bind_int(&fchngQuery, ":mid", rid);
490504
while( db_step(&fchngQuery)==SQLITE_ROW ){
491505
const char *zFilename = db_column_text(&fchngQuery, 2);
492506
int isNew = db_column_int(&fchngQuery, 0);
493
- int isDel = db_column_int(&fchngQuery, 1);
507
+ int fid = db_column_int(&fchngQuery, 1);
508
+ int isDel = fid==0;
494509
const char *zOldName = db_column_text(&fchngQuery, 5);
495510
const char *zOld = db_column_text(&fchngQuery, 4);
496511
const char *zNew = db_column_text(&fchngQuery, 3);
512
+ const char *zUnpubTag = "";
497513
if( !inUl ){
498514
@ <ul class="filelist">
499515
inUl = 1;
500516
}
501517
if( (tmFlags & TIMELINE_FRENAMES)!=0 ){
@@ -502,23 +518,26 @@
502518
if( !isNew && !isDel && zOldName!=0 ){
503519
@ <li> %h(zOldName) &rarr; %h(zFilename)
504520
}
505521
continue;
506522
}
523
+ if( content_is_private(fid) ){
524
+ zUnpubTag = UNPUB_TAG;
525
+ }
507526
if( isNew ){
508
- @ <li> %h(zFilename) (new file) &nbsp;
527
+ @ <li> %h(zFilename) %s(zUnpubTag) (new file) &nbsp;
509528
@ %z(href("%R/artifact/%s",zNew))[view]</a></li>
510529
}else if( isDel ){
511530
@ <li> %h(zFilename) (deleted)</li>
512531
}else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
513
- @ <li> %h(zOldName) &rarr; %h(zFilename)
532
+ @ <li> %h(zOldName) &rarr; %h(zFilename) %s(zUnpubTag)
514533
@ %z(href("%R/artifact/%s",zNew))[view]</a></li>
515534
}else{
516535
if( zOldName!=0 ){
517
- @ <li> %h(zOldName) &rarr; %h(zFilename)
536
+ @ <li> %h(zOldName) &rarr; %h(zFilename) %s(zUnpubTag)
518537
}else{
519
- @ <li> %h(zFilename) &nbsp;
538
+ @ <li> %h(zFilename) &nbsp; %s(zUnpubTag)
520539
}
521540
@ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li>
522541
}
523542
}
524543
db_reset(&fchngQuery);
@@ -589,12 +608,12 @@
589608
** for the upward portion of a merge arrow. The merge arrow goes up
590609
** to the row identified by mu:. If this value is zero then
591610
** node has no merge children and no merge-out line is drawn.
592611
** mu: The id of the row which is the top of the merge-out arrow.
593612
** u: Draw a thick child-line out of the top of this node and up to
594
- ** the node with an id equal to this value. 0 if there is no
595
- ** thick-line riser.
613
+ ** the node with an id equal to this value. 0 if it is straight to
614
+ ** the top of the page, -1 if there is no thick-line riser.
596615
** f: 0x01: a leaf node.
597616
** au: An array of integers that define thick-line risers for branches.
598617
** The integers are in pairs. For each pair, the first integer is
599618
** is the rail on which the riser should run and the second integer
600619
** is the id of the node upto which the riser should run.
@@ -1055,11 +1074,11 @@
10551074
const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */
10561075
const char *zYearWeek = P("yw"); /* Show checkins for the given YYYY-WW (week-of-year)*/
10571076
int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
10581077
int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
10591078
int tagid; /* Tag ID */
1060
- int tmFlags; /* Timeline flags */
1079
+ int tmFlags = 0; /* Timeline flags */
10611080
const char *zThisTag = 0; /* Suppress links to this tag */
10621081
const char *zThisUser = 0; /* Suppress links to this user */
10631082
HQuery url; /* URL for various branch links */
10641083
int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
10651084
int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
@@ -1088,16 +1107,22 @@
10881107
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
10891108
zThisTag = zBrName;
10901109
}else{
10911110
tagid = 0;
10921111
}
1112
+ if( tagid>0
1113
+ && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
1114
+ ){
1115
+ zCirca = zBefore = zAfter = 0;
1116
+ nEntry = -1;
1117
+ }
10931118
if( zType[0]=='a' ){
1094
- tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH;
1119
+ tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH;
10951120
}else{
1096
- tmFlags = TIMELINE_GRAPH;
1121
+ tmFlags |= TIMELINE_GRAPH;
10971122
}
1098
- url_add_parameter(&url, "n", mprintf("%d", nEntry));
1123
+ if( nEntry>0 ) url_add_parameter(&url, "n", mprintf("%d", nEntry));
10991124
if( P("ng")!=0 || zSearch!=0 ){
11001125
tmFlags &= ~TIMELINE_GRAPH;
11011126
url_add_parameter(&url, "ng", 0);
11021127
}
11031128
if( P("brbg")!=0 ){
@@ -1185,10 +1210,11 @@
11851210
}else if( (p_rid || d_rid) && g.perm.Read ){
11861211
/* If p= or d= is present, ignore all other parameters other than n= */
11871212
char *zUuid;
11881213
int np, nd;
11891214
1215
+ tmFlags |= TIMELINE_DISJOINT;
11901216
if( p_rid && d_rid ){
11911217
if( p_rid!=d_rid ) p_rid = d_rid;
11921218
if( P("n")==0 ) nEntry = 10;
11931219
}
11941220
db_multi_exec(
@@ -1229,11 +1255,11 @@
12291255
url_add_parameter(&url, "d", zUuid);
12301256
}
12311257
if( nEntry>20 ){
12321258
timeline_submenu(&url, "20 Entries", "n", "20", 0);
12331259
}
1234
- if( nEntry<200 ){
1260
+ if( nEntry<200 && nEntry>0 ){
12351261
timeline_submenu(&url, "200 Entries", "n", "200", 0);
12361262
}
12371263
if( tmFlags & TIMELINE_FCHANGES ){
12381264
timeline_submenu(&url, "Hide Files", "v", 0, 0);
12391265
}else{
@@ -1373,10 +1399,16 @@
13731399
}else if( zType[0]=='g' ){
13741400
zEType = "tag";
13751401
}
13761402
}
13771403
if( zUser ){
1404
+ int n = db_int(0,"SELECT count(*) FROM event"
1405
+ " WHERE user=%Q OR euser=%Q", zUser, zUser);
1406
+ if( n<=nEntry ){
1407
+ zCirca = zBefore = zAfter = 0;
1408
+ nEntry = -1;
1409
+ }
13781410
blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
13791411
zUser, zUser);
13801412
url_add_parameter(&url, "u", zUser);
13811413
zThisUser = zUser;
13821414
}
@@ -1394,11 +1426,11 @@
13941426
blob_append_sql(&sql,
13951427
" AND event.mtime>=%.17g AND event.mtime<=%.17g"
13961428
" ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
13971429
url_add_parameter(&url, "a", zAfter);
13981430
url_add_parameter(&url, "b", zBefore);
1399
- nEntry = 1000000;
1431
+ nEntry = -1;
14001432
}else{
14011433
blob_append_sql(&sql,
14021434
" AND event.mtime>=%.17g ORDER BY event.mtime ASC",
14031435
rAfter-ONE_SECOND);
14041436
url_add_parameter(&url, "a", zAfter);
@@ -1425,19 +1457,19 @@
14251457
if( useDividers ) timeline_add_dividers(rCirca, 0);
14261458
url_add_parameter(&url, "c", zCirca);
14271459
}else{
14281460
blob_append_sql(&sql, " ORDER BY event.mtime DESC");
14291461
}
1430
- blob_append_sql(&sql, " LIMIT %d", nEntry);
1462
+ if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry);
14311463
db_multi_exec("%s", blob_sql_text(&sql));
14321464
14331465
n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
14341466
if( zYearMonth ){
14351467
blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
14361468
}else if( zYearWeek ){
14371469
blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
1438
- }else if( zAfter==0 && zBefore==0 && zCirca==0 ){
1470
+ }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){
14391471
blob_appendf(&desc, "%d most recent %ss", n, zEType);
14401472
}else{
14411473
blob_appendf(&desc, "%d %ss", n, zEType);
14421474
}
14431475
if( zUses ){
@@ -1484,11 +1516,11 @@
14841516
}
14851517
if( zBefore || (zAfter && n==nEntry) ){
14861518
zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
14871519
timeline_submenu(&url, "Newer", "a", zDate, "b");
14881520
free(zDate);
1489
- }else if( tagid==0 ){
1521
+ }else if( tagid==0 && zUses==0 ){
14901522
if( zType[0]!='a' ){
14911523
timeline_submenu(&url, "All Types", "y", "all", 0);
14921524
}
14931525
if( zType[0]!='w' && g.perm.RdWiki ){
14941526
timeline_submenu(&url, "Wiki Only", "y", "w", 0);
@@ -1507,11 +1539,11 @@
15071539
}
15081540
}
15091541
if( nEntry>20 ){
15101542
timeline_submenu(&url, "20 Entries", "n", "20", 0);
15111543
}
1512
- if( nEntry<200 ){
1544
+ if( nEntry<200 && nEntry>0 ){
15131545
timeline_submenu(&url, "200 Entries", "n", "200", 0);
15141546
}
15151547
if( zType[0]=='a' || zType[0]=='c' ){
15161548
if( tmFlags & TIMELINE_FCHANGES ){
15171549
timeline_submenu(&url, "Hide Files", "v", 0, 0);
@@ -1525,10 +1557,11 @@
15251557
}
15261558
}
15271559
if( P("showsql") ){
15281560
@ <blockquote>%h(blob_sql_text(&sql))</blockquote>
15291561
}
1562
+ if( P("showrid") ) tmFlags |= TIMELINE_SHOWRID;
15301563
blob_zero(&sql);
15311564
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
15321565
@ <h2>%b(&desc)</h2>
15331566
blob_reset(&desc);
15341567
www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
@@ -1617,11 +1650,15 @@
16171650
sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], zBrType);
16181651
n = strlen(zPrefix);
16191652
}
16201653
if( fossil_strcmp(zCurrentUuid,zId)==0 ){
16211654
sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* ");
1622
- n += strlen(zPrefix);
1655
+ n += strlen(zPrefix+n);
1656
+ }
1657
+ if( content_is_private(rid) ){
1658
+ sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*UNPUBLISHED* ");
1659
+ n += strlen(zPrefix+n);
16231660
}
16241661
zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom);
16251662
/* record another X lines */
16261663
nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags);
16271664
fossil_free(zFree);
@@ -2362,11 +2399,11 @@
23622399
@ <br><div>Total events: %d(nEventTotal)
23632400
@ <br>Average per active %s(zAvgLabel): %d(nAvg)
23642401
@ </div>
23652402
}
23662403
if( !includeMonth ){
2367
- output_table_sorting_javascript("statsTable","tnx");
2404
+ output_table_sorting_javascript("statsTable","tnx",-1);
23682405
}
23692406
}
23702407
23712408
/*
23722409
** Implements the "byuser" view for /reports.
@@ -2413,11 +2450,11 @@
24132450
rowClass = ++nRowNumber % 2;
24142451
nEventTotal += nCount;
24152452
@<tr class='row%d(rowClass)'>
24162453
@ <td>
24172454
@ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
2418
- @ </td><td>%d(nCount)</td>
2455
+ @ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td>
24192456
@ <td>
24202457
@ <div class='statistics-report-graph-line'
24212458
@ style='width:%d(nSize)%%;'>&nbsp;</div>
24222459
@ </td>
24232460
@</tr>
@@ -2426,11 +2463,11 @@
24262463
use percent-based graph bars.
24272464
*/
24282465
}
24292466
@ </tbody></table>
24302467
db_finalize(&query);
2431
- output_table_sorting_javascript("statsTable","tnx");
2468
+ output_table_sorting_javascript("statsTable","tkx",2);
24322469
}
24332470
24342471
/*
24352472
** Implements the "byweekday" view for /reports.
24362473
*/
@@ -2491,11 +2528,11 @@
24912528
@ </td>
24922529
@</tr>
24932530
}
24942531
@ </tbody></table>
24952532
db_finalize(&query);
2496
- output_table_sorting_javascript("statsTable","ntnx");
2533
+ output_table_sorting_javascript("statsTable","ntnx",1);
24972534
}
24982535
24992536
25002537
/*
25012538
** Helper for stats_report_by_month_year(), which generates a list of
@@ -2624,11 +2661,11 @@
26242661
int nAvg = iterations ? (total/iterations) : 0;
26252662
cgi_printf("<br><div>Total events: %d<br>"
26262663
"Average per active week: %d</div>",
26272664
total, nAvg);
26282665
}
2629
- output_table_sorting_javascript("statsTable","tnx");
2666
+ output_table_sorting_javascript("statsTable","tnx",-1);
26302667
}
26312668
}
26322669
26332670
/*
26342671
** WEBPAGE: reports
26352672
--- 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){
@@ -77,10 +87,11 @@
77 #define TIMELINE_FCHANGES 0x0020 /* Detail file changes */
78 #define TIMELINE_BRCOLOR 0x0040 /* Background color by branch name */
79 #define TIMELINE_UCOLOR 0x0080 /* Background color by user */
80 #define TIMELINE_FRENAMES 0x0100 /* Detail only file name changes */
81 #define TIMELINE_UNHIDE 0x0200 /* Unhide check-ins with "hidden" tag */
 
82 #endif
83
84 /*
85 ** Hash a string and use the hash to determine a background color.
86 */
@@ -394,10 +405,13 @@
394 }
395 }else if( zType[0]=='e' && tagid ){
396 hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
397 }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
398 hyperlink_to_uuid(zUuid);
 
 
 
399 }
400 db_column_blob(pQuery, commentColumn, &comment);
401 if( zType[0]!='c' ){
402 /* Comments for anything other than a check-in are generated by
403 ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
@@ -417,11 +431,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 +456,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 +470,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 +485,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 +502,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 +518,26 @@
502 if( !isNew && !isDel && zOldName!=0 ){
503 @ <li> %h(zOldName) &rarr; %h(zFilename)
504 }
505 continue;
506 }
 
 
 
507 if( isNew ){
508 @ <li> %h(zFilename) (new file) &nbsp;
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) &rarr; %h(zFilename)
514 @ %z(href("%R/artifact/%s",zNew))[view]</a></li>
515 }else{
516 if( zOldName!=0 ){
517 @ <li> %h(zOldName) &rarr; %h(zFilename)
518 }else{
519 @ <li> %h(zFilename) &nbsp;
520 }
521 @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li>
522 }
523 }
524 db_reset(&fchngQuery);
@@ -589,12 +608,12 @@
589 ** for the upward portion of a merge arrow. The merge arrow goes up
590 ** to the row identified by mu:. If this value is zero then
591 ** node has no merge children and no merge-out line is drawn.
592 ** mu: The id of the row which is the top of the merge-out arrow.
593 ** u: Draw a thick child-line out of the top of this node and up to
594 ** the node with an id equal to this value. 0 if there is no
595 ** thick-line riser.
596 ** f: 0x01: a leaf node.
597 ** au: An array of integers that define thick-line risers for branches.
598 ** The integers are in pairs. For each pair, the first integer is
599 ** is the rail on which the riser should run and the second integer
600 ** is the id of the node upto which the riser should run.
@@ -1055,11 +1074,11 @@
1055 const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */
1056 const char *zYearWeek = P("yw"); /* Show checkins for the given YYYY-WW (week-of-year)*/
1057 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
1058 int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
1059 int tagid; /* Tag ID */
1060 int tmFlags; /* Timeline flags */
1061 const char *zThisTag = 0; /* Suppress links to this tag */
1062 const char *zThisUser = 0; /* Suppress links to this user */
1063 HQuery url; /* URL for various branch links */
1064 int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
1065 int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
@@ -1088,16 +1107,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 ){
@@ -1185,10 +1210,11 @@
1185 }else if( (p_rid || d_rid) && g.perm.Read ){
1186 /* If p= or d= is present, ignore all other parameters other than n= */
1187 char *zUuid;
1188 int np, nd;
1189
 
1190 if( p_rid && d_rid ){
1191 if( p_rid!=d_rid ) p_rid = d_rid;
1192 if( P("n")==0 ) nEntry = 10;
1193 }
1194 db_multi_exec(
@@ -1229,11 +1255,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 +1399,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 +1426,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 +1457,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 ){
@@ -1484,11 +1516,11 @@
1484 }
1485 if( zBefore || (zAfter && n==nEntry) ){
1486 zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
1487 timeline_submenu(&url, "Newer", "a", zDate, "b");
1488 free(zDate);
1489 }else if( tagid==0 ){
1490 if( zType[0]!='a' ){
1491 timeline_submenu(&url, "All Types", "y", "all", 0);
1492 }
1493 if( zType[0]!='w' && g.perm.RdWiki ){
1494 timeline_submenu(&url, "Wiki Only", "y", "w", 0);
@@ -1507,11 +1539,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);
@@ -1525,10 +1557,11 @@
1525 }
1526 }
1527 if( P("showsql") ){
1528 @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
1529 }
 
1530 blob_zero(&sql);
1531 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
1532 @ <h2>%b(&desc)</h2>
1533 blob_reset(&desc);
1534 www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
@@ -1617,11 +1650,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);
@@ -2362,11 +2399,11 @@
2362 @ <br><div>Total events: %d(nEventTotal)
2363 @ <br>Average per active %s(zAvgLabel): %d(nAvg)
2364 @ </div>
2365 }
2366 if( !includeMonth ){
2367 output_table_sorting_javascript("statsTable","tnx");
2368 }
2369 }
2370
2371 /*
2372 ** Implements the "byuser" view for /reports.
@@ -2413,11 +2450,11 @@
2413 rowClass = ++nRowNumber % 2;
2414 nEventTotal += nCount;
2415 @<tr class='row%d(rowClass)'>
2416 @ <td>
2417 @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
2418 @ </td><td>%d(nCount)</td>
2419 @ <td>
2420 @ <div class='statistics-report-graph-line'
2421 @ style='width:%d(nSize)%%;'>&nbsp;</div>
2422 @ </td>
2423 @</tr>
@@ -2426,11 +2463,11 @@
2426 use percent-based graph bars.
2427 */
2428 }
2429 @ </tbody></table>
2430 db_finalize(&query);
2431 output_table_sorting_javascript("statsTable","tnx");
2432 }
2433
2434 /*
2435 ** Implements the "byweekday" view for /reports.
2436 */
@@ -2491,11 +2528,11 @@
2491 @ </td>
2492 @</tr>
2493 }
2494 @ </tbody></table>
2495 db_finalize(&query);
2496 output_table_sorting_javascript("statsTable","ntnx");
2497 }
2498
2499
2500 /*
2501 ** Helper for stats_report_by_month_year(), which generates a list of
@@ -2624,11 +2661,11 @@
2624 int nAvg = iterations ? (total/iterations) : 0;
2625 cgi_printf("<br><div>Total events: %d<br>"
2626 "Average per active week: %d</div>",
2627 total, nAvg);
2628 }
2629 output_table_sorting_javascript("statsTable","tnx");
2630 }
2631 }
2632
2633 /*
2634 ** WEBPAGE: reports
2635
--- 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){
@@ -77,10 +87,11 @@
87 #define TIMELINE_FCHANGES 0x0020 /* Detail file changes */
88 #define TIMELINE_BRCOLOR 0x0040 /* Background color by branch name */
89 #define TIMELINE_UCOLOR 0x0080 /* Background color by user */
90 #define TIMELINE_FRENAMES 0x0100 /* Detail only file name changes */
91 #define TIMELINE_UNHIDE 0x0200 /* Unhide check-ins with "hidden" tag */
92 #define TIMELINE_SHOWRID 0x0400 /* Show RID values in addition to UUIDs */
93 #endif
94
95 /*
96 ** Hash a string and use the hash to determine a background color.
97 */
@@ -394,10 +405,13 @@
405 }
406 }else if( zType[0]=='e' && tagid ){
407 hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
408 }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
409 hyperlink_to_uuid(zUuid);
410 }
411 if( tmFlags & TIMELINE_SHOWRID ){
412 @ (%d(rid))
413 }
414 db_column_blob(pQuery, commentColumn, &comment);
415 if( zType[0]!='c' ){
416 /* Comments for anything other than a check-in are generated by
417 ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
@@ -417,11 +431,11 @@
431 /* Generate the "user: USERNAME" at the end of the comment, together
432 ** with a hyperlink to another timeline for that user.
433 */
434 if( zTagList && zTagList[0]==0 ) zTagList = 0;
435 if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
436 char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd&n=200", zDispUser, zDate);
437 @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051")
438 }else{
439 @ (user: %h(zDispUser)%s(zTagList?",":"\051")
440 }
441
@@ -442,11 +456,11 @@
456 while( z && z[0] ){
457 for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
458 if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
459 blob_appendf(&links,
460 "%z%#h</a>%.2s",
461 href("%R/timeline?r=%#t&nd&c=%t&n=200",i,z,zDate), i,z, &z[i]
462 );
463 }else{
464 blob_appendf(&links, "%#h", i+2, z);
465 }
466 if( z[i]==0 ) break;
@@ -456,11 +470,11 @@
470 blob_reset(&links);
471 }else{
472 @ tags: %h(zTagList))
473 }
474 }
475 tag_private_status(rid);
476
477 /* Generate extra hyperlinks at the end of the comment */
478 if( xExtra ){
479 xExtra(rid);
480 }
@@ -471,11 +485,11 @@
485 ){
486 int inUl = 0;
487 if( !fchngQueryInit ){
488 db_prepare(&fchngQuery,
489 "SELECT (pid==0) AS isnew,"
490 " fid,"
491 " (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
492 " (SELECT uuid FROM blob WHERE rid=fid),"
493 " (SELECT uuid FROM blob WHERE rid=pid),"
494 " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
495 " FROM mlink"
@@ -488,14 +502,16 @@
502 }
503 db_bind_int(&fchngQuery, ":mid", rid);
504 while( db_step(&fchngQuery)==SQLITE_ROW ){
505 const char *zFilename = db_column_text(&fchngQuery, 2);
506 int isNew = db_column_int(&fchngQuery, 0);
507 int fid = db_column_int(&fchngQuery, 1);
508 int isDel = fid==0;
509 const char *zOldName = db_column_text(&fchngQuery, 5);
510 const char *zOld = db_column_text(&fchngQuery, 4);
511 const char *zNew = db_column_text(&fchngQuery, 3);
512 const char *zUnpubTag = "";
513 if( !inUl ){
514 @ <ul class="filelist">
515 inUl = 1;
516 }
517 if( (tmFlags & TIMELINE_FRENAMES)!=0 ){
@@ -502,23 +518,26 @@
518 if( !isNew && !isDel && zOldName!=0 ){
519 @ <li> %h(zOldName) &rarr; %h(zFilename)
520 }
521 continue;
522 }
523 if( content_is_private(fid) ){
524 zUnpubTag = UNPUB_TAG;
525 }
526 if( isNew ){
527 @ <li> %h(zFilename) %s(zUnpubTag) (new file) &nbsp;
528 @ %z(href("%R/artifact/%s",zNew))[view]</a></li>
529 }else if( isDel ){
530 @ <li> %h(zFilename) (deleted)</li>
531 }else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
532 @ <li> %h(zOldName) &rarr; %h(zFilename) %s(zUnpubTag)
533 @ %z(href("%R/artifact/%s",zNew))[view]</a></li>
534 }else{
535 if( zOldName!=0 ){
536 @ <li> %h(zOldName) &rarr; %h(zFilename) %s(zUnpubTag)
537 }else{
538 @ <li> %h(zFilename) &nbsp; %s(zUnpubTag)
539 }
540 @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zOld,zNew))[diff]</a></li>
541 }
542 }
543 db_reset(&fchngQuery);
@@ -589,12 +608,12 @@
608 ** for the upward portion of a merge arrow. The merge arrow goes up
609 ** to the row identified by mu:. If this value is zero then
610 ** node has no merge children and no merge-out line is drawn.
611 ** mu: The id of the row which is the top of the merge-out arrow.
612 ** u: Draw a thick child-line out of the top of this node and up to
613 ** the node with an id equal to this value. 0 if it is straight to
614 ** the top of the page, -1 if there is no thick-line riser.
615 ** f: 0x01: a leaf node.
616 ** au: An array of integers that define thick-line risers for branches.
617 ** The integers are in pairs. For each pair, the first integer is
618 ** is the rail on which the riser should run and the second integer
619 ** is the id of the node upto which the riser should run.
@@ -1055,11 +1074,11 @@
1074 const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */
1075 const char *zYearWeek = P("yw"); /* Show checkins for the given YYYY-WW (week-of-year)*/
1076 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
1077 int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
1078 int tagid; /* Tag ID */
1079 int tmFlags = 0; /* Timeline flags */
1080 const char *zThisTag = 0; /* Suppress links to this tag */
1081 const char *zThisUser = 0; /* Suppress links to this user */
1082 HQuery url; /* URL for various branch links */
1083 int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
1084 int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
@@ -1088,16 +1107,22 @@
1107 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1108 zThisTag = zBrName;
1109 }else{
1110 tagid = 0;
1111 }
1112 if( tagid>0
1113 && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
1114 ){
1115 zCirca = zBefore = zAfter = 0;
1116 nEntry = -1;
1117 }
1118 if( zType[0]=='a' ){
1119 tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH;
1120 }else{
1121 tmFlags |= TIMELINE_GRAPH;
1122 }
1123 if( nEntry>0 ) url_add_parameter(&url, "n", mprintf("%d", nEntry));
1124 if( P("ng")!=0 || zSearch!=0 ){
1125 tmFlags &= ~TIMELINE_GRAPH;
1126 url_add_parameter(&url, "ng", 0);
1127 }
1128 if( P("brbg")!=0 ){
@@ -1185,10 +1210,11 @@
1210 }else if( (p_rid || d_rid) && g.perm.Read ){
1211 /* If p= or d= is present, ignore all other parameters other than n= */
1212 char *zUuid;
1213 int np, nd;
1214
1215 tmFlags |= TIMELINE_DISJOINT;
1216 if( p_rid && d_rid ){
1217 if( p_rid!=d_rid ) p_rid = d_rid;
1218 if( P("n")==0 ) nEntry = 10;
1219 }
1220 db_multi_exec(
@@ -1229,11 +1255,11 @@
1255 url_add_parameter(&url, "d", zUuid);
1256 }
1257 if( nEntry>20 ){
1258 timeline_submenu(&url, "20 Entries", "n", "20", 0);
1259 }
1260 if( nEntry<200 && nEntry>0 ){
1261 timeline_submenu(&url, "200 Entries", "n", "200", 0);
1262 }
1263 if( tmFlags & TIMELINE_FCHANGES ){
1264 timeline_submenu(&url, "Hide Files", "v", 0, 0);
1265 }else{
@@ -1373,10 +1399,16 @@
1399 }else if( zType[0]=='g' ){
1400 zEType = "tag";
1401 }
1402 }
1403 if( zUser ){
1404 int n = db_int(0,"SELECT count(*) FROM event"
1405 " WHERE user=%Q OR euser=%Q", zUser, zUser);
1406 if( n<=nEntry ){
1407 zCirca = zBefore = zAfter = 0;
1408 nEntry = -1;
1409 }
1410 blob_append_sql(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1411 zUser, zUser);
1412 url_add_parameter(&url, "u", zUser);
1413 zThisUser = zUser;
1414 }
@@ -1394,11 +1426,11 @@
1426 blob_append_sql(&sql,
1427 " AND event.mtime>=%.17g AND event.mtime<=%.17g"
1428 " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
1429 url_add_parameter(&url, "a", zAfter);
1430 url_add_parameter(&url, "b", zBefore);
1431 nEntry = -1;
1432 }else{
1433 blob_append_sql(&sql,
1434 " AND event.mtime>=%.17g ORDER BY event.mtime ASC",
1435 rAfter-ONE_SECOND);
1436 url_add_parameter(&url, "a", zAfter);
@@ -1425,19 +1457,19 @@
1457 if( useDividers ) timeline_add_dividers(rCirca, 0);
1458 url_add_parameter(&url, "c", zCirca);
1459 }else{
1460 blob_append_sql(&sql, " ORDER BY event.mtime DESC");
1461 }
1462 if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry);
1463 db_multi_exec("%s", blob_sql_text(&sql));
1464
1465 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1466 if( zYearMonth ){
1467 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1468 }else if( zYearWeek ){
1469 blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
1470 }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){
1471 blob_appendf(&desc, "%d most recent %ss", n, zEType);
1472 }else{
1473 blob_appendf(&desc, "%d %ss", n, zEType);
1474 }
1475 if( zUses ){
@@ -1484,11 +1516,11 @@
1516 }
1517 if( zBefore || (zAfter && n==nEntry) ){
1518 zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
1519 timeline_submenu(&url, "Newer", "a", zDate, "b");
1520 free(zDate);
1521 }else if( tagid==0 && zUses==0 ){
1522 if( zType[0]!='a' ){
1523 timeline_submenu(&url, "All Types", "y", "all", 0);
1524 }
1525 if( zType[0]!='w' && g.perm.RdWiki ){
1526 timeline_submenu(&url, "Wiki Only", "y", "w", 0);
@@ -1507,11 +1539,11 @@
1539 }
1540 }
1541 if( nEntry>20 ){
1542 timeline_submenu(&url, "20 Entries", "n", "20", 0);
1543 }
1544 if( nEntry<200 && nEntry>0 ){
1545 timeline_submenu(&url, "200 Entries", "n", "200", 0);
1546 }
1547 if( zType[0]=='a' || zType[0]=='c' ){
1548 if( tmFlags & TIMELINE_FCHANGES ){
1549 timeline_submenu(&url, "Hide Files", "v", 0, 0);
@@ -1525,10 +1557,11 @@
1557 }
1558 }
1559 if( P("showsql") ){
1560 @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
1561 }
1562 if( P("showrid") ) tmFlags |= TIMELINE_SHOWRID;
1563 blob_zero(&sql);
1564 db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
1565 @ <h2>%b(&desc)</h2>
1566 blob_reset(&desc);
1567 www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
@@ -1617,11 +1650,15 @@
1650 sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], zBrType);
1651 n = strlen(zPrefix);
1652 }
1653 if( fossil_strcmp(zCurrentUuid,zId)==0 ){
1654 sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*CURRENT* ");
1655 n += strlen(zPrefix+n);
1656 }
1657 if( content_is_private(rid) ){
1658 sqlite3_snprintf(sizeof(zPrefix)-n, &zPrefix[n], "*UNPUBLISHED* ");
1659 n += strlen(zPrefix+n);
1660 }
1661 zFree = mprintf("[%S] %s%s", zId, zPrefix, zCom);
1662 /* record another X lines */
1663 nLine += comment_print(zFree, zCom, 9, width, g.comFmtFlags);
1664 fossil_free(zFree);
@@ -2362,11 +2399,11 @@
2399 @ <br><div>Total events: %d(nEventTotal)
2400 @ <br>Average per active %s(zAvgLabel): %d(nAvg)
2401 @ </div>
2402 }
2403 if( !includeMonth ){
2404 output_table_sorting_javascript("statsTable","tnx",-1);
2405 }
2406 }
2407
2408 /*
2409 ** Implements the "byuser" view for /reports.
@@ -2413,11 +2450,11 @@
2450 rowClass = ++nRowNumber % 2;
2451 nEventTotal += nCount;
2452 @<tr class='row%d(rowClass)'>
2453 @ <td>
2454 @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
2455 @ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td>
2456 @ <td>
2457 @ <div class='statistics-report-graph-line'
2458 @ style='width:%d(nSize)%%;'>&nbsp;</div>
2459 @ </td>
2460 @</tr>
@@ -2426,11 +2463,11 @@
2463 use percent-based graph bars.
2464 */
2465 }
2466 @ </tbody></table>
2467 db_finalize(&query);
2468 output_table_sorting_javascript("statsTable","tkx",2);
2469 }
2470
2471 /*
2472 ** Implements the "byweekday" view for /reports.
2473 */
@@ -2491,11 +2528,11 @@
2528 @ </td>
2529 @</tr>
2530 }
2531 @ </tbody></table>
2532 db_finalize(&query);
2533 output_table_sorting_javascript("statsTable","ntnx",1);
2534 }
2535
2536
2537 /*
2538 ** Helper for stats_report_by_month_year(), which generates a list of
@@ -2624,11 +2661,11 @@
2661 int nAvg = iterations ? (total/iterations) : 0;
2662 cgi_printf("<br><div>Total events: %d<br>"
2663 "Average per active week: %d</div>",
2664 total, nAvg);
2665 }
2666 output_table_sorting_javascript("statsTable","tnx",-1);
2667 }
2668 }
2669
2670 /*
2671 ** WEBPAGE: reports
2672
+1 -3
--- src/undo.c
+++ src/undo.c
@@ -127,11 +127,10 @@
127127
** Undo or redo all undoable or redoable changes.
128128
*/
129129
static void undo_all(int redoFlag){
130130
int ucid;
131131
int ncid;
132
- const char *zDb = db_name("localdb");
133132
undo_all_filesystem(redoFlag);
134133
db_multi_exec(
135134
"CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
136135
"DELETE FROM vfile;"
137136
"INSERT INTO vfile SELECT * FROM undo_vfile;"
@@ -143,12 +142,11 @@
143142
"INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144143
"DELETE FROM undo_vmerge;"
145144
"INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146145
"DROP TABLE undo_vmerge_2;"
147146
);
148
- if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
149
- " WHERE name='undo_stash'", zDb) ){
147
+ if( db_table_exists("localdb", "undo_stash") ){
150148
if( redoFlag ){
151149
db_multi_exec(
152150
"DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
153151
"DELETE FROM stashfile"
154152
" WHERE stashid NOT IN (SELECT stashid FROM stash);"
155153
--- src/undo.c
+++ src/undo.c
@@ -127,11 +127,10 @@
127 ** Undo or redo all undoable or redoable changes.
128 */
129 static void undo_all(int redoFlag){
130 int ucid;
131 int ncid;
132 const char *zDb = db_name("localdb");
133 undo_all_filesystem(redoFlag);
134 db_multi_exec(
135 "CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
136 "DELETE FROM vfile;"
137 "INSERT INTO vfile SELECT * FROM undo_vfile;"
@@ -143,12 +142,11 @@
143 "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
144 "DELETE FROM undo_vmerge;"
145 "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
146 "DROP TABLE undo_vmerge_2;"
147 );
148 if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
149 " WHERE name='undo_stash'", zDb) ){
150 if( redoFlag ){
151 db_multi_exec(
152 "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
153 "DELETE FROM stashfile"
154 " WHERE stashid NOT IN (SELECT stashid FROM stash);"
155
--- src/undo.c
+++ src/undo.c
@@ -127,11 +127,10 @@
127 ** Undo or redo all undoable or redoable changes.
128 */
129 static void undo_all(int redoFlag){
130 int ucid;
131 int ncid;
 
132 undo_all_filesystem(redoFlag);
133 db_multi_exec(
134 "CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
135 "DELETE FROM vfile;"
136 "INSERT INTO vfile SELECT * FROM undo_vfile;"
@@ -143,12 +142,11 @@
142 "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
143 "DELETE FROM undo_vmerge;"
144 "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
145 "DROP TABLE undo_vmerge_2;"
146 );
147 if( db_table_exists("localdb", "undo_stash") ){
 
148 if( redoFlag ){
149 db_multi_exec(
150 "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
151 "DELETE FROM stashfile"
152 " WHERE stashid NOT IN (SELECT stashid FROM stash);"
153
+1 -1
--- src/xfer.c
+++ src/xfer.c
@@ -532,11 +532,11 @@
532532
** private artifacts if we are not doing a private transfer.
533533
*/
534534
static void request_phantoms(Xfer *pXfer, int maxReq){
535535
Stmt q;
536536
db_prepare(&q,
537
- "SELECT uuid FROM phantom JOIN blob USING(rid)"
537
+ "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
538538
" WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
539539
(pXfer->syncPrivate ? "" :
540540
" AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
541541
);
542542
while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
543543
--- src/xfer.c
+++ src/xfer.c
@@ -532,11 +532,11 @@
532 ** private artifacts if we are not doing a private transfer.
533 */
534 static void request_phantoms(Xfer *pXfer, int maxReq){
535 Stmt q;
536 db_prepare(&q,
537 "SELECT uuid FROM phantom JOIN blob USING(rid)"
538 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
539 (pXfer->syncPrivate ? "" :
540 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
541 );
542 while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
543
--- src/xfer.c
+++ src/xfer.c
@@ -532,11 +532,11 @@
532 ** private artifacts if we are not doing a private transfer.
533 */
534 static void request_phantoms(Xfer *pXfer, int maxReq){
535 Stmt q;
536 db_prepare(&q,
537 "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
538 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
539 (pXfer->syncPrivate ? "" :
540 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
541 );
542 while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
543
--- test/valgrind-www.tcl
+++ test/valgrind-www.tcl
@@ -1,10 +1,10 @@
11
#!/usr/bin/tclsh
22
#
3
-# Run this script in an open Fossil checkout at the top-level with a
3
+# Run this script in an open Fossil checkout at the top-level with a
44
# fresh build of Fossil itself. This script will run fossil on hundreds
5
-# of different web-pages looking for memory allocation problems using
5
+# of different web-pages looking for memory allocation problems using
66
# valgrind. Valgrind output appears on stderr. Suggested test scenario:
77
#
88
# make
99
# tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt
1010
#
1111
--- test/valgrind-www.tcl
+++ test/valgrind-www.tcl
@@ -1,10 +1,10 @@
1 #!/usr/bin/tclsh
2 #
3 # Run this script in an open Fossil checkout at the top-level with a
4 # fresh build of Fossil itself. This script will run fossil on hundreds
5 # of different web-pages looking for memory allocation problems using
6 # valgrind. Valgrind output appears on stderr. Suggested test scenario:
7 #
8 # make
9 # tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt
10 #
11
--- test/valgrind-www.tcl
+++ test/valgrind-www.tcl
@@ -1,10 +1,10 @@
1 #!/usr/bin/tclsh
2 #
3 # Run this script in an open Fossil checkout at the top-level with a
4 # fresh build of Fossil itself. This script will run fossil on hundreds
5 # of different web-pages looking for memory allocation problems using
6 # valgrind. Valgrind output appears on stderr. Suggested test scenario:
7 #
8 # make
9 # tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt
10 #
11
--- tools/fossil_chat.tcl
+++ tools/fossil_chat.tcl
@@ -84,11 +84,11 @@
8484
catch {close $SOCKET}
8585
if {[catch {
8686
if {$::PROXYHOST ne {}} {
8787
set SOCKET [socket $::PROXYHOST $::PROXYPORT]
8888
puts $SOCKET "CONNECT $::SERVERHOST:$::SERVERPORT HTTP/1.1"
89
- puts $SOCKET "Host: $::SERVERHOST:$::SERVERPORT"
89
+ puts $SOCKET "Host: $::SERVERHOST:$::SERVERPORT"
9090
puts $SOCKET ""
9191
} else {
9292
set SOCKET [socket $::SERVERHOST $::SERVERPORT]
9393
}
9494
fconfigure $SOCKET -translation binary -blocking 0
@@ -142,11 +142,11 @@
142142
#
143143
proc delete_files {} {
144144
global FILES
145145
.mb.files delete 3 end
146146
array unset FILES
147
- .mb.files entryconfigure 1 -state disabled
147
+ .mb.files entryconfigure 1 -state disabled
148148
}
149149
150150
# Prompt the user to select a file from the disk. Then send that
151151
# file to all chat participants.
152152
#
@@ -188,11 +188,11 @@
188188
if {![info exists prior] || $filename!=$prior} {
189189
.mb.files add command -label "Save \"$filename\"" \
190190
-command [list save_file $filename]
191191
}
192192
set FILES($filename) $data
193
- .mb.files entryconfigure 1 -state active
193
+ .mb.files entryconfigure 1 -state active
194194
set time [clock format [clock seconds] -format {%H:%M} -gmt 1]
195195
.msg.t insert end "\[$time $from\] " meta "File: \"$filename\"\n" norm
196196
.msg.t see end
197197
}
198198
@@ -232,11 +232,11 @@
232232
} elseif {$cmd=="file"} {
233233
if {[info commands handle_file]=="handle_file"} {
234234
handle_file [lindex $line 1] [lindex $line 2] [lindex $line 3]
235235
}
236236
}
237
-}
237
+}
238238
239239
# Handle a broken socket connection
240240
#
241241
proc disconnect {} {
242242
global SOCKET
243243
--- tools/fossil_chat.tcl
+++ tools/fossil_chat.tcl
@@ -84,11 +84,11 @@
84 catch {close $SOCKET}
85 if {[catch {
86 if {$::PROXYHOST ne {}} {
87 set SOCKET [socket $::PROXYHOST $::PROXYPORT]
88 puts $SOCKET "CONNECT $::SERVERHOST:$::SERVERPORT HTTP/1.1"
89 puts $SOCKET "Host: $::SERVERHOST:$::SERVERPORT"
90 puts $SOCKET ""
91 } else {
92 set SOCKET [socket $::SERVERHOST $::SERVERPORT]
93 }
94 fconfigure $SOCKET -translation binary -blocking 0
@@ -142,11 +142,11 @@
142 #
143 proc delete_files {} {
144 global FILES
145 .mb.files delete 3 end
146 array unset FILES
147 .mb.files entryconfigure 1 -state disabled
148 }
149
150 # Prompt the user to select a file from the disk. Then send that
151 # file to all chat participants.
152 #
@@ -188,11 +188,11 @@
188 if {![info exists prior] || $filename!=$prior} {
189 .mb.files add command -label "Save \"$filename\"" \
190 -command [list save_file $filename]
191 }
192 set FILES($filename) $data
193 .mb.files entryconfigure 1 -state active
194 set time [clock format [clock seconds] -format {%H:%M} -gmt 1]
195 .msg.t insert end "\[$time $from\] " meta "File: \"$filename\"\n" norm
196 .msg.t see end
197 }
198
@@ -232,11 +232,11 @@
232 } elseif {$cmd=="file"} {
233 if {[info commands handle_file]=="handle_file"} {
234 handle_file [lindex $line 1] [lindex $line 2] [lindex $line 3]
235 }
236 }
237 }
238
239 # Handle a broken socket connection
240 #
241 proc disconnect {} {
242 global SOCKET
243
--- tools/fossil_chat.tcl
+++ tools/fossil_chat.tcl
@@ -84,11 +84,11 @@
84 catch {close $SOCKET}
85 if {[catch {
86 if {$::PROXYHOST ne {}} {
87 set SOCKET [socket $::PROXYHOST $::PROXYPORT]
88 puts $SOCKET "CONNECT $::SERVERHOST:$::SERVERPORT HTTP/1.1"
89 puts $SOCKET "Host: $::SERVERHOST:$::SERVERPORT"
90 puts $SOCKET ""
91 } else {
92 set SOCKET [socket $::SERVERHOST $::SERVERPORT]
93 }
94 fconfigure $SOCKET -translation binary -blocking 0
@@ -142,11 +142,11 @@
142 #
143 proc delete_files {} {
144 global FILES
145 .mb.files delete 3 end
146 array unset FILES
147 .mb.files entryconfigure 1 -state disabled
148 }
149
150 # Prompt the user to select a file from the disk. Then send that
151 # file to all chat participants.
152 #
@@ -188,11 +188,11 @@
188 if {![info exists prior] || $filename!=$prior} {
189 .mb.files add command -label "Save \"$filename\"" \
190 -command [list save_file $filename]
191 }
192 set FILES($filename) $data
193 .mb.files entryconfigure 1 -state active
194 set time [clock format [clock seconds] -format {%H:%M} -gmt 1]
195 .msg.t insert end "\[$time $from\] " meta "File: \"$filename\"\n" norm
196 .msg.t see end
197 }
198
@@ -232,11 +232,11 @@
232 } elseif {$cmd=="file"} {
233 if {[info commands handle_file]=="handle_file"} {
234 handle_file [lindex $line 1] [lindex $line 2] [lindex $line 3]
235 }
236 }
237 }
238
239 # Handle a broken socket connection
240 #
241 proc disconnect {} {
242 global SOCKET
243
+28 -4
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -28,13 +28,13 @@
2828
2929
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
3030
3131
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
3232
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 sitemap_.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
3434
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)\sitemap$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
3636
3737
3838
RC=$(DMDIR)\bin\rcc
3939
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
4040
@@ -49,11 +49,11 @@
4949
5050
$(OBJDIR)\fossil.res: $B\win\fossil.rc
5151
$(RC) $(RCFLAGS) -o$@ $**
5252
5353
$(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 sitemap 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 > $@
5555
+echo fossil >> $@
5656
+echo fossil >> $@
5757
+echo $(LIBS) >> $@
5858
+echo. >> $@
5959
+echo fossil >> $@
@@ -176,10 +176,16 @@
176176
$(OBJDIR)\builtin$O : builtin_.c builtin.h
177177
$(TCC) -o$@ -c builtin_.c
178178
179179
builtin_.c : $(SRCDIR)\builtin.c
180180
+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 $** > $@
181187
182188
$(OBJDIR)\cache$O : cache_.c cache.h
183189
$(TCC) -o$@ -c cache_.c
184190
185191
cache_.c : $(SRCDIR)\cache.c
@@ -572,10 +578,22 @@
572578
$(OBJDIR)\printf$O : printf_.c printf.h
573579
$(TCC) -o$@ -c printf_.c
574580
575581
printf_.c : $(SRCDIR)\printf.c
576582
+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 $** > $@
577595
578596
$(OBJDIR)\rebuild$O : rebuild_.c rebuild.h
579597
$(TCC) -o$@ -c rebuild_.c
580598
581599
rebuild_.c : $(SRCDIR)\rebuild.c
@@ -626,10 +644,16 @@
626644
$(OBJDIR)\shun$O : shun_.c shun.h
627645
$(TCC) -o$@ -c shun_.c
628646
629647
shun_.c : $(SRCDIR)\shun.c
630648
+translate$E $** > $@
649
+
650
+$(OBJDIR)\sitemap$O : sitemap_.c sitemap.h
651
+ $(TCC) -o$@ -c sitemap_.c
652
+
653
+sitemap_.c : $(SRCDIR)\sitemap.c
654
+ +translate$E $** > $@
631655
632656
$(OBJDIR)\skins$O : skins_.c skins.h
633657
$(TCC) -o$@ -c skins_.c
634658
635659
skins_.c : $(SRCDIR)\skins.c
@@ -802,7 +826,7 @@
802826
803827
zip_.c : $(SRCDIR)\zip.c
804828
+translate$E $** > $@
805829
806830
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
831
+ +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 sitemap_.c:sitemap.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
808832
@copy /Y nul: headers
809833
--- 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
@@ -626,10 +644,16 @@
626 $(OBJDIR)\shun$O : shun_.c shun.h
627 $(TCC) -o$@ -c shun_.c
628
629 shun_.c : $(SRCDIR)\shun.c
630 +translate$E $** > $@
 
 
 
 
 
 
631
632 $(OBJDIR)\skins$O : skins_.c skins.h
633 $(TCC) -o$@ -c skins_.c
634
635 skins_.c : $(SRCDIR)\skins.c
@@ -802,7 +826,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 sitemap_.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)\sitemap$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 sitemap 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
@@ -626,10 +644,16 @@
644 $(OBJDIR)\shun$O : shun_.c shun.h
645 $(TCC) -o$@ -c shun_.c
646
647 shun_.c : $(SRCDIR)\shun.c
648 +translate$E $** > $@
649
650 $(OBJDIR)\sitemap$O : sitemap_.c sitemap.h
651 $(TCC) -o$@ -c sitemap_.c
652
653 sitemap_.c : $(SRCDIR)\sitemap.c
654 +translate$E $** > $@
655
656 $(OBJDIR)\skins$O : skins_.c skins.h
657 $(TCC) -o$@ -c skins_.c
658
659 skins_.c : $(SRCDIR)\skins.c
@@ -802,7 +826,7 @@
826
827 zip_.c : $(SRCDIR)\zip.c
828 +translate$E $** > $@
829
830 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
831 +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 sitemap_.c:sitemap.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
832 @copy /Y nul: headers
833
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -87,11 +87,12 @@
8787
# This is useful when Tcl has been compiled statically with MinGW.
8888
#
8989
FOSSIL_TCL_SOURCE = 1
9090
9191
#### Check if the workaround for the MinGW command line handling needs to
92
-# be enabled by default.
92
+# be enabled by default. This check may be somewhat fragile due to the
93
+# use of "findstring".
9394
#
9495
ifndef MINGW_IS_32BIT_ONLY
9596
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
9697
MINGW_IS_32BIT_ONLY = 1
9798
endif
@@ -100,26 +101,46 @@
100101
#### The directories where the zlib include and library files are located.
101102
#
102103
ZINCDIR = $(SRCDIR)/../compat/zlib
103104
ZLIBDIR = $(SRCDIR)/../compat/zlib
104105
106
+#### Make an attempt to detect if Fossil is being built for the x64 processor
107
+# architecture. This check may be somewhat fragile due to "findstring".
108
+#
105109
ifndef X64
106110
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
107111
X64 = 1
108112
endif
109113
endif
110114
115
+#### Determine if the optimized assembly routines provided with zlib should be
116
+# used, taking into account whether zlib is actually enabled and the target
117
+# processor architecture.
118
+#
111119
ifndef X64
112120
SSLCONFIG = mingw
121
+ifndef FOSSIL_ENABLE_MINIZ
113122
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
114123
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
124
+else
125
+ZLIBCONFIG =
126
+LIBTARGETS =
127
+endif
115128
else
116129
SSLCONFIG = mingw64
117
-ZLIBCONFIG =
130
+ZLIBCONFIG =
118131
LIBTARGETS =
119132
endif
120133
134
+#### Disable creation of the OpenSSL shared libraries. Also, disable support
135
+# for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
136
+#
137
+SSLCONFIG += no-ssl2 no-ssl3 no-shared
138
+
139
+#### When using zlib, make sure that OpenSSL is configured to use the zlib
140
+# that Fossil knows about (i.e. the one within the source tree).
141
+#
121142
ifndef FOSSIL_ENABLE_MINIZ
122143
SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
123144
endif
124145
125146
#### The directories where the OpenSSL include and library files are located.
@@ -352,10 +373,11 @@
352373
$(SRCDIR)/bisect.c \
353374
$(SRCDIR)/blob.c \
354375
$(SRCDIR)/branch.c \
355376
$(SRCDIR)/browse.c \
356377
$(SRCDIR)/builtin.c \
378
+ $(SRCDIR)/bundle.c \
357379
$(SRCDIR)/cache.c \
358380
$(SRCDIR)/captcha.c \
359381
$(SRCDIR)/cgi.c \
360382
$(SRCDIR)/checkin.c \
361383
$(SRCDIR)/checkout.c \
@@ -418,19 +440,22 @@
418440
$(SRCDIR)/path.c \
419441
$(SRCDIR)/pivot.c \
420442
$(SRCDIR)/popen.c \
421443
$(SRCDIR)/pqueue.c \
422444
$(SRCDIR)/printf.c \
445
+ $(SRCDIR)/publish.c \
446
+ $(SRCDIR)/purge.c \
423447
$(SRCDIR)/rebuild.c \
424448
$(SRCDIR)/regexp.c \
425449
$(SRCDIR)/report.c \
426450
$(SRCDIR)/rss.c \
427451
$(SRCDIR)/schema.c \
428452
$(SRCDIR)/search.c \
429453
$(SRCDIR)/setup.c \
430454
$(SRCDIR)/sha1.c \
431455
$(SRCDIR)/shun.c \
456
+ $(SRCDIR)/sitemap.c \
432457
$(SRCDIR)/skins.c \
433458
$(SRCDIR)/sqlcmd.c \
434459
$(SRCDIR)/stash.c \
435460
$(SRCDIR)/stat.c \
436461
$(SRCDIR)/style.c \
@@ -470,10 +495,11 @@
470495
$(OBJDIR)/bisect_.c \
471496
$(OBJDIR)/blob_.c \
472497
$(OBJDIR)/branch_.c \
473498
$(OBJDIR)/browse_.c \
474499
$(OBJDIR)/builtin_.c \
500
+ $(OBJDIR)/bundle_.c \
475501
$(OBJDIR)/cache_.c \
476502
$(OBJDIR)/captcha_.c \
477503
$(OBJDIR)/cgi_.c \
478504
$(OBJDIR)/checkin_.c \
479505
$(OBJDIR)/checkout_.c \
@@ -536,19 +562,22 @@
536562
$(OBJDIR)/path_.c \
537563
$(OBJDIR)/pivot_.c \
538564
$(OBJDIR)/popen_.c \
539565
$(OBJDIR)/pqueue_.c \
540566
$(OBJDIR)/printf_.c \
567
+ $(OBJDIR)/publish_.c \
568
+ $(OBJDIR)/purge_.c \
541569
$(OBJDIR)/rebuild_.c \
542570
$(OBJDIR)/regexp_.c \
543571
$(OBJDIR)/report_.c \
544572
$(OBJDIR)/rss_.c \
545573
$(OBJDIR)/schema_.c \
546574
$(OBJDIR)/search_.c \
547575
$(OBJDIR)/setup_.c \
548576
$(OBJDIR)/sha1_.c \
549577
$(OBJDIR)/shun_.c \
578
+ $(OBJDIR)/sitemap_.c \
550579
$(OBJDIR)/skins_.c \
551580
$(OBJDIR)/sqlcmd_.c \
552581
$(OBJDIR)/stash_.c \
553582
$(OBJDIR)/stat_.c \
554583
$(OBJDIR)/style_.c \
@@ -585,10 +614,11 @@
585614
$(OBJDIR)/bisect.o \
586615
$(OBJDIR)/blob.o \
587616
$(OBJDIR)/branch.o \
588617
$(OBJDIR)/browse.o \
589618
$(OBJDIR)/builtin.o \
619
+ $(OBJDIR)/bundle.o \
590620
$(OBJDIR)/cache.o \
591621
$(OBJDIR)/captcha.o \
592622
$(OBJDIR)/cgi.o \
593623
$(OBJDIR)/checkin.o \
594624
$(OBJDIR)/checkout.o \
@@ -651,19 +681,22 @@
651681
$(OBJDIR)/path.o \
652682
$(OBJDIR)/pivot.o \
653683
$(OBJDIR)/popen.o \
654684
$(OBJDIR)/pqueue.o \
655685
$(OBJDIR)/printf.o \
686
+ $(OBJDIR)/publish.o \
687
+ $(OBJDIR)/purge.o \
656688
$(OBJDIR)/rebuild.o \
657689
$(OBJDIR)/regexp.o \
658690
$(OBJDIR)/report.o \
659691
$(OBJDIR)/rss.o \
660692
$(OBJDIR)/schema.o \
661693
$(OBJDIR)/search.o \
662694
$(OBJDIR)/setup.o \
663695
$(OBJDIR)/sha1.o \
664696
$(OBJDIR)/shun.o \
697
+ $(OBJDIR)/sitemap.o \
665698
$(OBJDIR)/skins.o \
666699
$(OBJDIR)/sqlcmd.o \
667700
$(OBJDIR)/stash.o \
668701
$(OBJDIR)/stat.o \
669702
$(OBJDIR)/style.o \
@@ -893,10 +926,11 @@
893926
$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
894927
$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
895928
$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
896929
$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
897930
$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
931
+ $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
898932
$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
899933
$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
900934
$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
901935
$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
902936
$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -959,19 +993,22 @@
959993
$(OBJDIR)/path_.c:$(OBJDIR)/path.h \
960994
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
961995
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
962996
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
963997
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
998
+ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
999
+ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
9641000
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
9651001
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
9661002
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
9671003
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
9681004
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
9691005
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
9701006
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
9711007
$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
9721008
$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
1009
+ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
9731010
$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
9741011
$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
9751012
$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
9761013
$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
9771014
$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -1077,10 +1114,18 @@
10771114
10781115
$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
10791116
$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
10801117
10811118
$(OBJDIR)/builtin.h: $(OBJDIR)/headers
1119
+
1120
+$(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(TRANSLATE)
1121
+ $(TRANSLATE) $(SRCDIR)/bundle.c >$@
1122
+
1123
+$(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
1124
+ $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c
1125
+
1126
+$(OBJDIR)/bundle.h: $(OBJDIR)/headers
10821127
10831128
$(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
10841129
$(TRANSLATE) $(SRCDIR)/cache.c >$@
10851130
10861131
$(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1605,10 +1650,26 @@
16051650
16061651
$(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
16071652
$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
16081653
16091654
$(OBJDIR)/printf.h: $(OBJDIR)/headers
1655
+
1656
+$(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(TRANSLATE)
1657
+ $(TRANSLATE) $(SRCDIR)/publish.c >$@
1658
+
1659
+$(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
1660
+ $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c
1661
+
1662
+$(OBJDIR)/publish.h: $(OBJDIR)/headers
1663
+
1664
+$(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(TRANSLATE)
1665
+ $(TRANSLATE) $(SRCDIR)/purge.c >$@
1666
+
1667
+$(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
1668
+ $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c
1669
+
1670
+$(OBJDIR)/purge.h: $(OBJDIR)/headers
16101671
16111672
$(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE)
16121673
$(TRANSLATE) $(SRCDIR)/rebuild.c >$@
16131674
16141675
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1677,10 +1738,18 @@
16771738
16781739
$(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
16791740
$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
16801741
16811742
$(OBJDIR)/shun.h: $(OBJDIR)/headers
1743
+
1744
+$(OBJDIR)/sitemap_.c: $(SRCDIR)/sitemap.c $(TRANSLATE)
1745
+ $(TRANSLATE) $(SRCDIR)/sitemap.c >$@
1746
+
1747
+$(OBJDIR)/sitemap.o: $(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
1748
+ $(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c
1749
+
1750
+$(OBJDIR)/sitemap.h: $(OBJDIR)/headers
16821751
16831752
$(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(TRANSLATE)
16841753
$(TRANSLATE) $(SRCDIR)/skins.c >$@
16851754
16861755
$(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
16871756
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -87,11 +87,12 @@
87 # This is useful when Tcl has been compiled statically with MinGW.
88 #
89 FOSSIL_TCL_SOURCE = 1
90
91 #### Check if the workaround for the MinGW command line handling needs to
92 # be enabled by default.
 
93 #
94 ifndef MINGW_IS_32BIT_ONLY
95 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
96 MINGW_IS_32BIT_ONLY = 1
97 endif
@@ -100,26 +101,46 @@
100 #### The directories where the zlib include and library files are located.
101 #
102 ZINCDIR = $(SRCDIR)/../compat/zlib
103 ZLIBDIR = $(SRCDIR)/../compat/zlib
104
 
 
 
105 ifndef X64
106 ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
107 X64 = 1
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
120
 
 
 
 
 
 
 
 
121 ifndef FOSSIL_ENABLE_MINIZ
122 SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
123 endif
124
125 #### The directories where the OpenSSL include and library files are located.
@@ -352,10 +373,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,19 +440,22 @@
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 \
428 $(SRCDIR)/search.c \
429 $(SRCDIR)/setup.c \
430 $(SRCDIR)/sha1.c \
431 $(SRCDIR)/shun.c \
 
432 $(SRCDIR)/skins.c \
433 $(SRCDIR)/sqlcmd.c \
434 $(SRCDIR)/stash.c \
435 $(SRCDIR)/stat.c \
436 $(SRCDIR)/style.c \
@@ -470,10 +495,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,19 +562,22 @@
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 \
546 $(OBJDIR)/search_.c \
547 $(OBJDIR)/setup_.c \
548 $(OBJDIR)/sha1_.c \
549 $(OBJDIR)/shun_.c \
 
550 $(OBJDIR)/skins_.c \
551 $(OBJDIR)/sqlcmd_.c \
552 $(OBJDIR)/stash_.c \
553 $(OBJDIR)/stat_.c \
554 $(OBJDIR)/style_.c \
@@ -585,10 +614,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,19 +681,22 @@
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 \
661 $(OBJDIR)/search.o \
662 $(OBJDIR)/setup.o \
663 $(OBJDIR)/sha1.o \
664 $(OBJDIR)/shun.o \
 
665 $(OBJDIR)/skins.o \
666 $(OBJDIR)/sqlcmd.o \
667 $(OBJDIR)/stash.o \
668 $(OBJDIR)/stat.o \
669 $(OBJDIR)/style.o \
@@ -893,10 +926,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,19 +993,22 @@
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 \
969 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
970 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
971 $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
972 $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
 
973 $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
974 $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
975 $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
976 $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
977 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -1077,10 +1114,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 +1650,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
@@ -1677,10 +1738,18 @@
1677
1678 $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
1679 $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
1680
1681 $(OBJDIR)/shun.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1682
1683 $(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(TRANSLATE)
1684 $(TRANSLATE) $(SRCDIR)/skins.c >$@
1685
1686 $(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
1687
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -87,11 +87,12 @@
87 # This is useful when Tcl has been compiled statically with MinGW.
88 #
89 FOSSIL_TCL_SOURCE = 1
90
91 #### Check if the workaround for the MinGW command line handling needs to
92 # be enabled by default. This check may be somewhat fragile due to the
93 # use of "findstring".
94 #
95 ifndef MINGW_IS_32BIT_ONLY
96 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
97 MINGW_IS_32BIT_ONLY = 1
98 endif
@@ -100,26 +101,46 @@
101 #### The directories where the zlib include and library files are located.
102 #
103 ZINCDIR = $(SRCDIR)/../compat/zlib
104 ZLIBDIR = $(SRCDIR)/../compat/zlib
105
106 #### Make an attempt to detect if Fossil is being built for the x64 processor
107 # architecture. This check may be somewhat fragile due to "findstring".
108 #
109 ifndef X64
110 ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
111 X64 = 1
112 endif
113 endif
114
115 #### Determine if the optimized assembly routines provided with zlib should be
116 # used, taking into account whether zlib is actually enabled and the target
117 # processor architecture.
118 #
119 ifndef X64
120 SSLCONFIG = mingw
121 ifndef FOSSIL_ENABLE_MINIZ
122 ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
123 LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
124 else
125 ZLIBCONFIG =
126 LIBTARGETS =
127 endif
128 else
129 SSLCONFIG = mingw64
130 ZLIBCONFIG =
131 LIBTARGETS =
132 endif
133
134 #### Disable creation of the OpenSSL shared libraries. Also, disable support
135 # for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
136 #
137 SSLCONFIG += no-ssl2 no-ssl3 no-shared
138
139 #### When using zlib, make sure that OpenSSL is configured to use the zlib
140 # that Fossil knows about (i.e. the one within the source tree).
141 #
142 ifndef FOSSIL_ENABLE_MINIZ
143 SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
144 endif
145
146 #### The directories where the OpenSSL include and library files are located.
@@ -352,10 +373,11 @@
373 $(SRCDIR)/bisect.c \
374 $(SRCDIR)/blob.c \
375 $(SRCDIR)/branch.c \
376 $(SRCDIR)/browse.c \
377 $(SRCDIR)/builtin.c \
378 $(SRCDIR)/bundle.c \
379 $(SRCDIR)/cache.c \
380 $(SRCDIR)/captcha.c \
381 $(SRCDIR)/cgi.c \
382 $(SRCDIR)/checkin.c \
383 $(SRCDIR)/checkout.c \
@@ -418,19 +440,22 @@
440 $(SRCDIR)/path.c \
441 $(SRCDIR)/pivot.c \
442 $(SRCDIR)/popen.c \
443 $(SRCDIR)/pqueue.c \
444 $(SRCDIR)/printf.c \
445 $(SRCDIR)/publish.c \
446 $(SRCDIR)/purge.c \
447 $(SRCDIR)/rebuild.c \
448 $(SRCDIR)/regexp.c \
449 $(SRCDIR)/report.c \
450 $(SRCDIR)/rss.c \
451 $(SRCDIR)/schema.c \
452 $(SRCDIR)/search.c \
453 $(SRCDIR)/setup.c \
454 $(SRCDIR)/sha1.c \
455 $(SRCDIR)/shun.c \
456 $(SRCDIR)/sitemap.c \
457 $(SRCDIR)/skins.c \
458 $(SRCDIR)/sqlcmd.c \
459 $(SRCDIR)/stash.c \
460 $(SRCDIR)/stat.c \
461 $(SRCDIR)/style.c \
@@ -470,10 +495,11 @@
495 $(OBJDIR)/bisect_.c \
496 $(OBJDIR)/blob_.c \
497 $(OBJDIR)/branch_.c \
498 $(OBJDIR)/browse_.c \
499 $(OBJDIR)/builtin_.c \
500 $(OBJDIR)/bundle_.c \
501 $(OBJDIR)/cache_.c \
502 $(OBJDIR)/captcha_.c \
503 $(OBJDIR)/cgi_.c \
504 $(OBJDIR)/checkin_.c \
505 $(OBJDIR)/checkout_.c \
@@ -536,19 +562,22 @@
562 $(OBJDIR)/path_.c \
563 $(OBJDIR)/pivot_.c \
564 $(OBJDIR)/popen_.c \
565 $(OBJDIR)/pqueue_.c \
566 $(OBJDIR)/printf_.c \
567 $(OBJDIR)/publish_.c \
568 $(OBJDIR)/purge_.c \
569 $(OBJDIR)/rebuild_.c \
570 $(OBJDIR)/regexp_.c \
571 $(OBJDIR)/report_.c \
572 $(OBJDIR)/rss_.c \
573 $(OBJDIR)/schema_.c \
574 $(OBJDIR)/search_.c \
575 $(OBJDIR)/setup_.c \
576 $(OBJDIR)/sha1_.c \
577 $(OBJDIR)/shun_.c \
578 $(OBJDIR)/sitemap_.c \
579 $(OBJDIR)/skins_.c \
580 $(OBJDIR)/sqlcmd_.c \
581 $(OBJDIR)/stash_.c \
582 $(OBJDIR)/stat_.c \
583 $(OBJDIR)/style_.c \
@@ -585,10 +614,11 @@
614 $(OBJDIR)/bisect.o \
615 $(OBJDIR)/blob.o \
616 $(OBJDIR)/branch.o \
617 $(OBJDIR)/browse.o \
618 $(OBJDIR)/builtin.o \
619 $(OBJDIR)/bundle.o \
620 $(OBJDIR)/cache.o \
621 $(OBJDIR)/captcha.o \
622 $(OBJDIR)/cgi.o \
623 $(OBJDIR)/checkin.o \
624 $(OBJDIR)/checkout.o \
@@ -651,19 +681,22 @@
681 $(OBJDIR)/path.o \
682 $(OBJDIR)/pivot.o \
683 $(OBJDIR)/popen.o \
684 $(OBJDIR)/pqueue.o \
685 $(OBJDIR)/printf.o \
686 $(OBJDIR)/publish.o \
687 $(OBJDIR)/purge.o \
688 $(OBJDIR)/rebuild.o \
689 $(OBJDIR)/regexp.o \
690 $(OBJDIR)/report.o \
691 $(OBJDIR)/rss.o \
692 $(OBJDIR)/schema.o \
693 $(OBJDIR)/search.o \
694 $(OBJDIR)/setup.o \
695 $(OBJDIR)/sha1.o \
696 $(OBJDIR)/shun.o \
697 $(OBJDIR)/sitemap.o \
698 $(OBJDIR)/skins.o \
699 $(OBJDIR)/sqlcmd.o \
700 $(OBJDIR)/stash.o \
701 $(OBJDIR)/stat.o \
702 $(OBJDIR)/style.o \
@@ -893,10 +926,11 @@
926 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
927 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
928 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
929 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
930 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
931 $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
932 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
933 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
934 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
935 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
936 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -959,19 +993,22 @@
993 $(OBJDIR)/path_.c:$(OBJDIR)/path.h \
994 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
995 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
996 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
997 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
998 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
999 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1000 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1001 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1002 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1003 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1004 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1005 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1006 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
1007 $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
1008 $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
1009 $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
1010 $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
1011 $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
1012 $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
1013 $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
1014 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -1077,10 +1114,18 @@
1114
1115 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1116 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1117
1118 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
1119
1120 $(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(TRANSLATE)
1121 $(TRANSLATE) $(SRCDIR)/bundle.c >$@
1122
1123 $(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
1124 $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c
1125
1126 $(OBJDIR)/bundle.h: $(OBJDIR)/headers
1127
1128 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1129 $(TRANSLATE) $(SRCDIR)/cache.c >$@
1130
1131 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1605,10 +1650,26 @@
1650
1651 $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
1652 $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
1653
1654 $(OBJDIR)/printf.h: $(OBJDIR)/headers
1655
1656 $(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(TRANSLATE)
1657 $(TRANSLATE) $(SRCDIR)/publish.c >$@
1658
1659 $(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
1660 $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c
1661
1662 $(OBJDIR)/publish.h: $(OBJDIR)/headers
1663
1664 $(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(TRANSLATE)
1665 $(TRANSLATE) $(SRCDIR)/purge.c >$@
1666
1667 $(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
1668 $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c
1669
1670 $(OBJDIR)/purge.h: $(OBJDIR)/headers
1671
1672 $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE)
1673 $(TRANSLATE) $(SRCDIR)/rebuild.c >$@
1674
1675 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1677,10 +1738,18 @@
1738
1739 $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
1740 $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
1741
1742 $(OBJDIR)/shun.h: $(OBJDIR)/headers
1743
1744 $(OBJDIR)/sitemap_.c: $(SRCDIR)/sitemap.c $(TRANSLATE)
1745 $(TRANSLATE) $(SRCDIR)/sitemap.c >$@
1746
1747 $(OBJDIR)/sitemap.o: $(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
1748 $(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c
1749
1750 $(OBJDIR)/sitemap.h: $(OBJDIR)/headers
1751
1752 $(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(TRANSLATE)
1753 $(TRANSLATE) $(SRCDIR)/skins.c >$@
1754
1755 $(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
1756
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -87,11 +87,12 @@
8787
# This is useful when Tcl has been compiled statically with MinGW.
8888
#
8989
FOSSIL_TCL_SOURCE = 1
9090
9191
#### Check if the workaround for the MinGW command line handling needs to
92
-# be enabled by default.
92
+# be enabled by default. This check may be somewhat fragile due to the
93
+# use of "findstring".
9394
#
9495
ifndef MINGW_IS_32BIT_ONLY
9596
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
9697
MINGW_IS_32BIT_ONLY = 1
9798
endif
@@ -100,26 +101,46 @@
100101
#### The directories where the zlib include and library files are located.
101102
#
102103
ZINCDIR = $(SRCDIR)/../compat/zlib
103104
ZLIBDIR = $(SRCDIR)/../compat/zlib
104105
106
+#### Make an attempt to detect if Fossil is being built for the x64 processor
107
+# architecture. This check may be somewhat fragile due to "findstring".
108
+#
105109
ifndef X64
106110
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
107111
X64 = 1
108112
endif
109113
endif
110114
115
+#### Determine if the optimized assembly routines provided with zlib should be
116
+# used, taking into account whether zlib is actually enabled and the target
117
+# processor architecture.
118
+#
111119
ifndef X64
112120
SSLCONFIG = mingw
121
+ifndef FOSSIL_ENABLE_MINIZ
113122
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
114123
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
124
+else
125
+ZLIBCONFIG =
126
+LIBTARGETS =
127
+endif
115128
else
116129
SSLCONFIG = mingw64
117
-ZLIBCONFIG =
130
+ZLIBCONFIG =
118131
LIBTARGETS =
119132
endif
120133
134
+#### Disable creation of the OpenSSL shared libraries. Also, disable support
135
+# for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
136
+#
137
+SSLCONFIG += no-ssl2 no-ssl3 no-shared
138
+
139
+#### When using zlib, make sure that OpenSSL is configured to use the zlib
140
+# that Fossil knows about (i.e. the one within the source tree).
141
+#
121142
ifndef FOSSIL_ENABLE_MINIZ
122143
SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
123144
endif
124145
125146
#### The directories where the OpenSSL include and library files are located.
@@ -352,10 +373,11 @@
352373
$(SRCDIR)/bisect.c \
353374
$(SRCDIR)/blob.c \
354375
$(SRCDIR)/branch.c \
355376
$(SRCDIR)/browse.c \
356377
$(SRCDIR)/builtin.c \
378
+ $(SRCDIR)/bundle.c \
357379
$(SRCDIR)/cache.c \
358380
$(SRCDIR)/captcha.c \
359381
$(SRCDIR)/cgi.c \
360382
$(SRCDIR)/checkin.c \
361383
$(SRCDIR)/checkout.c \
@@ -374,10 +396,11 @@
374396
$(SRCDIR)/encode.c \
375397
$(SRCDIR)/event.c \
376398
$(SRCDIR)/export.c \
377399
$(SRCDIR)/file.c \
378400
$(SRCDIR)/finfo.c \
401
+ $(SRCDIR)/foci.c \
379402
$(SRCDIR)/fusefs.c \
380403
$(SRCDIR)/glob.c \
381404
$(SRCDIR)/graph.c \
382405
$(SRCDIR)/gzip.c \
383406
$(SRCDIR)/http.c \
@@ -417,19 +440,22 @@
417440
$(SRCDIR)/path.c \
418441
$(SRCDIR)/pivot.c \
419442
$(SRCDIR)/popen.c \
420443
$(SRCDIR)/pqueue.c \
421444
$(SRCDIR)/printf.c \
445
+ $(SRCDIR)/publish.c \
446
+ $(SRCDIR)/purge.c \
422447
$(SRCDIR)/rebuild.c \
423448
$(SRCDIR)/regexp.c \
424449
$(SRCDIR)/report.c \
425450
$(SRCDIR)/rss.c \
426451
$(SRCDIR)/schema.c \
427452
$(SRCDIR)/search.c \
428453
$(SRCDIR)/setup.c \
429454
$(SRCDIR)/sha1.c \
430455
$(SRCDIR)/shun.c \
456
+ $(SRCDIR)/sitemap.c \
431457
$(SRCDIR)/skins.c \
432458
$(SRCDIR)/sqlcmd.c \
433459
$(SRCDIR)/stash.c \
434460
$(SRCDIR)/stat.c \
435461
$(SRCDIR)/style.c \
@@ -469,10 +495,11 @@
469495
$(OBJDIR)/bisect_.c \
470496
$(OBJDIR)/blob_.c \
471497
$(OBJDIR)/branch_.c \
472498
$(OBJDIR)/browse_.c \
473499
$(OBJDIR)/builtin_.c \
500
+ $(OBJDIR)/bundle_.c \
474501
$(OBJDIR)/cache_.c \
475502
$(OBJDIR)/captcha_.c \
476503
$(OBJDIR)/cgi_.c \
477504
$(OBJDIR)/checkin_.c \
478505
$(OBJDIR)/checkout_.c \
@@ -491,10 +518,11 @@
491518
$(OBJDIR)/encode_.c \
492519
$(OBJDIR)/event_.c \
493520
$(OBJDIR)/export_.c \
494521
$(OBJDIR)/file_.c \
495522
$(OBJDIR)/finfo_.c \
523
+ $(OBJDIR)/foci_.c \
496524
$(OBJDIR)/fusefs_.c \
497525
$(OBJDIR)/glob_.c \
498526
$(OBJDIR)/graph_.c \
499527
$(OBJDIR)/gzip_.c \
500528
$(OBJDIR)/http_.c \
@@ -534,19 +562,22 @@
534562
$(OBJDIR)/path_.c \
535563
$(OBJDIR)/pivot_.c \
536564
$(OBJDIR)/popen_.c \
537565
$(OBJDIR)/pqueue_.c \
538566
$(OBJDIR)/printf_.c \
567
+ $(OBJDIR)/publish_.c \
568
+ $(OBJDIR)/purge_.c \
539569
$(OBJDIR)/rebuild_.c \
540570
$(OBJDIR)/regexp_.c \
541571
$(OBJDIR)/report_.c \
542572
$(OBJDIR)/rss_.c \
543573
$(OBJDIR)/schema_.c \
544574
$(OBJDIR)/search_.c \
545575
$(OBJDIR)/setup_.c \
546576
$(OBJDIR)/sha1_.c \
547577
$(OBJDIR)/shun_.c \
578
+ $(OBJDIR)/sitemap_.c \
548579
$(OBJDIR)/skins_.c \
549580
$(OBJDIR)/sqlcmd_.c \
550581
$(OBJDIR)/stash_.c \
551582
$(OBJDIR)/stat_.c \
552583
$(OBJDIR)/style_.c \
@@ -583,10 +614,11 @@
583614
$(OBJDIR)/bisect.o \
584615
$(OBJDIR)/blob.o \
585616
$(OBJDIR)/branch.o \
586617
$(OBJDIR)/browse.o \
587618
$(OBJDIR)/builtin.o \
619
+ $(OBJDIR)/bundle.o \
588620
$(OBJDIR)/cache.o \
589621
$(OBJDIR)/captcha.o \
590622
$(OBJDIR)/cgi.o \
591623
$(OBJDIR)/checkin.o \
592624
$(OBJDIR)/checkout.o \
@@ -605,10 +637,11 @@
605637
$(OBJDIR)/encode.o \
606638
$(OBJDIR)/event.o \
607639
$(OBJDIR)/export.o \
608640
$(OBJDIR)/file.o \
609641
$(OBJDIR)/finfo.o \
642
+ $(OBJDIR)/foci.o \
610643
$(OBJDIR)/fusefs.o \
611644
$(OBJDIR)/glob.o \
612645
$(OBJDIR)/graph.o \
613646
$(OBJDIR)/gzip.o \
614647
$(OBJDIR)/http.o \
@@ -648,19 +681,22 @@
648681
$(OBJDIR)/path.o \
649682
$(OBJDIR)/pivot.o \
650683
$(OBJDIR)/popen.o \
651684
$(OBJDIR)/pqueue.o \
652685
$(OBJDIR)/printf.o \
686
+ $(OBJDIR)/publish.o \
687
+ $(OBJDIR)/purge.o \
653688
$(OBJDIR)/rebuild.o \
654689
$(OBJDIR)/regexp.o \
655690
$(OBJDIR)/report.o \
656691
$(OBJDIR)/rss.o \
657692
$(OBJDIR)/schema.o \
658693
$(OBJDIR)/search.o \
659694
$(OBJDIR)/setup.o \
660695
$(OBJDIR)/sha1.o \
661696
$(OBJDIR)/shun.o \
697
+ $(OBJDIR)/sitemap.o \
662698
$(OBJDIR)/skins.o \
663699
$(OBJDIR)/sqlcmd.o \
664700
$(OBJDIR)/stash.o \
665701
$(OBJDIR)/stat.o \
666702
$(OBJDIR)/style.o \
@@ -890,10 +926,11 @@
890926
$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
891927
$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
892928
$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
893929
$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
894930
$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
931
+ $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
895932
$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
896933
$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
897934
$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
898935
$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
899936
$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -912,10 +949,11 @@
912949
$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
913950
$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
914951
$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
915952
$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
916953
$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
954
+ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
917955
$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
918956
$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
919957
$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
920958
$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
921959
$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
@@ -955,19 +993,22 @@
955993
$(OBJDIR)/path_.c:$(OBJDIR)/path.h \
956994
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
957995
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
958996
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
959997
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
998
+ $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
999
+ $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
9601000
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
9611001
$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
9621002
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
9631003
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
9641004
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
9651005
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
9661006
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
9671007
$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
9681008
$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
1009
+ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
9691010
$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
9701011
$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
9711012
$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
9721013
$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
9731014
$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -1073,10 +1114,18 @@
10731114
10741115
$(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
10751116
$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
10761117
10771118
$(OBJDIR)/builtin.h: $(OBJDIR)/headers
1119
+
1120
+$(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(TRANSLATE)
1121
+ $(TRANSLATE) $(SRCDIR)/bundle.c >$@
1122
+
1123
+$(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
1124
+ $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c
1125
+
1126
+$(OBJDIR)/bundle.h: $(OBJDIR)/headers
10781127
10791128
$(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
10801129
$(TRANSLATE) $(SRCDIR)/cache.c >$@
10811130
10821131
$(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1249,10 +1298,18 @@
12491298
12501299
$(OBJDIR)/finfo.o: $(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
12511300
$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c
12521301
12531302
$(OBJDIR)/finfo.h: $(OBJDIR)/headers
1303
+
1304
+$(OBJDIR)/foci_.c: $(SRCDIR)/foci.c $(TRANSLATE)
1305
+ $(TRANSLATE) $(SRCDIR)/foci.c >$@
1306
+
1307
+$(OBJDIR)/foci.o: $(OBJDIR)/foci_.c $(OBJDIR)/foci.h $(SRCDIR)/config.h
1308
+ $(XTCC) -o $(OBJDIR)/foci.o -c $(OBJDIR)/foci_.c
1309
+
1310
+$(OBJDIR)/foci.h: $(OBJDIR)/headers
12541311
12551312
$(OBJDIR)/fusefs_.c: $(SRCDIR)/fusefs.c $(TRANSLATE)
12561313
$(TRANSLATE) $(SRCDIR)/fusefs.c >$@
12571314
12581315
$(OBJDIR)/fusefs.o: $(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
@@ -1593,10 +1650,26 @@
15931650
15941651
$(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
15951652
$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
15961653
15971654
$(OBJDIR)/printf.h: $(OBJDIR)/headers
1655
+
1656
+$(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(TRANSLATE)
1657
+ $(TRANSLATE) $(SRCDIR)/publish.c >$@
1658
+
1659
+$(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
1660
+ $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c
1661
+
1662
+$(OBJDIR)/publish.h: $(OBJDIR)/headers
1663
+
1664
+$(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(TRANSLATE)
1665
+ $(TRANSLATE) $(SRCDIR)/purge.c >$@
1666
+
1667
+$(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
1668
+ $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c
1669
+
1670
+$(OBJDIR)/purge.h: $(OBJDIR)/headers
15981671
15991672
$(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE)
16001673
$(TRANSLATE) $(SRCDIR)/rebuild.c >$@
16011674
16021675
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1665,10 +1738,18 @@
16651738
16661739
$(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
16671740
$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
16681741
16691742
$(OBJDIR)/shun.h: $(OBJDIR)/headers
1743
+
1744
+$(OBJDIR)/sitemap_.c: $(SRCDIR)/sitemap.c $(TRANSLATE)
1745
+ $(TRANSLATE) $(SRCDIR)/sitemap.c >$@
1746
+
1747
+$(OBJDIR)/sitemap.o: $(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
1748
+ $(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c
1749
+
1750
+$(OBJDIR)/sitemap.h: $(OBJDIR)/headers
16701751
16711752
$(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(TRANSLATE)
16721753
$(TRANSLATE) $(SRCDIR)/skins.c >$@
16731754
16741755
$(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
16751756
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -87,11 +87,12 @@
87 # This is useful when Tcl has been compiled statically with MinGW.
88 #
89 FOSSIL_TCL_SOURCE = 1
90
91 #### Check if the workaround for the MinGW command line handling needs to
92 # be enabled by default.
 
93 #
94 ifndef MINGW_IS_32BIT_ONLY
95 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
96 MINGW_IS_32BIT_ONLY = 1
97 endif
@@ -100,26 +101,46 @@
100 #### The directories where the zlib include and library files are located.
101 #
102 ZINCDIR = $(SRCDIR)/../compat/zlib
103 ZLIBDIR = $(SRCDIR)/../compat/zlib
104
 
 
 
105 ifndef X64
106 ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
107 X64 = 1
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
120
 
 
 
 
 
 
 
 
121 ifndef FOSSIL_ENABLE_MINIZ
122 SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
123 endif
124
125 #### The directories where the OpenSSL include and library files are located.
@@ -352,10 +373,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 \
@@ -374,10 +396,11 @@
374 $(SRCDIR)/encode.c \
375 $(SRCDIR)/event.c \
376 $(SRCDIR)/export.c \
377 $(SRCDIR)/file.c \
378 $(SRCDIR)/finfo.c \
 
379 $(SRCDIR)/fusefs.c \
380 $(SRCDIR)/glob.c \
381 $(SRCDIR)/graph.c \
382 $(SRCDIR)/gzip.c \
383 $(SRCDIR)/http.c \
@@ -417,19 +440,22 @@
417 $(SRCDIR)/path.c \
418 $(SRCDIR)/pivot.c \
419 $(SRCDIR)/popen.c \
420 $(SRCDIR)/pqueue.c \
421 $(SRCDIR)/printf.c \
 
 
422 $(SRCDIR)/rebuild.c \
423 $(SRCDIR)/regexp.c \
424 $(SRCDIR)/report.c \
425 $(SRCDIR)/rss.c \
426 $(SRCDIR)/schema.c \
427 $(SRCDIR)/search.c \
428 $(SRCDIR)/setup.c \
429 $(SRCDIR)/sha1.c \
430 $(SRCDIR)/shun.c \
 
431 $(SRCDIR)/skins.c \
432 $(SRCDIR)/sqlcmd.c \
433 $(SRCDIR)/stash.c \
434 $(SRCDIR)/stat.c \
435 $(SRCDIR)/style.c \
@@ -469,10 +495,11 @@
469 $(OBJDIR)/bisect_.c \
470 $(OBJDIR)/blob_.c \
471 $(OBJDIR)/branch_.c \
472 $(OBJDIR)/browse_.c \
473 $(OBJDIR)/builtin_.c \
 
474 $(OBJDIR)/cache_.c \
475 $(OBJDIR)/captcha_.c \
476 $(OBJDIR)/cgi_.c \
477 $(OBJDIR)/checkin_.c \
478 $(OBJDIR)/checkout_.c \
@@ -491,10 +518,11 @@
491 $(OBJDIR)/encode_.c \
492 $(OBJDIR)/event_.c \
493 $(OBJDIR)/export_.c \
494 $(OBJDIR)/file_.c \
495 $(OBJDIR)/finfo_.c \
 
496 $(OBJDIR)/fusefs_.c \
497 $(OBJDIR)/glob_.c \
498 $(OBJDIR)/graph_.c \
499 $(OBJDIR)/gzip_.c \
500 $(OBJDIR)/http_.c \
@@ -534,19 +562,22 @@
534 $(OBJDIR)/path_.c \
535 $(OBJDIR)/pivot_.c \
536 $(OBJDIR)/popen_.c \
537 $(OBJDIR)/pqueue_.c \
538 $(OBJDIR)/printf_.c \
 
 
539 $(OBJDIR)/rebuild_.c \
540 $(OBJDIR)/regexp_.c \
541 $(OBJDIR)/report_.c \
542 $(OBJDIR)/rss_.c \
543 $(OBJDIR)/schema_.c \
544 $(OBJDIR)/search_.c \
545 $(OBJDIR)/setup_.c \
546 $(OBJDIR)/sha1_.c \
547 $(OBJDIR)/shun_.c \
 
548 $(OBJDIR)/skins_.c \
549 $(OBJDIR)/sqlcmd_.c \
550 $(OBJDIR)/stash_.c \
551 $(OBJDIR)/stat_.c \
552 $(OBJDIR)/style_.c \
@@ -583,10 +614,11 @@
583 $(OBJDIR)/bisect.o \
584 $(OBJDIR)/blob.o \
585 $(OBJDIR)/branch.o \
586 $(OBJDIR)/browse.o \
587 $(OBJDIR)/builtin.o \
 
588 $(OBJDIR)/cache.o \
589 $(OBJDIR)/captcha.o \
590 $(OBJDIR)/cgi.o \
591 $(OBJDIR)/checkin.o \
592 $(OBJDIR)/checkout.o \
@@ -605,10 +637,11 @@
605 $(OBJDIR)/encode.o \
606 $(OBJDIR)/event.o \
607 $(OBJDIR)/export.o \
608 $(OBJDIR)/file.o \
609 $(OBJDIR)/finfo.o \
 
610 $(OBJDIR)/fusefs.o \
611 $(OBJDIR)/glob.o \
612 $(OBJDIR)/graph.o \
613 $(OBJDIR)/gzip.o \
614 $(OBJDIR)/http.o \
@@ -648,19 +681,22 @@
648 $(OBJDIR)/path.o \
649 $(OBJDIR)/pivot.o \
650 $(OBJDIR)/popen.o \
651 $(OBJDIR)/pqueue.o \
652 $(OBJDIR)/printf.o \
 
 
653 $(OBJDIR)/rebuild.o \
654 $(OBJDIR)/regexp.o \
655 $(OBJDIR)/report.o \
656 $(OBJDIR)/rss.o \
657 $(OBJDIR)/schema.o \
658 $(OBJDIR)/search.o \
659 $(OBJDIR)/setup.o \
660 $(OBJDIR)/sha1.o \
661 $(OBJDIR)/shun.o \
 
662 $(OBJDIR)/skins.o \
663 $(OBJDIR)/sqlcmd.o \
664 $(OBJDIR)/stash.o \
665 $(OBJDIR)/stat.o \
666 $(OBJDIR)/style.o \
@@ -890,10 +926,11 @@
890 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
891 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
892 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
893 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
894 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
 
895 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
896 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
897 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
898 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
899 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -912,10 +949,11 @@
912 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
913 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
914 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
915 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
916 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
 
917 $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
918 $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
919 $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
920 $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
921 $(OBJDIR)/http_.c:$(OBJDIR)/http.h \
@@ -955,19 +993,22 @@
955 $(OBJDIR)/path_.c:$(OBJDIR)/path.h \
956 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
957 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
958 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
959 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
 
 
960 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
961 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
962 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
963 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
964 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
965 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
966 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
967 $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
968 $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
 
969 $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
970 $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
971 $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
972 $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
973 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -1073,10 +1114,18 @@
1073
1074 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1075 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1076
1077 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1078
1079 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1080 $(TRANSLATE) $(SRCDIR)/cache.c >$@
1081
1082 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1249,10 +1298,18 @@
1249
1250 $(OBJDIR)/finfo.o: $(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
1251 $(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c
1252
1253 $(OBJDIR)/finfo.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1254
1255 $(OBJDIR)/fusefs_.c: $(SRCDIR)/fusefs.c $(TRANSLATE)
1256 $(TRANSLATE) $(SRCDIR)/fusefs.c >$@
1257
1258 $(OBJDIR)/fusefs.o: $(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
@@ -1593,10 +1650,26 @@
1593
1594 $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
1595 $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
1596
1597 $(OBJDIR)/printf.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1598
1599 $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE)
1600 $(TRANSLATE) $(SRCDIR)/rebuild.c >$@
1601
1602 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1665,10 +1738,18 @@
1665
1666 $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
1667 $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
1668
1669 $(OBJDIR)/shun.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1670
1671 $(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(TRANSLATE)
1672 $(TRANSLATE) $(SRCDIR)/skins.c >$@
1673
1674 $(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
1675
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -87,11 +87,12 @@
87 # This is useful when Tcl has been compiled statically with MinGW.
88 #
89 FOSSIL_TCL_SOURCE = 1
90
91 #### Check if the workaround for the MinGW command line handling needs to
92 # be enabled by default. This check may be somewhat fragile due to the
93 # use of "findstring".
94 #
95 ifndef MINGW_IS_32BIT_ONLY
96 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
97 MINGW_IS_32BIT_ONLY = 1
98 endif
@@ -100,26 +101,46 @@
101 #### The directories where the zlib include and library files are located.
102 #
103 ZINCDIR = $(SRCDIR)/../compat/zlib
104 ZLIBDIR = $(SRCDIR)/../compat/zlib
105
106 #### Make an attempt to detect if Fossil is being built for the x64 processor
107 # architecture. This check may be somewhat fragile due to "findstring".
108 #
109 ifndef X64
110 ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
111 X64 = 1
112 endif
113 endif
114
115 #### Determine if the optimized assembly routines provided with zlib should be
116 # used, taking into account whether zlib is actually enabled and the target
117 # processor architecture.
118 #
119 ifndef X64
120 SSLCONFIG = mingw
121 ifndef FOSSIL_ENABLE_MINIZ
122 ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
123 LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
124 else
125 ZLIBCONFIG =
126 LIBTARGETS =
127 endif
128 else
129 SSLCONFIG = mingw64
130 ZLIBCONFIG =
131 LIBTARGETS =
132 endif
133
134 #### Disable creation of the OpenSSL shared libraries. Also, disable support
135 # for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
136 #
137 SSLCONFIG += no-ssl2 no-ssl3 no-shared
138
139 #### When using zlib, make sure that OpenSSL is configured to use the zlib
140 # that Fossil knows about (i.e. the one within the source tree).
141 #
142 ifndef FOSSIL_ENABLE_MINIZ
143 SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
144 endif
145
146 #### The directories where the OpenSSL include and library files are located.
@@ -352,10 +373,11 @@
373 $(SRCDIR)/bisect.c \
374 $(SRCDIR)/blob.c \
375 $(SRCDIR)/branch.c \
376 $(SRCDIR)/browse.c \
377 $(SRCDIR)/builtin.c \
378 $(SRCDIR)/bundle.c \
379 $(SRCDIR)/cache.c \
380 $(SRCDIR)/captcha.c \
381 $(SRCDIR)/cgi.c \
382 $(SRCDIR)/checkin.c \
383 $(SRCDIR)/checkout.c \
@@ -374,10 +396,11 @@
396 $(SRCDIR)/encode.c \
397 $(SRCDIR)/event.c \
398 $(SRCDIR)/export.c \
399 $(SRCDIR)/file.c \
400 $(SRCDIR)/finfo.c \
401 $(SRCDIR)/foci.c \
402 $(SRCDIR)/fusefs.c \
403 $(SRCDIR)/glob.c \
404 $(SRCDIR)/graph.c \
405 $(SRCDIR)/gzip.c \
406 $(SRCDIR)/http.c \
@@ -417,19 +440,22 @@
440 $(SRCDIR)/path.c \
441 $(SRCDIR)/pivot.c \
442 $(SRCDIR)/popen.c \
443 $(SRCDIR)/pqueue.c \
444 $(SRCDIR)/printf.c \
445 $(SRCDIR)/publish.c \
446 $(SRCDIR)/purge.c \
447 $(SRCDIR)/rebuild.c \
448 $(SRCDIR)/regexp.c \
449 $(SRCDIR)/report.c \
450 $(SRCDIR)/rss.c \
451 $(SRCDIR)/schema.c \
452 $(SRCDIR)/search.c \
453 $(SRCDIR)/setup.c \
454 $(SRCDIR)/sha1.c \
455 $(SRCDIR)/shun.c \
456 $(SRCDIR)/sitemap.c \
457 $(SRCDIR)/skins.c \
458 $(SRCDIR)/sqlcmd.c \
459 $(SRCDIR)/stash.c \
460 $(SRCDIR)/stat.c \
461 $(SRCDIR)/style.c \
@@ -469,10 +495,11 @@
495 $(OBJDIR)/bisect_.c \
496 $(OBJDIR)/blob_.c \
497 $(OBJDIR)/branch_.c \
498 $(OBJDIR)/browse_.c \
499 $(OBJDIR)/builtin_.c \
500 $(OBJDIR)/bundle_.c \
501 $(OBJDIR)/cache_.c \
502 $(OBJDIR)/captcha_.c \
503 $(OBJDIR)/cgi_.c \
504 $(OBJDIR)/checkin_.c \
505 $(OBJDIR)/checkout_.c \
@@ -491,10 +518,11 @@
518 $(OBJDIR)/encode_.c \
519 $(OBJDIR)/event_.c \
520 $(OBJDIR)/export_.c \
521 $(OBJDIR)/file_.c \
522 $(OBJDIR)/finfo_.c \
523 $(OBJDIR)/foci_.c \
524 $(OBJDIR)/fusefs_.c \
525 $(OBJDIR)/glob_.c \
526 $(OBJDIR)/graph_.c \
527 $(OBJDIR)/gzip_.c \
528 $(OBJDIR)/http_.c \
@@ -534,19 +562,22 @@
562 $(OBJDIR)/path_.c \
563 $(OBJDIR)/pivot_.c \
564 $(OBJDIR)/popen_.c \
565 $(OBJDIR)/pqueue_.c \
566 $(OBJDIR)/printf_.c \
567 $(OBJDIR)/publish_.c \
568 $(OBJDIR)/purge_.c \
569 $(OBJDIR)/rebuild_.c \
570 $(OBJDIR)/regexp_.c \
571 $(OBJDIR)/report_.c \
572 $(OBJDIR)/rss_.c \
573 $(OBJDIR)/schema_.c \
574 $(OBJDIR)/search_.c \
575 $(OBJDIR)/setup_.c \
576 $(OBJDIR)/sha1_.c \
577 $(OBJDIR)/shun_.c \
578 $(OBJDIR)/sitemap_.c \
579 $(OBJDIR)/skins_.c \
580 $(OBJDIR)/sqlcmd_.c \
581 $(OBJDIR)/stash_.c \
582 $(OBJDIR)/stat_.c \
583 $(OBJDIR)/style_.c \
@@ -583,10 +614,11 @@
614 $(OBJDIR)/bisect.o \
615 $(OBJDIR)/blob.o \
616 $(OBJDIR)/branch.o \
617 $(OBJDIR)/browse.o \
618 $(OBJDIR)/builtin.o \
619 $(OBJDIR)/bundle.o \
620 $(OBJDIR)/cache.o \
621 $(OBJDIR)/captcha.o \
622 $(OBJDIR)/cgi.o \
623 $(OBJDIR)/checkin.o \
624 $(OBJDIR)/checkout.o \
@@ -605,10 +637,11 @@
637 $(OBJDIR)/encode.o \
638 $(OBJDIR)/event.o \
639 $(OBJDIR)/export.o \
640 $(OBJDIR)/file.o \
641 $(OBJDIR)/finfo.o \
642 $(OBJDIR)/foci.o \
643 $(OBJDIR)/fusefs.o \
644 $(OBJDIR)/glob.o \
645 $(OBJDIR)/graph.o \
646 $(OBJDIR)/gzip.o \
647 $(OBJDIR)/http.o \
@@ -648,19 +681,22 @@
681 $(OBJDIR)/path.o \
682 $(OBJDIR)/pivot.o \
683 $(OBJDIR)/popen.o \
684 $(OBJDIR)/pqueue.o \
685 $(OBJDIR)/printf.o \
686 $(OBJDIR)/publish.o \
687 $(OBJDIR)/purge.o \
688 $(OBJDIR)/rebuild.o \
689 $(OBJDIR)/regexp.o \
690 $(OBJDIR)/report.o \
691 $(OBJDIR)/rss.o \
692 $(OBJDIR)/schema.o \
693 $(OBJDIR)/search.o \
694 $(OBJDIR)/setup.o \
695 $(OBJDIR)/sha1.o \
696 $(OBJDIR)/shun.o \
697 $(OBJDIR)/sitemap.o \
698 $(OBJDIR)/skins.o \
699 $(OBJDIR)/sqlcmd.o \
700 $(OBJDIR)/stash.o \
701 $(OBJDIR)/stat.o \
702 $(OBJDIR)/style.o \
@@ -890,10 +926,11 @@
926 $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
927 $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
928 $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
929 $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
930 $(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
931 $(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
932 $(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
933 $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
934 $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
935 $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
936 $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
@@ -912,10 +949,11 @@
949 $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
950 $(OBJDIR)/event_.c:$(OBJDIR)/event.h \
951 $(OBJDIR)/export_.c:$(OBJDIR)/export.h \
952 $(OBJDIR)/file_.c:$(OBJDIR)/file.h \
953 $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
954 $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
955 $(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
956 $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
957 $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
958 $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
959 $(OBJDIR)/http_.c:$(OBJDIR)/http.h \
@@ -955,19 +993,22 @@
993 $(OBJDIR)/path_.c:$(OBJDIR)/path.h \
994 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
995 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
996 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
997 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
998 $(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
999 $(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
1000 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
1001 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
1002 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
1003 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
1004 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
1005 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
1006 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
1007 $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
1008 $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
1009 $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
1010 $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
1011 $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
1012 $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
1013 $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
1014 $(OBJDIR)/style_.c:$(OBJDIR)/style.h \
@@ -1073,10 +1114,18 @@
1114
1115 $(OBJDIR)/builtin.o: $(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
1116 $(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c
1117
1118 $(OBJDIR)/builtin.h: $(OBJDIR)/headers
1119
1120 $(OBJDIR)/bundle_.c: $(SRCDIR)/bundle.c $(TRANSLATE)
1121 $(TRANSLATE) $(SRCDIR)/bundle.c >$@
1122
1123 $(OBJDIR)/bundle.o: $(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
1124 $(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c
1125
1126 $(OBJDIR)/bundle.h: $(OBJDIR)/headers
1127
1128 $(OBJDIR)/cache_.c: $(SRCDIR)/cache.c $(TRANSLATE)
1129 $(TRANSLATE) $(SRCDIR)/cache.c >$@
1130
1131 $(OBJDIR)/cache.o: $(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
@@ -1249,10 +1298,18 @@
1298
1299 $(OBJDIR)/finfo.o: $(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
1300 $(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c
1301
1302 $(OBJDIR)/finfo.h: $(OBJDIR)/headers
1303
1304 $(OBJDIR)/foci_.c: $(SRCDIR)/foci.c $(TRANSLATE)
1305 $(TRANSLATE) $(SRCDIR)/foci.c >$@
1306
1307 $(OBJDIR)/foci.o: $(OBJDIR)/foci_.c $(OBJDIR)/foci.h $(SRCDIR)/config.h
1308 $(XTCC) -o $(OBJDIR)/foci.o -c $(OBJDIR)/foci_.c
1309
1310 $(OBJDIR)/foci.h: $(OBJDIR)/headers
1311
1312 $(OBJDIR)/fusefs_.c: $(SRCDIR)/fusefs.c $(TRANSLATE)
1313 $(TRANSLATE) $(SRCDIR)/fusefs.c >$@
1314
1315 $(OBJDIR)/fusefs.o: $(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
@@ -1593,10 +1650,26 @@
1650
1651 $(OBJDIR)/printf.o: $(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
1652 $(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c
1653
1654 $(OBJDIR)/printf.h: $(OBJDIR)/headers
1655
1656 $(OBJDIR)/publish_.c: $(SRCDIR)/publish.c $(TRANSLATE)
1657 $(TRANSLATE) $(SRCDIR)/publish.c >$@
1658
1659 $(OBJDIR)/publish.o: $(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
1660 $(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c
1661
1662 $(OBJDIR)/publish.h: $(OBJDIR)/headers
1663
1664 $(OBJDIR)/purge_.c: $(SRCDIR)/purge.c $(TRANSLATE)
1665 $(TRANSLATE) $(SRCDIR)/purge.c >$@
1666
1667 $(OBJDIR)/purge.o: $(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
1668 $(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c
1669
1670 $(OBJDIR)/purge.h: $(OBJDIR)/headers
1671
1672 $(OBJDIR)/rebuild_.c: $(SRCDIR)/rebuild.c $(TRANSLATE)
1673 $(TRANSLATE) $(SRCDIR)/rebuild.c >$@
1674
1675 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
@@ -1665,10 +1738,18 @@
1738
1739 $(OBJDIR)/shun.o: $(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
1740 $(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c
1741
1742 $(OBJDIR)/shun.h: $(OBJDIR)/headers
1743
1744 $(OBJDIR)/sitemap_.c: $(SRCDIR)/sitemap.c $(TRANSLATE)
1745 $(TRANSLATE) $(SRCDIR)/sitemap.c >$@
1746
1747 $(OBJDIR)/sitemap.o: $(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
1748 $(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c
1749
1750 $(OBJDIR)/sitemap.h: $(OBJDIR)/headers
1751
1752 $(OBJDIR)/skins_.c: $(SRCDIR)/skins.c $(TRANSLATE)
1753 $(TRANSLATE) $(SRCDIR)/skins.c >$@
1754
1755 $(OBJDIR)/skins.o: $(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
1756
+54 -5
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -62,23 +62,32 @@
6262
SSLLIBDIR = $(SSLDIR)\out32
6363
SSLLFLAGS = /nologo /opt:ref /debug
6464
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
6565
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
6666
!message Using 'x64' platform for OpenSSL...
67
-SSLCONFIG = VC-WIN64A no-asm
67
+# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
68
+# SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-shared
69
+SSLCONFIG = VC-WIN64A no-asm no-shared
6870
SSLSETUP = ms\do_win64a.bat
6971
SSLNMAKE = ms\nt.mak all
72
+SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
7073
!elseif "$(PLATFORM)"=="ia64"
7174
!message Using 'ia64' platform for OpenSSL...
72
-SSLCONFIG = VC-WIN64I no-asm
75
+# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
76
+# SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-shared
77
+SSLCONFIG = VC-WIN64I no-asm no-shared
7378
SSLSETUP = ms\do_win64i.bat
7479
SSLNMAKE = ms\nt.mak all
80
+SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
7581
!else
7682
!message Assuming 'x86' platform for OpenSSL...
77
-SSLCONFIG = VC-WIN32 no-asm
83
+# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
84
+# SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-shared
85
+SSLCONFIG = VC-WIN32 no-asm no-shared
7886
SSLSETUP = ms\do_ms.bat
7987
SSLNMAKE = ms\nt.mak all
88
+SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
8089
!endif
8190
!endif
8291
8392
!ifdef FOSSIL_ENABLE_TCL
8493
TCLDIR = $(B)\compat\tcl-8.6
@@ -204,10 +213,11 @@
204213
bisect_.c \
205214
blob_.c \
206215
branch_.c \
207216
browse_.c \
208217
builtin_.c \
218
+ bundle_.c \
209219
cache_.c \
210220
captcha_.c \
211221
cgi_.c \
212222
checkin_.c \
213223
checkout_.c \
@@ -270,19 +280,22 @@
270280
path_.c \
271281
pivot_.c \
272282
popen_.c \
273283
pqueue_.c \
274284
printf_.c \
285
+ publish_.c \
286
+ purge_.c \
275287
rebuild_.c \
276288
regexp_.c \
277289
report_.c \
278290
rss_.c \
279291
schema_.c \
280292
search_.c \
281293
setup_.c \
282294
sha1_.c \
283295
shun_.c \
296
+ sitemap_.c \
284297
skins_.c \
285298
sqlcmd_.c \
286299
stash_.c \
287300
stat_.c \
288301
style_.c \
@@ -320,10 +333,11 @@
320333
$(OX)\bisect$O \
321334
$(OX)\blob$O \
322335
$(OX)\branch$O \
323336
$(OX)\browse$O \
324337
$(OX)\builtin$O \
338
+ $(OX)\bundle$O \
325339
$(OX)\cache$O \
326340
$(OX)\captcha$O \
327341
$(OX)\cgi$O \
328342
$(OX)\checkin$O \
329343
$(OX)\checkout$O \
@@ -387,10 +401,12 @@
387401
$(OX)\path$O \
388402
$(OX)\pivot$O \
389403
$(OX)\popen$O \
390404
$(OX)\pqueue$O \
391405
$(OX)\printf$O \
406
+ $(OX)\publish$O \
407
+ $(OX)\purge$O \
392408
$(OX)\rebuild$O \
393409
$(OX)\regexp$O \
394410
$(OX)\report$O \
395411
$(OX)\rss$O \
396412
$(OX)\schema$O \
@@ -397,10 +413,11 @@
397413
$(OX)\search$O \
398414
$(OX)\setup$O \
399415
$(OX)\sha1$O \
400416
$(OX)\shell$O \
401417
$(OX)\shun$O \
418
+ $(OX)\sitemap$O \
402419
$(OX)\skins$O \
403420
$(OX)\sqlcmd$O \
404421
$(OX)\sqlite3$O \
405422
$(OX)\stash$O \
406423
$(OX)\stat$O \
@@ -459,13 +476,13 @@
459476
@set PATH=$(PERLDIR);$(PATH)
460477
!endif
461478
@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
462479
@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
463480
!ifdef FOSSIL_ENABLE_WINXP
464
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
481
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
465482
!else
466
- @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
483
+ @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
467484
!endif
468485
!endif
469486
470487
!ifndef FOSSIL_ENABLE_MINIZ
471488
APPTARGETS = $(APPTARGETS) zlib
@@ -490,10 +507,11 @@
490507
echo $(OX)\bisect.obj >> $@
491508
echo $(OX)\blob.obj >> $@
492509
echo $(OX)\branch.obj >> $@
493510
echo $(OX)\browse.obj >> $@
494511
echo $(OX)\builtin.obj >> $@
512
+ echo $(OX)\bundle.obj >> $@
495513
echo $(OX)\cache.obj >> $@
496514
echo $(OX)\captcha.obj >> $@
497515
echo $(OX)\cgi.obj >> $@
498516
echo $(OX)\checkin.obj >> $@
499517
echo $(OX)\checkout.obj >> $@
@@ -557,10 +575,12 @@
557575
echo $(OX)\path.obj >> $@
558576
echo $(OX)\pivot.obj >> $@
559577
echo $(OX)\popen.obj >> $@
560578
echo $(OX)\pqueue.obj >> $@
561579
echo $(OX)\printf.obj >> $@
580
+ echo $(OX)\publish.obj >> $@
581
+ echo $(OX)\purge.obj >> $@
562582
echo $(OX)\rebuild.obj >> $@
563583
echo $(OX)\regexp.obj >> $@
564584
echo $(OX)\report.obj >> $@
565585
echo $(OX)\rss.obj >> $@
566586
echo $(OX)\schema.obj >> $@
@@ -567,10 +587,11 @@
567587
echo $(OX)\search.obj >> $@
568588
echo $(OX)\setup.obj >> $@
569589
echo $(OX)\sha1.obj >> $@
570590
echo $(OX)\shell.obj >> $@
571591
echo $(OX)\shun.obj >> $@
592
+ echo $(OX)\sitemap.obj >> $@
572593
echo $(OX)\skins.obj >> $@
573594
echo $(OX)\sqlcmd.obj >> $@
574595
echo $(OX)\sqlite3.obj >> $@
575596
echo $(OX)\stash.obj >> $@
576597
echo $(OX)\stat.obj >> $@
@@ -752,10 +773,16 @@
752773
$(OX)\builtin$O : builtin_.c builtin.h
753774
$(TCC) /Fo$@ -c builtin_.c
754775
755776
builtin_.c : $(SRCDIR)\builtin.c
756777
translate$E $** > $@
778
+
779
+$(OX)\bundle$O : bundle_.c bundle.h
780
+ $(TCC) /Fo$@ -c bundle_.c
781
+
782
+bundle_.c : $(SRCDIR)\bundle.c
783
+ translate$E $** > $@
757784
758785
$(OX)\cache$O : cache_.c cache.h
759786
$(TCC) /Fo$@ -c cache_.c
760787
761788
cache_.c : $(SRCDIR)\cache.c
@@ -1148,10 +1175,22 @@
11481175
$(OX)\printf$O : printf_.c printf.h
11491176
$(TCC) /Fo$@ -c printf_.c
11501177
11511178
printf_.c : $(SRCDIR)\printf.c
11521179
translate$E $** > $@
1180
+
1181
+$(OX)\publish$O : publish_.c publish.h
1182
+ $(TCC) /Fo$@ -c publish_.c
1183
+
1184
+publish_.c : $(SRCDIR)\publish.c
1185
+ translate$E $** > $@
1186
+
1187
+$(OX)\purge$O : purge_.c purge.h
1188
+ $(TCC) /Fo$@ -c purge_.c
1189
+
1190
+purge_.c : $(SRCDIR)\purge.c
1191
+ translate$E $** > $@
11531192
11541193
$(OX)\rebuild$O : rebuild_.c rebuild.h
11551194
$(TCC) /Fo$@ -c rebuild_.c
11561195
11571196
rebuild_.c : $(SRCDIR)\rebuild.c
@@ -1202,10 +1241,16 @@
12021241
$(OX)\shun$O : shun_.c shun.h
12031242
$(TCC) /Fo$@ -c shun_.c
12041243
12051244
shun_.c : $(SRCDIR)\shun.c
12061245
translate$E $** > $@
1246
+
1247
+$(OX)\sitemap$O : sitemap_.c sitemap.h
1248
+ $(TCC) /Fo$@ -c sitemap_.c
1249
+
1250
+sitemap_.c : $(SRCDIR)\sitemap.c
1251
+ translate$E $** > $@
12071252
12081253
$(OX)\skins$O : skins_.c skins.h
12091254
$(TCC) /Fo$@ -c skins_.c
12101255
12111256
skins_.c : $(SRCDIR)\skins.c
@@ -1390,10 +1435,11 @@
13901435
bisect_.c:bisect.h \
13911436
blob_.c:blob.h \
13921437
branch_.c:branch.h \
13931438
browse_.c:browse.h \
13941439
builtin_.c:builtin.h \
1440
+ bundle_.c:bundle.h \
13951441
cache_.c:cache.h \
13961442
captcha_.c:captcha.h \
13971443
cgi_.c:cgi.h \
13981444
checkin_.c:checkin.h \
13991445
checkout_.c:checkout.h \
@@ -1456,19 +1502,22 @@
14561502
path_.c:path.h \
14571503
pivot_.c:pivot.h \
14581504
popen_.c:popen.h \
14591505
pqueue_.c:pqueue.h \
14601506
printf_.c:printf.h \
1507
+ publish_.c:publish.h \
1508
+ purge_.c:purge.h \
14611509
rebuild_.c:rebuild.h \
14621510
regexp_.c:regexp.h \
14631511
report_.c:report.h \
14641512
rss_.c:rss.h \
14651513
schema_.c:schema.h \
14661514
search_.c:search.h \
14671515
setup_.c:setup.h \
14681516
sha1_.c:sha1.h \
14691517
shun_.c:shun.h \
1518
+ sitemap_.c:sitemap.h \
14701519
skins_.c:skins.h \
14711520
sqlcmd_.c:sqlcmd.h \
14721521
stash_.c:stash.h \
14731522
stat_.c:stat.h \
14741523
style_.c:style.h \
14751524
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -62,23 +62,32 @@
62 SSLLIBDIR = $(SSLDIR)\out32
63 SSLLFLAGS = /nologo /opt:ref /debug
64 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
65 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
66 !message Using 'x64' platform for OpenSSL...
67 SSLCONFIG = VC-WIN64A no-asm
 
 
68 SSLSETUP = ms\do_win64a.bat
69 SSLNMAKE = ms\nt.mak all
 
70 !elseif "$(PLATFORM)"=="ia64"
71 !message Using 'ia64' platform for OpenSSL...
72 SSLCONFIG = VC-WIN64I no-asm
 
 
73 SSLSETUP = ms\do_win64i.bat
74 SSLNMAKE = ms\nt.mak all
 
75 !else
76 !message Assuming 'x86' platform for OpenSSL...
77 SSLCONFIG = VC-WIN32 no-asm
 
 
78 SSLSETUP = ms\do_ms.bat
79 SSLNMAKE = ms\nt.mak all
 
80 !endif
81 !endif
82
83 !ifdef FOSSIL_ENABLE_TCL
84 TCLDIR = $(B)\compat\tcl-8.6
@@ -204,10 +213,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,19 +280,22 @@
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 \
280 search_.c \
281 setup_.c \
282 sha1_.c \
283 shun_.c \
 
284 skins_.c \
285 sqlcmd_.c \
286 stash_.c \
287 stat_.c \
288 style_.c \
@@ -320,10 +333,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 +401,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 \
@@ -397,10 +413,11 @@
397 $(OX)\search$O \
398 $(OX)\setup$O \
399 $(OX)\sha1$O \
400 $(OX)\shell$O \
401 $(OX)\shun$O \
 
402 $(OX)\skins$O \
403 $(OX)\sqlcmd$O \
404 $(OX)\sqlite3$O \
405 $(OX)\stash$O \
406 $(OX)\stat$O \
@@ -459,13 +476,13 @@
459 @set PATH=$(PERLDIR);$(PATH)
460 !endif
461 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
462 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
463 !ifdef FOSSIL_ENABLE_WINXP
464 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
465 !else
466 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
467 !endif
468 !endif
469
470 !ifndef FOSSIL_ENABLE_MINIZ
471 APPTARGETS = $(APPTARGETS) zlib
@@ -490,10 +507,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 +575,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 >> $@
@@ -567,10 +587,11 @@
567 echo $(OX)\search.obj >> $@
568 echo $(OX)\setup.obj >> $@
569 echo $(OX)\sha1.obj >> $@
570 echo $(OX)\shell.obj >> $@
571 echo $(OX)\shun.obj >> $@
 
572 echo $(OX)\skins.obj >> $@
573 echo $(OX)\sqlcmd.obj >> $@
574 echo $(OX)\sqlite3.obj >> $@
575 echo $(OX)\stash.obj >> $@
576 echo $(OX)\stat.obj >> $@
@@ -752,10 +773,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 +1175,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
@@ -1202,10 +1241,16 @@
1202 $(OX)\shun$O : shun_.c shun.h
1203 $(TCC) /Fo$@ -c shun_.c
1204
1205 shun_.c : $(SRCDIR)\shun.c
1206 translate$E $** > $@
 
 
 
 
 
 
1207
1208 $(OX)\skins$O : skins_.c skins.h
1209 $(TCC) /Fo$@ -c skins_.c
1210
1211 skins_.c : $(SRCDIR)\skins.c
@@ -1390,10 +1435,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,19 +1502,22 @@
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 search_.c:search.h \
1467 setup_.c:setup.h \
1468 sha1_.c:sha1.h \
1469 shun_.c:shun.h \
 
1470 skins_.c:skins.h \
1471 sqlcmd_.c:sqlcmd.h \
1472 stash_.c:stash.h \
1473 stat_.c:stat.h \
1474 style_.c:style.h \
1475
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -62,23 +62,32 @@
62 SSLLIBDIR = $(SSLDIR)\out32
63 SSLLFLAGS = /nologo /opt:ref /debug
64 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
65 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
66 !message Using 'x64' platform for OpenSSL...
67 # BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
68 # SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-shared
69 SSLCONFIG = VC-WIN64A no-asm no-shared
70 SSLSETUP = ms\do_win64a.bat
71 SSLNMAKE = ms\nt.mak all
72 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
73 !elseif "$(PLATFORM)"=="ia64"
74 !message Using 'ia64' platform for OpenSSL...
75 # BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
76 # SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-shared
77 SSLCONFIG = VC-WIN64I no-asm no-shared
78 SSLSETUP = ms\do_win64i.bat
79 SSLNMAKE = ms\nt.mak all
80 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
81 !else
82 !message Assuming 'x86' platform for OpenSSL...
83 # BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
84 # SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-shared
85 SSLCONFIG = VC-WIN32 no-asm no-shared
86 SSLSETUP = ms\do_ms.bat
87 SSLNMAKE = ms\nt.mak all
88 SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
89 !endif
90 !endif
91
92 !ifdef FOSSIL_ENABLE_TCL
93 TCLDIR = $(B)\compat\tcl-8.6
@@ -204,10 +213,11 @@
213 bisect_.c \
214 blob_.c \
215 branch_.c \
216 browse_.c \
217 builtin_.c \
218 bundle_.c \
219 cache_.c \
220 captcha_.c \
221 cgi_.c \
222 checkin_.c \
223 checkout_.c \
@@ -270,19 +280,22 @@
280 path_.c \
281 pivot_.c \
282 popen_.c \
283 pqueue_.c \
284 printf_.c \
285 publish_.c \
286 purge_.c \
287 rebuild_.c \
288 regexp_.c \
289 report_.c \
290 rss_.c \
291 schema_.c \
292 search_.c \
293 setup_.c \
294 sha1_.c \
295 shun_.c \
296 sitemap_.c \
297 skins_.c \
298 sqlcmd_.c \
299 stash_.c \
300 stat_.c \
301 style_.c \
@@ -320,10 +333,11 @@
333 $(OX)\bisect$O \
334 $(OX)\blob$O \
335 $(OX)\branch$O \
336 $(OX)\browse$O \
337 $(OX)\builtin$O \
338 $(OX)\bundle$O \
339 $(OX)\cache$O \
340 $(OX)\captcha$O \
341 $(OX)\cgi$O \
342 $(OX)\checkin$O \
343 $(OX)\checkout$O \
@@ -387,10 +401,12 @@
401 $(OX)\path$O \
402 $(OX)\pivot$O \
403 $(OX)\popen$O \
404 $(OX)\pqueue$O \
405 $(OX)\printf$O \
406 $(OX)\publish$O \
407 $(OX)\purge$O \
408 $(OX)\rebuild$O \
409 $(OX)\regexp$O \
410 $(OX)\report$O \
411 $(OX)\rss$O \
412 $(OX)\schema$O \
@@ -397,10 +413,11 @@
413 $(OX)\search$O \
414 $(OX)\setup$O \
415 $(OX)\sha1$O \
416 $(OX)\shell$O \
417 $(OX)\shun$O \
418 $(OX)\sitemap$O \
419 $(OX)\skins$O \
420 $(OX)\sqlcmd$O \
421 $(OX)\sqlite3$O \
422 $(OX)\stash$O \
423 $(OX)\stat$O \
@@ -459,13 +476,13 @@
476 @set PATH=$(PERLDIR);$(PATH)
477 !endif
478 @pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
479 @pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
480 !ifdef FOSSIL_ENABLE_WINXP
481 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
482 !else
483 @pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
484 !endif
485 !endif
486
487 !ifndef FOSSIL_ENABLE_MINIZ
488 APPTARGETS = $(APPTARGETS) zlib
@@ -490,10 +507,11 @@
507 echo $(OX)\bisect.obj >> $@
508 echo $(OX)\blob.obj >> $@
509 echo $(OX)\branch.obj >> $@
510 echo $(OX)\browse.obj >> $@
511 echo $(OX)\builtin.obj >> $@
512 echo $(OX)\bundle.obj >> $@
513 echo $(OX)\cache.obj >> $@
514 echo $(OX)\captcha.obj >> $@
515 echo $(OX)\cgi.obj >> $@
516 echo $(OX)\checkin.obj >> $@
517 echo $(OX)\checkout.obj >> $@
@@ -557,10 +575,12 @@
575 echo $(OX)\path.obj >> $@
576 echo $(OX)\pivot.obj >> $@
577 echo $(OX)\popen.obj >> $@
578 echo $(OX)\pqueue.obj >> $@
579 echo $(OX)\printf.obj >> $@
580 echo $(OX)\publish.obj >> $@
581 echo $(OX)\purge.obj >> $@
582 echo $(OX)\rebuild.obj >> $@
583 echo $(OX)\regexp.obj >> $@
584 echo $(OX)\report.obj >> $@
585 echo $(OX)\rss.obj >> $@
586 echo $(OX)\schema.obj >> $@
@@ -567,10 +587,11 @@
587 echo $(OX)\search.obj >> $@
588 echo $(OX)\setup.obj >> $@
589 echo $(OX)\sha1.obj >> $@
590 echo $(OX)\shell.obj >> $@
591 echo $(OX)\shun.obj >> $@
592 echo $(OX)\sitemap.obj >> $@
593 echo $(OX)\skins.obj >> $@
594 echo $(OX)\sqlcmd.obj >> $@
595 echo $(OX)\sqlite3.obj >> $@
596 echo $(OX)\stash.obj >> $@
597 echo $(OX)\stat.obj >> $@
@@ -752,10 +773,16 @@
773 $(OX)\builtin$O : builtin_.c builtin.h
774 $(TCC) /Fo$@ -c builtin_.c
775
776 builtin_.c : $(SRCDIR)\builtin.c
777 translate$E $** > $@
778
779 $(OX)\bundle$O : bundle_.c bundle.h
780 $(TCC) /Fo$@ -c bundle_.c
781
782 bundle_.c : $(SRCDIR)\bundle.c
783 translate$E $** > $@
784
785 $(OX)\cache$O : cache_.c cache.h
786 $(TCC) /Fo$@ -c cache_.c
787
788 cache_.c : $(SRCDIR)\cache.c
@@ -1148,10 +1175,22 @@
1175 $(OX)\printf$O : printf_.c printf.h
1176 $(TCC) /Fo$@ -c printf_.c
1177
1178 printf_.c : $(SRCDIR)\printf.c
1179 translate$E $** > $@
1180
1181 $(OX)\publish$O : publish_.c publish.h
1182 $(TCC) /Fo$@ -c publish_.c
1183
1184 publish_.c : $(SRCDIR)\publish.c
1185 translate$E $** > $@
1186
1187 $(OX)\purge$O : purge_.c purge.h
1188 $(TCC) /Fo$@ -c purge_.c
1189
1190 purge_.c : $(SRCDIR)\purge.c
1191 translate$E $** > $@
1192
1193 $(OX)\rebuild$O : rebuild_.c rebuild.h
1194 $(TCC) /Fo$@ -c rebuild_.c
1195
1196 rebuild_.c : $(SRCDIR)\rebuild.c
@@ -1202,10 +1241,16 @@
1241 $(OX)\shun$O : shun_.c shun.h
1242 $(TCC) /Fo$@ -c shun_.c
1243
1244 shun_.c : $(SRCDIR)\shun.c
1245 translate$E $** > $@
1246
1247 $(OX)\sitemap$O : sitemap_.c sitemap.h
1248 $(TCC) /Fo$@ -c sitemap_.c
1249
1250 sitemap_.c : $(SRCDIR)\sitemap.c
1251 translate$E $** > $@
1252
1253 $(OX)\skins$O : skins_.c skins.h
1254 $(TCC) /Fo$@ -c skins_.c
1255
1256 skins_.c : $(SRCDIR)\skins.c
@@ -1390,10 +1435,11 @@
1435 bisect_.c:bisect.h \
1436 blob_.c:blob.h \
1437 branch_.c:branch.h \
1438 browse_.c:browse.h \
1439 builtin_.c:builtin.h \
1440 bundle_.c:bundle.h \
1441 cache_.c:cache.h \
1442 captcha_.c:captcha.h \
1443 cgi_.c:cgi.h \
1444 checkin_.c:checkin.h \
1445 checkout_.c:checkout.h \
@@ -1456,19 +1502,22 @@
1502 path_.c:path.h \
1503 pivot_.c:pivot.h \
1504 popen_.c:popen.h \
1505 pqueue_.c:pqueue.h \
1506 printf_.c:printf.h \
1507 publish_.c:publish.h \
1508 purge_.c:purge.h \
1509 rebuild_.c:rebuild.h \
1510 regexp_.c:regexp.h \
1511 report_.c:report.h \
1512 rss_.c:rss.h \
1513 schema_.c:schema.h \
1514 search_.c:search.h \
1515 setup_.c:setup.h \
1516 sha1_.c:sha1.h \
1517 shun_.c:shun.h \
1518 sitemap_.c:sitemap.h \
1519 skins_.c:skins.h \
1520 sqlcmd_.c:sqlcmd.h \
1521 stash_.c:stash.h \
1522 stat_.c:stat.h \
1523 style_.c:style.h \
1524
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -115,10 +115,31 @@
115115
116116
The "tag:deed2" name will refer to the most recent check-in
117117
tagged with "deed2" not to the
118118
check-in whose canonical name begins with "deed2".
119119
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
+
120141
<h2>Timestamps</h2>
121142
122143
A timestamp in one of the formats shown below means the most recent
123144
check-in that occurs no later than the timestamp given:
124145
125146
--- 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
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -405,11 +405,11 @@
405405
can do pushes or pulls against your server. Use the <b>--port</b>
406406
option to the server command to specify a different TCP port. If
407407
you do not have a local source tree, use the <b>-R</b> command-line
408408
option to specify the repository file.
409409
410
-A stand-alone server is a great way to set of transient connections
410
+The "fossil server" command is a great way to set of transient connections
411411
between coworkers for doing quick pushes or pulls. But you can also
412412
set up a permanent stand-alone server if you prefer. Just make
413413
arrangements for fossil to be launched with appropriate arguments
414414
after every reboot.
415415
416416
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -405,11 +405,11 @@
405 can do pushes or pulls against your server. Use the <b>--port</b>
406 option to the server command to specify a different TCP port. If
407 you do not have a local source tree, use the <b>-R</b> command-line
408 option to specify the repository file.
409
410 A stand-alone server is a great way to set of transient connections
411 between coworkers for doing quick pushes or pulls. But you can also
412 set up a permanent stand-alone server if you prefer. Just make
413 arrangements for fossil to be launched with appropriate arguments
414 after every reboot.
415
416
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -405,11 +405,11 @@
405 can do pushes or pulls against your server. Use the <b>--port</b>
406 option to the server command to specify a different TCP port. If
407 you do not have a local source tree, use the <b>-R</b> command-line
408 option to specify the repository file.
409
410 The "fossil server" command is a great way to set of transient connections
411 between coworkers for doing quick pushes or pulls. But you can also
412 set up a permanent stand-alone server if you prefer. Just make
413 arrangements for fossil to be launched with appropriate arguments
414 after every reboot.
415
416
+8 -8
--- www/faq.tcl
+++ www/faq.tcl
@@ -55,12 +55,12 @@
5555
If you already have a fork in your check-in tree and you want to convert
5656
that fork to a branch, you can do this from the web interface.
5757
First locate the check-in that you want to be
5858
the initial check-in of your branch on the timeline and click on its
5959
link so that you are on the <b>ci</b> page. Then find the "<b>edit</b>"
60
- link (near the "Commands:" label) and click on that. On the
61
- "Edit Check-in" page, check the box beside "Branching:" and fill in
60
+ link (near the "Commands:" label) and click on that. On the
61
+ "Edit Check-in" page, check the box beside "Branching:" and fill in
6262
the name of your new branch to the right and press the "Apply Changes"
6363
button.
6464
}
6565
6666
faq {
@@ -83,31 +83,31 @@
8383
8484
The CHECK-IN in the previous line can be any
8585
[./checkin_names.wiki | valid check-in name format].
8686
8787
You can also add (and remove) tags from a check-in using the
88
- [./webui.wiki | web interface]. First locate the check-in that you
88
+ [./webui.wiki | web interface]. First locate the check-in that you
8989
what to tag on the tmline, then click on the link to go the detailed
9090
information page for that check-in. Then find the "<b>edit</b>"
9191
link (near the "Commands:" label) and click on that. There are
9292
controls on the edit page that allow new tags to be added and existing
9393
tags to be removed.
94
-}
94
+}
9595
9696
faq {
9797
How do I create a private branch that won't get pushed back to the
9898
main repository.
9999
} {
100
- Use the <b>--private</b> command-line option on the
100
+ Use the <b>--private</b> command-line option on the
101101
<b>commit</b> command. The result will be a check-in which exists on
102
- your local repository only and is never pushed to other repositories.
102
+ your local repository only and is never pushed to other repositories.
103103
All descendents of a private check-in are also private.
104
-
104
+
105105
Unless you specify something different using the <b>--branch</b> and/or
106106
<b>--bgcolor</b> options, the new private check-in will be put on a branch
107107
named "private" with an orange background color.
108
-
108
+
109109
You can merge from the trunk into your private branch in order to keep
110110
your private branch in sync with the latest changes on the trunk. Once
111111
you have everything in your private branch the way you want it, you can
112112
then merge your private branch back into the trunk and push. Only the
113113
final merge operation will appear in other repositories. It will seem
114114
--- www/faq.tcl
+++ www/faq.tcl
@@ -55,12 +55,12 @@
55 If you already have a fork in your check-in tree and you want to convert
56 that fork to a branch, you can do this from the web interface.
57 First locate the check-in that you want to be
58 the initial check-in of your branch on the timeline and click on its
59 link so that you are on the <b>ci</b> page. Then find the "<b>edit</b>"
60 link (near the "Commands:" label) and click on that. On the
61 "Edit Check-in" page, check the box beside "Branching:" and fill in
62 the name of your new branch to the right and press the "Apply Changes"
63 button.
64 }
65
66 faq {
@@ -83,31 +83,31 @@
83
84 The CHECK-IN in the previous line can be any
85 [./checkin_names.wiki | valid check-in name format].
86
87 You can also add (and remove) tags from a check-in using the
88 [./webui.wiki | web interface]. First locate the check-in that you
89 what to tag on the tmline, then click on the link to go the detailed
90 information page for that check-in. Then find the "<b>edit</b>"
91 link (near the "Commands:" label) and click on that. There are
92 controls on the edit page that allow new tags to be added and existing
93 tags to be removed.
94 }
95
96 faq {
97 How do I create a private branch that won't get pushed back to the
98 main repository.
99 } {
100 Use the <b>--private</b> command-line option on the
101 <b>commit</b> command. The result will be a check-in which exists on
102 your local repository only and is never pushed to other repositories.
103 All descendents of a private check-in are also private.
104
105 Unless you specify something different using the <b>--branch</b> and/or
106 <b>--bgcolor</b> options, the new private check-in will be put on a branch
107 named "private" with an orange background color.
108
109 You can merge from the trunk into your private branch in order to keep
110 your private branch in sync with the latest changes on the trunk. Once
111 you have everything in your private branch the way you want it, you can
112 then merge your private branch back into the trunk and push. Only the
113 final merge operation will appear in other repositories. It will seem
114
--- www/faq.tcl
+++ www/faq.tcl
@@ -55,12 +55,12 @@
55 If you already have a fork in your check-in tree and you want to convert
56 that fork to a branch, you can do this from the web interface.
57 First locate the check-in that you want to be
58 the initial check-in of your branch on the timeline and click on its
59 link so that you are on the <b>ci</b> page. Then find the "<b>edit</b>"
60 link (near the "Commands:" label) and click on that. On the
61 "Edit Check-in" page, check the box beside "Branching:" and fill in
62 the name of your new branch to the right and press the "Apply Changes"
63 button.
64 }
65
66 faq {
@@ -83,31 +83,31 @@
83
84 The CHECK-IN in the previous line can be any
85 [./checkin_names.wiki | valid check-in name format].
86
87 You can also add (and remove) tags from a check-in using the
88 [./webui.wiki | web interface]. First locate the check-in that you
89 what to tag on the tmline, then click on the link to go the detailed
90 information page for that check-in. Then find the "<b>edit</b>"
91 link (near the "Commands:" label) and click on that. There are
92 controls on the edit page that allow new tags to be added and existing
93 tags to be removed.
94 }
95
96 faq {
97 How do I create a private branch that won't get pushed back to the
98 main repository.
99 } {
100 Use the <b>--private</b> command-line option on the
101 <b>commit</b> command. The result will be a check-in which exists on
102 your local repository only and is never pushed to other repositories.
103 All descendents of a private check-in are also private.
104
105 Unless you specify something different using the <b>--branch</b> and/or
106 <b>--bgcolor</b> options, the new private check-in will be put on a branch
107 named "private" with an orange background color.
108
109 You can merge from the trunk into your private branch in order to keep
110 your private branch in sync with the latest changes on the trunk. Once
111 you have everything in your private branch the way you want it, you can
112 then merge your private branch back into the trunk and push. Only the
113 final merge operation will appear in other repositories. It will seem
114
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -49,11 +49,11 @@
4949
</ul>
5050
5151
These seven artifact types are described in the following sections.
5252
5353
In the current implementation (as of 2009-01-25) the artifacts that
54
-make up a fossil repository are stored in in as delta- and zlib-compressed
54
+make up a fossil repository are stored as delta- and zlib-compressed
5555
blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
5656
is an implementation detail and might change in a future release. For
5757
the purpose of this article "file format" means the format of the artifacts,
5858
not how the artifacts are stored on disk. It is the artifact format that
5959
is intended to be enduring. The specifics of how artifacts are stored on
@@ -184,11 +184,11 @@
184184
ancestor, the Q-card is used to identify a single check-in or a small
185185
range of check-ins which were cherry-picked for inclusion in or
186186
exclusion from the current manifest. The first argument of
187187
the Q-card is the artifact ID of another manifest (the "target")
188188
which has had its changes included or excluded in the current manifest.
189
-The target is preceeded by "+" or "-" to show inclusion or
189
+The target is preceded by "+" or "-" to show inclusion or
190190
exclusion, respectively. The optional second argument to the
191191
Q-card is another manifest artifact ID which is the "baseline"
192192
for the cherry-pick. If omitted, the baseline is the primary
193193
parent of the target. The
194194
changes included or excluded consist of all changes moving from
@@ -315,11 +315,11 @@
315315
is either "+", "-", or "*". The "+" means the tag should be added
316316
to the artifact. The "-" means the tag should be removed.
317317
The "*" character means the tag should be added to the artifact
318318
and all direct descendants (but not descendents through a merge) down
319319
to but not including the first descendant that contains a
320
-more recent "-" or "+" tag with the same name.
320
+more recent "-", "*", or "+" tag with the same name.
321321
The optional third argument is the value of the tag. A tag
322322
without a value is a boolean.
323323
324324
When two or more tags with the same name are applied to the
325325
same artifact, the tag with the latest (most recent) date is
@@ -362,11 +362,11 @@
362362
gives the name of the wiki page. The optional N card specifies
363363
the mimetype of the wiki text. If the N card is omitted, the
364364
mimetype is assumed to be text/x-fossil-wiki.
365365
The U card specifies the login
366366
of the user who made this edit to the wiki page. The Z card is
367
-the usual checksum over the either artifact and is required.
367
+the usual checksum over the entire artifact and is required.
368368
369369
The W card is used to specify the text of the wiki page. The
370370
argument to the W card is an integer which is the number of bytes
371371
of text in the wiki page. That text follows the newline character
372372
that terminates the W card. The wiki text is always followed by one
@@ -453,11 +453,11 @@
453453
454454
There may be zero or one N cards. The N card specifies the mimetype of the
455455
comment text provided in the C card. If the N card is omitted, the C card
456456
mimetype is taken to be text/plain.
457457
458
-A single U card gives the name of the user to added the attachment.
458
+A single U card gives the name of the user who added the attachment.
459459
If an attachment is added anonymously, then the U card may be omitted.
460460
461461
The Z card is the usual checksum over the rest of the attachment artifact.
462462
The Z card is required.
463463
464464
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -49,11 +49,11 @@
49 </ul>
50
51 These seven artifact types are described in the following sections.
52
53 In the current implementation (as of 2009-01-25) the artifacts that
54 make up a fossil repository are stored in in as delta- and zlib-compressed
55 blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
56 is an implementation detail and might change in a future release. For
57 the purpose of this article "file format" means the format of the artifacts,
58 not how the artifacts are stored on disk. It is the artifact format that
59 is intended to be enduring. The specifics of how artifacts are stored on
@@ -184,11 +184,11 @@
184 ancestor, the Q-card is used to identify a single check-in or a small
185 range of check-ins which were cherry-picked for inclusion in or
186 exclusion from the current manifest. The first argument of
187 the Q-card is the artifact ID of another manifest (the "target")
188 which has had its changes included or excluded in the current manifest.
189 The target is preceeded by "+" or "-" to show inclusion or
190 exclusion, respectively. The optional second argument to the
191 Q-card is another manifest artifact ID which is the "baseline"
192 for the cherry-pick. If omitted, the baseline is the primary
193 parent of the target. The
194 changes included or excluded consist of all changes moving from
@@ -315,11 +315,11 @@
315 is either "+", "-", or "*". The "+" means the tag should be added
316 to the artifact. The "-" means the tag should be removed.
317 The "*" character means the tag should be added to the artifact
318 and all direct descendants (but not descendents through a merge) down
319 to but not including the first descendant that contains a
320 more recent "-" or "+" tag with the same name.
321 The optional third argument is the value of the tag. A tag
322 without a value is a boolean.
323
324 When two or more tags with the same name are applied to the
325 same artifact, the tag with the latest (most recent) date is
@@ -362,11 +362,11 @@
362 gives the name of the wiki page. The optional N card specifies
363 the mimetype of the wiki text. If the N card is omitted, the
364 mimetype is assumed to be text/x-fossil-wiki.
365 The U card specifies the login
366 of the user who made this edit to the wiki page. The Z card is
367 the usual checksum over the either artifact and is required.
368
369 The W card is used to specify the text of the wiki page. The
370 argument to the W card is an integer which is the number of bytes
371 of text in the wiki page. That text follows the newline character
372 that terminates the W card. The wiki text is always followed by one
@@ -453,11 +453,11 @@
453
454 There may be zero or one N cards. The N card specifies the mimetype of the
455 comment text provided in the C card. If the N card is omitted, the C card
456 mimetype is taken to be text/plain.
457
458 A single U card gives the name of the user to added the attachment.
459 If an attachment is added anonymously, then the U card may be omitted.
460
461 The Z card is the usual checksum over the rest of the attachment artifact.
462 The Z card is required.
463
464
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -49,11 +49,11 @@
49 </ul>
50
51 These seven artifact types are described in the following sections.
52
53 In the current implementation (as of 2009-01-25) the artifacts that
54 make up a fossil repository are stored as delta- and zlib-compressed
55 blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
56 is an implementation detail and might change in a future release. For
57 the purpose of this article "file format" means the format of the artifacts,
58 not how the artifacts are stored on disk. It is the artifact format that
59 is intended to be enduring. The specifics of how artifacts are stored on
@@ -184,11 +184,11 @@
184 ancestor, the Q-card is used to identify a single check-in or a small
185 range of check-ins which were cherry-picked for inclusion in or
186 exclusion from the current manifest. The first argument of
187 the Q-card is the artifact ID of another manifest (the "target")
188 which has had its changes included or excluded in the current manifest.
189 The target is preceded by "+" or "-" to show inclusion or
190 exclusion, respectively. The optional second argument to the
191 Q-card is another manifest artifact ID which is the "baseline"
192 for the cherry-pick. If omitted, the baseline is the primary
193 parent of the target. The
194 changes included or excluded consist of all changes moving from
@@ -315,11 +315,11 @@
315 is either "+", "-", or "*". The "+" means the tag should be added
316 to the artifact. The "-" means the tag should be removed.
317 The "*" character means the tag should be added to the artifact
318 and all direct descendants (but not descendents through a merge) down
319 to but not including the first descendant that contains a
320 more recent "-", "*", or "+" tag with the same name.
321 The optional third argument is the value of the tag. A tag
322 without a value is a boolean.
323
324 When two or more tags with the same name are applied to the
325 same artifact, the tag with the latest (most recent) date is
@@ -362,11 +362,11 @@
362 gives the name of the wiki page. The optional N card specifies
363 the mimetype of the wiki text. If the N card is omitted, the
364 mimetype is assumed to be text/x-fossil-wiki.
365 The U card specifies the login
366 of the user who made this edit to the wiki page. The Z card is
367 the usual checksum over the entire artifact and is required.
368
369 The W card is used to specify the text of the wiki page. The
370 argument to the W card is an integer which is the number of bytes
371 of text in the wiki page. That text follows the newline character
372 that terminates the W card. The wiki text is always followed by one
@@ -453,11 +453,11 @@
453
454 There may be zero or one N cards. The N card specifies the mimetype of the
455 comment text provided in the C card. If the N card is omitted, the C card
456 mimetype is taken to be text/plain.
457
458 A single U card gives the name of the user who added the attachment.
459 If an attachment is added anonymously, then the U card may be omitted.
460
461 The Z card is the usual checksum over the rest of the attachment artifact.
462 The Z card is required.
463
464
--- www/foss-cklist.wiki
+++ www/foss-cklist.wiki
@@ -5,11 +5,11 @@
55
blog post <a href="http://spot.livejournal.com/308370.html">
66
http://spot.livejournal.com/308370.html</a> (see also
77
<a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and
88
<a href="https://www.theopensourceway.org/wiki/How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL">[2]</a>).
99
Tom's original post assigned point scores to the various elements and
10
-by adding together the individual points, the reader is suppose to be able
10
+by adding together the individual points, the reader is supposed to be able
1111
to judge the likelihood that the project will fail.
1212
The point scores, and the items on the list, clearly reflect Tom's
1313
biases and are not necessarily those of the larger open-source community.
1414
Nevertheless, the policy of the Fossil shall be to strive for a perfect
1515
score.</p>
1616
--- www/foss-cklist.wiki
+++ www/foss-cklist.wiki
@@ -5,11 +5,11 @@
5 blog post <a href="http://spot.livejournal.com/308370.html">
6 http://spot.livejournal.com/308370.html</a> (see also
7 <a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and
8 <a href="https://www.theopensourceway.org/wiki/How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL">[2]</a>).
9 Tom's original post assigned point scores to the various elements and
10 by adding together the individual points, the reader is suppose to be able
11 to judge the likelihood that the project will fail.
12 The point scores, and the items on the list, clearly reflect Tom's
13 biases and are not necessarily those of the larger open-source community.
14 Nevertheless, the policy of the Fossil shall be to strive for a perfect
15 score.</p>
16
--- www/foss-cklist.wiki
+++ www/foss-cklist.wiki
@@ -5,11 +5,11 @@
5 blog post <a href="http://spot.livejournal.com/308370.html">
6 http://spot.livejournal.com/308370.html</a> (see also
7 <a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and
8 <a href="https://www.theopensourceway.org/wiki/How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL">[2]</a>).
9 Tom's original post assigned point scores to the various elements and
10 by adding together the individual points, the reader is supposed to be able
11 to judge the likelihood that the project will fail.
12 The point scores, and the items on the list, clearly reflect Tom's
13 biases and are not necessarily those of the larger open-source community.
14 Nevertheless, the policy of the Fossil shall be to strive for a perfect
15 score.</p>
16
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -185,11 +185,11 @@
185185
between repositories and working checkouts. A power-loss or system crash
186186
in the middle of Git operation can damage or corrupt the Git repository.
187187
188188
A Fossil repository consists of a single disk file. A single Fossil
189189
repository can serve multiple simultaneous working checkouts.
190
-A Fossil repository is an SQLite database, so it highly resistant
190
+A Fossil repository is an SQLite database, so it is highly resistant
191191
to damage from a power-loss or system crash - incomplete transactions
192192
are simply rolled back after the system reboots.
193193
194194
<h3>3.8 Audit Trail</h3>
195195
196196
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -185,11 +185,11 @@
185 between repositories and working checkouts. A power-loss or system crash
186 in the middle of Git operation can damage or corrupt the Git repository.
187
188 A Fossil repository consists of a single disk file. A single Fossil
189 repository can serve multiple simultaneous working checkouts.
190 A Fossil repository is an SQLite database, so it highly resistant
191 to damage from a power-loss or system crash - incomplete transactions
192 are simply rolled back after the system reboots.
193
194 <h3>3.8 Audit Trail</h3>
195
196
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -185,11 +185,11 @@
185 between repositories and working checkouts. A power-loss or system crash
186 in the middle of Git operation can damage or corrupt the Git repository.
187
188 A Fossil repository consists of a single disk file. A single Fossil
189 repository can serve multiple simultaneous working checkouts.
190 A Fossil repository is an SQLite database, so it is highly resistant
191 to damage from a power-loss or system crash - incomplete transactions
192 are simply rolled back after the system reboots.
193
194 <h3>3.8 Audit Trail</h3>
195
196
--- www/index.wiki
+++ www/index.wiki
@@ -110,10 +110,14 @@
110110
a Fossil repository.
111111
112112
<hr>
113113
<h3>Links For Fossil Users:</h3>
114114
115
+ * "Fuel" is cross-platform GUI front-end for Fossil
116
+ written in Qt. [http://fuelscm.org/].
117
+ Fuel is an independent project run by a different group of
118
+ developers.
115119
* [./reviews.wiki | Testimonials] from satisfied fossil users and
116120
[./quotes.wiki | Quotes] about Fossil and other DVCSes.
117121
* [./faq.wiki | FAQ]
118122
* The [./concepts.wiki | concepts] behind fossil
119123
* [./quickstart.wiki | Quick Start] guide to using fossil
120124
--- www/index.wiki
+++ www/index.wiki
@@ -110,10 +110,14 @@
110 a Fossil repository.
111
112 <hr>
113 <h3>Links For Fossil Users:</h3>
114
 
 
 
 
115 * [./reviews.wiki | Testimonials] from satisfied fossil users and
116 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
117 * [./faq.wiki | FAQ]
118 * The [./concepts.wiki | concepts] behind fossil
119 * [./quickstart.wiki | Quick Start] guide to using fossil
120
--- www/index.wiki
+++ www/index.wiki
@@ -110,10 +110,14 @@
110 a Fossil repository.
111
112 <hr>
113 <h3>Links For Fossil Users:</h3>
114
115 * "Fuel" is cross-platform GUI front-end for Fossil
116 written in Qt. [http://fuelscm.org/].
117 Fuel is an independent project run by a different group of
118 developers.
119 * [./reviews.wiki | Testimonials] from satisfied fossil users and
120 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
121 * [./faq.wiki | FAQ]
122 * The [./concepts.wiki | concepts] behind fossil
123 * [./quickstart.wiki | Quick Start] guide to using fossil
124
+1 -1
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -1,8 +1,8 @@
11
#!/bin/sh
22
#
3
-# Run this TCL script to generate a WIKI page that contains a
3
+# Run this TCL script to generate a WIKI page that contains a
44
# permuted index of the various documentation files.
55
#
66
# tclsh mkindex.tcl >permutedindex.wiki
77
#
88
99
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -1,8 +1,8 @@
1 #!/bin/sh
2 #
3 # Run this TCL script to generate a WIKI page that contains a
4 # permuted index of the various documentation files.
5 #
6 # tclsh mkindex.tcl >permutedindex.wiki
7 #
8
9
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -1,8 +1,8 @@
1 #!/bin/sh
2 #
3 # Run this TCL script to generate a WIKI page that contains a
4 # permuted index of the various documentation files.
5 #
6 # tclsh mkindex.tcl >permutedindex.wiki
7 #
8
9
+1 -1
--- www/server.wiki
+++ www/server.wiki
@@ -70,11 +70,11 @@
7070
need to modify the pathnames for your particular setup.
7171
The final argument is either the name of the fossil repository to be served,
7272
or a directory containing multiple repositories.
7373
</p>
7474
<p>
75
-If you system is running xinetd, then the configuration is likely to be
75
+If your system is running xinetd, then the configuration is likely to be
7676
in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
7777
An xinetd configuration file will appear like this:</p>
7878
<blockquote>
7979
<pre>
8080
service http-alt
8181
--- www/server.wiki
+++ www/server.wiki
@@ -70,11 +70,11 @@
70 need to modify the pathnames for your particular setup.
71 The final argument is either the name of the fossil repository to be served,
72 or a directory containing multiple repositories.
73 </p>
74 <p>
75 If you system is running xinetd, then the configuration is likely to be
76 in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
77 An xinetd configuration file will appear like this:</p>
78 <blockquote>
79 <pre>
80 service http-alt
81
--- www/server.wiki
+++ www/server.wiki
@@ -70,11 +70,11 @@
70 need to modify the pathnames for your particular setup.
71 The final argument is either the name of the fossil repository to be served,
72 or a directory containing multiple repositories.
73 </p>
74 <p>
75 If your system is running xinetd, then the configuration is likely to be
76 in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
77 An xinetd configuration file will appear like this:</p>
78 <blockquote>
79 <pre>
80 service http-alt
81

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button