public static function assertFilesEqualDatabase() { HookMock::setUp(HookMock::TRUE_HOOKS); self::staticInitialization(); $entityNames = self::$schemaInfo->getAllEntityNames(); foreach ($entityNames as $entityName) { self::assertEntitiesEqualDatabase($entityName); } self::clearGlobalVariables(); HookMock::tearDown(); }
private function countEntities() { $entities = $this->schema->getAllEntityNames(); $totalEntitiesCount = 0; foreach ($entities as $entity) { $table = $this->schema->getPrefixedTableName($entity); $totalEntitiesCount += $this->database->get_var("SELECT COUNT(*) FROM {$table}"); } return $totalEntitiesCount; }
/** * Returns true if there is any entity with reference to the passed one. * * @param $entityName * @param $entityId * @return bool */ private function existsSomeEntityWithReferenceTo($entityName, $entityId) { $entityNames = $this->dbSchemaInfo->getAllEntityNames(); foreach ($entityNames as $otherEntityName) { $otherEntityInfo = $this->dbSchemaInfo->getEntityInfo($otherEntityName); $otherEntityReferences = $otherEntityInfo->references; $otherEntityMnReferences = $otherEntityInfo->mnReferences; $otherEntityValueReferences = $otherEntityInfo->valueReferences; $allReferences = array_merge($otherEntityReferences, $otherEntityMnReferences, $otherEntityValueReferences); $reference = array_search($entityName, $allReferences); if ($reference === false) { // Other entity is not referencing $entityName continue; } $otherEntityStorage = $this->storageFactory->getStorage($otherEntityName); $possiblyReferencingEntities = $otherEntityStorage->loadAll(); if (isset($otherEntityReferences[$reference])) { // 1:N reference $vpReference = "vp_{$reference}"; foreach ($possiblyReferencingEntities as $possiblyReferencingEntity) { if (isset($possiblyReferencingEntity[$vpReference]) && $possiblyReferencingEntity[$vpReference] === $entityId) { return true; } } } elseif (isset($otherEntityMnReferences[$reference])) { // M:N reference $vpReference = "vp_{$otherEntityName}"; foreach ($possiblyReferencingEntities as $possiblyReferencingEntity) { if (isset($possiblyReferencingEntity[$vpReference]) && array_search($entityId, $possiblyReferencingEntity[$vpReference]) !== false) { return true; } } } elseif (isset($otherEntityValueReferences[$reference])) { // Value reference list($sourceColumn, $sourceValue, $valueColumn) = array_values(ReferenceUtils::getValueReferenceDetails($reference)); foreach ($possiblyReferencingEntities as $possiblyReferencingEntity) { if (isset($possiblyReferencingEntity[$sourceColumn]) && $possiblyReferencingEntity[$sourceColumn] == $sourceValue && isset($possiblyReferencingEntity[$valueColumn]) && $possiblyReferencingEntity[$valueColumn] === $entityId) { return true; } } } } return false; }
private function lockDatabase() { return; // disabled for testing /** @noinspection PhpUnreachableStatementInspection */ $entityNames = $this->dbSchema->getAllEntityNames(); $dbSchema = $this->dbSchema; $tableNames = array_map(function ($entityName) use($dbSchema) { return "`{$dbSchema->getPrefixedTableName($entityName)}`"; }, $entityNames); $lockQueries = []; $lockQueries[] = "FLUSH TABLES " . join(",", $tableNames) . " WITH READ LOCK;"; $lockQueries[] = "SET AUTOCOMMIT=0;"; $lockQueries[] = "START TRANSACTION;"; register_shutdown_function(['self', 'rollbackDatabase']); foreach ($lockQueries as $lockQuery) { $this->database->query($lockQuery); } $this->isDatabaseLocked = true; }
/** * Saves all already existing meta and M:N references for an entity that wasn't tracked yet * * @param array $data * @param string $entityName */ private function storeRelatedEntities($data, $entityName) { $id = $data[$this->dbSchemaInfo->getEntityInfo($entityName)->idColumnName]; foreach ($this->dbSchemaInfo->getAllEntityNames() as $referencedEntityName) { $entityInfo = $this->dbSchemaInfo->getEntityInfo($referencedEntityName); if ($this->dbSchemaInfo->isChildEntity($referencedEntityName) && $entityInfo->references[$entityInfo->parentReference] === $entityName) { $childEntities = $this->database->get_results("SELECT * FROM {$this->dbSchemaInfo->getPrefixedTableName($referencedEntityName)} WHERE `{$entityInfo->parentReference}` = '{$id}'", ARRAY_A); foreach ($childEntities as $childEntity) { $childEntity = $this->vpidRepository->replaceForeignKeysWithReferences($referencedEntityName, $childEntity); if (!$this->mirror->shouldBeSaved($referencedEntityName, $childEntity)) { continue; } $id = $childEntity[$entityInfo->idColumnName]; $vpid = $this->vpidRepository->getVpidForEntity($referencedEntityName, $id); if ($vpid) { $childEntity[$entityInfo->vpidColumnName] = $vpid; } else { $childEntity = $this->vpidRepository->identifyEntity($referencedEntityName, $childEntity, $childEntity[$entityInfo->idColumnName]); } $childEntity = $this->shortcodesReplacer->replaceShortcodesInEntity($referencedEntityName, $childEntity); $this->mirror->save($referencedEntityName, $childEntity); } } } foreach ($this->dbSchemaInfo->getAllMnReferences() as $mnReferenceDetails) { if ($mnReferenceDetails['source-entity'] === $entityName) { $junctionTable = $mnReferenceDetails['junction-table']; $prefixedJunctionTable = $this->dbSchemaInfo->getPrefixedTableName($junctionTable); $sourceColumn = $mnReferenceDetails['source-column']; $references = $this->database->get_results("SELECT * FROM `{$prefixedJunctionTable}` WHERE `{$sourceColumn}` = '{$id}'", ARRAY_A); foreach ($references as $reference) { $reference = $this->vpidRepository->replaceForeignKeysWithReferences($junctionTable, $reference); $this->mirror->save($junctionTable, $reference); } } } }
/** * Returns true if there is any entity with reference to the passed one. * * @param $entityName * @param $entityId * @return bool */ private function existsSomeEntityWithReferenceTo($entityName, $entityId) { $entityNames = $this->dbSchemaInfo->getAllEntityNames(); foreach ($entityNames as $otherEntityName) { $otherEntityInfo = $this->dbSchemaInfo->getEntityInfo($otherEntityName); $otherEntityReferences = $otherEntityInfo->references; $otherEntityMnReferences = $otherEntityInfo->mnReferences; $otherEntityValueReferences = $otherEntityInfo->valueReferences; $allReferences = array_merge($otherEntityReferences, $otherEntityMnReferences, $otherEntityValueReferences); foreach ($allReferences as $reference => $referencedEntity) { // if the target is dynamic, check it anyway - just to be sure if ($referencedEntity !== $entityName && $referencedEntity[0] !== '@') { continue; } $otherEntityStorage = $this->storageFactory->getStorage($otherEntityName); $possiblyReferencingEntities = $otherEntityStorage->loadAll(); if (isset($otherEntityReferences[$reference])) { // 1:N reference $vpReference = "vp_{$reference}"; foreach ($possiblyReferencingEntities as $possiblyReferencingEntity) { if (isset($possiblyReferencingEntity[$vpReference])) { $referencedVpidsString = $possiblyReferencingEntity[$vpReference]; preg_match_all(IdUtil::getRegexMatchingId(), $referencedVpidsString, $matches); if (ArrayUtils::any($matches[0], Comparators::equals($entityId))) { return true; } } } } elseif (isset($otherEntityMnReferences[$reference])) { // M:N reference $vpReference = "vp_{$otherEntityName}"; foreach ($possiblyReferencingEntities as $possiblyReferencingEntity) { if (isset($possiblyReferencingEntity[$vpReference]) && array_search($entityId, $possiblyReferencingEntity[$vpReference]) !== false) { return true; } } } elseif (isset($otherEntityValueReferences[$reference])) { // Value reference list($sourceColumn, $sourceValue, $valueColumn, $pathInStructure) = array_values(ReferenceUtils::getValueReferenceDetails($reference)); foreach ($possiblyReferencingEntities as $possiblyReferencingEntity) { if (isset($possiblyReferencingEntity[$sourceColumn]) && ($possiblyReferencingEntity[$sourceColumn] === $sourceValue || ReferenceUtils::valueMatchesWildcard($sourceValue, $possiblyReferencingEntity[$sourceColumn])) && isset($possiblyReferencingEntity[$valueColumn])) { if (is_numeric($possiblyReferencingEntity[$valueColumn]) && intval($possiblyReferencingEntity[$valueColumn]) === 0 || $possiblyReferencingEntity[$valueColumn] === '') { continue; } if ($pathInStructure) { $possiblyReferencingEntity[$valueColumn] = unserialize($possiblyReferencingEntity[$valueColumn]); $paths = ReferenceUtils::getMatchingPaths($possiblyReferencingEntity[$valueColumn], $pathInStructure); } else { $paths = [[]]; // root = the value itself } /** @var Cursor[] $cursors */ $cursors = array_map(function ($path) use(&$possiblyReferencingEntity, $valueColumn) { return new Cursor($possiblyReferencingEntity[$valueColumn], $path); }, $paths); foreach ($cursors as $cursor) { $vpidsString = $cursor->getValue(); preg_match_all(IdUtil::getRegexMatchingId(), $vpidsString, $matches); if (ArrayUtils::any($matches[0], Comparators::equals($entityId))) { return true; } } } } } } } return false; }
private function adjustSynchronizationSequenceToDbVersion() { $allSupportedEntities = $this->dbSchema->getAllEntityNames(); $this->synchronizationSequence = array_intersect($this->synchronizationSequence, $allSupportedEntities); }
function vp_update_table_ddl_scripts(DbSchemaInfo $dbSchemaInfo, TableSchemaStorage $tableSchemaStorage) { $tableSchemaStorage->deleteAll(); $entityNames = $dbSchemaInfo->getAllEntityNames(); foreach ($entityNames as $entityName) { $table = $dbSchemaInfo->getPrefixedTableName($entityName); $tableSchemaStorage->saveSchema($table); } $referenceDetails = $dbSchemaInfo->getAllMnReferences(); foreach ($referenceDetails as $referenceDetail) { $table = $dbSchemaInfo->getPrefixedTableName($referenceDetail['junction-table']); $tableSchemaStorage->saveSchema($table); } }