DaPortal

<?php //$Id$
//Copyright (c) 2012-2016 Pierre Pronchery <khorben@defora.org>
//This file is part of DeforaOS Web DaPortal
//
//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, version 3 of the License.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program. If not, see <http://www.gnu.org/licenses/>.
//SQLite3Database
class SQLite3Database extends Database
{
//public
//methods
//essential
//SQLite3Database::~SQLite3Database
public function __destruct()
{
if(!is_null($this->handle))
$this->handle->close();
}
//accessors
//SQLite3Database::getLastID
public function getLastID(Engine $engine = NULL, $table, $field)
{
if(is_null($this->handle))
return FALSE;
//FIXME return the real last ID for $table_$field
return $this->handle->lastInsertRowID();
}
//useful
//SQLite3Database::enum
public function enum(Engine $engine = NULL, $table, $field)
{
$query = 'SELECT name FROM '.$table.'_enum_'.$field;
if(($res = $this->query($this->engine, $query)) === FALSE)
return FALSE;
$ret = array();
foreach($res as $r)
$ret[] = $r['name'];
return $ret;
}
//SQLite3Database::query
public function query(Engine $engine = NULL, $query,
$parameters = FALSE, $async = FALSE)
{
global $config;
if(is_null($this->handle))
return FALSE;
if($config->get('database', 'debug'))
$this->engine->log(LOG_DEBUG, $query);
if(($stmt = $this->prepare($query, $parameters)) === FALSE)
return $this->engine->log(LOG_ERR,
'Could not prepare statement: '
.$this->handle->lastErrorMsg());
if($parameters === FALSE)
$parameters = array();
if($stmt->clear() !== TRUE)
return $this->engine->log(LOG_ERR,
'Could not clear statement: '
.$this->handle->lastErrorMsg());
foreach($parameters as $k => $v)
$stmt->bindValue(':'.$k, $v);
//execute the query
$this->profileStart();
$res = $stmt->execute();
$this->profileStop($query);
if($res === FALSE)
return $this->engine->log(LOG_ERR,
'Could not execute statement: '
.$this->handle->lastErrorMsg());
return new SQLite3DatabaseResult($res);
}
//functions
//SQLite3Database::concat
public function _concat($string1, $string2)
{
if($string1 === NULL && $string2 === NULL)
return '';
else if($string1 === NULL)
return $string2;
else if($string2 === NULL)
return $string1;
return $string1.$string2;
}
//SQLite3Database::_date_trunc
public function _date_trunc($where, $value)
{
if($where == 'month')
return substr($value, 0, 8).'01';
//FIXME really implement
return $value;
}
//protected
//properties
static protected $transactionClass = 'SQLite3DatabaseTransaction';
//methods
//SQLite3Database::match
protected function match(Engine $engine)
{
if(!class_exists('SQLite3'))
return 0;
if($this->configGet('filename') !== FALSE)
return 100;
return 0;
}
//SQLite3Database::attach
protected function attach(Engine $engine)
{
if(($filename = $this->configGet('filename')) === FALSE)
return $this->engine->log(LOG_ERR,
'Database filename not defined');
try
{
$this->handle = new SQLite3($filename);
}
catch(Exception $e)
{
$this->handle = NULL;
return $engine->log(LOG_ERR,
'Could not open database');
}
$this->engine = $engine;
$func = array($this, '_concat');
$this->handle->createFunction('concat', $func, 2);
$func = array($this, '_date_trunc');
$this->handle->createFunction('date_trunc', $func);
//default the LIKE keyword to case-sensitive
$query = 'PRAGMA case_sensitive_like=1';
$this->query($this->engine, $query);
//enforce foreign keys if configured to
if($this->configGet('foreign'))
{
$query = 'PRAGMA foreign_keys=ON';
$this->query($this->engine, $query);
}
return TRUE;
}
//SQLite3Database::escape
protected function escape($string)
{
return "'".SQLite3::escapeString($string)."'";
}
//SQLite3Database::prepare
public function prepare($query, &$parameters = FALSE)
{
//FIXME use a class property instead
static $statements = array();
if(isset($statements[$query]))
return $statements[$query];
$statements[$query] = $this->handle->prepare($query);
return $statements[$query];
}
//SQLite3Database::regexp
public function regexp($case = TRUE, $pattern = FALSE)
{
$func = array($this, '_regexp_callback');
if(!$this->func_regexp)
{
$this->func_regexp = TRUE;
$this->handle->createFunction('regexp', $func);
}
//XXX applies globally
$this->case = $case;
return parent::regexp($case, $pattern);
}
public function _regexp_callback($pattern, $subject)
{
//XXX the delimiter character may be used within the pattern
$pattern = $this->case ? ",$pattern," : ",$pattern,i";
return (preg_match($pattern, $subject) === 1) ? TRUE : FALSE;
}
//private
//properties
private $handle = NULL;
private $case;
//functions
private $func_regexp = FALSE;
}
?>