00001 <?php
00002
00007 class MSQL
00008 {
00012 var $db;
00013
00017 var $distinct;
00018
00022 var $columns;
00023
00027 var $tables;
00028
00032 var $where;
00033
00037 var $groupBy;
00038
00042 var $having;
00043
00047 var $orderBy;
00048
00052 var $join;
00053
00057 var $parameters;
00058
00062 var $command;
00063
00067 var $range;
00068
00072 var $bind;
00073
00088 function __construct($columns = '', $tables = '', $where = '', $orderBy = '', $groupBy = '', $having = '')
00089 {
00090 $this->Clear();
00091 $this->SetColumns($columns);
00092 $this->SetTables($tables);
00093 $this->SetWhere($where);
00094 $this->SetGroupBy($groupBy);
00095 $this->SetHaving($having);
00096 $this->SetOrderBy($orderBy);
00097 $this->join = null;
00098 $this->parameters = null;
00099 $this->range = null;
00100 $this->db = null;
00101 $this->bind = false;
00102 $this->stmt = NULL;
00103 }
00104
00115 private function getTokens1($string, &$array)
00116 {
00117 $tok = strtok($string, ",");
00118
00119 while ($tok)
00120 {
00121 $tok = trim($tok);
00122 $array[$tok] = $tok;
00123 $tok = strtok(",");
00124 }
00125 }
00126
00137 private function getTokens($string, &$array)
00138 {
00139 if ($string == '')
00140 return;
00141
00142 $source = $string . ',';
00143 $tok = '';
00144 $l = strlen($source);
00145 $can = 0;
00146
00147 for ($i = 0; $i < $l; $i++)
00148 {
00149 $c = $source{$i};
00150
00151 if (!$can)
00152 {
00153 if ($c == ',')
00154 {
00155 $tok = trim($tok);
00156 $array[$tok] = $tok;
00157 $tok = '';
00158 }
00159 else
00160 {
00161 $tok .= $c;
00162 }
00163 }
00164 else
00165 {
00166 $tok .= $c;
00167 }
00168
00169 if ($c == '(')
00170 $can++;
00171
00172 if ($c == ')')
00173 $can--;
00174 }
00175
00176 }
00177
00185 private function getJoin()
00186 {
00187 global $MIOLO;
00188 $MIOLO->Uses('database/' . $this->db->system . '/msqljoin.class');
00189 $className = "{$this->db->system}SqlJoin";
00190 $join = new $className();
00191 $join->_sqlJoin($this);
00192 }
00193
00203 function SetDb($db)
00204 {
00205 $this->db = $db;
00206 }
00207
00218 function SetColumns($string, $distinct = false)
00219 {
00220 $this->getTokens($string, $this->columns);
00221 $this->distinct = $distinct;
00222 }
00223
00233 function SetTables($string)
00234 {
00235 $this->getTokens($string, $this->tables);
00236 }
00237
00247 function SetGroupBy($string)
00248 {
00249 $this->getTokens($string, $this->groupBy);
00250 }
00251
00261 function SetOrderBy($string)
00262 {
00263 $this->getTokens($string, $this->orderBy);
00264 }
00265
00275 function SetWhere($string)
00276 {
00277 $this->where .= (($this->where != '') && ($string != '') ? " and " : "") . $string;
00278 }
00279
00289 function SetWhereAnd($string)
00290 {
00291 $this->where .= (($this->where != '') && ($string != '') ? " and " : "") . $string;
00292 }
00293
00303 function SetWhereOr($string)
00304 {
00305 $this->where .= (($this->where != '') && ($string != '') ? " or " : "") . $string;
00306 }
00307
00317 function SetHaving($string)
00318 {
00319 $this->having .= (($this->having != '') && ($string != '') ? " and " : "") . $string;
00320 }
00321
00331 function SetHavingAnd($string)
00332 {
00333 $this->having .= (($this->having != '') && ($string != '') ? " and " : "") . $string;
00334 }
00335
00345 function SetHavingOr($string)
00346 {
00347 $this->having .= (($this->having != '') && ($string != '') ? " or " : "") . $string;
00348 }
00349
00362 function SetJoin($table1, $table2, $cond, $type = 'INNER')
00363 {
00364 $this->join[] = array
00365 (
00366 $table1,
00367 $table2,
00368 $cond,
00369 $type
00370 );
00371 }
00372
00384 function SetLeftJoin($table1, $table2, $cond)
00385 {
00386 $this->SetJoin($table1, $table2, $cond, 'LEFT');
00387 }
00388
00400 function SetRightJoin($table1, $table2, $cond)
00401 {
00402 $this->SetJoin($table1, $table2, $cond, 'RIGHT');
00403 }
00404
00414 function Bind($parameters = null)
00415 {
00416 $this->bind = true;
00417 $this->SetParameters($parameters);
00418 }
00419
00429 function Prepare($parameters = null)
00430 {
00431 global $MIOLO;
00432
00433 if ($this->bind)
00434 return;
00435
00436 if (!$parameters)
00437 return;
00438
00439 if (!is_array($parameters))
00440 {
00441 $parameters = array($parameters);
00442 }
00443
00444 $prepared = '';
00445 $sqlText = $this->command;
00446 $i = 0;
00447
00448 while (true)
00449 {
00450 $pos = strpos($sqlText, '?');
00451
00452 if ($pos == false)
00453 {
00454 $prepared .= $sqlText;
00455 break;
00456 }
00457 else
00458 {
00459 if ($pos > 0)
00460 {
00461 $prepared .= substr($sqlText, 0, $pos);
00462 }
00463
00464 if (substr($parameters[$i], 0, 1) == ':')
00465 {
00466 $prepared .= substr($parameters[$i++], 1);
00467 }
00468 else
00469 {
00470 $prepared .= is_null($p=$parameters[$i++]) ? 'NULL' : "'" . str_replace("'", "''", $p) . "'";
00471
00472 }
00473
00474 $sqlText = substr($sqlText, $pos + 1);
00475 }
00476 }
00477
00478 $MIOLO->Assert($i == count($parameters), "SQL PREPARE: Parâmetros inconsistentes! SQL: $sqlText");
00479 $this->command = $prepared;
00480 return $prepared;
00481 }
00482
00492 function Insert($parameters = null)
00493 {
00494 $sqlText = 'INSERT INTO ' . implode($this->tables, ',') . ' ( ' . implode($this->columns, ',') . ' ) VALUES ( ';
00495
00496 for ($i = 0; $i < count($this->columns); $i++)
00497 $par[] = '?';
00498
00499 $sqlText .= implode($par, ',') . ' )';
00500 $this->command = $sqlText;
00501
00502 if (isset($parameters))
00503 $this->SetParameters($parameters);
00504
00505 $this->Prepare($this->parameters);
00506 return $this->command;
00507 }
00508
00518 function InsertFrom($sql)
00519 {
00520 $sqlText = 'INSERT INTO ' . implode($this->tables, ',') . ' ( ' . implode($this->columns, ',') . ' ) ';
00521 $sqlText .= $sql;
00522 $this->command = $sqlText;
00523 return $this->command;
00524 }
00525
00535 function Delete($parameters = null)
00536 {
00537 global $MIOLO;
00538 $sqlText = 'DELETE FROM ' . implode($this->tables, ',');
00539 $MIOLO->Assert($this->where != '', "SQL DELETE: Condição não informada!");
00540 $sqlText .= ' WHERE ' . $this->where;
00541 $this->command = $sqlText;
00542
00543 if (isset($parameters))
00544 $this->SetParameters($parameters);
00545
00546 $this->Prepare($this->parameters);
00547 return $this->command;
00548 }
00549
00559 function Update($parameters = null)
00560 {
00561 global $MIOLO;
00562 $sqlText = 'UPDATE ' . implode($this->tables, ',') . ' SET ';
00563
00564 foreach ($this->columns as $c)
00565 $par[] = $c . '= ?';
00566
00567 $sqlText .= implode($par, ',');
00568 $MIOLO->Assert($this->where != '', "SQL UPDATE: Condição não informada!");
00569 $sqlText .= ' WHERE ' . $this->where;
00570 $this->command = $sqlText;
00571
00572 if (isset($parameters))
00573 $this->SetParameters($parameters);
00574
00575 $this->Prepare($this->parameters);
00576 return $this->command;
00577 }
00578
00588 function Select($parameters = null)
00589 {
00590 if ($this->join != NULL)
00591 $this->getJoin();
00592
00593 $sqlText = 'SELECT ' . ($this->distinct ? 'DISTINCT ' : '') . implode($this->columns, ',');
00594
00595 if ($this->tables != '')
00596 {
00597 $sqlText .= ' FROM ' . implode($this->tables, ',');
00598 }
00599
00600 if ($this->where != '')
00601 {
00602 $sqlText .= ' WHERE ' . $this->where;
00603 }
00604
00605 if ($this->groupBy != '')
00606 {
00607 $sqlText .= ' GROUP BY ' . implode($this->groupBy, ',');
00608 }
00609
00610 if ($this->having != '')
00611 {
00612 $sqlText .= ' HAVING ' . $this->having;
00613 }
00614
00615 if ($this->orderBy != '')
00616 {
00617 $sqlText .= ' ORDER BY ' . implode($this->orderBy, ',');
00618 }
00619
00620 $this->command = $sqlText;
00621
00622 if (isset($parameters))
00623 $this->SetParameters($parameters);
00624
00625 $this->Prepare($this->parameters);
00626 return $this->command;
00627 }
00628
00636 function Clear()
00637 {
00638 $this->columns = '';
00639 $this->tables = '';
00640 $this->where = '';
00641 $this->groupBy = '';
00642 $this->having = '';
00643 $this->orderBy = '';
00644 $this->parameters = null;
00645 $this->command = '';
00646 }
00647
00655 function SetParameters()
00656 {
00657 $numargs = func_num_args();
00658
00659 if ($numargs == 1)
00660 {
00661 if (!is_array($parameters = func_get_arg(0)))
00662 {
00663 if ($parameters == null)
00664 return;
00665
00666 $parameters = array($parameters);
00667 }
00668 }
00669 else
00670 {
00671 $parameters = func_get_args();
00672 }
00673
00674 $this->parameters = $parameters;
00675 }
00676
00686 function addParameter($value)
00687 {
00688 $this->parameters[] = $value;
00689 }
00690
00698 function SetRange()
00699 {
00700 $numargs = func_num_args();
00701
00702 if ($numargs == 1)
00703 {
00704 $this->range = func_get_arg(0);
00705 }
00706 elseif ($numargs == 2)
00707 {
00708 $page = func_get_arg(0);
00709 $rows = func_get_arg(1);
00710 $this->range = new QueryRange($page, $rows);
00711 }
00712 }
00713
00721 function setOffset($offset, $rows)
00722 {
00723 if (!$this->range)
00724 {
00725 $this->range = new MQueryRange(0,0);
00726 }
00727 $this->range->offset = $offset;
00728 $this->range->rows = $rows;
00729 }
00730
00741 function FindStr($target, $source)
00742 {
00743 $l = strlen($target);
00744 $lsource = strlen($source);
00745 $pos = 0;
00746
00747 while (($pos < $lsource) && (!$fim))
00748 {
00749 if ($source[$pos] == "(")
00750 {
00751 $p = $this->FindStr(")", substr($source, $pos + 1));
00752
00753 if ($p > 0)
00754 $pos += $p + 3;
00755 }
00756
00757 $fim = ($target == substr($source, $pos, $l));
00758
00759 if (!$fim)
00760 $pos++;
00761 }
00762
00763 return ($fim ? $pos : -1);
00764 }
00765
00777 function ParseSqlCommand(&$cmd, $clause, $delimiters)
00778 {
00779 if (substr($cmd, 0, strlen($clause)) != $clause)
00780 return false;
00781
00782 $cmd = substr($cmd, strlen($clause));
00783 $n = count($delimiters);
00784 $i = 0;
00785 $pos = -1;
00786
00787 while (($pos < 0) && ($i < $n))
00788 $pos = $this->FindStr($delimiters[$i++], $cmd);
00789
00790 if ($pos > 0)
00791 {
00792 $r = substr($cmd, 0, $pos);
00793 $cmd = substr($cmd, $pos);
00794 }
00795
00796 return $r;
00797 }
00798
00808 function CreateFrom($sqltext, $params=array())
00809 {
00810 $this->command = $sqltext;
00811 $this->setParameters($params);
00812 $sqltext = trim($sqltext) . " #";
00813 $sqltext = preg_replace("/(?i)select /", "select ", $sqltext);
00814 $sqltext = preg_replace("/(?i) from /", " from ", $sqltext);
00815 $sqltext = preg_replace("/(?i) where /", " where ", $sqltext);
00816 $sqltext = preg_replace("/(?i) order by /", " order by ", $sqltext);
00817 $sqltext = preg_replace("/(?i) group by /", " group by ", $sqltext);
00818 $sqltext = preg_replace("/(?i) having /", " having ", $sqltext);
00819 $this->SetColumns($this->ParseSqlCommand($sqltext, "select", array("from")));
00820
00821 if ($this->FindStr('JOIN', $sqltext) < 0)
00822 {
00823 $this->SetTables($this->ParseSqlCommand($sqltext, "from", array("where", "group by", "order by", "#")));
00824 }
00825 else
00826 {
00827 $this->join = $this->ParseSqlCommand($sqltext, "from", array("where", "group by", "order by", "#"));
00828 }
00829
00830 $this->SetWhere($this->ParseSqlCommand($sqltext, "where", array("group by", "order by", "#")));
00831 $this->SetGroupBy($this->ParseSqlCommand($sqltext, "group by", array("having", "order by", "#")));
00832 $this->SetHaving($this->ParseSqlCommand($sqltext, "having", array("order by", "#")));
00833 $this->SetOrderBy($this->ParseSqlCommand($sqltext, "order by", array("#")));
00834 }
00835 }
00836 ?>