def create_string_sequence(self, values): cvalues = [] for v in values: cvalues.append(ffi.new('char[]', unicode(v).encode('utf8'))) _seq = ffi.new('XQC_Sequence**') _handle_error( self._impl.create_string_sequence(self._impl, cvalues, len(cvalues), _seq)) return Sequence(self, _seq[0])
def create_context(self): """Create a static context to use for expressions""" _context = ffi.new('XQC_StaticContext**') _handle_error(self._impl.create_context(self._impl, _context)) c = StaticContext(self, _context[0]) c.set_error_handler() return c
def __init__(self): self._store = lib.create_store() if self._store == ffi.NULL: raise RuntimeError('Could not create Zorba store') _impl = ffi.new('XQC_Implementation **') _handle_error(lib.zorba_implementation(_impl, self._store)) self._impl = _impl[0]
def get_default_function_ns(self): uri = ffi.new('char**') _handle_error( self._context.set_default_element_and_type_ns(self._context, uri)) if uri[0] == ffi.NULL: return None return ffi.string(uri[0]).decode('utf8')
def get_ns_by_prefix(self, prefix): uri = ffi.new('char**', ffi.NULL) _handle_error( self._context.get_ns_by_prefix(self._context, prefix.encode('utf8'), uri)) if uri[0] == ffi.NULL: raise XQueryStaticError return ffi.string(uri[0]).decode('utf8')
def get_variable(self, name, uri=''): _seq = ffi.new('XQC_Sequence**') _handle_error( self._context.get_variable(self._context, uri.encode('utf8'), name.encode('utf8'), _seq)) # Should seq be freed? no idea s = Sequence(self.expr.impl, _seq[0]) self.refs.append(s) return s
def execute(self, context=None): _seq = ffi.new('XQC_Sequence**') if context is None: context = self.create_context() _context = context._context _handle_error(self._expr.execute(self._expr, _context, _seq)) s = Sequence(self.impl, _seq[0], refs=[self]) # Sequence needs to be deleted after context context.refs.append(s) return s
def prepare_file(self, expression_file, context=None): """Same as prepare but from a file""" _expr = ffi.new('XQC_Expression**') if context is None: context = self.create_context() _context = context._context else: _context = context._context _handle_error( self._impl.prepare_file(self._impl, expression_file, _context, _expr)) e = Expression(self, _expr[0], context) # context should be deleted before expression context.refs.append(e) return e
def prepare(self, expression, context=None): """Prepare an XQuery expression""" _expr = ffi.new('XQC_Expression**') _expr_str = expression.encode('utf8') if context is None: context = self.create_context() _context = context._context else: _context = context._context _handle_error( self._impl.prepare(self._impl, _expr_str, _context, _expr)) e = Expression(self, _expr[0], context) # context should be deleted before expression context.refs.append(e) return e
def create_singleton_sequence(self, value): """Create a sequence with a single value You can force the type by wrapping your value in a type class""" t = type(value) if t in _type_to_id: type_ = t value = unicode(value) elif t in _int_type_to_type: type_ = _int_type_to_type[t] value = unicode(type_(value)) else: raise ValueError('Unsupported type ' + repr(t)) tid = _type_to_id[type_] _seq = ffi.new('XQC_Sequence**') _handle_error( self._impl.create_singleton_sequence(self._impl, tid, value.encode('utf8'), _seq)) return Sequence(self, _seq[0])
def type(self): t = ffi.new('XQC_ItemType*') self._seq.item_type(self._seq, t) return _id_to_type[int(t[0])]
def create_context(self): _context = ffi.new('XQC_DynamicContext**') _handle_error(self._expr.create_context(self._expr, _context)) c = DynamicContext(self, _context[0]) c.set_error_handler() return c
def parse_document_file(self, document_file): _seq = ffi.new('XQC_Sequence**') _handle_error( self._impl.parse_document_file(self._impl, document_file, _seq)) return Sequence(self, _seq[0])
def node_name(self): uri = ffi.new('char**') s = ffi.new('char**') _handle_error(self._seq.node_name(self._seq, uri, s)) return (ffi.string(uri[0]).decode('utf8'), ffi.string(s[0]).decode('utf8'))
def get_base_uri(self): s = ffi.new('char**') self._context.get_base_uri(self._context, s) return ffi.string(s[0]).decode('utf8')
def get_copy_ns_mode(self): preserve = ffi.new('XQC_PreserveMode*') inherit = ffi.new('XQC_InheritMode*') _handle_error( self._context.get_copy_ns_mode(self._context, preserve, inherit)) return (int(preserve[0]), int(inherit[0]))
def get_boundary_space_policy(self): mode = ffi.new('XQC_BoundarySpaceMode*') _handle_error( self._context.get_boundary_space_policy(self._context, mode)) return int(mode[0])
def get_default_order_empty_sequences(self): mode = ffi.new('XQC_OrderEmptyMode*') _handle_error( self._context.get_default_order_empty_sequences( self._context, mode)) return int(mode[0])
def get_ordering_mode(self): mode = ffi.new('XQC_OrderingMode*') _handle_error(self._context.get_ordering_mode(self._context, mode)) return int(mode[0])
def get_construction_mode(self): mode = ffi.new('XQC_ConstructionMode*') _handle_error(self._context.get_construction_mode(self._context, mode)) return int(mode[0])
def get_xpath_compatib_mode(self): mode = ffi.new('XQC_XPath1Mode*') _handle_error( self._context.get_xpath_compatib_mode(self._context, mode)) return int(mode[0])
def string_value(self): s = ffi.new('char**') _handle_error(self._seq.string_value(self._seq, s)) return ffi.string(s[0]).decode('utf8')
def double_value(self): d = ffi.new('double*') _handle_error(self._seq.double_value(self._seq, d)) return float(d[0])
def create_child_context(self): context = ffi.new('XQC_StaticContext**') _handle_error( self._context.create_child_context(self._context, context)) return StaticContext(self.impl, context[0], refs=[self])
def parse_document(self, document): _seq = ffi.new('XQC_Sequence**') _handle_error( self._impl.parse_document(self._impl, document.encode('utf8'), _seq)) return Sequence(self, _seq[0])
def get_context_item(self): _seq = ffi.new('XQC_Sequence**') _handle_error(self._context.get_context_item(self._context, _seq)) s = Sequence(self.expr.impl, _seq[0]) self.refs.append(s) return s
def create_empty_sequence(self): _seq = ffi.new('XQC_Sequence**') _handle_error(self._impl.create_empty_sequence(self._impl, _seq)) return Sequence(self, _seq[0])
def get_implicit_timezone(self): t = ffi.new('int*') _handle_error(self._context.get_implicit_timezone(self._context, t)) return int(t[0])
if err == lib.XQC_STATIC_ERROR: exc = XQueryStaticError elif err == lib.XQC_TYPE_ERROR: exc = XQueryTypeError elif err == lib.XQC_DYNAMIC_ERROR: exc = XQueryDynamicError elif err == lib.XQC_SERIALIZATION_ERROR: exc = XQuerySerializationError else: exc = Exception # TODO should make this thread safe global _last_exception _last_exception = exc(info) _error_handler = ffi.new('XQC_ErrorHandler *') _error_handler.user_data = ffi.NULL _error_handler.error = lib.error_handle_callback def _handle_error(err): """Check the return value of calls and raise an exception if there was an error""" global _last_exception if _last_exception is not None: _last_exception_ = _last_exception _last_exception = None raise _last_exception_ if err == lib.XQC_END_OF_SEQUENCE: raise StopIteration elif err == lib.XQC_NOT_IMPLEMENTED:
def get_default_element_and_type_ns(self): uri = ffi.new('char**') _handle_error( self._context.get_default_element_and_type_ns(self._context, uri)) return ffi.string(uri[0]).decode('utf8')