/** * @param Table $compare * @param bool|false $standAlone * @return float|int */ protected function getPrimarySimilarityPercentage(Table $compare, $standAlone = false) { //nothing to compare, in terms of similarity they're identical if (!$this->hasPrimary() && $compare->hasPrimary()) { $similarity = 100; if ($standAlone === false) { //but let's not count that as a full match when this percentage //is used to determine the overall similarity percentage $similarity = 80; } return $similarity; } if (!$this->hasPrimary() && $compare->hasPrimary()) { //it is possible the primary key needs to be added, check for missing field: $similarity = 0; foreach ($compare->primary->getFieldNames() as $fieldName) { $similarity += $this->hasField($fieldName); } if ($similarity === count($compare->primary->getFieldNames())) { //all primary fields exist: 50/50 chance the primary needs to be added $similarity = 50; } else { //not all fields exist, but count those that do as a 10% similarity $similarity *= 10; } return $similarity; } elseif ($this->primary && !$compare->hasPrimary()) { //this table has a primary, but the target one doesn't... how likely is it to //DROP PRIMARY KEY without creating a new one? not very -> return that 1/1000 chance? return 0.1; } //both have PK's defined: $itemsCompared = 0; $similarity = (int) (count($this->primary->getFieldNames()) === count($compare->primary->getFieldNames())); ++$itemsCompared; $compareFields = $compare->primary->getFieldNames(); foreach ($this->primary->getFieldNames() as $fieldName) { //does the PK contain the same key? $similarity += in_array($fieldName, $compareFields); //does the field exist? $similarity += $compare->hasField($fieldName); $itemsCompared += 2; } $ownFields = $this->primary->getFieldNames(); foreach ($compareFields as $fieldName) { $similarity += in_array($fieldName, $ownFields); $similarity += $this->hasField($fieldName); $itemsCompared += 2; } if ($this->primary->isEqual($compare->primary)) { //if equality matches, vastly increase the chance of a 100% similarity being returned $similarity += $itemsCompared; } //give the isEqual call above the proper impact, and avoid returning values > 100% //by doubling the factor $itemsCompared *= 2; return round($similarity / $itemsCompared * 100, 2); }