/** * Build Self Config. * * @param array $config */ private function __buildConfig(array $config) { foreach ($config as $key => $conf) { if ($key == 'driver') { $this->rawConfig['type'] = strtolower($conf); continue; } if (!array_key_exists($key, $this->rawConfig)) { $this->error->setMessage(sprintf("invalid config '%s', allowed config are: %s", $key, implode(', ', array_keys($this->rawConfig)))); break; } $this->rawConfig[$key] = $conf; } if (!$this->error->hasError() && !$this->hasDriver($this->getType()) && !$this->preventNoLocalDriver) { $this->error->setMessage(sprintf("Driver '%s' not available. Please choose one of: '%s'. " . 'Or register new ConnectionString class by implements %s.', $this->getType(), implode("', '", $this->getAvailableDrivers()), ConnectionStringInterface::class)); } }
/** * Execute Query. * * @param \Realboard\Component\Database\DBInstance\Query $query */ public function execQuery(Query $query) { $this->connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $this->connection->setAttribute(\PDO::ATTR_EMULATE_PREPARES, $query->isSingle()); $resultDataType = $query->getResultDataType(); foreach ($query as $sql) { $sqlResult = $sql->getResult(); if ($resultDataType instanceof DataInterface) { $sqlResult->setDataType($resultDataType); } try { if ($this->error->hasError()) { throw new \PDOException($this->error->getMessage()); break; } $sqlQuery = $sql->toString(); $totalRows = 0; if ($sql->getCommand() == 'SELECT' && !$query->isSingle()) { $template = '{SQL}'; $templateCounter = 'SELECT COUNT(*) totalRows FROM (%s) fakeTable'; $templateParams = array('SQL' => $sqlQuery, 'LIMIT' => $query->getLimit(), 'OFFSET' => $query->getOffset()); if ($query->getLimit()) { switch ($this->config->getType()) { case 'firebird': $template = 'SELECT FIRST {LIMIT} SKIP {OFFSET} * FROM ({SQL}) fakeTable'; break; case 'oci': $templateCounter = 'SELECT COUNT(*) "totalRows" FROM (%s) "fakeTable"'; $template = 'SELECT a.* FROM (SELECT b.*, rownum "[]" FROM ' . '({SQL}) b WHERE rownum <= {LIMIT}) a WHERE "[]" > {OFFSET}'; break; default: $template = 'SELECT * FROM ({SQL}) fakeTable LIMIT {LIMIT} OFFSET {OFFSET}'; break; } } $resultCounter = $this->connection->prepare(sprintf($templateCounter, $sqlQuery)); $resultCounter->execute(); $totalRows = $resultCounter->fetch(); $sqlResult->setTotalRows((int) @$totalRows['totalRows']); foreach ($templateParams as $key => $val) { $template = str_replace('{' . $key . '}', $val, $template); } $sqlQuery = $template; } $result = $this->connection->prepare($sqlQuery); $stmt = $result->execute(); $sql->execute(); if ($sql->isRead()) { $columns = $this->_define_column_types($result); $sqlResult->setColumnTypes($columns); $sqlResult->setAffected(0); $sqlResult->setStartRow($query->getOffset()); if (!$sqlResult->getTotalRows()) { $sqlResult->setTotalRows($result->rowCount()); } $rows = $result->fetchAll(\PDO::FETCH_ASSOC); foreach ($rows as $row) { $data = $this->_merge_values($sql->getResult()->getDataType(), $row, $columns); $sqlResult->add($data); } $sqlResult->setTotalShows($sqlResult->length()); $sqlResult->setEnd(microtime(true)); } elseif ($sql->isWrite() || $sql->isDDL()) { $insertId = $this->connection->lastInsertId(); $affected = $result->rowCount(); $endTime = microtime(true); $sqlResult->setEnd($endTime); $columns = array('affected' => 'integer', 'seconds' => 'double'); $row = array('affected' => $affected, 'seconds' => $sqlResult->getSeconds()); $sqlResult->setColumnTypes($columns); $sqlResult->setAffected($affected); $data = new Data(); $this->_merge_values($data, $row, $columns); $sqlResult->add($data); $sqlResult->setInsertId($insertId); } } catch (\PDOException $e) { $sql->execute(false); $this->error->setMessage($e->getMessage() . ". \n" . $sql->toString()); $sqlResult->setEnd(microtime(true)); } catch (\Exception $e) { $sql->execute(false); $this->error->setMessage($e->getMessage() . ". \n" . $sql->toString()); $sqlResult->setEnd(microtime(true)); } } }