226 lines
8.2 KiB
Python

import MySQLdb
from .libraryparser import XMLLibraryParser, JSONLibraryParser, YAMLLibraryParser
from .LibraryOperation import LibraryOperation
from .operations.AssignAttributeOperation import AssignAttributeOperation
from .operations.AssignRelationshipOperation import AssignRelationshipOperation
from .operations.CreateClassOperation import CreateClassOperation
from .operations.CreateInstanceOperation import CreateInstanceOperation
from .operations.PrepareInstanceOperation import PrepareInstanceOperation
from .operations.StoredProcedureOperation import StoredProcedureOperation
from .Guid import Guid
class MochaLibraryManager:
def __init__(self):
self.entityReferences = dict()
self.db = None
self._instances = []
self._operations = []
self._relOps = []
def connect(self, hostname, database, username, password):
self.db = MySQLdb.connect(host=hostname, user=username, passwd=password, db=database)
def commit(self):
for (class_gid, inst_gid, class_index, index) in self._instances:
if class_index is None and class_gid is not None:
# class_index = self.db.query("SELECT inst_id FROM mocha_instances WHERE tenant_id = 1 AND id = mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + class_gid + "'))")
# class_index = (SELECT inst_id FROM mocha_instances WHERE tenant_id = p_tenant_id AND id = mocha_get_instance_by_global_identifier(p_class_global_identifier));
op = PrepareInstanceOperation(Guid(class_gid), Guid(inst_gid), class_index, index)
op.execute(self.db)
for op in self._operations:
op.execute(self.db)
for op in self._relOps:
op.execute(self.db)
hasSiblingRelationships = dict()
for op in self._relOps:
if op.relationshipInstanceId.get_value() == "{656110FF-4502-48B8-A7F3-D07F017AEA3F}":
# Relationship.has sibling Relationship
hasSiblingRelationships[op.instanceId.get_value()] = op.targetInstanceId
for op in self._relOps:
if op.relationshipInstanceId.get_value() in hasSiblingRelationships:
siblingOp = AssignRelationshipOperation(op.targetInstanceId, hasSiblingRelationships[op.relationshipInstanceId.get_value()], op.instanceId)
print ("assigning sibling relationship " + siblingOp.instanceId.get_value() + " . " + siblingOp.relationshipInstanceId.get_value() + " = " + siblingOp.instanceId.get_value() + "\n")
siblingOp.execute(self.db)
cur = self.db.cursor()
# cur.execute("UPDATE mocha_instances SET user_inst_id = mocha_get_instance_by_global_identifier(mocha_normalize_uuid('{B066A54B-B160-4510-A805-436D3F90C2E6}'))")
cur.execute("UPDATE mocha_attributes SET usr_inst_id = mocha_get_instance_by_global_identifier(mocha_normalize_uuid('{B066A54B-B160-4510-A805-436D3F90C2E6}'))")
cur.execute("UPDATE mocha_relationships SET user_inst_id = mocha_get_instance_by_global_identifier(mocha_normalize_uuid('{B066A54B-B160-4510-A805-436D3F90C2E6}'))")
# rows = cur.fetchall()
# print(rows)
# print ("ok , applying `Class.has Instance`...")
# for row in rows:
# print(row)
# id = row[0]
# tenant_id = row[1]
# class_id = row[2]
# inst_id = row[3]
# global_identifier = row[4]
# if class_id is not None and id is not None:
# # Class.has Instance
# query2 = ("CALL mocha_assign_relationship (" +
# "mocha_get_instance_by_key(1, " + str(class_id) + "), " +
# "mocha_get_instance_by_global_identifier(mocha_normalize_uuid('7EB41D3C-2AE9-4884-83A4-E59441BCAEFB'))" + ", " +
# str(id) + ", NULL, NULL)")
# cur.execute(query2)
# # Instance.for Class
# query3 = ("CALL mocha_assign_relationship (" +
# str(id) + ", " +
# "mocha_get_instance_by_global_identifier(mocha_normalize_uuid('494D5A6D-04BE-477B-8763-E3F57D0DD8C8'))" + ", " +
# "mocha_get_instance_by_key(1, " + str(class_id) + "), NULL, NULL)")
# cur.execute(query3)
self.db.commit()
def close(self):
self.db.close()
def print_error(self, cur):
rows = cur.fetchall()
for row in rows:
if 'error_description' in row:
print (row['error_description'])
def select_tenant(self, tenantName):
cur = self.db.cursor()
cur.execute("CALL mocha_select_tenant(mocha_get_tenant_by_name('" + tenantName + "'))")
self.print_error(cur)
def release_tenant(self):
cur = self.db.cursor()
cur.execute("CALL mocha_release_tenant()")
self.print_error(cur)
def assign_relationship(self, instanceId : Guid, relationshipInstanceId : Guid, targetInstanceId : Guid):
print("-- assigning relationship " + relationshipInstanceId.get_value() + " = '" + targetInstanceId.get_value() + "'")
self._relOps.append(AssignRelationshipOperation(instanceId, relationshipInstanceId, targetInstanceId))
# self._operations.append(AssignRelationshipOperation(instanceId, relationshipInstanceId, targetInstanceId))
# query = "CALL mocha_assign_relationship(mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + instanceId.get_value() + "')), mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + relationshipInstanceId.get_value() + "')), mocha_get_instance_by_global_identifier(mocha_normalize_uuid('" + targetInstanceId.get_value() + "')), NULL, NULL);"
# print(query)
# cur.execute(query)
# self.print_error(cur)
def set_attribute_value(self, instanceId : Guid, attributeInstanceId : Guid, value):
print("-- assigning attribute " + attributeInstanceId.get_value() + " = '" + str(value) + "'")
self._operations.append(AssignAttributeOperation(instanceId, attributeInstanceId, value))
def install_from_path(self, path):
from glob import glob
xl = XMLLibraryParser(self)
jl = JSONLibraryParser(self)
yl = YAMLLibraryParser(self)
#xml_files = glob(path + "/**/*.xml", recursive=True)
#for xml_file in xml_files:
#s xl.load_file(xml_file)
#json_files = glob(path + "/**/*.json", recursive=True)
#for json_file in json_files:
# jl.load_file(json_file)
yaml_files = sorted(glob(path + "/**/*.yaml", recursive=True))
if len(yaml_files) == 0:
print ("no files found ; does the path exist?")
return 3
# first, load the entity defs
for yaml_file in yaml_files:
yl.load_entity_definitions_from_file(yaml_file)
try:
# then, load instance definitions (also loads sugar elements into memory for later use)
for yaml_file in yaml_files:
yl.load_instances_from_file(yaml_file)
# finally, apply syntactic sugar
yl.apply_sugar()
return True
except NameError as ex:
print (ex)
rgx = "&(.*);"
# go through and get all entity references across all files
import re
import fileinput
stuff = []
for yaml_file in yaml_files:
f = open(yaml_file, "r")
text = f.read()
matches = re.findall(rgx, text)
for match in matches:
stuff.append(match)
f.close()
missingEntities = []
for stuf in stuff:
if not stuf in self.entityReferences:
if not stuf in missingEntities:
missingEntities.append(stuf)
if len(missingEntities) > 0:
print("\nNOTE: there were undefined referenced entities:\n")
for missingEntity in missingEntities:
print("\t" + missingEntity)
print("\n")
return False
def register_entity_reference(self, name, value):
self.entityReferences[name] = value
def define_entity_reference(self, name):
return self.entityReferences[name]
def expand_entity_references(self, value):
insideName = False
name = ""
retval = ""
for i in range(0, len(value)):
if value[i] == "&":
insideName = True
elif value[i] == ';':
insideName = False
if name in self.entityReferences:
retval += self.define_entity_reference(name)
else:
raise NameError("unknown entity ref '" + name + "'")
name = ""
elif insideName:
name += value[i]
else:
retval += value[i]
return retval
def add_instance(self, classGid : Guid, instGid : Guid, classIndex : int, index : int):
print("adding instance for class '" + classGid.get_value() + "' with globalid '" + instGid.get_value() + "' [" + str(index) + "]")
self._instances.append((classGid.get_value(), instGid.get_value(), classIndex, index))
# assign relationship `Instance.for Class`
self.assign_relationship(instGid, Guid('494D5A6D04BE477B8763E3F57D0DD8C8'), classGid)
# assign relationship `Class.has Instance`
self.assign_relationship(classGid, Guid('7EB41D3C2AE9488483A4E59441BCAEFB'), instGid)