Fossil SCM

Add the "builtin" virtual table to the "fossil sql" command. This vtab provides access to all of the built-in support files.

drh 2020-08-12 18:06 trunk
Commit c6359b4ec1b3cc62162a735c274533f1ed45a7e74d4a8553d6cfb54b3bf11874
2 files changed +217 +9
+217
--- src/builtin.c
+++ src/builtin.c
@@ -342,5 +342,222 @@
342342
}
343343
break;
344344
}
345345
}
346346
}
347
+
348
+/*****************************************************************************
349
+** A virtual table for accessing the information in aBuiltinFiles[].
350
+*/
351
+
352
+/* builtinVtab_vtab is a subclass of sqlite3_vtab which is
353
+** underlying representation of the virtual table
354
+*/
355
+typedef struct builtinVtab_vtab builtinVtab_vtab;
356
+struct builtinVtab_vtab {
357
+ sqlite3_vtab base; /* Base class - must be first */
358
+ /* Add new fields here, as necessary */
359
+};
360
+
361
+/* builtinVtab_cursor is a subclass of sqlite3_vtab_cursor which will
362
+** serve as the underlying representation of a cursor that scans
363
+** over rows of the result
364
+*/
365
+typedef struct builtinVtab_cursor builtinVtab_cursor;
366
+struct builtinVtab_cursor {
367
+ sqlite3_vtab_cursor base; /* Base class - must be first */
368
+ /* Insert new fields here. For this builtinVtab we only keep track
369
+ ** of the rowid */
370
+ sqlite3_int64 iRowid; /* The rowid */
371
+};
372
+
373
+/*
374
+** The builtinVtabConnect() method is invoked to create a new
375
+** builtin virtual table.
376
+**
377
+** Think of this routine as the constructor for builtinVtab_vtab objects.
378
+**
379
+** All this routine needs to do is:
380
+**
381
+** (1) Allocate the builtinVtab_vtab object and initialize all fields.
382
+**
383
+** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
384
+** result set of queries against the virtual table will look like.
385
+*/
386
+static int builtinVtabConnect(
387
+ sqlite3 *db,
388
+ void *pAux,
389
+ int argc, const char *const*argv,
390
+ sqlite3_vtab **ppVtab,
391
+ char **pzErr
392
+){
393
+ builtinVtab_vtab *pNew;
394
+ int rc;
395
+
396
+ rc = sqlite3_declare_vtab(db,
397
+ "CREATE TABLE x(name,size,data)"
398
+ );
399
+ if( rc==SQLITE_OK ){
400
+ pNew = sqlite3_malloc( sizeof(*pNew) );
401
+ *ppVtab = (sqlite3_vtab*)pNew;
402
+ if( pNew==0 ) return SQLITE_NOMEM;
403
+ memset(pNew, 0, sizeof(*pNew));
404
+ }
405
+ return rc;
406
+}
407
+
408
+/*
409
+** This method is the destructor for builtinVtab_vtab objects.
410
+*/
411
+static int builtinVtabDisconnect(sqlite3_vtab *pVtab){
412
+ builtinVtab_vtab *p = (builtinVtab_vtab*)pVtab;
413
+ sqlite3_free(p);
414
+ return SQLITE_OK;
415
+}
416
+
417
+/*
418
+** Constructor for a new builtinVtab_cursor object.
419
+*/
420
+static int builtinVtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
421
+ builtinVtab_cursor *pCur;
422
+ pCur = sqlite3_malloc( sizeof(*pCur) );
423
+ if( pCur==0 ) return SQLITE_NOMEM;
424
+ memset(pCur, 0, sizeof(*pCur));
425
+ *ppCursor = &pCur->base;
426
+ return SQLITE_OK;
427
+}
428
+
429
+/*
430
+** Destructor for a builtinVtab_cursor.
431
+*/
432
+static int builtinVtabClose(sqlite3_vtab_cursor *cur){
433
+ builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
434
+ sqlite3_free(pCur);
435
+ return SQLITE_OK;
436
+}
437
+
438
+
439
+/*
440
+** Advance a builtinVtab_cursor to its next row of output.
441
+*/
442
+static int builtinVtabNext(sqlite3_vtab_cursor *cur){
443
+ builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
444
+ pCur->iRowid++;
445
+ return SQLITE_OK;
446
+}
447
+
448
+/*
449
+** Return values of columns for the row at which the builtinVtab_cursor
450
+** is currently pointing.
451
+*/
452
+static int builtinVtabColumn(
453
+ sqlite3_vtab_cursor *cur, /* The cursor */
454
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
455
+ int i /* Which column to return */
456
+){
457
+ builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
458
+ const struct BuiltinFileTable *pFile = aBuiltinFiles + pCur->iRowid;
459
+ switch( i ){
460
+ case 0: /* name */
461
+ sqlite3_result_text(ctx, pFile->zName, -1, SQLITE_STATIC);
462
+ break;
463
+ case 1: /* size */
464
+ sqlite3_result_int(ctx, pFile->nByte);
465
+ break;
466
+ case 2: /* data */
467
+ sqlite3_result_blob(ctx, pFile->pData, pFile->nByte, SQLITE_STATIC);
468
+ break;
469
+ }
470
+ return SQLITE_OK;
471
+}
472
+
473
+/*
474
+** Return the rowid for the current row. In this implementation, the
475
+** rowid is the same as the output value.
476
+*/
477
+static int builtinVtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
478
+ builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
479
+ *pRowid = pCur->iRowid;
480
+ return SQLITE_OK;
481
+}
482
+
483
+/*
484
+** Return TRUE if the cursor has been moved off of the last
485
+** row of output.
486
+*/
487
+static int builtinVtabEof(sqlite3_vtab_cursor *cur){
488
+ builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
489
+ return pCur->iRowid>=count(aBuiltinFiles);
490
+}
491
+
492
+/*
493
+** This method is called to "rewind" the builtinVtab_cursor object back
494
+** to the first row of output. This method is always called at least
495
+** once prior to any call to builtinVtabColumn() or builtinVtabRowid() or
496
+** builtinVtabEof().
497
+*/
498
+static int builtinVtabFilter(
499
+ sqlite3_vtab_cursor *pVtabCursor,
500
+ int idxNum, const char *idxStr,
501
+ int argc, sqlite3_value **argv
502
+){
503
+ builtinVtab_cursor *pCur = (builtinVtab_cursor *)pVtabCursor;
504
+ pCur->iRowid = 1;
505
+ return SQLITE_OK;
506
+}
507
+
508
+/*
509
+** SQLite will invoke this method one or more times while planning a query
510
+** that uses the virtual table. This routine needs to create
511
+** a query plan for each invocation and compute an estimated cost for that
512
+** plan.
513
+*/
514
+static int builtinVtabBestIndex(
515
+ sqlite3_vtab *tab,
516
+ sqlite3_index_info *pIdxInfo
517
+){
518
+ pIdxInfo->estimatedCost = (double)count(aBuiltinFiles);
519
+ pIdxInfo->estimatedRows = count(aBuiltinFiles);
520
+ return SQLITE_OK;
521
+}
522
+
523
+/*
524
+** This following structure defines all the methods for the
525
+** virtual table.
526
+*/
527
+static sqlite3_module builtinVtabModule = {
528
+ /* iVersion */ 0,
529
+ /* xCreate */ 0, /* The builtin vtab is eponymous and read-only */
530
+ /* xConnect */ builtinVtabConnect,
531
+ /* xBestIndex */ builtinVtabBestIndex,
532
+ /* xDisconnect */ builtinVtabDisconnect,
533
+ /* xDestroy */ 0,
534
+ /* xOpen */ builtinVtabOpen,
535
+ /* xClose */ builtinVtabClose,
536
+ /* xFilter */ builtinVtabFilter,
537
+ /* xNext */ builtinVtabNext,
538
+ /* xEof */ builtinVtabEof,
539
+ /* xColumn */ builtinVtabColumn,
540
+ /* xRowid */ builtinVtabRowid,
541
+ /* xUpdate */ 0,
542
+ /* xBegin */ 0,
543
+ /* xSync */ 0,
544
+ /* xCommit */ 0,
545
+ /* xRollback */ 0,
546
+ /* xFindMethod */ 0,
547
+ /* xRename */ 0,
548
+ /* xSavepoint */ 0,
549
+ /* xRelease */ 0,
550
+ /* xRollbackTo */ 0,
551
+ /* xShadowName */ 0
552
+};
553
+
554
+
555
+/*
556
+** Register the builtin virtual table
557
+*/
558
+int builtin_vtab_register(sqlite3 *db){
559
+ int rc = sqlite3_create_module(db, "builtin", &builtinVtabModule, 0);
560
+ return rc;
561
+}
562
+/* End of the builtin virtual table
563
+******************************************************************************/
347564
--- src/builtin.c
+++ src/builtin.c
@@ -342,5 +342,222 @@
342 }
343 break;
344 }
345 }
346 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
--- src/builtin.c
+++ src/builtin.c
@@ -342,5 +342,222 @@
342 }
343 break;
344 }
345 }
346 }
347
348 /*****************************************************************************
349 ** A virtual table for accessing the information in aBuiltinFiles[].
350 */
351
352 /* builtinVtab_vtab is a subclass of sqlite3_vtab which is
353 ** underlying representation of the virtual table
354 */
355 typedef struct builtinVtab_vtab builtinVtab_vtab;
356 struct builtinVtab_vtab {
357 sqlite3_vtab base; /* Base class - must be first */
358 /* Add new fields here, as necessary */
359 };
360
361 /* builtinVtab_cursor is a subclass of sqlite3_vtab_cursor which will
362 ** serve as the underlying representation of a cursor that scans
363 ** over rows of the result
364 */
365 typedef struct builtinVtab_cursor builtinVtab_cursor;
366 struct builtinVtab_cursor {
367 sqlite3_vtab_cursor base; /* Base class - must be first */
368 /* Insert new fields here. For this builtinVtab we only keep track
369 ** of the rowid */
370 sqlite3_int64 iRowid; /* The rowid */
371 };
372
373 /*
374 ** The builtinVtabConnect() method is invoked to create a new
375 ** builtin virtual table.
376 **
377 ** Think of this routine as the constructor for builtinVtab_vtab objects.
378 **
379 ** All this routine needs to do is:
380 **
381 ** (1) Allocate the builtinVtab_vtab object and initialize all fields.
382 **
383 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
384 ** result set of queries against the virtual table will look like.
385 */
386 static int builtinVtabConnect(
387 sqlite3 *db,
388 void *pAux,
389 int argc, const char *const*argv,
390 sqlite3_vtab **ppVtab,
391 char **pzErr
392 ){
393 builtinVtab_vtab *pNew;
394 int rc;
395
396 rc = sqlite3_declare_vtab(db,
397 "CREATE TABLE x(name,size,data)"
398 );
399 if( rc==SQLITE_OK ){
400 pNew = sqlite3_malloc( sizeof(*pNew) );
401 *ppVtab = (sqlite3_vtab*)pNew;
402 if( pNew==0 ) return SQLITE_NOMEM;
403 memset(pNew, 0, sizeof(*pNew));
404 }
405 return rc;
406 }
407
408 /*
409 ** This method is the destructor for builtinVtab_vtab objects.
410 */
411 static int builtinVtabDisconnect(sqlite3_vtab *pVtab){
412 builtinVtab_vtab *p = (builtinVtab_vtab*)pVtab;
413 sqlite3_free(p);
414 return SQLITE_OK;
415 }
416
417 /*
418 ** Constructor for a new builtinVtab_cursor object.
419 */
420 static int builtinVtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
421 builtinVtab_cursor *pCur;
422 pCur = sqlite3_malloc( sizeof(*pCur) );
423 if( pCur==0 ) return SQLITE_NOMEM;
424 memset(pCur, 0, sizeof(*pCur));
425 *ppCursor = &pCur->base;
426 return SQLITE_OK;
427 }
428
429 /*
430 ** Destructor for a builtinVtab_cursor.
431 */
432 static int builtinVtabClose(sqlite3_vtab_cursor *cur){
433 builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
434 sqlite3_free(pCur);
435 return SQLITE_OK;
436 }
437
438
439 /*
440 ** Advance a builtinVtab_cursor to its next row of output.
441 */
442 static int builtinVtabNext(sqlite3_vtab_cursor *cur){
443 builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
444 pCur->iRowid++;
445 return SQLITE_OK;
446 }
447
448 /*
449 ** Return values of columns for the row at which the builtinVtab_cursor
450 ** is currently pointing.
451 */
452 static int builtinVtabColumn(
453 sqlite3_vtab_cursor *cur, /* The cursor */
454 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
455 int i /* Which column to return */
456 ){
457 builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
458 const struct BuiltinFileTable *pFile = aBuiltinFiles + pCur->iRowid;
459 switch( i ){
460 case 0: /* name */
461 sqlite3_result_text(ctx, pFile->zName, -1, SQLITE_STATIC);
462 break;
463 case 1: /* size */
464 sqlite3_result_int(ctx, pFile->nByte);
465 break;
466 case 2: /* data */
467 sqlite3_result_blob(ctx, pFile->pData, pFile->nByte, SQLITE_STATIC);
468 break;
469 }
470 return SQLITE_OK;
471 }
472
473 /*
474 ** Return the rowid for the current row. In this implementation, the
475 ** rowid is the same as the output value.
476 */
477 static int builtinVtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
478 builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
479 *pRowid = pCur->iRowid;
480 return SQLITE_OK;
481 }
482
483 /*
484 ** Return TRUE if the cursor has been moved off of the last
485 ** row of output.
486 */
487 static int builtinVtabEof(sqlite3_vtab_cursor *cur){
488 builtinVtab_cursor *pCur = (builtinVtab_cursor*)cur;
489 return pCur->iRowid>=count(aBuiltinFiles);
490 }
491
492 /*
493 ** This method is called to "rewind" the builtinVtab_cursor object back
494 ** to the first row of output. This method is always called at least
495 ** once prior to any call to builtinVtabColumn() or builtinVtabRowid() or
496 ** builtinVtabEof().
497 */
498 static int builtinVtabFilter(
499 sqlite3_vtab_cursor *pVtabCursor,
500 int idxNum, const char *idxStr,
501 int argc, sqlite3_value **argv
502 ){
503 builtinVtab_cursor *pCur = (builtinVtab_cursor *)pVtabCursor;
504 pCur->iRowid = 1;
505 return SQLITE_OK;
506 }
507
508 /*
509 ** SQLite will invoke this method one or more times while planning a query
510 ** that uses the virtual table. This routine needs to create
511 ** a query plan for each invocation and compute an estimated cost for that
512 ** plan.
513 */
514 static int builtinVtabBestIndex(
515 sqlite3_vtab *tab,
516 sqlite3_index_info *pIdxInfo
517 ){
518 pIdxInfo->estimatedCost = (double)count(aBuiltinFiles);
519 pIdxInfo->estimatedRows = count(aBuiltinFiles);
520 return SQLITE_OK;
521 }
522
523 /*
524 ** This following structure defines all the methods for the
525 ** virtual table.
526 */
527 static sqlite3_module builtinVtabModule = {
528 /* iVersion */ 0,
529 /* xCreate */ 0, /* The builtin vtab is eponymous and read-only */
530 /* xConnect */ builtinVtabConnect,
531 /* xBestIndex */ builtinVtabBestIndex,
532 /* xDisconnect */ builtinVtabDisconnect,
533 /* xDestroy */ 0,
534 /* xOpen */ builtinVtabOpen,
535 /* xClose */ builtinVtabClose,
536 /* xFilter */ builtinVtabFilter,
537 /* xNext */ builtinVtabNext,
538 /* xEof */ builtinVtabEof,
539 /* xColumn */ builtinVtabColumn,
540 /* xRowid */ builtinVtabRowid,
541 /* xUpdate */ 0,
542 /* xBegin */ 0,
543 /* xSync */ 0,
544 /* xCommit */ 0,
545 /* xRollback */ 0,
546 /* xFindMethod */ 0,
547 /* xRename */ 0,
548 /* xSavepoint */ 0,
549 /* xRelease */ 0,
550 /* xRollbackTo */ 0,
551 /* xShadowName */ 0
552 };
553
554
555 /*
556 ** Register the builtin virtual table
557 */
558 int builtin_vtab_register(sqlite3 *db){
559 int rc = sqlite3_create_module(db, "builtin", &builtinVtabModule, 0);
560 return rc;
561 }
562 /* End of the builtin virtual table
563 ******************************************************************************/
564
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -172,10 +172,11 @@
172172
re_add_sql_func(db);
173173
search_sql_setup(db);
174174
foci_register(db);
175175
deltafunc_init(db);
176176
helptext_vtab_register(db);
177
+ builtin_vtab_register(db);
177178
g.repositoryOpen = 1;
178179
g.db = db;
179180
sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "repository");
180181
db_maybe_set_encryption_key(db, g.zRepositoryName);
181182
if( g.zLocalDbName ){
@@ -291,10 +292,14 @@
291292
** All of the standard sqlite3 command-line shell options should also
292293
** work.
293294
**
294295
** The following SQL extensions are provided with this Fossil-enhanced
295296
** version of the sqlite3 command-line shell:
297
+**
298
+** builtin A virtual table that contains one row for
299
+** each datafile that is built into the Fossil
300
+** binary.
296301
**
297302
** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID)
298303
** found in check-in X (another BLOB.RID value).
299304
**
300305
** compress(X) Compress text X with the same algorithm used
@@ -323,10 +328,14 @@
323328
**
324329
** files_of_checkin(X) A table-valued function that returns info on
325330
** all files contained in check-in X. Example:
326331
**
327332
** SELECT * FROM files_of_checkin('trunk');
333
+**
334
+** helptext A virtual table with one row for each command,
335
+** webpage, and setting together with the built-in
336
+** help text.
328337
**
329338
** now() Return the number of seconds since 1970.
330339
**
331340
** obscure(T) Obfuscate the text password T so that its
332341
** original value is not readily visible. Fossil
333342
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -172,10 +172,11 @@
172 re_add_sql_func(db);
173 search_sql_setup(db);
174 foci_register(db);
175 deltafunc_init(db);
176 helptext_vtab_register(db);
 
177 g.repositoryOpen = 1;
178 g.db = db;
179 sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "repository");
180 db_maybe_set_encryption_key(db, g.zRepositoryName);
181 if( g.zLocalDbName ){
@@ -291,10 +292,14 @@
291 ** All of the standard sqlite3 command-line shell options should also
292 ** work.
293 **
294 ** The following SQL extensions are provided with this Fossil-enhanced
295 ** version of the sqlite3 command-line shell:
 
 
 
 
296 **
297 ** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID)
298 ** found in check-in X (another BLOB.RID value).
299 **
300 ** compress(X) Compress text X with the same algorithm used
@@ -323,10 +328,14 @@
323 **
324 ** files_of_checkin(X) A table-valued function that returns info on
325 ** all files contained in check-in X. Example:
326 **
327 ** SELECT * FROM files_of_checkin('trunk');
 
 
 
 
328 **
329 ** now() Return the number of seconds since 1970.
330 **
331 ** obscure(T) Obfuscate the text password T so that its
332 ** original value is not readily visible. Fossil
333
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -172,10 +172,11 @@
172 re_add_sql_func(db);
173 search_sql_setup(db);
174 foci_register(db);
175 deltafunc_init(db);
176 helptext_vtab_register(db);
177 builtin_vtab_register(db);
178 g.repositoryOpen = 1;
179 g.db = db;
180 sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "repository");
181 db_maybe_set_encryption_key(db, g.zRepositoryName);
182 if( g.zLocalDbName ){
@@ -291,10 +292,14 @@
292 ** All of the standard sqlite3 command-line shell options should also
293 ** work.
294 **
295 ** The following SQL extensions are provided with this Fossil-enhanced
296 ** version of the sqlite3 command-line shell:
297 **
298 ** builtin A virtual table that contains one row for
299 ** each datafile that is built into the Fossil
300 ** binary.
301 **
302 ** checkin_mtime(X,Y) Return the mtime for the file Y (a BLOB.RID)
303 ** found in check-in X (another BLOB.RID value).
304 **
305 ** compress(X) Compress text X with the same algorithm used
@@ -323,10 +328,14 @@
328 **
329 ** files_of_checkin(X) A table-valued function that returns info on
330 ** all files contained in check-in X. Example:
331 **
332 ** SELECT * FROM files_of_checkin('trunk');
333 **
334 ** helptext A virtual table with one row for each command,
335 ** webpage, and setting together with the built-in
336 ** help text.
337 **
338 ** now() Return the number of seconds since 1970.
339 **
340 ** obscure(T) Obfuscate the text password T so that its
341 ** original value is not readily visible. Fossil
342

Keyboard Shortcuts

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