/** * @param $id * @return Model */ function find($id) { $primaryColumn = static::findPrimaryColumn($this->class); $rawData = $this->connection->select(['*'], [$this->table], ':' . $primaryColumn . ' = ' . $id); if (count($rawData) > 0) { $model = $this->hydrateData($rawData[0], $this->class, $this->connection, $this->app); if (in_array($model, $this->entities, true)) { $this->entities[array_search($model, $this->entities)] = $model; } else { $this->entities[] = $model; } return $model; } else { return null; } }
/** * @param array $rawData * @param string $className * @param DbConnection $connection * @param App $app * @throws \Exception * @return Model */ private function hydrateData(array $rawData, $className, DbConnection $connection, App $app) { $hydrator = new \ReflectionClass($className); $model = new $className(); $propertiesMetadata = static::getPropertiesMetadata($className); foreach ($propertiesMetadata as $property => $meta) { $p = $hydrator->getProperty($property); $p->setAccessible(true); if (isset($meta['ORM_Column'])) { if ($meta['ORM_Type'] == 'date') { $p->setValue($model, new \DateTime($rawData[$meta['ORM_Column']])); } else { $p->setValue($model, $rawData[$meta['ORM_Column']]); } } elseif (isset($meta['ORM_ManyToOne'])) { $_data = preg_split('/[\\s]*,[\\s]*/', $meta['ORM_ManyToOne']); $data = []; foreach ($_data as $param) { preg_match_all('/([\\w]+)[\\s]*=[\\s]*"(.+?)"/s', $param, $matches); $data[$matches[1][0]] = $matches[2][0]; } $mappedByValue = $rawData[$data['mappedBy']]; $data['mappedByValue'] = $mappedByValue; $data['property'] = $p->getName(); $p->setValue($model, new ManyToOneRelationModel($model, $data, $app)); } elseif (isset($meta['ORM_OneToMany'])) { $_data = preg_split('/[\\s]*,[\\s]*/', $meta['ORM_OneToMany']); $data = []; foreach ($_data as $param) { preg_match_all('/([\\w]+)[\\s]*=[\\s]*"(.+?)"/s', $param, $matches); $data[$matches[1][0]] = $matches[2][0]; } $targetClass = 'Src\\Models\\' . $data['targetClass']; $targetTable = static::getClassAnnotation($targetClass)['ORM_Table']; $inversedBy = $data['inversedBy']; $primaryColumn = static::findPrimaryColumn($className); $id = $rawData[$primaryColumn]; $rawArray = $connection->select(['*'], [$targetTable], ':' . $inversedBy . '=' . $id); $models = []; foreach ($rawArray as $row) { $models[] = $this->hydrateData($row, $targetClass, $connection, $app); } $p->setValue($model, $models); } $p->setAccessible(false); } $ep = $hydrator->getProperty('_exists'); $ep->setAccessible(true); $ep->setValue($model, true); $ep->setAccessible(false); return $model; }
<?php class DbConnection { var $cn; public $host, $username, $password; public function __construct($hostname, $username, $password){ $this->host = $hostname; $this->username = $username; $this->password = $password; } public function connectdb(){ mysql_connect($this->host, $this->username, $this->password); } public function select($database){ mysql_select_db($database); } } $obj = new DbConnection('localhost', 'root', 'root'); $obj->connectdb(); $obj->select('a2xantianxiety.com'); ?>
/** * @throws \Exception * @return Model[]|int */ public function query() { switch ($this->queryType) { case QueryBuilder::SELECT: $this->class = 'Src\\Models\\' . $this->class; $meta = static::getClassAnnotation($this->class); if (!isset($meta['ORM_Entity'])) { throw new \Exception('Class "' . $this->class . '" is not mapped with ORM.'); } $table = $meta['ORM_Table']; $rawResult = $this->conn->select(['*'], [$table], $this->whereClause, $this->post); $models = []; foreach ($rawResult as $raw) { $models[] = $this->hydrateData($raw, $this->class, $this->conn, $this->app); } return $models; break; case QueryBuilder::UPDATE: /** * @var $model Model */ $affected = 0; foreach ($this->modelsToUpdate as $model) { if (!$model->getExists()) { continue; } $class = get_class($model); $table = @static::getClassAnnotation($class)['ORM_Table']; if ($table && strlen($table) > 0) { $primaryColumn = static::findPrimaryColumn($class); $primaryProp = static::findPrimaryProperty($class); $primaryProp = new \ReflectionProperty($class, $primaryProp); $primaryProp->setAccessible(true); $primaryValue = $primaryProp->getValue($model); $primaryProp->setAccessible(false); $fields = []; $meta = static::getPropertiesMetadata($class); foreach ($meta as $property => $data) { if ($property == $primaryProp->getName()) { continue; } $p = new \ReflectionProperty($class, $property); $p->setAccessible(true); if (isset($data['ORM_Column'])) { if (!isset($data['ORM_Type'])) { throw new \Exception('ORM Type is not set.'); } if ($data['ORM_Type'] == 'numeric') { $fields[$data['ORM_Column']] = $p->getValue($model); } elseif ($data['ORM_Type'] == 'string') { $fields[$data['ORM_Column']] = '\'' . $p->getValue($model) . '\''; } else { throw new \Exception('Wrong ORM Type: "' . $data['ORM_Type'] . '"'); } } elseif (isset($data['ORM_ManyToOne'])) { $relData = static::getRelationData($class, $p->getName(), 'ORM_ManyToOne'); $targetClass = $relData['targetClass']; $mappedByColumn = $relData['mappedBy']; $targetPrimaryName = static::findPrimaryProperty($targetClass); $targetPrimaryProperty = new \ReflectionProperty($targetClass, $targetPrimaryName); $targetPrimaryProperty->setAccessible(true); $targetPrimaryValue = $targetPrimaryProperty->getValue($p->getValue($model)); $fields[$mappedByColumn] = $targetPrimaryValue; } elseif (isset($data['ORM_OneToMany'])) { // TODO: if cascade } else { throw new \Exception('ORM annotation is not found.'); } unset($p); } $affected += $this->conn->update($fields, $table, [$primaryColumn => $primaryValue]); unset($primaryProp); unset($meta); } } return $affected; break; case QueryBuilder::INSERT: /** * @var $model Model */ $affected = 0; foreach ($this->modelsToInsert as $model) { //if ($model->getExists()) continue; // TODO: Добавление всех новых одним запросом $class = get_class($model); $table = @static::getClassAnnotation($class)['ORM_Table']; if ($table && strlen($table) > 0) { $fields = []; $values = []; $values[0] = []; $meta = static::getPropertiesMetadata($class); $primaryProp = static::findPrimaryProperty($class); foreach ($meta as $property => $data) { if ($property == $primaryProp) { continue; } $p = new \ReflectionProperty($class, $property); $p->setAccessible(true); if (isset($data['ORM_Column'])) { if (!isset($data['ORM_Type'])) { throw new \Exception('ORM Type is not set.'); } if ($data['ORM_Type'] == 'numeric') { $fields[] = $data['ORM_Column']; $values[0][] = $p->getValue($model); } elseif ($data['ORM_Type'] == 'string') { $fields[] = $data['ORM_Column']; $values[0][] = '\'' . $p->getValue($model) . '\''; } else { throw new \Exception('Wrong ORM Type: "' . $data['ORM_Type'] . '"'); } } elseif (isset($data['ORM_ManyToOne'])) { $relData = static::getRelationData($class, $p->getName(), 'ORM_ManyToOne'); $targetClass = 'Src\\Models\\' . $relData['targetClass']; $mappedByColumn = $relData['mappedBy']; $targetPrimaryName = static::findPrimaryProperty($targetClass); $targetPrimaryProperty = new \ReflectionProperty($targetClass, $targetPrimaryName); $targetPrimaryProperty->setAccessible(true); $targetPrimaryValue = $targetPrimaryProperty->getValue($p->getValue($model)); $fields[] = $mappedByColumn; $values[0][] = $targetPrimaryValue; } elseif (isset($data['ORM_OneToMany'])) { // TODO: if cascade } else { throw new \Exception('ORM annotation is not found.'); } unset($p); } $affected += $this->conn->insert($table, $fields, $values); unset($meta); } } return $affected; break; case QueryBuilder::DELETE: $affected = 0; foreach ($this->modelsToDelete as $model) { if (!$model->getExists()) { continue; } $c = get_class($model); $table = @static::getClassAnnotation($c)['ORM_Table']; if ($table && strlen($table) > 0) { $primaryColumn = static::findPrimaryColumn($c); $primaryProp = static::findPrimaryProperty($c); $primaryProp = new \ReflectionProperty($c, $primaryProp); $primaryProp->setAccessible(true); $primaryValue = $primaryProp->getValue($model); $primaryProp->setAccessible(false); unset($primaryProp); $affected += $this->conn->delete($table, [$primaryColumn => $primaryValue]); } } return $affected; break; default: throw new \Exception('No query type specified.'); } }