/** * Simple method to return if two schemas are different * * @param Schema $oldSchema * @param Schema $newSchema * * @return bool */ private function _schemasDiffer(Schema $oldSchema, Schema $newSchema){ // Compare the order of the columns. // This requires more than just A == B ? // because old columns that exist in the database should be ignored if they do not appear in the new schema // AND are at the end of the table. // This is because they get shuffled to the end WITHOUT deleting them. // So if the DB version has `key1`, `key2`, `oldkey1` // and the new has `key1`, `key2`, the order should NOT trigger a different flag since the old keys are at the end. foreach($newSchema->order as $i => $name){ if(!isset($oldSchema->order[$i])){ // The old schema has fewer keys than the new schema! return true; } if($oldSchema->order[$i] != $name){ // The old schema has a different order than the new schema, // eg: column '0' on old is `oldkey1` but the new schema has `key1`. return true; } } if(!\Core\compare_values($oldSchema->indexes, $newSchema->indexes)){ \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: Indexes Different'); return true; } // The schemas require a little more work, // iterate over each and compare the resolved SQL for altering. // This is because some columns have oddities such as TEXT fields and defaults. foreach($newSchema->definitions as $c2){ /** @var SchemaColumn $c2 */ $c1 = $oldSchema->getColumn($c2->field); if($c1 === null){ // This column doesn't exist in the old schema, DIFFERENT! return true; } $c1String = $this->_getColumnString($c1); $c2String = $this->_getColumnString($c2); if($c1String != $c2String){ \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: Column ' . $c1->field . ' Different'); \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: C1 == ' . $c1String); \Core\Utilities\Logger\write_debug('MySQLi Backend::_schemasDiffer: C2 == ' . $c2String); return true; } } // Order, Index, and Defintiion checks all passed. // The columns seem to be the same. return false; }
public function testCompareValues() { // float 5.20 and float 5.20000 are the same value. $this->assertTrue(\Core\compare_values(5.20, 5.20000)); $this->assertTrue(\Core\compare_values(5.20, '5.20000')); // (string) "0" and (int) 0 are the same value. $this->assertTrue(\Core\compare_values('0', 0)); // (boolean) false and (int) 0 are not the same value. $this->assertTrue(!\Core\compare_values(false, 0)); }
/** * Get the actual differences between this schema and another column. * * Will return null if there are no differences. * * @param SchemaColumn $col * @return null|string */ public function getDiff(SchemaColumn $col){ // Do an array comparison. $thisarray = (array)$this; $colarray = (array)$col; // If the schemas-to-arrays are identical, no need to proceed. if($thisarray === $colarray) return null; // What has changed? $differences = []; if($this->field != $col->field) $differences[] = 'field name'; //if($this->required != $col->required) return false; if($this->maxlength != $col->maxlength) $differences[] = 'max length'; if($this->null != $col->null) $differences[] = 'is null'; if($this->comment != $col->comment) $differences[] = 'comment'; if($this->precision != $col->precision) $differences[] = 'precision'; if($this->autoinc !== $col->autoinc) $differences[] = 'auto increment'; if($this->encoding != $col->encoding) $differences[] = 'encoding'; // Default is a bit touchy because it can have database-specific defaults if not set locally. if($this->default === false){ // I don't care what the database is, it'll pick its own defaults. } elseif($this->default === $col->default){ // They're identical... yay! } elseif(\Core\compare_values($this->default, $col->default)){ // They're close enough.... // Core will check and see if val1 === (string)"12" and val2 === (int)12. // Consider it a fuzzy comparison that actually acknowledges the difference between NULL, "", and 0. } elseif($col->default === false && $this->default !== false){ $differences[] = 'default value (#1)'; } else{ $differences[] = 'default value (#2)'; } // If one is an array but not the other.... if(is_array($this->options) != is_array($col->options)) $differences[] = 'options set/unset'; if(is_array($this->options) && is_array($col->options)){ // If they're both arrays, I need another way to check them. if(implode(',', $this->options) != implode(',', $col->options)) $differences[] = 'options changed'; } // Type needs to allow for a few special cases. // Here, there are several columns that are all identical. $typematches = array( array( \Model::ATT_TYPE_INT, \Model::ATT_TYPE_UUID, \Model::ATT_TYPE_UUID_FK, \Model::ATT_TYPE_CREATED, \Model::ATT_TYPE_UPDATED, \Model::ATT_TYPE_DELETED, \Model::ATT_TYPE_SITE, ) ); $typesidentical = false; foreach($typematches as $types){ if(in_array($this->type, $types) && in_array($col->type, $types)){ // Found an identical pair! break out to continue; $typesidentical = true; break; } } // If the types aren't found to be identical from above, then they have to actually be identical! if(!$typesidentical && $this->type != $col->type) $differences[] = 'type'; if(sizeof($differences)){ return implode(', ', $differences); } else{ // Otherwise.... return null; } }
/** * Simple method to compare two values with each other in a more restrictive manner than == but not quite fully typecasted. * * This is useful for the scenarios that involve needing to check that "3" == 3, but "" != 0. * * @param $val1 * @param $val2 * * @deprecated 2013.09 Please use the namespaced function instead. * * @return boolean */ public static function CompareValues($val1, $val2){ return \Core\compare_values($val1, $val2); }