From bed7bfaa453861040b7b334165546fe52b94de19 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sat, 10 Feb 2024 01:00:03 -0500 Subject: [PATCH] preliminary clearUNTESTEDclearUSE CAUTIONclear support for multiple tenants IT'S ABOUT TIME --- common/admin/mocha-libexec/mocha-oms | 2 +- .../000-EntityDefinitions/000-Module.yaml | 2 +- .../999-Tenants/001-ryderentals-prod.yaml | 3 - .../999-Tenants/ryderentals-prod/tenant.yaml | 5 + .../ryderentals-prod/users}/btrevino.yaml | 5 +- .../brooke-trevino.yaml | 6 - .../003-Classes/02737-RichTextAttribute.yaml | 30 +++ .../Tasks/RichTextAttribute.yaml | 64 +++++++ .../Tasks/SystemUser/Common.yaml | 8 +- .../lib/mocha/core/KnownClassGuids.inc.php | 1 + .../lib/mocha/oms/MySQLDatabaseOms.inc.php | 144 ++++++++++---- php/mocha/lib/mocha/system.inc.php | 1 + .../mocha/ui/renderers/html/Editor.inc.php | 21 ++ .../ui/renderers/html/HTMLRenderer.inc.php | 179 ++++++++++++++--- php/mocha/scripts/mcx-elementcontent.js | 4 + php/mocha/themes/avondale/uwt-alert.less | 6 + .../themes/avondale/uwt-richtextbox.less | 10 + php/mocha/themes/avondale/uwt-textbox.less | 6 + php/mocha/themes/avondale/uwt.less | 1 + php/mocha/ui/pages/LoginPage.phpx.php | 9 +- php/mocha/ui/pages/OTSPage.phpx.php | 181 +++++++++++++++--- .../__pycache__/InstanceKey.cpython-311.pyc | Bin 0 -> 1834 bytes .../InstanceReference.cpython-311.pyc | Bin 0 -> 1586 bytes .../TenantReference.cpython-311.pyc | Bin 0 -> 1271 bytes .../core/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 338 bytes .../mocha/oms/__pycache__/Oms.cpython-311.pyc | Bin 0 -> 1225 bytes .../oms/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 217 bytes .../__pycache__/MemoryOms.cpython-311.pyc | Bin 0 -> 908 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 230 bytes .../WebRequestHandler.cpython-311.pyc | Bin 0 -> 13708 bytes .../web/__pycache__/WebServer.cpython-311.pyc | Bin 0 -> 1294 bytes ...ocha_get_instance_by_global_identifier.sql | 3 +- .../mocha_get_instance_by_key.sql | 10 +- .../mocha_get_user_by_username.sql | 2 +- .../mocha_create_instance_of.sql | 4 +- .../mocha_get_attribute_value.sql | 4 +- ...ocha_get_instance_by_global_identifier.sql | 6 +- .../mocha_get_instance_by_key.sql | 2 +- sql/mysql/002-tables/000-mocha_tenants.sql | 3 +- ...ocha_tenants.sql => 001-mocha_tenants.sql} | 12 +- .../003-data/002-mocha_tenant_references.sql | 9 + sql/mysql/003-data/mocha_instances.sql | 129 ------------- 42 files changed, 628 insertions(+), 244 deletions(-) delete mode 100644 common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/001-ryderentals-prod.yaml create mode 100644 common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/tenant.yaml rename common/libraries/yaml/{net.alcetech.Mocha.System/999-Random/Home/Users => com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/users}/btrevino.yaml (90%) delete mode 100644 common/libraries/yaml/com.mochapowered.VehiclesForHire/brooke-trevino.yaml create mode 100644 common/libraries/yaml/net.alcetech.Mocha.System/003-Classes/02737-RichTextAttribute.yaml create mode 100644 common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/RichTextAttribute.yaml create mode 100644 php/mocha/lib/mocha/ui/renderers/html/Editor.inc.php create mode 100644 php/mocha/themes/avondale/uwt-richtextbox.less create mode 100644 python/mocha/core/__pycache__/InstanceKey.cpython-311.pyc create mode 100644 python/mocha/core/__pycache__/InstanceReference.cpython-311.pyc create mode 100644 python/mocha/core/__pycache__/TenantReference.cpython-311.pyc create mode 100644 python/mocha/core/__pycache__/__init__.cpython-311.pyc create mode 100644 python/mocha/oms/__pycache__/Oms.cpython-311.pyc create mode 100644 python/mocha/oms/__pycache__/__init__.cpython-311.pyc create mode 100644 python/mocha/oms/memory/__pycache__/MemoryOms.cpython-311.pyc create mode 100644 python/mocha/oms/memory/__pycache__/__init__.cpython-311.pyc create mode 100644 python/mocha/web/__pycache__/WebRequestHandler.cpython-311.pyc create mode 100644 python/mocha/web/__pycache__/WebServer.cpython-311.pyc rename sql/mysql/003-data/{mocha_tenants.sql => 001-mocha_tenants.sql} (50%) create mode 100644 sql/mysql/003-data/002-mocha_tenant_references.sql delete mode 100644 sql/mysql/003-data/mocha_instances.sql diff --git a/common/admin/mocha-libexec/mocha-oms b/common/admin/mocha-libexec/mocha-oms index 3ab7c1a..84b2450 100755 --- a/common/admin/mocha-libexec/mocha-oms +++ b/common/admin/mocha-libexec/mocha-oms @@ -66,7 +66,7 @@ elif [ "$1" == "tenant" ]; then OLDTENANT=$(mocha oms tenant) mocha oms tenant select $3 - mocha oms install library /usr/share/mocha/libraries/net.alcetech.Mocha.System/ + mocha oms install library /usr/share/mocha/libraries/ mocha oms tenant select $OLDTENANT diff --git a/common/libraries/yaml/com.mochapowered.VehiclesForHire/000-EntityDefinitions/000-Module.yaml b/common/libraries/yaml/com.mochapowered.VehiclesForHire/000-EntityDefinitions/000-Module.yaml index aa029b0..1b149d4 100644 --- a/common/libraries/yaml/com.mochapowered.VehiclesForHire/000-EntityDefinitions/000-Module.yaml +++ b/common/libraries/yaml/com.mochapowered.VehiclesForHire/000-EntityDefinitions/000-Module.yaml @@ -1,4 +1,4 @@ -- include: '../../net.alcetech.Mocha.System/000-EntityDefinitions/*.yaml' +# - include: '../../net.alcetech.Mocha.System/000-EntityDefinitions/*.yaml' - entityDefinitions: - IDL_MochaPowered_VehiclesForHire: '{bb1d56b4-c063-4232-a789-93c8419e2d31}' - IDI_Module_MochaPowered_VehiclesForHire: '{bb1d56b4-c063-4232-a789-93c8419e2d31}' diff --git a/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/001-ryderentals-prod.yaml b/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/001-ryderentals-prod.yaml deleted file mode 100644 index 705898c..0000000 --- a/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/001-ryderentals-prod.yaml +++ /dev/null @@ -1,3 +0,0 @@ -- tenant: '&IDT_RydeRentalsProduction;' - tenantType: '&IDI_TenantType_Production;' - \ No newline at end of file diff --git a/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/tenant.yaml b/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/tenant.yaml new file mode 100644 index 0000000..61dcbe7 --- /dev/null +++ b/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/tenant.yaml @@ -0,0 +1,5 @@ +- tenant: '&IDT_RydeRentalsProduction;' + globalIdentifier: '{966c02fd-65e8-4345-bc24-f76ee97c38b6}' + name: 'ryderentals' + tenantType: '&IDI_TenantType_Production;' + \ No newline at end of file diff --git a/common/libraries/yaml/net.alcetech.Mocha.System/999-Random/Home/Users/btrevino.yaml b/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/users/btrevino.yaml similarity index 90% rename from common/libraries/yaml/net.alcetech.Mocha.System/999-Random/Home/Users/btrevino.yaml rename to common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/users/btrevino.yaml index 016af7a..4839ed3 100644 --- a/common/libraries/yaml/net.alcetech.Mocha.System/999-Random/Home/Users/btrevino.yaml +++ b/common/libraries/yaml/com.mochapowered.VehiclesForHire/999-Tenants/ryderentals-prod/users/btrevino.yaml @@ -1,4 +1,4 @@ -- library: '&IDL_MochaBaseSystem;' +- tenant: '&IDT_RydeRentalsProduction;' instances: - file: '{1079b0d3-0a1d-47d3-a98c-3f062dc88f90}' @@ -19,3 +19,6 @@ familyName: 'Trevino' images: - instance: '{1079b0d3-0a1d-47d3-a98c-3f062dc88f90}' + + +# {b8136d2a-8238-443b-8d9e-4f47c8a47c4b} \ No newline at end of file diff --git a/common/libraries/yaml/com.mochapowered.VehiclesForHire/brooke-trevino.yaml b/common/libraries/yaml/com.mochapowered.VehiclesForHire/brooke-trevino.yaml deleted file mode 100644 index b5a7a8c..0000000 --- a/common/libraries/yaml/com.mochapowered.VehiclesForHire/brooke-trevino.yaml +++ /dev/null @@ -1,6 +0,0 @@ -- library: '&IDI_Library_VehiclesForHire;' - -- user: '{b8136d2a-8238-443b-8d9e-4f47c8a47c4b}' - username: btrevino - personId: '{9530a1ea-2423-43ee-a23d-bb82728b79c9}' - \ No newline at end of file diff --git a/common/libraries/yaml/net.alcetech.Mocha.System/003-Classes/02737-RichTextAttribute.yaml b/common/libraries/yaml/net.alcetech.Mocha.System/003-Classes/02737-RichTextAttribute.yaml new file mode 100644 index 0000000..10295c1 --- /dev/null +++ b/common/libraries/yaml/net.alcetech.Mocha.System/003-Classes/02737-RichTextAttribute.yaml @@ -0,0 +1,30 @@ +--- +- entityDefinitions: + - IDC_RichTextAttribute: '{9e393eb5-0b2d-4c31-bc8c-419f9af8aee6}' + + - IDA_RichTextValue: '{0afb33a8-67b8-4bf3-be61-899f7e82d85f}' + +- library: '&IDL_MochaBaseSystem;' + instances: + - class: '&IDC_RichTextAttribute;' + name: Rich Text Attribute + index: 2737 + customTagName: 'richTextAttribute' + superclasses: + - instance: '&IDC_Attribute;' + - instance: '&IDC_ExecutableReturningAttribute;' + attributes: + - instance: '&IDA_Name;' + customTagName: 'name' + - instance: '&IDA_Value;' + customTagName: 'value' + - instance: '&IDA_MaximumLength;' + customTagName: 'maximumLength' + defaultTask: '&IDI_Task_RichTextAttribute_View;' + relatedTasks: + - instance: '&IDI_Task_RichTextAttribute_View;' + - instance: '&IDI_Task_RichTextAttribute_Edit;' + + - richTextAttribute: '&IDA_RichTextValue;' + name: Rich Text Value + index: 1 diff --git a/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/RichTextAttribute.yaml b/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/RichTextAttribute.yaml new file mode 100644 index 0000000..85302c2 --- /dev/null +++ b/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/RichTextAttribute.yaml @@ -0,0 +1,64 @@ +- entityDefinitions: + - IDI_Task_RichTextAttribute_View: '{f14e644e-c23f-4e51-8705-218f8a7f8da6}' + - IDI_Task_RichTextAttribute_Edit: '{ac1a4a78-ed7c-4ffb-9da5-0038f7e7083b}' + - IDE_RichTextAttribute_View: '{1c349bae-073f-4d2d-be02-62c7f2ac19cc}' + - IDE_RichTextAttribute_Edit: '{e5372c59-37e6-473d-8972-8197c3fadb01}' + - IDE_RichTextAttribute_Subedits: '{7e6cc769-fa92-457a-98fb-f1b01ee1b6f9}' + - IDI_TaskCategory_RichTextAttribute: '{697285cd-5c7c-416e-adae-f686f87b1a3c}' + +- library: '&IDL_MochaBaseSystem;' + instances: + - taskCategory: '&IDI_TaskCategory_RichTextAttribute;' + name: 'Rich Text Attribute' + + - sequenceTask: '&IDI_Task_RichTextAttribute_View;' + name: 'View Rich Text Attribute' + initiatingElement: '&IDE_RichTextAttribute_View;' + taskCategory: '&IDI_TaskCategory_RichTextAttribute;' + + - sequenceTask: '&IDI_Task_RichTextAttribute_Edit;' + name: 'Edit Rich Text Attribute' + initiatingElement: '&IDE_RichTextAttribute_Edit;' + taskCategory: '&IDI_TaskCategory_RichTextAttribute;' + + - element: '&IDE_RichTextAttribute_View;' + name: 'view rich text attribute' + elementContents: + - globalIdentifier: '{dfc3530a-86f0-4cad-b0eb-cb873124bc5b}' + defaultDataType: '&IDE_RichTextAttribute_Subedits;' + displayOptions: + - instance: '&IDI_DisplayOption_NotEnterable;' + - instance: '&IDI_DisplayOption_ShowSubelementsVertically;' + - instance: '&IDI_DisplayOption_Singular;' + + - element: '&IDE_RichTextAttribute_Edit;' + name: 'edit rich text attribute' + elementContents: + - globalIdentifier: '{5af9cf61-29b7-4e6f-8ae3-08f35f482872}' + defaultDataType: '&IDE_RichTextAttribute_Subedits;' + displayOptions: + - instance: '&IDI_DisplayOption_ShowSubelementsVertically;' + - instance: '&IDI_DisplayOption_Singular;' + + - element: '&IDE_RichTextAttribute_Subedits;' + name: 'rich text attribute subedits' + elementContents: + - globalIdentifier: '{7ee9e026-73c7-48dc-8899-49a9381bd5a2}' + defaultDataType: '&IDC_RichTextAttribute;' + displayOptions: + - instance: '&IDI_DisplayOption_NotEnterable;' + - instance: '&IDI_DisplayOption_DoNotShow;' + + - globalIdentifier: '{34f9d452-a06a-4793-b09e-95dc6c80a05f}' + defaultDataType: '&IDA_Name;' + + - globalIdentifier: '{a33e9e97-606d-47b7-ac4d-46971e534e01}' + defaultDataType: '&IDA_RichTextValue;' + label: 'Default Value' + + - globalIdentifier: '{e71c2829-570d-45e5-99f9-0fb97a9dea57}' + defaultDataType: '&IDA_MaximumLength;' + + # - globalIdentifier: '{f6fbaab7-f947-49ee-95c3-d7b652e346f4}' + # defaultDataType: '&IDR_Work_Data__in__Namespace;' + # label: Namespace \ No newline at end of file diff --git a/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/SystemUser/Common.yaml b/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/SystemUser/Common.yaml index b829036..ccd653d 100644 --- a/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/SystemUser/Common.yaml +++ b/common/libraries/yaml/net.alcetech.Mocha.System/005-UserInterface/Tasks/SystemUser/Common.yaml @@ -4,10 +4,10 @@ - library: '&IDL_MochaBaseSystem;' instances: - element: '&IDE_Task_SystemUser_Common_Subedit;' - # elementContents: - # - globalIdentifier: '{dcc2aef3-2041-4787-a46b-4becc054b797}' - # label: 'Disabled' - # defaultDataType: '&IDA_Disabled;' + elementContents: + - globalIdentifier: '{dcc2aef3-2041-4787-a46b-4becc054b797}' + label: 'User Name' + defaultDataType: '&IDA_UserName;' # - globalIdentifier: '{d38ae189-9b74-4922-9245-e6f1621913eb}' # label: 'Locked' # defaultDataType: '&IDA_Locked;' diff --git a/php/mocha/lib/mocha/core/KnownClassGuids.inc.php b/php/mocha/lib/mocha/core/KnownClassGuids.inc.php index cb68708..0aab3da 100644 --- a/php/mocha/lib/mocha/core/KnownClassGuids.inc.php +++ b/php/mocha/lib/mocha/core/KnownClassGuids.inc.php @@ -15,6 +15,7 @@ class KnownClassGuids const BooleanAttribute = "EA830448A4034ED9A3D3048D5D5C3A03"; const NumericAttribute = "9DE86AF1EFD64B719DCC202F247C94CB"; const DateAttribute = "0B7B1812DFB44F25BF6DCEB0E1DF8744"; + const RichTextAttribute = "{9e393eb5-0b2d-4c31-bc8c-419f9af8aee6}"; const Element = "919295953dbd4eae8add6120a49797c7"; const ElementContent = "f85d4f5ec69f449899137a8554e233a4"; diff --git a/php/mocha/lib/mocha/oms/MySQLDatabaseOms.inc.php b/php/mocha/lib/mocha/oms/MySQLDatabaseOms.inc.php index bd1ceab..e2a8179 100644 --- a/php/mocha/lib/mocha/oms/MySQLDatabaseOms.inc.php +++ b/php/mocha/lib/mocha/oms/MySQLDatabaseOms.inc.php @@ -32,9 +32,10 @@ public function getInstances() : array { - $query = "SELECT * FROM mocha_instances WHERE tenant_id = :tenant_id"; + $query = "SELECT * FROM mocha_instances WHERE (" . $this->buildTenantIDQuery() . ")"; + $stmt = $this->PDO->prepare($query); - $result = $stmt->execute(array("tenant_id" => $this->getTenant()->ID)); + $result = $stmt->execute(); $values = $stmt->fetchAll(); $insts = array(); foreach ($values as $value) @@ -85,6 +86,22 @@ } return null; } + public function getTenantByID(int $id) : ?TenantReference + { + $query = "SELECT * FROM mocha_tenants WHERE id = :tenant_id;"; + $stmt = $this->PDO->prepare($query); + $result = $stmt->execute(array + ( + "tenant_id" => $id + )); + $values = $stmt->fetch(); + if ($values !== false) + { + $tenant = new TenantReference($values["id"], $values["tenant_name"], $values["global_identifier"]); + return $tenant; + } + return null; + } public function __construct($hostname, $port, $databasename, $username, $password) @@ -255,36 +272,64 @@ plus the SP actually works, and the straight query INTRODUCES bugs... wtf? */ + public function getReferencedTenants(TenantReference $tenantReference) : array + { + $retval = []; + $query = "SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = :source_tenant_id"; + $stmt = $this->PDO->prepare($query); + $result = $stmt->execute(array + ( + "source_tenant_id" => $tenantReference->ID + )); + if ($result === false) + { + $this->logDatabaseError($query); + } + else + { + $values = $stmt->fetchAll(); + $count = count($values); + for ($i = 0; $i < $count; $i++) + { + $target_tenant_id = $values[$i][0]; + $target_tenant = $this->getTenantByID($target_tenant_id); + if ($target_tenant !== null) + { + $retval[] = $target_tenant; + } + } + } + return $retval; + } + + private function logDatabaseError(string $query, ?array $parms = null) + { + trigger_error("unknown database error, query was:", \E_USER_ERROR); + trigger_error($query, \E_USER_NOTICE); + return null; + } + + private function buildTenantIDQuery(string $tenantIdParmName = "tenant_id") + { + $tenant_id_qry = $tenantIdParmName . " = " . $this->getTenant()->ID; + + $tenant_references = $this->getReferencedTenants($this->getTenant()); + foreach ($tenant_references as $tenantref) + { + $tenant_id_qry .= " OR " . $tenantIdParmName . " = " . $tenantref->ID; + } + + return $tenant_id_qry; + } + public function initializeInstanceCache() { error_log("invalidating instance cache"); $instanceCache = array(); - - $query = "SELECT * FROM mocha_instances WHERE tenant_id = :tenant_id AND class_id IS NOT NULL"; - $stmt = $this->PDO->prepare($query); - $parms = array - ( - "tenant_id" => $this->getTenant()->ID - ); - $result = $stmt->execute($parms); - if ($result === false) + $insts = $this->getInstances(); + foreach ($insts as $ir) { - trigger_error("unknown database error, query was:", \E_USER_ERROR); - trigger_error($query, \E_USER_NOTICE); - return null; - } - - $values = $stmt->fetchAll(); - $count = count($values); - for ($i = 0; $i < $count; $i++) - { - $dbid = $values[$i]["id"]; - $class_id = $values[$i]["class_id"]; - $inst_id = $values[$i]["inst_id"]; - $global_id = $values[$i]["global_identifier"]; - - $ir = new InstanceReference($dbid, new InstanceKey($class_id, $inst_id), $global_id); $instanceCache[$ir->GlobalIdentifier->__toStringFormat(false, "", "")] = array ( @@ -366,11 +411,10 @@ // $query = "CALL mocha_get_instance_by_global_identifier(mocha_normalize_uuid(:global_identifier))"; echo ("query using SQL"); - $query = "SELECT * FROM mocha_instances WHERE tenant_id = :tenant_id AND global_identifier = :global_identifier AND class_id IS NOT NULL"; + $query = "SELECT * FROM mocha_instances WHERE (" . $this->buildTenantIDQuery() . ") AND global_identifier = :global_identifier AND class_id IS NOT NULL"; $stmt = $this->PDO->prepare($query); $parms = array ( - "tenant_id" => $this->getTenant()->ID, //"global_identifier" => $globalIdentifier->__toString() "global_identifier" => $globalIdentifier->__toStringFormat(false, "", "") ); @@ -445,12 +489,11 @@ $query = "SELECT mocha_instances.* FROM mocha_instances INNER JOIN mocha_relationships ON mocha_instances.id = mocha_relationships.destination_inst_id WHERE mocha_relationships.tenant_id = :tenant_id " . "AND source_inst_id = :src_inst_id AND relationship_inst_id = :rel_inst_id" ; // AND :eff_date IS NULL OR (effective_date >= :eff_date)"; */ - $query = "SELECT destination_inst_id, remove_flag FROM mocha_relationships WHERE mocha_relationships.tenant_id = :tenant_id " . + $query = "SELECT destination_inst_id, remove_flag FROM mocha_relationships WHERE (" . $this->buildTenantIDQuery("mocha_relationships.tenant_id") . ") " . "AND source_inst_id = :src_inst_id AND relationship_inst_id = :rel_inst_id" ; // AND :eff_date IS NULL OR (effective_date >= :eff_date)"; $stmt = $this->PDO->prepare($query); $parms = array ( - "tenant_id" => $this->getTenant()->ID, "src_inst_id" => $this->getDbId($sourceInstance), "rel_inst_id" => $this->getDbId($relationshipInstance) //, //"eff_date" => $dt @@ -542,14 +585,17 @@ protected function getAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, $defaultValue = null, $effectiveDate = null) : ?string { $dt = $this->normalizeSqlDateTime($effectiveDate, true); - $query = "CALL mocha_get_attribute_value(:src_inst_id, :attr_inst_id, :eff_date)"; + // $query = "CALL mocha_get_attribute_value(:src_inst_id, :att_inst_id, :eff_date)"; + //echo ("GAV: " . $sourceInstance->InstanceKey . " : " . $attributeInstance->InstanceKey ); + $query = "SELECT * FROM mocha_attributes WHERE tenant_id = :tenant_id AND src_inst_id = :src_inst_id AND att_inst_id = :att_inst_id AND att_effective_date <= NOW() ORDER BY att_effective_date DESC"; $stmt = $this->PDO->prepare($query); $vars = array ( + "tenant_id" => $this->getTenant()->ID, "src_inst_id" => $this->getDbId($sourceInstance), - "attr_inst_id" => $this->getDbId($attributeInstance), - "eff_date" => $dt + "att_inst_id" => $this->getDbId($attributeInstance)//, + //"eff_date" => $dt ); $result = $stmt->execute($vars); @@ -564,6 +610,36 @@ $value = $values[0]["att_value"]; return $value; } + + // the attribute was not set on the current tenant, + // so retry the query with our parent tenants + $parentTenants = $this->getReferencedTenants($this->getTenant()); + foreach ($parentTenants as $parentTenant) + { + $vars["tenant_id"] = $parentTenant->ID; + $result = $stmt->execute($vars); + + if ($result === false) + { + return $defaultValue; + } + + $values = $stmt->fetchAll(); + if (count($values) > 0) + { + // we have a value! + $value = $values[0]["att_value"]; + return $value; + } + } + + // attribute has not been defined anywhere + /* + echo (""); + */ return $defaultValue; } public function setAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, mixed $value, ?\DateTime $effectiveDate = null) @@ -673,7 +749,7 @@ // FIXME: NOT IMPLEMENTED //usage: // getInstanceByAttributes (array ( getInstanceByGlobalIdentifier(NAME_ATTRIBUTE) => "zq-developer" )) - $query = "SELECT mocha_instances.* FROM mocha_instances, mocha_attributes WHERE mocha_instances.tenant_id = mocha_get_current_tenant() AND mocha_attributes.tenant_id = mocha_get_current_tenant() AND mocha_instances.id = mocha_attributes.src_inst_id"; + $query = "SELECT mocha_instances.* FROM mocha_instances, mocha_attributes WHERE (" . $this->buildTenantIDQuery("mocha_instances.tenant_id") . ") AND mocha_attributes.tenant_id = mocha_instances.tenant_id AND mocha_instances.id = mocha_attributes.src_inst_id"; if (count($parms) > 0) { $query .= " AND "; diff --git a/php/mocha/lib/mocha/system.inc.php b/php/mocha/lib/mocha/system.inc.php index 564ff81..9ed462b 100644 --- a/php/mocha/lib/mocha/system.inc.php +++ b/php/mocha/lib/mocha/system.inc.php @@ -35,6 +35,7 @@ require("ui/controls/InstanceBrowser.inc.php"); + require("ui/renderers/html/Editor.inc.php"); require("ui/renderers/html/HTMLRenderer.inc.php"); require("ui/tasks/Task.inc.php"); diff --git a/php/mocha/lib/mocha/ui/renderers/html/Editor.inc.php b/php/mocha/lib/mocha/ui/renderers/html/Editor.inc.php new file mode 100644 index 0000000..6afe7af --- /dev/null +++ b/php/mocha/lib/mocha/ui/renderers/html/Editor.inc.php @@ -0,0 +1,21 @@ +ForClass = $forClass; + $this->ViewFunction = $viewFunction; + $this->EditFunction = $editFunction; + } + + } +?> \ No newline at end of file diff --git a/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php b/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php index 3e4590a..8a6e841 100644 --- a/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php +++ b/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php @@ -19,6 +19,7 @@ use Phast\HTMLControls\Input; use Phast\HTMLControls\InputType; + use Phast\HTMLControls\RichTextBox; use Phast\QuickSort; use Phast\System; use Phast\Utilities\Stopwatch; @@ -40,6 +41,8 @@ */ public $DebugMode; + public array $Editors; + public $TargetInstance; /** @@ -67,6 +70,7 @@ { $this->DebugMode = false; $this->Context = $context; + $this->Editors = array(); $this->FailedValidations = []; $this->FailedValidationElements = []; $this->IsPostback = false; @@ -75,7 +79,56 @@ $this->IncludeTopNavigationBar = true; $this->__renderingElement = null; $this->__processingElement = null; + + $this->registerEditors(); } + + public function registerEditors() + { + /** + * @var MySQLDatabaseOms + */ + $oms = mocha_get_oms(); + + $genericViewFunc = function($oms, $parentElementContents, $elementContent, $ecInst, $value) + { + echo ($value); + }; + $booleanAttributeViewFunc = function($oms, $parentElementContents, $elementContent, $ecInst, $value) + { + if ($value == "1") + { + echo ("Yes"); + } + else + { + // if display option "Show No When False" + // echo ("No"); + } + }; + + $this->registerEditor($oms->getInstanceByGlobalIdentifier(KnownClassGuids::BooleanAttribute), $booleanAttributeViewFunc, function($oms, $parentElementContents, $elementContent, $ecInst, $value) + { + $displayOptions = $oms->getRelatedInstances($elementContent, KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option); + $this->renderBooleanAttributeEC($parentElementContents, $elementContent, $ecInst, $value); + }); + $this->registerEditor($oms->getInstanceByGlobalIdentifier(KnownClassGuids::TextAttribute), $genericViewFunc, function($oms, $parentElementContents, $elementContent, $ecInst, $value) + { + $displayOptions = $oms->getRelatedInstances($elementContent, KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option); + $this->renderTextAttributeEC($parentElementContents, $elementContent, $ecInst, $oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__ObscuredText)), $value); + }); + $this->registerEditor($oms->getInstanceByGlobalIdentifier(KnownClassGuids::NumericAttribute), $genericViewFunc, function($oms, $parentElementContents, $elementContent, $ecInst, $value) + { + $displayOptions = $oms->getRelatedInstances($elementContent, KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option); + $this->renderNumericAttributeEC($parentElementContents, $elementContent, $ecInst, $oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__ObscuredText)), $value); + }); + $this->registerEditor($oms->getInstanceByGlobalIdentifier(KnownClassGuids::RichTextAttribute), $genericViewFunc, function($oms, $parentElementContents, $elementContent, $ecInst, $value) + { + $displayOptions = $oms->getRelatedInstances($elementContent, KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option); + $this->renderRichTextAttributeEC($parentElementContents, $elementContent, $ecInst, $value); + }); + } + /** * Thanks https://stackoverflow.com/a/31107425 * @@ -325,6 +378,25 @@ echo (""); $this->renderEndForm($allElementsAreReadonly); + if (!$allElementsAreReadonly) + { + echo(""); + } + $this->renderEndPage(); } @@ -358,7 +430,19 @@ //!FIXME: refactor out the casting of POST values to actual instances or primitive literals if ($oms->is_a($ecInst, KnownClassGuids::Clasz)) { - $value = $oms->getInstanceByKey(InstanceKey::Parse($value)); + if ($value == "") + { + $value = null; + } + else + { + $ik = InstanceKey::Parse($value); + if ($ik === null) + { + echo ("invalid ik: " . $value); + } + $value = $oms->getInstanceByKey($ik); + } } $this->Context->setWorkData($ecInst, $value); } @@ -1385,6 +1469,27 @@ return $defaultValue; } + public function registerEditor(InstanceReference $forClass, callable $viewFunction, callable $editFunction) + { + $this->Editors[] = new Editor($forClass, $viewFunction, $editFunction); + } + public function getEditor(InstanceReference $ecInst) + { + /** + * @var MySQLDatabaseOms + */ + $oms = mocha_get_oms(); + + foreach ($this->Editors as $editor) + { + if ($oms->is_a($ecInst, $editor->ForClass)) + { + return $editor; + } + } + return null; + } + public function renderExecutableReturningAttribute(array &$parentElementContents, InstanceReference $elementContent, InstanceReference $ecInst, ?InstanceReference $relatedInstance, $renderNotEnterable = false) { /** @@ -1422,38 +1527,19 @@ $value = $_POST[$ecid]; } + $editor = $this->getEditor($ecInst); if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__NotEnterable)) || $renderNotEnterable) { - if ($oms->is_a($ecInst, KnownClassGuids::BooleanAttribute)) + if ($editor !== null) { - if ($value == "1") - { - echo ("Yes"); - } - else - { - // if display option "Show No When False" - // echo ("No"); - } - } - else - { - echo($value); + call_user_func($editor->ViewFunction, $oms, $parentElementContents, $elementContent, $ecInst, $value); } } else { - if ($oms->is_a($ecInst, KnownClassGuids::TextAttribute)) + if ($editor !== null) { - $this->renderTextAttributeEC($parentElementContents, $elementContent, $ecInst, $oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__ObscuredText)), $value); - } - else if ($oms->is_a($ecInst, KnownClassGuids::BooleanAttribute)) - { - $this->renderBooleanAttributeEC($parentElementContents, $elementContent, $ecInst, $oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__ObscuredText)), $value); - } - else if ($oms->is_a($ecInst, KnownClassGuids::NumericAttribute)) - { - $this->renderNumericAttributeEC($parentElementContents, $elementContent, $ecInst, $oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__ObscuredText)), $value); + call_user_func($editor->EditFunction, $oms, $parentElementContents, $elementContent, $ecInst, $value); } } } @@ -1505,7 +1591,7 @@ $p->Render(); } - public function renderBooleanAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $password = false, $value = null) + public function renderBooleanAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $value = null) { /** * @var MySQLDatabaseOms @@ -1542,10 +1628,6 @@ $p->Attributes[] = new WebControlAttribute("maxlength", $maxLength); } $p->HasContent = false; - if ($password) - { - $p->Type = InputType::Password; - } $p->Render(); } @@ -1579,6 +1661,42 @@ $p->Render(); } + + public function renderRichTextAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $value = null) + { + /** + * @var MySQLDatabaseOms + */ + $oms = mocha_get_oms(); + + $displayOptions = $oms->getRelatedInstances($ec, $oms->getInstanceByGlobalIdentifier(KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option)); + + $fullyQualifiedECID = $this->getElementContentId($parentElementContents, $ec); + $ecid = "ec_" . $fullyQualifiedECID; + + $p = new RichTextBox(); + $p->ClientID = $ecid; + $p->Name = $ecid; + $p->Attributes[] = new WebControlAttribute("data-ecid", $ecid); + $p->Value = $value; + + if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__Required))) + { + $p->ClassList[] = "uwt-required"; + } + if ($this->IsPostback && array_key_exists($ec->DatabaseId, $this->FailedValidationElements)) + { + $p->ClassList[] = "uwt-failed-validation"; + } + + $maxLength = $oms->getAttributeValue($inst, KnownAttributeGuids::MaximumLength); + if ($maxLength !== null) + { + $p->Attributes[] = new WebControlAttribute("maxlength", $maxLength); + } + $p->Render(); + } + public function renderArray(?array $array, string $separator, string $prefix = "", string $suffix = "") { @@ -1656,6 +1774,7 @@ "href" => System::ExpandRelativePath("~/themes/mocha/theme.css", false, true) )); + $this->renderTag("script", array("type" => "text/javascript", "src" => System::ExpandRelativePath("~/scripts/phast/ckeditor/ckeditor.js", false, true))); $this->renderTag("script", array("type" => "text/javascript", "src" => System::ExpandRelativePath("~/scripts/phast/System.js.php", false, true))); $this->renderTag("script", array("type" => "text/javascript", "src" => System::ExpandRelativePath("~/scripts/mocha.js.php", false, true))); $this->renderBeginTag("script", array("type" => "text/javascript")); diff --git a/php/mocha/scripts/mcx-elementcontent.js b/php/mocha/scripts/mcx-elementcontent.js index acfbbb6..b14cf5b 100644 --- a/php/mocha/scripts/mcx-elementcontent.js +++ b/php/mocha/scripts/mcx-elementcontent.js @@ -107,6 +107,10 @@ function McxElementContent(parentElement) this.NativeObject.ValueElement.NativeObject.__inhibit_update = true; this.NativeObject.ValueElement.NativeObject.ToggleChecked(); this.NativeObject.ValueElement.NativeObject.__inhibit_update = false; + if (this.status === 403 || this.status === 401) + { + Alert.show("Please log in to continue", "Not Logged In", "uwt-color-danger", 5000, "NotLoggedIn"); + } } } }; diff --git a/php/mocha/themes/avondale/uwt-alert.less b/php/mocha/themes/avondale/uwt-alert.less index c4e04c3..a210386 100644 --- a/php/mocha/themes/avondale/uwt-alert.less +++ b/php/mocha/themes/avondale/uwt-alert.less @@ -2,6 +2,12 @@ div.uwt-alert { padding: .9375rem; box-shadow: 4px 4px 10px rgba(0,0,0,0.3); + + &:not(.uwt-visible) + { + opacity: 0; + visibility: hidden; + } &> div.uwt-title { diff --git a/php/mocha/themes/avondale/uwt-richtextbox.less b/php/mocha/themes/avondale/uwt-richtextbox.less new file mode 100644 index 0000000..0063e8d --- /dev/null +++ b/php/mocha/themes/avondale/uwt-richtextbox.less @@ -0,0 +1,10 @@ +div.ck-editor +{ + &:hover + { + &> div.ck-content + { + border-color: var(--uwt-color-accent); + } + } +} \ No newline at end of file diff --git a/php/mocha/themes/avondale/uwt-textbox.less b/php/mocha/themes/avondale/uwt-textbox.less index f9e21f9..79a1a25 100644 --- a/php/mocha/themes/avondale/uwt-textbox.less +++ b/php/mocha/themes/avondale/uwt-textbox.less @@ -33,4 +33,10 @@ input[type=text], input[type=password], input[type=number], input[type=search], line-height: 1.42857; padding: 6px 12px; transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; +} +div.uwt-richtextbox +{ + border: 1px solid var(--uwt-color-gray-400); + height: 100px; + background-color: var(--uwt-color-gray-200); } \ No newline at end of file diff --git a/php/mocha/themes/avondale/uwt.less b/php/mocha/themes/avondale/uwt.less index ae95f18..c97b6fd 100644 --- a/php/mocha/themes/avondale/uwt.less +++ b/php/mocha/themes/avondale/uwt.less @@ -25,6 +25,7 @@ @import "uwt-page.less"; @import "uwt-panel.less"; @import "uwt-popup.less"; +@import "uwt-richtextbox.less"; @import "uwt-sidebar.less"; @import "uwt-slider.less"; @import "uwt-spinner.less"; diff --git a/php/mocha/ui/pages/LoginPage.phpx.php b/php/mocha/ui/pages/LoginPage.phpx.php index 4616cc7..118f3d4 100644 --- a/php/mocha/ui/pages/LoginPage.phpx.php +++ b/php/mocha/ui/pages/LoginPage.phpx.php @@ -130,11 +130,13 @@ { echo("`User@get User for User Name parm`: method not found ('" . KnownMethodBindingGuids::User__get__User_for_User_Name_parm . "')");die(); } - + $context = new OmsContext(); $instUser = $oms->execute($context, $mbUser__get__User_for_User_Name_parm, true, array( KnownAttributeGuids::UserName => $userName )); $instUser = $context->getWorkData($instUser); + echo ("user: " . $instUser->InstanceKey); + if ($instUser !== null) { $passwordSalt = $oms->getAttributeValue($instUser, $oms->getInstanceByGlobalIdentifier(KnownAttributeGuids::PasswordSalt)); @@ -157,6 +159,11 @@ $oms->setAttributeValue($instLogin, KnownAttributeGuids::IPAddress, $_SERVER["REMOTE_ADDR"]); $oms->assignRelationship($instLogin, $oms->getInstanceByGlobalIdentifier(KnownRelationshipGuids::User_Login__has__User), $instUser); } + else + { + echo ("could not create login token"); + die(); + } $_SESSION["user_token_" . $oms->getTenant()->ID] = $token; $oms->setCurrentUser($instUser); diff --git a/php/mocha/ui/pages/OTSPage.phpx.php b/php/mocha/ui/pages/OTSPage.phpx.php index 041c310..1b7c844 100644 --- a/php/mocha/ui/pages/OTSPage.phpx.php +++ b/php/mocha/ui/pages/OTSPage.phpx.php @@ -1,7 +1,11 @@ EntityDefinitions = array + ( + + ); + $this->EntityDefinitions2 = array + ( + "98cc2a320289406e8df45e154ca601d2" => "IDC_CircuitBreakerPanel", + "89102e1cc3144a5fa752aa84e05ca83f" => "IDI_CircuitBreakerPanel_CarmelBay" + ); + } + + private function zqGetClassName(InstanceReference $i) + { + $oms = mocha_get_oms(); + + $key = $i->GlobalIdentifier->__toStringFormat(false, "", ""); + if (array_key_exists($key, $this->EntityDefinitions2)) + { + return "&" . $this->EntityDefinitions2[$key] . ";"; + } + else + { + $name = $oms->getAttributeValue($i, KnownAttributeGuids::Name); + $name = str_replace(" ", "", $name); + return "&IDC_" . $name . ";"; + } + return $i->GlobalIdentifier->__toString(); + } + protected function OnRendering(RenderingEventArgs $re) { parent::OnRendering($re); @@ -46,8 +87,6 @@ { if (count($path) >= 5) { - header("HTTP/1.1 200 OK"); - // e.g. https://i-0c0398f84acecb702.privatesuv.com/ots/super/services/zq/v1/module/list // ots/{tenant}/services/{serviceName}/{version}/{command} @@ -61,33 +100,129 @@ $instClass = $oms->getInstanceByGlobalIdentifier(KnownClassGuids::Clasz); $instances = $oms->getRelatedInstances($instClass, $oms->getInstanceByGlobalIdentifier(KnownRelationshipGuids::Class__has__Instance)); - if ($command == "module/list") + $cmdparts = explode("/", $command); + if (count($cmdparts) >= 2) { - header("Content-Type: application/json"); - print("{ \"items\": [ "); - print("{ \"name\": \"mocha\", \"title\": \"mocha\", \"type\": \"module\", \"items\": [ "); - - $ct = count($instances); - for ($i = 0; $i < $ct; $i++) + if ($cmdparts[0] === "instance") { - print("{ \"name\": \"mocha:inst" . $i . "\", \"title\": \"" . $oms->getInstanceText($instances[$i]) . "\", \"type\": \"class\", \"instanceId\": \"" . $instances[$i]->InstanceKey . "\" }"); - if ($i < $ct - 1) + $ik = InstanceKey::Parse($cmdparts[1]); + if ($ik === null) { - print(", "); + header("HTTP/1.1 404 Not Found"); + header("Content-Type: text/plain"); + echo("invalid inst id " . $cmdparts[1]); + die(); + } + + $ir = $oms->getInstanceByKey($ik); + header("HTTP/1.1 200 OK"); + header("Content-Type: text/plain"); + + echo ("- library: '&IDL_MochaBaseSystem;'\n"); + echo (" instances:\n"); + + + if ($ik->ClassIndex == 1) + { + echo (" - class: '" . $this->zqGetClassName($ir) . "'\n"); + } + else + { + echo (" - instance: '" . $this->zqGetClassName($ir) . "'\n"); + } + + //$attrs = $oms->getRelatedInstances($ir, KnownRelationshipGuids::Class__has__Attribute); + $attrs = $oms->getAttributes($ir); + if (count($attrs) > 0) + { + echo (" - attributes:\n"); + foreach ($attrs as $attr) + { + echo (" - instance: '" . $attr->GlobalIdentifier . "'\n"); + echo (" - value: '" . $oms->getAttributeValue($ir, $attr) . "'\n"); + } + } + + $rels = $oms->getRelationships($ir); + if (count($rels) > 0) + { + echo (" - relationships:\n"); + foreach ($rels as $rel) + { + $gid = $rel->GlobalIdentifier->__toString(); + if (array_key_exists($rel->GlobalIdentifier->__toStringFormat(false, "", ""), $this->EntityDefinitions2)) + { + $gid = "&" . $this->EntityDefinitions2[$rel->GlobalIdentifier->__toStringFormat(false, "", "")] . ";"; + } + echo (" - instance: '" . $rel->GlobalIdentifier . "'\n"); + $targs = $oms->getRelatedInstances($ir, $rel); + if (count($targs) > 0) + { + echo (" targetInstances:\n"); + } + foreach ($targs as $targ) + { + $iid = $targ->GlobalIdentifier->__toString(); + if (array_key_exists($targ->GlobalIdentifier->__toStringFormat(false, "", ""), $this->EntityDefinitions2)) + { + $iid = "&" . $this->EntityDefinitions2[$targ->GlobalIdentifier->__toStringFormat(false, "", "")] . ";"; + } + + echo (" = instance: '" . $iid . "'\n"); + } + } + } + + + $defaultTask = $oms->getRelatedInstance($ir, KnownRelationshipGuids::Class__has_default__Task); + if ($defaultTask !== null) + { + echo (" - defaultTask: '" . $defaultTask->GlobalIdentifier . "'\n"); + } + + $relTasks = $oms->getRelatedINstances($ir, KnownRelationshipGuids::Class__has_related__Task); + if (count($relTasks) > 0) + { + echo (" - relatedTasks:\n"); + foreach ($relTasks as $relTask) + { + echo (" - instance: '" . $relTask->GlobalIdentifier . "'\n"); + } + } + $re->Cancel = true; + return; + } + else if ($cmdparts[0] === "module") + { + if ($cmdparts[1] === "list") + { + header("Content-Type: application/json"); + print("{ \"items\": [ "); + print("{ \"name\": \"mocha\", \"title\": \"mocha\", \"type\": \"module\", \"items\": [ "); + + $ct = count($instances); + for ($i = 0; $i < $ct; $i++) + { + print("{ \"name\": \"mocha:inst" . $i . "\", \"title\": \"" . $oms->getInstanceText($instances[$i]) . "\", \"type\": \"class\", \"instanceId\": \"" . $instances[$i]->InstanceKey . "\" }"); + if ($i < $ct - 1) + { + print(", "); + } + } + + print("] }"); + print("] }"); + return; } } - - print("] }"); - print("] }"); - } - else - { - header("Content-Type: text/plain"); - print("tenantName: " . $tenantName . "\n"); - print("serviceName: " . $serviceName . "\n"); - print("version: " . $version . "\n"); - print("command: " . $command . "\n"); } + + header("HTTP/1.1 501 Not Implemented"); + header("Content-Type: text/plain"); + print("tenantName: " . $tenantName . "\n"); + print("serviceName: " . $serviceName . "\n"); + print("version: " . $version . "\n"); + print("command: " . $command . "\n"); die(); } else diff --git a/python/mocha/core/__pycache__/InstanceKey.cpython-311.pyc b/python/mocha/core/__pycache__/InstanceKey.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbb7f7f0068c37a8df6757981dc8eed9bde75aab GIT binary patch literal 1834 zcmb7E-D@LN6hHS)Ce5@>YD~M^-Lh-eMy295^i@<41lLA_7+IFUGQ_!eZMw-M-kFFk z5k|>Fl|}m?w1N+PS}jHJ*}tM$3R?!01>J|fWvNen@|?*en@m^16LP-pJ?H%Hx%bRZ z$>by;E&TDD{EGqnNydO;p>moHn0M|!o~ z-0<~gMLBXaJ?17C6?fi5=E0-H)OW@=#`faZse37J@pnD3mHF~k=hk-mtJ~h~Tl= zu{M|#7f_p{HM|;X`93RRS1y<%kWF(~VQ$6YQxtFknFqZ%%w6$vo&0g;GKysne`nQtF0+m5+iK$r>`%F=OhXO)OGoMIza4uWO&o>uFp+y#hBhdhRaBL*+y>Q6q162PX z%^W6Cmm^r7r*hOw8Z%S~&ebTK@pU?t^Ayq5Lw@l*qR520!;1!*))5Png*5)j7@u6h zHgQ)Z3q7xM^j}#h2Tmw2DuRbkM{``I7Eo7Lh(((-VVbxB-%e(D zz4g(<f{)AT1zv)&M`8tK!f`Dv?C3sY4g=6%#ORz;j1lImq*G=;%o&Ju6*yYrTM1%1JZ-bSUTF~)j) So>A^+^CyA-?|)ehO8f&@FoqQX literal 0 HcmV?d00001 diff --git a/python/mocha/core/__pycache__/InstanceReference.cpython-311.pyc b/python/mocha/core/__pycache__/InstanceReference.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89a6e4cc9dee092dddc4d12c64bed9e9f976c640 GIT binary patch literal 1586 zcmb7E%}*0S6o0e3EnT374}}1hRzspqlo~YAgE1aR3^8elc&ag*vO9%B+r`;7gxZ)M zIC$V*jvNez@MriBw1&iH6HlJJ)zlLw-<$0g=yGwk`5Ml$>(5 zWb)U1&-543?Cv($aage*;3LTCwFVYCccLx>S8f^l?r z+z;@E=eXb)$&KVOrm>9y{RI4gDhl04GGL9>z#zLEH3c=I>}e`$K0!=-4Nh1(sk)lA zp0`98*SPvd!Cuc6jJ%c9T+QKyoY2uOoq{UrQ0xSb^VQU*UF4~CZfN>@9AhP_)g>Y-%yJvsd1VO$eGfr&FLN2Ac+>~fd(;cn zyTMWou8Gni7u;e^WlD0p!ioAqR_F-|S1WXMxsvGh#xYK(zJk5vRZ)>$;)V+LE*Am% zw}@K5#jsiOxjYxud)Ma>SSYJ8g)zM%&;QV4-}P8akDuxBrVFx+9oDB4z~K=Pm0LgMh9C*?NHLV^Rmf<3x1QNySS*a*Go|x;>KbdE~j5@(Ynb8+|8d1)-xd#@evZ Vy!z{C;|v1@;SbsVUgMCV{sB-gSDOF; literal 0 HcmV?d00001 diff --git a/python/mocha/core/__pycache__/TenantReference.cpython-311.pyc b/python/mocha/core/__pycache__/TenantReference.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7494bae6b6d06a84cd12cbef4f77b2ae32f3043 GIT binary patch literal 1271 zcmbVLJ#QL85S?9)FB{^-u@gHuF|wQj$>LI`h$2Ob6uCiBNQGpr@a z|H1ztk(EC~;R0QoDjgB2TxI4C2nMPwcW-BQcIUmDS-$7<8-U|o`L#M@06)o@4P$Cd zPSCgp36k01Kn)mh_yCd*KqkI%fFJnAqsF9Bg;Met=7JInADy~>P;ekNTzQUPM59{WFCA{5Li@KODmxGK{B(g_AMhybLME4`^))=sqKN8DeH4 y#s6BYFH&${)m`RI{8?}H0dA%1<)0#q6O6GDyc*tr#zvkY(JK6=wLfbDk&M6HG$s)M literal 0 HcmV?d00001 diff --git a/python/mocha/core/__pycache__/__init__.cpython-311.pyc b/python/mocha/core/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1dcb7bb7258ca80e90d65ee70390a309a1e6a985 GIT binary patch literal 338 zcmZ3^%ge<81ckfJQ=5VGV-N=hn4pZ$T0q8hh7^Vr#vF!RhA0L`5SuB7F_$rl5zJ=J zVajESVgj;Rf*CYfUorwUXfod7_RK3TNz6-5^-iq>as^@BpwzU~qEw(bP>??)H7_x* z1TN&K$y~$?)Lz5_B3OaMN`}uslHr%Tenx(7s(w;xa&~G_ZkE1FesXDUYFc_`t=4F<|$LkeT{^GF7%}*)KNwq8D1eyzS kYq2Ac_`uA_$asT6(y30A}l3Z~y=R literal 0 HcmV?d00001 diff --git a/python/mocha/oms/__pycache__/Oms.cpython-311.pyc b/python/mocha/oms/__pycache__/Oms.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c23b099355f82b9d78d47db733f526c4fe98b82 GIT binary patch literal 1225 zcmb7CJ#W)M7{2pIzMN3niXtX5bn#LzAS8q;@gX6Elp+d?8BVV6LfXc5xpRhO3R3<< zS0 zau1AS!U?BclF*PQR%j)5Xj5X5=Y(4$!tKu%A>ZJej?m%GF7e%881ZfGy+~CarLlM^ z`g(QlycTUC1w{4A8<9q7UIgNKA^aCSw!t|jf`pWl(BgDNLYrH{XmgWy>f_Y#rjDtINc0}+FfWN{}7wt}O6-pSILn+sX-??n!~ zPP@Q(>9z0SA>ty&bd9kjJ9rHq)$ literal 0 HcmV?d00001 diff --git a/python/mocha/oms/memory/__pycache__/MemoryOms.cpython-311.pyc b/python/mocha/oms/memory/__pycache__/MemoryOms.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eec16afb66710286d0c047c7ccaaf64a8b5c963 GIT binary patch literal 908 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 Aa{vGU literal 0 HcmV?d00001 diff --git a/python/mocha/web/__pycache__/WebServer.cpython-311.pyc b/python/mocha/web/__pycache__/WebServer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad805fee993c84e5f8a68996b5e490a790ff2d15 GIT binary patch literal 1294 zcmZuw&1(}u6n`_jiD_bO{b;RvSwzHDX#_oph!+LhgH`-Mh==KRXJR&HcjN3vu~Z3| zgGUdAUOiRB|G>YZielK4pqJhv6$DSdx7&@4Iy-suKIZ-2oA+K`kB^rD*U$bt^^F01 zB_UttHnVjenKh6gSqprq0RzdU(PBQYaRwZ&f;4*|3+o)Xp##_$r8_>J1$>m5Yo|saI#K?I&>~47SC` zYNg;M;3-q@H5Cn)z753Ku*0SB2bX=edr;+o1vn7qG>~ z!X~M3^2&3!Z{Nr!$1Wz7MjW?iv7;8>9P6W$ML+mvXiF>FC+_m2)2}=eo!HlLuDE zy2pE``n>d+Pk-Rk@A=F}KC_W;J&9-w_z-Me;P^_2q%4FV%1(>;-9kLO=?=evS>*d(T^;})f0M}qKQw@UNd`@T3$~e+lSVd6Aq{qz zM9Mx*;8*Elmh>fk1a&k<(LE#sgE7{JGaIA34^tbXdtgp5%;aD4ope9`V@QMl1|^;@ Apa1{> literal 0 HcmV?d00001 diff --git a/sql/mysql/000-functions/mocha_get_instance_by_global_identifier.sql b/sql/mysql/000-functions/mocha_get_instance_by_global_identifier.sql index bc1a9cb..b4dfbdd 100644 --- a/sql/mysql/000-functions/mocha_get_instance_by_global_identifier.sql +++ b/sql/mysql/000-functions/mocha_get_instance_by_global_identifier.sql @@ -7,6 +7,7 @@ CREATE FUNCTION mocha_get_instance_by_global_identifier RETURNS INT DETERMINISTIC RETURN ( - SELECT id FROM mocha_instances WHERE tenant_id = mocha_get_current_tenant() + SELECT id FROM mocha_instances + WHERE (tenant_id = mocha_get_current_tenant() OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = mocha_get_current_tenant())) AND mocha_normalize_uuid(global_identifier) = mocha_normalize_uuid(p_global_identifier) ORDER BY id DESC LIMIT 1); \ No newline at end of file diff --git a/sql/mysql/000-functions/mocha_get_instance_by_key.sql b/sql/mysql/000-functions/mocha_get_instance_by_key.sql index 61dc947..3c032e2 100644 --- a/sql/mysql/000-functions/mocha_get_instance_by_key.sql +++ b/sql/mysql/000-functions/mocha_get_instance_by_key.sql @@ -6,4 +6,12 @@ CREATE FUNCTION mocha_get_instance_by_key p_inst_id INT ) RETURNS INT -RETURN (SELECT id FROM mocha_instances WHERE tenant_id = mocha_get_current_tenant() AND class_id = p_class_id AND inst_id = p_inst_id LIMIT 1); \ No newline at end of file +RETURN (SELECT id FROM mocha_instances + + WHERE (tenant_id = mocha_get_current_tenant() + OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = mocha_get_current_tenant()) + ) + AND class_id = p_class_id + AND inst_id = p_inst_id + LIMIT 1 +); \ No newline at end of file diff --git a/sql/mysql/000-functions/mocha_get_user_by_username.sql b/sql/mysql/000-functions/mocha_get_user_by_username.sql index 2b15107..a19fc53 100644 --- a/sql/mysql/000-functions/mocha_get_user_by_username.sql +++ b/sql/mysql/000-functions/mocha_get_user_by_username.sql @@ -7,7 +7,7 @@ CREATE FUNCTION mocha_get_user_by_username RETURNS INT RETURN ( SELECT src_inst_id FROM mocha_attributes - WHERE tenant_id = mocha_get_current_tenant() + WHERE (tenant_id = mocha_get_current_tenant() OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = mocha_get_current_tenant())) AND att_inst_id = mocha_get_instance_by_global_identifier('960FAF025C5940F791A720012A99D9ED') AND att_value = p_user_name ORDER BY att_effective_date DESC diff --git a/sql/mysql/001-procedures/mocha_create_instance_of.sql b/sql/mysql/001-procedures/mocha_create_instance_of.sql index b35545e..a782225 100644 --- a/sql/mysql/001-procedures/mocha_create_instance_of.sql +++ b/sql/mysql/001-procedures/mocha_create_instance_of.sql @@ -19,7 +19,9 @@ sp: BEGIN SET p_tenant_id = mocha_get_current_tenant(); - SET p_class_index = (SELECT inst_id FROM mocha_instances WHERE tenant_id = p_tenant_id AND class_id = 1 AND id = p_class_inst_id); + SET p_class_index = (SELECT inst_id FROM mocha_instances + WHERE (tenant_id = p_tenant_id OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = p_tenant_id)) + AND class_id = 1 AND id = p_class_inst_id); IF p_class_index IS NULL THEN SELECT "cannot create an instance of something that is not a Class" AS error_description; diff --git a/sql/mysql/001-procedures/mocha_get_attribute_value.sql b/sql/mysql/001-procedures/mocha_get_attribute_value.sql index 38aaa46..5bfa490 100644 --- a/sql/mysql/001-procedures/mocha_get_attribute_value.sql +++ b/sql/mysql/001-procedures/mocha_get_attribute_value.sql @@ -19,11 +19,11 @@ BEGIN END IF; SELECT att_value FROM mocha_attributes - WHERE tenant_id = p_tenant_id + WHERE (tenant_id = p_tenant_id OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = p_tenant_id)) AND src_inst_id = p_source_inst_id AND att_inst_id = p_attribute_inst_id AND att_effective_date <= z_effective_date - ORDER BY att_effective_date DESC, id DESC + ORDER BY tenant_id DESC, att_effective_date DESC, id DESC LIMIT 1; END; diff --git a/sql/mysql/001-procedures/mocha_get_instance_by_global_identifier.sql b/sql/mysql/001-procedures/mocha_get_instance_by_global_identifier.sql index 2691365..1981bd9 100644 --- a/sql/mysql/001-procedures/mocha_get_instance_by_global_identifier.sql +++ b/sql/mysql/001-procedures/mocha_get_instance_by_global_identifier.sql @@ -5,9 +5,13 @@ CREATE PROCEDURE mocha_get_instance_by_global_identifier IN p_global_identifier CHAR(40) ) BEGIN + DECLARE p_tenant_id INT; + + SET p_tenant_id = mocha_get_current_tenant(); SELECT * FROM mocha_instances - WHERE tenant_id = mocha_get_current_tenant() + WHERE (tenant_id = p_tenant_id OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = p_tenant_id)) + AND UPPER(global_identifier) = UPPER(REPLACE(REPLACE(REPLACE(p_global_identifier, '{', ''), '}', ''), '-', '')) ORDER BY id DESC LIMIT 1; diff --git a/sql/mysql/001-procedures/mocha_get_instance_by_key.sql b/sql/mysql/001-procedures/mocha_get_instance_by_key.sql index 7a53bdc..2f07fa6 100644 --- a/sql/mysql/001-procedures/mocha_get_instance_by_key.sql +++ b/sql/mysql/001-procedures/mocha_get_instance_by_key.sql @@ -11,7 +11,7 @@ BEGIN SET p_tenant_id = mocha_get_current_tenant(); SELECT * FROM mocha_instances - WHERE tenant_id = p_tenant_id + WHERE (tenant_id = p_tenant_id OR tenant_id IN (SELECT target_tenant_id FROM mocha_tenant_references WHERE source_tenant_id = p_tenant_id)) AND class_id = p_class_id AND inst_id = p_inst_id; diff --git a/sql/mysql/002-tables/000-mocha_tenants.sql b/sql/mysql/002-tables/000-mocha_tenants.sql index a98a56b..73f8b50 100644 --- a/sql/mysql/002-tables/000-mocha_tenants.sql +++ b/sql/mysql/002-tables/000-mocha_tenants.sql @@ -5,5 +5,6 @@ CREATE TABLE mocha_tenants id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, tenant_name VARCHAR(32), global_identifier CHAR(32), - effective_date DATETIME + effective_date DATETIME, + is_library INT NOT NULL DEFAULT 0 ); diff --git a/sql/mysql/003-data/mocha_tenants.sql b/sql/mysql/003-data/001-mocha_tenants.sql similarity index 50% rename from sql/mysql/003-data/mocha_tenants.sql rename to sql/mysql/003-data/001-mocha_tenants.sql index 2119164..d55d310 100644 --- a/sql/mysql/003-data/mocha_tenants.sql +++ b/sql/mysql/003-data/001-mocha_tenants.sql @@ -3,11 +3,19 @@ INSERT INTO mocha_tenants ( tenant_name, global_identifier, - effective_date + effective_date, + is_library ) VALUES +( + 'net.alcetech.Mocha.System', + '2826E41F763A413FB2393D9698AB629F', + NOW(), + 1 +), ( 'default', '2552F66B0DBE41EB8A8076DE8575A468', - NOW() + NOW(), + 0 ) diff --git a/sql/mysql/003-data/002-mocha_tenant_references.sql b/sql/mysql/003-data/002-mocha_tenant_references.sql new file mode 100644 index 0000000..9143d79 --- /dev/null +++ b/sql/mysql/003-data/002-mocha_tenant_references.sql @@ -0,0 +1,9 @@ +INSERT INTO mocha_tenant_references +( + source_tenant_id, + target_tenant_id +) +VALUES +( + 2, 1 +) \ No newline at end of file diff --git a/sql/mysql/003-data/mocha_instances.sql b/sql/mysql/003-data/mocha_instances.sql deleted file mode 100644 index 195dc23..0000000 --- a/sql/mysql/003-data/mocha_instances.sql +++ /dev/null @@ -1,129 +0,0 @@ --- --- mocha_instances.sql - defines the mocha_instances table --- --- Author: --- Michael Becker --- --- Copyright (c) 2021 Mike Becker's Software --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -DROP PROCEDURE IF EXISTS mocha_build_tenant_from_template; - -CREATE PROCEDURE mocha_build_tenant_from_template -( - IN p_tenant_id INT, - IN p_template_id INT -) -BEGIN - - -- we don't want to use TRUNCATE here since we only want to zap the specified tenant - CALL mocha_truncate_tenant(p_tenant_id); - - CALL mocha_select_tenant(p_tenant_id); - /* - - -- Class - CALL mocha_create_class(1, 'B9C9B9B7AD8A4CBDAA6BE05784630B6B', NULL, NULL, @dummy); - -- Attribute - CALL mocha_create_class(2, 'F9CD7751EF624F7C8A28EBE90B8F46AA', NULL, NULL, @dummy); - -- Relationship - CALL mocha_create_class(3, '9B0A80F9C3254D36997CFB4106204648', NULL, NULL, @dummy); - - -- Class.has Instance - CALL mocha_create_instance_of(mocha_get_instance_by_global_identifier('9B0A80F9C3254D36997CFB4106204648'), '7EB41D3C2AE9488483A4E59441BCAEFB', NULL, NULL, @dummy) - -- Instance.for Class - CALL mocha_create_instance_of(mocha_get_instance_by_global_identifier('9B0A80F9C3254D36997CFB4106204648'), '494D5A6D04BE477B8763E3F57D0DD8C8', NULL, NULL, @dummy) - - CALL mocha_set_parent_class(mocha_get_instance_by_key(1, 1), mocha_get_instance_by_key(1, 1), NULL, NOW()); - - -- Text Attribute - CALL mocha_create_class(4, 'C2F3654260C34B9E9A96CA9B309C43AF', NULL, NULL, @dummy); - - -- Text Attribute: 'Name' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), '9153A637992E4712ADF2B03F0D9EDEA6', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 1), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Name', NULL, NULL); - - -- Text Attribute: 'Value' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), '041DD7FD2D9C412B8B9DD7125C166FE0', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 2), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Value', NULL, NULL); - - -- Text Attribute: 'Verb' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), '61345a5d33974a9687978863f03a476c', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 3), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Verb', NULL, NULL); - - -- Text Attribute: 'User Name' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), '960FAF025C5940F791A720012A99D9ED', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 4), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'User Name', NULL, NULL); - - -- Text Attribute: 'Password Hash' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), 'F377FC294DF14AFB96434191F37A00A9', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 5), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Password Hash', NULL, NULL); - - -- Text Attribute: 'Password Salt' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), '8C5A99BC40ED4FA2B23FF373C1F3F4BE', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 6), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Password Salt', NULL, NULL); - - -- Text Attribute: 'Token' - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 4), 'da7686b638034f1597f67f8f3ae16668', NULL, NOW(), @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(4, 7), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Token', NULL, NULL); - - -- name = 9153A637992E4712ADF2B03F0D9EDEA6 - -- value = 041DD7FD2D9C412B8B9DD7125C166FE0 - - -- CALL mocha_assign_translation(mocha_get_instance_by_global_identifier('61345a5d33974a9687978863f03a476c'), mocha_get_instance_by_global_identifier('')) - - CALL mocha_create_class(39, '9C6871C19A7F4A3A900E69D1D9E24486', NULL, NULL, @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(1, 39), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'System User', NULL, NULL); - - CALL mocha_create_class(96, '703F9D65C5844D9FA656D0E3C247FF1F', NULL, NULL, @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(1, 96), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'Tenant', NULL, NULL); - - -- zq-environments, 39$1 - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 39), 'B066A54BB1604510A805436D3F90C2E6', NULL, NOW(), @dummy); - -- username - CALL mocha_set_attribute_value(mocha_get_instance_by_key(39, 1), mocha_get_instance_by_global_identifier('960FAF025C5940F791A720012A99D9ED'), 'zq-environments', NULL, NULL); - - -- zq-developer, 39$2 - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 39), '098DDA82CD044B538C7589D420EA6902', NULL, NOW(), @dummy); - -- username - CALL mocha_set_attribute_value(mocha_get_instance_by_key(39, 2), mocha_get_instance_by_global_identifier('960FAF025C5940F791A720012A99D9ED'), 'zq-developer', NULL, NULL); - -- password - CALL mocha_set_attribute_value(mocha_get_instance_by_key(39, 2), mocha_get_instance_by_global_identifier('F377FC294DF14AFB96434191F37A00A9'), 'f4f166c4d578cb5ca942e07851d7c09de07d417463f2d8e5165a779f768d14b370cd1e82826a94b617b6c6359253e8c12ea8285cba1e6e69e2e13f2bdc0425d0', NULL, NULL); - -- salt - CALL mocha_set_attribute_value(mocha_get_instance_by_key(39, 2), mocha_get_instance_by_global_identifier('8C5A99BC40ED4FA2B23FF373C1F3F4BE'), '7e893ba949b041bab73c6f4f0bcb9413', NULL, NULL); - - - CALL mocha_create_user('superuser', '69e291d8381b4ad89013f3b0a0c693fe'); - CALL mocha_create_user('zq-support', '232A8CBF0D2B4BDABE863E2FA25A3FB5'); - CALL mocha_create_user('zq-configurator', 'FB20A79CEAA24A98A1DABDC351854694'); - CALL mocha_create_user('zq-implementer', '63F2EF51DC7348EC856A6FBBEDE01A8A'); - CALL mocha_create_user('admin', '739C26BC740F4CB0BCB12A28FA570E7D'); - - -- default tenant - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 96), 'F2C9D4A99EFB426384DB66A9DA65AD00', NULL, NOW(), @dummy); - - -- User Login - CALL mocha_create_class(105, '64F4BCDB38D04373BA308AE99AF1A5F7', NULL, NULL, @dummy); - CALL mocha_set_attribute_value(mocha_get_instance_by_key(1, 105), mocha_get_instance_by_global_identifier('9153A637992E4712ADF2B03F0D9EDEA6'), 'User Login', NULL, NULL); - - -- relationship : User Login.has User - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 3), '85B40E4B849B4006A9C04E201B25975F', NULL, NOW(), @dummy); - -- relationship : User.for User Login - CALL mocha_create_instance_of(mocha_get_instance_by_key(1, 3), 'C79A6041FC9441A59860D443C60FA7DE', NULL, NOW(), @dummy); -*/ - - CALL mocha_release_tenant(); - -END;