/** * 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; } }