Przeglądaj źródła

updated wps relations get, create, delete

Piotr Labudda 7 lat temu
rodzic
commit
2e1f198776
4 zmienionych plików z 99 dodań i 25 usunięć
  1. 29 14
      SE/se-lib/ACL.php
  2. 18 0
      SE/se-lib/Core/Pdo.php
  3. 38 2
      SE/se-lib/RefConfig.php
  4. 14 9
      SE/se-lib/Relations.php

+ 29 - 14
SE/se-lib/ACL.php

@@ -243,31 +243,46 @@ class ACL {
 		return $refConfig->source;
 	}
 
-	public static function addRef($ns, $remoteTypeName, $pk, $remotePk) {
-		$refTable = ACL::getRefTable($ns, $remoteTypeName); // TODO: RefConfig::fetch($ns, $remoteTypeName);
-		DB::getPDO()->insert($refTable, [ 'PRIMARY_KEY' => $pk, 'REMOTE_PRIMARY_KEY' => $remotePk ]);
+	static function addRef($namespace, $remoteTypeName, $pk, $remotePk) {
+		self::addListRef($namespace, $remoteTypeName, $pk, [ $remotePk ]);
 	}
-	public static function addListRef($ns, $remoteTypeName, $pk, $listRemotePk) {
-		$refTable = ACL::getRefTable($ns, $remoteTypeName); // TODO: RefConfig::fetch($ns, $remoteTypeName);
+	static function addListRef($namespace, $remoteTypeName, $pk, $listRemotePk) {
+		$refTable = ACL::getRefTable($namespace, $remoteTypeName); // TODO: RefConfig::fetch($namespace, $remoteTypeName);
 		foreach ($listRemotePk as $remotePk) {
-			DB::getPDO()->insert($refTable, [ 'PRIMARY_KEY' => $pk, 'REMOTE_PRIMARY_KEY' => $remotePk ]);
+			DB::getPDO()->insertIgnore($refTable, [ 'PRIMARY_KEY' => $pk, 'REMOTE_PRIMARY_KEY' => $remotePk ]);
+		}
+		$refLogTable = RefConfig::getRefEventLogTable($namespace, $remoteTypeName);
+		foreach ($listRemotePk as $remotePk) {
+			DB::getPDO()->insert($refLogTable, [
+				'PRIMARY_KEY' => $pk,
+				'REMOTE_PRIMARY_KEY' => $remotePk,
+				'REMOTE_TYPENAME' => $remoteTypeName,
+				'A_STATUS' => "NORMAL",
+				// 'TRANSACTION_ID' => 0,
+			]);
 		}
 	}
-	public static function removeRef($ns, $typeName, $pk, $remotePk) {
-		$refTable = ACL::getRefTable($ns, $typeName); // TODO: RefConfig::fetch($ns, $typeName);
-		DB::getPDO()->execSql(" delete from `{$refTable}` where PRIMARY_KEY = :pk and REMOTE_PRIMARY_KEY = :remote_pk ", [
-			':pk' => $pk,
-			':remote_pk' => $remotePk
-		]);
+	static function removeRef($namespace, $remoteTypeName, $pk, $remotePk) {
+		self::removeListRef($namespace, $remoteTypeName, $pk, [ $remotePk ]);
 	}
-	public static function removeListRef($ns, $typeName, $pk, $listRemotePk) {
-		$refTable = ACL::getRefTable($ns, $typeName); // TODO: RefConfig::fetch($ns, $typeName);
+	static function removeListRef($namepace, $remoteTypeName, $pk, $listRemotePk) {
+		$refTable = ACL::getRefTable($namepace, $remoteTypeName); // TODO: RefConfig::fetch($namepace, $remoteTypeName);
 		foreach ($listRemotePk as $remotePk) {
 			DB::getPDO()->execSql(" delete from `{$refTable}` where PRIMARY_KEY = :pk and REMOTE_PRIMARY_KEY = :remote_pk ", [
 				':pk' => $pk,
 				':remote_pk' => $remotePk
 			]);
 		}
+		$refLogTable = RefConfig::getRefEventLogTable($namepace, $remoteTypeName);
+		foreach ($listRemotePk as $remotePk) {
+			DB::getPDO()->insert($refLogTable, [
+				'PRIMARY_KEY' => $pk,
+				'REMOTE_PRIMARY_KEY' => $remotePk,
+				'REMOTE_TYPENAME' => $remoteTypeName,
+				'A_STATUS' => "DELETED",
+				// 'TRANSACTION_ID' => 0,
+			]);
+		}
 	}
 
 	public static function decodeAppInfoJson($appInfoJsonString) {

+ 18 - 0
SE/se-lib/Core/Pdo.php

@@ -571,6 +571,24 @@ EOF_STRUCT_MYSQL;
 		return $this->lastInsertId();
 	}
 
+	public function insertIgnore($tableName, $item, $sqlSchema = []) {// @returns int last inserted id
+		if (empty($tableName)) throw new Exception("Missing table name");
+		if (!is_array($item)) throw new Exception("Missing item");
+		$sqlFields = [];
+		$sqlValues = [];
+		foreach ($item as $field => $val) {
+			$sqlFields[] = $this->identifierQuote($field);
+			$sqlValues[] = $this->convertValueToSqlSafe($val, V::get($field, null, $sqlSchema));
+		}
+		$sqlTableName = $this->tableNameQuote($tableName);
+		$sql = "
+			insert ignore into {$sqlTableName} (" . implode(", ", $sqlFields) . ")
+				values (" . implode(", ", $sqlValues) . ")
+		";
+		$this->execSql($sql);
+		return $this->lastInsertId();
+	}
+
 	public function update($tableName, $primaryKeyName, $primaryKey, $item, $sqlSchema = []) {// @returns int affected rows
 		if (empty($tableName)) throw new Exception("Missing table name");
 		if (empty($primaryKeyName)) throw new Exception("Missing primaryKey name");

+ 38 - 2
SE/se-lib/RefConfig.php

@@ -32,7 +32,9 @@ Lib::loadClass('SchemaVersionUpgrade');
 
 class RefConfig {
 
-	static $REF_TABLE_VERSION = 3;
+	// $REF_TABLE_VERSION = 5; // TODO: add unique key to (PRIMARY_KEY, REMOTE_PRIMARY_KEY)
+	static $REF_TABLE_VERSION = 4;
+	// $REF_TABLE_VERSION = 4; // added ref event log table - `CRM__#REF_LOG__*`
 
 	static function isActive($objectNamespace, $childTypeName) {
 		$refInfo = self::fetch($objectNamespace, $childTypeName);
@@ -52,7 +54,7 @@ class RefConfig {
 		$refConfig = self::fetch($rootObjectNamespace, $childTypeName, $childNamespace);
 		if ('WAITING' == $refConfig->status || $refConfig->version < self::$REF_TABLE_VERSION) {
 			$typeField = Type_Field::build($fieldInfo);
-			self::update($rootObjectNamespace, $childTypeName, $typeField);
+			self::update($rootObjectNamespace, $childTypeName, $typeField, $refConfig);
 			$refConfig = self::fetch($rootObjectNamespace, $childTypeName, $childNamespace);
 		}
 
@@ -171,6 +173,14 @@ class RefConfig {
 		$oldRefSource = $refConfig->source;
 		if ($newRefSource !== $oldRefSource) DBG::log("RefConfig::update Change ref source from '{$oldRefSource}' to '{$newRefSource}'");
 		// always update ref config at reinstall - drop / create ref tables (table or view)
+
+		if ($refConfig->version < 4) self::installEventLogTable($objectNamespace, $childTypeName, $newField, $refConfig);
+
+		// if ($refConfig->version < 5) {
+		// 	Lib::loadClass('RefConfig_UpdateToVersion5');
+		// 	RefConfig_UpdateToVersion4::updateToVersion5($objectNamespace, $childTypeName, $newField, $refConfig);
+		// }
+
 		switch ($newRefSource) {
 			case 'table': return self::installRefTable($objectNamespace, $childTypeName, $newField, $refConfig);
 			case 'view': return self::installRefView($objectNamespace, $childTypeName, $newField, $refConfig);
@@ -191,6 +201,7 @@ class RefConfig {
 				, `A_STATUS` enum('WAITING', 'NORMAL', 'DELETED') NOT NULL DEFAULT 'WAITING'
 				, `TRANSACTION_ID` int(11) NOT NULL
 				, `A_LAST_ACTION_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+				, UNIQUE KEY `unique_ref` (`PRIMARY_KEY`,`REMOTE_PRIMARY_KEY`)
 				, KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
 				, KEY `REMOTE_PRIMARY_KEY` (`REMOTE_PRIMARY_KEY`)
 				, KEY `TRANSACTION_ID` (`TRANSACTION_ID`)
@@ -454,4 +465,29 @@ class RefConfig {
 		]);
 	}
 
+	static function getRefEventLogTable($objectNamespace, $childTypeName) {
+		$refConfig = self::fetch($objectNamespace, $childTypeName);
+		return "CRM__#REF_LOG__{$refConfig->id}";
+	}
+	static function installEventLogTable($objectNamespace, $childTypeName, Type_Field $newField, Type_RefConfig $refConfig = null) {
+		// $refConfig->id
+		// $refConfig->source
+		// $refConfig->version
+		// $refConfig->tableName
+		$sqlLogTableName = self::getRefEventLogTable($objectNamespace, $childTypeName);
+		DB::getPDO()->execSql("
+			CREATE TABLE IF NOT EXISTS `{$sqlLogTableName}` (
+				`PRIMARY_KEY` int(11) NOT NULL
+				, `REMOTE_PRIMARY_KEY` int(11) NOT NULL
+				, `REMOTE_TYPENAME` varchar(255) NOT NULL DEFAULT ''
+				, `A_STATUS` enum('WAITING', 'NORMAL', 'DELETED') NOT NULL DEFAULT 'WAITING'
+				, `TRANSACTION_ID` int(11) NOT NULL
+				, `A_ACTION_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
+				, KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
+				, KEY `REMOTE_PRIMARY_KEY` (`REMOTE_PRIMARY_KEY`)
+				, KEY `TRANSACTION_ID` (`TRANSACTION_ID`)
+			) ENGINE=MyISAM DEFAULT CHARSET=latin2 COMMENT='{$objectNamespace} #REF {$childTypeName}';
+		");
+	}
+
 }

+ 14 - 9
SE/se-lib/Relations.php

@@ -5,6 +5,17 @@ Lib::loadClass('Api_WfsNs');
 
 class Relations {
 
+	static function isAllowedToGetRelation($userLogin, $typeName, $primaryKey, $remoteTypeName) {
+		if ($userLogin !== User::getLogin()) throw new Exception("Not Implemented - isAllowedToGetRelation for another user");
+		$acl = ACL::getAclByNamespace( Api_WfsNs::toNamespace($typeName) );
+		if (!$acl->hasField($remoteTypeName)) throw new Exception("Missing field in given object. Field '{$remoteTypeName}' not exists in '{$typeName}'");
+		if (!$acl->canReadField($remoteTypeName)) throw new HttpException("Forbidden reading relations from {$typeName} to {$remoteTypeName} ", 403);
+		$item = $acl->getItem($primaryKey);
+		if (!$item) throw new HttpException("Object not found {$typeName}.{$primaryKey}", 404);
+		if (!$acl->canReadObjectField($remoteTypeName, $item)) throw new HttpException("Forbidden reading relations from {$typeName}.{$primaryKey} to {$remoteTypeName} ", 403);
+		return true;
+	}
+
 	static function isAllowedToCreateRelation($userLogin, $typeName, $primaryKey, $remoteTypeName) {
 		if ($userLogin !== User::getLogin()) throw new Exception("Not Implemented - isAllowedToCreateRelation for another user");
 		$acl = ACL::getAclByNamespace( Api_WfsNs::toNamespace($typeName) );
@@ -16,22 +27,16 @@ class Relations {
 		return true;
 	}
 
-	static function isAllowedToGetRelation($userLogin, $typeName, $primaryKey, $remoteTypeName) {
-		if ($userLogin !== User::getLogin()) throw new Exception("Not Implemented - isAllowedToGetRelation for another user");
+	static function isAllowedToDeleteRelation($userLogin, $typeName, $primaryKey, $remoteTypeName) {
+		if ($userLogin !== User::getLogin()) throw new Exception("Not Implemented - isAllowedToDeleteRelation for another user");
 		$acl = ACL::getAclByNamespace( Api_WfsNs::toNamespace($typeName) );
 		if (!$acl->hasField($remoteTypeName)) throw new Exception("Missing field in given object. Field '{$remoteTypeName}' not exists in '{$typeName}'");
-		if (!$acl->canReadField($remoteTypeName)) throw new HttpException("Forbidden reading relations from {$typeName} to {$remoteTypeName} ", 403);
 		$item = $acl->getItem($primaryKey);
 		if (!$item) throw new HttpException("Object not found {$typeName}.{$primaryKey}", 404);
-		if (!$acl->canReadObjectField($remoteTypeName, $item)) throw new HttpException("Forbidden reading relations from {$typeName}.{$primaryKey} to {$remoteTypeName} ", 403);
+		if (!$acl->canWriteObjectField($remoteTypeName, $item)) throw new HttpException("Forbidden delete relations from {$typeName}.{$primaryKey} to {$remoteTypeName} ", 403);
 		return true;
 	}
 
-	static function isAllowedToDeleteRelation($userLogin, $typeName, $primaryKey, $remoteTypeName) {
-		DBG::log("TODO: Relations::isAllowedToDeleteRelation()...");
-		return false;
-	}
-
 	static function getRelations($typeName, $primaryKey, $remoteTypeName) {
 		$namespace = Api_WfsNs::toNamespace($typeName);
 		return ACL::fetchRefs($namespace, $primaryKey, $remoteTypeName);