mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Extend the carray extension to allow the use of BLOB values to be bound
as an array of "struct iovec" objects. FossilOrigin-Name: e117a03ca6560e958884f277db827c51ae337a970c17143a0a5f9b150f52f87a
This commit is contained in:
@ -28,7 +28,7 @@
|
||||
**
|
||||
** There is an optional third parameter to determine the datatype of
|
||||
** the C-language array. Allowed values of the third parameter are
|
||||
** 'int32', 'int64', 'double', 'char*'. Example:
|
||||
** 'int32', 'int64', 'double', 'char*', 'struct iovec'. Example:
|
||||
**
|
||||
** SELECT * FROM carray($ptr,10,'char*');
|
||||
**
|
||||
@ -56,6 +56,14 @@
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
struct iovec {
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
#else
|
||||
# include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
/* Allowed values for the mFlags parameter to sqlite3_carray_bind().
|
||||
** Must exactly match the definitions in carray.h.
|
||||
@ -65,6 +73,7 @@ SQLITE_EXTENSION_INIT1
|
||||
# define CARRAY_INT64 1 /* Data is 64-bit signed integers */
|
||||
# define CARRAY_DOUBLE 2 /* Data is doubles */
|
||||
# define CARRAY_TEXT 3 /* Data is char* */
|
||||
# define CARRAY_BLOB 4 /* Data is struct iovec* */
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_API
|
||||
@ -80,7 +89,8 @@ SQLITE_EXTENSION_INIT1
|
||||
/*
|
||||
** Names of allowed datatypes
|
||||
*/
|
||||
static const char *azType[] = { "int32", "int64", "double", "char*" };
|
||||
static const char *azType[] = { "int32", "int64", "double", "char*",
|
||||
"struct iovec" };
|
||||
|
||||
/*
|
||||
** Structure used to hold the sqlite3_carray_bind() information
|
||||
@ -224,6 +234,12 @@ static int carrayColumn(
|
||||
sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case CARRAY_BLOB: {
|
||||
const struct iovec *p = (struct iovec*)pCur->pPtr;
|
||||
sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base,
|
||||
(int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -268,7 +284,7 @@ static int carrayFilter(
|
||||
if( pBind==0 ) break;
|
||||
pCur->pPtr = pBind->aData;
|
||||
pCur->iCnt = pBind->nData;
|
||||
pCur->eType = pBind->mFlags & 0x03;
|
||||
pCur->eType = pBind->mFlags & 0x07;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
@ -431,24 +447,29 @@ SQLITE_API int sqlite3_carray_bind(
|
||||
pNew->mFlags = mFlags;
|
||||
if( xDestroy==SQLITE_TRANSIENT ){
|
||||
sqlite3_int64 sz = nData;
|
||||
switch( mFlags & 0x03 ){
|
||||
case CARRAY_INT32: sz *= 4; break;
|
||||
case CARRAY_INT64: sz *= 8; break;
|
||||
case CARRAY_DOUBLE: sz *= 8; break;
|
||||
case CARRAY_TEXT: sz *= sizeof(char*); break;
|
||||
switch( mFlags & 0x07 ){
|
||||
case CARRAY_INT32: sz *= 4; break;
|
||||
case CARRAY_INT64: sz *= 8; break;
|
||||
case CARRAY_DOUBLE: sz *= 8; break;
|
||||
case CARRAY_TEXT: sz *= sizeof(char*); break;
|
||||
case CARRAY_BLOB: sz *= sizeof(struct iovec); break;
|
||||
}
|
||||
if( (mFlags & 0x03)==CARRAY_TEXT ){
|
||||
if( (mFlags & 0x07)==CARRAY_TEXT ){
|
||||
for(i=0; i<nData; i++){
|
||||
const char *z = ((char**)aData)[i];
|
||||
if( z ) sz += strlen(z) + 1;
|
||||
}
|
||||
}else if( (mFlags & 0x07)==CARRAY_BLOB ){
|
||||
for(i=0; i<nData; i++){
|
||||
sz += ((struct iovec*)aData)[i].iov_len;
|
||||
}
|
||||
}
|
||||
pNew->aData = sqlite3_malloc64( sz );
|
||||
if( pNew->aData==0 ){
|
||||
sqlite3_free(pNew);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( (mFlags & 0x03)==CARRAY_TEXT ){
|
||||
if( (mFlags & 0x07)==CARRAY_TEXT ){
|
||||
char **az = (char**)pNew->aData;
|
||||
char *z = (char*)&az[nData];
|
||||
for(i=0; i<nData; i++){
|
||||
@ -463,6 +484,16 @@ SQLITE_API int sqlite3_carray_bind(
|
||||
memcpy(z, zData, n+1);
|
||||
z += n+1;
|
||||
}
|
||||
}else if( (mFlags & 0x07)==CARRAY_BLOB ){
|
||||
struct iovec *p = (struct iovec*)pNew->aData;
|
||||
unsigned char *z = (unsigned char*)&p[nData];
|
||||
for(i=0; i<nData; i++){
|
||||
size_t n = ((struct iovec*)aData)[i].iov_len;
|
||||
p[i].iov_len = n;
|
||||
p[i].iov_base = z;
|
||||
z += n;
|
||||
memcpy(p[i].iov_base, ((struct iovec*)aData)[i].iov_base, n);
|
||||
}
|
||||
}else{
|
||||
memcpy(pNew->aData, aData, sz);
|
||||
}
|
||||
|
Reference in New Issue
Block a user