class RelTemplateCypher(): def __init__(self, parent=None, templateDict=None): self.parent = parent self.templateDict = templateDict self.type = "Relationship" self.helper = Helper() # this determines if the DataGridWidget should call genMatch on a grid refresh or should it suppy it's own cypher def isGeneric(self, ): return False # set which button driven functionality will be enabled def refreshOK(self, ): return True def exportOK(self, ): return True def newOK(self, ): return True def deleteOK(self, ): return True def rowSelect(self, ): return False def setNullOK(self, ): return True def genDeleteDetach(self, row=None, dataGrid=None): model = dataGrid.model() # get the relID self.relID = None for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "rel_id": self.relID = model.item(row, header).data(Qt.EditRole) if not self.relID is None: p1 = self.relID cypher = " ".join( ["match (f)-[r]->(t) \n", "where id(r) = {} \n", "delete r"]).format(p1) return cypher def genUpdateProp(self, updateIndex=None, dataGrid=None): cypher = "" rc = True model = dataGrid.model() # get the RELATIONSHIP ID self.relID = None for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "rel_id": self.relID = model.item(updateIndex.row(), header).data(Qt.EditRole) if self.relID is None: return False, "Relationship ID not found." try: self.updateData = model.item( updateIndex.row(), updateIndex.column()).data(Qt.EditRole) self.updateProp = model.headerData(updateIndex.column(), Qt.Horizontal, Qt.DisplayRole) # get the correct neo4j type neoType = model.item(updateIndex.row(), updateIndex.column()).data(Qt.UserRole + 1) # if the datatype comes back unknown then generate cypher comment if neoType == 'Unknown': cypher = "Can't update unknown datatype, correct datatype in relationship template." rc = False else: # generate the correct syntax that you set the property equal to self.setEqualTo = self.helper.genPropEqualTo( dataValue=self.updateData, neoType=neoType) p1 = self.relID p2 = self.updateProp p3 = self.setEqualTo cypher = " ".join([ "match (f)-[r]->(t) \n", "where id(r) = {} \n", "set r.{} = {}" ]).format(p1, p2, p3) rc = True except BaseException as e: # something went wrong cypher = "Error generating cypher: {}".format(repr(e)) rc = False finally: return rc, cypher def genRemoveProp(self, updateIndex=None, dataGrid=None): model = dataGrid.model() cypher = None self.relID = None # get the relID for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "rel_id": self.relID = model.item(updateIndex.row(), header).data(Qt.EditRole) if self.relID is None: return cypher # get the property name self.updateProp = model.headerData(updateIndex.column(), Qt.Horizontal, Qt.DisplayRole) # MAKE SURE IT ISN'T A REQUIRED PROPERTY for prop in self.templateDict["properties"]: if prop[PROPERTY] == self.updateProp: if prop[PROPREQ] != Qt.Checked: p1 = self.relID p2 = self.updateProp cypher = "match (f)-[r]->(t) \n where id(r) = {} \n remove r.{} ".format( p1, p2) else: self.helper.displayErrMsg( "Set Null", "Property {} is required by the Relationship Template. Cannot remove this property." .format(self.updateProp)) return cypher def genMatch(self): ''' Generate the match cypher statement that the data grid will use to refresh the grid. Generate the editParmDict dictionary that tells the data grid how to handle each column in the result set ''' # fromNodeVar = "f" # toNodeVar = "t" relVar = "r" p1 = self.templateDict["relname"] p3 = self.genReturnPropList(relVar) if len(p3) > 1: p2 = "," else: p2 = "" cypher = " ".join([ "match (f)-[r]->(t) \n", "where type(r) = '{}' \n", "return id(f) as From_NodeID, \n", "id(t) as To_NodeID, \n", "id(r) as rel_id, \n", "type(r) as rel_name {} \n", "{} \n", ]).format(p1, p2, p3) #PROP, REQLBL, OPTLBL, NODEID, RELID, NODE, RELATIONSHIP, RELNAME editParmDict = [] editParmDict.append([NODEID, False]) editParmDict.append([NODEID, False]) editParmDict.append([RELID, False]) editParmDict.append([RELNAME, False]) for prop in self.templateDict["properties"]: editParmDict.append([PROP, True]) return cypher, editParmDict def genReturnPropList(self, nodeName): 'return all properties in the template' propList = "" propList = ",".join(nodeName + "." + x[PROPERTY] + " as " + x[PROPERTY] + " \n" for x in self.templateDict["properties"]) return propList def genSetPropList(self, nodeName): 'return a set statement for each property that has a default value (i.e. required)' setPropList = [] if not self.templateDict is None: for prop in self.templateDict["properties"]: # if the property has a default value then generate the set statement. if prop[PROPDEF] != "": # generate the correct syntax that you set the property equal to setEqualTo = self.helper.genPropEqualTo( dataValue=prop[PROPDEF], neoType=prop[DATATYPE]) setPropList.append("set {}.{} = {}".format( nodeName, prop[PROPERTY], setEqualTo)) setProps = " \n ".join(setProp for setProp in setPropList) return setProps
class NodeTemplateCypher(): def __init__(self, parent=None, templateDict=None): self.parent = parent self.templateDict = templateDict self.type = "Node" self.helper = Helper() # this determines if the DataGridWidget should call genMatch on a grid refresh or should it suppy it's own cypher def isGeneric(self, ): return False # set which button driven functionality will be enabled def refreshOK(self, ): return True def exportOK(self, ): return True def newOK(self, ): return True def deleteOK(self, ): return True def rowSelect(self, ): return False def setNullOK(self, ): return True def genDeleteDetach(self, row=None, dataGrid=None): model = dataGrid.model() # get the nodeID self.nodeID = "no node" for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "nodeID": self.nodeID = model.item(row, header).data(Qt.EditRole) cypher = 'match (n) \n where id(n) = {} \n detach delete n'.format( self.nodeID) return cypher def genUpdateLabel(self, updateIndex=None, dataGrid=None): model = dataGrid.model() # get the nodeID for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "nodeID": self.nodeID = model.item(updateIndex.row(), header).data(Qt.EditRole) # get if the checkbox is checked or not if model.item(updateIndex.row(), updateIndex.column()).checkState() == Qt.Checked: self.operation = "Set" else: self.operation = "Remove" # get the label name self.updateLabel = model.headerData(updateIndex.column(), Qt.Horizontal, Qt.DisplayRole) p1 = self.nodeID p2 = self.operation p3 = self.updateLabel cypher = 'match (n) \n where id(n) = {} \n {} n:{} '.format( p1, p2, p3) return cypher def genUpdateProp(self, updateIndex=None, dataGrid=None): cypher = "" rc = True model = dataGrid.model() self.nodeID = None # get the nodeID for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "nodeID": self.nodeID = model.item(updateIndex.row(), header).data(Qt.EditRole) if self.nodeID is None: return False, "Node ID not found." try: # get the new data value which is a string self.updateData = model.item( updateIndex.row(), updateIndex.column()).data(Qt.EditRole) # get the property name self.updateProp = model.headerData(updateIndex.column(), Qt.Horizontal, Qt.DisplayRole) # get the correct neo4j type neoType = model.item(updateIndex.row(), updateIndex.column()).data(Qt.UserRole + 1) # if the datatype comes back unknown then generate cypher comment if neoType == 'Unknown': cypher = "Can't update unknown datatype, correct datatype in node template." rc = False else: # generate the correct syntax that you set the property equal to self.setEqualTo = self.helper.genPropEqualTo( dataValue=self.updateData, neoType=neoType) p1 = self.nodeID p2 = self.updateProp p3 = self.setEqualTo cypher = "match (n) \n where id(n) = {} \n set n.{} = {} ".format( p1, p2, p3) rc = True except BaseException as e: # something went wrong cypher = "Error generating cypher: {}".format(repr(e)) rc = False finally: return rc, cypher def genRemoveProp(self, updateIndex=None, dataGrid=None): model = dataGrid.model() cypher = None self.nodeID = None # get the nodeID for header in range(model.columnCount()): if model.headerData(header, Qt.Horizontal, Qt.DisplayRole) == "nodeID": self.nodeID = model.item(updateIndex.row(), header).data(Qt.EditRole) if self.nodeID is None: return cypher # get the property name self.updateProp = model.headerData(updateIndex.column(), Qt.Horizontal, Qt.DisplayRole) # MAKE SURE IT ISN'T A REQUIRED PROPERTY for prop in self.templateDict["properties"]: if prop[PROPERTY] == self.updateProp: if prop[PROPREQ] != Qt.Checked: p1 = self.nodeID p2 = self.updateProp cypher = "match (n) \n where id(n) = {} \n remove n.{} ".format( p1, p2) else: self.helper.displayErrMsg( "Set Null", "Property {} is required by the Node Template. Cannot remove this property." .format(self.updateProp)) return cypher def genNewNode(self): nodeName = "n" p1 = self.genWhereLabelList(nodeName) p11 = self.genSetPropList(nodeName) p2 = " id(" + nodeName + ") as nodeID " p3 = self.genReturnLblList(nodeName) p4 = self.genReturnPropList(nodeName) if p3 != "": p2 = p2 + " , " if p4 != "" and p3 != "": p3 = p3 + " , " if p4 != "" and p3 == "": p2 = p2 + " , " cypher = 'create ({}) \n {} \n return {} \n {} \n {} '.format( p1, p11, p2, p3, p4) return cypher def genMatchReturnNodeOnly(self): nodeName = "n" p1 = self.genWhereLabelList(nodeName) if len(p1) > 0: p1 = " where " + p1 p2 = " id(" + nodeName + ") as nodeID " p3 = " n as Node" cypher = 'match (n) \n {} \n return {}, \n {} '.format(p1, p2, p3) #PROP, REQLBL, OPTLBL, NODEID, RELID, NODE, RELATIONSHIP editParmDict = [] editParmDict.append([NODEID, False]) # editParmDict.append( [PROP, False] ) # editParmDict.append( [NODE, False] ) for label in self.templateDict["labels"]: if label[REQUIRED] == 2: editParmDict.append([REQLBL, False]) else: editParmDict.append([OPTLBL, True]) for prop in self.templateDict["properties"]: editParmDict.append([PROP, True]) return cypher, editParmDict def genMatch(self): nodeName = "n" p1 = self.genWhereLabelList(nodeName) if len(p1) > 0: p1 = " where " + p1 # p2 = " id(" + nodeName + ") as nodeID, \n n.NZID, \n n as Node " p2 = " id(" + nodeName + ") as nodeID " p3 = self.genReturnLblList(nodeName) p4 = self.genReturnPropList(nodeName) if p3 != "": p2 = p2 + " , " if p4 != "" and p3 != "": p3 = p3 + " , " if p4 != "" and p3 == "": p2 = p2 + " , " cypher = 'match (n) \n {} \n return {} \n {} \n {} '.format( p1, p2, p3, p4) #PROP, REQLBL, OPTLBL, NODEID, RELID, NODE, RELATIONSHIP editParmDict = [] editParmDict.append([NODEID, False]) # editParmDict.append( [PROP, False] ) # editParmDict.append( [NODE, False] ) for label in self.templateDict["labels"]: if label[REQUIRED] == 2: editParmDict.append([REQLBL, False]) else: editParmDict.append([OPTLBL, True]) for prop in self.templateDict["properties"]: editParmDict.append([PROP, True]) return cypher, editParmDict def genWhereLabelList(self, nodeName): 'only check for labels that are marked required' lblList = "" if len(self.templateDict["labels"]) > 0: lblList = nodeName + ":" + ":".join( x[LABEL] for x in self.templateDict["labels"] if x[REQUIRED] == 2) return lblList def genReturnPropList(self, nodeName): 'return all properties in the template' propList = "" propList = ",".join(nodeName + "." + x[PROPERTY] + " as " + x[PROPERTY] for x in self.templateDict["properties"]) return propList def genReturnLblList(self, nodeName): 'return all labels in the template' lblList = "" lblList = ",".join(nodeName + ":" + x[LABEL] + " as " + x[LABEL] for x in self.templateDict["labels"]) return lblList def genSetPropList(self, nodeName): 'return a set statement for each property that has a default value (i.e. required)' setPropList = [] if not self.templateDict is None: for prop in self.templateDict["properties"]: # if the property has a default value then generate the set statement. if prop[PROPDEF] != "": # generate the correct syntax that you set the property equal to setEqualTo = self.helper.genPropEqualTo( dataValue=prop[PROPDEF], neoType=prop[DATATYPE]) setPropList.append("set {}.{} = {}".format( nodeName, prop[PROPERTY], setEqualTo)) setProps = " \n ".join(setProp for setProp in setPropList) return setProps