Exemplo n.º 1
0
def _from_python(param, value, encoding):
    is_null = ffi.new('unsigned int *', value is None)
    param.value.is_null = is_null

    if is_null[0]:
        value = 0
    if param.value.type == lib.A_INVALID_TYPE:
        param.value.type = _infer_type(param, value)

    fmt = _FORMATS[param.value.type]
    if fmt == 'x':
        if isinstance(value, bytes):
            size = length = len(value)
        elif isinstance(value, str):
            param.value.type = lib.A_NCHAR
            value = value.encode('utf-16')
            size = length = len(value) + 2  # +2 for the BOM chars
        else:
            try:
                value = str(value).encode('ascii')
            except UnicodeEncodeError:
                raise DataError('Cannot convert value {}'.format(value))
            size = length = len(value)
    else:
        value = struct.pack(fmt, value)
        size = length = struct.calcsize(fmt)
    buf = ffi.new('char[]', value)
    param.value.buffer = buf
    param.value.buffer_size = size
    l = ffi.new('unsigned int *', length)
    param.value.length = l
    _ref_bucket[param] = (is_null, buf, l)
Exemplo n.º 2
0
 def bind(self, i, value):
     param = ffi.new('struct a_ads_bind_param *')
     if not lib.ads_describe_bind_param(self.stmt, i, param):
         raise DatabaseError(*_error(self.handler))
     _from_python(param, value, self.encoding)
     if not lib.ads_bind_param(self.stmt, i, param):
         raise DatabaseError(*_error(self.handler))
Exemplo n.º 3
0
 def column_info(self, i):
     info = ffi.new('struct a_ads_column_info *')
     lib.ads_get_column_info(self.stmt, i, info)
     if info.native_type in _UNICODE_FIELD:
         # Precision and size here are in bytes, so convert it to chars
         # for unicode fields
         info.precision = info.precision // 2
         info.max_size = info.max_size // 2
     return (ffi.string(info.name).decode('ascii',
                                          'ignore'), info.native_type, None,
             info.max_size, info.precision, info.scale, info.nullable)
Exemplo n.º 4
0
def _error(handler):
    buflength = lib.ADS_MAX_ERROR_LEN
    buf = ffi.new('char[]', buflength + 1)
    errno = lib.ads_error(handler, buf, buflength)
    if errno == 0:
        return 'internal error: success', 0
    msg = ffi.string(buf, buflength + 1).decode('ascii', 'ignore').rstrip()
    if errno == 7200:
        # because 7200 seems to be a generic error we look for a more specific
        # error code and we report that instead
        matchobj = _NATIVE_ERROR_RE.search(msg)
        if matchobj is not None:
            errno = int(matchobj.group('errno') or 0)
    return msg, errno
Exemplo n.º 5
0
 def iter_columns(self):
     data_value = ffi.new('struct a_ads_data_value *')
     for i in range(self.num_cols()):
         if not lib.ads_get_column(self.stmt, i, data_value):
             raise DatabaseError(*_error(self.handler))
         yield _to_python(data_value, self.encoding)
Exemplo n.º 6
0
 def _transaction_count(self):
     c = ffi.new('unsigned int *')
     if lib.AdsGetTransactionCount(self._handler.handle, c):
         raise OperationalError(*_error(self._handler))
     return c[0]
Exemplo n.º 7
0
 def _in_transaction(self):
     in_trans = ffi.new('unsigned short int[1]')
     if lib.AdsInTransaction(self._handler.handle, in_trans):
         raise OperationalError(*_error(self._handler))
     return bool(in_trans[0])
Exemplo n.º 8
0
_MAX_INT32 = 2**31 - 1
_MIN_INT64 = -(2**63)
_MAX_INT64 = 2**63 - 1
_TIME_RE = re.compile(r'^'
                      r'(?P<hour>\d{2})'
                      r':'
                      r'(?P<minute>\d{2})'
                      r':'
                      r'(?P<second>\d{2})'
                      r'(?P<microsecond>\.\d+)?'
                      r'(?: (?P<ampm>AM|PM))?'
                      r'$')
_NATIVE_ERROR_RE = re.compile(r'NativeError\s+=\s+(?P<errno>\d+);')
_ref_bucket = weakref.WeakKeyDictionary()

ver = ffi.new('unsigned int[1]', [API_VERSION])
if not lib.ads_init(b'adsdb3', API_VERSION, ver):
    raise ImportError('Error initializing libace')
if ver[0] != API_VERSION:
    lib.ads_fini()
    raise ImportError('Incompatible libace version %s. Required %s' %
                      (ver[0], API_VERSION))
del ver


class DBAPITypeObject:
    def __init__(self, *values):
        self.values = frozenset(values)

    def __eq__(self, other):
        if other in self.values:
Exemplo n.º 9
0
 def test_init(self):
     ver = ffi.new('unsigned int[1]', [1])
     try:
         self.assertEqual(lib.ads_init(b'test', 1, ver), 1)
     finally:
         lib.ads_fini()