[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 %name VTQL_Parser 2 //%left EQ LT GT LTE GTE NE IN LIKE. 3 4 sql ::= select_statement. 5 select_statement ::= SELECT(SEL) selectcol_list FRM(F) table_list where_condition order_clause limit_clause end_stmt. { 6 if(SEL){ 7 $this->out['select'] = SEL; 8 } 9 if(F){ 10 $this->out['from'] = F ; 11 } 12 if(SEMI){ 13 $this->out['semi_colon'] = SEMI; 14 } 15 if($this->out['select']){ 16 $this->buildSelectStmt($this->out); 17 } 18 } 19 selectcol_list ::= selectcolumn_exp COLUMNNAME(CNAME). { 20 $this->out['column_list'][] = CNAME; 21 } 22 selectcol_list ::= ASTERISK(A). { 23 $this->out['column_list'][] = A; 24 } 25 selectcol_list ::= COUNT PARENOPEN ASTERISK PARENCLOSE. { 26 $this->out['column_list'][] = 'count(*)'; 27 } 28 selectcolumn_exp ::= selectcol_list COMMA. 29 selectcolumn_exp ::= . 30 table_list ::= TABLENAME(TNAME). { 31 if(!in_array($this->out["column_list"], "*") && !in_array(array_map(strtolower, $this->out["column_list"]), "count(*)")){ 32 if(!in_array("id",$this->out["column_list"])){ 33 $this->out["column_list"][] = "id"; 34 } 35 } 36 $moduleName = TNAME; 37 if(!$moduleName){ 38 $this->syntax_error = true; 39 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "There is an syntax error in query"); 40 } 41 global $adb; 42 $handler = vtws_getModuleHandlerFromName($moduleName,$this->user); 43 $objectMeta = $handler->getMeta(); 44 $this->out['moduleName'] = $moduleName; 45 $this->out['tableName'] = implode(',',$objectMeta->getEntityTableList()); 46 } 47 where_condition ::= WHERE(Wh) condition. 48 where_condition ::= . 49 condition ::= expr_set expr(E). 50 expr_set ::= condition LOGICAL_AND(LAND). { 51 $this->out['where_condition']['operators'][] = LAND; 52 } 53 expr_set ::= condition LOGICAL_OR(LOR). { 54 $this->out['where_condition']['operators'][] = LOR; 55 } 56 expr_set ::= . 57 expr ::= COLUMNNAME(ECNAME) logical_term valuelist.{ 58 $this->out['columnDone']=true; 59 $this->out['where_condition']['column_names'][] = ECNAME; 60 if(strcmp(ECNAME, 'id')===0){ 61 $prev = $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1]; 62 if(is_array($prev)){ 63 $new = array(); 64 foreach($prev as $ind=>$val){ 65 $val = trim($val,'\'"'); 66 $value = vtws_getIdComponents($val); 67 $new[] = $value[1]; 68 } 69 $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1] = $new; 70 }else{ 71 $prev = trim($prev,'\'"'); 72 $value = vtws_getIdComponents($prev); 73 if(strcasecmp($this->out['where_condition']['column_operators'][sizeof($this->out['where_condition']['column_operators'])-1],'like')===0){ 74 $value[1] = "'".$value[1]."'"; 75 } 76 $this->out['where_condition']['column_values'][sizeof($this->out['where_condition']['column_values'])-1] = $value[1]; 77 } 78 } 79 } 80 valuelist ::= PARENOPEN valueref PARENCLOSE. 81 valuelist ::= valueref. 82 valueref ::= value_exp VALUE(VAL).{ 83 $length = sizeof($this->out['where_condition']['column_values']); 84 $pos = $length - 1; 85 if($pos < 0){ 86 $pos = 0; 87 } 88 if(strcasecmp($this->out['where_condition']['column_operators'][$pos],"in")===0 && 89 !empty($this->out['where_condition']['column_values'][$pos]) && !$this->out['columnDone']){ 90 if(!is_array($this->out['where_condition']['column_values'][$pos])){ 91 $prev = $this->out['where_condition']['column_values'][$pos]; 92 $this->out['where_condition']['column_values'][$pos] = array(); 93 $this->out['where_condition']['column_values'][$pos][] = $prev; 94 } 95 $this->out['where_condition']['column_values'][$pos][] = VAL; 96 }else{ 97 $this->out['columnDone'] = false; 98 $this->out['where_condition']['column_values'][] = VAL; 99 } 100 } 101 value_exp ::= valueref COMMA. 102 value_exp ::= . 103 logical_term ::= EQ. { 104 $this->out['where_condition']['column_operators'][] = '='; 105 } 106 logical_term ::= LT. { 107 $this->out['where_condition']['column_operators'][] = '<'; 108 } 109 logical_term ::= GT. { 110 $this->out['where_condition']['column_operators'][] = '>'; 111 } 112 logical_term ::= LTE. { 113 $this->out['where_condition']['column_operators'][] = '<='; 114 } 115 logical_term ::= GTE. { 116 $this->out['where_condition']['column_operators'][] = '>='; 117 } 118 logical_term ::= NE. { 119 $this->out['where_condition']['column_operators'][] = '!='; 120 } 121 logical_term ::= IN. { 122 $this->out['where_condition']['column_operators'][] = 'IN'; 123 } 124 logical_term ::= LIKE. { 125 $this->out['where_condition']['column_operators'][] = 'LIKE'; 126 } 127 order_clause ::= ORDERBY column_group clause. 128 order_clause ::= . 129 column_group ::= column_list . 130 column_list ::= column_exp COLUMNNAME(CN). { 131 $this->out['orderby'][] = CN; 132 } 133 column_exp ::= column_list COMMA. 134 column_exp ::= . 135 clause ::= ASC. { 136 $this->out['sortOrder'] = 'ASC'; 137 } 138 clause ::= DESC. { 139 $this->out['sortOrder'] = 'DESC'; 140 } 141 clause ::= . 142 limit_clause ::= LIMIT limit_set. 143 limit_clause ::= . 144 limit_set ::= VALUE(LV). { 145 $this->out['limit'][] = LV; 146 } 147 limit_set ::= VALUE(LV) COMMA VALUE(LV2). { 148 $this->out['limit'][] = LV; 149 $this->out['limit'][] = LV2; 150 } 151 end_stmt ::= SEMICOLON(SEMI). { 152 global $adb; 153 if(!$this->out['meta']){ 154 $module = $this->out['moduleName']; 155 $handler = vtws_getModuleHandlerFromName($module,$this->user); 156 $objectMeta = $handler->getMeta(); 157 $this->out['meta'] = $objectMeta; 158 $meta = $this->out['meta']; 159 $fieldcol = $meta->getFieldColumnMapping(); 160 $columns = array(); 161 if(in_array($this->out['column_list'],'*')){ 162 $columns = array_values($fieldcol); 163 }else if( !in_array(array_map(strcmp, $this->out['column_list']),'count(*)')){ 164 foreach($this->out['column_list'] as $ind=>$field){ 165 $columns[] = $fieldcol[$field]; 166 } 167 } 168 if($this->out['where_condition']){ 169 foreach($this->out['where_condition']['column_names'] as $ind=>$field){ 170 $columns[] = $fieldcol[$field]; 171 } 172 } 173 $tables = $this->getTables($this->out, $columns); 174 if(!in_array($objectMeta->getEntityBaseTable(), $tables)){ 175 $tables[] = $objectMeta->getEntityBaseTable(); 176 } 177 $defaultTableList = $objectMeta->getEntityDefaultTableList(); 178 foreach($defaultTableList as $tableName){ 179 if(!in_array($tableName,$tables)){ 180 array_push($tables,$tableName); 181 } 182 } 183 $firstTable = $objectMeta->getEntityBaseTable(); 184 $tabNameIndex = $objectMeta->getEntityTableIndexList(); 185 $firstIndex = $tabNameIndex[$firstTable]; 186 foreach($tables as $ind=>$table){ 187 if($firstTable!=$table){ 188 if(!isset($tabNameIndex[$table]) && $table == "vtiger_crmentity"){ 189 $this->out['defaultJoinConditions'] = $this->out['defaultJoinConditions']." LEFT JOIN $table ON $firstTable.$firstIndex=$table.crmid"; 190 }else{ 191 $this->out['defaultJoinConditions'] = $this->out['defaultJoinConditions']." LEFT JOIN $table ON $firstTable.$firstIndex=$table.{$tabNameIndex[$table]}"; 192 } 193 }else{ 194 $this->out['tableName'] = $table; 195 } 196 } 197 } 198 } 199 %include_class { 200 /* 201 add this rule to add parenthesis support. 202 condition ::= PARENOPEN expr_set expr(E) PARENCLOSE. 203 sample format(for contacts) for generated sql object 204 Array ( 205 [column_list] => c4,c3,c2,c1 206 [tableName] => vtiger_crmentity,vtiger_contactdetails,vtiger_contactaddress,vtiger_contactsubdetails,vtiger_contactscf,vtiger_customerdetails 207 [where_condition] => Array ( 208 [column_operators] => Array ( 209 [0] => = 210 [1] => = 211 [2] => = 212 ) 213 [column_names] => Array ( 214 [0] => c1 215 [1] => c2 216 [2] => c3 217 ) 218 [column_values] => Array ( 219 [0] => 'llet me' 220 [1] => 45 221 [2] => -1 222 ) 223 //TO BE DONE 224 [grouping] => Array ( 225 [0] => Array ( 226 [0] => 1 227 [1] => 2 228 ) 229 ) 230 [operators] => Array ( 231 [0] => and 232 [1] => or 233 ) 234 ) 235 [orderby] => Array ( 236 [0] => c4 237 [1] => c5 238 ) 239 [select] => SELECT 240 [from] => from 241 [semi_colon] => ; 242 )*/ 243 private $out; 244 public $lex; 245 private $success ; 246 private $query ; 247 private $error_msg; 248 private $syntax_error; 249 private $user; 250 function __construct($user, $lex,$out){ 251 if(!is_array($out)){ 252 $out = array(); 253 } 254 $this->out = &$out; 255 $this->lex = $lex; 256 $this->success = false; 257 $this->error_msg =''; 258 $this->query = ''; 259 $this->syntax_error = false; 260 $this->user = $user; 261 } 262 263 function __toString(){ 264 return $this->value.""; 265 } 266 function buildSelectStmt($sqlDump){ 267 $meta = $sqlDump['meta']; 268 $fieldcol = $meta->getFieldColumnMapping(); 269 $columnTable = $meta->getColumnTableMapping(); 270 $this->query = 'SELECT '; 271 if(in_array($sqlDump['column_list'],'*')){ 272 $i=0; 273 foreach($fieldcol as $field=>$col){ 274 if($i===0){ 275 $this->query = $this->query.$columnTable[$col].'.'.$col; 276 $i++; 277 }else{ 278 $this->query = $this->query.','.$columnTable[$col].'.'.$col; 279 } 280 } 281 }else if(in_array($sqlDump['column_list'],'count(*)')){ 282 $this->query = $this->query." COUNT(*)"; 283 }else{ 284 $i=0; 285 foreach($sqlDump['column_list'] as $ind=>$field){ 286 if(!$fieldcol[$field]){ 287 throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to access '.$field.' attribute denied."); 288 } 289 if($i===0){ 290 $this->query = $this->query.$columnTable[$fieldcol[$field]].'.'.$fieldcol[$field]; 291 $i++; 292 }else{ 293 $this->query = $this->query.','.$columnTable[$fieldcol[$field]].'.'.$fieldcol[$field]; 294 } 295 } 296 } 297 $this->query = $this->query.' FROM '.$sqlDump['tableName'].$sqlDump['defaultJoinConditions']; 298 $deletedQuery = $meta->getEntityDeletedQuery(); 299 $accessControlQuery = $meta->getEntityAccessControlQuery(); 300 $this->query = $this->query.' '.$accessControlQuery; 301 if($sqlDump['where_condition']){ 302 if((sizeof($sqlDump['where_condition']['column_names']) == 303 sizeof($sqlDump['where_condition']['column_values'])) && 304 (sizeof($sqlDump['where_condition']['column_operators']) == sizeof($sqlDump['where_condition']['operators'])+1)){ 305 $this->query = $this->query.' WHERE ('; 306 $i=0; 307 $referenceFields = $meta->getReferenceFieldDetails(); 308 $ownerFields = $meta->getOwnerFields(); 309 for(;$i<sizeof($sqlDump['where_condition']['column_values']);++$i){ 310 if(!$fieldcol[$sqlDump['where_condition']['column_names'][$i]]){ 311 throw new WebServiceException(WebServiceErrorCode::$ACCESSDENIED, "Permission to access ".$sqlDump['where_condition']['column_names'][$i]." attribute denied."); 312 } 313 $whereField = $sqlDump['where_condition']['column_names'][$i]; 314 $whereOperator = $sqlDump['where_condition']['column_operators'][$i]; 315 $whereValue = $sqlDump['where_condition']['column_values'][$i]; 316 if(in_array($whereField,array_keys($referenceFields))){ 317 if(is_array($whereValue)){ 318 foreach($whereValue as $index=>$value){ 319 if(strpos($value,'x')===false){ 320 throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect"); 321 } 322 } 323 $whereValue = array_map(array($this, 'getReferenceValue'),$whereValue); 324 }else if(strpos($whereValue,'x')!==false){ 325 $whereValue = $this->getReferenceValue($whereValue); 326 if(strcasecmp($whereOperator,'like')===0){ 327 $whereValue = "'".$whereValue."'"; 328 } 329 }else{ 330 throw new WebServiceException(WebServiceErrorCode::$INVALIDID,"Id specified is incorrect"); 331 } 332 }else if(in_array($whereField,$ownerFields)){ 333 if(is_array($whereValue)){ 334 $groupId = array_map(array($this, 'getOwner'),$whereValue); 335 }else{ 336 $groupId = $this->getOwner($whereValue); 337 if(strcasecmp($whereOperator,'like')===0){ 338 $groupId = "'$groupId'"; 339 } 340 } 341 $whereValue = $groupId; 342 } 343 if(is_array($whereValue)){ 344 $whereValue = "(".implode(',',$whereValue).")"; 345 }elseif(strcasecmp($whereOperator, 'in') === 0){ 346 $whereValue = "($whereValue)"; 347 } 348 $this->query = $this->query.$columnTable[$fieldcol[$whereField]].'.'. 349 $fieldcol[$whereField]." ".$whereOperator." ".$whereValue; 350 if($i <sizeof($sqlDump['where_condition']['column_values'])-1){ 351 $this->query = $this->query.' '; 352 $this->query = $this->query.$sqlDump['where_condition']['operators'][$i].' '; 353 } 354 } 355 }else{ 356 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "columns data inappropriate"); 357 } 358 $this->query = $this->query.")"; 359 $nextToken = ' AND '; 360 }else{ 361 if(!empty($deletedQuery)){ 362 $nextToken = " WHERE "; 363 } 364 } 365 if(strcasecmp('calendar',$this->out['moduleName'])===0){ 366 $this->query = $this->query." $nextToken activitytype='Task' AND "; 367 }elseif(strcasecmp('events',$this->out['moduleName'])===0){ 368 $this->query = $this->query."$nextToken activitytype!='Emails' AND activitytype!='Task' AND "; 369 }else if(strcasecmp('emails',$this->out['moduleName'])===0){ 370 $this->query = $this->query."$nextToken activitytype='Emails' AND "; 371 }elseif(!empty($deletedQuery)){ 372 $this->query = $this->query.$nextToken; 373 } 374 375 $this->query = $this->query.' '.$deletedQuery; 376 377 if($sqlDump['orderby']){ 378 $i=0; 379 $this->query = $this->query.' ORDER BY '; 380 foreach($sqlDump['orderby'] as $ind=>$field){ 381 if($i===0){ 382 $this->query = $this->query.$columnTable[$fieldcol[$field]].".".$fieldcol[$field]; 383 $i++; 384 }else{ 385 $this->query = $this->query.','.$columnTable[$fieldcol[$field]].".".$fieldcol[$field]; 386 } 387 } 388 if($sqlDump['sortOrder']) { 389 $this->query .= ' '.$sqlDump['sortOrder']; 390 } 391 } 392 if($sqlDump['limit']){ 393 $i=0; 394 $offset =false; 395 if(sizeof($sqlDump['limit'])>1){ 396 $offset = true; 397 } 398 $this->query = $this->query.' LIMIT '; 399 foreach($sqlDump['limit'] as $ind=>$field){ 400 if(!$offset){ 401 $field = ($field>100)? 100: $field; 402 } 403 if($i===0){ 404 $this->query = $this->query.$field; 405 $i++; 406 $offset = false; 407 }else{ 408 $this->query = $this->query.','.$field; 409 } 410 } 411 }else{ 412 $this->query = $this->query.' LIMIT 100'; 413 } 414 $this->query = $this->query.';'; 415 } 416 function getTables($sqlDump,$columns){ 417 $meta = $sqlDump['meta']; 418 $coltable = $meta->getColumnTableMapping(); 419 $tables = array(); 420 foreach($columns as $ind=>$col){ 421 $tables[$coltable[$col]] = $coltable[$col]; 422 } 423 $tables = array_keys($tables); 424 return ($tables); 425 } 426 function getReferenceValue($whereValue){ 427 $whereValue = trim($whereValue,'\'"'); 428 $whereValue = vtws_getIdComponents($whereValue); 429 $whereValue = $whereValue[1]; 430 return $whereValue; 431 } 432 function getOwner($whereValue){ 433 $whereValue = trim($whereValue,'\'"'); 434 $whereValue = vtws_getIdComponents($whereValue); 435 $whereValue = $whereValue[1]; 436 return $whereValue; 437 } 438 function isSuccess(){ 439 return $this->success; 440 } 441 function getErrorMsg(){ 442 return $this->error_msg; 443 } 444 function getQuery(){ 445 return $this->query; 446 } 447 function getObjectMetaData(){ 448 return $this->out['meta']; 449 } 450 } 451 //%token_prefix VTQL_ 452 %declare_class {class VTQL_Parser} 453 %parse_accept { 454 $this->success = true; 455 } 456 457 %parse_failure { 458 if(!$this->syntax_error){ 459 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "Parsing failed"); 460 } 461 } 462 463 %stack_overflow { 464 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, "Parser stack overflow"); 465 } 466 467 %syntax_error { 468 $synMsg = "Syntax Error on line " . $this->lex->linenum . ": token '" .$this->lex->value."' "; 469 $expect = array(); 470 foreach ($this->yy_get_expected_tokens($yymajor) as $token) { 471 $expect[] = self::$yyTokenName[$token]; 472 } 473 $synMsg =$synMsg.('Unexpected ' . $this->tokenName($yymajor) . '(' . $TOKEN 474 . '), expected one of: ' . implode(',', $expect)); 475 476 throw new WebServiceException(WebServiceErrorCode::$QUERYSYNTAX, $synMsg); 477 } 478
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |