mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Add support for the new sqlite3_bind_*() APIs. (CVS 1410)
FossilOrigin-Name: e8f980d842fcd793552acd32708db55c8f014634
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Get\smore\stests\srunning.\s(CVS\s1409)
|
C Add\ssupport\sfor\sthe\snew\ssqlite3_bind_*()\sAPIs.\s(CVS\s1410)
|
||||||
D 2004-05-19T21:09:32
|
D 2004-05-20T01:12:34
|
||||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -49,10 +49,10 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
|||||||
F src/select.c d01c03462d57b9d1ea25eea297bbd2c1b1c70e47
|
F src/select.c d01c03462d57b9d1ea25eea297bbd2c1b1c70e47
|
||||||
F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21
|
F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21
|
||||||
F src/sqlite.h.in 8c62076ea226b1870df977d7438bf99383d02387
|
F src/sqlite.h.in 8c62076ea226b1870df977d7438bf99383d02387
|
||||||
F src/sqliteInt.h 6c3822050d10eb648dd04e4ca68a2e577e145496
|
F src/sqliteInt.h 6b43ef88542c242b39ed41a84055e4504571a9f0
|
||||||
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
|
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
|
||||||
F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1
|
F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1
|
||||||
F src/test1.c 12ef76b8aaba4408422f21f269256b630d4dd627
|
F src/test1.c 9b068ec5488d1845fc890d25fc84e8577a0dff98
|
||||||
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
|
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
|
||||||
F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
|
F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
|
||||||
F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296
|
F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296
|
||||||
@@ -60,13 +60,13 @@ F src/test5.c c92dca7028b19b9c8319d55e0a5037fc183640a6
|
|||||||
F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
|
F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
|
||||||
F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
|
F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
|
||||||
F src/update.c 1f6687f8d1085f896a24c0fa13d802223ed55539
|
F src/update.c 1f6687f8d1085f896a24c0fa13d802223ed55539
|
||||||
F src/utf.c 48c537bf7990ce32a36b051401874d024ec2a07b
|
F src/utf.c 72a9843000985d11100e711e0ef06ff4b8946057
|
||||||
F src/util.c 35d20bd8d467861747262d12b87045d937781d93
|
F src/util.c 35d20bd8d467861747262d12b87045d937781d93
|
||||||
F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
|
F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
|
||||||
F src/vdbe.c 0f1918d2a702c5b99c7713646a60c78fe5085cfc
|
F src/vdbe.c 973ffe763e40b0a5c993d5f5632de58a37c411db
|
||||||
F src/vdbe.h 314e9c07db73a42a6ba91ab7539e27652fc88870
|
F src/vdbe.h 314e9c07db73a42a6ba91ab7539e27652fc88870
|
||||||
F src/vdbeInt.h faaa64433d2498f7a6eabccebac854e097b83680
|
F src/vdbeInt.h 97b95c622ea467d39879ae97d07732ebb4891b76
|
||||||
F src/vdbeaux.c c241a6ba1cc7dcd4158da6c4329d33de3c4d0e03
|
F src/vdbeaux.c 4cd7291c34ff21079d4ddd62df4390b8bc22d1fb
|
||||||
F src/where.c 626b2cbc4290d8be6c04ad7c8395f46d4e21d0d8
|
F src/where.c 626b2cbc4290d8be6c04ad7c8395f46d4e21d0d8
|
||||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
||||||
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
|
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
|
||||||
@@ -74,7 +74,7 @@ F test/attach2.test 7c388dee63a4c1997695c3d41957f32ce784ac56
|
|||||||
F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
|
F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
|
||||||
F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
|
F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
|
||||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||||
F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a
|
F test/bind.test b0676476d1ccf210867ad972fa45d9ca0b9906c3
|
||||||
F test/btree.test 08e4093c78d2bc1d54e27266f8d17fed14751125
|
F test/btree.test 08e4093c78d2bc1d54e27266f8d17fed14751125
|
||||||
F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
|
F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
|
||||||
F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
|
F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
|
||||||
@@ -193,7 +193,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
|||||||
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
||||||
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 34f03ba6a9d6e2144d0c6cbbbeb37b4c69705f1f
|
P 7eb3f29e305d0f455f6544560c567fa6b6e24986
|
||||||
R 6f649f6c623ad18fd759a30cd0ff66ff
|
R 1fcae74675628dbbea5a8739e50916af
|
||||||
U drh
|
U danielk1977
|
||||||
Z 2a22d59e6c6d628572425793997ef923
|
Z 6bd7c10a30f56d031b982fa43af23d80
|
||||||
|
@@ -1 +1 @@
|
|||||||
7eb3f29e305d0f455f6544560c567fa6b6e24986
|
e8f980d842fcd793552acd32708db55c8f014634
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.238 2004/05/19 20:41:03 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.239 2004/05/20 01:12:34 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
@@ -1321,6 +1321,7 @@ void *sqlite3utf8to16be(const unsigned char *pIn, int N);
|
|||||||
void *sqlite3utf8to16le(const unsigned char *pIn, int N);
|
void *sqlite3utf8to16le(const unsigned char *pIn, int N);
|
||||||
void sqlite3utf16to16le(void *pData, int N);
|
void sqlite3utf16to16le(void *pData, int N);
|
||||||
void sqlite3utf16to16be(void *pData, int N);
|
void sqlite3utf16to16be(void *pData, int N);
|
||||||
|
int sqlite3utf16ByteLen(const void *pData);
|
||||||
int sqlite3PutVarint(unsigned char *, u64);
|
int sqlite3PutVarint(unsigned char *, u64);
|
||||||
int sqlite3GetVarint(const unsigned char *, u64 *);
|
int sqlite3GetVarint(const unsigned char *, u64 *);
|
||||||
int sqlite3GetVarint32(const unsigned char *, u32 *);
|
int sqlite3GetVarint32(const unsigned char *, u32 *);
|
||||||
|
242
src/test1.c
242
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.40 2004/05/13 11:34:16 danielk1977 Exp $
|
** $Id: test1.c,v 1.41 2004/05/20 01:12:35 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -51,6 +51,21 @@ static int getVmPointer(Tcl_Interp *interp, const char *zArg, sqlite_vm **ppVm){
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Decode a pointer to an sqlite3_stmt object.
|
||||||
|
*/
|
||||||
|
static int getStmtPointer(
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
const char *zArg,
|
||||||
|
sqlite3_stmt **ppStmt
|
||||||
|
){
|
||||||
|
if( sscanf(zArg, PTR_FMT, (void**)ppStmt)!=1 ){
|
||||||
|
Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate a text representation of a pointer that can be understood
|
** Generate a text representation of a pointer that can be understood
|
||||||
** by the getDbPointer and getVmPointer routines above.
|
** by the getDbPointer and getVmPointer routines above.
|
||||||
@@ -967,6 +982,216 @@ static int test_breakpoint(
|
|||||||
return TCL_OK; /* Do nothing */
|
return TCL_OK; /* Do nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_bind_int32(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
int value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=4 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_int32(pStmt, idx, value);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_bind_int64(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
i64 value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=4 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_int64(pStmt, idx, value);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_bind_double(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
double value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=4 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_double(pStmt, idx, value);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_bind_null(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=3 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_null(pStmt, idx);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_bind_text(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
int bytes;
|
||||||
|
char *value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=5 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>"
|
||||||
|
" <bytes>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
value = Tcl_GetString(objv[3]);
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text(pStmt, idx, value, bytes, 1);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_bind_text16(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
int bytes;
|
||||||
|
char *value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=5 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>"
|
||||||
|
" <bytes>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
value = Tcl_GetByteArrayFromObj(objv[3], 0);
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, 1);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_bind_blob(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
sqlite3_stmt *pStmt;
|
||||||
|
int idx;
|
||||||
|
int bytes;
|
||||||
|
char *value;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=5 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>"
|
||||||
|
" <bytes>", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||||
|
value = Tcl_GetString(objv[3]);
|
||||||
|
if( Tcl_GetIntFromObj(interp, objv[2], &bytes) ) return TCL_ERROR;
|
||||||
|
|
||||||
|
rc = sqlite3_bind_blob(pStmt, idx, value, bytes, 1);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Register commands with the TCL interpreter.
|
** Register commands with the TCL interpreter.
|
||||||
*/
|
*/
|
||||||
@@ -1005,11 +1230,26 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
{ "sqlite_reset", (Tcl_CmdProc*)test_reset },
|
{ "sqlite_reset", (Tcl_CmdProc*)test_reset },
|
||||||
{ "breakpoint", (Tcl_CmdProc*)test_breakpoint },
|
{ "breakpoint", (Tcl_CmdProc*)test_breakpoint },
|
||||||
};
|
};
|
||||||
|
static struct {
|
||||||
|
char *zName;
|
||||||
|
Tcl_ObjCmdProc *xProc;
|
||||||
|
} aObjCmd[] = {
|
||||||
|
{ "sqlite3_bind_int32", (Tcl_ObjCmdProc*)test_bind_int32 },
|
||||||
|
{ "sqlite3_bind_int64", (Tcl_ObjCmdProc*)test_bind_int64 },
|
||||||
|
{ "sqlite3_bind_double", (Tcl_ObjCmdProc*)test_bind_double },
|
||||||
|
{ "sqlite3_bind_null", (Tcl_ObjCmdProc*)test_bind_null },
|
||||||
|
{ "sqlite3_bind_text", (Tcl_ObjCmdProc*)test_bind_text },
|
||||||
|
{ "sqlite3_bind_text16", (Tcl_ObjCmdProc*)test_bind_text16 },
|
||||||
|
{ "sqlite3_bind_blob", (Tcl_ObjCmdProc*)test_bind_blob },
|
||||||
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
|
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
|
||||||
Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
|
Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
|
||||||
}
|
}
|
||||||
|
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||||
|
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
|
||||||
|
}
|
||||||
Tcl_LinkVar(interp, "sqlite_search_count",
|
Tcl_LinkVar(interp, "sqlite_search_count",
|
||||||
(char*)&sqlite3_search_count, TCL_LINK_INT);
|
(char*)&sqlite3_search_count, TCL_LINK_INT);
|
||||||
Tcl_LinkVar(interp, "sqlite_interrupt_count",
|
Tcl_LinkVar(interp, "sqlite_interrupt_count",
|
||||||
|
10
src/utf.c
10
src/utf.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used to translate between UTF-8,
|
** This file contains routines used to translate between UTF-8,
|
||||||
** UTF-16, UTF-16BE, and UTF-16LE.
|
** UTF-16, UTF-16BE, and UTF-16LE.
|
||||||
**
|
**
|
||||||
** $Id: utf.c,v 1.4 2004/05/19 10:34:57 danielk1977 Exp $
|
** $Id: utf.c,v 1.5 2004/05/20 01:12:35 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** Notes on UTF-8:
|
** Notes on UTF-8:
|
||||||
**
|
**
|
||||||
@@ -327,14 +327,14 @@ static int writeUtf16(UtfString *pStr, int code, int big_endian){
|
|||||||
** Return the number of bytes up to (but not including) the first \u0000
|
** Return the number of bytes up to (but not including) the first \u0000
|
||||||
** character in *pStr.
|
** character in *pStr.
|
||||||
*/
|
*/
|
||||||
static int utf16Bytelen(const unsigned char *pZ){
|
int sqlite3utf16ByteLen(const void *pZ){
|
||||||
const unsigned char *pC1 = pZ;
|
const unsigned char *pC1 = pZ;
|
||||||
const unsigned char *pC2 = pZ+1;
|
const unsigned char *pC2 = pZ+1;
|
||||||
while( *pC1 || *pC2 ){
|
while( *pC1 || *pC2 ){
|
||||||
pC1 += 2;
|
pC1 += 2;
|
||||||
pC2 += 2;
|
pC2 += 2;
|
||||||
}
|
}
|
||||||
return pC1-pZ;
|
return pC1-(unsigned char *)pZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -359,7 +359,7 @@ unsigned char *sqlite3utf16to8(const void *pData, int N){
|
|||||||
in.c = 0;
|
in.c = 0;
|
||||||
|
|
||||||
if( in.n<0 ){
|
if( in.n<0 ){
|
||||||
in.n = utf16Bytelen(in.pZ);
|
in.n = sqlite3utf16ByteLen(in.pZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A UTF-8 encoding of a unicode string can require at most 1.5 times as
|
/* A UTF-8 encoding of a unicode string can require at most 1.5 times as
|
||||||
@@ -447,7 +447,7 @@ static void utf16to16(void *pData, int N, int big_endian){
|
|||||||
inout.n = N;
|
inout.n = N;
|
||||||
|
|
||||||
if( inout.n<0 ){
|
if( inout.n<0 ){
|
||||||
inout.n = utf16Bytelen(inout.pZ);
|
inout.n = sqlite3utf16ByteLen(inout.pZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( readUtf16Bom(&inout)!=big_endian ){
|
if( readUtf16Bom(&inout)!=big_endian ){
|
||||||
|
63
src/vdbe.c
63
src/vdbe.c
@@ -43,7 +43,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.305 2004/05/19 20:41:03 drh Exp $
|
** $Id: vdbe.c,v 1.306 2004/05/20 01:12:35 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -189,6 +189,51 @@ static AggElem *_AggInFocus(Agg *p){
|
|||||||
return pElem ? sqliteHashData(pElem) : 0;
|
return pElem ? sqliteHashData(pElem) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NulTermify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);} \
|
||||||
|
else if(((P)->flags & MEM_Term)==0){hardNulTermify(P);}
|
||||||
|
static int hardNulTermify(Mem *pStack){
|
||||||
|
int flags = pStack->flags;
|
||||||
|
|
||||||
|
assert( !(flags&MEM_Term) && (flags&MEM_Str) );
|
||||||
|
assert( flags&(MEM_Utf8|MEM_Utf16le|MEM_Utf16be) );
|
||||||
|
|
||||||
|
if( flags&MEM_Utf8 ){
|
||||||
|
/* If the string is already dynamically allocated, use sqliteRealloc()
|
||||||
|
** to allocate extra space for the terminator.
|
||||||
|
*/
|
||||||
|
if( flags&MEM_Dyn ){
|
||||||
|
pStack->z = sqliteRealloc(pStack->z, pStack->n+1);
|
||||||
|
if( !pStack->z ){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( flags&(MEM_Static|MEM_Ephem|MEM_Short) ){
|
||||||
|
if( pStack->n+1<NBFS ){
|
||||||
|
if( flags&MEM_Short ){
|
||||||
|
memcpy(pStack->zShort, pStack->z, pStack->n);
|
||||||
|
pStack->flags = MEM_Short|MEM_Str|MEM_Utf8|MEM_Term;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
char *z = sqliteMalloc(pStack->n+1);
|
||||||
|
if( !z ){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memcpy(z, pStack->z, pStack->n);
|
||||||
|
pStack->z = z;
|
||||||
|
pStack->flags = MEM_Dyn|MEM_Str|MEM_Utf8|MEM_Term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pStack->z[pStack->n] = '\0';
|
||||||
|
pStack->n++;
|
||||||
|
}else{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Convert the given stack entity into a string if it isn't one
|
** Convert the given stack entity into a string if it isn't one
|
||||||
** already.
|
** already.
|
||||||
@@ -205,7 +250,7 @@ static int hardStringify(Mem *pStack){
|
|||||||
}
|
}
|
||||||
pStack->z = pStack->zShort;
|
pStack->z = pStack->zShort;
|
||||||
pStack->n = strlen(pStack->zShort)+1;
|
pStack->n = strlen(pStack->zShort)+1;
|
||||||
pStack->flags = MEM_Str | MEM_Short;
|
pStack->flags = MEM_Str | MEM_Short | MEM_Term;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,7 +879,7 @@ case OP_Variable: {
|
|||||||
** variable is used again, even after the virtual machine is reset, the
|
** variable is used again, even after the virtual machine is reset, the
|
||||||
** conversion won't have to be done again.
|
** conversion won't have to be done again.
|
||||||
**
|
**
|
||||||
** TODO: This is where we need to support databases that use other than
|
** FIX ME: This is where we need to support databases that use other than
|
||||||
** UTF-8 on disk.
|
** UTF-8 on disk.
|
||||||
*/
|
*/
|
||||||
pVar = &p->apVar[j];
|
pVar = &p->apVar[j];
|
||||||
@@ -848,7 +893,17 @@ case OP_Variable: {
|
|||||||
Release(pVar);
|
Release(pVar);
|
||||||
pVar->z = zUtf8;
|
pVar->z = zUtf8;
|
||||||
pVar->n = strlen(zUtf8)+1;
|
pVar->n = strlen(zUtf8)+1;
|
||||||
pVar->flags = MEM_Str|MEM_Dyn;
|
pVar->flags = MEM_Str|MEM_Dyn|MEM_Utf8|MEM_Term;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure that the variable value is nul terminated. Again, do this in
|
||||||
|
** place.
|
||||||
|
**
|
||||||
|
** FIX ME: The rest of the vdbe will soon understand MEM_Term, making
|
||||||
|
** this step unnecessary.
|
||||||
|
*/
|
||||||
|
if( pVar->flags&MEM_Str ){
|
||||||
|
NulTermify(pVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the value in pVar to the top of the stack. If pVar is a string or
|
/* Copy the value in pVar to the top of the stack. If pVar is a string or
|
||||||
|
@@ -146,6 +146,8 @@ typedef struct Mem Mem;
|
|||||||
#define MEM_Real 0x0008 /* Value is a real number */
|
#define MEM_Real 0x0008 /* Value is a real number */
|
||||||
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
#define MEM_Blob 0x0010 /* Value is a BLOB */
|
||||||
|
|
||||||
|
#define MEM_Term 0x1000 /* String has a nul terminator character */
|
||||||
|
|
||||||
#define MEM_Utf8 0x0020 /* String uses UTF-8 encoding */
|
#define MEM_Utf8 0x0020 /* String uses UTF-8 encoding */
|
||||||
#define MEM_Utf16be 0x0040 /* String uses UTF-16 big-endian */
|
#define MEM_Utf16be 0x0040 /* String uses UTF-16 big-endian */
|
||||||
#define MEM_Utf16le 0x0080 /* String uses UTF-16 little-endian */
|
#define MEM_Utf16le 0x0080 /* String uses UTF-16 little-endian */
|
||||||
|
@@ -1043,10 +1043,16 @@ int sqlite3_bind_text(
|
|||||||
int nData,
|
int nData,
|
||||||
int eCopy
|
int eCopy
|
||||||
){
|
){
|
||||||
if( zData && nData<0 ){
|
int flags = MEM_Str|MEM_Utf8;
|
||||||
|
if( zData ){
|
||||||
|
if( nData<0 ){
|
||||||
nData = strlen(zData)+1;
|
nData = strlen(zData)+1;
|
||||||
|
flags |= MEM_Term;
|
||||||
|
}else if( !zData[nData-1] ){
|
||||||
|
flags |= MEM_Term;
|
||||||
}
|
}
|
||||||
return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, MEM_Str|MEM_Utf8);
|
}
|
||||||
|
return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sqlite3_bind_text16(
|
int sqlite3_bind_text16(
|
||||||
@@ -1056,14 +1062,26 @@ int sqlite3_bind_text16(
|
|||||||
int nData,
|
int nData,
|
||||||
int eCopy
|
int eCopy
|
||||||
){
|
){
|
||||||
if( zData && nData<0 ){
|
int flags = MEM_Str|MEM_Utf16le|MEM_Utf16be;
|
||||||
char *z = (char *)zData;
|
|
||||||
while( (*z)!=0 && (*(z+1))!=0 ) z+=2;
|
if( zData ){
|
||||||
nData = (z - (char *)zData) + 2;
|
/* If nData is less than zero, measure the length of the string.
|
||||||
|
** manually. In this case the variable will always be null terminated.
|
||||||
|
*/
|
||||||
|
if( nData<0 ){
|
||||||
|
nData = sqlite3utf16ByteLen(zData) + 2;
|
||||||
|
flags |= MEM_Term;
|
||||||
|
}else{
|
||||||
|
/* If nData is greater than zero, check if the final character appears
|
||||||
|
** to be a terminator.
|
||||||
|
*/
|
||||||
|
if( !(((u8 *)zData)[nData-1]) && !(((u8 *)zData)[nData-2]) ){
|
||||||
|
flags |= MEM_Term;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIX ME - MEM_Utf16le? */
|
return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, flags);
|
||||||
return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, MEM_Str|MEM_Utf16le);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sqlite3_bind_blob(
|
int sqlite3_bind_blob(
|
||||||
|
131
test/bind.test
131
test/bind.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 sqlite_bind API.
|
# focus of this script testing the sqlite_bind API.
|
||||||
#
|
#
|
||||||
# $Id: bind.test,v 1.1 2003/09/06 22:45:21 drh Exp $
|
# $Id: bind.test,v 1.2 2004/05/20 01:12:35 danielk1977 Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@@ -63,10 +63,137 @@ do_test bind-1.9 {
|
|||||||
execsql {SELECT rowid, * FROM t1}
|
execsql {SELECT rowid, * FROM t1}
|
||||||
} {1 123 abcdefg {} 2 456 abcdefg {}}
|
} {1 123 abcdefg {} 2 456 abcdefg {}}
|
||||||
|
|
||||||
|
|
||||||
do_test bind-1.99 {
|
do_test bind-1.99 {
|
||||||
sqlite_finalize $VM
|
sqlite_finalize $VM
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
do_test bind-2.1 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
set VM [sqlite_compile $DB {INSERT INTO t1 VALUES(?,?,?)} TAIL]
|
||||||
|
set TAIL
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# 32 bit Integers
|
||||||
|
do_test bind-2.2 {
|
||||||
|
sqlite3_bind_int32 $VM 1 123
|
||||||
|
sqlite3_bind_int32 $VM 2 456
|
||||||
|
sqlite3_bind_int32 $VM 3 789
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 123 456 789}
|
||||||
|
do_test bind-2.3 {
|
||||||
|
sqlite3_bind_int32 $VM 2 -2000000000
|
||||||
|
sqlite3_bind_int32 $VM 3 2000000000
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 123 456 789 2 123 -2000000000 2000000000}
|
||||||
|
do_test bind-2.4 {
|
||||||
|
execsql {SELECT classof(a), classof(b), classof(c) FROM t1}
|
||||||
|
} {INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER}
|
||||||
|
do_test bind-2.5 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# 64 bit Integers
|
||||||
|
do_test bind-3.1 {
|
||||||
|
sqlite3_bind_int64 $VM 1 32
|
||||||
|
sqlite3_bind_int64 $VM 2 -2000000000000
|
||||||
|
sqlite3_bind_int64 $VM 3 2000000000000
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 32 -2000000000000 2000000000000}
|
||||||
|
do_test bind-3.2 {
|
||||||
|
execsql {SELECT classof(a), classof(b), classof(c) FROM t1}
|
||||||
|
} {INTEGER INTEGER INTEGER}
|
||||||
|
do_test bind-3.3 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# Doubles
|
||||||
|
do_test bind-4.1 {
|
||||||
|
sqlite3_bind_double $VM 1 1234.1234
|
||||||
|
sqlite3_bind_double $VM 2 0.00001
|
||||||
|
sqlite3_bind_double $VM 3 123456789
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 1234.1234 1e-05 123456789}
|
||||||
|
do_test bind-4.2 {
|
||||||
|
execsql {SELECT classof(a), classof(b), classof(c) FROM t1}
|
||||||
|
} {REAL REAL REAL}
|
||||||
|
do_test bind-4.3 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# NULL
|
||||||
|
do_test bind-5.1 {
|
||||||
|
sqlite3_bind_null $VM 1
|
||||||
|
sqlite3_bind_null $VM 2
|
||||||
|
sqlite3_bind_null $VM 3
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 {} {} {}}
|
||||||
|
do_test bind-5.2 {
|
||||||
|
execsql {SELECT classof(a), classof(b), classof(c) FROM t1}
|
||||||
|
} {NULL NULL NULL}
|
||||||
|
do_test bind-5.3 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# UTF-8 text
|
||||||
|
do_test bind-6.1 {
|
||||||
|
sqlite3_bind_text $VM 1 hellothere 5
|
||||||
|
sqlite3_bind_text $VM 2 "." 2
|
||||||
|
sqlite3_bind_text $VM 3 world -1
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 hello . world}
|
||||||
|
do_test bind-6.2 {
|
||||||
|
execsql {SELECT classof(a), classof(b), classof(c) FROM t1}
|
||||||
|
} {TEXT TEXT TEXT}
|
||||||
|
do_test bind-6.3 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# UTF-16 text
|
||||||
|
do_test bind-7.1 {
|
||||||
|
sqlite3_bind_text16 $VM 1 [encoding convertto unicode hellothere] 10
|
||||||
|
sqlite3_bind_text16 $VM 2 [encoding convertto unicode ""] 0
|
||||||
|
sqlite3_bind_text16 $VM 3 [encoding convertto unicode world] 10
|
||||||
|
sqlite_step $VM N VALUES COLNAMES
|
||||||
|
sqlite_reset $VM
|
||||||
|
execsql {SELECT rowid, * FROM t1}
|
||||||
|
} {1 hello {} world}
|
||||||
|
do_test bind-7.2 {
|
||||||
|
execsql {SELECT classof(a), classof(b), classof(c) FROM t1}
|
||||||
|
} {TEXT TEXT TEXT}
|
||||||
|
do_test bind-7.3 {
|
||||||
|
execsql {
|
||||||
|
DELETE FROM t1;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_test bind-8.99 {
|
||||||
|
sqlite_finalize $VM
|
||||||
|
} {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user