diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php
index a2e6a9e3b83..6e60bd29b87 100644
--- a/htdocs/core/db/mssql.class.php
+++ b/htdocs/core/db/mssql.class.php
@@ -157,7 +157,7 @@ class DoliDBMssql
* @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
* @return string SQL request line converted
*/
- function convertSQLFromMysql($line,$type='ddl')
+ static function convertSQLFromMysql($line,$type='ddl')
{
return $line;
}
diff --git a/htdocs/core/db/mysql.class.php b/htdocs/core/db/mysql.class.php
index 4dee1c977bf..89c8885d74a 100644
--- a/htdocs/core/db/mysql.class.php
+++ b/htdocs/core/db/mysql.class.php
@@ -185,7 +185,7 @@ class DoliDBMysql
* @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
* @return string SQL request line converted
*/
- function convertSQLFromMysql($line,$type='ddl')
+ static function convertSQLFromMysql($line,$type='ddl')
{
return $line;
}
diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php
index 7afea5a8da3..82496a9e3cd 100644
--- a/htdocs/core/db/mysqli.class.php
+++ b/htdocs/core/db/mysqli.class.php
@@ -188,7 +188,7 @@ class DoliDBMysqli
* @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
* @return string SQL request line converted
*/
- function convertSQLFromMysql($line,$type='ddl')
+ static function convertSQLFromMysql($line,$type='ddl')
{
return $line;
}
diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php
index f2c867191c0..2f42a9cb9c4 100644
--- a/htdocs/core/db/pgsql.class.php
+++ b/htdocs/core/db/pgsql.class.php
@@ -157,11 +157,12 @@ class DoliDBPgsql
/**
* 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
+ * @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...)
+ * @param string $unescapeslashquot Unescape slash quote with quote quote
+ * @return string SQL request line converted
*/
- function convertSQLFromMysql($line,$type='auto')
+ static function convertSQLFromMysql($line,$type='auto',$unescapeslashquot=0)
{
// Removed empty line if this is a comment line for SVN tagging
if (preg_match('/^--\s\$Id/i',$line)) {
@@ -231,7 +232,7 @@ class DoliDBPgsql
}
// We remove end of requests "AFTER fieldxxx"
- $line=preg_replace('/AFTER [a-z0-9_]+/i','',$line);
+ $line=preg_replace('/\sAFTER [a-z0-9_]+/i','',$line);
// We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX
$line=preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i','DROP INDEX',$line);
@@ -258,7 +259,7 @@ class DoliDBPgsql
}
// alter table add primary key (field1, field2 ...) -> We remove the primary key name not accepted by PostGreSQL
- // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity);
+ // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity)
if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg))
{
$line = "-- ".$line." replaced by --\n";
@@ -266,14 +267,21 @@ class DoliDBPgsql
}
// Translate order to drop foreign keys
- // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx;
+ // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx
if (preg_match('/ALTER\s+TABLE\s*(.*)\s*DROP\s+FOREIGN\s+KEY\s*(.*)$/i',$line,$reg))
{
$line = "-- ".$line." replaced by --\n";
$line.= "ALTER TABLE ".$reg[1]." DROP CONSTRAINT ".$reg[2];
}
- // alter table add [unique] [index] (field1, field2 ...)
+ // Translate order to add foreign keys
+ // ALTER TABLE llx_tablechild ADD CONSTRAINT fk_tablechild_fk_fieldparent FOREIGN KEY (fk_fieldparent) REFERENCES llx_tableparent (rowid)
+ if (preg_match('/ALTER\s+TABLE\s+(.*)\s*ADD CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*(.*)$/i',$line,$reg))
+ {
+ $line.=" DEFERRABLE INITIALLY IMMEDIATE";
+ }
+
+ // alter table add [unique] [index] (field1, field2 ...)
// ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version)
if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i',$line,$reg))
{
@@ -319,17 +327,10 @@ class DoliDBPgsql
//print $line."\n";
// Replace espacing \' by ''.
- // By default we do not (should be already done by db->escape function if required)
- if (! empty($this->unescapeslashquot))
- {
- // Except for sql insert in data file that
- // are mysql escaped so we removed them to be compatible with standard_conforming_strings=on
- // that considers \ as ordinary character).
- if ($this->standard_conforming_strings)
- {
- $line=preg_replace("/\\\'/","''",$line);
- }
- }
+ // By default we do not (should be already done by db->escape function if required
+ // except for sql insert in data file that are mysql escaped so we removed them to
+ // be compatible with standard_conforming_strings=on that considers \ as ordinary character).
+ if ($unescapeslashquot) $line=preg_replace("/\\\'/","''",$line);
//print "type=".$type." newline=".$line."
\n";
}
@@ -542,7 +543,7 @@ class DoliDBPgsql
$query = trim($query);
// Convert MySQL syntax to PostgresSQL syntax
- $query=$this->convertSQLFromMysql($query,$type);
+ $query=$this->convertSQLFromMysql($query,$type,($this->unescapeslashquot && $this->standard_conforming_strings));
//print "After convertSQLFromMysql:\n".$query."
\n";
// Fix bad formed requests. If request contains a date without quotes, we fix this but this should not occurs.
diff --git a/htdocs/core/db/sqlite.class.php b/htdocs/core/db/sqlite.class.php
index c7a02ecded1..f7f72475fbe 100644
--- a/htdocs/core/db/sqlite.class.php
+++ b/htdocs/core/db/sqlite.class.php
@@ -146,7 +146,7 @@ class DoliDBSqlite
* @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
* @return string SQL request line converted
*/
- function convertSQLFromMysql($line,$type='ddl')
+ static function convertSQLFromMysql($line,$type='ddl')
{
// Removed empty line if this is a comment line for SVN tagging
if (preg_match('/^--\s\$Id/i',$line)) {
diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php
index 41073db30cc..c8fb505336f 100644
--- a/test/phpunit/AllTests.php
+++ b/test/phpunit/AllTests.php
@@ -72,14 +72,16 @@ class AllTests
$suite->addTestSuite('ImagesLibTest');
require_once dirname(__FILE__).'/FunctionsTest.php';
$suite->addTestSuite('FunctionsTest');
- require_once dirname(__FILE__).'/_NumberingModulesTest.php';
- $suite->addTestSuite('NumberingModulesTest');
- require_once dirname(__FILE__).'/PdfDocTest.php';
- $suite->addTestSuite('PdfDocTest');
require_once dirname(__FILE__).'/SecurityTest.php';
$suite->addTestSuite('SecurityTest');
+ require_once dirname(__FILE__).'/_NumberingModulesTest.php';
+ $suite->addTestSuite('NumberingModulesTest');
+ require_once dirname(__FILE__).'/PgsqlTest.php';
+ $suite->addTestSuite('PgsqlTest');
+ require_once dirname(__FILE__).'/PdfDocTest.php';
+ $suite->addTestSuite('PdfDocTest');
require_once dirname(__FILE__).'/BuildDocTest.php';
$suite->addTestSuite('BuildDocTest');
require_once dirname(__FILE__).'/CMailFileTest.php';
diff --git a/test/phpunit/PgsqlTest.php b/test/phpunit/PgsqlTest.php
new file mode 100755
index 00000000000..18ec1246547
--- /dev/null
+++ b/test/phpunit/PgsqlTest.php
@@ -0,0 +1,165 @@
+
+ *
+ * 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 2 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 .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file test/phpunit/PgsqlTest.php
+ * \ingroup test
+ * \brief PHPUnit test
+ * \remarks To run this script as CLI: phpunit filename.php
+ */
+
+global $conf,$user,$langs,$db;
+//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
+require_once 'PHPUnit/Autoload.php';
+require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
+$langs->load("dict");
+
+if (empty($user->id))
+{
+ print "Load permissions for admin user nb 1\n";
+ $user->fetch(1);
+ $user->getrights();
+}
+
+$conf->global->MAIN_DISABLE_ALL_MAILS=1;
+
+
+/**
+ * Class for PHPUnit tests
+ *
+ * @backupGlobals disabled
+ * @backupStaticAttributes enabled
+ * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased.
+ */
+class PgsqlTest extends PHPUnit_Framework_TestCase
+{
+ protected $savconf;
+ protected $savuser;
+ protected $savlangs;
+ protected $savdb;
+
+ /**
+ * Constructor
+ * We save global variables into local variables
+ *
+ * @return ContactTest
+ */
+ function PgsqlTest()
+ {
+ //$this->sharedFixture
+ global $conf,$user,$langs,$db;
+ $this->savconf=$conf;
+ $this->savuser=$user;
+ $this->savlangs=$langs;
+ $this->savdb=$db;
+
+ print __METHOD__." db->type=".$db->type." user->id=".$user->id;
+ //print " - db ".$db->db;
+ print "\n";
+ }
+
+ // Static methods
+ public static function setUpBeforeClass()
+ {
+ global $conf,$user,$langs,$db;
+
+ $db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
+
+ print __METHOD__."\n";
+ }
+ public static function tearDownAfterClass()
+ {
+ global $conf,$user,$langs,$db;
+ $db->rollback();
+
+ print __METHOD__."\n";
+ }
+
+ /**
+ * Init phpunit tests
+ *
+ * @return void
+ */
+ protected function setUp()
+ {
+ global $conf,$user,$langs,$db;
+ $conf=$this->savconf;
+ $user=$this->savuser;
+ $langs=$this->savlangs;
+ $db=$this->savdb;
+
+ print __METHOD__."\n";
+ }
+ /**
+ * End phpunit tests
+ *
+ * @return void
+ */
+ protected function tearDown()
+ {
+ print __METHOD__."\n";
+ }
+
+ /**
+ * testConvertSQLFromMysql
+ *
+ * @return int
+ */
+ public function testConvertSQLFromMysql()
+ {
+ global $conf,$user,$langs,$db;
+ $conf=$this->savconf;
+ $user=$this->savuser;
+ $langs=$this->savlangs;
+ $db=$this->savdb;
+
+ $sql="ALTER TABLE llx_table RENAME TO llx_table_new";
+ $result=DoliDBPgsql::convertSQLFromMysql($sql);
+ print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, "ALTER TABLE llx_table RENAME TO llx_table_new");
+
+ $sql="ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol";
+ $result=DoliDBPgsql::convertSQLFromMysql($sql);
+ print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, "ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0'");
+
+ $sql="ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60)";
+ $result=DoliDBPgsql::convertSQLFromMysql($sql);
+ print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, "-- ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60) replaced by --\nALTER TABLE llx_table RENAME COLUMN oldname TO newname");
+
+ $sql="ALTER TABLE llx_table DROP COLUMN oldname";
+ $result=DoliDBPgsql::convertSQLFromMysql($sql);
+ print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, $sql);
+
+ $sql="ALTER TABLE llx_table MODIFY name varchar(60)";
+ $result=DoliDBPgsql::convertSQLFromMysql($sql);
+ print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, "-- ALTER TABLE llx_table MODIFY name varchar(60) replaced by --\nALTER TABLE llx_table ALTER COLUMN name TYPE varchar(60)");
+
+ // Create a constraint
+ $sql='ALTER TABLE llx_tablechild ADD CONSTRAINT fk_tablechild_fk_fieldparent FOREIGN KEY (fk_fieldparent) REFERENCES llx_tableparent (rowid)';
+ $result=DoliDBPgsql::convertSQLFromMysql($sql);
+ print __METHOD__." result=".$result."\n";
+ $this->assertEquals($result, $sql.' DEFERRABLE INITIALLY IMMEDIATE');
+
+ return $result;
+ }
+}
+?>