/** * @param \Realboard\Component\Database\DBInstance\ConfigInterface $config */ public function __construct(ConfigInterface $config) { $this->config = $config; $this->error = $config->getError(); if (!in_array($config->getType(), $config->getAvailableDrivers())) { $config->getError()->setMessage(sprintf('%s driver is not available', ucfirst($config->getType()))); return $this; } try { $this->connection = new \PDO($config->getDsn(), $config->getUser(), $config->getPass(), $config->getAttr()); } catch (\PDOException $e) { $config->getError()->setMessage($e->getMessage()); } catch (\Exception $e) { $config->getError()->setMessage($e->getMessage()); } }
/** * 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)); } } }