Esempio n. 1
0
	/**
	 * 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));
	}
Esempio n. 3
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;
		}
	}
Esempio n. 4
0
	/**
	 * 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);
	}