private function sanitizeQuery($query)
 {
     $query['explainable'] = true;
     $query['params'] = (array) $query['params'];
     foreach ($query['params'] as $j => &$param) {
         $key = is_int($j) ? $j + 1 : $j;
         if (isset($query['types'][$key])) {
             // Transform the param according to the type
             $type = $query['types'][$key];
             if (is_string($type)) {
                 $type = Type::getType($type);
             }
             if ($type instanceof Type) {
                 $query['types'][$key] = $type->getBindingType();
                 $param = $type->convertToDatabaseValue($param, $this->connection->getDatabasePlatform());
             }
         }
         list($param, $explainable) = $this->sanitizeParam($param);
         if (!$explainable) {
             $query['explainable'] = false;
         }
     }
     if ($query['explainable'] && ($explanation = $this->explain($query))) {
         $query['explain'] = $explanation;
     }
     return $query;
 }
 /**
  * Initialize the all or only autoload options.
  *
  * @param bool $autoload
  */
 protected function initialize($autoload = false)
 {
     if ($this->initialized) {
         return;
     }
     if ($autoload) {
         if (!$this->autoload) {
             $this->options = $this->autoload = $this->cache->fetch($this->prefix . 'Autoload');
         }
         if ($this->autoload) {
             return;
         }
         $query = "SELECT name, value, autoload FROM {$this->table} WHERE autoload = 1";
     } else {
         $query = "SELECT name, value, autoload FROM {$this->table}";
     }
     if ($options = $this->connection->fetchAll($query)) {
         foreach ($options as $option) {
             $this->options[$option['name']] = json_decode($option['value'], true);
             if ($option['autoload']) {
                 $this->autoload[$option['name']] = $this->options[$option['name']];
             }
         }
         $this->cache->save($this->prefix . 'Autoload', $this->autoload);
         if (!$autoload) {
             $this->initialized = true;
         }
     }
 }
 /**
  * Returns a merge/upsert (i.e. insert or update) SQL query when supported by the database.
  *
  * @return string|null The SQL string or null when not supported
  */
 protected function getMergeSql()
 {
     $platform = $this->connection->getDatabasePlatform();
     if ($platform instanceof MySqlPlatform) {
         return "INSERT INTO {$this->table} (id, data, time) VALUES (:id, :data, :time) " . "ON DUPLICATE KEY UPDATE data = VALUES(data), time = CASE WHEN time = :time THEN (VALUES(time) + INTERVAL 1 SECOND) ELSE VALUES(time) END";
     } elseif ($platform instanceof SqlitePlatform) {
         return "INSERT OR REPLACE INTO {$this->table} (id, data, time) VALUES (:id, :data, :time)";
     }
 }
 /**
  * Dispatches an event to all registered listeners.
  *
  * @param  string   $name
  * @param  mixed    $entity
  * @param  Metadata $metadata
  * @return bool
  */
 public function dispatchEvent($name, $entity, Metadata $metadata)
 {
     $prefix = $metadata->getEventPrefix();
     $event = new $this->eventClass($entity, $metadata, $this);
     if ($events = $metadata->getEvents() and isset($events[$name])) {
         foreach ($events[$name] as $callback) {
             call_user_func_array([$entity, $callback], [$event]);
         }
     }
     $this->connection->getEventDispatcher()->dispatch(($prefix ? $prefix . '.' : '') . $name, $event);
 }
 /**
  * Creates the "select" SQL string from the query parts.
  *
  * @return string
  */
 protected function getSQLForSelect()
 {
     extract($this->parts);
     $query = sprintf('SELECT %s FROM ' . $from, $select ? implode(', ', $select) : '*');
     foreach ($join as $j) {
         $query .= sprintf(' %s JOIN %s ON %s', strtoupper($j['type']), $j['table'], (string) $j['condition']);
     }
     if ($where) {
         $query .= ' WHERE ' . $where;
     }
     if ($group) {
         $query .= ' GROUP BY ' . implode(', ', $group);
     }
     if ($having) {
         $query .= ' HAVING ' . $having;
     }
     if ($order) {
         $query .= ' ORDER BY ' . implode(', ', $order);
     }
     return $limit === null && $offset === null ? $query : $this->connection->getDatabasePlatform()->modifyLimitQuery($query, $limit, $offset);
 }
 /**
  * @return \Doctrine\DBAL\Schema\AbstractSchemaManager
  */
 public function getSchemaManager()
 {
     return $this->connection->getSchemaManager();
 }
 /**
  * Replaces the table prefix placeholder with actual one.
  *
  * @param  string $query
  * @return string
  */
 protected function replacePrefix($query)
 {
     return $this->connection->replacePrefix($query);
 }