Beispiel #1
0
	/**
	 * Called internally by the save() method for new records.
	 */
	protected function _saveNew($defer = false) {
		$i = self::GetIndexes();
		$s = self::GetSchema();
		$n = $this->_getTableName();

		if (!isset($i['primary'])) $i['primary'] = []; // No primary schema defined... just don't make the in_array bail out.

		if($defer){
			$inserts = []; // key => value map for this model
			if(!isset(self::$_DeferInserts[$n])){
				$dat = new Core\Datamodel\Dataset();
				$dat->table($n);
				$dat->_mode = \Core\Datamodel\Dataset::MODE_BULK_INSERT;
				self::$_DeferInserts[$n] = [
					'dataset' => $dat,
					'interface' => $this->interface,
				];
			}
			else{
				$dat = self::$_DeferInserts[$n]['dataset'];
			}
		}
		else{
			$dat = new Core\Datamodel\Dataset();
			$dat->table($n);
		}

		$idcol = false;
		
		foreach($this->_columns as $c){
			/** @var \Core\Datamodel\Columns\SchemaColumn $c */
			if($c->type == Model::ATT_TYPE_UUID){
				if($c->value && $c->valueDB){
					// Yay, a UUID is already set, no need to really do much.
					// It's already set and this will most likely be ignored, but may not be for UPDATE statements...
					// although there shouldn't be any update statements here.... but ya never know
					if($defer){
						$inserts[$c->field] = $c->getInsertValue();
					}
					else{
						$dat->setID($c->field, $c->getInsertValue());
					}
				}
				else{
					// a UUID is already set, but it doesn't exist yet still.
					// This means that the UUID was set externally even though the record is new.
					// THIS IS ALLOWED!
					// Insert it as typical key.
					// Addtionally if this is a new key, the column will automatically generate a UUID as necessary.
					if($defer){
						$inserts[$c->field] = $c->getInsertValue();
					}
					else{
						$dat->insert($c->field, $c->getInsertValue());
						$dat->setID($c->field, $c->getInsertValue());
					}
				}
				// Remember this for after the save.
				$idcol = $c->field;
			}
			elseif($c->type == Model::ATT_TYPE_ID){
				if($c->value){
					// An ID is already set on this key, even though it's an auto-increment ID.
					// Allow this as you may be syncing a model from another system and want their IDs to match up.
					// NOTE, this can be a dangerous operation.
					if($defer){
						$inserts[$c->field] = $c->getInsertValue();
					}
					else{
						$dat->insert($c->field, $c->getInsertValue());
					}
				}
				if(!$defer){
					$dat->setID($c->field, $c->getInsertValue());
					// Remember this for after the save.
					$idcol = $c->field;
				}
			}
			else{
				if($defer){
					$inserts[$c->field] = $c->getInsertValue();
				}
				else{
					$dat->insert($c->field, $c->getInsertValue());
				}
			}
		}
//var_dump($dat); die();
		if($defer) {
			$dat->_sets[] = $inserts;
		}
		else{
			$dat->execute($this->interface);
			if ($idcol){
				$this->_columns[$idcol]->setValueFromDB($dat->getID());
			}
		}
	}
	/**
	 * Internal function to parse and handle the dataset in the <upgrade> and <install> tasks.
	 * This is used for installations and upgrades.
	 *
	 * Unlike the other parse functions, this handles a single node at a time.
	 *
	 * @param $node DOMElement
	 * @param $verbose bool
	 *
	 * @throws InstallerException
	 */
	private function _parseDatasetNode(DOMElement $node, $verbose = false){
		$action   = $node->getAttribute('action');
		$table    = $node->getAttribute('table');
		$haswhere = false;
		$sets     = array();
		$renames  = array();
		$ds       = new Core\Datamodel\Dataset();


		$ds->table($table);

		foreach($node->getElementsByTagName('datasetset') as $el){
			$sets[$el->getAttribute('key')] = $el->nodeValue;
		}

		foreach($node->getElementsByTagName('datasetrenamecolumn') as $el){
			// <datasetrenamecolumn oldname="ID" newname="id"/>
			$renames[$el->getAttribute('oldname')] = $el->getAttribute('newname');
		}

		foreach($node->getElementsByTagName('datasetwhere') as $el){
			$haswhere = true;
			$ds->where(trim($el->nodeValue));
		}

		switch($action){
			case 'alter':
				if(sizeof($sets)) throw new InstallerException('Invalid mix of arguments on ' . $action . ' dataset request, datasetset is not supported!');
				if($haswhere) throw new InstallerException('Invalid mix of arguments on ' . $action . ' dataset request, datasetwhere is not supported!');

				foreach($renames as $k => $v){
					// ALTER TABLE `controllers` CHANGE `ID` `id` INT( 11 ) NOT NULL AUTO_INCREMENT
					$ds->renameColumn($k, $v);
				}
				break;
			case 'update':
				foreach($sets as $k => $v){
					$ds->update($k, $v);
				}
				break;
			case 'insert':
				foreach($sets as $k => $v){
					$ds->insert($k, $v);
				}
				break;
			case 'delete':
				if(sizeof($sets)) throw new InstallerException('Invalid mix of arguments on ' . $action . ' dataset request');
				if(!$haswhere) throw new InstallerException('Cowardly refusing to delete with no where statement');
				$ds->delete();
				break;
			default:
				throw new InstallerException('Invalid action type, '. $action);
		}

		// and GO!
		if($verbose){
			CLI::PrintActionStart('Executing dataset ' . $action . ' command on ' . $table);
		}

		$ds->execute();
		if($ds->num_rows){
			CLI::PrintActionStatus(true);
			return array($action . ' on table ' . $table . ' affected ' . $ds->num_rows . ' records.');
		}
		else{
			CLI::PrintActionStatus(false);
			return false;
		}
	}