Пример #1
0
Файл: MySQL.php Проект: jasny/Q
 /**
  * Excecute query.
  * Returns DB_MySQL_Result for 'SELECT', 'SHOW', etc queries, returns new id for 'INSERT' query, returns TRUE for other
  * 
  * @param mixed $statement  String or a query statement object
  * @param array $args       Arguments to be parsed into the query on placeholders
  * @return DB_MySQL_Result
  */
 public function query($statement, $args = array())
 {
     // Get statement out of object
     if (is_object($statement)) {
         $source = $statement->getBaseTable();
         $statement = $statement->getStatement();
     }
     // Parse arguments
     if (func_num_args() > 2) {
         $args = func_get_args();
         array_shift($args);
     }
     if (!empty($args)) {
         $statement = $this->parse($statement, $args);
     }
     // Extract (child) subqueries for cascading data
     $tree = $this->sqlSplitter->extractTree($statement);
     // Execute query statement
     $result = $this->nativeQuery($tree[0]);
     if (!$result) {
         $match = null;
         if ($this->native->errno == 1451 && preg_match('/^Cannot delete or update a parent row: a foreign key constraint fails \\(`.*?`\\.`(.*?)`, CONSTRAINT `.*?` FOREIGN KEY \\(`(.*?)`\\) REFERENCES `(.*?)` \\(`(.*?)`\\)\\)/', $this->native->error, $match)) {
             throw new DB_ConstraintException($this->native->error, $this->native->errno, $match[3], $match[4], $match[1], $match[2]);
         }
         throw new DB_QueryException($this->native->error, $tree[0], $this->native->errno);
     }
     // Return value if query did not return a mysql_result object
     if (!is_object($result)) {
         return $this->native->insert_id ? $this->native->insert_id : $result;
     }
     // Create result object
     $class = count($tree) > 1 ? self::$classes['Result_Tree'] : self::$classes['Result'];
     while ($field = $result->fetch_field()) {
         if ($field->name === self::NESTED_LEFT) {
             $class = self::$classes['Result_NestedSet'];
             break;
         }
     }
     load_class($class);
     $ob = new $class(isset($source) ? $source : $this, $result, $statement);
     // If statement has any childqueries, create tree result
     if (count($tree) > 1) {
         for ($i = 1, $m = count($tree); $i < $m; $i++) {
             // array(index, statement, format, filter(bool))
             $child_result = $tree[$i][3] ? $this->query($tree[$i][1], $ob->getColumn($tree[$i][0])) : $this->query($tree[$i][1]);
             $ob->addChild($ob->getFieldIndex($tree[$i][0]), $child_result, $tree[$i][2]);
         }
     }
     // Pass base table definition if any and return result
     return $ob;
 }
Пример #2
0
 /**
  * Create query to update rows of a table.
  * 
  * @param string       $table
  * @param array        $columns   Assasioted array as (column=>value, ...)
  * @param string|array $criteria  WHERE expression or array(column=>value, ...)
  * @param int          $flags     Options as bitset
  * @return string
  */
 public static function buildUpdateStatement($table = null, $columns = null, $criteria = null, $flags = 0)
 {
     $sql_set = array();
     foreach ($columns as $column => &$value) {
         $sql_set[] = self::quoteIdentifier($column) . '=' . self::quote($value);
     }
     if (!is_scalar($criteria)) {
         array_walk($criteria, function (&$value, $key) use($table) {
             $value = DB_MySQL_SQLSplitter::buildWhere(DB_MySQL_SQLSplitter::makeIdentifier($table, $key, null, $flags), $value);
         });
         $criteria = join($flags & DB::GLUE_OR ? ' OR ' : ' AND ', $criteria);
     }
     return "UPDATE" . (isset($table) ? ' ' . self::quoteIdentifier($table, $flags) : null) . (!empty($sql_set) ? " SET " . join(', ', $sql_set) : null) . (isset($criteria) ? " WHERE {$criteria}" : null);
 }