def __create_or_lookup_cpl_object(self, prefix, name, type=None, create=None): ''' Create or lookup a CPL object ** Parameters ** prefix name: name type: type, type can be none for lookup create: None: lookup or create True: create only False: lookup only ''' if create == None: ret, idp = CPLDirect.cpl_lookup_or_create_object(prefix, name, type) if ret == S_OBJECT_CREATED: ret = S_OK elif create: ret, idp = CPLDirect.cpl_create_object(prefix, name, type) else: ret, idp = CPLDirect.cpl_lookup_object(prefix, name, type) if ret == E_NOT_FOUND: raise LookupError('Not found') if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find or create' + ' provenance object: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_object(idp) return r
def control_flow_from(self, src, type=CONTROL_OP, version=None): ''' Add control flow edge of the given type from src to self. If version is specified, then add flow to dest with explicit version, else add to most recent version. Allowed types: CPL.CONTROL_OP (default) CPL.CONTROL_START CPL.CONTROL_GENERIC is an alias for CPL.CONTROL_OP. ''' if isinstance(src, cpl_object_version): if version is not None and version != VERSION_NONE: raise Exception('The version argument must be None if ' + 'src is of type cpl_object_version') _version = src.version _src = src.object elif version is None or version == VERSION_NONE: _version = src.version() _src = src else: _version = version _src = src ret = CPLDirect.cpl_control_flow_ext(self.id, _src.id, _version, type) if not CPLDirect.cpl_is_ok(ret): raise Exception('Could not add control dependency: ' + CPLDirect.cpl_error_string(ret)) return not ret == S_DUPLICATE_IGNORED
def import_document_json(self, json, bundle_name, anchor_objects=None, flags=0): ''' Imports a Prov-JSON document into the CPL as a bundle. ** Parameters ** json the JSON document in string format prefix bundle_name anchor_objects: a list of cpl_object, name tuples, can be None flags: a logical combination of CPL_J_* flags ''' if anchor_objects == None: id_name_vector = CPLDirect.cplxx_id_name_pair_vector() else: id_name_pairs = [(entry.get(0).id, entry.get(1)) for entry in anchor_objects] id_name_vector = CPLDirect.cplxx_id_name_pair_vector(id_name_pairs) ret, idp = CPLDirect.import_document_json(json, bundle_name, id_name_vector, flags) if not CPLDirect.cpl_is_ok(ret): raise CPLException( 'Error importing document:' + CPLDirect.cpl_error_string(ret), ret) return cpl_bundle(idp)
def data_flow_from(self, src, type=DATA_INPUT, version=None): ''' Add data flow edge of the given type from src to self. If version is specified, then add flow to dest with explicit version, else add to most recent version. Allowed types: CPL.DATA_INPUT (default) CPL.DATA_IPC CPL.DATA_TRANSLATION CPL.DATA_COPY CPL.DATA_GENERIC is an alias for CPL.DATA_INPUT. ''' if isinstance(src, cpl_object_version): if version is not None and version != VERSION_NONE: raise Exception('The version argument must be None if ' + 'src is of type cpl_object_version') _version = src.version _src = src.object elif version is None or version == VERSION_NONE: _version = src.version() _src = src else: _version = version _src = src ret = CPLDirect.cpl_data_flow_ext(self.id, _src.id, _version, type) if not CPLDirect.cpl_is_ok(ret): raise Exception('Could not add data dependency ' + CPLDirect.cpl_error_string(ret)) return not ret == S_DUPLICATE_IGNORED
def validate_json(self, json): ''' Checks a Prov-JSON document (in string format) for cycles and correctness. ''' ret = CPLDirect.validate_json(json) if CPLDirect.cpl_is_ok(ret.return_code): return None return ret.out_string
def lookup_object_property_wildcard(self, value): ret, idp = CPLDirect.cpl_lookup_object_property_wildcard(value) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find' + ' object property: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_object(idp) return r
def get_current_session(): ret, id = CPLDirect.cpl_get_current_session() if not CPLDirect.cpl_is_ok(ret): raise CPLException("Could not get current session " + CPLDirect.cpl_error_string(ret), ret) return id
def delete_bundle(self, bundle): ''' Delete the specified bundle and everything in it. ''' ret = CPLDirect.cpl_delete_bundle(bundle.id) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Error deleting bundle: ' + CPLDirect.cpl_error_string(ret), ret) return None
def lookup_bundle(self, name): ret, idp = CPLDirect.cpl_lookup_bundle(name) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find' + ' provenance bundle: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_bundle(idp) return r
def lookup_bundle(self, name, prefix): ret, idp = CPLDirect.cpl_lookup_object(prefix, name, BUNDLE) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find' + ' provenance bundle: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_object(idp) return r
def lookup_by_boolean_property(self, prefix, key, value): ''' Return all objects that have the key/value property specified; raise LookupError if no such object is found. ''' vp = CPLDirect.new_std_vector_cpl_id_tp() ret = CPLDirect.cpl_lookup_object_by_boolean_property(prefix, key, value, CPLDirect.cpl_cb_collect_property_lookup_vector, vp) return self.__lookup_by_property_helper(vp, ret)
def lookup_bundle(self, name): ret, idp = CPLDirect.cpl_lookup_bundle(name) if not CPLDirect.cpl_is_ok(ret): raise CPLException( 'Could not find' + ' provenance bundle: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_bundle(idp) return r
def delete_bundle(self, bundle): ''' Delete the specified bundle and everything in it. ''' ret = CPLDirect.cpl_delete_bundle(bundle.id) if not CPLDirect.cpl_is_ok(ret): raise CPLException( 'Error deleting bundle: ' + CPLDirect.cpl_error_string(ret), ret) return None
def relations(self, direction=D_ANCESTORS, flags=0): ''' Return a list of cpl_relations ''' vp = CPLDirect.new_std_vector_cpl_relation_tp() ret = CPLDirect.cpl_get_object_relations(self.id, direction, flags, CPLDirect.cpl_cb_collect_relation_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_relation_tp(vp) raise CPLException('Error retrieving relations: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cpl_relation_t(vp) l = [] if direction == D_ANCESTORS: for entry in v: a = cpl_relation(entry.id, entry.other_object_id, entry.query_object_id, entry.type, entry.bundle_id, direction) l.append(a) else: for entry in v: a = cpl_relation(entry.id, entry.query_object_id, entry.other_object_id, entry.type, entry.bundle_id, direction) l.append(a) CPLDirect.delete_std_vector_cpl_relation_tp(vp) return l
def lookup_all_objects(self, prefix, name, type, bundle): ''' Return all objects that have the specified prefix, name, type, or bundle. ''' bundle = bundle.id vp = CPLDirect.new_std_vector_cpl_id_timestamp_tp() ret = CPLDirect.cpl_lookup_object_ext( prefix, name, type, bundle, L_NO_FAIL, CPLDirect.cpl_cb_collect_id_timestamp_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_id_timestamp_tp(vp) raise CPLException( 'Unable to lookup all objects: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cpl_id_timestamp_t(vp) l = [] if v != S_NO_DATA: for e in v: l.append(cpl_object(e.id)) CPLDirect.delete_std_vector_cpl_id_timestamp_tp(vp) return l
def properties(self, key=None, version=None): ''' Return all the properties associated with the current object. If key is set to something other than None, return only those properties matching key. By default, returns properties for the current version of the object, but if version is set to a value other than CPL.VERSION_NONE, then will return properties for that version. ''' if version is None: version = VERSION_NONE vp = CPLDirect.new_std_vector_cplxx_property_entry_tp() ret = CPLDirect.cpl_get_properties(self.id, version, key, CPLDirect.cpl_cb_collect_properties_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_property_entry_tp(vp) raise Exception('Error retrieving properties: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_property_entry_t(vp) l = [] for e in v: l.append([e.key, e.value]) CPLDirect.delete_std_vector_cplxx_property_entry_tp(vp) return l
def ancestry(self, version=None, direction=D_ANCESTORS, flags=0): ''' Return a list of cpl_ancestor objects ''' if version is None: version = VERSION_NONE vp = CPLDirect.new_std_vector_cpl_ancestry_entry_tp() ret = CPLDirect.cpl_get_object_ancestry(self.id, version, direction, flags, CPLDirect.cpl_cb_collect_ancestry_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_ancestry_entry_tp(vp) raise Exception('Error retrieving ancestry: ' + CPLDirect.cpl_error_string(ret)) return None v = CPLDirect.cpl_dereference_p_std_vector_cpl_ancestry_entry_t(vp) l = [] if direction == D_ANCESTORS: for entry in v: a = cpl_ancestor(entry.other_object_id, entry.other_object_version, entry.query_object_id, entry.query_object_version, entry.type, direction) l.append(a) else: for entry in v: a = cpl_ancestor(entry.query_object_id, entry.query_object_version, entry.other_object_id, entry.other_object_version, entry.type, direction) l.append(a) CPLDirect.delete_std_vector_cpl_ancestry_entry_tp(vp) return l
def relations(self, direction=D_ANCESTORS, flags=0): ''' Return a list of cpl_relations ''' vp = CPLDirect.new_std_vector_cpl_relation_tp() ret = CPLDirect.cpl_get_object_relations(self.id, direction, flags, CPLDirect.cpl_cb_collect_relation_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_relation_tp(vp) raise CPLException('Error retrieving relations: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cpl_relation_t(vp) l = [] if direction == D_ANCESTORS: for entry in v: a = cpl_relation(entry.id, entry.other_object_id, entry.query_object_id, entry.type, direction) l.append(a) else: for entry in v: a = cpl_relation(entry.id, entry.query_object_id, entry.other_object_id, entry.type, direction) l.append(a) CPLDirect.delete_std_vector_cpl_relation_tp(vp) return l
def get_all_objects(self, fast=False): ''' Return all objects in the provenance database. If fast = True, then fetch only incomplete information about each object, so that it is faster. ''' if fast: flags = CPLDirect.CPL_I_FAST else: flags = 0 vp = CPLDirect.new_std_vector_cplxx_object_info_tp() ret = CPLDirect.cpl_get_all_objects(flags, CPLDirect.cpl_cb_collect_object_info_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) raise CPLException('Unable to get all objects: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_object_info_t(vp) l = [] if v != S_NO_DATA : for e in v: if e.bundle_id == NONE: bundle = None else: bundle = cpl_object(e.bundle_id) l.append(cpl_object_info(cpl_object(e.id), e.creation_time, e.prefix, e.name, e.type, bundle)) CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) return l
def properties(self, key=None, version=None): ''' Return all the properties associated with the current object. If key is set to something other than None, return only those properties matching key. By default, returns properties for the current version of the object, but if version is set to a value other than CPL.VERSION_NONE, then will return properties for that version. ''' if version is None: version = VERSION_NONE vp = CPLDirect.new_std_vector_cplxx_property_entry_tp() ret = CPLDirect.cpl_get_properties( self.id, version, key, CPLDirect.cpl_cb_collect_properties_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_property_entry_tp(vp) raise Exception('Error retrieving properties: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_property_entry_t(vp) l = [] for e in v: l.append([e.key, e.value]) CPLDirect.delete_std_vector_cplxx_property_entry_tp(vp) return l
def get_all_objects(self, prefix, type = 0, fast=False): ''' Return all objects in the provenance database. If fast = True, then fetch only incomplete information about each object, so that it is faster. ''' if fast: flags = CPLDirect.CPL_I_FAST else: flags = 0 vp = CPLDirect.new_std_vector_cplxx_object_info_tp() ret = CPLDirect.cpl_get_all_objects(prefix, flags, type, CPLDirect.cpl_cb_collect_object_info_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) raise CPLException('Unable to get all objects: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_object_info_t(vp) l = [] if v != S_NO_DATA : for e in v: l.append(cpl_object_info(cpl_object(e.id), e.creation_time, e.prefix, e.name, e.type)) CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) return l
def export_bundle_json(self, bundles): ''' Exports bundles as a Prov-JSON document. Only works with single bundles currently. ''' bundle_ids = [bundle.id for bundle in bundles] bundles_vec = CPLDirect.cpl_id_t_vector(bundle_ids) ret = CPLDirect.export_bundle_json(bundles_vec) if not CPLDirect.cpl_is_ok(ret.return_code): raise CPLException('Error exporting bundle:' + CPLDirect.cpl_error_string(ret.return_code), ret) return ret.out_string
def lookup_relation_to(self, dest, type): ''' Lookup relation from self to dest. ''' ret, idp = CPLDirect.cpl_lookup_relation(self.id, dest.id, type) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find' + ' relation: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_relation(idp, dest.id, self.id, type, D_ANCESTORS) return r
def lookup_relation_from(self, src, type): ''' Lookup relation from src to self. ''' ret, idp = CPLDirect.cpl_lookup_relation(src.id, self.id, type) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find' + ' relation: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_relation(idp, self.id, src.id, type, D_DESCENDANTS) return r
def relation_from(self, src, type): ''' Add relation type from src to self. ''' ret, idp = CPLDirect.cpl_add_relation(src.id, self.id, type) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not add relation: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_relation(idp, self.id, src.id, type, D_DESCENDANTS) return r
def relation_to(self, dest, type): ''' Add relation type from self to dest. ''' ret, idp = CPLDirect.cpl_add_relation(self.id, dest.id, type) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not add relation: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_relation(idp, dest.id, self.id, type, D_ANCESTORS) return r
def relation_from(self, src, type, bundle): ''' Add relation type from src to self. ''' bundle = bundle.id ret, idp = CPLDirect.cpl_add_relation(src.id, self.id, type, bundle) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not add relation: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_relation(idp, self.id, src.id, type, bundle, D_DESCENDANTS) return r
def relation_to(self, dest, type, bundle): ''' Add relation type from self to dest. ''' bundle = bundle.id ret, idp = CPLDirect.cpl_add_relation(self.id, dest.id, type, bundle) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not add relation: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_relation(idp, dest.id, self.id, type, bundle, D_ANCESTORS) return r
def close(self): ''' Close database connection and session ''' global _cpl_connection if self != _cpl_connection or self.closed: return ret = CPLDirect.cpl_detach() if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not detach ' + CPLDirect.cpl_error_string(ret), ret) _cpl_connection = None self.closed = True
def close(self): ''' Close database connection and session ''' global _cpl_connection if self != _cpl_connection or self.closed: return ret = CPLDirect.cpl_detach() if not CPLDirect.cpl_is_ok(ret): raise Exception('Could not detach ' + CPLDirect.cpl_error_string(ret)) _cpl_connection = None self.closed = True
def __init__(self, cstring="DSN=CPL;"): ''' Constructor for CPL connection. ** Parameters ** ** cstring ** Connection string for database backend ** Note ** Currently the python bindings support only ODBC connection. RDF connector coming soon. ''' global _cpl_connection self.connection_string = cstring self.closed = False def get_current_session(): idp = CPLDirect.new_cpl_id_tp() ret = CPLDirect.cpl_get_current_session(idp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_cpl_id_tp(idp) raise Exception("Could not get current session" + CPLDirect.cpl_error_string(ret)) s = CPLDirect.cpl_id_tp_value(idp) i = copy_id(s) CPLDirect.delete_cpl_id_tp(idp) return i backend = CPLDirect.new_cpl_db_backend_tpp() ret = CPLDirect.cpl_create_odbc_backend(cstring, CPLDirect.CPL_ODBC_GENERIC, backend) if not CPLDirect.cpl_is_ok(ret): raise Exception("Could not create ODBC connection" + CPLDirect.cpl_error_string(ret)) self.db = CPLDirect.cpl_dereference_pp_cpl_db_backend_t(backend) ret = CPLDirect.cpl_attach(self.db) CPLDirect.delete_cpl_db_backend_tpp(backend) if not CPLDirect.cpl_is_ok(ret): raise Exception("Could not open ODBC connection" + CPLDirect.cpl_error_string(ret)) self.session = cpl_session(get_current_session()) _cpl_connection = self
def get_current_session(): idp = CPLDirect.new_cpl_id_tp() ret = CPLDirect.cpl_get_current_session(idp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_cpl_id_tp(idp) raise Exception("Could not get current session" + CPLDirect.cpl_error_string(ret)) s = CPLDirect.cpl_id_tp_value(idp) i = copy_id(s) CPLDirect.delete_cpl_id_tp(idp) return i
def version(self): ''' Determine the current version of this provenance object ''' vp = CPLDirect.new_cpl_version_tp() ret = CPLDirect.cpl_get_version(self.id, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_cpl_version_tp(vp) raise Exception('Could not determine the version of an object: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_version_tp_value(vp) CPLDirect.delete_cpl_version_tp(vp) return v
def new_version(self): ''' Create a new version of this object and return the new version. ''' vp = CPLDirect.new_cpl_version_tp() ret = CPLDirect.cpl_new_version(self.id, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_cpl_version_tp(vp) raise Exception('Could not createa a new version of an object: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_version_tp_value(vp) CPLDirect.delete_cpl_version_tp(vp) return v
def __lookup_by_property_helper(self, vp, ret): if ret == E_NOT_FOUND: CPLDirect.delete_std_vector_cpl_id_tp(vp) raise LookupError('Not found') if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_id_tp(vp) raise CPLException('Unable to lookup by property ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cpl_id_t(vp) l = [] for e in v: l.append(cpl_object(e)) CPLDirect.delete_std_vector_cpl_id_tp(vp) return l
def copy_id(idp): ''' Construct a cpl identifier type consisting of the hi and lo values. Method calls:: id = copy_id(idp) ''' i = CPLDirect.cpl_id_t() i.hi = idp.hi i.lo = idp.lo return i
def control_flow_to(self, dest, type=CONTROL_OP, version=None): ''' Add control flow edge of type from self to dest. If version is specified, then add flow to dest with explicit version, else add to most recent version. Allowed types: CPL.CONTROL_OP (default) CPL.CONTROL_START CPL.CONTROL_GENERIC is an alias for CPL.CONTROL_OP. ''' if version is None or version == VERSION_NONE: version = self.version() ret = CPLDirect.cpl_control_flow_ext(dest.id, self.id, version, type) if not CPLDirect.cpl_is_ok(ret): raise Exception('Could not add control dependency: ' + CPLDirect.cpl_error_string(ret)) return not ret == S_DUPLICATE_IGNORED
def __create_or_lookup_cpl_object(self, prefix, name, type=None, create=None, bundle=None): ''' Create or lookup a CPL object ** Parameters ** prefix name: name type: type, type can be none for lookup create: None: lookup or create True: create only False: lookup only bundle: Id of bundle into which to place this object, can be none ''' if bundle == None: bundle_id = NONE else: bundle_id = bundle.id if create == None: ret, idp = CPLDirect.cpl_lookup_or_create_object(prefix, name, type, bundle_id) if ret == S_OBJECT_CREATED: ret = S_OK elif create: ret, idp = CPLDirect.cpl_create_object(prefix, name, type, bundle_id) else: ret, idp = CPLDirect.cpl_lookup_object(prefix, name, type, bundle_id) if ret == E_NOT_FOUND: raise LookupError('Not found') if not CPLDirect.cpl_is_ok(ret): raise CPLException('Could not find or create' + ' provenance object: ' + CPLDirect.cpl_error_string(ret), ret) r = cpl_object(idp) return r
def data_flow_to(self, dest, type=DATA_INPUT, version=None): ''' Add data flow edge of type from self to dest. If version is specified, then add flow to dest with explicit version, else add to most recent version. Allowed types: CPL.DATA_INPUT (default) CPL.DATA_IPC CPL.DATA_TRANSLATION CPL.DATA_COPY CPL.DATA_GENERIC is an alias for CPL.DATA_INPUT. ''' if version is None or version == VERSION_NONE: version = self.version() ret = CPLDirect.cpl_data_flow_ext(dest.id, self.id, version, type) if not CPLDirect.cpl_is_ok(ret): raise Exception('Could not add data dependency ' + CPLDirect.cpl_error_string(ret)) return not ret == S_DUPLICATE_IGNORED
def import_document_json(self, json, bundle_name, anchor_objects = None, flags = 0): ''' Imports a Prov-JSON document into the CPL as a bundle. ** Parameters ** json the JSON document in string format prefix bundle_name anchor_objects: a list of cpl_object, name tuples, can be None flags: a logical combination of CPL_J_* flags ''' if anchor_objects == None: id_name_vector = CPLDirect.cplxx_id_name_pair_vector() else: id_name_pairs = [(entry.get(0).id, entry.get(1)) for entry in anchor_objects] id_name_vector = CPLDirect.cplxx_id_name_pair_vector(id_name_pairs) ret, idp = CPLDirect.import_document_json(json, bundle_name, id_name_vector, flags) if not CPLDirect.cpl_is_ok(ret): raise CPLException('Error importing document:' + CPLDirect.cpl_error_string(ret), ret) return cpl_bundle(idp)
def get_bundle_objects(self, bundle): ''' Return all objects in the specified bundle. ''' vp = CPLDirect.new_std_vector_cplxx_object_info_tp() ret = CPLDirect.cpl_get_bundle_objects(bundle.id, CPLDirect.cpl_cb_collect_object_info_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) raise CPLException('Unable to lookup all objects: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_object_info_t(vp) l = [] if v != S_NO_DATA : for e in v: l.append(cpl_object(e.id)) CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) return l
def get_all_objects(self, fast=False): ''' Return all objects in the provenance database. If fast = True, then fetch only incomplete information about each object, so that it is faster. ''' if fast: flags = CPLDirect.CPL_I_FAST else: flags = 0 vp = CPLDirect.new_std_vector_cplxx_object_info_tp() ret = CPLDirect.cpl_get_all_objects( flags, CPLDirect.cpl_cb_collect_object_info_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) raise Exception('Unable to get all objects: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_object_info_t(vp) l = [] if v != S_NO_DATA: for e in v: if e.container_id == NONE or e.container_version < 0: container = None else: container = cpl_object_version(cpl_object(e.container_id), e.container_version) if e.creation_session == NONE: creation_session = None else: creation_session = cpl_session(e.creation_session) l.append( cpl_object_info(cpl_object(e.id), e.version, creation_session, e.creation_time, e.originator, e.name, e.type, container)) CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) return l
def prefixes(self, prefix): ''' Return all the prefixes associated with the current bundle. If prefix return only those properties matching prefix. ''' vp = CPLDirect.new_std_vector_cplxx_prefix_entry_tp() ret = CPLDirect.cpl_get_prefixes(self.id, prefix, CPLDirect.cpl_cb_collect_prefixes_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_prefix_entry_tp(vp) raise CPLException('Error retrieving properties: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_prefix_entry_t(vp) l = [] for e in v: l.append((e.prefix, e.iri)) CPLDirect.delete_std_vector_cplxx_prefix_entry_tp(vp) return l
def get_all_objects(self, fast=False): ''' Return all objects in the provenance database. If fast = True, then fetch only incomplete information about each object, so that it is faster. ''' if fast: flags = CPLDirect.CPL_I_FAST else: flags = 0 vp = CPLDirect.new_std_vector_cplxx_object_info_tp() ret = CPLDirect.cpl_get_all_objects(flags, CPLDirect.cpl_cb_collect_object_info_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) raise Exception('Unable to get all objects: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_object_info_t(vp) l = [] if v != S_NO_DATA : for e in v: if e.container_id == NONE or e.container_version < 0: container = None else: container = cpl_object_version(cpl_object(e.container_id), e.container_version) if e.creation_session == NONE: creation_session = None else: creation_session = cpl_session(e.creation_session) l.append(cpl_object_info(cpl_object(e.id), e.version, creation_session, e.creation_time, e.originator, e.name, e.type, container)) CPLDirect.delete_std_vector_cplxx_object_info_tp(vp) return l
def lookup_all(self, originator, name, type): ''' Return all objects that have the specified originator, name, and type (they might differ by container). ''' vp = CPLDirect.new_std_vector_cpl_id_timestamp_tp() ret = CPLDirect.cpl_lookup_object_ext(originator, name, type, L_NO_FAIL, CPLDirect.cpl_cb_collect_id_timestamp_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_id_timestamp_tp(vp) raise Exception('Unable to lookup all objects: ' + CPLDirect.cpl_error_string(ret)) v = CPLDirect.cpl_dereference_p_std_vector_cpl_id_timestamp_t(vp) l = [] if v != S_NO_DATA : for e in v: l.append(cpl_object(e.id)) CPLDirect.delete_std_vector_cpl_id_timestamp_tp(vp) return l
def lookup_all_bundles(self, name): ''' Return all bundles that have the specified name ''' vp = CPLDirect.new_std_vector_cpl_id_timestamp_tp() ret = CPLDirect.cpl_lookup_bundle_ext(name, L_NO_FAIL, CPLDirect.cpl_cb_collect_id_timestamp_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_id_timestamp_tp(vp) raise CPLException('Unable to lookup all bundles: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cpl_id_timestamp_t(vp) l = [] if v != S_NO_DATA : for e in v: l.append(cpl_object(e.id)) CPLDirect.delete_std_vector_cpl_id_timestamp_tp(vp) return l
def properties(self, prefix=None, key=None): ''' Return all the properties associated with the current relation. If key is set to something other than None, return only those properties matching key. ''' vp = CPLDirect.new_std_vector_cplxx_property_entry_tp() ret = CPLDirect.cpl_get_relation_properties(self.id, prefix, key, CPLDirect.cpl_cb_collect_properties_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cplxx_property_entry_tp(vp) raise CPLException('Error retrieving properties: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cplxx_property_entry_t(vp) l = [] for e in v: l.append([e.prefix, e.key, e.value]) CPLDirect.delete_std_vector_cplxx_property_entry_tp(vp) return l
def get_bundle_relations(self, bundle): ''' Return all relations in the specified bundle. ''' vp = CPLDirect.new_std_vector_cpl_relation_tp() ret = CPLDirect.cpl_get_bundle_relations(bundle.id, CPLDirect.cpl_cb_collect_relation_vector, vp) if not CPLDirect.cpl_is_ok(ret): CPLDirect.delete_std_vector_cpl_relation_tp(vp) raise CPLException('Error retrieving relations: ' + CPLDirect.cpl_error_string(ret), ret) v = CPLDirect.cpl_dereference_p_std_vector_cpl_relation_t(vp) l = [] for entry in v: a = cpl_relation(entry.id, entry.query_object_id, entry.other_object_id, entry.type, entry.bundle_id, D_DESCENDANTS) l.append(a) CPLDirect.delete_std_vector_cpl_relation_tp(vp) return l
def get_object_for_file(self, file_name, mode=F_CREATE_IF_DOES_NOT_EXIST): ''' Get or create (depending on the value of mode) a provenance object that corresponds to the given file on the file system. The file must already exist. Please note that the CPL internally refers to the files using their full path, so if you move the file by a utility that is not CPL-aware, a subsequent call to this function with the same file (after it has been moved or renamed) will not find the return back the same provenance object. Furthermore, beware that if you use hard links, you will get different provenance objects for different names/paths of the file. The mode can be one of the following values: * F_LOOKUP_ONLY: Perform only the lookup -- do not create the corresponding provenance object if it does not already exists. * F_CREATE_IF_DOES_NOT_EXIST: Create the corresponding provenance object if it does not already exist (this is the default). * F_ALWAYS_CREATE: Always create a new corresponding provenance object, even if it already exists. Use this if you completely overwrite the file. ''' idp = CPLDirect.new_cpl_id_tp() vp = CPLDirect.new_cpl_version_tp() ret = CPLDirect.cpl_lookup_file(file_name, mode, idp, vp) if not CPLDirect.cpl_is_ok(ret): raise Exception('Could not find or create provenance object' + ' for a file: ' + CPLDirect.cpl_error_string(ret)) r = cpl_object(idp) CPLDirect.delete_cpl_id_tp(idp) CPLDirect.delete_cpl_version_tp(vp) return r