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 0000000..dbb7f7f Binary files /dev/null and b/python/mocha/core/__pycache__/InstanceKey.cpython-311.pyc differ 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 0000000..89a6e4c Binary files /dev/null and b/python/mocha/core/__pycache__/InstanceReference.cpython-311.pyc differ 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 0000000..b7494ba Binary files /dev/null and b/python/mocha/core/__pycache__/TenantReference.cpython-311.pyc differ 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 0000000..1dcb7bb Binary files /dev/null and b/python/mocha/core/__pycache__/__init__.cpython-311.pyc differ 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 0000000..5c23b09 Binary files /dev/null and b/python/mocha/oms/__pycache__/Oms.cpython-311.pyc differ diff --git a/python/mocha/oms/__pycache__/__init__.cpython-311.pyc b/python/mocha/oms/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..39197e8 Binary files /dev/null and b/python/mocha/oms/__pycache__/__init__.cpython-311.pyc differ 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 0000000..1eec16a Binary files /dev/null and b/python/mocha/oms/memory/__pycache__/MemoryOms.cpython-311.pyc differ diff --git a/python/mocha/oms/memory/__pycache__/__init__.cpython-311.pyc b/python/mocha/oms/memory/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..4b0613f Binary files /dev/null and b/python/mocha/oms/memory/__pycache__/__init__.cpython-311.pyc differ diff --git a/python/mocha/web/__pycache__/WebRequestHandler.cpython-311.pyc b/python/mocha/web/__pycache__/WebRequestHandler.cpython-311.pyc new file mode 100644 index 0000000..f5372a1 Binary files /dev/null and b/python/mocha/web/__pycache__/WebRequestHandler.cpython-311.pyc differ 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 0000000..ad805fe Binary files /dev/null and b/python/mocha/web/__pycache__/WebServer.cpython-311.pyc differ 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;