Skip to content

Commit

Permalink
composer
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsuh committed Mar 23, 2017
1 parent 49cc461 commit 22fdf6e
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/vendor/
/.idea
18 changes: 18 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "mrsuh/mongo-odm",
"description": "mongo odm",
"type": "library",
"require": {
"mongodb/mongodb": "^1.1"
},
"autoload": {
"psr-4": { "ODM\\": "src/" }
},
"license": "MIT",
"authors": [
{
"name": "Sukhachev Anton",
"email": "mrsuh6@gmail.com"
}
]
}
51 changes: 51 additions & 0 deletions src/DBAL.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace ODM;

use MongoDB\Client;

class DBAL
{
private $db;

public function __construct($host, $port, $db_name)
{
$this->db = (new Client("mongodb://$host:$port"))->$db_name;
}

public function insert($table_name, array $data)
{
return $this->db->$table_name->insertOne($data);
}

public function insertMany($table_name, array $data)
{
return $this->db->$table_name->insertMany($data);
}

public function update($table_name, array $filter, array $data)
{
return $this->db->$table_name->updateOne($filter, ['$set' => $data]);
}

public function delete($table_name, array $filter)
{
return $this->db->$table_name->deleteOne($filter);
}

public function find($table_name, array $filter, array $options = [])
{
return $this->db->$table_name->find($filter, $options);
}

public function findOne($table_name, array $filter, array $options = [])
{
return $this->db->$table_name->findOne($filter, $options);
}

public function drop($table_name)
{
return $this->db->$table_name->drop();
}
}

8 changes: 8 additions & 0 deletions src/Document/Document.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace ODM\Document;

class Document
{

}
151 changes: 151 additions & 0 deletions src/DocumentMapper/DataMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

namespace ODM\DocumentMapper;

use ODM\DBAL;
use ODM\Document\Document;

class DataMapper
{
private $dbal;

private $table_name;
private $class;

const MONGO_ID = '_id';
const ID = 'id';

public function __construct(DBAL $dbal, $class)
{
$this->dbal = $dbal;
$this->class = $class;
$path = explode('\\', $class);
$this->table_name = mb_strtolower($this->camelCaseToSnake(array_pop($path)));
}

public function insert(Document $obj)
{
$data = $this->objToArray($obj);

if (array_key_exists(self::MONGO_ID, $data) && empty($data[self::MONGO_ID])) {
unset($data[self::MONGO_ID]);
}

$result = $this->dbal->insert($this->table_name, $data);

return $obj->setId($result->getInsertedId());
}

public function update(Document $obj)
{
$data = $this->objToArray($obj);
unset($data[self::MONGO_ID]);

$this->dbal->update($this->table_name, [self::MONGO_ID => $obj->getId()], $data);

return $obj;
}

public function delete(Document $obj)
{
return $this->dbal->delete($this->table_name, [self::MONGO_ID => $obj->getId()]);
}

public function drop()
{
return $this->dbal->drop($this->table_name);
}

public function find(array $filter = [], array $options = [])
{
if (array_key_exists(self::ID, $filter)) {
$filter[self::MONGO_ID] = $filter[self::ID];
unset($filter[self::ID]);
}

$result = [];
foreach ($this->dbal->find($this->table_name, $filter, $options) as $r) {
$result[] = $this->mapObj(new $this->class, $r);
}

return $result;
}

public function findOne(array $filter = [], array $options = [])
{
if (array_key_exists(self::ID, $filter)) {
$filter[self::MONGO_ID] = $filter[self::ID];
unset($filter[self::ID]);
}

$data = $this->dbal->findOne($this->table_name, $filter, $options);

return empty($data) ? null : $this->mapObj(new $this->class, $data);
}

private function mapObj($obj, $data)
{
$methods = get_class_methods(get_class($obj));

foreach ((array)$data as $field => $value) {

$field_name = self::MONGO_ID === (string)$field ? self::ID : $field;
$value = self::MONGO_ID === (string)$field ? (string)$value : $value;
$value = is_object($value) ? (array)$value : $value;

if (null === $value) {
continue;
}

$setter = 'set' . $this->snakeToCamelCase($field_name);

if (!in_array($setter, $methods)) {
continue;
}

$obj->$setter($value);
}

return $obj;
}

private function snakeToCamelCase($input)
{
$new = [];
foreach (explode('_', $input) as $key => $word) {
$new[] = ucfirst($word);
}

return implode('', $new);
}

private function camelCaseToSnake($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$res = $matches[0];
foreach ($res as &$match) {
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
}

return implode('_', $res);
}

public function objToArray($obj)
{
$data = [];
$reflect = new \ReflectionClass($obj);
foreach ($reflect->getProperties() as $prop) {
$getter = 'get' . $this->snakeToCamelCase($prop->getName());

if ($prop->getName() === self::ID) {
$prop_name = self::MONGO_ID;
} else {
$prop_name = $prop->getName();
}

$data[$prop_name] = $obj->$getter();
}

return $data;
}
}
20 changes: 20 additions & 0 deletions src/DocumentMapper/DataMapperFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace ODM\DocumentMapper;

use ODM\DBAL;

class DataMapperFactory
{
private $dbal;

public function __construct(DBAL $dbal)
{
$this->dbal = $dbal;
}

public function init($class)
{
return new DataMapper($this->dbal, $class);
}
}

0 comments on commit 22fdf6e

Please sign in to comment.