diff options
-rwxr-xr-x | include/dba/dba_driver.php | 82 | ||||
-rwxr-xr-x | include/dba/dba_mysql.php | 67 | ||||
-rwxr-xr-x | include/dba/dba_mysqli.php | 86 | ||||
-rwxr-xr-x | include/dba/dba_pdo.php | 40 | ||||
-rw-r--r-- | include/dba/dba_postgres.php | 117 |
5 files changed, 60 insertions, 332 deletions
diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index deec9adfd..b3298b673 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -1,15 +1,20 @@ <?php +/** + * @file dba_driver.php + * @brief Some database related functions and database classes. + * + * This file contains the abstract database driver class dba_driver, the + * database class DBA and some functions for working with databases. + */ +/** + * @brief Database classs with database factory method. + * + * The factory will return a database driver which is an implementation of the + * abstract dba_driver class. + */ class DBA { - /** - * @file dba_driver.php - * @brief some database related functions and abstract driver class. - * - * This file contains the abstract database driver class dba_driver and some - * functions for working with databases. - */ - static public $dba = null; static public $dbtype = null; static public $scheme = 'mysql'; @@ -21,7 +26,6 @@ class DBA { static public $tquot = "`"; - /** * @brief Returns the database driver object. * @@ -34,14 +38,11 @@ class DBA { * @param bool $install Defaults to false * @return null|dba_driver A database driver object (dba_pdo) or null if no driver found. */ - static public function dba_factory($server,$port,$user,$pass,$db,$dbtype,$install = false) { self::$dba = null; - self::$dbtype = intval($dbtype); - if(self::$dbtype == DBTYPE_POSTGRES) { if(!($port)) $port = 5432; @@ -50,7 +51,6 @@ class DBA { self::$utc_now = "now() at time zone 'UTC'"; self::$tquot = '"'; self::$scheme = 'pgsql'; - } else { @@ -66,40 +66,27 @@ class DBA { require_once('include/dba/dba_pdo.php'); self::$dba = new dba_pdo($server,self::$scheme,$port,$user,$pass,$db,$install); - - if(is_object(self::$dba) && self::$dba->connected) { - - if(strpbrk($server,':;')) { - $dsn = $server; - } - else { - $dsn = self::$scheme . ':host=' . $server . (intval($port) ? '' : ';port=' . $port); - } - $dsn .= ';dbname=' . $db; - - - self::$dba->pdo_set(array($dsn,$user,$pass)); - } define('NULL_DATE', self::$null_date); define('ACTIVE_DBTYPE', self::$dbtype); define('TQUOT', self::$tquot); + return self::$dba; } } /** - * @brief abstract database driver class. + * @brief Abstract database driver class. * - * This class gets extended by the real database driver classes, e.g. dba_mysql, - * dba_mysqli. + * This class gets extended by the real database driver class. We used to have + * dba_mysql, dba_mysqli or dba_postgres, but we moved to PDO and the only + * implemented driver is dba_pdo. */ abstract class dba_driver { // legacy behavior public $db; - protected $pdo = array(); public $debug = 0; public $connected = false; @@ -111,6 +98,7 @@ abstract class dba_driver { * This abstract function needs to be implemented in the real driver. * * @param string $server DB server name + * @param string $scheme DB scheme * @param string $port DB port * @param string $user DB username * @param string $pass DB password @@ -166,6 +154,7 @@ abstract class dba_driver { $platform_name = \Zotlabs\Lib\System::get_platform_name(); if(file_exists('install/' . $platform_name . '/' . \DBA::$install_script)) return 'install/' . $platform_name . '/' . \DBA::$install_script; + return 'install/' . \DBA::$install_script; } @@ -173,7 +162,6 @@ abstract class dba_driver { return \DBA::$tquot; } - function utcnow() { return \DBA::$utc_now; } @@ -232,19 +220,12 @@ abstract class dba_driver { return $str; } - function pdo_set($x) { - $this->pdo = $x; - } - - function pdo_get() { - return $this->pdo; - } - } // end abstract dba_driver class - +// // Procedural functions +// function printable($s) { $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s); @@ -275,7 +256,7 @@ function dbg($state) { * wrapping with intval(). * * @param string $str A string to pass to a DB query - * @return Return an escaped string of the value to pass to a DB query. + * @return string Return an escaped string of the value to pass to a DB query. */ function dbesc($str) { @@ -298,6 +279,7 @@ function dbunescbin($str) { function dbescdate($date) { if(is_null_date($date)) return \DBA::$dba->escape(NULL_DATE); + return \DBA::$dba->escape($date); } @@ -330,17 +312,17 @@ function db_use_index($str) { * * printf style arguments %s and %d are replaced with variable arguments, which * should each be appropriately dbesc() or intval(). + * * SELECT queries return an array of results or false if SQL or DB error. Other * queries return true if the command was successful or false if it wasn't. * * Example: - * $r = q("SELECT * FROM %s WHERE `uid` = %d", - * 'user', 1); + * @code{.php}$r = q("SELECT * FROM %s WHERE `uid` = %d", + * 'user', 1);@endcode * * @param string $sql The SQL query to execute * @return bool|array */ - function q($sql) { $args = func_get_args(); @@ -359,8 +341,8 @@ function q($sql) { } /* - * This will happen occasionally trying to store the - * session data after abnormal program termination + * This will happen occasionally trying to store the + * session data after abnormal program termination */ db_logger('dba: no database: ' . print_r($args,true),LOGGER_NORMAL,LOG_CRIT); @@ -389,8 +371,8 @@ function dbq($sql) { // Caller is responsible for ensuring that any integer arguments to // dbesc_array are actually integers and not malformed strings containing -// SQL injection vectors. All integer array elements should be specifically -// cast to int to avoid trouble. +// SQL injection vectors. All integer array elements should be specifically +// cast to int to avoid trouble. function dbesc_array_cb(&$item, $key) { if(is_string($item)) { @@ -423,7 +405,7 @@ function dbesc_array(&$arr) { function db_getfunc($f) { $lookup = array( 'rand'=>array( - DBTYPE_MYSQL=>'RAND()', + DBTYPE_MYSQL=>'RAND()', DBTYPE_POSTGRES=>'RANDOM()' ), 'utc_timestamp'=>array( diff --git a/include/dba/dba_mysql.php b/include/dba/dba_mysql.php deleted file mode 100755 index 8b51cf578..000000000 --- a/include/dba/dba_mysql.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php - -require_once('include/dba/dba_driver.php'); - - -class dba_mysql extends dba_driver { - - function connect($server, $scheme, $port, $user,$pass,$db) { - $this->db = mysql_connect($server.":".$port,$user,$pass); - if($this->db && mysql_select_db($db,$this->db)) { - $this->connected = true; - } - if($this->connected) { - return true; - } - return false; - } - - - function q($sql) { - if((! $this->db) || (! $this->connected)) - return false; - - $this->error = ''; - $result = @mysql_query($sql,$this->db); - - - if(mysql_errno($this->db)) - $this->error = mysql_error($this->db); - - if($result === false || $this->error) { - logger('dba_mysql: ' . printable($sql) . ' returned false.' . "\n" . $this->error); - if(file_exists('dbfail.out')) - file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND); - } - - if(($result === true) || ($result === false)) - return $result; - - $r = array(); - if(mysql_num_rows($result)) { - while($x = mysql_fetch_array($result,MYSQL_ASSOC)) - $r[] = $x; - mysql_free_result($result); - if($this->debug) - logger('dba_mysql: ' . printable(print_r($r,true))); - } - return $r; - } - - function escape($str) { - if($this->db && $this->connected) { - return @mysql_real_escape_string($str,$this->db); - } - } - - function close() { - if($this->db) - mysql_close($this->db); - $this->connected = false; - } - - function getdriver() { - return 'mysql'; - } - -} diff --git a/include/dba/dba_mysqli.php b/include/dba/dba_mysqli.php deleted file mode 100755 index 165c8e969..000000000 --- a/include/dba/dba_mysqli.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php /** @file */ - -require_once('include/dba/dba_driver.php'); - -class dba_mysqli extends dba_driver { - - function connect($server,$scheme,$port,$user,$pass,$db) { - if($port) - $this->db = new mysqli($server,$user,$pass,$db, $port); - else - $this->db = new mysqli($server,$user,$pass,$db); - - if($this->db->connect_error) { - $this->connected = false; - $this->error = $this->db->connect_error; - - if(file_exists('dbfail.out')) { - file_put_contents('dbfail.out', datetime_convert() . "\nConnect: " . $this->error . "\n", FILE_APPEND); - } - - return false; - } - else { - $this->connected = true; - return true; - } - } - - function q($sql) { - if((! $this->db) || (! $this->connected)) - return false; - - $this->error = ''; - $result = $this->db->query($sql); - - if($this->db->errno) - $this->error = $this->db->error; - - - if($this->error) { - db_logger('dba_mysqli: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR); - if(file_exists('dbfail.out')) { - file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . "\n" . $this->error . "\n", FILE_APPEND); - } - } - - if(($result === true) || ($result === false)) { - if($this->debug) { - db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returns ' . (($result) ? 'true' : 'false'), LOGGER_NORMAL,(($result) ? LOG_INFO : LOG_ERR)); - } - return $result; - } - - if($this->debug) { - db_logger('dba_mysqli: DEBUG: ' . printable($sql) . ' returned ' . $result->num_rows . ' results.', LOGGER_NORMAL, LOG_INFO); - } - - $r = array(); - if($result->num_rows) { - while($x = $result->fetch_array(MYSQLI_ASSOC)) - $r[] = $x; - $result->free_result(); - if($this->debug) { - db_logger('dba_mysqli: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); - } - } - return $r; - } - - function escape($str) { - if($this->db && $this->connected) { - return @$this->db->real_escape_string($str); - } - } - - function close() { - if($this->db) - $this->db->close(); - $this->connected = false; - } - - function getdriver() { - return 'mysqli'; - } - -}
\ No newline at end of file diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php index a9d824a50..719f23c4b 100755 --- a/include/dba/dba_pdo.php +++ b/include/dba/dba_pdo.php @@ -1,14 +1,21 @@ -<?php /** @file */ +<?php -require_once('include/dba/dba_driver.php'); +require_once 'include/dba/dba_driver.php'; +/** + * @brief PDO based database driver. + * + */ class dba_pdo extends dba_driver { - public $driver_dbtype = null; - function connect($server,$scheme,$port,$user,$pass,$db) { - + /** + * {@inheritDoc} + * @see dba_driver::connect() + */ + function connect($server, $scheme, $port, $user, $pass, $db) { + $this->driver_dbtype = $scheme; if(strpbrk($server,':;')) { @@ -17,7 +24,7 @@ class dba_pdo extends dba_driver { else { $dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? ';port=' . $port : ''); } - + $dsn .= ';dbname=' . $db; try { @@ -36,10 +43,19 @@ class dba_pdo extends dba_driver { $this->q("SET standard_conforming_strings = 'off'; SET backslash_quote = 'on';"); $this->connected = true; - return true; + return true; } + /** + * {@inheritDoc} + * @see dba_driver::q() + * + * @return bool|array|PDOStatement + * - \b false if not connected or PDOException occured on query + * - \b array with results on a SELECT query + * - \b PDOStatement on a non SELECT SQL query + */ function q($sql) { if((! $this->db) || (! $this->connected)) return false; @@ -57,7 +73,7 @@ class dba_pdo extends dba_driver { $result = $this->db->query($sql, PDO::FETCH_ASSOC); } catch(PDOException $e) { - + $this->error = $e->getMessage(); if($this->error) { db_logger('dba_pdo: ERROR: ' . printable($sql) . "\n" . $this->error, LOGGER_NORMAL, LOG_ERR); @@ -82,11 +98,10 @@ class dba_pdo extends dba_driver { } if($this->debug) { - db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO); + db_logger('dba_pdo: DEBUG: ' . printable($sql) . ' returned ' . count($r) . ' results.', LOGGER_NORMAL, LOG_INFO); db_logger('dba_pdo: ' . printable(print_r($r,true)), LOGGER_NORMAL, LOG_INFO); } - return (($this->error) ? false : $r); } @@ -99,9 +114,10 @@ class dba_pdo extends dba_driver { function close() { if($this->db) $this->db = null; + $this->connected = false; } - + function concat($fld,$sep) { if($this->driver_dbtype === 'pgsql') { return 'string_agg(' . $fld . ',\'' . $sep . '\')'; @@ -140,7 +156,7 @@ class dba_pdo extends dba_driver { return $this->escape($str); } } - + function unescapebin($str) { if($this->driver_dbtype === 'pgsql' && (! is_null($str))) { $x = ''; diff --git a/include/dba/dba_postgres.php b/include/dba/dba_postgres.php deleted file mode 100644 index 560d8da60..000000000 --- a/include/dba/dba_postgres.php +++ /dev/null @@ -1,117 +0,0 @@ -<?php - -require_once('include/dba/dba_driver.php'); - - -class dba_postgres extends dba_driver { - const INSTALL_SCRIPT='install/schema_postgres.sql'; - const NULL_DATE = '0001-01-01 00:00:00'; - const UTC_NOW = "now() at time zone 'UTC'"; - const TQUOT = '"'; - - function connect($server,$scheme,$port,$user,$pass,$db) { - if(!$port) $port = 5432; - $connstr = 'host=' . $server . ' port='.$port . ' user=' . $user . ' password=' . $pass . ' dbname='. $db; - $this->db = pg_connect($connstr); - if($this->db !== false) { - $this->connected = true; - } else { - $this->connected = false; - } - $this->q("SET standard_conforming_strings = 'off'; SET backslash_quote = 'on';"); // emulate mysql string escaping to prevent massive code-clobber - return $this->connected; - } - - function q($sql) { - if((! $this->db) || (! $this->connected)) - return false; - - if(!strpos($sql, ';')) - $sql .= ';'; - - if(strpos($sql, '`')) // this is a hack. quoted identifiers should be replaced everywhere in the code with dbesc_identifier(), remove this once it is - $sql = str_replace('`', '"', $sql); - - $this->error = ''; - $result = @pg_query($this->db, $sql); - if(file_exists('db-allqueries.out')) { - $bt = debug_backtrace(); - $trace = array(); - foreach($bt as $frame) { - if(!empty($frame['file']) && @strstr($frame['file'], $_SERVER['DOCUMENT_ROOT'])) - $frame['file'] = substr($frame['file'], strlen($_SERVER['DOCUMENT_ROOT'])+1); - - $trace[] = $frame['file'] . ':' . $frame['function'] . '():' . $frame['line'] ; - } - $compact = join(', ', $trace); - file_put_contents('db-allqueries.out', datetime_convert() . ": " . $sql . ' is_resource: '.var_export(is_resource($result), true).', backtrace: '.$compact."\n\n", FILE_APPEND); - } - - if($result === false) - $this->error = pg_last_error($this->db); - - if($result === false || $this->error) { - //db_logger('dba_postgres: ' . printable($sql) . ' returned false.' . "\n" . $this->error); - if(file_exists('dbfail.out')) - file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND); - } - - if(($result === true) || ($result === false)) - return $result; - - if(pg_result_status($result) == PGSQL_COMMAND_OK) - return true; - - $r = array(); - if(pg_num_rows($result)) { - while($x = pg_fetch_array($result, null, PGSQL_ASSOC)) - $r[] = $x; - pg_free_result($result); - if($this->debug) - db_logger('dba_postgres: ' . printable(print_r($r,true))); - } - return $r; - } - - function escape($str) { - if($this->db && $this->connected) { - $x = @pg_escape_string($this->db, $str); - return $x; - } - } - - function escapebin($str) { - return pg_escape_bytea($str); - } - - function unescapebin($str) { - return pg_unescape_bytea($str); - } - - function close() { - if($this->db) - pg_close($this->db); - $this->connected = false; - } - - function quote_interval($txt) { - return "'$txt'"; - } - - function escape_identifier($str) { - return pg_escape_identifier($this->db, $str); - } - - function optimize_table($table) { - // perhaps do some equivalent thing here, vacuum, etc? I think this is the DBA's domain anyway. Applications should not need to muss with this. - // for now do nothing without a compelling reason. function overrides default legacy mysql. - } - - function concat($fld, $sep) { - return 'string_agg(' . $fld . ',\'' . $sep . '\')'; - } - - function getdriver() { - return 'pgsql'; - } -}
\ No newline at end of file |