Go to the documentation of this file.00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00032 final class OqlSelectParser extends OqlParser
00033 {
00034
00035 const PROPERTY_STATE = 1;
00036 const FROM_STATE = 2;
00037 const WHERE_STATE = 3;
00038 const GROUP_BY_STATE = 4;
00039 const ORDER_BY_STATE = 5;
00040 const HAVING_STATE = 6;
00041 const LIMIT_STATE = 7;
00042 const OFFSET_STATE = 8;
00043
00047 public static function create()
00048 {
00049 return new self;
00050 }
00051
00055 protected function makeOqlObject()
00056 {
00057 return OqlSelectQuery::create();
00058 }
00059
00060 protected function handleState()
00061 {
00062 switch ($this->state) {
00063 case self::INITIAL_STATE:
00064 case self::PROPERTY_STATE:
00065 return $this->propertyState();
00066
00067 case self::FROM_STATE:
00068 return $this->fromState();
00069
00070 case self::WHERE_STATE:
00071 return $this->whereState();
00072
00073 case self::GROUP_BY_STATE:
00074 return $this->groupByState();
00075
00076 case self::ORDER_BY_STATE:
00077 return $this->orderByState();
00078
00079 case self::HAVING_STATE:
00080 return $this->havingState();
00081
00082 case self::LIMIT_STATE:
00083 return $this->limitState();
00084
00085 case self::OFFSET_STATE:
00086 return $this->offsetState();
00087 }
00088
00089 throw new WrongStateException('state machine is broken');
00090 }
00091
00092 private function propertyState()
00093 {
00094 $token = $this->tokenizer->peek();
00095
00096 if (!$token)
00097 $this->error("expecting 'from' clause");
00098
00099 if ($this->checkKeyword($token, 'from'))
00100 return self::FROM_STATE;
00101
00102 $clause = OqlSelectPropertiesParser::create()->
00103 setTokenizer($this->tokenizer)->
00104 parse();
00105
00106 $this->oqlObject->addProperties($clause);
00107 if ($clause->isDistinct())
00108 $this->oqlObject->setDistinct(true);
00109
00110 return self::FROM_STATE;
00111 }
00112
00113 private function fromState()
00114 {
00115 if ($this->checkKeyword($this->tokenizer->peek(), 'from')) {
00116 $this->tokenizer->next();
00117
00118 $class = $this->tokenizer->next();
00119 $className = $this->getTokenValue($class, true);
00120
00121 if (
00122 !$this->checkIdentifier($class)
00123 || !ClassUtils::isClassName($className)
00124 ) {
00125 $this->error('invalid class name:', $className);
00126 }
00127
00128 if (!class_exists($className, true))
00129 $this->error('class does not exists:', $className);
00130
00131 if (!ClassUtils::isInstanceOf($className, 'DAOConnected'))
00132 $this->error('class must implement DAOConnected interface:', $className);
00133
00134 $this->oqlObject->setDao(
00135 call_user_func(array($className, 'dao'))
00136 );
00137
00138 } else
00139 $this->error("expecting 'from' clause");
00140
00141 return self::WHERE_STATE;
00142 }
00143
00144 private function whereState()
00145 {
00146 if ($this->checkKeyword($this->tokenizer->peek(), 'where')) {
00147 $this->tokenizer->next();
00148
00149 $this->oqlObject->where(
00150 OqlWhereParser::create()->
00151 setTokenizer($this->tokenizer)->
00152 parse()
00153 );
00154 }
00155
00156 return self::GROUP_BY_STATE;
00157 }
00158
00159 private function groupByState()
00160 {
00161 if ($this->checkKeyword($this->tokenizer->peek(), 'group by')) {
00162 $this->tokenizer->next();
00163
00164 $this->oqlObject->addGroupBy(
00165 OqlGroupByParser::create()->
00166 setTokenizer($this->tokenizer)->
00167 parse()
00168 );
00169 }
00170
00171 return self::ORDER_BY_STATE;
00172 }
00173
00174 private function orderByState()
00175 {
00176 if ($this->checkKeyword($this->tokenizer->peek(), 'order by')) {
00177 $this->tokenizer->next();
00178
00179 $this->oqlObject->addOrderBy(
00180 OqlOrderByParser::create()->
00181 setTokenizer($this->tokenizer)->
00182 parse()
00183 );
00184 }
00185
00186 return self::HAVING_STATE;
00187 }
00188
00189 private function havingState()
00190 {
00191 if ($this->checkKeyword($this->tokenizer->peek(), 'having')) {
00192 $this->tokenizer->next();
00193
00194 $this->oqlObject->addHaving(
00195 OqlHavingParser::create()->
00196 setTokenizer($this->tokenizer)->
00197 parse()
00198 );
00199 }
00200
00201 return self::LIMIT_STATE;
00202 }
00203
00204 private function limitState()
00205 {
00206 if ($this->checkKeyword($this->tokenizer->peek(), 'limit')) {
00207 $this->tokenizer->next();
00208
00209 $token = $this->tokenizer->next();
00210 if (
00211 $this->checkToken($token, OqlToken::NUMBER)
00212 || $this->checkToken($token, OqlToken::SUBSTITUTION)
00213 ) {
00214 $this->oqlObject->setLimit(
00215 $this->makeQueryParameter($token)
00216 );
00217
00218 } else {
00219 $this->error("expecting 'limit' expression");
00220 }
00221 }
00222
00223 return self::OFFSET_STATE;
00224 }
00225
00226 private function offsetState()
00227 {
00228 if ($this->checkKeyword($this->tokenizer->peek(), 'offset')) {
00229 $this->tokenizer->next();
00230
00231 $token = $this->tokenizer->next();
00232 if (
00233 $this->checkToken($token, OqlToken::NUMBER)
00234 || $this->checkToken($token, OqlToken::SUBSTITUTION)
00235 ) {
00236 $this->oqlObject->setOffset(
00237 $this->makeQueryParameter($token)
00238 );
00239
00240 } else {
00241 $this->error("expecting 'offset' expression");
00242 }
00243 }
00244
00245 if ($token = $this->tokenizer->peek())
00246 $this->error('unexpected:', $this->getTokenValue($token, true));
00247
00248 return self::FINAL_STATE;
00249 }
00250 }
00251 ?>