private function saveId($entityName, $id, $vpId) { $vpIdTableName = $this->schemaInfo->getPrefixedTableName('vp_id'); $tableName = $this->schemaInfo->getTableName($entityName); $query = "INSERT INTO {$vpIdTableName} (`vp_id`, `table`, `id`) VALUES (UNHEX('{$vpId}'), \"{$tableName}\", {$id})"; $this->database->query($query); }
/** * @param $entityName * @return mixed */ private function getEntitiesFromDatabase($entityName) { if ($this->dbSchema->isChildEntity($entityName)) { $entityInfo = $this->dbSchema->getEntityInfo($entityName); $parentReference = $entityInfo->parentReference; return $this->database->get_results("SELECT * FROM {$this->dbSchema->getPrefixedTableName($entityName)} ORDER BY {$parentReference}", ARRAY_A); } return $this->database->get_results("SELECT * FROM {$this->dbSchema->getPrefixedTableName($entityName)}", ARRAY_A); }
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; }
private function fillParentId($metaEntityName, $where, $id) { $entityInfo = $this->dbSchemaInfo->getEntityInfo($metaEntityName); $parentReference = $entityInfo->parentReference; $parent = $entityInfo->references[$parentReference]; $vpIdTable = $this->dbSchemaInfo->getPrefixedTableName('vp_id'); $entityTable = $this->dbSchemaInfo->getPrefixedTableName($metaEntityName); $parentTable = $this->dbSchemaInfo->getTableName($parent); $idColumnName = $this->dbSchemaInfo->getEntityInfo($metaEntityName)->idColumnName; $where["vp_{$parentReference}"] = $this->database->get_var("SELECT HEX(vp_id) FROM {$vpIdTable} WHERE `table` = '{$parentTable}' AND ID = (SELECT {$parentReference} FROM {$entityTable} WHERE {$idColumnName} = {$id})"); return $where; }
private function maybeRestoreReference($option) { $entityInfo = $this->dbSchema->getEntityInfo('option'); foreach ($entityInfo->valueReferences as $reference => $targetEntity) { $referenceDetails = ReferenceUtils::getValueReferenceDetails($reference); if ($option[$referenceDetails['source-column']] === $referenceDetails['source-value'] && isset($option[$referenceDetails['value-column']])) { $vpid = $option[$referenceDetails['value-column']]; $vpidTable = $this->dbSchema->getPrefixedTableName('vp_id'); $targetTable = $this->dbSchema->getTableName($targetEntity); $dbId = $this->database->get_var("SELECT id FROM {$vpidTable} WHERE `table`='{$targetTable}' AND vp_id=UNHEX('{$vpid}')"); $option[$referenceDetails['value-column']] = $dbId; } } return $option; }
/** * 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); } } } }
private function getPrefixedTableName($tableName) { return $this->dbSchema->getPrefixedTableName($tableName); }
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); } }
/** * @param $entityName */ private static function assertEntitiesEqualDatabase($entityName) { $storage = self::$storageFactory->getStorage($entityName); $entityInfo = self::$schemaInfo->getEntityInfo($entityName); $allDbEntities = self::selectAll(self::$schemaInfo->getPrefixedTableName($entityName)); $idMap = self::getVpIdMap(); $allDbEntities = self::identifyEntities($entityName, $allDbEntities, $idMap); $allDbEntities = self::replaceForeignKeys($entityName, $allDbEntities, $idMap); $dbEntities = array_filter($allDbEntities, [$storage, 'shouldBeSaved']); $urlReplacer = new AbsoluteUrlReplacer(self::$testConfig->testSite->url); $storageEntities = array_map(function ($entity) use($urlReplacer) { return $urlReplacer->restore($entity); }, $storage->loadAll()); $countOfentitiesInDb = count($dbEntities); $countOfentitiesInStorage = count($storageEntities); if ($countOfentitiesInDb !== $countOfentitiesInStorage) { if ($countOfentitiesInStorage > $countOfentitiesInDb) { $problematicEntities = self::findMissingEntities($entityName, $storageEntities, $dbEntities); } else { $problematicEntities = self::findExceedingEntities($entityName, $storageEntities, $dbEntities); } throw new \PHPUnit_Framework_AssertionFailedError("Different count of synchronized entities ({$entityName}): DB = {$countOfentitiesInDb}, " . "storage = {$countOfentitiesInStorage}\nProblematic entities: " . join(", ", $problematicEntities)); } foreach ($dbEntities as $dbEntity) { $id = $dbEntity[$entityInfo->vpidColumnName]; $storageEntity = $storageEntities[$id]; $dbEntity = self::$shortcodesReplacer->replaceShortcodesInEntity($entityName, $dbEntity); foreach ($dbEntity as $column => $value) { if ($entityInfo->idColumnName === $column || isset($entityInfo->getIgnoredColumns()[$column])) { continue; } if (!isset($storageEntity[$column])) { throw new \PHPUnit_Framework_AssertionFailedError("{$entityName}[{$column}] with value = {$value}, ID = {$id} not found in storage"); } if (is_string($storageEntity[$column])) { $storageEntity[$column] = str_replace("\r\n", "\n", $storageEntity[$column]); } if (is_string($value)) { $value = str_replace("\r\n", "\n", $value); } if ($storageEntity[$column] != $value) { throw new \PHPUnit_Framework_AssertionFailedError("Different values ({$entityName}[{$column}]: {$id}): DB = {$value}, storage = {$storageEntity[$column]}"); } } } $missingReferences = []; $exceedingReferences = []; foreach ($entityInfo->mnReferences as $reference => $targetEntity) { if ($entityInfo->isVirtualReference($reference)) { continue; } $referenceDetails = ReferenceUtils::getMnReferenceDetails(self::$schemaInfo, $entityName, $reference); $sourceColumn = $referenceDetails['source-column']; $targetColumn = $referenceDetails['target-column']; $junctionTable = $referenceDetails['junction-table']; $prefixedJunctionTable = self::$schemaInfo->getPrefixedTableName($junctionTable); $prefixedVpIdTable = self::$schemaInfo->getPrefixedTableName('vp_id'); $sourceTable = self::$schemaInfo->getTableName($referenceDetails['source-entity']); $targetTable = self::$schemaInfo->getTableName($referenceDetails['target-entity']); $junctionTableContent = self::fetchAll("SELECT HEX(s_vp_id.vp_id), HEX(t_vp_id.vp_id) FROM {$prefixedJunctionTable} j\n JOIN {$prefixedVpIdTable} s_vp_id ON j.{$sourceColumn} = s_vp_id.id AND s_vp_id.`table`='{$sourceTable}'\n JOIN {$prefixedVpIdTable} t_vp_id ON j.{$targetColumn} = t_vp_id.id AND t_vp_id.`table` = '{$targetTable}'", MYSQLI_NUM); $checkedReferences = []; $missingReferences[$junctionTable] = []; foreach ($storageEntities as $storageEntity) { if (!isset($storageEntity["vp_{$targetEntity}"])) { continue; } foreach ($storageEntity["vp_{$targetEntity}"] as $referenceVpId) { if (!ArrayUtils::any($junctionTableContent, function ($junctionRow) use($storageEntity, $referenceVpId) { return $junctionRow[0] === $storageEntity['vp_id'] && $junctionRow[1] === $referenceVpId; })) { $missingReferences[$junctionTable][] = [$sourceColumn => $storageEntity['vp_id'], $targetColumn => $referenceVpId]; } $checkedReferences[] = [$storageEntity['vp_id'], $referenceVpId]; } } $exceedingReferences[$junctionTable] = array_map(function ($pair) use($sourceColumn, $targetColumn) { return [$sourceColumn => $pair[0], $targetColumn => $pair[1]]; }, array_filter($junctionTableContent, function ($pair) use($checkedReferences) { foreach ($checkedReferences as $reference) { if ($reference[0] === $pair[0] && $reference[1] === $pair[1]) { return false; } } return true; })); } self::reportResultOfMnReferenceCheck($missingReferences, "Missing"); self::reportResultOfMnReferenceCheck($exceedingReferences, "Exceeding"); }