DataBuf objects manage buffers which are used to hold data to be sent to and received from the server.
DataBuf objects contain an embedded Sybase CS_DATAFMT
structure and allocated buffers suitable for binding the contained
data to Sybase-CT API functions.
When constructed from native Python or Sybase data types a buffer is
created for a single value. When created using a CS_DATAFMT
object the count
attribute is used to allocate buffers suitable
for array binding. A count
of zero is treated the same as
1
.
The DataBuf objects have the same attributes as a CS_DATAFMT object but the attributes which describe the memory are read only and cannot be modified.
attribute | type | read only? |
name |
string |
no |
datatype |
int |
yes |
format |
int |
no |
maxlength |
int |
yes |
scale |
int |
yes |
precision |
int |
yes |
status |
int |
no |
count |
int |
yes |
usertype |
int |
yes |
strip |
int |
no |
In addition the DataBuf object behaves like a fixed length mutable sequence.
Adapted from Sybase.py, this is how you create a set of buffers suitable for retrieving a number of rows from the server:
def row_bind(cmd, count = 1): status, num_cols = cmd.ct_res_info(CS_NUMDATA) if status != CS_SUCCEED: raise 'ct_res_info' bufs = [] for i in range(num_cols): status, fmt = cmd.ct_describe(i + 1) if status != CS_SUCCEED: raise 'ct_describe' fmt.count = count status, buf = cmd.ct_bind(i + 1, fmt) if status != CS_SUCCEED: raise 'ct_bind' bufs.append(buf) return bufs
Then once the rows have been fetched, this is how you extract the data from the buffers:
def fetch_rows(cmd, bufs): rows = [] status, rows_read = cmd.ct_fetch() if status == CS_SUCCEED: for i in range(rows_read): row = [] for buf in bufs: row.append(buf[i]) rows.append(tuple(row)) return rows
To send a parameter to a dynamic SQL command or a stored procedure you are likely to create a DataBuf object directly from the value you wish to send. For example:
if cmd.ct_command(CS_RPC_CMD, 'sp_help', CS_NO_RECOMPILE) != CS_SUCCEED: raise 'ct_command' buf = DataBuf('sysobjects') buf.status = CS_INPUTVALUE if cmd.ct_param(buf) != CS_SUCCEED: raise 'ct_param' if cmd.ct_send() != CS_SUCCEED: raise 'ct_send'
Note that it is your responsibility to make sure that the buffers are not deallocated before you have finished using them. If you are not careful you will get a segmentation fault.