Merge pull request #2422 from guedel/sqlite3-dev

Sqlite3 dev
This commit is contained in:
Laurent Destailleur 2015-03-11 02:54:15 +01:00
commit 4b8fa00edb
10 changed files with 1912 additions and 300 deletions

View File

@ -66,6 +66,10 @@ else if ($conf->db->type == 'mssql')
//$sqls[0] = ""; //$sqls[0] = "";
//$base=3; //$base=3;
} }
else if ($conf->db->type == 'sqlite3') {
//$sql = "SELECT name, type FROM sqlite_master";
$base = 4;
}
if (! $base) if (! $base)
@ -169,6 +173,40 @@ else
} }
print '</table>'; print '</table>';
} }
if ($base == 4)
{
// Sqlite3
print '<table class="noborder">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("TableName").'</td>';
print '<td>'.$langs->trans("NbOfRecord").'</td>';
print "</tr>\n";
$sql = "SELECT name, type FROM sqlite_master where type='table' and name not like 'sqlite%' ORDER BY name";
$resql = $db->query($sql);
if ($resql)
{
$var=True;
while ($row = $db->fetch_row($resql)) {
$rescount = $db->query("SELECT COUNT(*) FROM " . $row[0]);
if ($rescount) {
$row_count = $db->fetch_row($rescount);
$count = $row_count[0];
} else {
$count = '?';
}
print "<tr ".$bc[$var].">";
print '<td>'.$row[0].'</td>';
print '<td>'.$count.'</td>';
print '</tr>';
}
}
}
} }
llxFooter(); llxFooter();

5
htdocs/conf/phpinfo.php Normal file
View File

@ -0,0 +1,5 @@
<a href="index.php">Go back to index</a>
| <a href="<?php echo $_SERVER["REQUEST_URI"];?>">Refresh</a>
<br><br>
<?php phpinfo(); ?>

View File

@ -40,6 +40,12 @@ class DoliDBSqlite extends DoliDB
//! Resultset of last query //! Resultset of last query
private $_results; private $_results;
/**
* Indique que les fonctions personnalisées sont définies
* @var boolean
*/
private static $customFunctionsDefined = false;
/** /**
* Constructor. * Constructor.
* This create an opened connexion to a database server and eventually to a database * This create an opened connexion to a database server and eventually to a database
@ -153,7 +159,7 @@ class DoliDBSqlite extends DoliDB
// Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..." // 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)) { 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); $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line);
//$line = "-- ".$line." replaced by --\n".$newline; //$line = "-- ".$line." replaced by --\n".$newline;
$line=$newline; $line=$newline;
} }
@ -242,10 +248,17 @@ class DoliDBSqlite extends DoliDB
$line = "-- ".$line." replaced by --\n"; $line = "-- ".$line." replaced by --\n";
$line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")"; $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")";
} }
if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$line, $reg)) {
// Pour l'instant les contraintes ne sont pas créées
dol_syslog(get_class().'::query line emptied');
$line = 'SELECT 0;';
} }
// To have postgresql case sensitive //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) {
$line=str_replace(' LIKE \'',' ILIKE \'',$line); //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line);
//}
}
// Delete using criteria on other table must not declare twice the deleted table // Delete using criteria on other table must not declare twice the deleted table
// DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable
@ -387,7 +400,53 @@ class DoliDBSqlite extends DoliDB
$this->error = 0; $this->error = 0;
// Convert MySQL syntax to SQLite syntax // Convert MySQL syntax to SQLite syntax
if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*\(([\w,\s]+)\)\s*REFERENCES\s+(\w+)\s*\(([\w,\s]+)\)/i',$query, $reg)) {
// Ajout d'une clef étrangère à la table
// procédure de remplacement de la table pour ajouter la contrainte
// Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)
// -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid))
$foreignFields = $reg[5];
$foreignTable = $reg[4];
$localfields = $reg[3];
$constraintname=trim($reg[2]);
$tablename=trim($reg[1]);
$res = $this->db->query("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'");
$descTable = $res->fetchColumn();
$res->closeCursor();
// 1- Renommer la table avec un nom temporaire
$res = $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename);
$res->closeCursor();
// 2- Recréer la table avec la contrainte ajoutée
// on bricole la requete pour ajouter la contrainte
$descTable = substr($descTable, 0, strlen($descTable) - 1);
$descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")";
// fermeture de l'instruction
$descTable .= ')';
// Création proprement dite de la table
$res = $this->query($descTable);
$res->closeCursor();
// 3- Transférer les données
$res = $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename);
$res->closeCursor();
// 4- Supprimer la table temporaire
$res = $this->query('DROP TABLE tmp_' . $tablename);
$res->closeCursor();
// dummy statement
$query="SELECT 0";
} else {
$query=$this->convertSQLFromMysql($query,$type); $query=$this->convertSQLFromMysql($query,$type);
}
//print "After convertSQLFromMysql:\n".$query."<br>\n"; //print "After convertSQLFromMysql:\n".$query."<br>\n";
dol_syslog('sql='.$query, LOG_DEBUG); dol_syslog('sql='.$query, LOG_DEBUG);
@ -487,6 +546,10 @@ class DoliDBSqlite extends DoliDB
{ {
// If resultset not provided, we take the last used by connexion // If resultset not provided, we take the last used by connexion
if (! is_object($resultset)) { $resultset=$this->_results; } if (! is_object($resultset)) { $resultset=$this->_results; }
if (preg_match("/^SELECT/i", $resultset->queryString)) {
$res = $this->db->query("SELECT count(*) FROM (" . $resultset->queryString . ") q");
return $res->fetchColumn();
}
return $resultset->rowCount(); return $resultset->rowCount();
} }
@ -529,7 +592,12 @@ class DoliDBSqlite extends DoliDB
*/ */
function escape($stringtoencode) function escape($stringtoencode)
{ {
return $this->db->quote($stringtoencode); $ret = $this->db->quote($stringtoencode);
$l = strlen($ret);
if ($l >= 2) {
return substr($ret, 1, $l -2);
}
return '';
} }
/** /**
@ -1135,5 +1203,6 @@ class DoliDBSqlite extends DoliDB
return $result; return $result;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -781,11 +781,22 @@ abstract class DolibarrModules
if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility
if ($this->db->type == 'sqlite3') {
// sqlite doesn't support "USING" syntax.
// TODO: remove this dependency.
$sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes ";
$sql .= "WHERE ".MAIN_DB_PREFIX."boxes.box_id IN (";
$sql .= "SELECT ".MAIN_DB_PREFIX."boxes_def.rowid ";
$sql .= "FROM ".MAIN_DB_PREFIX."boxes_def ";
$sql .= "WHERE ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."') ";
$sql .= "AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity;
} else {
$sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes"; $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes";
$sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def"; $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def";
$sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid"; $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid";
$sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'"; $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'";
$sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity; $sql.= " AND ".MAIN_DB_PREFIX."boxes.entity = ".$conf->entity;
}
dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG); dol_syslog(get_class($this)."::delete_boxes", LOG_DEBUG);
$resql=$this->db->query($sql); $resql=$this->db->query($sql);
@ -1012,7 +1023,7 @@ abstract class DolibarrModules
if ($resql) if ($resql)
{ {
$obj=$this->db->fetch_object($resql); $obj=$this->db->fetch_object($resql);
if (! empty($obj->value) && ! empty($this->rights)) if ($obj !== null && ! empty($obj->value) && ! empty($this->rights))
{ {
// Si module actif // Si module actif
foreach ($this->rights as $key => $value) foreach ($this->rights as $key => $value)

View File

@ -86,12 +86,15 @@ if (! is_writable($conffile))
// Check parameters // Check parameters
$is_sqlite = false;
if (empty($db_type)) if (empty($db_type))
{ {
print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseType")).'</div>'; print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseType")).'</div>';
$error++; $error++;
} else {
$is_sqlite = ($db_type === 'sqlite' || $db_type === 'sqlite3' );
} }
if (empty($db_host)) if (empty($db_host) && ! $is_sqlite)
{ {
print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Server")).'</div>'; print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Server")).'</div>';
$error++; $error++;
@ -101,7 +104,7 @@ if (empty($db_name))
print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseName")).'</div>'; print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("DatabaseName")).'</div>';
$error++; $error++;
} }
if (empty($db_user)) if (empty($db_user) && ! $is_sqlite)
{ {
print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Login")).'</div>'; print '<div class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentities("Login")).'</div>';
$error++; $error++;

View File

@ -51,6 +51,8 @@ if ($dolibarr_main_db_type == "mysql") $choix=1;
if ($dolibarr_main_db_type == "mysqli") $choix=1; if ($dolibarr_main_db_type == "mysqli") $choix=1;
if ($dolibarr_main_db_type == "pgsql") $choix=2; if ($dolibarr_main_db_type == "pgsql") $choix=2;
if ($dolibarr_main_db_type == "mssql") $choix=3; if ($dolibarr_main_db_type == "mssql") $choix=3;
if ($dolibarr_main_db_type == "sqlite3") $choix=4;
//if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into etape2.php page'); //if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into etape2.php page');
// Now we load forced value from install.forced.php file. // Now we load forced value from install.forced.php file.
@ -411,6 +413,7 @@ if ($action == "set")
if ($choix==1) $dir = "mysql/functions/"; if ($choix==1) $dir = "mysql/functions/";
elseif ($choix==2) $dir = "pgsql/functions/"; elseif ($choix==2) $dir = "pgsql/functions/";
elseif ($choix==3) $dir = "mssql/functions/"; elseif ($choix==3) $dir = "mssql/functions/";
elseif ($choix==4) { $dir = "sqlite3/functions/"; }
// Creation donnees // Creation donnees
$file = "functions.sql"; $file = "functions.sql";

View File

@ -320,7 +320,7 @@ if (! empty($force_install_message))
if ($type=='mysqli') { $testfunction='mysqli_connect'; $testclass=''; } if ($type=='mysqli') { $testfunction='mysqli_connect'; $testclass=''; }
if ($type=='pgsql') { $testfunction='pg_connect'; $testclass=''; } if ($type=='pgsql') { $testfunction='pg_connect'; $testclass=''; }
if ($type=='mssql') { $testfunction='mssql_connect'; $testclass=''; } if ($type=='mssql') { $testfunction='mssql_connect'; $testclass=''; }
if ($type=='sqlite') { $testfunction=''; $testclass='PDO'; } if ($type=='sqlite3') { $testfunction=''; $testclass='SQLite3'; }
$option.='<option value="'.$type.'"'.($defaultype == $type?' selected="selected"':''); $option.='<option value="'.$type.'"'.($defaultype == $type?' selected="selected"':'');
if ($testfunction && ! function_exists($testfunction)) $option.=' disabled="disabled"'; if ($testfunction && ! function_exists($testfunction)) $option.=' disabled="disabled"';
if ($testclass && ! class_exists($testclass)) $option.=' disabled="disabled"'; if ($testclass && ! class_exists($testclass)) $option.=' disabled="disabled"';
@ -330,6 +330,7 @@ if (! empty($force_install_message))
// Experimental // Experimental
if ($type=='mssql') $option.=' '.$langs->trans("Experimental"); if ($type=='mssql') $option.=' '.$langs->trans("Experimental");
elseif ($type=='sqlite') $option.=' '.$langs->trans("Experimental"); elseif ($type=='sqlite') $option.=' '.$langs->trans("Experimental");
elseif ($type=='sqlite3') $option.=' '.$langs->trans("Experimental");
// No available // No available
elseif (! function_exists($testfunction)) $option.=' - '.$langs->trans("FunctionNotAvailableInThisPHP"); elseif (! function_exists($testfunction)) $option.=' - '.$langs->trans("FunctionNotAvailableInThisPHP");
$option.='</option>'; $option.='</option>';
@ -479,7 +480,7 @@ if (! empty($force_install_message))
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery("#db_type").change(function() { jQuery("#db_type").change(function() {
if (jQuery("#db_type").val()=='sqlite') { jQuery(".hidesqlite").hide(); } if (jQuery("#db_type").val()=='sqlite' || jQuery("#db_type").val()=='sqlite3') { jQuery(".hidesqlite").hide(); }
else { jQuery(".hidesqlite").show(); } else { jQuery(".hidesqlite").show(); }
}); });

View File