function __construct($queryset = false) { $this->queryset = $queryset; if ($queryset) { $this->stmt = $queryset->getQuery(); $connection = Manager::getConnection($this->model); } }
function save($refetch = false) { if ($this->__deleted__) { throw new OrmException('Trying to update a deleted object'); } $pk = static::getMeta('pk'); $wasnew = $this->__new__; // First, if any foreign properties of this object are connected to // another *new* object, then save those objects first and set the // local foreign key field values foreach (static::getMeta('joins') as $prop => $j) { if (isset($this->ht[$prop]) && ($foreign = $this->ht[$prop]) && $foreign instanceof VerySimpleModel && !in_array($j['local'], $pk) && null === $this->get($j['local'])) { if ($foreign->__new__ && !$foreign->save()) { return false; } $this->set($j['local'], $foreign->get($j['fkey'][1])); } } // If there's nothing in the model to be saved, then we're done if (count($this->__dirty__) === 0) { return true; } $ex = Manager::save($this); try { $ex->execute(); if ($ex->affected_rows() != 1) { // This doesn't really signify an error. It just means that // the database believes that the row did not change. For // inserts though, it's a deal breaker if ($this->__new__) { return false; } else { // No need to reload the record if requested — the // database didn't update anything $refetch = false; } } } catch (Exception\OrmError $e) { return false; } if ($wasnew) { // XXX: Ensure AUTO_INCREMENT is set for the field if (count($pk) == 1 && !$refetch) { $key = $pk[0]; $id = $ex->insert_id(); if (!isset($this->{$key}) && $id) { $this->__ht__[$key] = $id; } } $this->__new__ = false; Signal::send('model.created', $this); } else { $data = array('dirty' => $this->__dirty__); Signal::send('model.updated', $this, $data); } # Refetch row from database if ($refetch) { // Preserve non database information such as list relationships // across the refetch $this->__ht__ = static::objects()->filter($this->getPk())->values()->one() + $this->__ht__; // TODO: Cache $this object } if ($wasnew) { // Attempt to update foreign, unsaved objects with the PK of // this newly created object foreach (static::getMeta('joins') as $prop => $j) { if (isset($this->ht[$prop]) && ($foreign = $this->ht[$prop]) && in_array($j['local'], $pk)) { if ($foreign instanceof VerySimpleModel && null === $foreign->get($j['fkey'][1])) { $foreign->set($j['fkey'][1], $this->get($j['local'])); } elseif ($foreign instanceof InstrumentedList) { foreach ($foreign as $item) { if (null === $item->get($j['fkey'][1])) { $item->set($j['fkey'][1], $this->get($j['local'])); } } } } } $this->__onsave(); } $this->__dirty__ = array(); return true; }
function startup() { foreach ($this->getSettings()->get('DATABASES') as $name => $info) { Db\Manager::addConnection($info, $name); } }
function getQuery($options = array()) { if (isset($this->query)) { return $this->query; } // Load defaults from model $model = $this->model; $model::_inspect(); $query = clone $this; $options += $this->options; // Be careful not to make local modifications based on model meta // compilation preferences if ($options['nosort']) { $query->ordering = array(); } elseif (!$query->ordering && $model::getMeta('ordering')) { $query->ordering = $model::$meta['ordering']; } if (false !== $query->related && !$query->values && $model::getMeta('select_related')) { $query->related = $model::getMeta('select_related'); } if (!$query->defer && $model::getMeta('defer')) { $query->defer = $model::getMeta('defer'); } $class = $options['compiler'] ?: $this->compiler; $connection = Manager::getConnection($model); $compiler = $connection->getCompiler(); return $this->query = $compiler->compileSelect($query); }
function inspectFields() { $connection = Manager::getConnection($this); $compiler = $connection->getCompiler(); return $compiler->inspectTable($this['table']); // TODO: Support caching the fields }