major updates to mocha-shell

This commit is contained in:
Michael Becker 2024-03-31 00:58:51 -04:00
parent 2df465286a
commit 5e45462608
8 changed files with 287 additions and 136 deletions

View File

@ -47,9 +47,6 @@ atexit.register(readline.write_history_file, histfile)
colorama.init()
def clear():
print("\033c", end='')
class MochaShell (REPLApplication):
def print_instance_list(self, instances : list):
@ -190,32 +187,44 @@ class MochaShell (REPLApplication):
prompt += "> "
return prompt
def process_input(self, value):
parms = value.split(' ')
def interactive_create_attribute(self, attr_class : InstanceReference):
if len(parms) > 0:
att_Name = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.Name)
if parms[0] == "cd":
os.chdir(parse_cwd(parms[1]))
name = input("name: ")
if name == "":
print("please specify a name")
return None
elif parms[0] == "ls":
attr = self.oms.create_instance_of(attr_class)
self.oms.set_attribute_value(attr, att_Name, name)
return attr
def process_input(self, value, quotes):
if len(value) > 0:
if value[0] == "cd":
os.chdir(parse_cwd(value[1]))
elif value[0] == "ls":
os.system("ls --color=always")
elif parms[0] == "open":
elif value[0] == "open":
if len(parms) == 2:
if len(value) == 2:
if parms[1] == "database":
if value[1] == "database":
if len(parms) > 2:
if len(value) > 2:
self.open_file(self.oms, parms[2])
self.open_file(self.oms, value[2])
return
else:
print("usage: open database|tenant 'filename'")
elif parms[1] == "tenant":
elif value[1] == "tenant":
print("error: not implemented")
@ -224,131 +233,212 @@ class MochaShell (REPLApplication):
else:
# default to "open database ..."
self.open_file(self.oms, parms[1])
self.open_file(self.oms, value[1])
return
else:
print("usage: open database|tenant 'filename'")
elif parms[0] == "create":
elif value[0] == "create":
self.create_file(self.oms, parms[1])
if len (value) > 1:
self.open_file(self.oms, parms[1])
self.create_file(self.oms, value[1])
# print ("error: no database open, use `open filename.mql` first")
self.open_file(self.oms, value[1])
elif parms[0] == "instance":
else:
if parms[1] == "create":
print("usage: create filename.mql")
# print ("error: no database open, use `open filename.mql` first")
if len(parms) == 3:
elif value[0] == "instance":
iid = self.parse(parms[2])
inst = self.oms.create_instance_of(iid)
print(inst)
if len(value) > 1:
else:
print("usage: instance create class_iid [index]")
if value[1] == "create":
elif parms[1] == "get":
if len(value) == 3:
if len(parms) == 3:
iid = self.parse(parms[2])
print(iid)
iid = self.parse(value[2])
inst = self.oms.create_instance_of(iid)
print(inst)
elif parms[1] == "list":
else:
print("usage: instance create class_iid [index]")
if not self.oms.is_open():
self.print_error_not_open()
return
elif value[1] == "get":
ik_of = None
if len(parms) > 2:
ik_of = self.parse(parms[2])
if len(value) == 3:
iid = self.parse(value[2])
print(iid)
instances = self.oms.get_instances(ik_of)
self.print_instance_list(instances)
elif parms[0] == "attribute":
if parms[1] == "list":
if len(parms) == 3:
inst_id = self.parse(parms[2])
if inst_id is None:
print("invalid inst id " + parms[2] + " (inst not found)")
return
attrs = self.oms.get_attributes(inst_id)
self.print_instance_list_with_attribute_values(attrs, self.oms, inst_id)
else:
print ("usage: attribute list instance_id")
elif parms[1] == "get":
if len(parms) == 4:
elif value[1] == "list":
if not self.oms.is_open():
self.print_error_not_open()
return
inst_id = self.parse(parms[2])
att_id = self.parse(parms[3])
ik_of = None
if len(value) > 2:
ik_of = self.parse(value[2])
instances = self.oms.get_instances(ik_of)
self.print_instance_list(instances)
else:
print("usage: instance create|get|list")
elif value[0] == "attribute":
if len(value) > 1:
if value[1] == "create":
if len(value) > 2:
if value[2] == "text" or value[2] == "richtext":
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.TextAttribute)
if value[2] == "richtext":
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.RichTextAttribute)
attr = self.interactive_create_attribute(attrClass)
if attr is None:
return
att_MaximumLength = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.MaximumLength)
maxlen = input("maximum length (leave empty for infinite): ")
if maxlen != "":
self.oms.set_attribute_value(attr, att_MaximumLength, int(maxlen))
elif value[2] == "boolean":
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.BooleanAttribute)
attr = self.interactive_create_attribute(attrClass)
if attr is None:
return
elif value[2] == "numeric":
attrClass = self.oms.get_instance_by_global_identifier(KnownClassGuids.NumericAttribute)
attr = self.interactive_create_attribute(attrClass)
if attr is None:
return
att_MinimumValue = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.MinimumValue)
att_MaximumValue = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.MaximumValue)
if att_MinimumValue is None:
print("warning: numeric attribute `Minimum Value` is not defined")
else:
minimum_value = input("minimum value (empty for infinite): ")
if minimum_value != "":
self.oms.set_attribute_value(attr, att_MinimumValue, int(minimum_value))
if att_MaximumValue is None:
print("warning: numeric attribute `Maximum Value` is not defined")
else:
maximum_value = input("maximum value (empty for infinite): ")
if maximum_value != "":
self.oms.set_attribute_value(attr, att_MaximumValue, int(maximum_value))
else:
print("usage: attribute create text|boolean|numeric|date|xml|richtext")
else:
print("usage: attribute create text|boolean|numeric|date|xml|richtext")
if value[1] == "list":
if len(value) == 3:
inst_id = self.parse(value[2])
if inst_id is None:
print("invalid inst id " + value[2] + " (inst not found)")
return
attrs = self.oms.get_attributes(inst_id)
self.print_instance_list_with_attribute_values(attrs, self.oms, inst_id)
else:
print ("usage: attribute list instance_id")
elif value[1] == "get":
if len(value) == 4:
if not self.oms.is_open():
self.print_error_not_open()
return
inst_id = self.parse(value[2])
att_id = self.parse(value[3])
if inst_id is None:
print("invalid inst id " + self.strip(value[2]) + " (inst not found)")
return
if att_id is None:
print("invalid inst id " + self.strip(value[3]) + " (inst not found)")
return
value = self.oms.get_attribute_value(inst_id, att_id)
print(value)
else:
print("usage: attribute get inst_iid|inst_gid att_iid|att_gid")
elif value[1] == "set":
if len(value) == 5:
if not self.oms.is_open():
self.print_error_not_open()
return
inst_id = self.parse(value[2])
att_id = self.parse(value[3])
value = value[4]
if inst_id is None:
print("invalid inst id " + self.strip(value[2]) + " (inst not found)")
return
if att_id is None:
print("invalid inst id " + self.strip(value[3]) + " (inst not found)")
return
result = self.oms.set_attribute_value(inst_id, att_id, value)
if result.success:
print("ok")
else:
print ("error: " + result.message)
else:
print("usage: attribute set inst_iid|inst_gid att_iid|att_gid value")
else:
print("usage: attribute list|get|set")
elif value[0] == "relationship":
if value[1] == "list":
if len(value) == 3:
inst_id = self.parse(value[2])
if inst_id is None:
print("invalid inst id " + self.strip(parms[2]) + " (inst not found)")
return
if att_id is None:
print("invalid inst id " + self.strip(parms[3]) + " (inst not found)")
return
value = self.oms.get_attribute_value(inst_id, att_id)
print(value)
else:
print("usage: attribute get inst_iid|inst_gid att_iid|att_gid")
elif parms[1] == "set":
if len(parms) == 5:
if not self.oms.is_open():
self.print_error_not_open()
return
inst_id = self.parse(parms[2])
att_id = self.parse(parms[3])
value = parms[4]
if inst_id is None:
print("invalid inst id " + self.strip(parms[2]) + " (inst not found)")
return
if att_id is None:
print("invalid inst id " + self.strip(parms[3]) + " (inst not found)")
return
self.oms.set_attribute_value(inst_id, att_id, value)
print("ok")
else:
print("usage: attribute set inst_iid|inst_gid att_iid|att_gid value")
elif parms[0] == "relationship":
if parms[1] == "list":
if len(parms) == 3:
inst_id = self.parse(parms[2])
if inst_id is None:
print("invalid inst id " + parms[2] + " (inst not found)")
print("invalid inst id " + value[2] + " (inst not found)")
return
rels = self.oms.get_relationships(inst_id)
@ -358,9 +448,9 @@ class MochaShell (REPLApplication):
print ("usage: relationship list instance_id")
elif parms[0] == "user":
elif value[0] == "user":
if parms[1] == "list":
if value[1] == "list":
ik_User = self.oms.get_instance_by_global_identifier(KnownClassGuids.User)
ik_UserName = self.oms.get_instance_by_global_identifier(KnownAttributeGuids.UserName)
@ -378,11 +468,11 @@ class MochaShell (REPLApplication):
return
elif parms[1] == "set-password":
elif value[1] == "set-password":
if len(parms) > 2:
if len(value) > 2:
my_username = parms[2]
my_username = value[2]
my_user = self.oms.get_user_by_username(my_username)
if my_user is None:
@ -401,12 +491,12 @@ class MochaShell (REPLApplication):
print("Sorry, passwords do not match.")
return
elif parms[0] == "close":
elif value[0] == "close":
self.oms.close()
else:
print("invalid cmd '" + parms[0] + "'")
print("invalid cmd '" + value[0] + "'")
if __name__ == '__main__':

View File

@ -22,3 +22,6 @@ class InstanceKey():
return str(self.get_class_index()) + '$' + str(self.get_instance_index())
def __eq__(self, other):
return self.__class_id == other.__class_id and self.__inst_id == other.__inst_id

View File

@ -50,3 +50,6 @@ IPAddress = Guid.parse("ADE5A3C3A84E4798BC5BE08F21380208")
Token = Guid.parse("da7686b638034f1597f67f8f3ae16668")
DebugDefinitionFileName = Guid.parse("03bf47c7dc9743c8a8c9c6147bee4e1f")
MinimumValue = Guid.parse('{bc90ffdf-9b6e-444a-a484-f9d06d7f3c31}')
MaximumValue = Guid.parse('{b9353b1c-2597-4097-96eb-449a6fafcdab}')

View File

@ -14,6 +14,8 @@ BooleanAttribute = Guid.parse("{EA830448-A403-4ED9-A3D3-048D5D5C3A03}")
NumericAttribute = Guid.parse("{9DE86AF1-EFD6-4B71-9DCC-202F247C94CB}")
DateAttribute = Guid.parse("{0B7B1812-DFB4-4F25-BF6D-CEB0E1DF8744}")
RichTextAttribute = Guid.parse("{9e393eb5-0b2d-4c31-bc8c-419f9af8aee6}")
Element = Guid.parse("{91929595-3dbd-4eae-8add-6120a49797c7}")
ElementContent = Guid.parse("{f85d4f5e-c69f-4498-9913-7a8554e233a4}")

View File

@ -3,6 +3,8 @@ from ..definitions import KnownClassGuids, KnownInstanceGuids, KnownAttributeGui
from framework import Guid
from .OmsResult import OmsResult
class Oms:
def __init__(self):
pass
@ -39,18 +41,53 @@ class Oms:
return ik_current
def get_parent_class(self, instance : InstanceReference) -> InstanceReference:
ik = InstanceKey(1, instance.get_instance_key().get_class_index())
return self.get_instance_by_key(ik)
def assign_attribute(self, instance : InstanceReference, attribute : InstanceReference, value : str):
pass
def assign_relationship(self, instance : InstanceReference, relationship : InstanceReference, related_instances : InstanceReference|list):
pass
def get_attribute_value(self, inst : InstanceReference, att : InstanceReference, default_value = None):
def get_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, default_value = None):
pass
def set_attribute_value(self, inst : InstanceReference, att : InstanceReference, value):
def get_attribute_value(self, inst : InstanceReference, att : InstanceReference, default_value = None):
value = self.get_attribute_value_internal(inst, att, default_value)
pclass = self.get_parent_class(att)
if pclass is not None:
if pclass.get_global_identifier() == KnownClassGuids.NumericAttribute:
return float(value)
return value
def set_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, value):
pass
def set_attribute_value(self, inst : InstanceReference, att : InstanceReference, value) -> OmsResult:
if inst is None or att is None:
return OmsResult(False, "no value specified for instance reference: inst | att")
pclass = self.get_parent_class(att)
if pclass is not None:
if pclass.get_global_identifier() == KnownClassGuids.NumericAttribute:
try:
val = float(value)
max_val = self.get_attribute_value(att, self.get_instance_by_global_identifier(KnownAttributeGuids.MaximumValue))
min_val = self.get_attribute_value(att, self.get_instance_by_global_identifier(KnownAttributeGuids.MinimumValue))
if val < min_val or val > max_val:
return OmsResult(False, "parameter out of range: value")
except ValueError:
return OmsResult(False, "parameter type mismatch: expected int, got " + str(type(value)))
self.set_attribute_value_internal(inst, att, value)
return OmsResult.SUCCESS
def get_instance_by_key(self, key : InstanceKey):
pass
@ -103,7 +140,7 @@ class Oms:
user = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.User), global_identifier)
if password is not None:
self.assign_user_password(user, password)
self.set_user_password(user, password)
def before_init(self):
pass
@ -113,14 +150,15 @@ class Oms:
self.create_class(1, 2, 'Attribute', KnownClassGuids.Attribute)
ik_Relationship = self.create_class(1, 3, 'Relationship', KnownClassGuids.Relationship)
self.create_class(1, 4, 'Text Attribute', KnownClassGuids.TextAttribute)
self.create_class(1, 5, 'Boolean Attribute', KnownClassGuids.BooleanAttribute)
ik_TextAttribute = self.create_class(1, 4, 'Text Attribute', KnownClassGuids.TextAttribute)
ik_BooleanAttribute = self.create_class(1, 5, 'Boolean Attribute', KnownClassGuids.BooleanAttribute)
self.create_class(1, 6, 'Element', KnownClassGuids.Element)
self.create_class(1, 20, 'Numeric Attribute', KnownClassGuids.NumericAttribute)
ik_NumericAttribute = self.create_class(1, 20, 'Numeric Attribute', KnownClassGuids.NumericAttribute)
ik_RichTextAttribute = self.create_class(1, 2737, 'Rich Text Attribute', KnownClassGuids.RichTextAttribute)
self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.Name)
self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.Value)
self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.TextAttribute), KnownAttributeGuids.Token)
att_Name = self.create_instance_of(ik_TextAttribute, KnownAttributeGuids.Name)
att_Value = self.create_instance_of(ik_TextAttribute, KnownAttributeGuids.Value)
att_Token = self.create_instance_of(ik_TextAttribute, KnownAttributeGuids.Token)
rel_Relationship__has_source__Class = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.Relationship), KnownRelationshipGuids.Relationship__has_source__Class)
rel_Relationship__has_destination__Class = self.create_instance_of(self.get_instance_by_global_identifier(KnownClassGuids.Relationship), KnownRelationshipGuids.Relationship__has_destination__Class)
@ -173,6 +211,14 @@ class Oms:
self.update_relationship(rel_Class__has__Instance, None, None, None, None, rel_Instance__for__Class)
self.update_relationship(rel_Instance__for__Class, None, None, None, None, rel_Class__has__Instance)
ik_MaximumLength = self.create_instance_of(ik_NumericAttribute, KnownAttributeGuids.MaximumLength)
self.set_attribute_value(ik_MaximumLength, att_Name, "Maximum Length")
ik_MinimumValue = self.create_instance_of(ik_NumericAttribute, KnownAttributeGuids.MinimumValue)
self.set_attribute_value(ik_MinimumValue, att_Name, "Minimum Value")
ik_MaximumValue = self.create_instance_of(ik_NumericAttribute, KnownAttributeGuids.MaximumValue)
self.set_attribute_value(ik_MaximumValue, att_Name, "Maximum Value")
self.update_class_instances()
def update_relationship(self, relationship : InstanceReference, src_class : InstanceReference, type : str, dst_class : InstanceReference, singular: bool, sibling_relationship : InstanceReference):

View File

@ -0,0 +1,9 @@
class OmsResult:
def __init__(self, success : bool, message : str):
self.success = success
self.message = message
OmsResult.SUCCESS = OmsResult(True, "the operation completed successfully")

View File

@ -1 +1,2 @@
from .Oms import Oms
from .OmsResult import OmsResult

View File

@ -180,7 +180,7 @@ class SQLiteDatabaseOms (DatabaseOms):
# return retval
def get_attribute_value(self, inst : InstanceReference, att : InstanceReference, default_value = None):
def get_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, default_value = None):
if inst is None or att is None:
return None
@ -190,10 +190,7 @@ class SQLiteDatabaseOms (DatabaseOms):
return results[0][0]
return None
def set_attribute_value(self, inst : InstanceReference, att : InstanceReference, value):
if inst is None or att is None:
return
def set_attribute_value_internal(self, inst : InstanceReference, att : InstanceReference, value):
cursor = self.conn.execute("INSERT INTO attributes (src_inst_id, att_inst_id, att_value, effective_date) VALUES (?, ?, ?, CURRENT_TIMESTAMP)", [inst.dbid, att.dbid, value])
self.conn.commit()