Beispiel #1
0
 def _fetch(cls, match_spec, params=None):
     if params is None:
         params = {}
     query = graph.construct_query(match_spec=match_spec,
                                   return_spec=cls._fetch_fields)
     qret = graph.query(query, **params)
     return qret
Beispiel #2
0
    def add_relation(cls, src, dst, rel_class, rel_attrs=None, _global=False):
        query = """
        MATCH (src:Instance) WHERE id(src) = $src_id
        MATCH (dst:Instance) WHERE id(dst) = $dst_id
        MATCH (relcls:RelationClass { name: $rel_clsname })
        MERGE (src)-[:from]->(rel:Thing:RelationInstance:`%s`)-[:to]->(dst)
         ON CREATE SET rel += $rel_attrs
         ON MATCH SET rel += {clobbered: true}
        MERGE (rel)-[:instance_of]->(relcls)
        WITH src, dst, rel
         CALL apoc.create.addLabels(rel, [ $rel_clsname ]) YIELD node AS n_rel
         RETURN src, dst, n_rel;
        """ % (rel_class)

        # TODO: handle _global here properly

        assert src._id is not None
        assert dst._id is not None
        if rel_attrs is None:
            rel_attrs = {}

        assert src._oid is not None
        assert dst._oid is not None

        rel_attrs.setdefault('_oid', str(uuid_edgehash(src._oid, dst._oid)))

        LOG.debug('add-relation, query=%r' % query)
        qret = graph.query(query,
                           src_id=src._id,
                           dst_id=dst._id,
                           rel_attrs=rel_attrs,
                           rel_clsname=rel_class)
        LOG.debug('add-relation returned=%r' % qret)
        return qret
Beispiel #3
0
    def create(self, _global=False):
        query = """
        MATCH (cls:Class { name: $cls_name })
        MERGE (inst:Thing:Instance { _oid: $inst_oid })-[:instance_of]->(cls)
         SET inst = $inst_props
        WITH cls, inst
         CALL apoc.create.addLabels(inst, $inst_labels) YIELD node as n_inst
         RETURN id(n_inst) as inst_id, n_inst as inst;
        """
        obj_props = self._get_props()
        obj_labels = [self.instance_of]

        is_global = _global or self._global

        if is_global:
            obj_labels.append('Global')
            assert obj_props['_oid'] is not None
        else:
            obj_labels.append('Local')
            if obj_props.get('_oid', None) is None:
                obj_props['_oid'] = str(uuid.uuid4())

        qret = graph.query(query,
                           inst_oid=obj_props['_oid'],
                           cls_name=self.instance_of,
                           inst_labels=obj_labels,
                           inst_props=obj_props)
        assert len(qret) == 1
        retobj = qret[0]['inst']
        self._id = qret[0]['inst_id']
        self._oid = retobj['_oid']
        LOG.debug('oid set to %r (retob=%r)' % (self._oid, retobj))
        return self
Beispiel #4
0
 def delete_by_id(cls, inst_id):
     ret = graph.query('''
     MATCH (x:Instance) WHERE id(x) = $inst_id
     OPTIONAL MATCH (x)-[:to|from]-(ri:RelationInstance)-[:to|from]-()
     DETACH DELETE x, ri;
     ''',
                       inst_id=inst_id)
     return ret
Beispiel #5
0
def create_instances():
    LOG.debug('create_instances()')

    LOG.debug('create_instances() deleting existing global instances')
    graph.query("MATCH (x:Global:Instance) DETACH DELETE x;")
    graph.query("MATCH (x:Global:RelationInstance) DETACH DELETE x;")

    create_roles()
    create_topics()

    create_actions()
    create_terms()

    create_parties()
    create_documents()
    create_demo_playbook()

    graph.schema_check()
Beispiel #6
0
 def delete_by_id(cls, rel_id):
     ret = graph.query('''
     MATCH (x:RelationInstance)-[:instance_of]->(xcls:RelationClass)
      WHERE id(x) = $rel_id
     OPTIONAL MATCH (x)-[:to]->(to_inst), (x)<-[:from]-(from_inst)
     DETACH DELETE x
     RETURN to_inst, id(to_inst) as to_id, xcls.name as relcls_name, from_inst, id(from_inst) as from_id;''',
                       rel_id=rel_id)
     return ret
Beispiel #7
0
    def update_properties(cls, rel_id, new_props):
        query = '''
        MATCH (r:RelationInstance) WHERE id(r) = {rel_id}
        SET r += {new_props}
        RETURN r;
        '''

        assert rel_id > 0
        ret = graph.query(query, rel_id=rel_id, new_props=new_props)
        return ret
Beispiel #8
0
    def fetch_by_name(cls, name):
        # qret = cls._fetch(
        #     match_spec=[
        #         ['match', '(cls:%s)' % cls._type, 'cls.name = {name}'],
        #         ['optional match', '(cls)-[:isa]->(supercls:%s)' % cls._type, None]],
        #     params={'name': name})

        # TODO: fix this to use the schema better and work for other fetch_* methods as well.
        qret = graph.query("""
        MATCH (cls:Class {name: $clsname})
        OPTIONAL MATCH isa=(cls)-[:isa*1..10]->(_supercls:Class {name: "Any"})
        WITH cls, isa, extract(n IN nodes(isa) | n.scope) AS thing
        WITH cls, isa, filter(x IN thing WHERE size(x) > 0) AS clean
        RETURN cls, id(cls) as cls_id,
        labels(cls) as labels,
        nodes(isa)[1] as supercls,
        [isa_n in nodes(isa) where exists(isa_n.fields) | isa_n.fields] as isa_fields,
        coalesce(head(clean), []) as isa_scope;
        """,
                           clsname=name)

        if len(qret) == 0:
            return None
        print "=================qurrr===", qret
        # if len(qret[0]) > 1:
        #     raise ValueError('%s.fetch_by_name returned more than 1 result'%cls._type, qret)

        row = qret[0]
        clsdata = copy(dict(row['cls']))
        clsdata['_id'] = row['cls_id']
        clsdata['_labels'] = row['labels']
        clsdata['supercls'] = dict(row['supercls']).get('name')
        LOG.debug('clsdata=%r' % clsdata)
        if clsdata.get('fields', None) is not None:
            #print 'fields=%r' % clsdata['fields']
            try:
                fieldata = json.loads(clsdata['fields'])
            except:
                fieldata = None

        if not fieldata:
            # walk the isa hierarchy and look for field defs
            for parent_fieldspec in row['isa_fields'] or []:
                if parent_fieldspec and json.loads(parent_fieldspec):
                    clsdata['fields'] = parent_fieldspec
                    break

        LOG.debug('loading %r' % clsdata)
        obj = cls.get_schema().load(clsdata)
        if obj.errors:
            raise ValueError('error objectifying', obj.errors)
        return obj.data
Beispiel #9
0
def destroy_and_refixture():
    LOG.debug('destroy_and_refixture()')
    #graph.db_handle().delete_all()

    recreate_constraints()

    LOG.debug(graph.query('match (n) return count(distinct n)'))
    create_classes()
    create_relationships()
    # LOG.debug('classes#={!r}'.format(graph.query('match (c:Class) return count(distinct c)')))
    # LOG.debug('relationclasses#={!r}'.format(graph.query('match (rc:RelationClass) return count(distinct rc)')))
    graph.dump_info()
    graph.schema_check()
Beispiel #10
0
    def update_properties(cls, inst_id, new_props):
        assert inst_id is not None
        assert inst_id > 0
        assert '_oid' not in new_props  # don't allow changing IDs of things

        ret = graph.query('''
        MATCH (x:Instance) WHERE id(x) = $inst_id
        SET x += $new_props
        RETURN x;
        ''',
                          inst_id=inst_id,
                          new_props=new_props)
        return ret
Beispiel #11
0
    def create(self, _global=False):
        if self.supercls is not None:
            create_query = """
            MATCH (supercls:`%s` { name: $supername }),
              (domcls:Class { name: $domname }),
              (rangecls:Class { name: $rangename })
            MERGE (relcls:Thing:`%s` { name: $clsname })-[:isa]->(supercls)
             SET relcls += $props
            MERGE (relcls)-[:domain]->(domcls)
            MERGE (relcls)-[:range]->(rangecls)
            WITH relcls
             CALL apoc.create.addLabels(relcls, $cls_labels) YIELD node AS n_rel
             RETURN id(n_rel) as relcls_id;
            """ % (self._type, self._type)
        else:
            create_query = """
            MATCH (domcls:Class { name: $domname }), (rangecls:Class { name: $rangename })
            MERGE (relcls:Thing:`%s` { name: $clsname })
             SET relcls += $props
            MERGE (relcls)-[:domain]->(domcls)
            MERGE (relcls)-[:range]->(rangecls)
            WITH relcls
             CALL apoc.create.addLabels(relcls, $cls_labels) YIELD node AS n_rel
             RETURN id(n_rel) as relcls_id;
            """ % self._type

        #print 'query=%s' % create_query

        obj_props = self._get_props()
        obj_labels = [self.name]

        is_global = _global or self._global

        if is_global:
            obj_labels.append('Global')
            assert obj_props['_oid'] is not None
        else:
            obj_labels.append('Local')
            obj_props.setdefault('_oid', str(uuid.uuid4()))

        qret = graph.query(create_query,
                           supername=self.supercls,
                           cls_labels=obj_labels,
                           clsname=self.name,
                           domname=self.domain,
                           rangename=self.range,
                           props=self._get_props())
        #assert len(qret) == 1
        self._id = qret[0]['relcls_id']
        return qret
Beispiel #12
0
def recreate_constraints(ns_suffix=''):
    LOG.debug('recreate_constraints()')
    cons = graph.get_constraints()
    LOG.debug('constraints={!r}'.format(cons))
    for c in cons:
        drop_query = 'DROP %s' % c
        ret = graph.query(drop_query)
        cons2 = graph.get_constraints()
        graph.add_unique_constraint('Thing%s' % ns_suffix, '_oid')
        graph.add_unique_constraint('Class', 'name')
        graph.add_unique_constraint('RelationClass', 'name')

    cons3 = graph.get_constraints()

    new_cons = list(set(cons3) - set(cons))
    if len(new_cons):
        LOG.debug("New constraints: {!r}".format(new_cons))
Beispiel #13
0
    def fetch_by_id(cls, inst_id):
        ret = graph.query("""
        MATCH (x:Instance)-[:instance_of]->(cx:Class)
        WHERE id(x) = $inst_id
        RETURN x, cx, id(x) as x_id LIMIT 1;
        """,
                          inst_id=inst_id)
        # TODO: parse/objectify this with a schema
        if len(ret):
            raw_obj = ret[0]['x']
            obj = Instance(class_name=dict(ret[0]['cx'])['name'],
                           **dict(raw_obj))
            #obj.class_name = dict(ret[0]['cx'])['name']
            obj._id = ret[0]['x_id']

            return obj
        else:
            LOG.debug('no Instance found for id: ', inst_id)
            return None
Beispiel #14
0
    def create(self, _global=False):
        if self.supercls is not None:
            create_query = """
            MATCH (supercls:%s {name: $supername})
            MERGE  (cls:Thing:`%s` {name: $clsname})
             SET cls += $props
            MERGE (cls)-[:isa]->(supercls)
            WITH cls
            CALL apoc.create.addLabels(cls, $clslabels) YIELD node AS n_cls
            RETURN id(n_cls) as cls_id;
            """ % (self._type, self._type)
        else:
            create_query = """
            MERGE (cls:Thing:`%s` {name: $clsname})
             SET cls += $props
            WITH cls
            CALL apoc.create.addLabels(cls, $clslabels) YIELD node AS n_cls
            RETURN id(n_cls) as cls_id;
            """ % self._type

        obj_props = self._get_props()
        obj_labels = [self.name]

        is_global = _global or self._global
        print "is---->", is_global
        if is_global:
            obj_labels.append('Global')
            assert obj_props['_oid'] is not None
        else:
            obj_labels.append('Local')
            obj_props.setdefault('_oid', str(uuid.uuid4()))

        qret = graph.query(create_query,
                           supername=self.supercls,
                           clslabels=obj_labels,
                           clsname=self.name,
                           props=self._get_props())

        #assert len(qret) == 1
        self._id = qret[0]['cls_id']
        return qret
Beispiel #15
0
 def fetch_by_id(cls, relinst_id):
     ret = graph.query("""
     MATCH (x:RelationInstance)-[:instance_of]->(cx:RelationClass)
     WHERE id(x) = $rel_id
     OPTIONAL MATCH (x)<-[:from]-(from:Instance)-[:instance_of]->(fromcls:Class),
      (x)-[:to]->(to:Instance)-[:instance_of]->(tocls:Class)
     RETURN x, cx, id(x) as x_id,
            from, id(from) as from_id, to, id(to) as to_id,
            fromcls.name as from_cls, tocls.name as to_cls
     LIMIT 1
     """,
                       rel_id=relinst_id)
     # TODO: parse/objectify this with a schema
     if len(ret):
         row = ret[0]
         rel_obj = copy(dict(row['x']))
         rel_obj['class_name'] = dict(row['cx'])['name']
         rel_obj['_id'] = row['x_id']
         rel_obj['dst'] = {'_id': row['to_id'], 'class': row['to_cls']}
         rel_obj['src'] = {'_id': row['from_id'], 'class': row['from_cls']}
         return rel_obj
     else:
         print 'no RelationInstance found for id: ', relinst_id
         return None
Beispiel #16
0
 def get(self, inst_class=None):
     if inst_class:
         return 'class=%s' % inst_class
     return graph.query(
         'match (x:Instance)-[:instance_of]->(c:Class) return id(x) as id, properties(x) as props, c.name as class;'
     ), 200
Beispiel #17
0
def destroy_instances():
    graph.query("MATCH (x:Instance) DETACH DELETE x;")
    graph.query("MATCH (x:RelationInstance) DETACH DELETE x;")