mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-08 00:47:55 +08:00
File retrieve methods added to Mongo File Active Record.
This commit is contained in:
@ -129,33 +129,13 @@ class Query extends Component implements QueryInterface
|
||||
* @throws Exception on failure.
|
||||
* @return array|boolean result.
|
||||
*/
|
||||
protected function fetchRows(\MongoCursor $cursor, $all = true, $indexBy = null)
|
||||
protected function fetchRows($cursor, $all = true, $indexBy = null)
|
||||
{
|
||||
$token = 'Querying: ' . Json::encode($cursor->info());
|
||||
Yii::info($token, __METHOD__);
|
||||
try {
|
||||
Yii::beginProfile($token, __METHOD__);
|
||||
$result = [];
|
||||
if ($all) {
|
||||
foreach ($cursor as $row) {
|
||||
if ($indexBy !== null) {
|
||||
if (is_string($indexBy)) {
|
||||
$key = $row[$indexBy];
|
||||
} else {
|
||||
$key = call_user_func($indexBy, $row);
|
||||
}
|
||||
$result[$key] = $row;
|
||||
} else {
|
||||
$result[] = $row;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($cursor->hasNext()) {
|
||||
$result = $cursor->getNext();
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
$result = $this->fetchRowsInternal($cursor, $all, $indexBy);
|
||||
Yii::endProfile($token, __METHOD__);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
@ -164,6 +144,39 @@ class Query extends Component implements QueryInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MongoCursor $cursor Mongo cursor instance to fetch data from.
|
||||
* @param boolean $all whether to fetch all rows or only first one.
|
||||
* @param string|callable $indexBy value to index by.
|
||||
* @return array|boolean result.
|
||||
* @see Query::fetchRows()
|
||||
*/
|
||||
protected function fetchRowsInternal($cursor, $all, $indexBy)
|
||||
{
|
||||
$result = [];
|
||||
if ($all) {
|
||||
foreach ($cursor as $row) {
|
||||
if ($indexBy !== null) {
|
||||
if (is_string($indexBy)) {
|
||||
$key = $row[$indexBy];
|
||||
} else {
|
||||
$key = call_user_func($indexBy, $row);
|
||||
}
|
||||
$result[$key] = $row;
|
||||
} else {
|
||||
$result[] = $row;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($cursor->hasNext()) {
|
||||
$result = $cursor->getNext();
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the query and returns all results as an array.
|
||||
* @param Connection $db the Mongo connection used to execute the query.
|
||||
|
||||
@ -205,7 +205,7 @@ class ActiveRecord extends \yii\mongo\ActiveRecord
|
||||
/**
|
||||
* Returns the associated file content.
|
||||
* @return null|string file content.
|
||||
* @throws \yii\base\InvalidParamException on invalid file value.
|
||||
* @throws \yii\base\InvalidParamException on invalid file attribute value.
|
||||
*/
|
||||
public function getFileContent()
|
||||
{
|
||||
@ -227,6 +227,67 @@ class ActiveRecord extends \yii\mongo\ActiveRecord
|
||||
} elseif (is_string($file)) {
|
||||
if (file_exists($file)) {
|
||||
return file_get_contents($file);
|
||||
} else {
|
||||
throw new InvalidParamException("File '{$file}' does not exist.");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParamException('Unsupported type of "file" attribute.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the the internal file content into the given filename.
|
||||
* @param string $filename full filename to be written.
|
||||
* @return boolean whether the operation was successful.
|
||||
* @throws \yii\base\InvalidParamException on invalid file attribute value.
|
||||
*/
|
||||
public function writeFile($filename)
|
||||
{
|
||||
$file = $this->getAttribute('file');
|
||||
if (empty($file) && !$this->getIsNewRecord()) {
|
||||
$file = $this->refreshFile();
|
||||
}
|
||||
if (empty($file)) {
|
||||
throw new InvalidParamException('There is no file associated with this object.');
|
||||
} elseif ($file instanceof \MongoGridFSFile) {
|
||||
return ($file->write($filename) == $file->getSize());
|
||||
} elseif ($file instanceof UploadedFile) {
|
||||
return copy($file->tempName, $filename);
|
||||
} elseif (is_string($file)) {
|
||||
if (file_exists($file)) {
|
||||
return copy($file, $filename);
|
||||
} else {
|
||||
throw new InvalidParamException("File '{$file}' does not exist.");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParamException('Unsupported type of "file" attribute.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a stream resource that can be used with all file functions in PHP,
|
||||
* which deal with reading files. The contents of the file are pulled out of MongoDB on the fly,
|
||||
* so that the whole file does not have to be loaded into memory first.
|
||||
* @return resource file stream resource.
|
||||
* @throws \yii\base\InvalidParamException on invalid file attribute value.
|
||||
*/
|
||||
public function getFileResource()
|
||||
{
|
||||
$file = $this->getAttribute('file');
|
||||
if (empty($file) && !$this->getIsNewRecord()) {
|
||||
$file = $this->refreshFile();
|
||||
}
|
||||
if (empty($file)) {
|
||||
throw new InvalidParamException('There is no file associated with this object.');
|
||||
} elseif ($file instanceof \MongoGridFSFile) {
|
||||
return $file->getResource();
|
||||
} elseif ($file instanceof UploadedFile) {
|
||||
return fopen($file->tempName, 'r');
|
||||
} elseif (is_string($file)) {
|
||||
if (file_exists($file)) {
|
||||
return fopen($file, 'r');
|
||||
} else {
|
||||
throw new InvalidParamException("File '{$file}' does not exist.");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParamException('Unsupported type of "file" attribute.');
|
||||
|
||||
@ -33,50 +33,39 @@ class Query extends \yii\mongo\Query
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches rows from the given Mongo cursor.
|
||||
* @param \MongoCursor $cursor Mongo cursor instance to fetch data from.
|
||||
* @param \MongoGridFSCursor $cursor Mongo cursor instance to fetch data from.
|
||||
* @param boolean $all whether to fetch all rows or only first one.
|
||||
* @param string|callable $indexBy the column name or PHP callback,
|
||||
* by which the query results should be indexed by.
|
||||
* @throws Exception on failure.
|
||||
* @param string|callable $indexBy value to index by.
|
||||
* @return array|boolean result.
|
||||
* @see Query::fetchRows()
|
||||
*/
|
||||
protected function fetchRows(\MongoCursor $cursor, $all = true, $indexBy = null)
|
||||
protected function fetchRowsInternal($cursor, $all, $indexBy)
|
||||
{
|
||||
$token = 'Querying: ' . Json::encode($cursor->info());
|
||||
Yii::info($token, __METHOD__);
|
||||
try {
|
||||
Yii::beginProfile($token, __METHOD__);
|
||||
$result = [];
|
||||
if ($all) {
|
||||
foreach ($cursor as $file) {
|
||||
$row = $file->file;
|
||||
$row['file'] = $file;
|
||||
if ($indexBy !== null) {
|
||||
if (is_string($indexBy)) {
|
||||
$key = $row[$indexBy];
|
||||
} else {
|
||||
$key = call_user_func($indexBy, $row);
|
||||
}
|
||||
$result[$key] = $row;
|
||||
$result = [];
|
||||
if ($all) {
|
||||
foreach ($cursor as $file) {
|
||||
$row = $file->file;
|
||||
$row['file'] = $file;
|
||||
if ($indexBy !== null) {
|
||||
if (is_string($indexBy)) {
|
||||
$key = $row[$indexBy];
|
||||
} else {
|
||||
$result[] = $row;
|
||||
$key = call_user_func($indexBy, $row);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($cursor->hasNext()) {
|
||||
$file = $cursor->getNext();
|
||||
$result = $file->file;
|
||||
$result['file'] = $file;
|
||||
$result[$key] = $row;
|
||||
} else {
|
||||
$result = false;
|
||||
$result[] = $row;
|
||||
}
|
||||
}
|
||||
Yii::endProfile($token, __METHOD__);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
Yii::endProfile($token, __METHOD__);
|
||||
throw new Exception($e->getMessage(), (int)$e->getCode(), $e);
|
||||
} else {
|
||||
if ($cursor->hasNext()) {
|
||||
$file = $cursor->getNext();
|
||||
$result = $file->file;
|
||||
$result['file'] = $file;
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace yiiunit\extensions\mongo\file;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\FileHelper;
|
||||
use yiiunit\extensions\mongo\MongoTestCase;
|
||||
use yii\mongo\file\ActiveQuery;
|
||||
use yiiunit\data\ar\mongo\file\ActiveRecord;
|
||||
@ -22,14 +24,30 @@ class ActiveRecordTest extends MongoTestCase
|
||||
parent::setUp();
|
||||
ActiveRecord::$db = $this->getConnection();
|
||||
$this->setUpTestRows();
|
||||
$filePath = $this->getTestFilePath();
|
||||
if (!file_exists($filePath)) {
|
||||
FileHelper::createDirectory($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$filePath = $this->getTestFilePath();
|
||||
if (file_exists($filePath)) {
|
||||
FileHelper::removeDirectory($filePath);
|
||||
}
|
||||
$this->dropFileCollection(CustomerFile::collectionName());
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string test file path.
|
||||
*/
|
||||
protected function getTestFilePath()
|
||||
{
|
||||
return Yii::getAlias('@yiiunit/runtime') . DIRECTORY_SEPARATOR . basename(get_class($this)) . '_' . getmypid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up test rows.
|
||||
*/
|
||||
@ -256,4 +274,50 @@ class ActiveRecordTest extends MongoTestCase
|
||||
$this->assertEquals($record->status, $record2->status);
|
||||
$this->assertEquals($updateFileContent, $record2->getFileContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testInsertFileContent
|
||||
*/
|
||||
public function testWriteFile()
|
||||
{
|
||||
$record = new CustomerFile;
|
||||
$record->tag = 'new new';
|
||||
$record->status = 7;
|
||||
$newFileContent = 'Test new file content';
|
||||
$record->setAttribute('newFileContent', $newFileContent);
|
||||
$record->save();
|
||||
|
||||
$outputFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . 'out.txt';
|
||||
$this->assertTrue($record->writeFile($outputFileName));
|
||||
$this->assertEquals($newFileContent, file_get_contents($outputFileName));
|
||||
|
||||
$record2 = CustomerFile::find($record->_id);
|
||||
$outputFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . 'out_refreshed.txt';
|
||||
$this->assertTrue($record2->writeFile($outputFileName));
|
||||
$this->assertEquals($newFileContent, file_get_contents($outputFileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testInsertFileContent
|
||||
*/
|
||||
public function testGetFileResource()
|
||||
{
|
||||
$record = new CustomerFile;
|
||||
$record->tag = 'new new';
|
||||
$record->status = 7;
|
||||
$newFileContent = 'Test new file content';
|
||||
$record->setAttribute('newFileContent', $newFileContent);
|
||||
$record->save();
|
||||
|
||||
$fileResource = $record->getFileResource();
|
||||
$contents = stream_get_contents($fileResource);
|
||||
fclose($fileResource);
|
||||
$this->assertEquals($newFileContent, $contents);
|
||||
|
||||
$record2 = CustomerFile::find($record->_id);
|
||||
$fileResource = $record2->getFileResource();
|
||||
$contents = stream_get_contents($fileResource);
|
||||
fclose($fileResource);
|
||||
$this->assertEquals($newFileContent, $contents);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user