From ea14ca10cd2042522e6c510a8b0a8c551bb4dabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Fri, 21 Feb 2014 12:38:43 +0100 Subject: [PATCH 1/5] Extracted mysql interface --- htdocs/core/db/Database.interface.php | 464 ++++++++++++++++++++++++++ htdocs/core/db/DoliDB.class.php | 7 +- 2 files changed, 468 insertions(+), 3 deletions(-) create mode 100644 htdocs/core/db/Database.interface.php diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php new file mode 100644 index 00000000000..6c98682dafa --- /dev/null +++ b/htdocs/core/db/Database.interface.php @@ -0,0 +1,464 @@ + + * Copyright (C) 2002-2007 Rodolphe Quiedeville + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014 Raphaël Doursenaud + * + * 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; either version 3 of the License, or + * (at your option) any later version. + * + * 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 . + */ + +/** + * Class to manage Dolibarr database access for a Mysql database + */ +interface Database +{ + /** + * Format a SQL IF + * + * @param string $test Test string (example: 'cd.statut=0', 'field IS NULL') + * @param string $resok resultat si test egal + * @param string $resko resultat si test non egal + * @return string SQL string + */ + function ifsql($test, $resok, $resko); + + /** + * Return datas as an array + * + * @param Resultset $resultset Resultset of request + * @return array Array + */ + function fetch_row($resultset); + + /** + * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field. + * Function to use to build INSERT, UPDATE or WHERE predica + * + * @param string $param Date TMS to convert + * @return string Date in a string YYYYMMDDHHMMSS + */ + function idate($param); + + /** + * Return last error code + * + * @return string lasterrno + */ + function lasterrno(); + + /** + * Start transaction + * + * @return int 1 if transaction successfuly opened or already opened, 0 if error + */ + function begin(); + + /** + * Create a new database + * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated + * We force to create database with charset this->forcecharset and collate this->forcecollate + * + * @param string $database Database name to create + * @param string $charset Charset used to store data + * @param string $collation Charset used to sort data + * @param string $owner Username of database owner + * @return resource resource defined if OK, null if KO + */ + function DDLCreateDb($database, $charset = '', $collation = '', $owner = ''); + + /** + * Return version of database server into an array + * + * @return array Version array + */ + function getVersionArray(); + + /** + * Convert a SQL request in Mysql syntax to native syntax + * + * @param string $line SQL request line to convert + * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) + * @return string SQL request line converted + */ + static function convertSQLFromMysql($line, $type = 'ddl'); + + /** + * Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE + * + * @param resultset $resultset Curseur de la requete voulue + * @return int Nombre de lignes + * @see num_rows + */ + function affected_rows($resultset); + + /** + * Return description of last error + * + * @return string Error text + */ + function error(); + + /** + * Return label of manager + * + * @return string Label + */ + function getLabel(); + + /** + * List tables into a database + * + * @param string $database Name of database + * @param string $table Nmae of table filter ('xxx%') + * @return resource Resource + */ + function DDLListTables($database, $table = ''); + + /** + * Return last request executed with query() + * + * @return string Last query + */ + function lastquery(); + + /** + * Define sort criteria of request + * + * @param string $sortfield List of sort fields + * @param string $sortorder Sort order + * @return string String to provide syntax of a sort sql string + */ + function order($sortfield = 0, $sortorder = 0); + + /** + * Decrypt sensitive data in database + * + * @param string $value Value to decrypt + * @return string Decrypted value if used + */ + function decrypt($value); + + /** + * Return datas as an array + * + * @param Resultset $resultset Resultset of request + * @return array Array + */ + function fetch_array($resultset); + + /** + * Return last error label + * + * @return string lasterror + */ + function lasterror(); + + /** + * Escape a string to insert data + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + function escape($stringtoencode); + + /** + * Get last ID after an insert INSERT + * + * @param string $tab Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql + * @param string $fieldid Field name + * @return int Id of row + */ + function last_insert_id($tab, $fieldid = 'rowid'); + + /** + * Return full path of restore program + * + * @return string Full path of restore program + */ + function getPathOfRestore(); + + /** + * Annulation d'une transaction et retour aux anciennes valeurs + * + * @param string $log Add more log to default log line + * @return int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur + */ + function rollback($log = ''); + + /** + * Execute a SQL request and return the resultset + * + * @param string $query SQL query string + * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollbock to savepoint if error (this allow to have some request with errors inside global transactions). + * Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints. + * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...) + * @return resource Resultset of answer + */ + function query($query, $usesavepoint = 0, $type = 'auto'); + + /** + * Connexion to server + * + * @param string $host database server host + * @param string $login login + * @param string $passwd password + * @param string $name name of database (not used for mysql, used for pgsql) + * @param string $port Port of database server + * @return resource Database access handler + * @see close + */ + function connect($host, $login, $passwd, $name, $port = 0); + + /** + * Define limits and offset of request + * + * @param int $limit Maximum number of lines returned (-1=conf->liste_limit, 0=no limit) + * @param int $offset Numero of line from where starting fetch + * @return string String with SQL syntax to add a limit and offset + */ + function plimit($limit = 0, $offset = 0); + + /** + * Return value of server status + * + * @param string $filter Filter list on a particular value + * @return string Value for parameter + */ + function getServerStatusValues($filter = ''); + + /** + * Return collation used in database + * + * @return string Collation value + */ + function getDefaultCollationDatabase(); + + /** + * Return number of lines for result of a SELECT + * + * @param Resultset $resultset Resulset of requests + * @return int Nb of lines + * @see affected_rows + */ + function num_rows($resultset); + + /** + * Return full path of dump program + * + * @return string Full path of dump program + */ + function getPathOfDump(); + + /** + * Return version of database client driver + * + * @return string Version string + */ + function getDriverInfo(); + + /** + * Return generic error code of last operation. + * + * @return string Error code (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...) + */ + function errno(); + + /** + * Create a table into database + * + * @param string $table Nom de la table + * @param array $fields Tableau associatif [nom champ][tableau des descriptions] + * @param string $primary_key Nom du champ qui sera la clef primaire + * @param string $type Type de la table + * @param array $unique_keys Tableau associatifs Nom de champs qui seront clef unique => valeur + * @param array $fulltext_keys Tableau des Nom de champs qui seront indexes en fulltext + * @param string $keys Tableau des champs cles noms => valeur + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = "", $fulltext_keys = "", $keys = ""); + + /** + * Return list of available charset that can be used to store data in database + * + * @return array List of Charset + */ + function getListOfCharacterSet(); + + /** + * Create a new field into table + * + * @param string $table Name of table + * @param string $field_name Name of field to add + * @param string $field_desc Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre] + * @param string $field_position Optionnel ex.: "after champtruc" + * @return int <0 if KO, >0 if OK + */ + function DDLAddField($table, $field_name, $field_desc, $field_position = ""); + + /** + * Drop a field from table + * + * @param string $table Name of table + * @param string $field_name Name of field to drop + * @return int <0 if KO, >0 if OK + */ + function DDLDropField($table, $field_name); + + /** + * Update format of a field into a table + * + * @param string $table Name of table + * @param string $field_name Name of field to modify + * @param string $field_desc Array with description of field format + * @return int <0 if KO, >0 if OK + */ + function DDLUpdateField($table, $field_name, $field_desc); + + /** + * Return list of available collation that can be used for database + * + * @return array List of Collation + */ + function getListOfCollation(); + + /** + * Return a pointer of line with description of a table or field + * + * @param string $table Name of table + * @param string $field Optionnel : Name of field if we want description of field + * @return resource Resource + */ + function DDLDescTable($table, $field = ""); + + /** + * Return version of database server + * + * @return string Version string + */ + function getVersion(); + + /** + * Return charset used to store data in database + * + * @return string Charset + */ + function getDefaultCharacterSetDatabase(); + + /** + * Create a user and privileges to connect to database (even if database does not exists yet) + * + * @param string $dolibarr_main_db_host Ip serveur + * @param string $dolibarr_main_db_user Nom user a creer + * @param string $dolibarr_main_db_pass Mot de passe user a creer + * @param string $dolibarr_main_db_name Database name where user must be granted + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateUser( + $dolibarr_main_db_host, + $dolibarr_main_db_user, + $dolibarr_main_db_pass, + $dolibarr_main_db_name + ); + + /** + * Convert (by PHP) a PHP server TZ string date into a GM Timestamps date + * 19700101020000 -> 3600 with TZ+1 + * + * @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS) + * @return date Date TMS + */ + function jdate($string); + + /** + * Encrypt sensitive data in database + * Warning: This function includes the escape, so it must use direct value + * + * @param string $fieldorvalue Field name or value to encrypt + * @param int $withQuotes Return string with quotes + * @return string XXX(field) or XXX('value') or field or 'value' + */ + function encrypt($fieldorvalue, $withQuotes = 0); + + /** + * Validate a database transaction + * + * @param string $log Add more log to default log line + * @return int 1 if validation is OK or transaction level no started, 0 if ERROR + */ + function commit($log = ''); + + /** + * List information of columns into a table. + * + * @param string $table Name of table + * @return array Tableau des informations des champs de la table + */ + function DDLInfoTable($table); + + /** + * Free last resultset used. + * + * @param resultset $resultset Curseur de la requete voulue + * @return void + */ + function free($resultset = 0); + + /** + * Close database connexion + * + * @return boolean True if disconnect successfull, false otherwise + * @see connect + */ + function close(); + + /** + * Return last query in error + * + * @return string lastqueryerror + */ + function lastqueryerror(); + + /** + * Return connexion ID + * + * @return string Id connexion + */ + function DDLGetConnectId(); + + /** + * Renvoie la ligne courante (comme un objet) pour le curseur resultset + * + * @param Resultset $resultset Curseur de la requete voulue + * @return Object Object result line or false if KO or end of cursor + */ + function fetch_object($resultset); + + /** + * Select a database + * + * @param string $database Name of database + * @return boolean true if OK, false if KO + */ + function select_db($database); + + /** + * Return value of server parameters + * + * @param string $filter Filter list on a particular value + * @return string Value for parameter + */ + function getServerParametersValues($filter = ''); +} diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 43b05aea150..6f5a75b35ab 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -1,6 +1,6 @@ + * Copyright (C) 2013-2014 Raphaël Doursenaud * * 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 @@ -21,10 +21,12 @@ * \brief Class file to manage Dolibarr database access */ +require_once DOL_DOCUMENT_ROOT .'/core/db/Database.interface.php'; + /** * Class to manage Dolibarr database access */ -abstract class DoliDB +abstract class DoliDB implements Database { //! Database handler public $db; @@ -92,6 +94,5 @@ abstract class DoliDB return ''; } } - } From 894ac6fdc047955188e0c741c897a479dee71d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Fri, 21 Feb 2014 14:27:29 +0100 Subject: [PATCH 2/5] Added missing method to mysqli class --- htdocs/core/db/mysqli.class.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 4cc57a880b8..fb1ab73407b 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -233,6 +233,16 @@ class DoliDBMysqli extends DoliDB return $this->db; } + /** + * Return label of manager + * + * @return string Label + */ + function getLabel() + { + return $this->label; + } + /** * Return version of database server * From 283fec164ed63e5a7f7fe15dbd559d582cc70881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Fri, 21 Feb 2014 14:40:10 +0100 Subject: [PATCH 3/5] Implemented rollback according to interface for Microsoft SQL and PostgreSQL --- htdocs/core/db/mssql.class.php | 7 ++++--- htdocs/core/db/pgsql.class.php | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php index c50a7ed8925..706bacef870 100644 --- a/htdocs/core/db/mssql.class.php +++ b/htdocs/core/db/mssql.class.php @@ -310,15 +310,16 @@ class DoliDBMssql extends DoliDB /** * Annulation d'une transaction et retour aux anciennes valeurs * - * @return int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur + * @param string $log Add more log to default log line + * @return int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur */ - function rollback() + function rollback($log='') { if ($this->transaction_opened<=1) { $ret=$this->query("ROLLBACK TRANSACTION"); $this->transaction_opened=0; - dol_syslog("ROLLBACK Transaction",LOG_DEBUG); + dol_syslog("ROLLBACK Transaction".($log?' '.$log:''),LOG_DEBUG); return $ret; } else diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 531427b9547..78cafae6c4a 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -541,16 +541,17 @@ class DoliDBPgsql extends DoliDB /** * Annulation d'une transaction et retour aux anciennes valeurs * - * @return int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur + * @param string $log Add more log to default log line + * @return int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur */ - function rollback() + function rollback($log='') { dol_syslog('',0,-1); if ($this->transaction_opened<=1) { $ret=$this->query("ROLLBACK;"); $this->transaction_opened=0; - dol_syslog("ROLLBACK Transaction",LOG_DEBUG); + dol_syslog("ROLLBACK Transaction".($log?' '.$log:''),LOG_DEBUG); return $ret; } else From 501ffb12b3d0bf779d72531e14653141742d3d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Fri, 21 Feb 2014 14:41:00 +0100 Subject: [PATCH 4/5] Added dummy methods according to interface for Microsoft SQL and PostgreSQL Please implement if you have the required knowledge --- htdocs/core/db/mssql.class.php | 66 ++++++++++++++++++++++++++++++++++ htdocs/core/db/pgsql.class.php | 15 ++++++++ 2 files changed, 81 insertions(+) diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php index 706bacef870..d16462dce12 100644 --- a/htdocs/core/db/mssql.class.php +++ b/htdocs/core/db/mssql.class.php @@ -805,6 +805,23 @@ class DoliDBMssql extends DoliDB return $this->_results; } + /** + * List information of columns into a table. + * + * @param string $table Name of table + * @return array Tableau des informations des champs de la table + */ + function DDLInfoTable($table) + { + + // FIXME: Dummy method + // TODO: Implement + // May help: https://stackoverflow.com/questions/600446/sql-server-how-do-you-return-the-column-names-from-a-table + + $infotables=array(); + return $infotables; + } + /** * Create a table into database * @@ -976,6 +993,24 @@ class DoliDBMssql extends DoliDB else return 1; } + /** + * Create a user and privileges to connect to database (even if database does not exists yet) + * + * @param string $dolibarr_main_db_host Ip serveur + * @param string $dolibarr_main_db_user Nom user a creer + * @param string $dolibarr_main_db_pass Mot de passe user a creer + * @param string $dolibarr_main_db_name Database name where user must be granted + * @return int <0 if KO, >=0 if OK + */ + function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name) + { + // FIXME: Dummy method + // TODO: Implement + // May help: http://msdn.microsoft.com/fr-fr/library/ms173463.aspx + + // Always fail for now + return -1; + } /** * Return charset used to store data in database @@ -1088,6 +1123,37 @@ class DoliDBMssql extends DoliDB return ''; } + + /** + * Return value of server parameters + * + * @param string $filter Filter list on a particular value + * @return string Value for parameter + */ + function getServerParametersValues($filter='') + { + // FIXME: Dummy method + // TODO: Implement + // May help: SELECT SERVERPROPERTY + + $result=array(); + return $result; + } + + /** + * Return value of server status + * + * @param string $filter Filter list on a particular value + * @return string Value for parameter + */ + function getServerStatusValues($filter='') + { + // FIXME: Dummy method + // TODO: Implement + // May help: http://www.experts-exchange.com/Database/MS-SQL-Server/Q_20971756.html + + return ''; + } } ?> diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 78cafae6c4a..f85eff1e5e1 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -1403,5 +1403,20 @@ class DoliDBPgsql extends DoliDB return $result; } + + /** + * Return value of server status + * + * @param string $filter Filter list on a particular value + * @return string Value for parameter + */ + function getServerStatusValues($filter='') + { + // FIXME: Dummy method + // TODO: Implement + // May help: http://netpenthe.wordpress.com/2011/12/07/mysql-show-status-for-postgresql + + return ''; + } } ?> From 0a74467296833f8b520710a20b51a013e8693958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Fri, 21 Feb 2014 14:57:19 +0100 Subject: [PATCH 5/5] Added FIXMEs and TODOs on all dummy methods in database drivers --- htdocs/core/db/mssql.class.php | 64 ++++++++++----------------------- htdocs/core/db/pgsql.class.php | 3 ++ htdocs/core/db/sqlite.class.php | 3 ++ 3 files changed, 24 insertions(+), 46 deletions(-) diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php index d16462dce12..19fe025ab8b 100644 --- a/htdocs/core/db/mssql.class.php +++ b/htdocs/core/db/mssql.class.php @@ -237,6 +237,9 @@ class DoliDBMssql extends DoliDB */ function getDriverInfo() { + // FIXME: Dummy method + // TODO: Implement + return ''; } @@ -1019,15 +1022,9 @@ class DoliDBMssql extends DoliDB */ function getDefaultCharacterSetDatabase() { - /* - $resql=$this->query('SHOW VARIABLES LIKE \'character_set_database\''); - if (!$resql) - { - return $this->forcecharset; - } - $liste=$this->fetch_array($resql); - return $liste['Value']; - */ + // FIXME: Dummy method + // TODO: Implement + return ''; } @@ -1038,25 +1035,10 @@ class DoliDBMssql extends DoliDB */ function getListOfCharacterSet() { - /* - $resql=$this->query('SHOW CHARSET'); - $liste = array(); - if ($resql) - { - $i = 0; - while ($obj = $this->fetch_object($resql) ) - { - $liste[$i]['charset'] = $obj->Charset; - $liste[$i]['description'] = $obj->Description; - $i++; - } - $this->free($resql); - } else { - return null; - } - return $liste; - */ - return ''; // attente debuggage + // FIXME: Dummy method + // TODO: Implement + + return ''; } /** @@ -1082,24 +1064,10 @@ class DoliDBMssql extends DoliDB */ function getListOfCollation() { - /* - $resql=$this->query('SHOW COLLATION'); - $liste = array(); - if ($resql) - { - $i = 0; - while ($obj = $this->fetch_object($resql) ) - { - $liste[$i]['collation'] = $obj->Collation; - $i++; - } - $this->free($resql); - } else { - return null; - } - return $liste; - */ - return ''; // attente debugage + // FIXME: Dummy method + // TODO: Implement + + return ''; } /** @@ -1109,6 +1077,8 @@ class DoliDBMssql extends DoliDB */ function getPathOfDump() { + // FIXME: Dummy method + // TODO: Implement return ''; } @@ -1120,6 +1090,8 @@ class DoliDBMssql extends DoliDB */ function getPathOfRestore() { + // FIXME: Dummy method + // TODO: Implement return ''; } diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index f85eff1e5e1..a73e5f545bb 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -466,6 +466,9 @@ class DoliDBPgsql extends DoliDB */ function getDriverInfo() { + // FIXME: Dummy method + // TODO: Implement + return ''; } diff --git a/htdocs/core/db/sqlite.class.php b/htdocs/core/db/sqlite.class.php index 37460f0e23c..fb033bb65da 100644 --- a/htdocs/core/db/sqlite.class.php +++ b/htdocs/core/db/sqlite.class.php @@ -389,6 +389,9 @@ class DoliDBSqlite extends DoliDB */ function getDriverInfo() { + // FIXME: Dummy method + // TODO: Implement + return ''; }