Laravel - How to extend Illuminate/Database/Query/Builder? - php

I tried with google and StackOverflow but there is nothing useful.
Does anyone know how to extend Query Builder? For example, I want to write my own count() method from Query Builder...
/**
* Retrieve the "count" result of the query.
*
* #param string $columns
* #return int
*/
public function count($columns = '*')
{
if (! is_array($columns)) {
$columns = [$columns];
}
return (int) $this->aggregate(__FUNCTION__, $columns);
}

Related

Undefined array key "docScores"

I'm working with the scout library and the tntsearch driver but when I try to search for a word that is in the website I get the error in the title. The code part where the error is according to Laravel is the one below and the line is the one between **. Do you have any idea on how to solve this? Thanks!
public function map(Builder $builder, $results, $model)
{
if (empty($results['ids'])) {
return $model->newCollection([]);
}
$keys = collect($results['ids'])->values()->all();
$builder = $this->getBuilder($model);
if ($this->builder->queryCallback) {
call_user_func($this->builder->queryCallback, $builder);
}
$models = $builder->whereIn(
$model->getQualifiedKeyName(), $keys
)->get()->keyBy($model->getKeyName());
// sort models by user choice
if (!empty($this->builder->orders)) {
return $models->values();
}
// sort models by tnt search result set
return $model->newCollection(collect($results['ids'])->map(function ($hit) use ($models, $results) {
if (isset($models[$hit])) {
*return $models[$hit]->setAttribute('__tntSearchScore__', $results['docScores'][$hit]);*
}
})->filter()->all());
}
This is the whole page of code:
class TNTSearchEngine extends Engine
{
private $filters;
/**
* #var TNTSearch
*/
protected $tnt;
/**
* #var Builder
*/
protected $builder;
/**
* Create a new engine instance.
*
* #param TNTSearch $tnt
*/
public function __construct(TNTSearch $tnt)
{
$this->tnt = $tnt;
}
public function getTNT()
{
return $this->tnt;
}
/**
* Update the given model in the index.
*
* #param Collection $models
*
* #return void
*/
public function update($models)
{
$this->initIndex($models->first());
$this->tnt->selectIndex("{$models->first()->searchableAs()}.index");
$index = $this->tnt->getIndex();
$index->setPrimaryKey($models->first()->getKeyName());
$index->indexBeginTransaction();
$models->each(function ($model) use ($index) {
$array = $model->toSearchableArray();
if (empty($array)) {
return;
}
if ($model->getKey()) {
$index->update($model->getKey(), $array);
} else {
$index->insert($array);
}
});
$index->indexEndTransaction();
}
/**
* Remove the given model from the index.
*
* #param Collection $models
*
* #return void
*/
public function delete($models)
{
$this->initIndex($models->first());
$models->each(function ($model) {
$this->tnt->selectIndex("{$model->searchableAs()}.index");
$index = $this->tnt->getIndex();
$index->setPrimaryKey($model->getKeyName());
$index->delete($model->getKey());
});
}
/**
* Perform the given search on the engine.
*
* #param Builder $builder
*
* #return mixed
*/
public function search(Builder $builder)
{
try {
return $this->performSearch($builder);
} catch (IndexNotFoundException $e) {
$this->initIndex($builder->model);
}
}
/**
* Perform the given search on the engine.
*
* #param Builder $builder
* #param int $perPage
* #param int $page
*
* #return mixed
*/
public function paginate(Builder $builder, $perPage, $page)
{
$results = $this->performSearch($builder);
if ($builder->limit) {
$results['hits'] = $builder->limit;
}
$filtered = $this->discardIdsFromResultSetByConstraints($builder, $results['ids']);
$results['hits'] = $filtered->count();
$chunks = array_chunk($filtered->toArray(), $perPage);
if (empty($chunks)) {
return $results;
}
if (array_key_exists($page - 1, $chunks)) {
$results['ids'] = $chunks[$page - 1];
} else {
$results['ids'] = [];
}
return $results;
}
/**
* Perform the given search on the engine.
*
* #param Builder $builder
*
* #return mixed
*/
protected function performSearch(Builder $builder, array $options = [])
{
$index = $builder->index ?: $builder->model->searchableAs();
$limit = $builder->limit ?: 10000;
$this->tnt->selectIndex("{$index}.index");
$this->builder = $builder;
if (isset($builder->model->asYouType)) {
$this->tnt->asYouType = $builder->model->asYouType;
}
if ($builder->callback) {
return call_user_func(
$builder->callback,
$this->tnt,
$builder->query,
$options
);
}
$builder->query = $this->applyFilters('query_expansion', $builder->query, get_class($builder->model));
if (isset($this->tnt->config['searchBoolean']) ? $this->tnt->config['searchBoolean'] : false) {
$res = $this->tnt->searchBoolean($builder->query, $limit);
event(new SearchPerformed($builder, $res, true));
return $res;
} else {
$res = $this->tnt->search($builder->query, $limit);
event(new SearchPerformed($builder, $res));
return $res;
}
}
/**
* Map the given results to instances of the given model.
*
* #param mixed $results
* #param \Illuminate\Database\Eloquent\Model $model
*
* #return Collection
*/
public function map(Builder $builder, $results, $model)
{
if (empty($results['ids'])) {
return $model->newCollection([]);
}
$keys = collect($results['ids'])->values()->all();
$builder = $this->getBuilder($model);
if ($this->builder->queryCallback) {
call_user_func($this->builder->queryCallback, $builder);
}
$models = $builder->whereIn(
$model->getQualifiedKeyName(), $keys
)->get()->keyBy($model->getKeyName());
// sort models by user choice
if (!empty($this->builder->orders)) {
return $models->values();
}
// sort models by tnt search result set
return $model->newCollection(collect($results['ids'])->map(function ($hit) use ($models, $results) {
if (isset($models[$hit])) {
return $models[$hit]->setAttribute('__tntSearchScore__', $results['docScores'][$hit]);
}
})->filter()->all());
}
/**
* Map the given results to instances of the given model via a lazy collection.
*
* #param mixed $results
* #param \Illuminate\Database\Eloquent\Model $model
*
* #return LazyCollection
*/
public function lazyMap(Builder $builder, $results, $model)
{
if (empty($results['ids'])) {
return LazyCollection::make();
}
$keys = collect($results['ids'])->values()->all();
$builder = $this->getBuilder($model);
if ($this->builder->queryCallback) {
call_user_func($this->builder->queryCallback, $builder);
}
$models = $builder->whereIn(
$model->getQualifiedKeyName(), $keys
)->get()->keyBy($model->getKeyName());
// sort models by user choice
if (!empty($this->builder->orders)) {
return $models->values();
}
// sort models by tnt search result set
return $model->newCollection($results['ids'])->map(function ($hit) use ($models) {
if (isset($models[$hit])) {
return $models[$hit];
}
})->filter()->values();
}
/**
* Return query builder either from given constraints, or as
* new query. Add where statements to builder when given.
*
* #param \Illuminate\Database\Eloquent\Model $model
*
* #return Builder
*/
public function getBuilder($model)
{
// get query as given constraint or create a new query
$builder = isset($this->builder->constraints) ? $this->builder->constraints : $model->newQuery();
$builder = $this->handleSoftDeletes($builder, $model);
$builder = $this->applyWheres($builder);
$builder = $this->applyOrders($builder);
return $builder;
}
/**
* Pluck and return the primary keys of the given results.
*
* #param mixed $results
* #return \Illuminate\Support\Collection
*/
public function mapIds($results)
{
if (empty($results['ids'])) {
return collect();
}
return collect($results['ids'])->values();
}
/**
* Get the total count from a raw result returned by the engine.
*
* #param mixed $results
*
* #return int
*/
public function getTotalCount($results)
{
return $results['hits'];
}
public function initIndex($model)
{
$indexName = $model->searchableAs();
if (!file_exists($this->tnt->config['storage']."/{$indexName}.index")) {
$indexer = $this->tnt->createIndex("$indexName.index");
$indexer->setDatabaseHandle($model->getConnection()->getPdo());
$indexer->setPrimaryKey($model->getKeyName());
}
}
/**
* The search index results ($results['ids']) need to be compared against our query
* that contains the constraints.
*
* To get the correct results and counts for the pagination, we remove those ids
* from the search index results that were found by the search but are not part of
* the query ($sub) that is constrained.
*
* This is achieved with self joining the constrained query as subquery and selecting
* the ids which are not matching to anything (i.e., is null).
*
* The constraints usually remove only a small amount of results, which is why the non
* matching results are looked up and removed, instead of returning a collection with
* all the valid results.
*/
private function discardIdsFromResultSetByConstraints($builder, $searchResults)
{
$qualifiedKeyName = $builder->model->getQualifiedKeyName(); // tableName.id
$subQualifiedKeyName = 'sub.'.$builder->model->getKeyName(); // sub.id
$sub = $this->getBuilder($builder->model)->whereIn(
$qualifiedKeyName, $searchResults
); // sub query for left join
$discardIds = $builder->model->newQuery()
->select($qualifiedKeyName)
->leftJoin(DB::raw('('.$sub->getQuery()->toSql().') as '.$builder->model->getConnection()->getTablePrefix().'sub'), $subQualifiedKeyName, '=', $qualifiedKeyName)
->addBinding($sub->getQuery()->getBindings(), 'join')
->whereIn($qualifiedKeyName, $searchResults)
->whereNull($subQualifiedKeyName)
->pluck($builder->model->getKeyName());
// returns values of $results['ids'] that are not part of $discardIds
return collect($searchResults)->diff($discardIds);
}
/**
* Determine if the given model uses soft deletes.
*
* #param \Illuminate\Database\Eloquent\Model $model
* #return bool
*/
protected function usesSoftDelete($model)
{
return in_array(SoftDeletes::class, class_uses_recursive($model));
}
/**
* Determine if soft delete is active and depending on state return the
* appropriate builder.
*
* #param Builder $builder
* #param \Illuminate\Database\Eloquent\Model $model
* #return Builder
*/
private function handleSoftDeletes($builder, $model)
{
// remove where statement for __soft_deleted when soft delete is not active
// does not show soft deleted items when trait is attached to model and
// config('scout.soft_delete') is false
if (!$this->usesSoftDelete($model) || !config('scout.soft_delete', true)) {
unset($this->builder->wheres['__soft_deleted']);
return $builder;
}
/**
* Use standard behaviour of Laravel Scout builder class to support soft deletes.
*
* When no __soft_deleted statement is given return all entries
*/
if (!array_key_exists('__soft_deleted', $this->builder->wheres)) {
return $builder->withTrashed();
}
/**
* When __soft_deleted is 1 then return only soft deleted entries
*/
if ($this->builder->wheres['__soft_deleted']) {
$builder = $builder->onlyTrashed();
}
/**
* Returns all undeleted entries, default behaviour
*/
unset($this->builder->wheres['__soft_deleted']);
return $builder;
}
/**
* Apply where statements as constraints to the query builder.
*
* #param Builder $builder
* #return \Illuminate\Support\Collection
*/
private function applyWheres($builder)
{
// iterate over given where clauses
return collect($this->builder->wheres)->map(function ($value, $key) {
// for reduce function combine key and value into array
return [$key, $value];
})->reduce(function ($builder, $where) {
// separate key, value again
list($key, $value) = $where;
return $builder->where($key, $value);
}, $builder);
}
/**
* Apply order by statements as constraints to the query builder.
*
* #param Builder $builder
* #return \Illuminate\Support\Collection
*/
private function applyOrders($builder)
{
//iterate over given orderBy clauses - should be only one
return collect($this->builder->orders)->map(function ($value, $key) {
// for reduce function combine key and value into array
return [$value["column"], $value["direction"]];
})->reduce(function ($builder, $orderBy) {
// separate key, value again
list($column, $direction) = $orderBy;
return $builder->orderBy($column, $direction);
}, $builder);
}
/**
* Flush all of the model's records from the engine.
*
* #param \Illuminate\Database\Eloquent\Model $model
* #return void
*/
public function flush($model)
{
$indexName = $model->searchableAs();
$pathToIndex = $this->tnt->config['storage']."/{$indexName}.index";
if (file_exists($pathToIndex)) {
unlink($pathToIndex);
}
}
/**
* Create a search index.
*
* #param string $name
* #param array $options
* #return mixed
*
* #throws \Exception
*/
public function createIndex($name, array $options = [])
{
throw new Exception('TNT indexes are created automatically upon adding objects.');
}
/**
* Delete a search index.
*
* #param string $name
* #return mixed
*/
public function deleteIndex($name)
{
throw new Exception(sprintf('TNT indexes cannot reliably be removed. Please manually remove the file in %s/%s.index', config('scout.tntsearch.storage'), $name));
}
/**
* Adds a filter
*
* #param string
* #param callback
* #return void
*/
public function addFilter($name, $callback)
{
if (!is_callable($callback, true)) {
throw new InvalidArgumentException(sprintf('Filter is an invalid callback: %s.', print_r($callback, true)));
}
$this->filters[$name][] = $callback;
}
/**
* Returns an array of filters
*
* #param string
* #return array
*/
public function getFilters($name)
{
return isset($this->filters[$name]) ? $this->filters[$name] : [];
}
/**
* Returns a string on which a filter is applied
*
* #param string
* #param string
* #return string
*/
public function applyFilters($name, $result, $model)
{
foreach ($this->getFilters($name) as $callback) {
// prevent fatal errors, do your own warning or
// exception here as you need it.
if (!is_callable($callback)) {
continue;
}
$result = call_user_func($callback, $result, $model);
}
return $result;
}
}

How to set _models and _keys for BaseDataProvider

<?php
/**
* #link http://www.yiiframework.com/
* #copyright Copyright (c) 2008 Yii Software LLC
* #license http://www.yiiframework.com/license/
*/
namespace yii\data;
use Yii;
use yii\base\Component;
use yii\base\InvalidParamException;
/**
* BaseDataProvider provides a base class that implements the [[DataProviderInterface]].
*
* #property integer $count The number of data models in the current page. This property is read-only.
* #property array $keys The list of key values corresponding to [[models]]. Each data model in [[models]] is
* uniquely identified by the corresponding key value in this array.
* #property array $models The list of data models in the current page.
* #property Pagination|boolean $pagination The pagination object. If this is false, it means the pagination
* is disabled. Note that the type of this property differs in getter and setter. See [[getPagination()]] and
* [[setPagination()]] for details.
* #property Sort|boolean $sort The sorting object. If this is false, it means the sorting is disabled. Note
* that the type of this property differs in getter and setter. See [[getSort()]] and [[setSort()]] for details.
* #property integer $totalCount Total number of possible data models.
*
* #author Qiang Xue <qiang.xue#gmail.com>
* #since 2.0
*/
abstract class BaseDataProvider extends Component implements DataProviderInterface
{
/**
* #var string an ID that uniquely identifies the data provider among all data providers.
* You should set this property if the same page contains two or more different data providers.
* Otherwise, the [[pagination]] and [[sort]] may not work properly.
*/
public $id;
private $_sort;
private $_pagination;
private $_keys;
private $_models;
private $_totalCount;
/**
* Prepares the data models that will be made available in the current page.
* #return array the available data models
*/
abstract protected function prepareModels();
/**
* Prepares the keys associated with the currently available data models.
* #param array $models the available data models
* #return array the keys
*/
abstract protected function prepareKeys($models);
/**
* Returns a value indicating the total number of data models in this data provider.
* #return integer total number of data models in this data provider.
*/
abstract protected function prepareTotalCount();
/**
* Prepares the data models and keys.
*
* This method will prepare the data models and keys that can be retrieved via
* [[getModels()]] and [[getKeys()]].
*
* This method will be implicitly called by [[getModels()]] and [[getKeys()]] if it has not been called before.
*
* #param boolean $forcePrepare whether to force data preparation even if it has been done before.
*/
public function prepare($forcePrepare = false)
{
if ($forcePrepare || $this->_models === null) {
$this->_models = $this->prepareModels();
}
if ($forcePrepare || $this->_keys === null) {
$this->_keys = $this->prepareKeys($this->_models);
}
}
/**
* Returns the data models in the current page.
* #return array the list of data models in the current page.
*/
public function getModels()
{
$this->prepare();
return $this->_models;
}
/**
* Sets the data models in the current page.
* #param array $models the models in the current page
*/
public function setModels($models)
{
$this->_models = $models;
}
/**
* Returns the key values associated with the data models.
* #return array the list of key values corresponding to [[models]]. Each data model in [[models]]
* is uniquely identified by the corresponding key value in this array.
*/
public function getKeys()
{
$this->prepare();
return $this->_keys;
}
/**
* Sets the key values associated with the data models.
* #param array $keys the list of key values corresponding to [[models]].
*/
public function setKeys($keys)
{
$this->_keys = $keys;
}
/**
* Returns the number of data models in the current page.
* #return integer the number of data models in the current page.
*/
public function getCount()
{
return count($this->getModels());
}
/**
* Returns the total number of data models.
* When [[pagination]] is false, this returns the same value as [[count]].
* Otherwise, it will call [[prepareTotalCount()]] to get the count.
* #return integer total number of possible data models.
*/
public function getTotalCount()
{
if ($this->getPagination() === false) {
return $this->getCount();
} elseif ($this->_totalCount === null) {
$this->_totalCount = $this->prepareTotalCount();
}
return $this->_totalCount;
}
/**
* Sets the total number of data models.
* #param integer $value the total number of data models.
*/
public function setTotalCount($value)
{
$this->_totalCount = $value;
}
/**
* Returns the pagination object used by this data provider.
* Note that you should call [[prepare()]] or [[getModels()]] first to get correct values
* of [[Pagination::totalCount]] and [[Pagination::pageCount]].
* #return Pagination|boolean the pagination object. If this is false, it means the pagination is disabled.
*/
public function getPagination()
{
if ($this->_pagination === null) {
$this->setPagination([]);
}
return $this->_pagination;
}
/**
* Sets the pagination for this data provider.
* #param array|Pagination|boolean $value the pagination to be used by this data provider.
* This can be one of the following:
*
* - a configuration array for creating the pagination object. The "class" element defaults
* to 'yii\data\Pagination'
* - an instance of [[Pagination]] or its subclass
* - false, if pagination needs to be disabled.
*
* #throws InvalidParamException
*/
public function setPagination($value)
{
if (is_array($value)) {
$config = ['class' => Pagination::className()];
if ($this->id !== null) {
$config['pageParam'] = $this->id . '-page';
$config['pageSizeParam'] = $this->id . '-per-page';
}
$this->_pagination = Yii::createObject(array_merge($config, $value));
} elseif ($value instanceof Pagination || $value === false) {
$this->_pagination = $value;
} else {
throw new InvalidParamException('Only Pagination instance, configuration array or false is allowed.');
}
}
/**
* Returns the sorting object used by this data provider.
* #return Sort|boolean the sorting object. If this is false, it means the sorting is disabled.
*/
public function getSort()
{
if ($this->_sort === null) {
$this->setSort([]);
}
return $this->_sort;
}
/**
* Sets the sort definition for this data provider.
* #param array|Sort|boolean $value the sort definition to be used by this data provider.
* This can be one of the following:
*
* - a configuration array for creating the sort definition object. The "class" element defaults
* to 'yii\data\Sort'
* - an instance of [[Sort]] or its subclass
* - false, if sorting needs to be disabled.
*
* #throws InvalidParamException
*/
public function setSort($value)
{
if (is_array($value)) {
$config = ['class' => Sort::className()];
if ($this->id !== null) {
$config['sortParam'] = $this->id . '-sort';
}
$this->_sort = Yii::createObject(array_merge($config, $value));
} elseif ($value instanceof Sort || $value === false) {
$this->_sort = $value;
} else {
throw new InvalidParamException('Only Sort instance, configuration array or false is allowed.');
}
}
/**
* Refreshes the data provider.
* After calling this method, if [[getModels()]], [[getKeys()]] or [[getTotalCount()]] is called again,
* they will re-execute the query and return the latest data available.
*/
public function refresh()
{
$this->_totalCount = null;
$this->_models = null;
$this->_keys = null;
}
}
The code above is the BaseDataProvider for yii2. My question is how i can set the _models and _keys in yii2? Which file do i need to change to link to that? Sorry i am quite new to yii. Please provide an example if possible thank you.
That what's You pasted here is abstract Yii2 class, which You should NEVER edit.
To use this thing i suggest You to read about ActiveDataProvider here: Docs
$query = Post::find()->where(['status' => 1]);
$provider = new ActiveDataProvider([
'query' => $query,
]);
Here's an example how to use it, first line defines data which will be used to populate ActiveDataProvider (it's a SQL query), and then You create ActiveDataProvider instance with query as config parameter.

Laravel - Get related data with find method (for one record)

I don't understand why results are so different:
Shop::find($id)->with('products'); // just empty
Shop::find($id)->with('products')->first(); // ignores find()
But same thing with where() works.
Shop::where('id', $id)->with('products')->first(); // works fine
So, is this last one the correct way? (If I just want a shop with its products attached)
where() returns a query builder object (which you can add extra terms to before executing with get or first)
From the source code:
/**
* Add a basic where clause to the query.
*
* #param string $column
* #param string $operator
* #param mixed $value
* #param string $boolean
* #return $this
*/
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
if ($column instanceof Closure) {
$query = $this->model->newQueryWithoutScopes();
call_user_func($column, $query);
$this->query->addNestedWhereQuery($query->getQuery(), $boolean);
} else {
call_user_func_array([$this->query, 'where'], func_get_args());
}
return $this;
}
On the other hand, find just returns the actual model or a collection of models (not a query builder).
From the source code:
/**
* Find a model by its primary key.
*
* #param mixed $id
* #param array $columns
* #return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null
*/
public function find($id, $columns = ['*'])
{
if (is_array($id)) {
return $this->findMany($id, $columns);
}
$this->query->where($this->model->getQualifiedKeyName(), '=', $id);
return $this->first($columns);
}
Look at api documentations:
http://laravel.com/api/5.1/Illuminate/Database/Eloquent/Builder.html
only eloquent methods that returns $this(Builder) can be used in pipe for adding rules what to select.

Getting random results with Doctrine

I'm new to Doctrine and had a hard time deciding how to get random rows within it without creating custom DQL functions or using a native query.
The solution I have come up with is below, this is within a custom repository for an Entity. I'm hoping for some constructive criticism in regards to it, however it currently is working.
class MyRepository extends EntityRepository
{
/**
* #param int $numberOfResults
* #return array
*/
public function getRandomResults($numberOfResults = 1)
{
$maxID = $this->getMax();
$count = 0;
$randomNumberCounter = 0;
$randomNumbers = array();
while ($randomNumberCounter < $numberOfResults) {
$randomNumberCounter++;
$randomNumbers[] = $this->getRandom(0, $maxID);
}
$qb = $this->createQueryBuilder('r');
while ($count < $numberOfResults) {
$qb
->andWhere(
$qb->expr()->orX(
// the greater than is to account for holes within the primary key
$qb->expr()->gte("r.id", "?".$count),
/* the less than is in case we have a beginning database with a large disparity
between starting and ending ID */
$qb->expr()->lte("r.id", "?".$count)
)
);
$count++;
}
$result = $qb
->setParameters($randomNumbers)
->setMaxResults($numberOfResults)
// ensure we have no duplicates
->groupBy('r.id')
->getQuery();
return $result->getResult();
}
/**
* get the maximum ID that the table has
* #return mixed
* TODO: Create a Cron job to set this every 6 hours
*/
public function getMax()
{
$maxID = $this->createQueryBuilder('r')
->select('(MAX(r.id))')
->getQuery()
->getSingleScalarResult();
return $maxID;
}
/**
* #param $min
* #param $max
* #return int
*/
public function getRandom($min, $max)
{
return mt_rand($min, $max);
}
}

Zend Framework 2 Db: Make a part of the query negative using Predicate objects

How do you negate a part of the query using Zend Framework 2? I'm trying to do the Zend\Db equivalent of this dynamic MySQL query-part:
NOT (`a` = 1 AND `b`IS NULL AND `c` LIKE 'foo')
Right now I have the three query-parts as Predicate objects (Operator, IsNull and Like objects). How can I negate these and put in the where?
Is it possible to convert a Predicate object (like an Operator or IsNull object) to a Sql String?
Zend dose not have a out of box solution for this , I wrote a class to do this .
/**
* Created by PhpStorm.
* User: Exlord (adeli.farhad#gmail.com)
* Date: 6/19/14
* Time: 11:44 AM
*/
namespace System\DB\Sql\Predicate;
use Zend\Db\Sql\Predicate\PredicateInterface;
class Not implements PredicateInterface
{
/**
* #var string
*/
protected $specification = 'NOT (%1$s)';
protected $expression;
public function __construct($expression = null)
{
$this->expression = $expression;
}
/**
* #param null $expression
*/
public function setExpression($expression)
{
$this->expression = $expression;
}
/**
* #return null
*/
public function getExpression()
{
return $this->expression;
}
/**
* #param string $specification
* #return self
*/
public function setSpecification($specification)
{
$this->specification = $specification;
return $this;
}
/**
* #return string
*/
public function getSpecification()
{
return $this->specification;
}
/**
* #return array
*/
public function getExpressionData()
{
return array(
array($this->specification, array($this->expression), array(self::TYPE_VALUE))
);
}
}
usage :
$where = new Where();
$where->notIn('id', array(1, 2));
$where->equalTo('name', 'Foo');
$select = new Select('tbl_');
$select->where->addPredicate(new Not($where));
var_dump($select->getSqlString());
output :
string 'SELECT "tbl_".* FROM "tbl_" WHERE NOT ("id" NOT IN ('1', '2')
AND "name" = 'Foo')' (length=81)
Its more like -
'a' != 1 AND 'b' IS NOT NULL AND 'c' NOT LIKE 'foo'
Try these as individual where conditions.
Eg:
$where = new Where();
$where->notEqualTo('a', 1);
$where->isNotNull('b');
$where->literal('c NOT LIKE ?', array('foo'));

Categories