mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Additional testing and bug fixing with the non-callback API. Updated the
C/C++ interface document to describe the non-callback API. (CVS 855) FossilOrigin-Name: af1e9299468aa70d7d91e7a5445ba391ccc8ff8b
This commit is contained in:
24
manifest
24
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Better\serror\smessages\son\sconstraint\sviolations.\s\sAdditional\stests\sand\sbug\sfixes\nfor\sthe\scallback-free\sAPI.\s(CVS\s854)
|
C Additional\stesting\sand\sbug\sfixing\swith\sthe\snon-callback\sAPI.\s\sUpdated\sthe\nC/C++\sinterface\sdocument\sto\sdescribe\sthe\snon-callback\sAPI.\s(CVS\s855)
|
||||||
D 2003-01-29T18:46:52
|
D 2003-01-29T22:58:26
|
||||||
F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64
|
F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -19,7 +19,7 @@ F publish.sh ce0bf7e235984bc156dc5d1a0c8092db4c8442f3
|
|||||||
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
|
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
|
||||||
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
||||||
F src/auth.c 9c2db0bc7707f2d2e227f47e3d557b41d44ade75
|
F src/auth.c 9c2db0bc7707f2d2e227f47e3d557b41d44ade75
|
||||||
F src/btree.c eb4f430b062500d7533c031097d3ff8824eca3ba
|
F src/btree.c 668402ca441592d85da521309625bd1bcc6f010e
|
||||||
F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
|
F src/btree.h 17710339f7a8f46e3c7d6d0d4648ef19c584ffda
|
||||||
F src/build.c 6e0310086b8e2deef74f0d4fb3297c4e8fcf6222
|
F src/build.c 6e0310086b8e2deef74f0d4fb3297c4e8fcf6222
|
||||||
F src/delete.c cbd499f3f9297504c42e328af89bef1a2113d04c
|
F src/delete.c cbd499f3f9297504c42e328af89bef1a2113d04c
|
||||||
@@ -33,7 +33,7 @@ F src/main.c 764a72e6a4f021ae1d3db7e82dab625075f4fedb
|
|||||||
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
||||||
F src/os.c ed27e178e0c4b71f2807da81b8851f0fadc50778
|
F src/os.c ed27e178e0c4b71f2807da81b8851f0fadc50778
|
||||||
F src/os.h afa3e096213bad86845f8bdca81a9e917505e401
|
F src/os.h afa3e096213bad86845f8bdca81a9e917505e401
|
||||||
F src/pager.c 95f5c5c775ed47e837ce02b407d80527d93e6c43
|
F src/pager.c 7ca152bb9fcab56e2f6df62e2ebd20f538214fad
|
||||||
F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
|
F src/pager.h 540833e8cb826b80ce2e39aa917deee5e12db626
|
||||||
F src/parse.y cdaed5009423d851708848bd279147c268e6022e
|
F src/parse.y cdaed5009423d851708848bd279147c268e6022e
|
||||||
F src/printf.c f8fd911a8738f9b2eb07aca2870473d34707055d
|
F src/printf.c f8fd911a8738f9b2eb07aca2870473d34707055d
|
||||||
@@ -45,7 +45,7 @@ F src/sqlite.h.in 6f648803f2ffb9beb35cb1cfa42b323d55519171
|
|||||||
F src/sqliteInt.h f22092ed33fea784f58bcd57b90c0babd16a0e29
|
F src/sqliteInt.h f22092ed33fea784f58bcd57b90c0babd16a0e29
|
||||||
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
|
||||||
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
|
F src/tclsqlite.c 9f2c00a92338c51171ded8943bd42d77f7e69e64
|
||||||
F src/test1.c a24735c6e6364ccaa73ce3b106859fb325b076d9
|
F src/test1.c eb05abd3ec6822f800476c04aed4db112690b144
|
||||||
F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b
|
F src/test2.c 03f05e984c8e2f2badc44644d42baf72b249096b
|
||||||
F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728
|
F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728
|
||||||
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
|
||||||
@@ -53,7 +53,7 @@ F src/tokenize.c bc40937d6666f188037aa3e54f0a2661a6fef6d1
|
|||||||
F src/trigger.c da142decd2808bc39e801f3bb1f161dbc2bd4005
|
F src/trigger.c da142decd2808bc39e801f3bb1f161dbc2bd4005
|
||||||
F src/update.c f06afa9bf1f777d17702e0f6e33cf44c44bc4f75
|
F src/update.c f06afa9bf1f777d17702e0f6e33cf44c44bc4f75
|
||||||
F src/util.c 757875a366be838d96c09f255631596a2f558fca
|
F src/util.c 757875a366be838d96c09f255631596a2f558fca
|
||||||
F src/vdbe.c de4c00495ed6d3c7798153996ea174881fc29b42
|
F src/vdbe.c 2ad2510bc3d25db9da66054d33fdcadf54d25fff
|
||||||
F src/vdbe.h ed43771f1dc2b994d5c484fdf2eab357c6ef0ee3
|
F src/vdbe.h ed43771f1dc2b994d5c484fdf2eab357c6ef0ee3
|
||||||
F src/where.c 5bf7f1e1d756ab3d25a18b24bb42106cb8e14d18
|
F src/where.c 5bf7f1e1d756ab3d25a18b24bb42106cb8e14d18
|
||||||
F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029
|
F test/all.test 873d30e25a41b3aa48fec5633a7ec1816e107029
|
||||||
@@ -64,7 +64,7 @@ F test/btree.test 10e75aec120ecefc0edc4c912a0980a43db1b6c2
|
|||||||
F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080
|
F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080
|
||||||
F test/btree3.test e597fb59be2ac0ea69c62aaa2064e998e528b665
|
F test/btree3.test e597fb59be2ac0ea69c62aaa2064e998e528b665
|
||||||
F test/btree4.test fa955a3d7a8bc91d6084b7f494f9e5d1bdfb15b6
|
F test/btree4.test fa955a3d7a8bc91d6084b7f494f9e5d1bdfb15b6
|
||||||
F test/capi2.test 21f73319ae288d874f68787b5af4bd2022e25dcb
|
F test/capi2.test b0b4b73b3e6a5babe8a4945fb7d74c2bc4443b15
|
||||||
F test/conflict.test d7d9dbea9909c1b843f9e89c8318fdb7ca07a5e5
|
F test/conflict.test d7d9dbea9909c1b843f9e89c8318fdb7ca07a5e5
|
||||||
F test/copy.test 73df5ed3112e858e006a8b7ddb4c9bab6a25d0fb
|
F test/copy.test 73df5ed3112e858e006a8b7ddb4c9bab6a25d0fb
|
||||||
F test/delete.test 5821a95a66061ae09723a88938f23d10d8a881ad
|
F test/delete.test 5821a95a66061ae09723a88938f23d10d8a881ad
|
||||||
@@ -134,7 +134,7 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
|
|||||||
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
||||||
F www/arch.tcl 679a0c48817f71bc91d5911ef386e5ef35d4f178
|
F www/arch.tcl 679a0c48817f71bc91d5911ef386e5ef35d4f178
|
||||||
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
|
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
|
||||||
F www/c_interface.tcl e76c9fd609326c34cd45cd040b508b0e21908800
|
F www/c_interface.tcl bca0aea880d043ed1bc0ad3bb39e24043f88b5bf
|
||||||
F www/changes.tcl b48068eabfd0ff603d90f75b01bed295f23198e2
|
F www/changes.tcl b48068eabfd0ff603d90f75b01bed295f23198e2
|
||||||
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
|
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
|
||||||
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
|
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
|
||||||
@@ -145,7 +145,7 @@ F www/faq.tcl 06276ff6c3e369374bb83034cc9d4a7d3a2a34a1
|
|||||||
F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936
|
F www/fileformat.tcl a4b5c2c6e89b7d42d09f97fd4d7bbd39cbf24936
|
||||||
F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e
|
F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e
|
||||||
F www/index.tcl b5265ca54a5124ec40bffb7c7943e072e074d61a
|
F www/index.tcl b5265ca54a5124ec40bffb7c7943e072e074d61a
|
||||||
F www/lang.tcl 1c11172bd6511b39d2c69f153a5e82332d0379ef
|
F www/lang.tcl 7ad51d873059368a98bcc2afec60d6ba4bb5688a
|
||||||
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
|
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
|
||||||
F www/nulls.tcl 29497dac2bc5b437aa7e2e94577dad4d8933ed26
|
F www/nulls.tcl 29497dac2bc5b437aa7e2e94577dad4d8933ed26
|
||||||
F www/omitted.tcl 118062f40a203fcb88b8d68ef1d7c0073ac191ec
|
F www/omitted.tcl 118062f40a203fcb88b8d68ef1d7c0073ac191ec
|
||||||
@@ -155,7 +155,7 @@ F www/speed.tcl 4d463e2aea41f688ed320a937f93ff885be918c3
|
|||||||
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
|
||||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
|
||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||||
P 162b259188e6967fe9c3722da26b81aab5655d83
|
P ccc82f1ab4539a60ee5cc2625743c5389f9ccd8e
|
||||||
R 715f66b82d831caba169ad25678a9655
|
R 71f3061b9977afdcd191ea15858b4f86
|
||||||
U drh
|
U drh
|
||||||
Z 12bd865865cbc9da0a476fa88511badb
|
Z da2509caf930012c96a4743c5b339fae
|
||||||
|
@@ -1 +1 @@
|
|||||||
ccc82f1ab4539a60ee5cc2625743c5389f9ccd8e
|
af1e9299468aa70d7d91e7a5445ba391ccc8ff8b
|
10
src/btree.c
10
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.81 2003/01/24 12:14:20 drh Exp $
|
** $Id: btree.c,v 1.82 2003/01/29 22:58:26 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -900,13 +900,13 @@ int sqliteBtreeRollback(Btree *pBt){
|
|||||||
if( pBt->inTrans==0 ) return SQLITE_OK;
|
if( pBt->inTrans==0 ) return SQLITE_OK;
|
||||||
pBt->inTrans = 0;
|
pBt->inTrans = 0;
|
||||||
pBt->inCkpt = 0;
|
pBt->inCkpt = 0;
|
||||||
|
rc = pBt->readOnly ? SQLITE_OK : sqlitepager_rollback(pBt->pPager);
|
||||||
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
||||||
if( pCur->pPage ){
|
if( pCur->pPage && pCur->pPage->isInit==0 ){
|
||||||
sqlitepager_unref(pCur->pPage);
|
sqlitepager_unref(pCur->pPage);
|
||||||
pCur->pPage = 0;
|
pCur->pPage = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = pBt->readOnly ? SQLITE_OK : sqlitepager_rollback(pBt->pPager);
|
|
||||||
unlockBtreeIfUnused(pBt);
|
unlockBtreeIfUnused(pBt);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -959,13 +959,13 @@ int sqliteBtreeRollbackCkpt(Btree *pBt){
|
|||||||
int rc;
|
int rc;
|
||||||
BtCursor *pCur;
|
BtCursor *pCur;
|
||||||
if( pBt->inCkpt==0 || pBt->readOnly ) return SQLITE_OK;
|
if( pBt->inCkpt==0 || pBt->readOnly ) return SQLITE_OK;
|
||||||
|
rc = sqlitepager_ckpt_rollback(pBt->pPager);
|
||||||
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
|
||||||
if( pCur->pPage ){
|
if( pCur->pPage && pCur->pPage->isInit==0 ){
|
||||||
sqlitepager_unref(pCur->pPage);
|
sqlitepager_unref(pCur->pPage);
|
||||||
pCur->pPage = 0;
|
pCur->pPage = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = sqlitepager_ckpt_rollback(pBt->pPager);
|
|
||||||
pBt->inCkpt = 0;
|
pBt->inCkpt = 0;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
21
src/pager.c
21
src/pager.c
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.71 2003/01/25 15:43:22 drh Exp $
|
** @(#) $Id: pager.c,v 1.72 2003/01/29 22:58:26 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "os.h" /* Must be first to enable large file support */
|
#include "os.h" /* Must be first to enable large file support */
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -450,8 +450,19 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd){
|
|||||||
rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
|
rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
if( pPg ){
|
if( pPg ){
|
||||||
|
if( pPg->nRef==0 ||
|
||||||
|
memcmp(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE)==0
|
||||||
|
){
|
||||||
|
/* Do not update the data on this page if the page is in use
|
||||||
|
** and the page has never been modified. This avoids resetting
|
||||||
|
** the "extra" data. That in turn avoids invalidating BTree cursors
|
||||||
|
** in trees that have never been modified. The end result is that
|
||||||
|
** you can have a SELECT going on in one table and ROLLBACK changes
|
||||||
|
** to a different table and the SELECT is unaffected by the ROLLBACK.
|
||||||
|
*/
|
||||||
memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
|
memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
|
||||||
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
|
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
|
||||||
|
}
|
||||||
pPg->dirty = 0;
|
pPg->dirty = 0;
|
||||||
pPg->needSync = 0;
|
pPg->needSync = 0;
|
||||||
}
|
}
|
||||||
@@ -545,14 +556,18 @@ end_playback:
|
|||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
PgHdr *pPg;
|
PgHdr *pPg;
|
||||||
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
||||||
|
char zBuf[SQLITE_PAGE_SIZE];
|
||||||
if( (int)pPg->pgno <= pPager->origDbSize ){
|
if( (int)pPg->pgno <= pPager->origDbSize ){
|
||||||
sqliteOsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
|
sqliteOsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
|
||||||
rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
|
rc = sqliteOsRead(&pPager->fd, zBuf, SQLITE_PAGE_SIZE);
|
||||||
if( rc ) break;
|
if( rc ) break;
|
||||||
}else{
|
}else{
|
||||||
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
|
memset(zBuf, 0, SQLITE_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE) ){
|
||||||
|
memcpy(PGHDR_TO_DATA(pPg), zBuf, SQLITE_PAGE_SIZE);
|
||||||
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
|
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
|
||||||
|
}
|
||||||
pPg->needSync = 0;
|
pPg->needSync = 0;
|
||||||
pPg->dirty = 0;
|
pPg->dirty = 0;
|
||||||
}
|
}
|
||||||
|
12
src/test1.c
12
src/test1.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.19 2003/01/29 18:46:53 drh Exp $
|
** $Id: test1.c,v 1.20 2003/01/29 22:58:26 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -755,9 +755,9 @@ static int test_step(
|
|||||||
){
|
){
|
||||||
sqlite_vm *vm;
|
sqlite_vm *vm;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
const char **azValue;
|
const char **azValue = 0;
|
||||||
const char **azColName;
|
const char **azColName = 0;
|
||||||
int N;
|
int N = 0;
|
||||||
char *zRc;
|
char *zRc;
|
||||||
char zBuf[50];
|
char zBuf[50];
|
||||||
if( argc!=5 ){
|
if( argc!=5 ){
|
||||||
@@ -767,17 +767,17 @@ static int test_step(
|
|||||||
}
|
}
|
||||||
if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
|
if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
|
||||||
rc = sqlite_step(vm, &N, &azValue, &azColName);
|
rc = sqlite_step(vm, &N, &azValue, &azColName);
|
||||||
if( rc==SQLITE_DONE || rc==SQLITE_ROW ){
|
|
||||||
sprintf(zBuf, "%d", N);
|
sprintf(zBuf, "%d", N);
|
||||||
Tcl_SetVar(interp, argv[2], zBuf, 0);
|
Tcl_SetVar(interp, argv[2], zBuf, 0);
|
||||||
Tcl_SetVar(interp, argv[3], "", 0);
|
Tcl_SetVar(interp, argv[3], "", 0);
|
||||||
if( rc==SQLITE_ROW ){
|
if( azValue ){
|
||||||
for(i=0; i<N; i++){
|
for(i=0; i<N; i++){
|
||||||
Tcl_SetVar(interp, argv[3], azValue[i] ? azValue[i] : "",
|
Tcl_SetVar(interp, argv[3], azValue[i] ? azValue[i] : "",
|
||||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tcl_SetVar(interp, argv[4], "", 0);
|
Tcl_SetVar(interp, argv[4], "", 0);
|
||||||
|
if( azColName ){
|
||||||
for(i=0; i<N*2; i++){
|
for(i=0; i<N*2; i++){
|
||||||
Tcl_SetVar(interp, argv[4], azColName[i] ? azColName[i] : "",
|
Tcl_SetVar(interp, argv[4], azColName[i] ? azColName[i] : "",
|
||||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||||
|
22
src/vdbe.c
22
src/vdbe.c
@@ -36,7 +36,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.202 2003/01/29 18:46:53 drh Exp $
|
** $Id: vdbe.c,v 1.203 2003/01/29 22:58:26 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -738,8 +738,8 @@ int sqlite_aggregate_count(sqlite_func *p){
|
|||||||
/*
|
/*
|
||||||
** Advance the virtual machine to the next output row.
|
** Advance the virtual machine to the next output row.
|
||||||
**
|
**
|
||||||
** The return vale will be either SQLITE_BUSY, SQLITE_DONE, or
|
** The return vale will be either SQLITE_BUSY, SQLITE_DONE,
|
||||||
** SQLITE_ROW.
|
** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE.
|
||||||
**
|
**
|
||||||
** SQLITE_BUSY means that the virtual machine attempted to open
|
** SQLITE_BUSY means that the virtual machine attempted to open
|
||||||
** a locked database and there is no busy callback registered.
|
** a locked database and there is no busy callback registered.
|
||||||
@@ -759,9 +759,16 @@ int sqlite_aggregate_count(sqlite_func *p){
|
|||||||
** The name of the i-th column is (*pazColName)[i] and the datatype
|
** The name of the i-th column is (*pazColName)[i] and the datatype
|
||||||
** of the i-th column is (*pazColName)[i+*pN].
|
** of the i-th column is (*pazColName)[i+*pN].
|
||||||
**
|
**
|
||||||
** If a run-time error is encountered, SQLITE_DONE is returned. You
|
** SQLITE_ERROR means that a run-time error (such as a constraint
|
||||||
** can access the error code and error message using the sqlite_finalize()
|
** violation) has occurred. The details of the error will be returned
|
||||||
** routine.
|
** by the next call to sqlite_finalize(). sqlite_step() should not
|
||||||
|
** be called again on the VM.
|
||||||
|
**
|
||||||
|
** SQLITE_MISUSE means that the this routine was called inappropriately.
|
||||||
|
** Perhaps it was called on a virtual machine that had already been
|
||||||
|
** finalized or on one that had previously returned SQLITE_ERROR or
|
||||||
|
** SQLITE_DONE. Or it could be the case the the same database connection
|
||||||
|
** is being used simulataneously by two or more threads.
|
||||||
*/
|
*/
|
||||||
int sqlite_step(
|
int sqlite_step(
|
||||||
sqlite_vm *pVm, /* The virtual machine to execute */
|
sqlite_vm *pVm, /* The virtual machine to execute */
|
||||||
@@ -1588,7 +1595,8 @@ int sqliteVdbeExec(
|
|||||||
|
|
||||||
if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
|
if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
|
||||||
assert( db->magic==SQLITE_MAGIC_BUSY );
|
assert( db->magic==SQLITE_MAGIC_BUSY );
|
||||||
assert( p->rc==SQLITE_OK );
|
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
|
||||||
|
p->rc = SQLITE_OK;
|
||||||
assert( p->explain==0 );
|
assert( p->explain==0 );
|
||||||
if( sqlite_malloc_failed ) goto no_mem;
|
if( sqlite_malloc_failed ) goto no_mem;
|
||||||
if( p->popStack ){
|
if( p->popStack ){
|
||||||
|
217
test/capi2.test
217
test/capi2.test
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script testing the callback-free C/C++ API.
|
# focus of this script testing the callback-free C/C++ API.
|
||||||
#
|
#
|
||||||
# $Id: capi2.test,v 1.2 2003/01/29 18:46:54 drh Exp $
|
# $Id: capi2.test,v 1.3 2003/01/29 22:58:27 drh Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@@ -55,7 +55,7 @@ do_test capi2-1.8 {
|
|||||||
} {SQLITE_MISUSE}
|
} {SQLITE_MISUSE}
|
||||||
do_test capi2-1.9 {
|
do_test capi2-1.9 {
|
||||||
list $N $VALUES $COLNAMES
|
list $N $VALUES $COLNAMES
|
||||||
} {x y z}
|
} {0 {} {}}
|
||||||
do_test capi2-1.10 {
|
do_test capi2-1.10 {
|
||||||
sqlite_finalize $VM
|
sqlite_finalize $VM
|
||||||
} {}
|
} {}
|
||||||
@@ -175,6 +175,219 @@ do_test capi2-3.13 {
|
|||||||
do_test capi2-3.14 {
|
do_test capi2-3.14 {
|
||||||
list [catch {sqlite_finalize $VM} msg] [set msg]
|
list [catch {sqlite_finalize $VM} msg] [set msg]
|
||||||
} {1 {(19) uniqueness constraint failed}}
|
} {1 {(19) uniqueness constraint failed}}
|
||||||
|
do_test capi2-3.15 {
|
||||||
|
set VM [sqlite_compile $DB {CREATE TABLE t2(a NOT NULL, b)} TAIL]
|
||||||
|
set TAIL
|
||||||
|
} {}
|
||||||
|
do_test capi2-3.16 {
|
||||||
|
list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_DONE 0 {} {}}
|
||||||
|
do_test capi2-3.17 {
|
||||||
|
list [catch {sqlite_finalize $VM} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
do_test capi2-3.18 {
|
||||||
|
set VM [sqlite_compile $DB {INSERT INTO t2 VALUES(NULL,2)} TAIL]
|
||||||
|
list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ERROR 0 {} {}}
|
||||||
|
do_test capi2-3.19 {
|
||||||
|
list [catch {sqlite_finalize $VM} msg] [set msg]
|
||||||
|
} {1 {(19) t2.a may not be NULL}}
|
||||||
|
|
||||||
|
# Two or more virtual machines exists at the same time.
|
||||||
|
#
|
||||||
|
do_test capi2-4.1 {
|
||||||
|
set VM1 [sqlite_compile $DB {INSERT INTO t2 VALUES(1,2)} TAIL]
|
||||||
|
set TAIL
|
||||||
|
} {}
|
||||||
|
do_test capi2-4.2 {
|
||||||
|
set VM2 [sqlite_compile $DB {INSERT INTO t2 VALUES(2,3)} TAIL]
|
||||||
|
set TAIL
|
||||||
|
} {}
|
||||||
|
do_test capi2-4.3 {
|
||||||
|
set VM3 [sqlite_compile $DB {INSERT INTO t2 VALUES(3,4)} TAIL]
|
||||||
|
set TAIL
|
||||||
|
} {}
|
||||||
|
do_test capi2-4.4 {
|
||||||
|
list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_DONE 0 {} {}}
|
||||||
|
do_test capi2-4.5 {
|
||||||
|
execsql {SELECT * FROM t2 ORDER BY a}
|
||||||
|
} {2 3}
|
||||||
|
do_test capi2-4.6 {
|
||||||
|
list [catch {sqlite_finalize $VM2} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
do_test capi2-4.7 {
|
||||||
|
list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_DONE 0 {} {}}
|
||||||
|
do_test capi2-4.8 {
|
||||||
|
execsql {SELECT * FROM t2 ORDER BY a}
|
||||||
|
} {2 3 3 4}
|
||||||
|
do_test capi2-4.9 {
|
||||||
|
list [catch {sqlite_finalize $VM3} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
do_test capi2-4.10 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_DONE 0 {} {}}
|
||||||
|
do_test capi2-4.11 {
|
||||||
|
execsql {SELECT * FROM t2 ORDER BY a}
|
||||||
|
} {1 2 2 3 3 4}
|
||||||
|
do_test capi2-4.12 {
|
||||||
|
list [catch {sqlite_finalize $VM1} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
|
||||||
|
# Interleaved SELECTs
|
||||||
|
#
|
||||||
|
do_test capi2-5.1 {
|
||||||
|
set VM1 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
|
||||||
|
set VM2 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
|
||||||
|
set VM3 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
|
||||||
|
do_test capi2-5.2 {
|
||||||
|
list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
|
||||||
|
do_test capi2-5.3 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {3 4} {a b {} {}}}
|
||||||
|
do_test capi2-5.4 {
|
||||||
|
list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
|
||||||
|
do_test capi2-5.5 {
|
||||||
|
list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {3 4} {a b {} {}}}
|
||||||
|
do_test capi2-5.6 {
|
||||||
|
list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {1 2} {a b {} {}}}
|
||||||
|
do_test capi2-5.7 {
|
||||||
|
list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_DONE 2 {} {a b {} {}}}
|
||||||
|
do_test capi2-5.8 {
|
||||||
|
list [catch {sqlite_finalize $VM3} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
do_test capi2-5.9 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {1 2} {a b {} {}}}
|
||||||
|
do_test capi2-5.10 {
|
||||||
|
list [catch {sqlite_finalize $VM1} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
do_test capi2-5.11 {
|
||||||
|
list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {3 4} {a b {} {}}}
|
||||||
|
do_test capi2-5.12 {
|
||||||
|
list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 2 {1 2} {a b {} {}}}
|
||||||
|
do_test capi2-5.11 {
|
||||||
|
list [catch {sqlite_finalize $VM2} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
|
||||||
|
# Check for proper SQLITE_BUSY returns.
|
||||||
|
#
|
||||||
|
do_test capi2-6.1 {
|
||||||
|
execsql {
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE t3(x counter);
|
||||||
|
INSERT INTO t3 VALUES(1);
|
||||||
|
INSERT INTO t3 VALUES(2);
|
||||||
|
INSERT INTO t3 SELECT x+2 FROM t3;
|
||||||
|
INSERT INTO t3 SELECT x+4 FROM t3;
|
||||||
|
INSERT INTO t3 SELECT x+8 FROM t3;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
set VM1 [sqlite_compile $DB {SELECT * FROM t3} TAIL]
|
||||||
|
sqlite db2 test.db
|
||||||
|
execsql {BEGIN} db2
|
||||||
|
} {}
|
||||||
|
do_test capi2-6.2 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_BUSY 0 {} {}}
|
||||||
|
do_test capi2-6.3 {
|
||||||
|
execsql {COMMIT} db2
|
||||||
|
} {}
|
||||||
|
do_test capi2-6.4 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 1 {x counter}}
|
||||||
|
do_test capi2-6.5 {
|
||||||
|
catchsql {BEGIN} db2
|
||||||
|
} {1 {database is locked}}
|
||||||
|
do_test capi2-6.6 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 2 {x counter}}
|
||||||
|
do_test capi2-6.7 {
|
||||||
|
execsql {SELECT * FROM t2} db2
|
||||||
|
} {2 3 3 4 1 2}
|
||||||
|
do_test capi2-6.8 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 3 {x counter}}
|
||||||
|
do_test capi2-6.9 {
|
||||||
|
execsql {SELECT * FROM t2}
|
||||||
|
} {2 3 3 4 1 2}
|
||||||
|
do_test capi2-6.10 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 4 {x counter}}
|
||||||
|
do_test capi2-6.11 {
|
||||||
|
execsql {BEGIN}
|
||||||
|
} {}
|
||||||
|
do_test capi2-6.12 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 5 {x counter}}
|
||||||
|
# execsql {pragma vdbe_trace=on}
|
||||||
|
do_test capi2-6.13 {
|
||||||
|
catchsql {UPDATE t3 SET x=x+1}
|
||||||
|
} {1 {database table is locked}}
|
||||||
|
do_test capi2-6.14 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 6 {x counter}}
|
||||||
|
# puts [list [catch {sqlite_finalize $VM1} msg] [set msg]]; exit
|
||||||
|
do_test capi2-6.15 {
|
||||||
|
execsql {SELECT * FROM t1}
|
||||||
|
} {1 2 3}
|
||||||
|
do_test capi2-6.16 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 7 {x counter}}
|
||||||
|
do_test capi2-6.17 {
|
||||||
|
catchsql {UPDATE t1 SET b=b+1}
|
||||||
|
} {0 {}}
|
||||||
|
do_test capi2-6.18 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 8 {x counter}}
|
||||||
|
do_test capi2-6.19 {
|
||||||
|
execsql {SELECT * FROM t1}
|
||||||
|
} {1 3 3}
|
||||||
|
do_test capi2-6.20 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 9 {x counter}}
|
||||||
|
do_test capi2-6.21 {
|
||||||
|
execsql {ROLLBACK; SELECT * FROM t1}
|
||||||
|
} {1 2 3}
|
||||||
|
do_test capi2-6.22 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 10 {x counter}}
|
||||||
|
do_test capi2-6.23 {
|
||||||
|
execsql {BEGIN TRANSACTION ON CONFLICT ROLLBACK;}
|
||||||
|
} {}
|
||||||
|
do_test capi2-6.24 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 11 {x counter}}
|
||||||
|
do_test capi2-6.25 {
|
||||||
|
execsql {
|
||||||
|
INSERT INTO t1 VALUES(2,3,4);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 2 3 2 3 4}
|
||||||
|
do_test capi2-6.26 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 12 {x counter}}
|
||||||
|
do_test capi2-6.27 {
|
||||||
|
catchsql {
|
||||||
|
INSERT INTO t1 VALUES(2,4,5);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 {uniqueness constraint failed}}
|
||||||
|
do_test capi2-6.28 {
|
||||||
|
list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
|
||||||
|
} {SQLITE_ROW 1 13 {x counter}}
|
||||||
|
do_test capi2-6.99 {
|
||||||
|
list [catch {sqlite_finalize $VM1} msg] [set msg]
|
||||||
|
} {0 {}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Run this Tcl script to generate the sqlite.html file.
|
# Run this Tcl script to generate the sqlite.html file.
|
||||||
#
|
#
|
||||||
set rcsid {$Id: c_interface.tcl,v 1.35 2002/08/24 18:24:57 drh Exp $}
|
set rcsid {$Id: c_interface.tcl,v 1.36 2003/01/29 22:58:27 drh Exp $}
|
||||||
|
|
||||||
puts {<html>
|
puts {<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -20,7 +20,7 @@ puts {
|
|||||||
a C or C++ program. This document gives an overview of the C/C++
|
a C or C++ program. This document gives an overview of the C/C++
|
||||||
programming interface.</p>
|
programming interface.</p>
|
||||||
|
|
||||||
<h2>The Core API</h2>
|
<h2>1.0 The Core API</h2>
|
||||||
|
|
||||||
<p>The interface to the SQLite library consists of three core functions,
|
<p>The interface to the SQLite library consists of three core functions,
|
||||||
one opaque data structure, and some constants used as return values.
|
one opaque data structure, and some constants used as return values.
|
||||||
@@ -32,26 +32,28 @@ typedef struct sqlite sqlite;
|
|||||||
|
|
||||||
sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);
|
sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);
|
||||||
|
|
||||||
void sqlite_close(sqlite*);
|
void sqlite_close(sqlite *db);
|
||||||
|
|
||||||
int sqlite_exec(
|
int sqlite_exec(
|
||||||
sqlite*,
|
sqlite *db,
|
||||||
char *sql,
|
char *sql,
|
||||||
int (*)(void*,int,char**,char**),
|
int (*xCallback)(void*,int,char**,char**),
|
||||||
void*,
|
void *pArg,
|
||||||
char **errmsg
|
char **errmsg
|
||||||
);
|
);
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The above is all you really need to know in order to use SQLite
|
The above is all you really need to know in order to use SQLite
|
||||||
in your C or C++ programs. There are other convenience functions
|
in your C or C++ programs. There are other interface functions
|
||||||
available (and described below) but we will begin by describing
|
available (and described below) but we will begin by describing
|
||||||
the core functions shown above.
|
the core functions shown above.
|
||||||
</p>
|
</p>
|
||||||
<h2>Opening a database</h2>
|
|
||||||
|
|
||||||
<p>Use the <b>sqlite_open()</b> function to open an existing SQLite
|
<a name="sqlite_open">
|
||||||
|
<h3>1.1 Opening a database</h3>
|
||||||
|
|
||||||
|
<p>Use the <b>sqlite_open</b> function to open an existing SQLite
|
||||||
database or to create a new SQLite database. The first argument
|
database or to create a new SQLite database. The first argument
|
||||||
is the database name. The second argument is intended to signal
|
is the database name. The second argument is intended to signal
|
||||||
whether the database is going to be used for reading and writing
|
whether the database is going to be used for reading and writing
|
||||||
@@ -74,28 +76,30 @@ additional temporary files may be created during the execution of
|
|||||||
an SQL command in order to store the database rollback journal or
|
an SQL command in order to store the database rollback journal or
|
||||||
temporary and intermediate results of a query.</p>
|
temporary and intermediate results of a query.</p>
|
||||||
|
|
||||||
<p>The return value of the <b>sqlite_open()</b> function is a
|
<p>The return value of the <b>sqlite_open</b> function is a
|
||||||
pointer to an opaque <b>sqlite</b> structure. This pointer will
|
pointer to an opaque <b>sqlite</b> structure. This pointer will
|
||||||
be the first argument to all subsequent SQLite function calls that
|
be the first argument to all subsequent SQLite function calls that
|
||||||
deal with the same database. NULL is returned if the open fails
|
deal with the same database. NULL is returned if the open fails
|
||||||
for any reason.</p>
|
for any reason.</p>
|
||||||
|
|
||||||
<h2>Closing the database</h2>
|
<a name="sqlite_close">
|
||||||
|
<h3>1.2 Closing the database</h3>
|
||||||
|
|
||||||
<p>To close an SQLite database, call the <b>sqlite_close()</b>
|
<p>To close an SQLite database, call the <b>sqlite_close</b>
|
||||||
function passing it the sqlite structure pointer that was obtained
|
function passing it the sqlite structure pointer that was obtained
|
||||||
from a prior call to <b>sqlite_open</b>.
|
from a prior call to <b>sqlite_open</b>.
|
||||||
If a transaction is active when the database is closed, the transaction
|
If a transaction is active when the database is closed, the transaction
|
||||||
is rolled back.</p>
|
is rolled back.</p>
|
||||||
|
|
||||||
<h2>Executing SQL statements</h2>
|
<a name="sqlite_exec">
|
||||||
|
<h3>1.3 Executing SQL statements</h3>
|
||||||
|
|
||||||
<p>The <b>sqlite_exec()</b> function is used to process SQL statements
|
<p>The <b>sqlite_exec</b> function is used to process SQL statements
|
||||||
and queries. This function requires 5 parameters as follows:</p>
|
and queries. This function requires 5 parameters as follows:</p>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li><p>A pointer to the sqlite structure obtained from a prior call
|
<li><p>A pointer to the sqlite structure obtained from a prior call
|
||||||
to <b>sqlite_open()</b>.</p></li>
|
to <b>sqlite_open</b>.</p></li>
|
||||||
<li><p>A null-terminated string containing the text of one or more
|
<li><p>A null-terminated string containing the text of one or more
|
||||||
SQL statements and/or queries to be processed.</p></li>
|
SQL statements and/or queries to be processed.</p></li>
|
||||||
<li><p>A pointer to a callback function which is invoked once for each
|
<li><p>A pointer to a callback function which is invoked once for each
|
||||||
@@ -121,8 +125,9 @@ int Callback(void *pArg, int argc, char **argv, char **columnNames){
|
|||||||
}
|
}
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
|
|
||||||
|
<a name="callback_row_data">
|
||||||
<p>The first argument to the callback is just a copy of the fourth argument
|
<p>The first argument to the callback is just a copy of the fourth argument
|
||||||
to <b>sqlite_exec()</b> This parameter can be used to pass arbitrary
|
to <b>sqlite_exec</b> This parameter can be used to pass arbitrary
|
||||||
information through to the callback function from client code.
|
information through to the callback function from client code.
|
||||||
The second argument is the number of columns in the query result.
|
The second argument is the number of columns in the query result.
|
||||||
The third argument is an array of pointers to strings where each string
|
The third argument is an array of pointers to strings where each string
|
||||||
@@ -137,9 +142,17 @@ argv[i][0] == 0
|
|||||||
<blockquote><pre>
|
<blockquote><pre>
|
||||||
argv[i] == 0
|
argv[i] == 0
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
<p>The names of the columns are contained in the fourth argument.</p>
|
|
||||||
|
|
||||||
<p>If the EMPTY_RESULT_CALLBACKS pragma is set to ON and the result of
|
<p>The names of the columns are contained in first <i>argc</i>
|
||||||
|
entries of the fourth argument.
|
||||||
|
If the <a href="lang.html#pragma_show_datatypes">SHOW_DATATYPES</a> pragma
|
||||||
|
is on (it is off by default) then
|
||||||
|
the second <i>argc</i> entries in the 4th argument are the datatypes
|
||||||
|
for the corresponding columns.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>If the <a href="lang.html#pragma_empty_result_callbacks">
|
||||||
|
EMPTY_RESULT_CALLBACKS</a> pragma is set to ON and the result of
|
||||||
a query is an empty set, then the callback is invoked once with the
|
a query is an empty set, then the callback is invoked once with the
|
||||||
third parameter (argv) set to 0. In other words
|
third parameter (argv) set to 0. In other words
|
||||||
<blockquote><pre>
|
<blockquote><pre>
|
||||||
@@ -152,14 +165,15 @@ columns if there had been a result.
|
|||||||
The default behavior is not to invoke the callback at all if the
|
The default behavior is not to invoke the callback at all if the
|
||||||
result set is empty.</p>
|
result set is empty.</p>
|
||||||
|
|
||||||
|
<a name="callback_returns_nonzero">
|
||||||
<p>The callback function should normally return 0. If the callback
|
<p>The callback function should normally return 0. If the callback
|
||||||
function returns non-zero, the query is immediately aborted and
|
function returns non-zero, the query is immediately aborted and
|
||||||
<b>sqlite_exec()</b> will return SQLITE_ABORT.</p>
|
<b>sqlite_exec</b> will return SQLITE_ABORT.</p>
|
||||||
|
|
||||||
<h2>Error Codes</h2>
|
<h3>1.4 Error Codes</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The <b>sqlite_exec()</b> function normally returns SQLITE_OK. But
|
The <b>sqlite_exec</b> function normally returns SQLITE_OK. But
|
||||||
if something goes wrong it can return a different value to indicate
|
if something goes wrong it can return a different value to indicate
|
||||||
the type of error. Here is a complete list of the return codes:
|
the type of error. Here is a complete list of the return codes:
|
||||||
</p>
|
</p>
|
||||||
@@ -187,6 +201,10 @@ the type of error. Here is a complete list of the return codes:
|
|||||||
#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */
|
#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */
|
||||||
#define SQLITE_MISMATCH 20 /* Data type mismatch */
|
#define SQLITE_MISMATCH 20 /* Data type mismatch */
|
||||||
#define SQLITE_MISUSE 21 /* Library used incorrectly */
|
#define SQLITE_MISUSE 21 /* Library used incorrectly */
|
||||||
|
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
|
||||||
|
#define SQLITE_AUTH 23 /* Authorization denied */
|
||||||
|
#define SQLITE_ROW 100 /* sqlite_step() has another row ready */
|
||||||
|
#define SQLITE_DONE 101 /* sqlite_step() has finished executing */
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -202,12 +220,12 @@ The meanings of these various return values are as follows:
|
|||||||
<dd><p>This value indicates that an internal consistency check within
|
<dd><p>This value indicates that an internal consistency check within
|
||||||
the SQLite library failed. This can only happen if there is a bug in
|
the SQLite library failed. This can only happen if there is a bug in
|
||||||
the SQLite library. If you ever get an SQLITE_INTERNAL reply from
|
the SQLite library. If you ever get an SQLITE_INTERNAL reply from
|
||||||
an <b>sqlite_exec()</b> call, please report the problem on the SQLite
|
an <b>sqlite_exec</b> call, please report the problem on the SQLite
|
||||||
mailing list.
|
mailing list.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
<dt>SQLITE_ERROR</dt>
|
<dt>SQLITE_ERROR</dt>
|
||||||
<dd><p>This return value indicates that there was an error in the SQL
|
<dd><p>This return value indicates that there was an error in the SQL
|
||||||
that was passed into the <b>sqlite_exec()</b>.
|
that was passed into the <b>sqlite_exec</b>.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
<dt>SQLITE_PERM</dt>
|
<dt>SQLITE_PERM</dt>
|
||||||
<dd><p>This return value says that the access permissions on the database
|
<dd><p>This return value says that the access permissions on the database
|
||||||
@@ -226,21 +244,21 @@ entire database.</p>
|
|||||||
<dt>SQLITE_LOCKED</dt>
|
<dt>SQLITE_LOCKED</dt>
|
||||||
<dd><p>This return code is similar to SQLITE_BUSY in that it indicates
|
<dd><p>This return code is similar to SQLITE_BUSY in that it indicates
|
||||||
that the database is locked. But the source of the lock is a recursive
|
that the database is locked. But the source of the lock is a recursive
|
||||||
call to <b>sqlite_exec()</b>. This return can only occur if you attempt
|
call to <b>sqlite_exec</b>. This return can only occur if you attempt
|
||||||
to invoke sqlite_exec() from within a callback routine of a query
|
to invoke sqlite_exec from within a callback routine of a query
|
||||||
from a prior invocation of sqlite_exec(). Recursive calls to
|
from a prior invocation of sqlite_exec. Recursive calls to
|
||||||
sqlite_exec() are allowed as long as they do
|
sqlite_exec are allowed as long as they do
|
||||||
not attempt to write the same table.
|
not attempt to write the same table.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
<dt>SQLITE_NOMEM</dt>
|
<dt>SQLITE_NOMEM</dt>
|
||||||
<dd><p>This value is returned if a call to <b>malloc()</b> fails.
|
<dd><p>This value is returned if a call to <b>malloc</b> fails.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
<dt>SQLITE_READONLY</dt>
|
<dt>SQLITE_READONLY</dt>
|
||||||
<dd><p>This return code indicates that an attempt was made to write to
|
<dd><p>This return code indicates that an attempt was made to write to
|
||||||
a database file that is opened for reading only.
|
a database file that is opened for reading only.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
<dt>SQLITE_INTERRUPT</dt>
|
<dt>SQLITE_INTERRUPT</dt>
|
||||||
<dd><p>This value is returned if a call to <b>sqlite_interrupt()</b>
|
<dd><p>This value is returned if a call to <b>sqlite_interrupt</b>
|
||||||
interrupts a database operation in progress.
|
interrupts a database operation in progress.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
<dt>SQLITE_IOERR</dt>
|
<dt>SQLITE_IOERR</dt>
|
||||||
@@ -298,16 +316,249 @@ an INTEGER PRIMARY KEY column is only allowed to store integer data.
|
|||||||
<dt>SQLITE_MISUSE</dt>
|
<dt>SQLITE_MISUSE</dt>
|
||||||
<dd><p>This error might occur if one or more of the SQLite API routines
|
<dd><p>This error might occur if one or more of the SQLite API routines
|
||||||
is used incorrectly. Examples of incorrect usage include calling
|
is used incorrectly. Examples of incorrect usage include calling
|
||||||
<b>sqlite_exec()</b> after the database has been closed using
|
<b>sqlite_exec</b> after the database has been closed using
|
||||||
<b>sqlite_close()</b> or calling <b>sqlite_exec()</b> with the same
|
<b>sqlite_close</b> or
|
||||||
|
calling <b>sqlite_exec</b> with the same
|
||||||
database pointer simultaneously from two separate threads.
|
database pointer simultaneously from two separate threads.
|
||||||
</p></dd>
|
</p></dd>
|
||||||
|
<dt>SQLITE_NOLFS</dt>
|
||||||
|
<dd><p>This error means that you have attempts to create or access a file
|
||||||
|
database file that is larger that 2GB on a legacy Unix machine that
|
||||||
|
lacks large file support.
|
||||||
|
</p></dd>
|
||||||
|
<dt>SQLITE_AUTH</dt>
|
||||||
|
<dd><p>This error indicates that the authorizer callback
|
||||||
|
has disallowed the SQL you are attempting to execute.
|
||||||
|
</p></dd>
|
||||||
|
<dt>SQLITE_ROW</dt>
|
||||||
|
<dd><p>This is one of the return codes from the
|
||||||
|
<b>sqlite_step</b> routine which is part of the non-callback API.
|
||||||
|
It indicates that another row of result data is available.
|
||||||
|
</p></dd>
|
||||||
|
<dt>SQLITE_DONE</dt>
|
||||||
|
<dd><p>This is one of the return codes from the
|
||||||
|
<b>sqlite_step</b> routine which is part of the non-callback API.
|
||||||
|
It indicates that the SQL statement has been completely executed and
|
||||||
|
the <b>sqlite_finalize</b> routine is ready to be called.
|
||||||
|
</p></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h2>The Extended API</h2>
|
<h2>2.0 Accessing Data Without Using A Callback Function</h2>
|
||||||
|
|
||||||
<p>Only the three core routines shown above are required to use
|
<p>
|
||||||
|
The <b>sqlite_exec</b> routine described above used to be the only
|
||||||
|
way to retrieve data from an SQLite database. But many programmers found
|
||||||
|
it inconvenient to use a callback function to obtain results. So beginning
|
||||||
|
with SQLite version 2.7.7, a second access interface is available that
|
||||||
|
does not use callbacks.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The new interface uses three separate functions to replace the single
|
||||||
|
<b>sqlite_exec</b> function.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<blockquote><pre>
|
||||||
|
typedef struct sqlite_vm sqlite_vm;
|
||||||
|
|
||||||
|
int sqlite_compile(
|
||||||
|
sqlite *db, /* The open database */
|
||||||
|
const char *zSql, /* SQL statement to be compiled */
|
||||||
|
const char **pzTail, /* OUT: uncompiled tail of zSql */
|
||||||
|
sqlite_vm **ppVm, /* OUT: the virtual machine to execute zSql */
|
||||||
|
char **pzErrmsg /* OUT: Error message. */
|
||||||
|
);
|
||||||
|
|
||||||
|
int sqlite_step(
|
||||||
|
sqlite_vm *pVm, /* The virtual machine to execute */
|
||||||
|
int *pN, /* OUT: Number of columns in result */
|
||||||
|
const char ***pazValue, /* OUT: Column data */
|
||||||
|
const char ***pazColName /* OUT: Column names and datatypes */
|
||||||
|
);
|
||||||
|
|
||||||
|
int sqlite_finalize(
|
||||||
|
sqlite_vm *pVm, /* The virtual machine to be finalized */
|
||||||
|
char **pzErrMsg /* OUT: Error message */
|
||||||
|
);
|
||||||
|
</pre></blockquote>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The strategy is to compile a single SQL statement using
|
||||||
|
<b>sqlite_compile</b> then invoke <b>sqlite_step</b> multiple times,
|
||||||
|
once for each row of output, and finally call <b>sqlite_finalize</b>
|
||||||
|
to clean up after the SQL has finished execution.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>2.1 Compiling An SQL Statement Into A Virtual Machine</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <b>sqlite_compile</b> "compiles" a single SQL statement (specified
|
||||||
|
by the second parameter) and generates a virtual machine that is able
|
||||||
|
to execute that statement.
|
||||||
|
As with must interface routines, the first parameter must be a pointer
|
||||||
|
to an sqlite structure that was obtained from a prior call to
|
||||||
|
<b>sqlite_open</b>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A pointer to the virtual machine is stored in a pointer which is passed
|
||||||
|
in as the 4th parameter.
|
||||||
|
Space to hold the virtual machine is dynamically allocated. To avoid
|
||||||
|
a memory leak, the calling function must invoke
|
||||||
|
<b>sqlite_finalize</b> on the virtual machine after it has finished
|
||||||
|
with it.
|
||||||
|
The 4th parameter may be set to NULL if an error is encountered during
|
||||||
|
compilation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If any errors are encountered during compilation, an error message is
|
||||||
|
written into memory obtained from <b>malloc</b> and the 5th parameter
|
||||||
|
is made to point to that memory. If the 5th parameter is NULL, then
|
||||||
|
no error message is generated. If the 5th parameter is not NULL, then
|
||||||
|
the calling function should dispose of the memory containing the error
|
||||||
|
message by calling <b>sqlite_freemem</b>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If the 2nd parameter actually contains two or more statements of SQL,
|
||||||
|
only the first statement is compiled. (This is different from the
|
||||||
|
behavior of <b>sqlite_exec</b> which executes all SQL statements
|
||||||
|
in its input string.) The 3rd parameter to <b>sqlite_compile</b>
|
||||||
|
is made to point to the first character beyond the end of the first
|
||||||
|
statement of SQL in the input. If the 2nd parameter contains only
|
||||||
|
a single SQL statement, then the 3rd parameter will be made to point
|
||||||
|
to the '\000' terminator at the end of the 2nd parameter.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
On success, <b>sqlite_compile</b> returns SQLITE_OK.
|
||||||
|
Otherwise and error code is returned.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>2.2 Step-By-Step Execution Of An SQL Statement</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
After a virtual machine has been generated using <b>sqlite_compile</b>
|
||||||
|
it is executed by one or more calls to <b>sqlite_step</b>. Each
|
||||||
|
invocation of <b>sqlite_step</b>, except the last one,
|
||||||
|
returns a single row of the result.
|
||||||
|
The number of columns in the result is stored in the integer that
|
||||||
|
the 2nd parameter points to.
|
||||||
|
The pointer specified by the 3rd parameter is made to point
|
||||||
|
to an array of pointers to column values.
|
||||||
|
The pointer in the 4th parameter is made to point to an array
|
||||||
|
of pointers to column names and datatypes.
|
||||||
|
The 2nd through 4th parameters to <b>sqlite_step</b> convey the
|
||||||
|
same information as the 2nd through 4th parameters of the
|
||||||
|
<b>callback</b> routine when using
|
||||||
|
the <b>sqlite_exec</b> interface. Except, with <b>sqlite_step</b>
|
||||||
|
the column datatype information is always included in the in the
|
||||||
|
4th parameter regardless of whether or not the
|
||||||
|
<a href="lang.html#pragma_show_datatypes">SHOW_DATATYPES</a> pragma
|
||||||
|
is on or off.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Each invocation of <b>sqlite_step</b> returns an integer code that
|
||||||
|
indicates what happened during that step. This code may be
|
||||||
|
SQLITE_BUSY, SQLITE_ROW, SQLITE_DONE, SQLITE_ERROR, or
|
||||||
|
SQLITE_MISUSE.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If the virtual machine is unable to open the database file because
|
||||||
|
it is locked by another thread or process, <b>sqlite_step</b>
|
||||||
|
will return SQLITE_BUSY. The calling function should do some other
|
||||||
|
activity, or sleep, for a short amount of time to give the lock a
|
||||||
|
chance to clear, then invoke <b>sqlite_step</b> again. This can
|
||||||
|
be repeated as many times as desired.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Whenever another row of result data is available,
|
||||||
|
<b>sqlite_step</b> will return SQLITE_ROW. The row data is
|
||||||
|
stored in an array of pointers to strings and the 2nd parameter
|
||||||
|
is made to point to this array.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When all processing is complete, <b>sqlite_step</b> will return
|
||||||
|
either SQLITE_DONE or SQLITE_ERROR. SQLITE_DONE indicates that the
|
||||||
|
statement completed successfully and SQLITE_ERROR indicates that there
|
||||||
|
was a run-time error. (The details of the error are obtained from
|
||||||
|
<b>sqlite_finalize</b>.) It is a misuse of the library to attempt
|
||||||
|
to call <b>sqlite_step</b> again after it has returned SQLITE_DONE
|
||||||
|
or SQLITE_ERROR.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When <b>sqlite_step</b> returns SQLITE_DONE or SQLITE_ERROR,
|
||||||
|
the *pN and *pazColName values are set to the number of columns
|
||||||
|
in the result set and to the names of the columns, just as they
|
||||||
|
are for an SQLITE_ROW return. This allows the calling code to
|
||||||
|
find the number of result columns and the column names and datatypes
|
||||||
|
even if the result set is empty. The *pazValue parameter is always
|
||||||
|
set to NULL when the return codes is SQLITE_DONE or SQLITE_ERROR.
|
||||||
|
If the SQL being executed is a statement that does not
|
||||||
|
return a result (such as an INSERT or an UPDATE) then *pN will
|
||||||
|
be set to zero and *pazColName will be set to NULL.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you abuse the library by trying to call <b>sqlite_step</b>
|
||||||
|
inappropriately it will attempt return SQLITE_MISUSE.
|
||||||
|
This can happen if you call sqlite_step() on the same virtual machine
|
||||||
|
at the same
|
||||||
|
time from two or more threads or if you call sqlite_step()
|
||||||
|
again after it returned SQLITE_DONE or SQLITE_ERROR or if you
|
||||||
|
pass in an invalid virtual machine pointer to sqlite_step().
|
||||||
|
You should not depend on the SQLITE_MISUSE return code to indicate
|
||||||
|
an error. It is possible that a misuse of the interface will go
|
||||||
|
undetected and result in a program crash. The SQLITE_MISUSE is
|
||||||
|
intended as a debugging aid only - to help you detect incorrect
|
||||||
|
usage prior to a mishap. The misuse detection logic is not guaranteed
|
||||||
|
to work in every case.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>2.3 Deleting A Virtual Machine</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Every virtual machine that <b>sqlite_compile</b> creates should
|
||||||
|
eventually be handed to <b>sqlite_finalize</b>. The sqlite_finalize()
|
||||||
|
procedure deallocates the memory and other resources that the virtual
|
||||||
|
machine uses. Failure to call sqlite_finalize() will result in
|
||||||
|
resource leaks in your program.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <b>sqlite_finalize</b> routine also returns the result code
|
||||||
|
that indicates success or failure of the SQL operation that the
|
||||||
|
virtual machine carried out.
|
||||||
|
The value returned by sqlite_finalize() will be the same as would
|
||||||
|
have been returned had the same SQL been executed by <b>sqlite_exec</b>.
|
||||||
|
The error message returned will also be the same.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is acceptable to call <b>sqlite_finalize</b> on a virtual machine
|
||||||
|
before <b>sqlite_step</b> has returned SQLITE_DONE. Doing so has
|
||||||
|
the effect of interrupting the operation in progress. Partially completed
|
||||||
|
changes will be rolled back and the database will be restored to its
|
||||||
|
original state (unless an alternative recovery algorithm is selected using
|
||||||
|
an ON CONFLICT clause in the SQL being executed.) The effect is the
|
||||||
|
same as if a callback function of <b>sqlite_exec</b> had returned
|
||||||
|
non-zero.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is also acceptable to call <b>sqlite_finalize</b> on a virtual machine
|
||||||
|
that has never been passed to <b>sqlite_step</b> even once.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>3.0 The Extended API</h2>
|
||||||
|
|
||||||
|
<p>Only the three core routines described in section 1.0 are required to use
|
||||||
SQLite. But there are many other functions that provide
|
SQLite. But there are many other functions that provide
|
||||||
useful interfaces. These extended routines are as follows:
|
useful interfaces. These extended routines are as follows:
|
||||||
</p>
|
</p>
|
||||||
@@ -389,7 +640,7 @@ void sqlite_freemem(char*);
|
|||||||
<p>All of the above definitions are included in the "sqlite.h"
|
<p>All of the above definitions are included in the "sqlite.h"
|
||||||
header file that comes in the source tree.</p>
|
header file that comes in the source tree.</p>
|
||||||
|
|
||||||
<h2>The ROWID of the most recent insert</h2>
|
<h3>3.1 The ROWID of the most recent insert</h3>
|
||||||
|
|
||||||
<p>Every row of an SQLite table has a unique integer key. If the
|
<p>Every row of an SQLite table has a unique integer key. If the
|
||||||
table has a column labeled INTEGER PRIMARY KEY, then that column
|
table has a column labeled INTEGER PRIMARY KEY, then that column
|
||||||
@@ -403,33 +654,33 @@ KEY column, or if the table does have an INTEGER PRIMARY KEY but the value
|
|||||||
for that column is not specified in the VALUES clause of the insert, then
|
for that column is not specified in the VALUES clause of the insert, then
|
||||||
the key is automatically generated. You can find the value of the key
|
the key is automatically generated. You can find the value of the key
|
||||||
for the most recent INSERT statement using the
|
for the most recent INSERT statement using the
|
||||||
<b>sqlite_last_insert_rowid()</b> API function.</p>
|
<b>sqlite_last_insert_rowid</b> API function.</p>
|
||||||
|
|
||||||
<h2>The number of rows that changed</h2>
|
<h3>3.2 The number of rows that changed</h3>
|
||||||
|
|
||||||
<p>The <b>sqlite_changes()</b> API function returns the number of rows
|
<p>The <b>sqlite_changes</b> API function returns the number of rows
|
||||||
that were inserted, deleted, or modified during the most recent
|
that were inserted, deleted, or modified during the most recent
|
||||||
<b>sqlite_exec()</b> call. The number reported includes any changes
|
<b>sqlite_exec</b> call. The number reported includes any changes
|
||||||
that were later undone by a ROLLBACK or ABORT. But rows that are
|
that were later undone by a ROLLBACK or ABORT. But rows that are
|
||||||
deleted because of a DROP TABLE are <em>not</em> counted.</p>
|
deleted because of a DROP TABLE are <em>not</em> counted.</p>
|
||||||
|
|
||||||
<p>SQLite implements the command "<b>DELETE FROM table</b>" (without
|
<p>SQLite implements the command "<b>DELETE FROM table</b>" (without
|
||||||
a WHERE clause) by dropping the table then recreating it.
|
a WHERE clause) by dropping the table then recreating it.
|
||||||
This is much faster than deleting the elements of the table individually.
|
This is much faster than deleting the elements of the table individually.
|
||||||
But it also means that the value returned from <b>sqlite_changes()</b>
|
But it also means that the value returned from <b>sqlite_changes</b>
|
||||||
will be zero regardless of the number of elements that were originally
|
will be zero regardless of the number of elements that were originally
|
||||||
in the table. If an accurate count of the number of elements deleted
|
in the table. If an accurate count of the number of elements deleted
|
||||||
is necessary, use "<b>DELETE FROM table WHERE 1</b>" instead.</p>
|
is necessary, use "<b>DELETE FROM table WHERE 1</b>" instead.</p>
|
||||||
|
|
||||||
<h2>Querying without using a callback function</h2>
|
<h3>3.3 Querying into memory obtained from malloc()</h3>
|
||||||
|
|
||||||
<p>The <b>sqlite_get_table()</b> function is a wrapper around
|
<p>The <b>sqlite_get_table</b> function is a wrapper around
|
||||||
<b>sqlite_exec()</b> that collects all the information from successive
|
<b>sqlite_exec</b> that collects all the information from successive
|
||||||
callbacks and writes it into memory obtained from malloc(). This
|
callbacks and writes it into memory obtained from malloc(). This
|
||||||
is a convenience function that allows the application to get the
|
is a convenience function that allows the application to get the
|
||||||
entire result of a database query with a single function call.</p>
|
entire result of a database query with a single function call.</p>
|
||||||
|
|
||||||
<p>The main result from <b>sqlite_get_table()</b> is an array of pointers
|
<p>The main result from <b>sqlite_get_table</b> is an array of pointers
|
||||||
to strings. There is one element in this array for each column of
|
to strings. There is one element in this array for each column of
|
||||||
each row in the result. NULL results are represented by a NULL
|
each row in the result. NULL results are represented by a NULL
|
||||||
pointer. In addition to the regular data, there is an added row at the
|
pointer. In addition to the regular data, there is an added row at the
|
||||||
@@ -444,7 +695,7 @@ SELECT employee_name, login, host FROM users WHERE logic LIKE 'd%';
|
|||||||
|
|
||||||
<p>This query will return the name, login and host computer name
|
<p>This query will return the name, login and host computer name
|
||||||
for every employee whose login begins with the letter "d". If this
|
for every employee whose login begins with the letter "d". If this
|
||||||
query is submitted to <b>sqlite_get_table()</b> the result might
|
query is submitted to <b>sqlite_get_table</b> the result might
|
||||||
look like this:</p>
|
look like this:</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
@@ -465,7 +716,7 @@ result[8] = "zadok"
|
|||||||
the result[] array contains a NULL pointer at that slot.</p>
|
the result[] array contains a NULL pointer at that slot.</p>
|
||||||
|
|
||||||
<p>If the result set of a query is empty, then by default
|
<p>If the result set of a query is empty, then by default
|
||||||
<b>sqlite_get_table()</b> will set nrow to 0 and leave its
|
<b>sqlite_get_table</b> will set nrow to 0 and leave its
|
||||||
result parameter is set to NULL. But if the EMPTY_RESULT_CALLBACKS
|
result parameter is set to NULL. But if the EMPTY_RESULT_CALLBACKS
|
||||||
pragma is ON then the result parameter is initialized to the names
|
pragma is ON then the result parameter is initialized to the names
|
||||||
of the columns only. For example, consider this query which has
|
of the columns only. For example, consider this query which has
|
||||||
@@ -498,47 +749,47 @@ result[1] = "login"<br>
|
|||||||
result[2] = "host"<br>
|
result[2] = "host"<br>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>Memory to hold the information returned by <b>sqlite_get_table()</b>
|
<p>Memory to hold the information returned by <b>sqlite_get_table</b>
|
||||||
is obtained from malloc(). But the calling function should not try
|
is obtained from malloc(). But the calling function should not try
|
||||||
to free this information directly. Instead, pass the complete table
|
to free this information directly. Instead, pass the complete table
|
||||||
to <b>sqlite_free_table()</b> when the table is no longer needed.
|
to <b>sqlite_free_table</b> when the table is no longer needed.
|
||||||
It is safe to call <b>sqlite_free_table()</b> with a NULL pointer such
|
It is safe to call <b>sqlite_free_table</b> with a NULL pointer such
|
||||||
as would be returned if the result set is empty.</p>
|
as would be returned if the result set is empty.</p>
|
||||||
|
|
||||||
<p>The <b>sqlite_get_table()</b> routine returns the same integer
|
<p>The <b>sqlite_get_table</b> routine returns the same integer
|
||||||
result code as <b>sqlite_exec()</b>.</p>
|
result code as <b>sqlite_exec</b>.</p>
|
||||||
|
|
||||||
<h2>Interrupting an SQLite operation</h2>
|
<h3>3.4 Interrupting an SQLite operation</h3>
|
||||||
|
|
||||||
<p>The <b>sqlite_interrupt()</b> function can be called from a
|
<p>The <b>sqlite_interrupt</b> function can be called from a
|
||||||
different thread or from a signal handler to cause the current database
|
different thread or from a signal handler to cause the current database
|
||||||
operation to exit at its first opportunity. When this happens,
|
operation to exit at its first opportunity. When this happens,
|
||||||
the <b>sqlite_exec()</b> routine (or the equivalent) that started
|
the <b>sqlite_exec</b> routine (or the equivalent) that started
|
||||||
the database operation will return SQLITE_INTERRUPT.</p>
|
the database operation will return SQLITE_INTERRUPT.</p>
|
||||||
|
|
||||||
<h2>Testing for a complete SQL statement</h2>
|
<h3>3.5 Testing for a complete SQL statement</h3>
|
||||||
|
|
||||||
<p>The next interface routine to SQLite is a convenience function used
|
<p>The next interface routine to SQLite is a convenience function used
|
||||||
to test whether or not a string forms a complete SQL statement.
|
to test whether or not a string forms a complete SQL statement.
|
||||||
If the <b>sqlite_complete()</b> function returns true when its input
|
If the <b>sqlite_complete</b> function returns true when its input
|
||||||
is a string, then the argument forms a complete SQL statement.
|
is a string, then the argument forms a complete SQL statement.
|
||||||
There are no guarantees that the syntax of that statement is correct,
|
There are no guarantees that the syntax of that statement is correct,
|
||||||
but we at least know the statement is complete. If <b>sqlite_complete()</b>
|
but we at least know the statement is complete. If <b>sqlite_complete</b>
|
||||||
returns false, then more text is required to complete the SQL statement.</p>
|
returns false, then more text is required to complete the SQL statement.</p>
|
||||||
|
|
||||||
<p>For the purpose of the <b>sqlite_complete()</b> function, an SQL
|
<p>For the purpose of the <b>sqlite_complete</b> function, an SQL
|
||||||
statement is complete if it ends in a semicolon.</p>
|
statement is complete if it ends in a semicolon.</p>
|
||||||
|
|
||||||
<p>The <b>sqlite</b> command-line utility uses the <b>sqlite_complete()</b>
|
<p>The <b>sqlite</b> command-line utility uses the <b>sqlite_complete</b>
|
||||||
function to know when it needs to call <b>sqlite_exec()</b>. After each
|
function to know when it needs to call <b>sqlite_exec</b>. After each
|
||||||
line of input is received, <b>sqlite</b> calls <b>sqlite_complete()</b>
|
line of input is received, <b>sqlite</b> calls <b>sqlite_complete</b>
|
||||||
on all input in its buffer. If <b>sqlite_complete()</b> returns true,
|
on all input in its buffer. If <b>sqlite_complete</b> returns true,
|
||||||
then <b>sqlite_exec()</b> is called and the input buffer is reset. If
|
then <b>sqlite_exec</b> is called and the input buffer is reset. If
|
||||||
<b>sqlite_complete()</b> returns false, then the prompt is changed to
|
<b>sqlite_complete</b> returns false, then the prompt is changed to
|
||||||
the continuation prompt and another line of text is read and added to
|
the continuation prompt and another line of text is read and added to
|
||||||
the input buffer.</p>
|
the input buffer.</p>
|
||||||
|
|
||||||
<h2>Library version string</h2>
|
<h3>3.6 Library version string</h3>
|
||||||
|
|
||||||
<p>The SQLite library exports the string constant named
|
<p>The SQLite library exports the string constant named
|
||||||
<b>sqlite_version</b> which contains the version number of the
|
<b>sqlite_version</b> which contains the version number of the
|
||||||
@@ -548,7 +799,7 @@ the SQLITE_VERSION macro against the <b>sqlite_version</b>
|
|||||||
string constant to verify that the version number of the
|
string constant to verify that the version number of the
|
||||||
header file and the library match.</p>
|
header file and the library match.</p>
|
||||||
|
|
||||||
<h2>Library character encoding</h2>
|
<h3>3.7 Library character encoding</h3>
|
||||||
|
|
||||||
<p>By default, SQLite assumes that all data uses a fixed-size
|
<p>By default, SQLite assumes that all data uses a fixed-size
|
||||||
8-bit character (iso8859). But if you give the --enable-utf8 option
|
8-bit character (iso8859). But if you give the --enable-utf8 option
|
||||||
@@ -565,9 +816,9 @@ be changed at run-time. This is a compile-time option only. The
|
|||||||
<b>sqlite_encoding</b> character string just tells you how the library
|
<b>sqlite_encoding</b> character string just tells you how the library
|
||||||
was compiled.</p>
|
was compiled.</p>
|
||||||
|
|
||||||
<h2>Changing the library's response to locked files</h2>
|
<h3>3.8 Changing the library's response to locked files</h3>
|
||||||
|
|
||||||
<p>The <b>sqlite_busy_handler()</b> procedure can be used to register
|
<p>The <b>sqlite_busy_handler</b> procedure can be used to register
|
||||||
a busy callback with an open SQLite database. The busy callback will
|
a busy callback with an open SQLite database. The busy callback will
|
||||||
be invoked whenever SQLite tries to access a database that is locked.
|
be invoked whenever SQLite tries to access a database that is locked.
|
||||||
The callback will typically do some other useful work, or perhaps sleep,
|
The callback will typically do some other useful work, or perhaps sleep,
|
||||||
@@ -576,8 +827,8 @@ non-zero, then SQLite tries again to access the database and the cycle
|
|||||||
repeats. If the callback returns zero, then SQLite aborts the current
|
repeats. If the callback returns zero, then SQLite aborts the current
|
||||||
operation and returns SQLITE_BUSY.</p>
|
operation and returns SQLITE_BUSY.</p>
|
||||||
|
|
||||||
<p>The arguments to <b>sqlite_busy_handler()</b> are the opaque
|
<p>The arguments to <b>sqlite_busy_handler</b> are the opaque
|
||||||
structure returned from <b>sqlite_open()</b>, a pointer to the busy
|
structure returned from <b>sqlite_open</b>, a pointer to the busy
|
||||||
callback function, and a generic pointer that will be passed as
|
callback function, and a generic pointer that will be passed as
|
||||||
the first argument to the busy callback. When SQLite invokes the
|
the first argument to the busy callback. When SQLite invokes the
|
||||||
busy callback, it sends it three arguments: the generic pointer
|
busy callback, it sends it three arguments: the generic pointer
|
||||||
@@ -587,15 +838,15 @@ to access, and the number of times that the library has attempted to
|
|||||||
access the database table or index.</p>
|
access the database table or index.</p>
|
||||||
|
|
||||||
<p>For the common case where we want the busy callback to sleep,
|
<p>For the common case where we want the busy callback to sleep,
|
||||||
the SQLite library provides a convenience routine <b>sqlite_busy_timeout()</b>.
|
the SQLite library provides a convenience routine <b>sqlite_busy_timeout</b>.
|
||||||
The first argument to <b>sqlite_busy_timeout()</b> is a pointer to
|
The first argument to <b>sqlite_busy_timeout</b> is a pointer to
|
||||||
an open SQLite database and the second argument is a number of milliseconds.
|
an open SQLite database and the second argument is a number of milliseconds.
|
||||||
After <b>sqlite_busy_timeout()</b> has been executed, the SQLite library
|
After <b>sqlite_busy_timeout</b> has been executed, the SQLite library
|
||||||
will wait for the lock to clear for at least the number of milliseconds
|
will wait for the lock to clear for at least the number of milliseconds
|
||||||
specified before it returns SQLITE_BUSY. Specifying zero milliseconds for
|
specified before it returns SQLITE_BUSY. Specifying zero milliseconds for
|
||||||
the timeout restores the default behavior.</p>
|
the timeout restores the default behavior.</p>
|
||||||
|
|
||||||
<h2>Using the <tt>_printf()</tt> wrapper functions</h2>
|
<h3>3.9 Using the <tt>_printf()</tt> wrapper functions</h3>
|
||||||
|
|
||||||
<p>The four utility functions</p>
|
<p>The four utility functions</p>
|
||||||
|
|
||||||
@@ -608,23 +859,23 @@ the timeout restores the default behavior.</p>
|
|||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>implement the same query functionality as <b>sqlite_exec()</b>
|
<p>implement the same query functionality as <b>sqlite_exec</b>
|
||||||
and <b>sqlite_get_table()</b>. But instead of taking a complete
|
and <b>sqlite_get_table</b>. But instead of taking a complete
|
||||||
SQL statement as their second argument, the four <b>_printf</b>
|
SQL statement as their second argument, the four <b>_printf</b>
|
||||||
routines take a printf-style format string. The SQL statement to
|
routines take a printf-style format string. The SQL statement to
|
||||||
be executed is generated from this format string and from whatever
|
be executed is generated from this format string and from whatever
|
||||||
additional arguments are attached to the end of the function call.</p>
|
additional arguments are attached to the end of the function call.</p>
|
||||||
|
|
||||||
<p>There are two advantages to using the SQLite printf
|
<p>There are two advantages to using the SQLite printf
|
||||||
functions instead of <b>sprintf()</b>. First of all, with the
|
functions instead of <b>sprintf</b>. First of all, with the
|
||||||
SQLite printf routines, there is never a danger of overflowing a
|
SQLite printf routines, there is never a danger of overflowing a
|
||||||
static buffer as there is with <b>sprintf()</b>. The SQLite
|
static buffer as there is with <b>sprintf</b>. The SQLite
|
||||||
printf routines automatically allocate (and later frees)
|
printf routines automatically allocate (and later frees)
|
||||||
as much memory as is
|
as much memory as is
|
||||||
necessary to hold the SQL statements generated.</p>
|
necessary to hold the SQL statements generated.</p>
|
||||||
|
|
||||||
<p>The second advantage the SQLite printf routines have over
|
<p>The second advantage the SQLite printf routines have over
|
||||||
<b>sprintf()</b> are two new formatting options specifically designed
|
<b>sprintf</b> are two new formatting options specifically designed
|
||||||
to support string literals in SQL. Within the format string,
|
to support string literals in SQL. Within the format string,
|
||||||
the %q formatting option works very much like %s in that it
|
the %q formatting option works very much like %s in that it
|
||||||
reads a null-terminated string from the argument list and inserts
|
reads a null-terminated string from the argument list and inserts
|
||||||
@@ -717,7 +968,7 @@ by passing it to <b>sqlite_freemem()</b>.
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a name="cfunc">
|
<a name="cfunc">
|
||||||
<h2>Adding New SQL Functions</h2>
|
<h2>4.0 Adding New SQL Functions</h2>
|
||||||
|
|
||||||
<p>Beginning with version 2.4.0, SQLite allows the SQL language to be
|
<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
|
extended with new functions implemented as C code. The following interface
|
||||||
@@ -800,13 +1051,13 @@ new SQL functions, review the SQLite source code in the file
|
|||||||
<b>func.c</b>.
|
<b>func.c</b>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Multi-Threading And SQLite</h2>
|
<h2>5.0 Multi-Threading And SQLite</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If SQLite is compiled with the THREADSAFE preprocessor macro set to 1,
|
If SQLite is compiled with the THREADSAFE preprocessor macro set to 1,
|
||||||
then it is safe to use SQLite from two or more threads of the same process
|
then it is safe to use SQLite from two or more threads of the same process
|
||||||
at the same time. But each thread should have its own <b>sqlite*</b>
|
at the same time. But each thread should have its own <b>sqlite*</b>
|
||||||
pointer returned from <b>sqlite_open()</b>. It is never safe for two
|
pointer returned from <b>sqlite_open</b>. It is never safe for two
|
||||||
or more threads to access the same <b>sqlite*</b> pointer at the same time.
|
or more threads to access the same <b>sqlite*</b> pointer at the same time.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -823,7 +1074,7 @@ Under Unix, an <b>sqlite*</b> pointer should not be carried across a
|
|||||||
should open its own copy of the database after the <b>fork()</b>.
|
should open its own copy of the database after the <b>fork()</b>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Usage Examples</h2>
|
<h2>6.0 Usage Examples</h2>
|
||||||
|
|
||||||
<p>For examples of how the SQLite C/C++ interface can be used,
|
<p>For examples of how the SQLite C/C++ interface can be used,
|
||||||
refer to the source code for the <b>sqlite</b> program in the
|
refer to the source code for the <b>sqlite</b> program in the
|
||||||
|
10
www/lang.tcl
10
www/lang.tcl
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Run this Tcl script to generate the sqlite.html file.
|
# Run this Tcl script to generate the sqlite.html file.
|
||||||
#
|
#
|
||||||
set rcsid {$Id: lang.tcl,v 1.48 2003/01/26 15:28:18 jplyon Exp $}
|
set rcsid {$Id: lang.tcl,v 1.49 2003/01/29 22:58:27 drh Exp $}
|
||||||
|
|
||||||
puts {<html>
|
puts {<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -1103,6 +1103,7 @@ with caution.</p>
|
|||||||
<b>synchronous</b> pragma does the same thing but only applies the setting
|
<b>synchronous</b> pragma does the same thing but only applies the setting
|
||||||
to the current session.</p>
|
to the current session.</p>
|
||||||
|
|
||||||
|
<a name="pragma_empty_result_callbacks">
|
||||||
<li><p><b>PRAGMA empty_result_callbacks = ON;
|
<li><p><b>PRAGMA empty_result_callbacks = ON;
|
||||||
<br>PRAGMA empty_result_callbacks = OFF;</b></p>
|
<br>PRAGMA empty_result_callbacks = OFF;</b></p>
|
||||||
<p>When on, the EMPTY_RESULT_CALLBACKS pragma causes the callback
|
<p>When on, the EMPTY_RESULT_CALLBACKS pragma causes the callback
|
||||||
@@ -1145,14 +1146,17 @@ with caution.</p>
|
|||||||
a description of all problems. If everything is in order, "ok" is
|
a description of all problems. If everything is in order, "ok" is
|
||||||
returned.</p>
|
returned.</p>
|
||||||
|
|
||||||
|
<a name="pragma_show_datatypes">
|
||||||
<li><p><b>PRAGMA show_datatypes = ON;<br>PRAGMA show_datatypes = OFF;</b></p>
|
<li><p><b>PRAGMA show_datatypes = ON;<br>PRAGMA show_datatypes = OFF;</b></p>
|
||||||
<p>When turned on, the SHOW_DATATYPES pragma causes extra entries containing
|
<p>When turned on, the SHOW_DATATYPES pragma causes extra entries containing
|
||||||
the names of <a href="datatypes.html">datatypes</a> of columns to be
|
the names of <a href="datatypes.html">datatypes</a> of columns to be
|
||||||
appended to the 4th ("columnNames") argument to <b>sqlite_exec()</b>
|
appended to the 4th ("columnNames") argument to <b>sqlite_exec()</b>
|
||||||
callbacks. When
|
callbacks. When
|
||||||
turned off, the 4th argument to callbacks contains only the column names.
|
turned off, the 4th argument to callbacks contains only the column names.
|
||||||
SQLite <a href="datatypes.html">datatypes</a> are always either "TEXT"
|
The datatype for table columns is taken from the CREATE TABLE statement
|
||||||
or "NUMERIC".
|
that defines the table. Columns with an unspecified datatype have a
|
||||||
|
datatype of "NUMERIC" and the results of expression have a datatype of
|
||||||
|
either "TEXT" or "NUMERIC" depending on the expression.
|
||||||
The following chart illustrates the difference for the query
|
The following chart illustrates the difference for the query
|
||||||
"SELECT 'xyzzy', 5, NULL AS empty ":</p>
|
"SELECT 'xyzzy', 5, NULL AS empty ":</p>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user