Esempio n. 1
0
File: mysql.php Progetto: milkae/Php
 public function query($sql, $params = null, $flags = 0, $wantFields = null, $offset = 0, $limit = 0)
 {
     $link = $this->link;
     $handler = $this->dataHandler;
     $wantFields = array_flip($wantFields);
     if ($params) {
         $offs = 0;
         foreach ($params as $p) {
             $i = strpos($sql, '?', $offs);
             if ($i === FALSE) {
                 return 'Too many parameters supplied for the query';
             }
             $d =& $p['data'];
             if (isset($p['file'])) {
                 $fn = $p['file'];
                 if (!preg_match('/^[0-9a-z\\.\\-]+$/i', $fn)) {
                     return 'Illegal file name';
                 }
                 $d = file_get_contents($this->path . '/' . $p['file']);
             }
             if ($p['type'] == 'b') {
                 $d = 'X\'' . bin2hex($d) . '\'';
             } else {
                 if ($p['type'] == 's') {
                     $d = '\'' . mysqli_real_escape_string($link, $p['data']) . '\'';
                 } else {
                     $d = $d . '';
                 }
             }
             $sql = substr_replace($sql, $d, $i, 1);
             $offs = $i + strlen($d);
         }
     }
     $sqlLen = strlen($sql);
     if ($sqlLen > 0x80000) {
         $t = MySQLQuery::SimpleQuery($link, 'SHOW VARIABLES LIKE "max_allowed_packet"', TRUE);
         if (!$t) {
             throw new Exception("Query is very large ({$sqlLen} bytes). Failed to read the value of 'max_allowed_packed' MySQL variable");
         }
         if ($sqlLen >= $t[0][1]) {
             throw new Exception("Length of the query ({$sqlLen} bytes) is larger than 'max_allowed_packet' variable ({$t[0][1]} bytes) in MySQL configuration file.");
         }
     }
     $t = microtime(TRUE);
     if (!$link->multi_query($sql)) {
         throw new Exception($link->error);
     }
     $extime = microtime(TRUE) - $t;
     $affRows = $link->affected_rows;
     $results = array();
     $noData = $flags & QUERY_ONLY_FIELDS ? TRUE : FALSE;
     $hashing = $flags & QUERY_WITH_HASHING ? TRUE : FALSE;
     $totalRows = $totalSize = 0;
     $warning = '';
     do {
         if (!($result = $link->use_result())) {
             continue;
         }
         $res = array();
         $flds = array();
         $resRowCnt = 0;
         foreach ($result->fetch_fields() as $f) {
             $flds[] = MySQLQuery::GetFieldParams($f);
         }
         if ($wantFields) {
             $flds = array_intersect_key($flds, $wantFields);
         }
         if ($handler && ($q = call_user_func_array(array($handler, 'handleResultStarted'), array(&$flds)))) {
             $warning = $q;
         }
         while (!$warning && !$noData) {
             while ($row = $result->fetch_row()) {
                 if ($offset > 0) {
                     $offset--;
                     continue;
                 }
                 if ($this->maxRows > 0 && ++$totalRows > $this->maxRows) {
                     $warning = "Query aborted: {$this->maxRows} record limit has been reached.";
                     break;
                 } else {
                     if ($wantFields) {
                         $row = array_intersect_key($row, $wantFields);
                     }
                     foreach ($row as $i => &$c) {
                         if ($c === NULL || $c === '') {
                             continue;
                         }
                         $totalSize += strlen($c);
                         if ($hashing) {
                             if ($flds[$i]['binary']) {
                                 $c = array('label' => 'Binary', 'hash' => md5($c));
                             } else {
                                 if ($this->maxCellSize > 0 && strlen($c) > $this->maxCellSize) {
                                     $c = array('label' => 'Large', 'hash' => md5($c));
                                 }
                             }
                         }
                     }
                     if ($this->maxDataSize > 0 && $totalSize > $this->maxDataSize) {
                         $warning = "Query aborted: {$this->maxDataSize} megabyte limit has been reached.";
                         break;
                     } else {
                         if ($handler) {
                             if ($q = call_user_func_array(array($handler, 'handleRecord'), array(&$row))) {
                                 $warning = $q;
                                 break;
                             }
                         } else {
                             $res[] = $row;
                         }
                     }
                     if (++$resRowCnt == $limit) {
                         break;
                     }
                 }
             }
             break;
         }
         $result->free();
         $a = array('data' => $handler ? NULL : $res, 'fields' => $flds, 'rowCount' => $resRowCnt);
         if ($flags & QUERY_CALC_FOUND_ROWS) {
             $t = MySQLQuery::SimpleQuery($link, 'SELECT FOUND_ROWS()', TRUE);
             $a['calcFoundRows'] = (int) $t[0][0];
         }
         if ($handler) {
             call_user_func_array(array($handler, 'handleResultEnded'), array(&$a));
         }
         $results[] = $a;
     } while ($link->more_results() && $link->next_result());
     if ($flags & QUERY_WITH_FIELD_DETAILS) {
         $cols = array();
         foreach ($results as &$r) {
             foreach ($r['fields'] as &$f) {
                 if (!($t = $f['table'])) {
                     continue;
                 }
                 $c =& $cols[$t];
                 if (!isset($c)) {
                     $c = MySQLQuery::SimpleQuery($link, 'SHOW COLUMNS FROM ' . ($f['db'] ? '`' . $f['db'] . '`.' : '') . "`{$t}`");
                     if (!$c) {
                         $f['table'] = '';
                         continue;
                     }
                 }
                 foreach ($c as &$q) {
                     if ($q['Field'] != $f['field']) {
                         continue;
                     }
                     if ($f['type'] == 'set' || $f['type'] == 'enum') {
                         $f['values'] = str_replace("','", ",", preg_replace("/(enum|set)\\('(.+?)'\\)/", "\\2", $q['Type']));
                     } else {
                         $f['values'] = '';
                     }
                     $f['default'] = $q['Default'];
                     break;
                 }
             }
         }
     }
     $a = array('results' => $results, 'affectedRows' => $affRows < 0 ? 0 : $affRows, 'execTime' => sprintf("%.3f", $extime));
     if ($handler) {
         call_user_func_array(array($handler, 'handleQueryEnded'), array(&$a));
     }
     if (is_string($warning)) {
         $a['warning'] = $warning;
     }
     if ($flags & QUERY_WITH_INSERT_ID) {
         $t = MySQLQuery::SimpleQuery($link, 'SELECT LAST_INSERT_ID()', TRUE);
         $a['lastInsertId'] = $t[0][0];
     }
     return $a;
 }