Skip to content

Commit

Permalink
Allow parameter binding Arrays and Tuples
Browse files Browse the repository at this point in the history
Signed-off-by: asardesai2 <[email protected]>
  • Loading branch information
asardesai2 committed Nov 9, 2023
1 parent 29b0c11 commit 8eae32f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
56 changes: 52 additions & 4 deletions comdb2/_ccdb2.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ cdef _bind_datetime(obj, client_datetime *val):


cdef class _ParameterValue(object):
cdef int type
cdef lib.cdb2_coltype type
cdef int size
cdef void *data
cdef object owner
cdef int list_size

def __cinit__(self, obj, param_name):
try:
self.list_size = -1
if obj is None:
self.type = lib.CDB2_INTEGER
self.owner = None
Expand Down Expand Up @@ -153,6 +155,48 @@ cdef class _ParameterValue(object):
self.data = PyMem_Malloc(self.size)
_bind_datetime(obj, <lib.cdb2_client_datetime_t*>self.data)
return
elif isinstance(obj, (list, tuple)):
# Size of the list.
self.list_size = len(obj)
# Check if all elements are integers
if all(isinstance(ele, six.integer_types) for ele in obj):
self.type = lib.CDB2_INTEGER
self.size = sizeof(long long)
self.owner = None
self.data = PyMem_Malloc(self.list_size*self.size)
for l_index in range(self.list_size):
(<long long*>self.data)[l_index] = obj[l_index]
return
# Check all elements are floats
elif all(isinstance(ele, float) for ele in obj):
self.type = lib.CDB2_REAL
self.size = sizeof(double)
self.owner = None
self.data = PyMem_Malloc(self.list_size*self.size)
for l_index in range(self.list_size):
(<double*>self.data)[l_index] = obj[l_index]
return
# Check all elements are bytes
elif all(isinstance(ele, bytes) for ele in obj):
self.type = lib.CDB2_BLOB
self.size = sizeof(size_t) + sizeof(char*)
self.owner = obj
self.data = PyMem_Malloc(self.list_size*self.size)
for l_index in range(self.list_size):
(<size_t*>self.data)[2 * l_index] = len(self.owner[l_index])
(<char**>self.data)[2 * l_index + 1] = <char*>(self.owner[l_index])
return
# Check all elements are unicode
elif all(isinstance(ele, unicode) for ele in obj):
self.type = lib.CDB2_CSTRING
self.size = sizeof(char*)
# Strings need to be converted to bytes
self.owner = [x.encode('utf-8') for x in obj]
self.data = PyMem_Malloc(self.list_size*self.size)
for l_index in range(self.list_size):
(<char**>self.data)[l_index] = <char*>(self.owner[l_index])
return

except Exception as e:
exc = e
else:
Expand All @@ -178,7 +222,7 @@ cdef class _ParameterValue(object):


def __dealloc__(self):
if self.owner is None:
if self.owner is None or self.list_size != -1:
PyMem_Free(self.data)


Expand Down Expand Up @@ -344,8 +388,12 @@ cdef class Handle(object):
cval = _ParameterValue(val, key)
param_guards.append(ckey)
param_guards.append(cval)
rc = lib.cdb2_bind_param(self.hndl, <char*>ckey,
cval.type, cval.data, cval.size)
if cval.list_size == -1:
rc = lib.cdb2_bind_param(self.hndl, <char*>ckey,
cval.type, cval.data, cval.size)
else:
# Bind Array if cval is an array
rc = lib.cdb2_bind_array(self.hndl, <char*>ckey, cval.type, cval.data, cval.list_size, cval.size)
_errchk(rc, self.hndl)

with nogil:
Expand Down
3 changes: 2 additions & 1 deletion comdb2/_cdb2api.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cdef extern from "cdb2api.h" nogil:
CDB2ERR_NOTSUPPORTED
CDB2ERR_CONV_FAIL

enum:
enum cdb2_coltype:
CDB2_INTEGER
CDB2_REAL
CDB2_CSTRING
Expand Down Expand Up @@ -75,5 +75,6 @@ cdef extern from "cdb2api.h" nogil:
void* cdb2_column_value(cdb2_hndl_tp* hndl, int col);
const char* cdb2_errstr(cdb2_hndl_tp* hndl);
int cdb2_bind_param(cdb2_hndl_tp *hndl, const char *name, int type, const void *varaddr, int length);
int cdb2_bind_array(cdb2_hndl_tp *hndl, const char *name, cdb2_coltype, const void *varaddr, size_t count, size_t typelen);
int cdb2_clearbindings(cdb2_hndl_tp *hndl);
int cdb2_clear_ack(cdb2_hndl_tp *hndl);

0 comments on commit 8eae32f

Please sign in to comment.