Piotr Labudda 7 år sedan
förälder
incheckning
0c2627f218
2 ändrade filer med 143 tillägg och 18 borttagningar
  1. 43 1
      SE/se-lib/RefConfig.php
  2. 100 17
      SE/se-lib/Route/Status.php

+ 43 - 1
SE/se-lib/RefConfig.php

@@ -32,9 +32,51 @@ Lib::loadClass('SchemaVersionUpgrade');
 
 class RefConfig {
 
-	// $REF_TABLE_VERSION = 5; // TODO: add unique key to (PRIMARY_KEY, REMOTE_PRIMARY_KEY)
 	static $REF_TABLE_VERSION = 6;
+	// TODO: add unique key to (PRIMARY_KEY, REMOTE_PRIMARY_KEY)
 	// $REF_TABLE_VERSION = 4; // added ref event log table - `CRM__#REF_LOG__*`
+	static function getVersion() {
+		return self::$REF_TABLE_VERSION;
+	}
+	static function getToUpdateTotal() {
+		return DB::getPDO()->fetchValue("
+			select count(*) as cnt
+			from `CRM_REF_CONFIG` c
+			where c.A_STATUS = 'NORMAL' and c.VERSION < :version
+		", [
+			':version' => self::$REF_TABLE_VERSION,
+		]);
+	}
+	static function getToUpdateItems($type = 'table') {
+		$sqlWhereAndType = "";
+		switch ($type) {
+			case 'backRef': $sqlWhereAndType = " and c.SOURCE in ( 'backRef' ) "; break;
+			default: $sqlWhereAndType = " and c.SOURCE in ( 'table', 'view' ) "; break;
+		}
+		return DB::getPDO()->fetchAll("
+			select c.ID, c.ROOT_OBJECT_NS, c.CHILD_NAME, c.CHILD_NS
+			from `CRM_REF_CONFIG` c
+			where c.A_STATUS = 'NORMAL' and c.VERSION < :version {$sqlWhereAndType}
+		", [
+			':version' => self::$REF_TABLE_VERSION,
+		]);
+	}
+	static function backRefCheck() {
+		// TODO: p_ID != NULL - parent Ref must exist
+		// TODO: p_SOURCE != 'backRef' - only ( 'table', 'view' ) allowed as source ref
+		// TODO: p_SOURCE = 'NORMAL'
+		//       whene p_SOURCE = 'WAITING' then update p_SOURCE to 'WAITING' too
+		//       whene p_SOURCE = 'DELETED' then update p_SOURCE to 'DELETED' too
+		$backRefCheckSql = "
+			select c.ID, c.SOURCE, c.A_STATUS, c.ROOT_OBJECT_NS, c.CHILD_NAME, c.CHILD_NS
+				, p.ID as p_ID, p.SOURCE as p_SOURCE, p.A_STATUS as p_A_STATUS, p.ROOT_OBJECT_NS as p_ROOT_OBJECT_NS, p.CHILD_NAME as p_CHILD_NAME, p.CHILD_NS as p_CHILD_NS
+			from `CRM_REF_CONFIG` c
+				left join `CRM_REF_CONFIG` p on ( p.ROOT_OBJECT_NS = c.CHILD_NS and p.CHILD_NS = c.ROOT_OBJECT_NS )
+			where c.A_STATUS = 'NORMAL' and c.SOURCE in ( 'backRef' )
+		";
+		return DB::getPDO()->fetchAll($backRefCheckSql);
+	}
+
 
 	static function isActive($objectNamespace, $childTypeName) {
 		$refInfo = self::fetch($objectNamespace, $childTypeName);

+ 100 - 17
SE/se-lib/Route/Status.php

@@ -18,19 +18,7 @@ class Route_Status extends RouteBase {
 		try {
 			DB::getPDO();
 
-			if ($postTask = V::get('_postTask', '', $_REQUEST)) {
-				DBG::log($args, 'array', "exec '{$postTask}'");
-				if (!method_exists($this, "{$postTask}PostTask")) throw new Exception("Post Task not exists!");
-				ob_start();
-				$this->{"{$postTask}PostTask"}($args);
-				$outputPostTask = ob_get_clean();
-				if ($outputPostTask) {
-					echo UI::h('details', [], [
-						UI::h('summary', [], "Wynik '{$postTask}' <i>(rozwiń)</i>"),
-						$outputPostTask,
-					]);
-				}
-			}
+			$this->runPostTask();
 
 			$this->viewStatusDatabase();
 
@@ -48,6 +36,21 @@ class Route_Status extends RouteBase {
 		UI::endTag('div');// .container
 		UI::dol();
 	}
+	function runPostTask() {
+		if ($postTask = V::get('_postTask', '', $_REQUEST)) {
+			DBG::log($args, 'array', "exec '{$postTask}'");
+			if (!method_exists($this, "{$postTask}PostTask")) throw new Exception("Post Task not exists!");
+			ob_start();
+			$this->{"{$postTask}PostTask"}($args);
+			$outputPostTask = ob_get_clean();
+			if ($outputPostTask) {
+				echo UI::h('details', [], [
+					UI::h('summary', [], "Wynik '{$postTask}' <i>(rozwiń)</i>"),
+					$outputPostTask,
+				]);
+			}
+		}
+	}
 
 	public function viewStatusDatabase() {
 		$dbEvents = DB::getPDO()->fetchFirst(" SHOW VARIABLES WHERE VARIABLE_NAME = 'event_scheduler' ");
@@ -69,6 +72,9 @@ class Route_Status extends RouteBase {
 		DBG::log($objectStorage, 'array', "\$objectStorage");
 		DBG::log($objectStorage->getRootTableName(), 'array', "\$objectStorage->getRootTableName()");
 
+		Lib::loadClass('RefConfig');
+		$totalToUpdateRef = RefConfig::getToUpdateTotal();
+
 		UI::table([
 			'caption' => UI::h('b', ['style' => "color:#000"], 'Baza danych'),
 			'rows' => [
@@ -96,6 +102,18 @@ class Route_Status extends RouteBase {
 						]
 					])
 				],
+				[
+					'nazwa' => "Tabela z relacjami (REF)",
+					'wartość' => ($totalToUpdateRef)
+					?	UI::h('span', ['class' => "label label-danger"], "wymaga aktualizacji ({$totalToUpdateRef})")
+					:	UI::h('span', ['class' => "label label-success"], "akualne"),
+					'#' => UI::hButtonPost("Aktualizuj tabele relacyjne", [
+						'class' => "btn btn-xs btn-default",
+						'data' => [
+							'_postTask' => 'updateRefTables'
+						]
+					])
+				],
 			]
 		]);
 	}
@@ -109,14 +127,79 @@ class Route_Status extends RouteBase {
 		SchemaFactory::loadDefaultObject('SystemObjectField')->updateCache();
 		UI::alert('info', "Lista obiketów zaktualizowana");
 	}
+	function updateRefTablesPostTask() {
+		Lib::loadClass('RefConfig');
+		DBG::log("DBG:updateRefTablesPostTask...");
+		$toUpdateStep = 10;
+		$baseRefOffset = V::get('baseref_offset', 0, $_POST, 'int');
+		$backRefOffset = V::get('backref_offset', 0, $_POST, 'int');
+		$todoBaseRefOffset = $baseRefOffset;
+		$todoBackRefOffset = $backRefOffset;
+		$baseRefToUpdate = RefConfig::getToUpdateItems();
+		DBG::log($baseRefToUpdate, 'array', "DBG:updateRefTablesPostTask \$baseRefToUpdate");
+		if ($baseRefOffset > count($baseRefToUpdate)) {
+			$backRefToUpdate = RefConfig::getToUpdateItems('backRef');
+			$listBackRefConf = array_slice($backRefToUpdate, $backRefOffset, $toUpdateStep);
+			DBG::log($listBackRefConf, 'array', "DBG:updateRefTablesPostTask \$listBackRefConf ({$backRefOffset}, {$toUpdateStep})");
+			self::_updateRefTables($listBackRefConf);
+			$todoBackRefOffset = $backRefOffset + $toUpdateStep;
+		} else {
+			$listBaseRefConf = array_slice($baseRefToUpdate, $baseRefOffset, $toUpdateStep);
+			DBG::log($listBaseRefConf, 'array', "DBG:updateRefTablesPostTask \$listBaseRefConf ({$baseRefOffset}, {$toUpdateStep})");
+			self::_updateRefTables($listBaseRefConf);
+			$todoBaseRefOffset = $baseRefOffset + $toUpdateStep;
+		}
+
+		$totalToUpdateRef = RefConfig::getToUpdateTotal();
+		echo ($totalToUpdateRef)
+		?	UI::h('div', [ 'class' => 'alert alert-warning'], [
+				"Uwaga: Struktura tabel z relacjami częściowo zaktualizowana. Pozostało {$totalToUpdateRef}. ",
+				UI::hButtonPost("Uruchom dla kolejnych", [
+					'class' => "btn btn-xs btn-default",
+					'data' => [
+						'_postTask' => 'updateRefTables',
+						'baseref_offset' => $todoBaseRefOffset,
+						'backref_offset' => $todoBackRefOffset,
+					]
+				])
+			])
+		: UI::h('div', [ 'class' => 'alert alert-info' ], "Struktura tabel z relacjami zaktualizowana");
+	}
+	static function _updateRefTables($listRefConf) {
+		Lib::loadClass('RefConfig');
+		// $listRefConf = array_slice($listRefConf, 0, 10);
+		$totalTableSkippedNotAcl = 0;
+		$totalTableSkippedMissingAclType = 0;
+		$totalTableSkippedFieldNotFound = 0;
+		DBG::nicePrint($listRefConf, '$listRefConf');
+		foreach ($listRefConf as $refConf) {
+			try {
+				UI::alert('info', "Aktualizuje ['{$refConf['ID']}'] od '{$refConf['ROOT_OBJECT_NS']}' do '{$refConf['CHILD_NAME']}' ...");
+				RefConfig::getRefConfig($refConf['ROOT_OBJECT_NS'], $refConf['CHILD_NAME'], $refConf['CHILD_NS']);
+			} catch (\Exception $e) {
+				DBG::log($e);
+				if ('Ref allowed only for AntAcl objects' === $e->getMessage()) {
+					$totalTableSkippedNotAcl++;
+				} else if ('Field ' === substr($e->getMessage(), 0, strlen('Field ')) && false !== strpos($e->getMessage(), 'not found')) {
+					$totalTableSkippedFieldNotFound++;
+				} else if ("Not Implemented acl type ''" === substr($e->getMessage(), 0, strlen("Not Implemented acl type ''"))) {
+					$totalTableSkippedMissingAclType++;
+				}
+				UI::alert('danger', "Problem z aktualizacją tabeli z relacjami ['{$refConf['ID']}'] od '{$refConf['ROOT_OBJECT_NS']}' do '{$refConf['CHILD_NAME']}'");
+			}
+		}
+		if ($totalTableSkippedNotAcl) UI::alert('warning', "Nie zaktualizowano {$totalTableSkippedNotAcl} tabeli z relajami - obiekty różnego typu od 'Acl'");
+		if ($totalTableSkippedFieldNotFound) UI::alert('warning', "Nie zaktualizowano {$totalTableSkippedFieldNotFound} tabeli z relajami - pola 'do' nie istnieją");
+		if ($totalTableSkippedMissingAclType) UI::alert('warning', "Nie zaktualizowano {$totalTableSkippedMissingAclType} tabeli z relajami - brak typu obiektu (Instance config)");
+	}
 
 	public function viewStatusUsers() {
 		$nowMinus3Months = date("Y-m-d", mktime(0,0,0, date('m') - 1, date('d'), date('Y')));
 		$sesUsers = DB::getPDO()->fetchAll("
-			select c.ID, c.CONF_KEY, c.CONF_VAL
-			from CRM_CONFIG c
-			where c.CONF_KEY like 'acl_user_%_%_cache_update'
-			and c.CONF_VAL > '{$nowMinus3Months}'
+		select c.ID, c.CONF_KEY, c.CONF_VAL
+		from CRM_CONFIG c
+		where c.CONF_KEY like 'acl_user_%_%_cache_update'
+		and c.CONF_VAL > '{$nowMinus3Months}'
 		");
 		$sesUsers = array_reduce( $sesUsers, function ($ret, $record) {
 			// $format = "acl_user_{ID_USERS}_{ID_PROCES}_cache_update";