PageRenderTime 86ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/libraries/anahita/domain/query/query.php

https://github.com/bhar1red/anahita
PHP | 1001 lines | 493 code | 125 blank | 383 comment | 54 complexity | e7849392e052ba2ef4a7e40b436a520c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * LICENSE: ##LICENSE##
  4. *
  5. * @category Anahita
  6. * @package Anahita_Domain
  7. * @subpackage Query
  8. * @author Arash Sanieyan <ash@anahitapolis.com>
  9. * @author Rastin Mehr <rastin@anahitapolis.com>
  10. * @copyright 2008 - 2010 rmdStudio Inc./Peerglobe Technology Inc
  11. * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl-3.0.html>
  12. * @version SVN: $Id$
  13. * @link http://www.anahitapolis.com
  14. */
  15. /**
  16. * Domain Query Class
  17. *
  18. * @category Anahita
  19. * @package Anahita_Domain
  20. * @subpackage Query
  21. * @author Arash Sanieyan <ash@anahitapolis.com>
  22. * @author Rastin Mehr <rastin@anahitapolis.com>
  23. * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl-3.0.html>
  24. * @link http://www.anahitapolis.com
  25. */
  26. class AnDomainQuery extends KObject implements KCommandInterface
  27. {
  28. /**
  29. * Query Operation
  30. */
  31. const QUERY_SELECT_DEFAULT = 2;
  32. const QUERY_SELECT = 4;
  33. const QUERY_UPDATE = 8;
  34. const QUERY_DELETE = 16;
  35. /**
  36. * Creates a new query object from a set of conditions
  37. *
  38. * @param mixed $repository A repository
  39. * @param mixed $conditions A set of conditions
  40. *
  41. * @return AnDomainQuery
  42. */
  43. static public function getInstance($repository, $conditions)
  44. {
  45. if ( !$conditions instanceof AnDomainQuery )
  46. {
  47. if ( $repository instanceof AnDomainQuery ) {
  48. $query = clone $repository;
  49. $repository = $query->getRepository();
  50. }
  51. else
  52. $query = $repository->getQuery();
  53. $identity_property = $repository->getDescription()->getIdentityProperty();
  54. if ( !empty($conditions) )
  55. {
  56. if ( is_numeric($conditions) )
  57. $conditions = array($conditions);
  58. //if conditions is number of an array of numbers
  59. if ( is_numeric($conditions) ||
  60. (is_array($conditions) && is_numeric(key($conditions))) )
  61. {
  62. $conditions = array($identity_property->getName()=>$conditions);
  63. }
  64. $query->where($conditions);
  65. }
  66. } else
  67. //clone the query to avoid changing the passed query
  68. $query = clone $conditions;
  69. return $query;
  70. }
  71. /**
  72. * Links to other query
  73. *
  74. * @var array
  75. */
  76. public $link = array();
  77. /**
  78. * The quer binds
  79. *
  80. * @var array
  81. */
  82. public $binds = array();
  83. /**
  84. * Query Operation. SELECT, COUNT, UPDATE or Custom
  85. *
  86. * @var int
  87. */
  88. public $operation;
  89. /**
  90. * Distinct operation
  91. *
  92. * @var boolean
  93. */
  94. public $distinct = false;
  95. /**
  96. * The columns
  97. *
  98. * @var array
  99. */
  100. public $columns = array();
  101. /**
  102. * The from element
  103. *
  104. * @var array
  105. */
  106. public $from = array();
  107. /**
  108. * The join element
  109. *
  110. * @var array
  111. */
  112. public $join = array();
  113. /**
  114. * The where element
  115. *
  116. * @var array
  117. */
  118. public $where = array();
  119. /**
  120. * The group element
  121. *
  122. * @var array
  123. */
  124. public $group = array();
  125. /**
  126. * The having element
  127. *
  128. * @var array
  129. */
  130. public $having = array();
  131. /**
  132. * The order element
  133. *
  134. * @var string
  135. */
  136. public $order = array();
  137. /**
  138. * The limit element
  139. *
  140. * @var integer
  141. */
  142. public $limit = null;
  143. /**
  144. * The limit offset element
  145. *
  146. * @var integer
  147. */
  148. public $offset = null;
  149. /**
  150. * Resource prefix
  151. *
  152. * @var string
  153. */
  154. protected $_prefix;
  155. /**
  156. * state
  157. *
  158. * @var KConfig
  159. */
  160. protected $_state;
  161. /**
  162. * Repository
  163. *
  164. * @var AnDomainRepositoryAbstract
  165. */
  166. protected $_repository;
  167. /**
  168. * Constructor.
  169. *
  170. * @param object An optional KConfig object with configuration options
  171. */
  172. public function __construct(KConfig $config)
  173. {
  174. parent::__construct($config);
  175. $this->_repository = $config->repository;
  176. $this->operation = array('type'=>AnDomainQuery::QUERY_SELECT_DEFAULT, 'value'=>'');
  177. $this->_prefix = $config->resource_prefix;
  178. $this->_state = $config->state;
  179. if ( $config['query_options'] instanceof Closure ) {
  180. $config['query_options']($this);
  181. } else {
  182. AnDomainQueryHelper::applyFilters($this, $config['query_options']);
  183. }
  184. }
  185. /**
  186. * Initializes the options for the object
  187. *
  188. * Called from {@link __construct()} as a first step of object instantiation.
  189. *
  190. * @param object An optional KConfig object with configuration options.
  191. * @return void
  192. */
  193. protected function _initialize(KConfig $config)
  194. {
  195. $config->append(array(
  196. 'repository' => $this->getIdentifier()->name,
  197. 'resource_prefix' => '#__',
  198. 'query_options' => array(),
  199. 'state' => array(
  200. 'instance_of' => array(),
  201. 'disable_chain' => false
  202. )
  203. ));
  204. }
  205. /**
  206. * If a $key is an array then a query will be created from the array
  207. *
  208. * @see KDatabaseQuery::where()
  209. */
  210. public function where( $key, $constraint = null, $value = null , $condition = 'AND' )
  211. {
  212. if ( in_array($constraint, array('AND', 'OR')) )
  213. {
  214. $condition = $constraint;
  215. $constraint = null;
  216. }
  217. else if ( is_array($key) )
  218. {
  219. if ( !is_numeric(key($key)) )
  220. {
  221. foreach($key as $k => $v) $this->where($k,'=',$v, 'AND');
  222. return $this;
  223. }
  224. }
  225. $where = array();
  226. $where['property'] = $key;
  227. if(isset($constraint))
  228. {
  229. $constraint = strtoupper($constraint);
  230. $condition = strtoupper($condition);
  231. $list = $value instanceof KObjectSet || is_array($value);
  232. //fix the contstraint
  233. if ( $list || $value instanceof AnDomainQuery )
  234. {
  235. if ( $constraint == '=' )
  236. $constraint = 'IN';
  237. elseif ( $constraint == '<>' )
  238. $constraint = 'NOT IN';
  239. }
  240. $where['constraint'] = $constraint;
  241. $where['value'] = $value;
  242. }
  243. $where['condition'] = count($this->where) ? $condition : '';
  244. $this->where[] = $where;
  245. return $this;
  246. }
  247. /**
  248. * Return a subclause
  249. *
  250. * @param string $condition The glue condition
  251. *
  252. * @return AnDomainQuery
  253. */
  254. public function clause($condition = 'AND')
  255. {
  256. if ( !count($this->where) )
  257. $condition = null;
  258. $clause = new AnDomainQueryClause( $this, $condition);
  259. return $clause;
  260. }
  261. /**
  262. * Return the resource prefix
  263. *
  264. * @return string
  265. */
  266. public function getPrefix()
  267. {
  268. return $this->_prefix;
  269. }
  270. /**
  271. * Converts the query to a update query
  272. *
  273. * @param array|string $values The values to update
  274. *
  275. * @return AnDomainQuery
  276. */
  277. public function update($values)
  278. {
  279. $this->operation = array('type'=>AnDomainQuery::QUERY_UPDATE, 'value'=>$values);
  280. return $this;
  281. }
  282. /**
  283. * Converts the query to a delete query
  284. *
  285. * @return AnDomainQuery
  286. */
  287. public function delete()
  288. {
  289. $this->operation = array('type'=>AnDomainQuery::QUERY_DELETE, 'value'=>'');
  290. return $this;
  291. }
  292. /**
  293. * Built a select query
  294. *
  295. * @param array|string $columns A string or an array of column names
  296. *
  297. * @return AnDomainQuery
  298. */
  299. public function select( $columns )
  300. {
  301. settype($columns, 'array');
  302. $this->columns = array_unique( array_merge( $this->columns, $columns ) );
  303. $this->operation = array('type'=>AnDomainQuery::QUERY_SELECT_DEFAULT, 'value'=>'');
  304. return $this;
  305. }
  306. /**
  307. * Build a customized operation
  308. *
  309. * @param array $columns Columns names
  310. *
  311. * @return AnDomainQuery
  312. */
  313. public function columns($columns)
  314. {
  315. $this->operation = array('type'=>AnDomainQuery::QUERY_SELECT, 'value'=>$columns);
  316. return $this;
  317. }
  318. /**
  319. * Links a query to anotehr query by joining the main query resoruce
  320. *
  321. * @param mixed $query Query object
  322. * @param string|array $condition Array condition
  323. * @param array $options Options
  324. *
  325. * @return AnDomainQuery
  326. */
  327. public function link($query, $condition = array(), $options = array())
  328. {
  329. if ( is_string($query) )
  330. {
  331. if ( strpos($query,'.') === false )
  332. {
  333. $name = $query;
  334. if ( $property = $this->getRepository()->getDescription()->getProperty($name) ) {
  335. $name = $property->getName();
  336. }
  337. AnDomainQueryHelper::addRelationship($this, $name);
  338. $link = $this->getLink($name);
  339. $config = new KConfig($condition);
  340. $config->append(array(
  341. 'type' => $link->type,
  342. 'bind_type' => $link->bind_type,
  343. 'conditions' => array()
  344. ));
  345. $link->offsetSet('type', $config->type)->offsetSet('bind_type', $config->bind_type);
  346. foreach($config->conditions as $key => $value)
  347. {
  348. if ( is_string($value) )
  349. {
  350. $value = AnDomainQueryBuilder::getInstance()->parseMethods($this, $value);
  351. }
  352. elseif ( $value instanceof AnDomainResourceColumn)
  353. {
  354. $value = clone $value;
  355. }
  356. $link->conditions[$key] = $value;
  357. }
  358. return $this;
  359. }
  360. else
  361. {
  362. $query = AnDomain::getRepository($query)->getQuery();
  363. }
  364. }
  365. elseif ($query instanceof AnDomainRepositoryAbstract )
  366. $query = $query->getQuery();
  367. settype($condition, 'array');
  368. $options = new KConfig($options);
  369. $options->append(array(
  370. 'type' => 'strong',
  371. 'resource' => $query->getRepository()->getResources()->main(),
  372. 'as' => $query->getRepository()->getDescription()->getEntityIdentifier()->name
  373. ));
  374. if ( !isset($this->link[$options->as]) )
  375. {
  376. $options->resource->setAlias(KInflector::underscore($options->as));
  377. $destination = $query->getRepository()->getDescription()->getInheritanceColumn();
  378. $link = array(
  379. 'query' => $query,
  380. 'resource' => $options->resource,
  381. 'resource_name' => $options->resource->getAlias(),
  382. 'type' => $options->type,
  383. 'conditions' => array(),
  384. 'bind_type' => $destination ? clone $destination : null
  385. );
  386. foreach($condition as $key => $value)
  387. {
  388. $link['conditions'][$key] = $value instanceof AnDomainResourceColumn ? clone $value : $value;
  389. }
  390. $this->link[$options->as] = new KConfig($link);
  391. $this->distinct = true;
  392. }
  393. return $this;
  394. }
  395. /**
  396. * Returns a query link
  397. *
  398. * @param string $link The link name
  399. *
  400. * @return array
  401. */
  402. public function getLink($link)
  403. {
  404. return isset($this->link[$link]) ? $this->link[$link] : null;
  405. }
  406. /**
  407. * Return the entityset repository
  408. *
  409. * @return AnDomainAbstractRepository
  410. */
  411. public function getRepository()
  412. {
  413. if ( !$this->_repository instanceof AnDomainRepositoryAbstract )
  414. {
  415. if ( !$this->_repository instanceof KServiceIdentifier ) {
  416. $this->setRepository($this->_repository);
  417. }
  418. $this->_repository = $this->getService($this->_repository);
  419. }
  420. return $this->_repository;
  421. }
  422. /**
  423. * Set the repository using identifier or a repository object
  424. *
  425. * @param mixed $repository
  426. *
  427. * @return void
  428. */
  429. public function setRepository($repository)
  430. {
  431. if ( !$this->_repository instanceof AnDomainRepositoryAbstract )
  432. {
  433. if(is_string($repository) && strpos($repository, '.') === false )
  434. {
  435. $identifier = clone $this->getIdentifier();
  436. $identifier->type = 'repos';
  437. $identifier->path = array();
  438. $identifier->name = $repository;
  439. }
  440. else $identifier = $this->getIdentifier($repository);
  441. $repository = $identifier;
  442. }
  443. $this->_repository = $repository;
  444. }
  445. /**
  446. * Return an identiable value for the query
  447. *
  448. * @return mixed|array
  449. */
  450. public function getKey()
  451. {
  452. $key = false;
  453. if ( count($this->where) == 1 )
  454. {
  455. $where = array_pop(array_values($this->where));
  456. if ( isset($where['property']) ) {
  457. $property = $where['property'];
  458. $keys = $this->getRepository()->getDescription()->getIdentifyingProperties();
  459. if ( isset($keys[$property]) && isset($where['constraint']) && $where['constraint'] == '=' && !is_array($where['value'])) {
  460. $key[$property] = $where['value'];
  461. }
  462. }
  463. }
  464. return $key;
  465. }
  466. /**
  467. * Built the from clause of the query
  468. *
  469. * @param array|string $resources A string or array of resource names
  470. *
  471. * @return AnDomainQuery
  472. */
  473. public function from( $resources )
  474. {
  475. settype($resources, 'array');
  476. //Prepent the resource prefix
  477. foreach($resources as &$resource)
  478. {
  479. if(strpos($resource, $this->_prefix) !== 0) {
  480. $resource = $this->_prefix.$resource;
  481. }
  482. }
  483. $this->from = array_unique(array_merge($this->from, $resources));
  484. return $this;
  485. }
  486. /**
  487. * Built the group clause of the query
  488. *
  489. * @param array|string $columns A string or array of ordering columns
  490. *
  491. * @return AnDomainQuery
  492. */
  493. public function group( $columns )
  494. {
  495. settype($columns, 'array'); //force to an array
  496. $this->group = array_unique( array_merge( $this->group, $columns));
  497. return $this;
  498. }
  499. /**
  500. * Built the having clause of the query
  501. *
  502. * @param array|string $columns A string or array of ordering columns
  503. *
  504. * @return AnDomainQuery
  505. */
  506. public function having( $columns )
  507. {
  508. settype($columns, 'array'); //force to an array
  509. $this->having = array_unique( array_merge( $this->having, $columns ));
  510. return $this;
  511. }
  512. /**
  513. * Build the order clause of the query
  514. *
  515. * @param array|string $columns A string or array of ordering columns
  516. * @param string $direction Either DESC or ASC
  517. *
  518. * @return AnDomainQuery
  519. */
  520. public function order( $columns, $direction = 'ASC' )
  521. {
  522. settype($columns, 'array'); //force to an array
  523. foreach($columns as $column)
  524. {
  525. $this->order[] = array(
  526. 'column' => $column,
  527. 'direction' => $direction
  528. );
  529. }
  530. return $this;
  531. }
  532. /**
  533. * Built the limit element of the query
  534. *
  535. * @param int $limit Number of items to fetch.
  536. * @param int $offset Offset to start fetching at.
  537. *
  538. * @return AnDomainQuery
  539. */
  540. public function limit( $limit, $offset = 0 )
  541. {
  542. $this->limit = (int) $limit;
  543. $this->offset = (int) $offset;
  544. return $this;
  545. }
  546. /**
  547. * Built the join clause of the query
  548. *
  549. * @param string $type The type of join; empty for a plain JOIN, or "LEFT", "INNER", etc.
  550. * @param string $resource The table name to join to.
  551. * @param string|array $condition Join on this condition.
  552. *
  553. * @return AnDomainQuery
  554. */
  555. public function join($type, $resource, $condition)
  556. {
  557. settype($condition, 'array');
  558. if(strpos($resource, $this->_prefix) !== 0) {
  559. $resource = $this->_prefix.$resource;
  560. }
  561. $this->join[] = array(
  562. 'type' => strtoupper($type),
  563. 'resource' => $resource,
  564. 'condition' => $condition,
  565. );
  566. return $this;
  567. }
  568. /**
  569. * Binds an array of params
  570. *
  571. * @return AnDomainQuery
  572. */
  573. public function bind($key, $value = null)
  574. {
  575. $data = $key;
  576. if ( !is_array($key) )
  577. $data = array($key => $value);
  578. foreach($data as $key => $value) {
  579. $this->binds[$key] = $value;
  580. }
  581. return $this;
  582. }
  583. /**
  584. * If set, the repository will disable the chain for this query before fetch. This prevents
  585. * a query from being tampered with
  586. *
  587. * @return AnDomainQuery
  588. */
  589. public function disableChain()
  590. {
  591. $this->disable_chain = true;
  592. return $this;
  593. }
  594. /**
  595. * If a proeprty is used then it will be used as condition. For example $query->id(10) create
  596. * $query->where('id','=',10)
  597. *
  598. * If a method is format of fetch|select[Function Name]Value(s)(property). This will be translated in to
  599. * fetchValue('{Function Name}(property)'). For example fetchCount => fetchValue('COUNT({property}')
  600. *
  601. * If not of the above then KInflector::underscore($method) will be inserted as a state
  602. *
  603. */
  604. public function __call($method, array $arguments)
  605. {
  606. $match = array();
  607. //only do condition chaining if it's a real property
  608. //don't check the parent property
  609. if ( $this->getRepository()->getDescription()->getProperty($method) )
  610. {
  611. $constraint = isset($arguments[1]) ? $arguments[1] : '=';
  612. $condition = isset($arguments[2]) ? $arguments[2] : 'AND';
  613. $this->where($method,$constraint,$arguments[0], $condition);
  614. }
  615. //if a method is format of fetch|select[Function Name](property). This will be translated in to
  616. //fetch('{Function Name}(property)'). For example fetchCount => fetchValue('COUNT({property}')
  617. elseif ( preg_match('/(fetch|select)(\w+)/',$method, $match) )
  618. {
  619. deprecated('use '.$match[1].'(FUNC) instead');
  620. $column = isset($arguments[0]) ? $arguments[0] : '*';
  621. $property = $this->getRepository()->getDescription()->getProperty($column);
  622. if ( $property ) {
  623. $column = '@col('.$column.')';
  624. }
  625. if ( $match[1] == 'select' )
  626. $method = 'columns';
  627. elseif ( KInflector::isPlural($match[2]) )
  628. $method = 'fetchValues';
  629. else
  630. $method = 'fetchValue';
  631. $function = strtoupper($match[2]).'('.$column.')';
  632. return $this->$method($function);
  633. }
  634. elseif ( count($arguments) > 0 )
  635. {
  636. $this->__set(KInflector::underscore($method), $arguments[0]);
  637. }
  638. else
  639. {
  640. throw new BadMethodCallException('Call to undefined method :'.$method);
  641. }
  642. return $this;
  643. }
  644. /**
  645. * Get a value from the query state
  646. *
  647. * @param string $name State name
  648. *
  649. * @return mixed
  650. */
  651. public function __get($name)
  652. {
  653. return $this->_state->$name;
  654. }
  655. /**
  656. * Set a state of the query
  657. *
  658. * @param string $name Name of the state
  659. * @param string $value Value of the state
  660. *
  661. * @return void
  662. */
  663. public function __set($name, $value)
  664. {
  665. $state = KConfig::unbox($this->_state->$name);
  666. if ( is_array($state) && is_array($value))
  667. {
  668. settype($value, 'array');
  669. $state = array_merge($state, $value);
  670. }
  671. else $state = $value;
  672. $this->_state->$name = $state;
  673. }
  674. /**
  675. * Calls the query repositry fetch method and pass the query
  676. *
  677. * @param mixed $condition The condition of the fetch. This condition will not affect the query
  678. *
  679. * @return AnDomainEntityAbstract
  680. */
  681. public function fetch($condition=array())
  682. {
  683. $query = self::getInstance($this, $condition);
  684. return $this->getRepository()->fetch($query);
  685. }
  686. /**
  687. * Calls the query repositry fetch method with the collection mode and pass the query
  688. *
  689. * @param mixed $condition The condition of the fetch. This condition will not affect the query
  690. *
  691. * @return AnDomainEntitysetDefault
  692. */
  693. public function fetchSet($condition=array())
  694. {
  695. $query = self::getInstance($this, $condition);
  696. return $this->getRepository()->fetch($query, AnDomain::FETCH_ENTITY_SET);
  697. }
  698. /**
  699. * Calls the query repositry fetch method with the value mode and pass the query
  700. *
  701. * @param array $columns An array of columns whose value to get
  702. * @param mixed $condition The condition of the fetch. This condition will not affect the query
  703. *
  704. * @return AnDomainEntityAbstract
  705. */
  706. public function fetchValue($column, $condition=array())
  707. {
  708. $query = self::getInstance($this, $condition);
  709. $query->columns($column);
  710. return $this->getRepository()->fetch($query, AnDomain::FETCH_VALUE);
  711. }
  712. /**
  713. * Calls the query repositry fetch method with the value mode and pass the query
  714. *
  715. * @param array $columns An array of columns whose value to get
  716. * @param mixed $condition The condition of the fetch. This condition will not affect the query
  717. *
  718. * @return AnDomainEntityAbstract
  719. */
  720. public function fetchValues($column, $condition=array())
  721. {
  722. $query = self::getInstance($this, $condition);
  723. $query->columns($column);
  724. return $this->getRepository()->fetch($query, AnDomain::FETCH_VALUE_LIST);
  725. }
  726. /**
  727. * Return the row data
  728. *
  729. * @return array
  730. */
  731. public function fetchRow($condition=array())
  732. {
  733. $query = self::getInstance($this, $condition);
  734. return $this->getRepository()->fetch($query, AnDomain::FETCH_ROW);
  735. }
  736. /**
  737. * Return the row data
  738. *
  739. * @return array
  740. */
  741. public function fetchRows($condition=array())
  742. {
  743. $query = self::getInstance($this, $condition);
  744. return $this->getRepository()->fetch($query, AnDomain::FETCH_ROW_LIST);
  745. }
  746. /**
  747. * Forwards the call to the repository destory.
  748. *
  749. * @see AnDomainRepositoryAbstract::destory()
  750. *
  751. * @return void
  752. */
  753. public function destroy()
  754. {
  755. return $this->getRepository()->destroy($this);
  756. }
  757. /**
  758. * Returns a entity set whose data has not been fetched yet
  759. *
  760. * @return AnDomainEntitysetDefault
  761. */
  762. public function toEntitySet()
  763. {
  764. return KService::get($this->getRepository()->getEntitySet(), array('query'=>clone $this, 'repository'=>$this->getRepository()));
  765. }
  766. /**
  767. * Retun AnDomain operation based on the query operation
  768. *
  769. * @return int
  770. */
  771. public function getOperation()
  772. {
  773. switch($this->operation['type'])
  774. {
  775. case AnDomainQuery::QUERY_UPDATE :
  776. return AnDomain::OPERATION_UPDATE;
  777. case AnDomainQuery::QUERY_DELETE :
  778. return AnDomain::OPERATION_DELETE;
  779. default :
  780. return AnDomain::OPERATION_FETCH;
  781. }
  782. }
  783. /**
  784. * Return the query in a string format
  785. *
  786. * @return string
  787. */
  788. final public function __toString()
  789. {
  790. try
  791. {
  792. $query = clone $this;
  793. //if the chain is not disabled then
  794. //allows the registered command chains
  795. //to modify the query based on its state
  796. if ( !$query->disable_chain )
  797. {
  798. $chain = clone $this->getRepository()->getCommandChain();
  799. $chain->enqueue($query);
  800. $context = $this->getRepository()->getCommandContext();
  801. $context->caller = $this;
  802. $context->query = $query;
  803. switch($this->operation['type'])
  804. {
  805. case AnDomainQuery::QUERY_UPDATE :
  806. $command = 'update';break;
  807. case AnDomainQuery::QUERY_DELETE :
  808. $command = 'delete';break;
  809. default :
  810. $command = 'select';break;
  811. }
  812. $chain->run('before.'.$command, $context);
  813. $context->result = $query->build();
  814. $chain->run('after.'.$command, $context);
  815. return $context->result;
  816. } else {
  817. return $query->build();
  818. }
  819. }
  820. catch(Exception $e) {
  821. trigger_error($e->getMessage());
  822. }
  823. }
  824. /**
  825. * Builds the query and return the string
  826. *
  827. * @return string
  828. */
  829. public function build()
  830. {
  831. return AnDomainQueryBuilder::getInstance()->build($this);
  832. }
  833. /**
  834. * (non-PHPdoc)
  835. * @see KCommandInterface::execute()
  836. */
  837. public function execute($command, KCommandContext $context)
  838. {
  839. $identifier = $context->caller->getIdentifier();
  840. $type = $identifier->path;
  841. $type = array_pop($type);
  842. $parts = explode('.', $command);
  843. $method = '_'.($parts[0]).ucfirst($type).ucfirst($parts[1]);
  844. if(method_exists($this, $method)) {
  845. return $this->$method($context);
  846. }
  847. }
  848. /**
  849. * Return an array of serializable properties
  850. *
  851. * @return array
  852. */
  853. public function __sleep()
  854. {
  855. $vars = explode(' ','__service_identifier _state link binds operation distinct columns from join where group having order limit offset _prefix');
  856. return $vars;
  857. }
  858. /**
  859. * The priority of the query
  860. *
  861. * @return number
  862. */
  863. public function getPriority()
  864. {
  865. return -PHP_INT_MAX;
  866. }
  867. /**
  868. * Reset the query state if it's cloned
  869. *
  870. * @return void
  871. */
  872. public function __clone()
  873. {
  874. $this->_state = clone $this->_state;
  875. }
  876. }