Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* @method Results aggregate(string $function, array $wheres, array $options, array $columns)
* @method Results distinct(array $wheres, array $options, array $columns, bool $includeDocCount = false)
* @method Results find(array $wheres, array $options, array $columns)
* @method Results getDocument(string $id)
* @method Results save(array $data, string $refresh)
* @method array insertBulk(array $data, bool $returnData = false, string|null $refresh = false)
* @method Results multipleAggregate(array $functions, array $wheres, array $options, string $column)
Expand Down
51 changes: 51 additions & 0 deletions src/DSL/Bridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,35 @@ public function processSearch($searchParams, $searchOptions, $wheres, $opts, $fi
return $this->_returnSearch($params, __FUNCTION__);
}

/**
* @throws QueryException
*/
public function processGetDocument($id): Results
{
$params = [
'index' => $this->index,
'id' => $id,
];

return $this->_returnDocument($params, __FUNCTION__);
}

/**
* @throws QueryException
*/
protected function _returnDocument($params, $source): Results
{

$process = [];
try {
$process = $this->client->get($params);
} catch (Exception $e) {
$this->_throwError($e, $params, $this->_queryTag(__FUNCTION__));
}

return $this->_sanitizeGetResponse($process, $params, $this->_queryTag($source));
}

/**
* @throws QueryException
*/
Expand Down Expand Up @@ -1179,6 +1208,28 @@ private function _sanitizeSearchResponse($response, $params, $queryTag)
return $this->_return($data, $meta, $params, $queryTag);
}

private function _sanitizeGetResponse($response): Results
{

//Fake the Meta Response
$meta['took'] = 0;
$meta['timed_out'] = false;
$meta['total'] = 1;
$meta['max_score'] = 0;
$meta['shards'] = [];

$response = $response->asArray();
$data = [...$response['_source']];
$data['_index'] = $response['_index'];
$data['_id'] = $response['_id'];
$data['_meta']['_index'] = $response['_index'];
$data['_meta']['_id'] = $response['_id'];

//Hook in to the general return statement
return $this->_return([$data], $meta, [], '');

}

private function _sanitizeDistinctResponse($response, $columns, $includeDocCount): array
{
$keys = [];
Expand Down
34 changes: 34 additions & 0 deletions src/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Eloquent\Builder as BaseEloquentBuilder;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Pagination\Cursor;
use Illuminate\Pagination\CursorPaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use PDPhilip\Elasticsearch\Collection\ElasticCollection;
use PDPhilip\Elasticsearch\DSL\exceptions\QueryException;
use PDPhilip\Elasticsearch\Exceptions\DocumentFoundException;
use PDPhilip\Elasticsearch\Exceptions\MissingOrderException;
use PDPhilip\Elasticsearch\Helpers\QueriesRelationships;
use PDPhilip\Elasticsearch\Pagination\SearchAfterPaginator;
Expand Down Expand Up @@ -199,6 +202,37 @@ public function firstOrCreate(array $attributes = [], array $values = []): Model
return $this->create(array_merge($attributes, $values));
}

public function documentOrNew(string $id): Model
{
try {
$d = $this->getConnection()->getDocument($id);
//We use hydrate for the model, but we get the first result.
return $this->hydrate($d->data)->first();
} catch (QueryException $e){
// Create a new model instance but set the ID since we are looking for a specific ID here.
$newModel = $this->newModelInstance();
$newModel['_id'] = $id;
return $newModel;
}
}

/**
* @param string $id
*
* @return Model
* @throws ModelNotFoundException
*/
public function documentOrFail(string $id): Model
{
try {
$d = $this->getConnection()->getDocument($id);
//We use hydrate for the model, but we get the first result.
return $this->hydrate($d->data)->first();
} catch (\Exception $e){
throw new ModelNotFoundException($e->getMessage());
}
}

private function _instanceBuilder(array $attributes = [])
{
$instance = clone $this;
Expand Down
2 changes: 2 additions & 0 deletions src/Eloquent/Docs/ModelDocs.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
* @method static $this whereRegex(string $column, string $regex)
* @method static $this whereNestedObject(string $column, Callable $callback, string $scoreType = 'avg')
* @method static $this whereNotNestedObject(string $column, Callable $callback, string $scoreType = 'avg')
* @method static $this documentOrNew(string $id)
* @method static $this documentOrFail(string $id)
* @method static $this firstOrCreate(array $attributes, array $values = [])
* @method static $this firstOrCreateWithoutRefresh(array $attributes, array $values = [])
* @method static $this orderBy(string $column, string $direction = 'asc')
Expand Down
29 changes: 29 additions & 0 deletions tests/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,36 @@
test('Find Or Fail', function () {
$this->expectException(ModelNotFoundException::class);
Product::findOrFail('51c33d8981fec6813e00000a');
});

test('Document Or New', function () {
$product = Product::documentOrNew('51c33d8981fec6813e00000a');
expect($product->exists)->toBe(false)
->and($product['_id'])->toBe('51c33d8981fec6813e00000a');

$product['name'] = 'John Doe';
$product['description'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lacinia odio vitae vestibulum vestibulum.';
$product['in_stock'] = 35;
$product->save();

$getDocument = Product::documentOrNew('51c33d8981fec6813e00000a');
expect($getDocument->exists)->toBe(true)->and($product['_id'])->toBe('51c33d8981fec6813e00000a');
});

test('Document Or Fail', function () {
$this->expectException(ModelNotFoundException::class);
Product::documentOrFail('51c33d8981fec6813e00000a');
});

test('Document Or Fail (Found)', function () {
$product = new Product;
$product['name'] = 'John Doe';
$product['description'] = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus lacinia odio vitae vestibulum vestibulum.';
$product['in_stock'] = 24;
$product['_id'] = '51c33d8981fec6813e00000a';
$product->save();
$getDocument = Product::documentOrFail('51c33d8981fec6813e00000a');
expect($getDocument->exists)->toBe(true)->and($product['_id'])->toBe('51c33d8981fec6813e00000a');
});

test('Create', function () {
Expand Down