Record_adapter now uses a specific repository from databox

This commit is contained in:
Benoît Burnichon
2015-07-15 11:26:13 +02:00
parent fd530d8795
commit e8d4d5f38d
9 changed files with 284 additions and 166 deletions

View File

@@ -33,9 +33,7 @@ class Sha256 extends AbstractChecker
*/ */
public function check(EntityManager $em, File $file) public function check(EntityManager $em, File $file)
{ {
$boolean = ! count(\record_adapter::get_record_by_sha( $boolean = ! count($file->getCollection()->get_databox()->getRecordRepository()->findBySha256($file->getSha256()));
$this->app, $file->getCollection()->get_databox()->get_sbas_id(), $file->getSha256()
));
return new Response($boolean, $this); return new Response($boolean, $this);
} }

View File

@@ -32,9 +32,7 @@ class UUID extends AbstractChecker
*/ */
public function check(EntityManager $em, File $file) public function check(EntityManager $em, File $file)
{ {
$boolean = ! count(\record_adapter::get_record_by_uuid( $boolean = ! count($file->getCollection()->get_databox()->getRecordRepository()->findByUuid($file->getUUID()));
$this->app, $file->getCollection()->get_databox(), $file->getUUID()
));
return new Response($boolean, $this); return new Response($boolean, $this);
} }

View File

@@ -17,6 +17,7 @@ use Alchemy\Phrasea\Databox\DataboxFactory;
use Alchemy\Phrasea\Databox\DbalDataboxRepository; use Alchemy\Phrasea\Databox\DbalDataboxRepository;
use Alchemy\Phrasea\Databox\Field\DataboxFieldFactory; use Alchemy\Phrasea\Databox\Field\DataboxFieldFactory;
use Alchemy\Phrasea\Databox\Field\DbalDataboxFieldRepository; use Alchemy\Phrasea\Databox\Field\DbalDataboxFieldRepository;
use Alchemy\Phrasea\Databox\Record\LegacyRecordRepository;
use Silex\Application; use Silex\Application;
use Silex\ServiceProviderInterface; use Silex\ServiceProviderInterface;
@@ -24,6 +25,10 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
{ {
public function register(Application $app) public function register(Application $app)
{ {
if (!$app instanceof PhraseaApplication) {
throw new \LogicException('Expects $app to be an instance of Phraseanet application');
}
$app['repo.users'] = $app->share(function (PhraseaApplication $app) { $app['repo.users'] = $app->share(function (PhraseaApplication $app) {
return $app['orm.em']->getRepository('Phraseanet:User'); return $app['orm.em']->getRepository('Phraseanet:User');
}); });
@@ -138,6 +143,10 @@ class RepositoriesServiceProvider implements ServiceProviderInterface
$app['repo.fields.factory'] = $app->protect(function (\databox $databox) use ($app) { $app['repo.fields.factory'] = $app->protect(function (\databox $databox) use ($app) {
return new DbalDataboxFieldRepository($databox->get_connection(), new DataboxFieldFactory($app, $databox)); return new DbalDataboxFieldRepository($databox->get_connection(), new DataboxFieldFactory($app, $databox));
}); });
$app['repo.records.factory'] = $app->protect(function (\databox $databox) use ($app) {
return new LegacyRecordRepository($app, $databox);
});
} }
public function boot(Application $app) public function boot(Application $app)

View File

@@ -0,0 +1,146 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2015 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Databox\Record;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Cache\Exception;
class LegacyRecordRepository implements RecordRepository
{
/** @var Application */
private $app;
/** @var \databox */
private $databox;
public function __construct(Application $app, \databox $databox)
{
$this->app = $app;
$this->databox = $databox;
}
/**
* @param mixed $record_id
* @return \record_adapter|null
*/
public function find($record_id)
{
$record = new \record_adapter($this->app, $this->databox->get_sbas_id(), $record_id, null, false);
try {
$data = $record->get_data_from_cache();
} catch (Exception $exception) {
$data = false;
}
if (false === $data) {
static $sql;
if (!$sql) {
$sql = $this->createSelectBuilder()->where('record_id = :record_id')->getSQL();
}
$data = $this->databox->get_connection()->fetchAssoc($sql, ['record_id' => $record_id]);
}
if (false === $data) {
return null;
}
return $this->mapRecordFromResultRow($data, $record);
}
/**
* @param string $sha256
* @return \record_adapter[]
*/
public function findBySha256($sha256)
{
static $sql;
if (!$sql) {
$sql = $this->createSelectBuilder()->where('sha256 = :sha256')->getSQL();
}
$result = $this->databox->get_connection()->fetchAll($sql, ['sha256' => $sha256]);
return $this->mapRecordsFromResultSet($result);
}
/**
* @param string $uuid
* @return \record_adapter[]
*/
public function findByUuid($uuid)
{
static $sql;
if (!$sql) {
$sql = $this->createSelectBuilder()->where('uuid = :uuid')->getSQL();
}
$result = $this->databox->get_connection()->fetchAll($sql, ['uuid' => $uuid]);
return $this->mapRecordsFromResultSet($result);
}
/**
* @return \Doctrine\DBAL\Query\QueryBuilder
*/
private function createSelectBuilder()
{
$connection = $this->databox->get_connection();
return $connection->createQueryBuilder()
->select(
'coll_id AS collection_id',
'record_id',
'credate AS created',
'uuid',
'moddate AS updated',
'parent_record_id AS isStory',
$connection->quoteIdentifier('type'),
'originalname AS originalName',
'sha256',
'mime'
)
->from('record', 'r');
}
/**
* @param array $result
* @return \record_adapter[]
*/
private function mapRecordsFromResultSet(array $result)
{
$records = [];
foreach ($result as $row) {
$records[] = $this->mapRecordFromResultRow($row);
}
return $records;
}
/**
* @param array $row
* @param \record_adapter|null $record
* @return \record_adapter
*/
private function mapRecordFromResultRow(array $row, \record_adapter $record = null)
{
if (null === $record) {
$record = new \record_adapter($this->app, $this->databox->get_sbas_id(), $row['record_id'], null, false);
}
$record->mapFromData($row);
$record->putInCache();
return $record;
}
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2015 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Databox\Record;
interface RecordRepository
{
/**
* @param mixed $record_id
* @return \record_adapter|null
*/
public function find($record_id);
/**
* @param string $sha256
* @return \record_adapter[]
*/
public function findBySha256($sha256);
/**
* @param string $uuid
* @return \record_adapter[]
*/
public function findByUuid($uuid);
}

View File

@@ -427,13 +427,9 @@ class LazaretFile
{ {
$ret = []; $ret = [];
$shaRecords = \record_adapter::get_record_by_sha( $repository = $this->getCollection($app)->get_databox()->getRecordRepository();
$app, $this->getCollection($app)->get_sbas_id(), $this->getSha256() $shaRecords = $repository->findBySha256($this->getSha256());
); $uuidRecords = $repository->findByUuid($this->getUuid());
$uuidRecords = \record_adapter::get_record_by_uuid(
$app, $this->getCollection($app)->get_databox(), $this->getUuid()
);
$merged = array_merge($uuidRecords, $shaRecords); $merged = array_merge($uuidRecords, $shaRecords);

View File

@@ -14,6 +14,7 @@ use Alchemy\Phrasea\Core\Connection\ConnectionSettings;
use Alchemy\Phrasea\Core\PhraseaTokens; use Alchemy\Phrasea\Core\PhraseaTokens;
use Alchemy\Phrasea\Core\Thumbnail\ThumbnailedElement; use Alchemy\Phrasea\Core\Thumbnail\ThumbnailedElement;
use Alchemy\Phrasea\Core\Version\DataboxVersionRepository; use Alchemy\Phrasea\Core\Version\DataboxVersionRepository;
use Alchemy\Phrasea\Databox\Record\RecordRepository;
use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Status\StatusStructure; use Alchemy\Phrasea\Status\StatusStructure;
@@ -61,6 +62,8 @@ class databox extends base implements ThumbnailedElement
/** @var databox_subdefsStructure */ /** @var databox_subdefsStructure */
protected $subdef_struct; protected $subdef_struct;
/** @var RecordRepository */
private $recordRepository;
/** @var string[] */ /** @var string[] */
private $labels = []; private $labels = [];
private $ord; private $ord;
@@ -102,6 +105,18 @@ class databox extends base implements ThumbnailedElement
$this->loadFromRow($row); $this->loadFromRow($row);
} }
/**
* @return RecordRepository
*/
public function getRecordRepository()
{
if (null === $this->recordRepository) {
$this->recordRepository = $this->app['repo.records.factory']($this);
}
return $this->recordRepository;
}
public function get_viewname() public function get_viewname()
{ {
return $this->viewname ? : $this->connectionSettings->getDatabaseName(); return $this->viewname ? : $this->connectionSettings->getDatabaseName();

View File

@@ -98,17 +98,28 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
protected function load() protected function load()
{ {
if ($this->mapFromCache()) { if (null === $record = $this->getDatabox()->getRecordRepository()->find($this->record_id)) {
return;
}
$row = $this->fetchDataFromDb();
if (!$row) {
throw new Exception_Record_AdapterNotFound('Record ' . $this->record_id . ' on database ' . $this->get_sbas_id() . ' not found '); throw new Exception_Record_AdapterNotFound('Record ' . $this->record_id . ' on database ' . $this->get_sbas_id() . ' not found ');
} }
$this->mapFromDbData($row); $this->mirror($record);
$this->putInCache(); }
/**
* @param record_adapter $record
*/
private function mirror(record_adapter $record)
{
$this->mime = $record->getMimeType();
$this->sha256 = $record->getSha256();
$this->original_name = $record->getOriginalName();
$this->type = $record->getType();
$this->isStory = $record->isStory();
$this->uuid = $record->getUuid();
$this->updated = $record->getUpdated();
$this->created = $record->getCreated();
$this->base_id = $record->getBaseId();
$this->collection_id = $record->getCollectionId();
} }
/** /**
@@ -266,7 +277,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/** /**
* @return string * @return string
* @deprecated use {@link getMimeType} instead. * @deprecated use {@link self::getMimeType} instead.
*/ */
public function get_mime() public function get_mime()
{ {
@@ -465,8 +476,14 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/** /**
* @return string * @return string
* @deprecated use {self::getSha256} instead.
*/ */
public function get_sha256() public function get_sha256()
{
return $this->getSha256();
}
public function getSha256()
{ {
return $this->sha256; return $this->sha256;
} }
@@ -867,8 +884,8 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
} }
/** /**
*
* @return int * @return int
* @deprecated use {@link self::getDatabox} instead
*/ */
public function get_sbas_id() public function get_sbas_id()
{ {
@@ -1335,38 +1352,20 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
} }
/** /**
* @param Application $app * @param databox $databox
* @param integer $sbas_id * @param string $sha256
* @param string $sha256 * @param integer $record_id
* @param integer $record_id * @return record_adapter[]
* @return record_adapter * @deprecated use {@link databox::getRecordRepository} instead.
*/ */
public static function get_record_by_sha(Application $app, $sbas_id, $sha256, $record_id = null) public static function get_record_by_sha(\databox $databox, $sha256, $record_id = null)
{ {
$databox = $app->findDataboxById($sbas_id); $records = $databox->getRecordRepository()->findBySha256($sha256);
$conn = $databox->get_connection();
$sql = "SELECT record_id
FROM record r
WHERE sha256 IS NOT NULL
AND sha256 = :sha256";
$params = [':sha256' => $sha256];
if (!is_null($record_id)) { if (!is_null($record_id)) {
$sql .= ' AND record_id = :record_id'; $records = array_filter($records, function (record_adapter $record) use ($record_id) {
$params[':record_id'] = $record_id; return $record->getRecordId() == $record_id;
} });
$stmt = $conn->prepare($sql);
$stmt->execute($params);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$records = [];
foreach ($rs as $row) {
$records[] = new record_adapter($app, $sbas_id, $row['record_id']);
} }
return $records; return $records;
@@ -1375,34 +1374,20 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/** /**
* Search for a record on a databox by UUID * Search for a record on a databox by UUID
* *
* @param Application $app * @param \databox $databox
* @param \databox $databox * @param string $uuid
* @param string $uuid * @param int $record_id Restrict check on a record_id
* @param int $record_id Restrict check on a record_id * @return record_adapter[]
* * @deprecated use {@link databox::getRecordRepository} instead.
* @return \record_adapter
*/ */
public static function get_record_by_uuid(Application $app, \databox $databox, $uuid, $record_id = null) public static function get_record_by_uuid(\databox $databox, $uuid, $record_id = null)
{ {
$sql = "SELECT record_id FROM record r $records = $databox->getRecordRepository()->findByUuid($uuid);
WHERE uuid IS NOT NULL AND uuid = :uuid";
$params = [':uuid' => $uuid];
if (!is_null($record_id)) { if (!is_null($record_id)) {
$sql .= ' AND record_id = :record_id'; $records = array_filter($records, function (record_adapter $record) use ($record_id) {
$params[':record_id'] = $record_id; return $record->getRecordId() == $record_id;
} });
$stmt = $databox->get_connection()->prepare($sql);
$stmt->execute($params);
$rs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$records = [];
foreach ($rs as $row) {
$records[] = new record_adapter($app, $databox->get_sbas_id(), $row['record_id']);
} }
return $records; return $records;
@@ -1857,12 +1842,6 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
$this->set_original_name($originalName); $this->set_original_name($originalName);
} }
/** {@inheritdoc} */
public function getSha256()
{
return $this->get_sha256();
}
/** {@inheritdoc} */ /** {@inheritdoc} */
public function getId() public function getId()
{ {
@@ -1893,51 +1872,19 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
return $this->databox->getStatusStructure(); return $this->databox->getStatusStructure();
} }
/** public function putInCache()
* Try to map data from cache.
*
* @return bool true when cache hit.
* false when cache miss.
*/
protected function mapFromCache()
{
try {
$data = $this->get_data_from_cache();
} catch (Exception $exception) {
$data = false;
};
if (false === $data) {
return false;
}
$this->mime = $data['mime'];
$this->sha256 = $data['sha256'];
$this->original_name = $data['original_name'];
$this->type = $data['type'];
$this->isStory = $data['grouping'];
$this->uuid = $data['uuid'];
$this->updated = $data['modification_date'];
$this->created = $data['creation_date'];
$this->base_id = $data['base_id'];
$this->collection_id = $data['collection_id'];
return true;
}
protected function putInCache()
{ {
$data = [ $data = [
'mime' => $this->mime, 'mime' => $this->mime,
'sha256' => $this->sha256, 'sha256' => $this->sha256,
'original_name' => $this->original_name, 'originalName' => $this->original_name,
'type' => $this->type, 'type' => $this->type,
'grouping' => $this->isStory, 'isStory' => $this->isStory,
'uuid' => $this->uuid, 'uuid' => $this->uuid,
'modification_date' => $this->updated, 'updated' => $this->updated->format(DATE_ISO8601),
'creation_date' => $this->created, 'created' => $this->created->format(DATE_ISO8601),
'base_id' => $this->base_id, 'base_id' => $this->base_id,
'collection_id' => $this->collection_id, 'collection_id' => $this->collection_id,
]; ];
$this->set_data_to_cache($data); $this->set_data_to_cache($data);
@@ -1946,48 +1893,23 @@ class record_adapter implements RecordInterface, cache_cacheableInterface
/** /**
* @param array $row * @param array $row
*/ */
protected function mapFromDbData(array $row) public function mapFromData(array $row)
{ {
$this->collection_id = (int)$row['coll_id']; if (!isset($row['base_id'])) {
$this->base_id = (int)phrasea::baseFromColl($this->get_sbas_id(), $this->collection_id, $this->app); $row['base_id'] = phrasea::baseFromColl($this->get_sbas_id(), $row['collection_id'], $this->app);
$this->created = new DateTime($row['credate']);
$this->updated = new DateTime($row['moddate']);
$this->uuid = $row['uuid'];
$this->isStory = ($row['parent_record_id'] == '1');
$this->type = $row['type'];
$this->original_name = $row['originalname'];
$this->sha256 = $row['sha256'];
$this->mime = $row['mime'];
}
/**
* @return false|array
*/
protected function fetchDataFromDb()
{
static $sql;
$connection = $this->databox->get_connection();
if (!$sql) {
$sql = $connection->createQueryBuilder()
->select(
'coll_id',
'record_id',
'credate',
'uuid',
'moddate',
'parent_record_id',
$connection->quoteIdentifier('type'),
'originalname',
'sha256',
'mime'
)->from('record', 'r')
->where('record_id = :record_id')
->getSQL();
} }
return $connection->fetchAssoc($sql, [':record_id' => $this->record_id]); $this->collection_id = (int)$row['collection_id'];
$this->base_id = (int)$row['base_id'];
$this->created = new DateTime($row['created']);
$this->updated = new DateTime($row['updated']);
$this->uuid = $row['uuid'];
$this->isStory = ($row['isStory'] == '1');
$this->type = $row['type'];
$this->original_name = $row['originalName'];
$this->sha256 = $row['sha256'];
$this->mime = $row['mime'];
} }
/** /**

View File

@@ -483,8 +483,7 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
public function testGet_record_by_sha() public function testGet_record_by_sha()
{ {
$record_1 = $this->getRecord1(); $record_1 = $this->getRecord1();
$app = $this->getApplication(); $tmp_records = record_adapter::get_record_by_sha($record_1->getDatabox(), $record_1->get_sha256());
$tmp_records = record_adapter::get_record_by_sha($app, $record_1->get_sbas_id(), $record_1->get_sha256());
$this->assertTrue(is_array($tmp_records)); $this->assertTrue(is_array($tmp_records));
foreach ($tmp_records as $tmp_record) { foreach ($tmp_records as $tmp_record) {
@@ -492,7 +491,11 @@ class record_adapterTest extends \PhraseanetAuthenticatedTestCase
$this->assertEquals($record_1->get_sha256(), $tmp_record->get_sha256()); $this->assertEquals($record_1->get_sha256(), $tmp_record->get_sha256());
} }
$tmp_records = record_adapter::get_record_by_sha($app, $record_1->get_sbas_id(), $record_1->get_sha256(), $record_1->get_record_id()); $tmp_records = record_adapter::get_record_by_sha(
$record_1->getDatabox(),
$record_1->get_sha256(),
$record_1->get_record_id()
);
$this->assertTrue(is_array($tmp_records)); $this->assertTrue(is_array($tmp_records));
$this->assertTrue(count($tmp_records) === 1); $this->assertTrue(count($tmp_records) === 1);