30   protected $preparedStatements;
    34   protected $cumulatedTime = array();
    36   protected $queryCount = array();
    38   private $transactionDepth = 0;
    40   function __construct(Logger $logger)
    42     $this->preparedStatements = array();
    43     $this->logger = $logger;
    49     $this->dbDriver = $dbDriver;
    55     return $this->dbDriver;
    58   public function begin()
    60     if ($this->transactionDepth==0) {
    61       $this->dbDriver->begin();
    63     $this->transactionDepth++;
    66   public function commit()
    68     $this->transactionDepth--;
    69     if ($this->transactionDepth==0) {
    70       $this->dbDriver->commit();
    71     } 
else if ($this->transactionDepth < 0) {
    72       throw new \Exception(
'too much transaction commits');
    76   public function rollback()
    78     if ($this->transactionDepth > 0) {
    79       $this->transactionDepth--;
    80       $this->dbDriver->rollback();
    81     } 
else if ($this->transactionDepth == 0) {
    82       throw new \Exception(
'too much transaction rollbacks');
    91   abstract public function prepare($statementName, $sqlStatement);
   105     $sqlStatement .= 
" RETURNING $returning";
   106     $statementName .= 
".returning:$returning";
   107     $this->
prepare($statementName,$sqlStatement);
   108     $res = $this->
execute($statementName,$params);
   111     return $return[$returning];
   120   abstract public function execute($statementName, $params = array());
   129     if ($result !== 
false) {
   133     if ($this->dbDriver->isConnected()) {
   134       $lastError = $this->dbDriver->getLastError();
   135       $this->logger->addCritical($lastError);
   136       if ($this->transactionDepth>0) {
   137         $this->dbDriver->rollback();
   140       $this->logger->addCritical(
"DB connection lost.");
   143     $message = 
"error executing: $sqlStatement\n\n$lastError";
   153   public function getSingleRow($sqlStatement, $params = array(), $statementName = 
"")
   155     if (empty($statementName)) {
   156       $backtrace = debug_backtrace();
   157       $caller = $backtrace[1];
   158       $statementName = (array_key_exists(
'class', $caller) ? 
"$caller[class]::" : 
'') . 
"$caller[function]";
   160     if (!array_key_exists($statementName, $this->preparedStatements)) {
   161       $this->
prepare($statementName, $sqlStatement);
   163     $res = $this->
execute($statementName, $params);
   164     $row = $this->dbDriver->fetchArray($res);
   165     $this->dbDriver->freeResult($res);
   175   public function getRows($sqlStatement, $params = array(), $statementName = 
"")
   177     if (empty($statementName)) {
   178       $backtrace = debug_backtrace();
   179       $caller = $backtrace[1];
   180       $statementName = (array_key_exists(
'class', $caller) ? 
"$caller[class]::" : 
'') . 
"$caller[function]";
   182     if (!array_key_exists($statementName, $this->preparedStatements)) {
   183       $this->
prepare($statementName, $sqlStatement);
   185     $res = $this->
execute($statementName, $params);
   186     $rows = $this->dbDriver->fetchAll($res);
   187     $this->dbDriver->freeResult($res);
   198     if (empty($sqlLog)) {
   199       $sqlLog = $sqlStatement;
   201     $startTime = microtime($get_as_float = 
true);
   202     $res = $this->dbDriver->query($sqlStatement);
   205     $execTime = microtime($get_as_float = 
true) - $startTime;
   206     $this->logger->addDebug(
"query '$sqlLog' took " . $this->
formatMilliseconds($execTime));
   215     return $this->dbDriver->freeResult($res);
   224     return $this->dbDriver->fetchArray($res);
   233     return $this->dbDriver->fetchAll($res);
   243   public function createMap($tableName,$keyColumn,$valueColumn,$sqlLog=
'')
   245     if (empty($sqlLog)) {
   246       $sqlLog = __METHOD__ . 
".$tableName.$keyColumn,$valueColumn";
   248     $this->
prepare($sqlLog, 
"select $keyColumn,$valueColumn from $tableName");
   249     $res = $this->
execute($sqlLog);
   252       $map[$row[$keyColumn]] = $row[$valueColumn];
   258   public function flushStats()
   260     foreach ($this->cumulatedTime as $statementName => $seconds) {
   261       $queryCount = $this->queryCount[$statementName];
   262       $this->logger->addDebug(
"executing '$statementName' took "   264           . 
" ($queryCount queries" . ($queryCount > 0 ? 
", avg " . $this->
formatMilliseconds($seconds / $queryCount) : 
"") . 
")");
   267     if ($this->transactionDepth != 0) {
   268       throw new \Fossology\Lib\Exception(
"you have not committed enough");
   278     return sprintf(
"%0.3fms", 1000 * $seconds);
   287     $this->cumulatedTime[$statementName] += $execTime;
   288     $this->queryCount[$statementName]++;
   291   public function booleanFromDb($booleanValue)
   293     return $this->dbDriver->booleanFromDb($booleanValue);
   296   public function booleanToDb($booleanValue)
   298     return $this->dbDriver->booleanToDb($booleanValue);
   301   private function cleanupParamsArray($params)
   303     $nParams = 
sizeof($params);
   304     for ($i = 0; $i<$nParams; $i++) {
   305       if (is_bool($params[$i])) {
   306         $params[$i] = $this->dbDriver->booleanToDb($params[$i]);
   318   public function insertInto($tableName, $keys, $params, $sqlLog=
'', $returning=
'')
   320     if (empty($sqlLog)) {
   321       $sqlLog = __METHOD__ . 
".$tableName.$keys" . (empty($returning) ? 
"" : md5($returning));
   323     $sql = 
"INSERT INTO $tableName ($keys) VALUES (";
   324     $nKeys = substr_count($keys,
',')+1;
   325     for ($i = 1; $i < $nKeys; $i++) {
   328     $sql .= 
'$'.$nKeys.
')';
   329     $params = $this->cleanupParamsArray($params);
   330     if (!empty($returning)) {
   334     $res = $this->
execute($sqlLog,$params);
   346     $params = array_values($assocParams);
   347     $keys = implode(
',',array_keys($assocParams));
   348     if (empty($sqlLog)) {
   349       $sqlLog = __METHOD__ . 
".$tableName.$keys" . (empty($returning) ? 
"" : md5($returning));
   351     return $this->
insertInto($tableName, $keys, $params, $sqlLog, $returning);
   354   public function updateTableRow($tableName, $assocParams, $idColName, $id, $sqlLog=
'')
   356     $params = array_values($assocParams);
   357     $keys = array_keys($assocParams);
   358     $nKeys = 
sizeof($keys);
   360     if (empty($sqlLog)) {
   361       $sqlLog = __METHOD__ . 
".$tableName.$keys";
   364     $sql = 
"UPDATE $tableName SET";
   365     for ($i = 1; $i < $nKeys; $i++) {
   366       $sql .= 
" ".$keys[$i - 1].
' = $'.$i.
",";
   368     $sql .= 
" ".$keys[$nKeys - 1].
' = $'.$nKeys;
   369     $sql .= 
" WHERE $idColName = \$".($nKeys + 1);
   372     $params = $this->cleanupParamsArray($params);
   375     $res = $this->
execute($sqlLog,$params);
   386     if (! preg_match(
'/^[a-z0-9_]+$/i',$tableName)) {
   387       throw new \Exception(
"invalid table name '$tableName'");
   389     return $this->dbDriver->existsTable($tableName);
   400     if (! preg_match(
'/^[a-z0-9_]+$/i',$columnName)) {
   401       throw new \Exception(
"invalid column name '$columnName'");
   403     return $this->
existsTable($tableName) && $this->dbDriver->existsColumn($tableName, $columnName);
 insertPreparedAndReturn($statementName, $sqlStatement, $params, $returning)
formatMilliseconds($seconds)
createMap($tableName, $keyColumn, $valueColumn, $sqlLog='')
prepare($statementName, $sqlStatement)
setDriver(Driver &$dbDriver)
insertInto($tableName, $keys, $params, $sqlLog='', $returning='')
insertTableRow($tableName, $assocParams, $sqlLog='', $returning='')
getSingleRow($sqlStatement, $params=array(), $statementName="")
existsColumn($tableName, $columnName)
queryOnce($sqlStatement, $sqlLog= '')
execute($statementName, $params=array())
checkResult($result, $sqlStatement="")
Check the result for unexpected errors. If found, treat them as fatal. 
getRows($sqlStatement, $params=array(), $statementName="")
collectStatistics($statementName, $execTime)