Work on PDO Sqlite driver

This commit is contained in:
Laurent Destailleur 2012-01-02 02:46:12 +01:00
parent fb662a91db
commit 6f63c5ecff
6 changed files with 227 additions and 49 deletions

View File

@ -507,7 +507,7 @@ class DoliDBPgsql
// Convert MySQL syntax to PostgresSQL syntax
$query=$this->convertSQLFromMysql($query,$type);
//print "FF\n".$query."<br>\n";
//print "After convertSQLFromMysql:\n".$query."<br>\n";
// Fix bad formed requests. If request contains a date without quotes, we fix this but this should not occurs.
$loop=true;
@ -786,7 +786,7 @@ class DoliDBPgsql
return 'DB_ERROR_FAILED_TO_CONNECT';
}
else {
// Constants to convert a MySql error code to a generic Dolibarr error code
// Constants to convert error code to a generic Dolibarr error code
$errorcode_map = array(
1004 => 'DB_ERROR_CANNOT_CREATE',
1005 => 'DB_ERROR_CANNOT_CREATE',

View File

@ -36,7 +36,7 @@ class DoliDBSqlite
//! Database type
public $type='sqlite';
//! Database label
static $label='Sqlite';
static $label='PDO Sqlite';
//! Charset used to force charset when creating database
static $forcecharset='utf8'; // latin1, utf8
//! Collate used to force collate when creating database
@ -148,7 +148,157 @@ class DoliDBSqlite
*/
function convertSQLFromMysql($line,$type='ddl')
{
return $line;
// Removed empty line if this is a comment line for SVN tagging
if (preg_match('/^--\s\$Id/i',$line)) {
return '';
}
// Return line if this is a comment
if (preg_match('/^#/i',$line) || preg_match('/^$/i',$line) || preg_match('/^--/i',$line))
{
return $line;
}
if ($line != "")
{
if ($type == 'auto')
{
if (preg_match('/ALTER TABLE/i',$line)) $type='dml';
else if (preg_match('/CREATE TABLE/i',$line)) $type='dml';
else if (preg_match('/DROP TABLE/i',$line)) $type='dml';
}
if ($type == 'dml')
{
$line=preg_replace('/\s/',' ',$line); // Replace tabulation with space
// we are inside create table statement so lets process datatypes
if (preg_match('/(ISAM|innodb)/i',$line)) { // end of create table sequence
$line=preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line);
$line=preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line);
$line=preg_replace('/,$/','',$line);
}
// Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..."
if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) {
$newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 SERIAL PRIMARY KEY',$line);
//$line = "-- ".$line." replaced by --\n".$newline;
$line=$newline;
}
// tinyint type conversion
$line=str_replace('tinyint','smallint',$line);
// nuke unsigned
$line=preg_replace('/(int\w+|smallint)\s+unsigned/i','\\1',$line);
// blob -> text
$line=preg_replace('/\w*blob/i','text',$line);
// tinytext/mediumtext -> text
$line=preg_replace('/tinytext/i','text',$line);
$line=preg_replace('/mediumtext/i','text',$line);
// change not null datetime field to null valid ones
// (to support remapping of "zero time" to null
$line=preg_replace('/datetime not null/i','datetime',$line);
$line=preg_replace('/datetime/i','timestamp',$line);
// double -> numeric
$line=preg_replace('/^double/i','numeric',$line);
$line=preg_replace('/(\s*)double/i','\\1numeric',$line);
// float -> numeric
$line=preg_replace('/^float/i','numeric',$line);
$line=preg_replace('/(\s*)float/i','\\1numeric',$line);
// unique index(field1,field2)
if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i',$line))
{
$line=preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i','UNIQUE\(\\1\)',$line);
}
// We remove end of requests "AFTER fieldxxx"
$line=preg_replace('/AFTER [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);
// Translate order to rename fields
if (preg_match('/ALTER TABLE ([a-z0-9_]+) CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i',$line,$reg))
{
$line = "-- ".$line." replaced by --\n";
$line.= "ALTER TABLE ".$reg[1]." RENAME COLUMN ".$reg[2]." TO ".$reg[3];
}
// Translate order to modify field format
if (preg_match('/ALTER TABLE ([a-z0-9_]+) MODIFY(?: COLUMN)? ([a-z0-9_]+) (.*)$/i',$line,$reg))
{
$line = "-- ".$line." replaced by --\n";
$newreg3=$reg[3];
$newreg3=preg_replace('/ DEFAULT NULL/i','',$newreg3);
$newreg3=preg_replace('/ NOT NULL/i','',$newreg3);
$newreg3=preg_replace('/ NULL/i','',$newreg3);
$newreg3=preg_replace('/ DEFAULT 0/i','',$newreg3);
$newreg3=preg_replace('/ DEFAULT \'[0-9a-zA-Z_@]*\'/i','',$newreg3);
$line.= "ALTER TABLE ".$reg[1]." ALTER COLUMN ".$reg[2]." TYPE ".$newreg3;
// TODO Add alter to set default value or null/not null if there is this in $reg[3]
}
// 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);
if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg))
{
$line = "-- ".$line." replaced by --\n";
$line.= "ALTER TABLE ".$reg[1]." ADD PRIMARY KEY (".$reg[3];
}
// Translate order to drop foreign keys
// 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 ...)
// 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))
{
$fieldlist=$reg[4];
$idxname=$reg[3];
$tablename=$reg[1];
$line = "-- ".$line." replaced by --\n";
$line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")";
}
}
// To have postgresql case sensitive
$line=str_replace(' LIKE \'',' ILIKE \'',$line);
// Delete using criteria on other table must not declare twice the deleted table
// DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable
if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg))
{
if ($reg[1] == $reg[2]) // If same table, we remove second one
{
$line=preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i','DELETE FROM \\1 USING \\3', $line);
}
}
// Remove () in the tables in FROM if one table
$line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line);
//print $line."\n";
// Remove () in the tables in FROM if two table
$line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2',$line);
//print $line."\n";
// Remove () in the tables in FROM if two table
$line=preg_replace('/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i','FROM \\1, \\2, \\3',$line);
//print $line."\n";
//print "type=".$type." newline=".$line."<br>\n";
}
return $line;
}
/**
@ -188,6 +338,7 @@ class DoliDBSqlite
try {
/*** connect to SQLite database ***/
$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb');
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
@ -337,11 +488,16 @@ class DoliDBSqlite
$ret='';
$query = trim($query);
$this->error = 0;
// Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE)
// Convert MySQL syntax to SQLite syntax
$query=$this->convertSQLFromMysql($query,$type);
//print "After convertSQLFromMysql:\n".$query."<br>\n";
// Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE)
try {
//$ret = $this->db->exec($query);
$ret = $this->db->query($query);
$ret = $this->db->query($query); // $ret is a PDO object
}
catch(PDOException $e)
{
@ -351,12 +507,13 @@ class DoliDBSqlite
if (! preg_match("/^COMMIT/i",$query) && ! preg_match("/^ROLLBACK/i",$query))
{
// Si requete utilisateur, on la sauvegarde ainsi que son resultset
if (! $ret)
if (! is_object($ret) || $this->error)
{
$this->lastqueryerror = $query;
$this->lasterror = $this->error();
$this->lasterrno = $this->errno();
dol_syslog(get_class($this)."::query SQL error: ".$query." ".$this->lasterrno, LOG_WARNING);
if (preg_match('/[0-9]/',$this->lasterrno)) dol_syslog(get_class($this)."::query SQL error: ".$query." ".$this->lasterrno." ".$this->lasterror, LOG_WARNING);
else dol_syslog(get_class($this)."::query SQL error: ".$query." ".$this->lasterrno, LOG_WARNING);
}
$this->lastquery=$query;
$this->results = $ret;
@ -424,11 +581,12 @@ class DoliDBSqlite
{
// If resultset not provided, we take the last used by connexion
if (! is_object($resultset)) { $resultset=$this->results; }
return sqlite_num_rows($resultset);
return $resultset->rowCount();
}
/**
* Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE
*
* @see num_rows
* @param resultset Curseur de la requete voulue
* @return int Nombre de lignes
@ -440,7 +598,7 @@ class DoliDBSqlite
if (! is_object($resultset)) { $resultset=$this->results; }
// mysql necessite un link de base pour cette fonction contrairement
// a pqsql qui prend un resultset
return sqlite_affected_rows($this->db);
return $resultset->rowCount();
}
@ -454,7 +612,7 @@ class DoliDBSqlite
// If resultset not provided, we take the last used by connexion
if (! is_object($resultset)) { $resultset=$this->results; }
// Si resultset en est un, on libere la memoire
if (is_object($resultset)) sqlite_free_result($resultset);
if (is_object($resultset)) $resultset->closeCursor();
}
@ -558,8 +716,9 @@ class DoliDBSqlite
/**
* \brief Renvoie la derniere requete soumise par la methode query()
* \return lastquery
* Renvoie la derniere requete soumise par la methode query()
*
* @return lastquery
*/
function lastquery()
{
@ -567,8 +726,9 @@ class DoliDBSqlite
}
/**
* \brief Renvoie la derniere requete en erreur
* \return string lastqueryerror
* Renvoie la derniere requete en erreur
*
* @return string lastqueryerror
*/
function lastqueryerror()
{
@ -576,8 +736,9 @@ class DoliDBSqlite
}
/**
* \brief Renvoie le libelle derniere erreur
* \return string lasterror
* Renvoie le libelle derniere erreur
*
* @return string lasterror
*/
function lasterror()
{
@ -585,8 +746,9 @@ class DoliDBSqlite
}
/**
* \brief Renvoie le code derniere erreur
* \return string lasterrno
* Renvoie le code derniere erreur
*
* @return string lasterrno
*/
function lasterrno()
{
@ -594,8 +756,9 @@ class DoliDBSqlite
}
/**
* \brief Renvoie le code erreur generique de l'operation precedente.
* \return error_num (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...)
* Renvoie le code erreur generique de l'operation precedente.
*
* @return string $error_num (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...)
*/
function errno()
{
@ -604,8 +767,8 @@ class DoliDBSqlite
return 'DB_ERROR_FAILED_TO_CONNECT';
}
else {
// Constants to convert a MySql error code to a generic Dolibarr error code
$errorcode_map = array(
// Constants to convert error code to a generic Dolibarr error code
/*$errorcode_map = array(
1004 => 'DB_ERROR_CANNOT_CREATE',
1005 => 'DB_ERROR_CANNOT_CREATE',
1006 => 'DB_ERROR_CANNOT_CREATE',
@ -615,7 +778,7 @@ class DoliDBSqlite
1044 => 'DB_ERROR_ACCESSDENIED',
1046 => 'DB_ERROR_NODBSELECTED',
1048 => 'DB_ERROR_CONSTRAINT',
1050 => 'DB_ERROR_TABLE_ALREADY_EXISTS',
'HY000' => 'DB_ERROR_TABLE_ALREADY_EXISTS',
1051 => 'DB_ERROR_NOSUCHTABLE',
1054 => 'DB_ERROR_NOSUCHFIELD',
1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS',
@ -636,16 +799,28 @@ class DoliDBSqlite
if (isset($errorcode_map[$this->db->errorCode()]))
{
return $errorcode_map[$this->db->errorCode()];
}
}*/
$errno=$this->db->errorCode();
if ($errno=='HY000')
{
if (preg_match('/table.*already exists/i',$this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS';
elseif (preg_match('/index.*already exists/i',$this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS';
elseif (preg_match('/syntax error/i',$this->error)) return 'DB_ERROR_SYNTAX';
}
if ($errno=='23000')
{
if (preg_match('/column.* not unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS';
elseif (preg_match('/PRIMARY KEY must be unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS';
}
return ($errno?'DB_ERROR_'.$errno:'0');
}
}
/**
* \brief Renvoie le texte de l'erreur mysql de l'operation precedente.
* \return error_text
* Renvoie le texte de l'erreur mysql de l'operation precedente.
*
* @return string $error_text
*/
function error()
{

View File

@ -45,10 +45,12 @@ $langs->setDefaultLang($setuplang);
$langs->load("admin");
$langs->load("install");
$choix=0;
if ($dolibarr_main_db_type == "mysql") $choix=1;
if ($dolibarr_main_db_type == "mysqli") $choix=1;
if ($dolibarr_main_db_type == "pgsql") $choix=2;
if ($dolibarr_main_db_type == "mssql") $choix=3;
//if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into etape2.php page');
// Init "forced values" to nothing. "forced values" are used after a Doliwamp install wizard.
$useforcedwizard=false;
@ -188,7 +190,7 @@ if ($action == "set")
{
$buffer=preg_replace('/type=innodb/i','ENGINE=innodb',$buffer);
}
// Replace the prefix tables
if ($dolibarr_main_db_prefix != 'llx_')
{
@ -337,7 +339,7 @@ if ($action == "set")
{
$buffer=preg_replace('/llx_/i',$dolibarr_main_db_prefix,$buffer);
}
//print "<tr><td>Creation des cles et index de la table $name: '$buffer'</td>";
$requestnb++;
@ -547,7 +549,7 @@ if ($action == "set")
{
$buffer=preg_replace('/llx_/i',$dolibarr_main_db_prefix,$buffer);
}
//dolibarr_install_syslog("Request: ".$buffer,LOG_DEBUG);
$resql=$db->query($buffer);
if ($resql)

View File

@ -291,13 +291,14 @@ if (! empty($force_install_message))
if ($defaultype=='mysqli' && !function_exists('mysqli_connect')) $defaultype = 'mysql';
// Show line into list
if ($type=='mysql') { $testfunction='mysql_connect'; }
if ($type=='mysqli') { $testfunction='mysqli_connect'; }
if ($type=='pgsql') { $testfunction='pg_connect'; }
if ($type=='mssql') { $testfunction='mssql_connect'; }
if ($type=='sqlite') { $testfunction='notyetready'; }
if ($type=='mysql') { $testfunction='mysql_connect'; $testclass=''; }
if ($type=='mysqli') { $testfunction='mysqli_connect'; $testclass=''; }
if ($type=='pgsql') { $testfunction='pg_connect'; $testclass=''; }
if ($type=='mssql') { $testfunction='mssql_connect'; $testclass=''; }
if ($type=='sqlite') { $testfunction=''; $testclass='PDO'; }
$option.='<option value="'.$type.'"'.($defaultype == $type?' selected="selected"':'');
if (! function_exists($testfunction)) $option.=' disabled="disabled"';
if ($testfunction && ! function_exists($testfunction)) $option.=' disabled="disabled"';
if ($testclass && ! class_exists($testclass)) $option.=' disabled="disabled"';
$option.='>';
$option.=$type.'&nbsp; &nbsp;';
if ($note) $option.=' '.$note;
@ -321,7 +322,7 @@ if (! empty($force_install_message))
</tr>
<tr>
<tr class="hidesqlite">
<td valign="top" class="label"><b> <?php echo $langs->trans("Server"); ?>
</b></td>
<td valign="top" class="label"><input type="text"
@ -335,7 +336,7 @@ if (! empty($force_install_message))
</tr>
<tr>
<tr class="hidesqlite">
<td valign="top" class="label"><?php echo $langs->trans("Port"); ?></td>
<td valign="top" class="label"><input type="text"
name="db_port<?php print ($force_install_noedit==2 && $force_install_port)?'_bis':''; ?>"
@ -348,7 +349,7 @@ if (! empty($force_install_message))
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><?php echo $langs->trans("DatabasePrefix"); ?>
</td>
@ -358,7 +359,7 @@ if (! empty($force_install_message))
<td class="comment"><?php echo $langs->trans("DatabasePrefix"); ?></td>
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><?php echo $langs->trans("CreateDatabase"); ?>
</td>
@ -369,7 +370,7 @@ if (! empty($force_install_message))
</td>
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><b><?php echo $langs->trans("Login"); ?></b>
</td>
<td class="label" valign="top"><input type="text" id="db_user"
@ -378,7 +379,7 @@ if (! empty($force_install_message))
<td class="comment"><?php echo $langs->trans("AdminLogin"); ?></td>
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><b><?php echo $langs->trans("Password"); ?></b>
</td>
<td class="label" valign="top"><input type="password" id="db_pass"
@ -387,7 +388,7 @@ if (! empty($force_install_message))
<td class="comment"><?php echo $langs->trans("AdminPassword"); ?></td>
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><?php echo $langs->trans("CreateUser"); ?>
</td>
@ -404,13 +405,13 @@ if (! empty($force_install_message))
$force_install_databaserootlogin=preg_replace('/__SUPERUSERLOGIN__/','root',$force_install_databaserootlogin);
$force_install_databaserootpass=preg_replace('/__SUPERUSERPASSWORD__/','',$force_install_databaserootpass);
?>
<tr>
<tr class="hidesqlite">
<td colspan="3" class="label" align="center"><br>
<h3><?php echo $langs->trans("DatabaseSuperUserAccess"); ?></h3>
</td>
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><?php echo $langs->trans("Login"); ?></td>
<td class="label" valign="top"><input type="text" id="db_user_root"
name="db_user_root" class="needroot"
@ -427,7 +428,7 @@ if (! empty($force_install_message))
</tr>
<tr>
<tr class="hidesqlite">
<td class="label" valign="top"><?php echo $langs->trans("Password"); ?>
</td>
<td class="label" valign="top"><input type="password"

View File

@ -55,8 +55,8 @@ insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,no
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (74,'19','19272',3,'CORREZE','Corrèze');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (94,'2A','2A004',3,'CORSE-DU-SUD','Corse-du-Sud');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (94,'2B','2B033',3,'HAUTE-CORSE','Haute-Corse');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (26,'21','21231',3,'COTE-D\'OR','Côte-d\'Or');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (53,'22','22278',4,'COTES-D\'ARMOR','Côtes-d\'Armor');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (26,'21','21231',3,'COTE-D OR','Côte-d Or');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (53,'22','22278',4,'COTES-D ARMOR','Côtes-d Armor');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (74,'23','23096',3,'CREUSE','Creuse');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (72,'24','24322',3,'DORDOGNE','Dordogne');
insert into llx_c_departements (fk_region, code_departement,cheflieu,tncc,ncc,nom) values (43,'25','25056',2,'DOUBS','Doubs');

View File

@ -50,6 +50,6 @@ insert into llx_c_chargesociales (id, libelle, deductible, active, code, fk_pays
--
insert into llx_c_chargesociales (id, libelle, deductible, active, code, fk_pays) values (201, 'ONSS', 1,1,'TAXBEONSS' ,'2');
insert into llx_c_chargesociales (id, libelle, deductible, active, code, fk_pays) values (210, 'Precompte professionnel', 1,1,'TAXBEPREPRO' ,'2');
insert into llx_c_chargesociales (id, libelle, deductible, active, code, fk_pays) values (220, 'Prime d\'existence', 1,1,'TAXBEPRIEXI' ,'2');
insert into llx_c_chargesociales (id, libelle, deductible, active, code, fk_pays) values (220, 'Prime existence', 1,1,'TAXBEPRIEXI' ,'2');
insert into llx_c_chargesociales (id, libelle, deductible, active, code, fk_pays) values (230, 'Precompte immobilier', 1,1,'TAXBEPREIMMO','2');