Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add sqlite_progress_handler() API for specifying an progress callback (CVS 1111) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ddb364635a207658664ea92fc677cf16 |
User & Date: | danielk1977 2003-10-18 09:37:26.000 |
Context
2003-10-21
| ||
13:16 | Convert lemon to use a single perfect hash table for storing the actions. This should make the resulting parser both smaller and faster. (CVS 1112) (check-in: 4f955c0007 user: drh tags: trunk) | |
2003-10-18
| ||
09:37 | Add sqlite_progress_handler() API for specifying an progress callback (CVS 1111) (check-in: ddb364635a user: danielk1977 tags: trunk) | |
2003-10-10
| ||
02:09 | Update to the date functions. (CVS 1110) (check-in: 06d4e88394 user: drh tags: trunk) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.143 2003/10/18 09:37:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
821 822 823 824 825 826 827 828 829 830 831 832 833 834 | sqlite *db, int (*xBusy)(void*,const char*,int), void *pArg ){ db->xBusyCallback = xBusy; db->pBusyArg = pArg; } /* ** This routine installs a default busy handler that waits for the ** specified number of milliseconds before returning 0. */ void sqlite_busy_timeout(sqlite *db, int ms){ if( ms>0 ){ | > > > > > > > > > > > > > > > > > > > > > > > > > | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | sqlite *db, int (*xBusy)(void*,const char*,int), void *pArg ){ db->xBusyCallback = xBusy; db->pBusyArg = pArg; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* ** This routine sets the progress callback for an Sqlite database to the ** given callback function with the given argument. The progress callback will ** be invoked every nOps opcodes. */ void sqlite_progress_handler( sqlite *db, int nOps, int (*xProgress)(void*), void *pArg ){ if( nOps>0 ){ db->xProgress = xProgress; db->nProgressOps = nOps; db->pProgressArg = pArg; }else{ db->xProgress = 0; db->nProgressOps = 0; db->pProgressArg = 0; } } #endif /* ** This routine installs a default busy handler that waits for the ** specified number of milliseconds before returning 0. */ void sqlite_busy_timeout(sqlite *db, int ms){ if( ms>0 ){ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.53 2003/10/18 09:37:26 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
725 726 727 728 729 730 731 732 733 734 735 736 | ** This routine can only be called immediately after sqlite_compile() ** or sqlite_reset() and before any calls to sqlite_step(). ** ******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy); #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif /* _SQLITE_H_ */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | ** This routine can only be called immediately after sqlite_compile() ** or sqlite_reset() and before any calls to sqlite_step(). ** ******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy); /* ** This routine configures a callback function - the progress callback - that ** is invoked periodically during long running calls to sqlite_exec(), ** sqlite_step() and sqlite_get_table(). An example use for this API is to keep ** a GUI updated during a large query. ** ** The progress callback is invoked once for every N virtual machine opcodes, ** where N is the second argument to this function. The progress callback ** itself is identified by the third argument to this function. The fourth ** argument to this function is a void pointer passed to the progress callback ** function each time it is invoked. ** ** If a call to sqlite_exec(), sqlite_step() or sqlite_get_table() results ** in less than N opcodes being executed, then the progress callback is not ** invoked. ** ** Calling this routine overwrites any previously installed progress callback. ** To remove the progress callback altogether, pass NULL as the third ** argument to this function. ** ** If the progress callback returns a result other than 0, then the current ** query is immediately terminated and any database changes rolled back. If the ** query was part of a larger transaction, then the transaction is not rolled ** back and remains active. The sqlite_exec() call returns SQLITE_ABORT. */ void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*); #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif /* _SQLITE_H_ */ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.200 2003/10/18 09:37:26 danielk1977 Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" |
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | ** features of the library and thus keep the size of the library to ** a minimum. */ /* #define SQLITE_OMIT_AUTHORIZATION 1 */ /* #define SQLITE_OMIT_INMEMORYDB 1 */ /* #define SQLITE_OMIT_VACUUM 1 */ /* #define SQLITE_OMIT_TIMEDATE_FUNCS 1 */ /* ** Integers of known sizes. These typedefs might change for architectures ** where the sizes very. Preprocessor macros are available so that the ** types can be conveniently redefined at compile-type. Like this: ** ** cc '-DUINTPTR_TYPE=long long int' ... | > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | ** features of the library and thus keep the size of the library to ** a minimum. */ /* #define SQLITE_OMIT_AUTHORIZATION 1 */ /* #define SQLITE_OMIT_INMEMORYDB 1 */ /* #define SQLITE_OMIT_VACUUM 1 */ /* #define SQLITE_OMIT_TIMEDATE_FUNCS 1 */ /* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */ /* ** Integers of known sizes. These typedefs might change for architectures ** where the sizes very. Preprocessor macros are available so that the ** types can be conveniently redefined at compile-type. Like this: ** ** cc '-DUINTPTR_TYPE=long long int' ... |
︙ | ︙ | |||
322 323 324 325 326 327 328 329 330 331 332 333 334 335 | void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif }; /* ** Possible values for the sqlite.flags and or Db.flags fields. ** ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement | > > > > > | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int (*xProgress)(void *); /* The progress callback */ void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif }; /* ** Possible values for the sqlite.flags and or Db.flags fields. ** ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement |
︙ | ︙ |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.51 2003/10/18 09:37:26 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
48 49 50 51 52 53 54 55 56 57 58 59 60 61 | */ typedef struct SqliteDb SqliteDb; struct SqliteDb { sqlite *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ char *zTrace; /* The trace callback routine */ char *zAuth; /* The authorization callback routine */ SqlFunc *pFunc; /* List of SQL functions */ int rc; /* Return code of most recent sqlite_exec() */ }; /* ** An instance of this structure passes information thru the sqlite | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | */ typedef struct SqliteDb SqliteDb; struct SqliteDb { sqlite *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ char *zTrace; /* The trace callback routine */ char *zProgress; /* The progress callback routine */ char *zAuth; /* The authorization callback routine */ SqlFunc *pFunc; /* List of SQL functions */ int rc; /* Return code of most recent sqlite_exec() */ }; /* ** An instance of this structure passes information thru the sqlite |
︙ | ︙ | |||
320 321 322 323 324 325 326 327 328 329 330 331 332 333 | rc = Tcl_Eval(pDb->interp, zCmd); Tcl_DStringFree(&cmd); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 0; } return 1; } /* ** This routine is called by the SQLite trace handler whenever a new ** block of SQL is executed. The TCL script in pDb->zTrace is executed. */ static void DbTraceHandler(void *cd, const char *zSql){ SqliteDb *pDb = (SqliteDb*)cd; | > > > > > > > > > > > > > > > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | rc = Tcl_Eval(pDb->interp, zCmd); Tcl_DStringFree(&cmd); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 0; } return 1; } /* ** This routine is invoked as the 'progress callback' for the database. */ static int DbProgressHandler(void *cd){ SqliteDb *pDb = (SqliteDb*)cd; int rc; assert( pDb->zProgress ); rc = Tcl_Eval(pDb->interp, pDb->zProgress); if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ return 1; } return 0; } /* ** This routine is called by the SQLite trace handler whenever a new ** block of SQL is executed. The TCL script in pDb->zTrace is executed. */ static void DbTraceHandler(void *cd, const char *zSql){ SqliteDb *pDb = (SqliteDb*)cd; |
︙ | ︙ | |||
453 454 455 456 457 458 459 | SqliteDb *pDb = (SqliteDb*)cd; int choice; static const char *DB_strs[] = { "authorizer", "busy", "changes", "close", "complete", "errorcode", "eval", "function", "last_insert_rowid", "onecolumn", "timeout", "trace", | < > > | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 | SqliteDb *pDb = (SqliteDb*)cd; int choice; static const char *DB_strs[] = { "authorizer", "busy", "changes", "close", "complete", "errorcode", "eval", "function", "last_insert_rowid", "onecolumn", "timeout", "trace", "progress", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BUSY, DB_CHANGES, DB_CLOSE, DB_COMPLETE, DB_ERRORCODE, DB_EVAL, DB_FUNCTION, DB_LAST_INSERT_ROWID, DB_ONECOLUMN, DB_TIMEOUT, DB_TRACE, DB_PROGRESS, }; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ |
︙ | ︙ | |||
557 558 559 560 561 562 563 564 565 566 567 568 569 570 | sqlite_busy_handler(pDb->db, DbBusyHandler, pDb); }else{ sqlite_busy_handler(pDb->db, 0, 0); } } break; } /* ** $db changes ** ** Return the number of rows that were modified, inserted, or deleted by ** the most recent "eval". */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | sqlite_busy_handler(pDb->db, DbBusyHandler, pDb); }else{ sqlite_busy_handler(pDb->db, 0, 0); } } break; } /* $db progress ?N CALLBACK? ** ** Invoke the given callback every N virtual machine opcodes while executing ** queries. */ case DB_PROGRESS: { if( objc==2 ){ if( pDb->zProgress ){ Tcl_AppendResult(interp, pDb->zProgress, 0); } }else if( objc==4 ){ char *zProgress; int len; int N; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ return TCL_ERROR; }; if( pDb->zProgress ){ Tcl_Free(pDb->zProgress); } zProgress = Tcl_GetStringFromObj(objv[3], &len); if( zProgress && len>0 ){ pDb->zProgress = Tcl_Alloc( len + 1 ); strcpy(pDb->zProgress, zProgress); }else{ pDb->zProgress = 0; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( pDb->zProgress ){ pDb->interp = interp; sqlite_progress_handler(pDb->db, N, DbProgressHandler, pDb); }else{ sqlite_progress_handler(pDb->db, 0, 0, 0); } #endif }else{ Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK"); return TCL_ERROR; } break; } /* ** $db changes ** ** Return the number of rows that were modified, inserted, or deleted by ** the most recent "eval". */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.242 2003/10/18 09:37:26 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
525 526 527 528 529 530 531 532 533 534 535 536 537 538 | char **zStack = p->zStack; /* Text stack */ Stack *aStack = p->aStack; /* Additional stack information */ char zBuf[100]; /* Space to sprintf() an integer */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE; assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); p->rc = SQLITE_OK; assert( p->explain==0 ); if( sqlite_malloc_failed ) goto no_mem; | > > > | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | char **zStack = p->zStack; /* Text stack */ Stack *aStack = p->aStack; /* Additional stack information */ char zBuf[100]; /* Space to sprintf() an integer */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE; assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); p->rc = SQLITE_OK; assert( p->explain==0 ); if( sqlite_malloc_failed ) goto no_mem; |
︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 | /* Only allow tracing if NDEBUG is not defined. */ #ifndef NDEBUG if( p->trace ){ sqliteVdbePrintOp(p->trace, pc, pOp); } #endif switch( pOp->opcode ){ /***************************************************************************** ** What follows is a massive switch statement where each case implements a ** separate instruction in the virtual machine. If we follow the usual ** indentation conventions, each case should be indented by 6 spaces. But | > > > > > > > > > > > > > > > > > | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | /* Only allow tracing if NDEBUG is not defined. */ #ifndef NDEBUG if( p->trace ){ sqliteVdbePrintOp(p->trace, pc, pOp); } #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number ** of VDBE ops have been executed (either since this invocation of ** sqliteVdbeExec() or since last time the progress callback was called). ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ if( db->xProgress && (db->nProgressOps==nProgressOps) ){ if( db->xProgress(db->pProgressArg)!=0 ){ rc = SQLITE_ABORT; continue; /* skip to the next iteration of the for loop */ } nProgressOps = 0; } nProgressOps++; #endif switch( pOp->opcode ){ /***************************************************************************** ** What follows is a massive switch statement where each case implements a ** separate instruction in the virtual machine. If we follow the usual ** indentation conventions, each case should be indented by 6 spaces. But |
︙ | ︙ |
Added test/progress.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the 'progress callback'. # # $Id: progress.test,v 1.1 2003/10/18 09:37:27 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # execsql { BEGIN; CREATE TABLE t1(a); INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(2); INSERT INTO t1 VALUES(3); INSERT INTO t1 VALUES(4); INSERT INTO t1 VALUES(5); INSERT INTO t1 VALUES(6); INSERT INTO t1 VALUES(7); INSERT INTO t1 VALUES(8); INSERT INTO t1 VALUES(9); INSERT INTO t1 VALUES(10); COMMIT; } # Test that the progress callback is invoked. do_test progress-1.0 { set counter 0 db progress 1 "[namespace code {incr counter}] ; expr 0" execsql { SELECT * FROM t1 } expr $counter > 1 } 1 # Test that the query is abandoned when the progress callback returns non-zero do_test progress1.1 { set counter 0 db progress 1 "[namespace code {incr counter}] ; expr 1" execsql { SELECT * FROM t1 } set counter } 1 # Test that the query is rolled back when the progress callback returns # non-zero. do_test progress1.2 { # This figures out how many opcodes it takes to copy 5 extra rows into t1. db progress 1 "[namespace code {incr five_rows}] ; expr 0" set five_rows 0 execsql { INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 6 } db progress 0 "" execsql { DELETE FROM t1 WHERE a > 10 } # Now set up the progress callback to abandon the query after the number of # opcodes to copy 5 rows. That way, when we try to copy 6 rows, we know # some data will have been inserted into the table by the time the progress # callback abandons the query. db progress $five_rows "expr 1" execsql { INSERT INTO t1 SELECT a+10 FROM t1 WHERE a < 7 } execsql { SELECT count(*) FROM t1 } } 10 # Test that an active transaction remains active and not rolled back after the # progress query abandons a query. do_test progress1.3 { db progress 0 "" execsql BEGIN execsql { INSERT INTO t1 VALUES(11) } db progress 1 "expr 1" execsql { INSERT INTO t1 VALUES(12) } db progress 0 "" execsql COMMIT execsql { SELECT count(*) FROM t1 } } 11 # Check that a value of 0 for N means no progress callback do_test progress1.4 { set counter 0 db progress 0 "[namespace code {incr counter}] ; expr 0" execsql { SELECT * FROM t1; } set counter } 0 db progress 0 "" finish_test |
Changes to www/c_interface.tcl.
1 2 3 | # # Run this Tcl script to generate the sqlite.html file. # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this Tcl script to generate the sqlite.html file. # set rcsid {$Id: c_interface.tcl,v 1.39 2003/10/18 09:37:27 danielk1977 Exp $} puts {<html> <head> <title>The C language interface to the SQLite library</title> </head> <body bgcolor=white> <h1 align=center> |
︙ | ︙ | |||
631 632 633 634 635 636 637 638 639 640 641 642 643 644 | char *sqlite_mprintf(const char *zFormat, ...); char *sqlite_vmprintf(const char *zFormat, va_list); void sqlite_freemem(char*); </pre></blockquote> <p>All of the above definitions are included in the "sqlite.h" header file that comes in the source tree.</p> <h3>3.1 The ROWID of the most recent insert</h3> | > > | 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 | char *sqlite_mprintf(const char *zFormat, ...); char *sqlite_vmprintf(const char *zFormat, va_list); void sqlite_freemem(char*); void sqlite_progress_handler(sqlite*, int, int (*)(void*), void*); </pre></blockquote> <p>All of the above definitions are included in the "sqlite.h" header file that comes in the source tree.</p> <h3>3.1 The ROWID of the most recent insert</h3> |
︙ | ︙ | |||
974 975 976 977 978 979 980 981 982 983 984 985 986 987 | <b>sprintf()</b> except that it writes its results into memory obtained from malloc() and returns a pointer to the malloced buffer. <b>sqlite_mprintf()</b> also understands the %q and %Q extensions described above. The <b>sqlite_vmprintf()</b> is a varargs version of the same routine. The string pointer that these routines return should be freed by passing it to <b>sqlite_freemem()</b>. </p> <a name="cfunc"> <h2>4.0 Adding New SQL Functions</h2> <p>Beginning with version 2.4.0, SQLite allows the SQL language to be extended with new functions implemented as C code. The following interface is used: | > > > > > > > > > > > > > > > > > > > > > > > > | 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | <b>sprintf()</b> except that it writes its results into memory obtained from malloc() and returns a pointer to the malloced buffer. <b>sqlite_mprintf()</b> also understands the %q and %Q extensions described above. The <b>sqlite_vmprintf()</b> is a varargs version of the same routine. The string pointer that these routines return should be freed by passing it to <b>sqlite_freemem()</b>. </p> <h3>3.10 Performing background jobs during large queries </h2> <p>The <b>sqlite_progress_handler()</b> routine can be used to register a callback routine with an SQLite database to be invoked periodically during long running calls to <b>sqlite_exec()</b>, <b>sqlite_step()</b> and the various wrapper functions. </p> <p>The callback is invoked every N virtual machine operations, where N is supplied as the second argument to <b>sqlite_progress_handler()</b>. The third and fourth arguments to <b>sqlite_progress_handler()</b> are a pointer to the routine to be invoked and a void pointer to be passed as the first argument to it. </p> <p>The time taken to execute each virtual machine operation can vary based on many factors. A typical value for a 1 GHz PC is between half and three million per second but may be much higher or lower, depending on the query. As such it is difficult to schedule background operations based on virtual machine operations. Instead, it is recommended that a callback be scheduled relatively frequently (say every 1000 instructions) and external timer routines used to determine whether or not background jobs need to be run. </p> <a name="cfunc"> <h2>4.0 Adding New SQL Functions</h2> <p>Beginning with version 2.4.0, SQLite allows the SQL language to be extended with new functions implemented as C code. The following interface is used: |
︙ | ︙ |