dolibarr  13.0.2
sqlite3.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2001 Fabien Seisen <seisen@linuxfr.org>
3  * Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
4  * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
5  * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
6  * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
7  * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  */
22 
28 require_once DOL_DOCUMENT_ROOT.'/core/db/DoliDB.class.php';
29 
33 class DoliDBSqlite3 extends DoliDB
34 {
36  public $type = 'sqlite3';
38  const LABEL = 'Sqlite3';
40  const VERSIONMIN = '3.0.0';
42  private $_results;
43 
44  const WEEK_MONDAY_FIRST = 1;
45  const WEEK_YEAR = 2;
46  const WEEK_FIRST_WEEKDAY = 4;
47 
48 
60  public function __construct($type, $host, $user, $pass, $name = '', $port = 0)
61  {
62  global $conf;
63 
64  // Note that having "static" property for "$forcecharset" and "$forcecollate" will make error here in strict mode, so they are not static
65  if (!empty($conf->db->character_set)) $this->forcecharset = $conf->db->character_set;
66  if (!empty($conf->db->dolibarr_main_db_collation)) $this->forcecollate = $conf->db->dolibarr_main_db_collation;
67 
68  $this->database_user = $user;
69  $this->database_host = $host;
70  $this->database_port = $port;
71 
72  $this->transaction_opened = 0;
73 
74  //print "Name DB: $host,$user,$pass,$name<br>";
75 
76  /*if (! function_exists("sqlite_query"))
77  {
78  $this->connected = false;
79  $this->ok = false;
80  $this->error="Sqlite PHP functions for using Sqlite driver are not available in this version of PHP. Try to use another driver.";
81  dol_syslog(get_class($this)."::DoliDBSqlite3 : Sqlite PHP functions for using Sqlite driver are not available in this version of PHP. Try to use another driver.",LOG_ERR);
82  return $this->ok;
83  }*/
84 
85  /*if (! $host)
86  {
87  $this->connected = false;
88  $this->ok = false;
89  $this->error=$langs->trans("ErrorWrongHostParameter");
90  dol_syslog(get_class($this)."::DoliDBSqlite3 : Erreur Connect, wrong host parameters",LOG_ERR);
91  return $this->ok;
92  }*/
93 
94  // Essai connexion serveur
95  // We do not try to connect to database, only to server. Connect to database is done later in constrcutor
96  $this->db = $this->connect($host, $user, $pass, $name, $port);
97 
98  if ($this->db)
99  {
100  $this->connected = true;
101  $this->ok = true;
102  $this->database_selected = true;
103  $this->database_name = $name;
104 
105  $this->addCustomFunction('IF');
106  $this->addCustomFunction('MONTH');
107  $this->addCustomFunction('CURTIME');
108  $this->addCustomFunction('CURDATE');
109  $this->addCustomFunction('WEEK', 1);
110  $this->addCustomFunction('WEEK', 2);
111  $this->addCustomFunction('WEEKDAY');
112  $this->addCustomFunction('date_format');
113  //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
114  } else {
115  // host, login ou password incorrect
116  $this->connected = false;
117  $this->ok = false;
118  $this->database_selected = false;
119  $this->database_name = '';
120  //$this->error=sqlite_connect_error();
121  dol_syslog(get_class($this)."::DoliDBSqlite3 : Error Connect ".$this->error, LOG_ERR);
122  }
123 
124  return $this->ok;
125  }
126 
127 
135  public static function convertSQLFromMysql($line, $type = 'ddl')
136  {
137  // Removed empty line if this is a comment line for SVN tagging
138  if (preg_match('/^--\s\$Id/i', $line)) {
139  return '';
140  }
141  // Return line if this is a comment
142  if (preg_match('/^#/i', $line) || preg_match('/^$/i', $line) || preg_match('/^--/i', $line))
143  {
144  return $line;
145  }
146  if ($line != "")
147  {
148  if ($type == 'auto')
149  {
150  if (preg_match('/ALTER TABLE/i', $line)) $type = 'dml';
151  elseif (preg_match('/CREATE TABLE/i', $line)) $type = 'dml';
152  elseif (preg_match('/DROP TABLE/i', $line)) $type = 'dml';
153  }
154 
155  if ($type == 'dml')
156  {
157  $line = preg_replace('/\s/', ' ', $line); // Replace tabulation with space
158 
159  // we are inside create table statement so lets process datatypes
160  if (preg_match('/(ISAM|innodb)/i', $line)) { // end of create table sequence
161  $line = preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i', ');', $line);
162  $line = preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i', ');', $line);
163  $line = preg_replace('/,$/', '', $line);
164  }
165 
166  // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..."
167  if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i', $line, $reg)) {
168  $newline = preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i', '\\1 \\2 integer PRIMARY KEY AUTOINCREMENT', $line);
169  //$line = "-- ".$line." replaced by --\n".$newline;
170  $line = $newline;
171  }
172 
173  // tinyint type conversion
174  $line = str_replace('tinyint', 'smallint', $line);
175 
176  // nuke unsigned
177  $line = preg_replace('/(int\w+|smallint)\s+unsigned/i', '\\1', $line);
178 
179  // blob -> text
180  $line = preg_replace('/\w*blob/i', 'text', $line);
181 
182  // tinytext/mediumtext -> text
183  $line = preg_replace('/tinytext/i', 'text', $line);
184  $line = preg_replace('/mediumtext/i', 'text', $line);
185 
186  // change not null datetime field to null valid ones
187  // (to support remapping of "zero time" to null
188  $line = preg_replace('/datetime not null/i', 'datetime', $line);
189  $line = preg_replace('/datetime/i', 'timestamp', $line);
190 
191  // double -> numeric
192  $line = preg_replace('/^double/i', 'numeric', $line);
193  $line = preg_replace('/(\s*)double/i', '\\1numeric', $line);
194  // float -> numeric
195  $line = preg_replace('/^float/i', 'numeric', $line);
196  $line = preg_replace('/(\s*)float/i', '\\1numeric', $line);
197 
198  // unique index(field1,field2)
199  if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i', $line))
200  {
201  $line = preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i', 'UNIQUE\(\\1\)', $line);
202  }
203 
204  // We remove end of requests "AFTER fieldxxx"
205  $line = preg_replace('/AFTER [a-z0-9_]+/i', '', $line);
206 
207  // We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX
208  $line = preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i', 'DROP INDEX', $line);
209 
210  // Translate order to rename fields
211  if (preg_match('/ALTER TABLE ([a-z0-9_]+) CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i', $line, $reg))
212  {
213  $line = "-- ".$line." replaced by --\n";
214  $line .= "ALTER TABLE ".$reg[1]." RENAME COLUMN ".$reg[2]." TO ".$reg[3];
215  }
216 
217  // Translate order to modify field format
218  if (preg_match('/ALTER TABLE ([a-z0-9_]+) MODIFY(?: COLUMN)? ([a-z0-9_]+) (.*)$/i', $line, $reg))
219  {
220  $line = "-- ".$line." replaced by --\n";
221  $newreg3 = $reg[3];
222  $newreg3 = preg_replace('/ DEFAULT NULL/i', '', $newreg3);
223  $newreg3 = preg_replace('/ NOT NULL/i', '', $newreg3);
224  $newreg3 = preg_replace('/ NULL/i', '', $newreg3);
225  $newreg3 = preg_replace('/ DEFAULT 0/i', '', $newreg3);
226  $newreg3 = preg_replace('/ DEFAULT \'[0-9a-zA-Z_@]*\'/i', '', $newreg3);
227  $line .= "ALTER TABLE ".$reg[1]." ALTER COLUMN ".$reg[2]." TYPE ".$newreg3;
228  // TODO Add alter to set default value or null/not null if there is this in $reg[3]
229  }
230 
231  // alter table add primary key (field1, field2 ...) -> We create a unique index instead as dynamic creation of primary key is not supported
232  // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity);
233  if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i', $line, $reg))
234  {
235  $line = "-- ".$line." replaced by --\n";
236  $line .= "CREATE UNIQUE INDEX ".$reg[2]." ON ".$reg[1]."(".$reg[3];
237  }
238 
239  // Translate order to drop foreign keys
240  // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx;
241  if (preg_match('/ALTER\s+TABLE\s*(.*)\s*DROP\s+FOREIGN\s+KEY\s*(.*)$/i', $line, $reg))
242  {
243  $line = "-- ".$line." replaced by --\n";
244  $line .= "ALTER TABLE ".$reg[1]." DROP CONSTRAINT ".$reg[2];
245  }
246 
247  // alter table add [unique] [index] (field1, field2 ...)
248  // ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version)
249  if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i', $line, $reg))
250  {
251  $fieldlist = $reg[4];
252  $idxname = $reg[3];
253  $tablename = $reg[1];
254  $line = "-- ".$line." replaced by --\n";
255  $line .= "CREATE ".(preg_match('/UNIQUE/', $reg[2]) ? 'UNIQUE ' : '')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")";
256  }
257  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)) {
258  // Pour l'instant les contraintes ne sont pas créées
259  dol_syslog(get_class().'::query line emptied');
260  $line = 'SELECT 0;';
261  }
262 
263  //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) {
264  //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line);
265  //}
266  }
267 
268  // Delete using criteria on other table must not declare twice the deleted table
269  // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable
270  if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i', $line, $reg))
271  {
272  if ($reg[1] == $reg[2]) // If same table, we remove second one
273  {
274  $line = preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i', 'DELETE FROM \\1 USING \\3', $line);
275  }
276  }
277 
278  // Remove () in the tables in FROM if one table
279  $line = preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i', 'FROM \\1', $line);
280  //print $line."\n";
281 
282  // Remove () in the tables in FROM if two table
283  $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);
284  //print $line."\n";
285 
286  // Remove () in the tables in FROM if two table
287  $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);
288  //print $line."\n";
289 
290  //print "type=".$type." newline=".$line."<br>\n";
291  }
292 
293  return $line;
294  }
295 
296  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
303  public function select_db($database)
304  {
305  // phpcs:enable
306  dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG);
307  // sqlite_select_db() does not exist
308  //return sqlite_select_db($this->db,$database);
309  return true;
310  }
311 
312 
324  public function connect($host, $login, $passwd, $name, $port = 0)
325  {
326  global $main_data_dir;
327 
328  dol_syslog(get_class($this)."::connect name=".$name, LOG_DEBUG);
329 
330  $dir = $main_data_dir;
331  if (empty($dir)) $dir = DOL_DATA_ROOT;
332  // With sqlite, port must be in connect parameters
333  //if (! $newport) $newport=3306;
334  $database_name = $dir.'/database_'.$name.'.sdb';
335  try {
336  /*** connect to SQLite database ***/
337  //$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb');
338  $this->db = new SQLite3($database_name);
339  //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
340  } catch (Exception $e)
341  {
342  $this->error = self::LABEL.' '.$e->getMessage().' current dir='.$database_name;
343  return '';
344  }
345 
346  //print "Resultat fonction connect: ".$this->db;
347  return $this->db;
348  }
349 
350 
356  public function getVersion()
357  {
358  $tmp = $this->db->version();
359  return $tmp['versionString'];
360  }
361 
367  public function getDriverInfo()
368  {
369  return 'sqlite3 php driver';
370  }
371 
372 
379  public function close()
380  {
381  if ($this->db)
382  {
383  if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened, LOG_ERR);
384  $this->connected = false;
385  $this->db->close();
386  unset($this->db); // Clean this->db
387  return true;
388  }
389  return false;
390  }
391 
401  public function query($query, $usesavepoint = 0, $type = 'auto')
402  {
403  global $conf;
404 
405  $ret = null;
406 
407  $query = trim($query);
408 
409  $this->error = '';
410 
411  // Convert MySQL syntax to SQLite syntax
412  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)) {
413  // Ajout d'une clef étrangère à la table
414  // procédure de remplacement de la table pour ajouter la contrainte
415  // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)
416  // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid))
417  $foreignFields = $reg[5];
418  $foreignTable = $reg[4];
419  $localfields = $reg[3];
420  $constraintname = trim($reg[2]);
421  $tablename = trim($reg[1]);
422 
423  $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='".$this->escape($tablename)."'");
424 
425  // 1- Renommer la table avec un nom temporaire
426  $this->query('ALTER TABLE '.$tablename.' RENAME TO tmp_'.$tablename);
427 
428  // 2- Recréer la table avec la contrainte ajoutée
429 
430  // on bricole la requete pour ajouter la contrainte
431  $descTable = substr($descTable, 0, strlen($descTable) - 1);
432  $descTable .= ", CONSTRAINT ".$constraintname." FOREIGN KEY (".$localfields.") REFERENCES ".$foreignTable."(".$foreignFields.")";
433 
434  // fermeture de l'instruction
435  $descTable .= ')';
436 
437  // Création proprement dite de la table
438  $this->query($descTable);
439 
440  // 3- Transférer les données
441  $this->query('INSERT INTO '.$tablename.' SELECT * FROM tmp_'.$tablename);
442 
443  // 4- Supprimer la table temporaire
444  $this->query('DROP TABLE tmp_'.$tablename);
445 
446  // dummy statement
447  $query = "SELECT 0";
448  } else {
449  $query = $this->convertSQLFromMysql($query, $type);
450  }
451  //print "After convertSQLFromMysql:\n".$query."<br>\n";
452 
453  if (!in_array($query, array('BEGIN', 'COMMIT', 'ROLLBACK')))
454  {
455  $SYSLOG_SQL_LIMIT = 10000; // limit log to 10kb per line to limit DOS attacks
456  dol_syslog('sql='.substr($query, 0, $SYSLOG_SQL_LIMIT), LOG_DEBUG);
457  }
458  if (empty($query)) return false; // Return false = error if empty request
459 
460  // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE)
461  try {
462  //$ret = $this->db->exec($query);
463  $ret = $this->db->query($query); // $ret is a Sqlite3Result
464  if ($ret) {
465  $ret->queryString = $query;
466  }
467  } catch (Exception $e)
468  {
469  $this->error = $this->db->lastErrorMsg();
470  }
471 
472  if (!preg_match("/^COMMIT/i", $query) && !preg_match("/^ROLLBACK/i", $query))
473  {
474  // Si requete utilisateur, on la sauvegarde ainsi que son resultset
475  if (!is_object($ret) || $this->error)
476  {
477  $this->lastqueryerror = $query;
478  $this->lasterror = $this->error();
479  $this->lasterrno = $this->errno();
480 
481  dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR);
482 
483  $errormsg = get_class($this)."::query SQL Error message: ".$this->lasterror;
484 
485  if (preg_match('/[0-9]/', $this->lasterrno)) {
486  $errormsg .= ' ('.$this->lasterrno.')';
487  }
488 
489  if ($conf->global->SYSLOG_LEVEL < LOG_DEBUG) dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR); // Log of request was not yet done previously
490  dol_syslog(get_class($this)."::query SQL Error message: ".$errormsg, LOG_ERR);
491  }
492  $this->lastquery = $query;
493  $this->_results = $ret;
494  }
495 
496  return $ret;
497  }
498 
499  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
506  public function fetch_object($resultset)
507  {
508  // phpcs:enable
509  // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
510  if (!is_object($resultset)) { $resultset = $this->_results; }
511  //return $resultset->fetch(PDO::FETCH_OBJ);
512  $ret = $resultset->fetchArray(SQLITE3_ASSOC);
513  if ($ret) {
514  return (object) $ret;
515  }
516  return false;
517  }
518 
519 
520  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
527  public function fetch_array($resultset)
528  {
529  // phpcs:enable
530  // If resultset not provided, we take the last used by connexion
531  if (!is_object($resultset)) { $resultset = $this->_results; }
532  //return $resultset->fetch(PDO::FETCH_ASSOC);
533  $ret = $resultset->fetchArray(SQLITE3_ASSOC);
534  return $ret;
535  }
536 
537  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
544  public function fetch_row($resultset)
545  {
546  // phpcs:enable
547  // If resultset not provided, we take the last used by connexion
548  if (!is_bool($resultset))
549  {
550  if (!is_object($resultset)) { $resultset = $this->_results; }
551  return $resultset->fetchArray(SQLITE3_NUM);
552  } else {
553  // si le curseur est un booleen on retourne la valeur 0
554  return false;
555  }
556  }
557 
558  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
566  public function num_rows($resultset)
567  {
568  // phpcs:enable
569  // FIXME: SQLite3Result does not have a queryString member
570 
571  // If resultset not provided, we take the last used by connexion
572  if (!is_object($resultset)) { $resultset = $this->_results; }
573  if (preg_match("/^SELECT/i", $resultset->queryString)) {
574  return $this->db->querySingle("SELECT count(*) FROM (".$resultset->queryString.") q");
575  }
576  return 0;
577  }
578 
579  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
587  public function affected_rows($resultset)
588  {
589  // phpcs:enable
590  // FIXME: SQLite3Result does not have a queryString member
591 
592  // If resultset not provided, we take the last used by connexion
593  if (!is_object($resultset)) { $resultset = $this->_results; }
594  if (preg_match("/^SELECT/i", $resultset->queryString)) {
595  return $this->num_rows($resultset);
596  }
597  // mysql necessite un link de base pour cette fonction contrairement
598  // a pqsql qui prend un resultset
599  return $this->db->changes();
600  }
601 
602 
609  public function free($resultset = null)
610  {
611  // If resultset not provided, we take the last used by connexion
612  if (!is_object($resultset)) { $resultset = $this->_results; }
613  // Si resultset en est un, on libere la memoire
614  if ($resultset && is_object($resultset)) $resultset->finalize();
615  }
616 
623  public function escape($stringtoencode)
624  {
625  return Sqlite3::escapeString($stringtoencode);
626  }
627 
633  public function errno()
634  {
635  if (!$this->connected) {
636  // Si il y a eu echec de connexion, $this->db n'est pas valide.
637  return 'DB_ERROR_FAILED_TO_CONNECT';
638  } else {
639  // Constants to convert error code to a generic Dolibarr error code
640  /*$errorcode_map = array(
641  1004 => 'DB_ERROR_CANNOT_CREATE',
642  1005 => 'DB_ERROR_CANNOT_CREATE',
643  1006 => 'DB_ERROR_CANNOT_CREATE',
644  1007 => 'DB_ERROR_ALREADY_EXISTS',
645  1008 => 'DB_ERROR_CANNOT_DROP',
646  1025 => 'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
647  1044 => 'DB_ERROR_ACCESSDENIED',
648  1046 => 'DB_ERROR_NODBSELECTED',
649  1048 => 'DB_ERROR_CONSTRAINT',
650  'HY000' => 'DB_ERROR_TABLE_ALREADY_EXISTS',
651  1051 => 'DB_ERROR_NOSUCHTABLE',
652  1054 => 'DB_ERROR_NOSUCHFIELD',
653  1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS',
654  1061 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
655  1062 => 'DB_ERROR_RECORD_ALREADY_EXISTS',
656  1064 => 'DB_ERROR_SYNTAX',
657  1068 => 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
658  1075 => 'DB_ERROR_CANT_DROP_PRIMARY_KEY',
659  1091 => 'DB_ERROR_NOSUCHFIELD',
660  1100 => 'DB_ERROR_NOT_LOCKED',
661  1136 => 'DB_ERROR_VALUE_COUNT_ON_ROW',
662  1146 => 'DB_ERROR_NOSUCHTABLE',
663  1216 => 'DB_ERROR_NO_PARENT',
664  1217 => 'DB_ERROR_CHILD_EXISTS',
665  1451 => 'DB_ERROR_CHILD_EXISTS'
666  );
667 
668  if (isset($errorcode_map[$this->db->errorCode()]))
669  {
670  return $errorcode_map[$this->db->errorCode()];
671  }*/
672  $errno = $this->db->lastErrorCode();
673  if ($errno == 'HY000' || $errno == 0)
674  {
675  if (preg_match('/table.*already exists/i', $this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS';
676  elseif (preg_match('/index.*already exists/i', $this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS';
677  elseif (preg_match('/syntax error/i', $this->error)) return 'DB_ERROR_SYNTAX';
678  }
679  if ($errno == '23000')
680  {
681  if (preg_match('/column.* not unique/i', $this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS';
682  elseif (preg_match('/PRIMARY KEY must be unique/i', $this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS';
683  }
684  if ($errno > 1) {
685  // TODO Voir la liste des messages d'erreur
686  }
687 
688  return ($errno ? 'DB_ERROR_'.$errno : '0');
689  }
690  }
691 
697  public function error()
698  {
699  if (!$this->connected) {
700  // Si il y a eu echec de connexion, $this->db n'est pas valide pour sqlite_error.
701  return 'Not connected. Check setup parameters in conf/conf.php file and your sqlite version';
702  } else {
703  return $this->error;
704  }
705  }
706 
707  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
715  public function last_insert_id($tab, $fieldid = 'rowid')
716  {
717  // phpcs:enable
718  return $this->db->lastInsertRowId();
719  }
720 
729  public function encrypt($fieldorvalue, $withQuotes = 0)
730  {
731  global $conf;
732 
733  // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
734  $cryptType = ($conf->db->dolibarr_main_db_encryption ? $conf->db->dolibarr_main_db_encryption : 0);
735 
736  //Encryption key
737  $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey) ? $conf->db->dolibarr_main_db_cryptkey : '');
738 
739  $return = ($withQuotes ? "'" : "").$this->escape($fieldorvalue).($withQuotes ? "'" : "");
740 
741  if ($cryptType && !empty($cryptKey))
742  {
743  if ($cryptType == 2)
744  {
745  $return = 'AES_ENCRYPT('.$return.',\''.$cryptKey.'\')';
746  } elseif ($cryptType == 1)
747  {
748  $return = 'DES_ENCRYPT('.$return.',\''.$cryptKey.'\')';
749  }
750  }
751 
752  return $return;
753  }
754 
761  public function decrypt($value)
762  {
763  global $conf;
764 
765  // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
766  $cryptType = ($conf->db->dolibarr_main_db_encryption ? $conf->db->dolibarr_main_db_encryption : 0);
767 
768  //Encryption key
769  $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey) ? $conf->db->dolibarr_main_db_cryptkey : '');
770 
771  $return = $value;
772 
773  if ($cryptType && !empty($cryptKey))
774  {
775  if ($cryptType == 2)
776  {
777  $return = 'AES_DECRYPT('.$value.',\''.$cryptKey.'\')';
778  } elseif ($cryptType == 1)
779  {
780  $return = 'DES_DECRYPT('.$value.',\''.$cryptKey.'\')';
781  }
782  }
783 
784  return $return;
785  }
786 
787 
788  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
794  public function DDLGetConnectId()
795  {
796  // phpcs:enable
797  return '?';
798  }
799 
800 
801  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
813  public function DDLCreateDb($database, $charset = '', $collation = '', $owner = '')
814  {
815  // phpcs:enable
816  if (empty($charset)) $charset = $this->forcecharset;
817  if (empty($collation)) $collation = $this->forcecollate;
818 
819  // ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci
820  $sql = 'CREATE DATABASE '.$database;
821  $sql .= ' DEFAULT CHARACTER SET '.$charset.' DEFAULT COLLATE '.$collation;
822 
823  dol_syslog($sql, LOG_DEBUG);
824  $ret = $this->query($sql);
825  if (!$ret)
826  {
827  // We try again for compatibility with Mysql < 4.1.1
828  $sql = 'CREATE DATABASE '.$database;
829  $ret = $this->query($sql);
830  dol_syslog($sql, LOG_DEBUG);
831  }
832  return $ret;
833  }
834 
835  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
843  public function DDLListTables($database, $table = '')
844  {
845  // phpcs:enable
846  $listtables = array();
847 
848  $like = '';
849  if ($table) $like = "LIKE '".$table."'";
850  $sql = "SHOW TABLES FROM ".$database." ".$like.";";
851  //print $sql;
852  $result = $this->query($sql);
853  if ($result)
854  {
855  while ($row = $this->fetch_row($result))
856  {
857  $listtables[] = $row[0];
858  }
859  }
860  return $listtables;
861  }
862 
863  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
871  public function DDLInfoTable($table)
872  {
873  // phpcs:enable
874  $infotables = array();
875 
876  $sql = "SHOW FULL COLUMNS FROM ".$table.";";
877 
878  dol_syslog($sql, LOG_DEBUG);
879  $result = $this->query($sql);
880  if ($result)
881  {
882  while ($row = $this->fetch_row($result))
883  {
884  $infotables[] = $row;
885  }
886  }
887  return $infotables;
888  }
889 
890  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
903  public function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null)
904  {
905  // phpcs:enable
906  // FIXME: $fulltext_keys parameter is unused
907 
908  // cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
909  // ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
910  $sql = "create table ".$table."(";
911  $i = 0;
912  foreach ($fields as $field_name => $field_desc)
913  {
914  $sqlfields[$i] = $field_name." ";
915  $sqlfields[$i] .= $field_desc['type'];
916  if (preg_match("/^[^\s]/i", $field_desc['value']))
917  $sqlfields[$i] .= "(".$field_desc['value'].")";
918  elseif (preg_match("/^[^\s]/i", $field_desc['attribute']))
919  $sqlfields[$i] .= " ".$field_desc['attribute'];
920  elseif (preg_match("/^[^\s]/i", $field_desc['default']))
921  {
922  if (preg_match("/null/i", $field_desc['default']))
923  $sqlfields[$i] .= " default ".$field_desc['default'];
924  else $sqlfields[$i] .= " default '".$this->escape($field_desc['default'])."'";
925  } elseif (preg_match("/^[^\s]/i", $field_desc['null']))
926  $sqlfields[$i] .= " ".$field_desc['null'];
927 
928  elseif (preg_match("/^[^\s]/i", $field_desc['extra']))
929  $sqlfields[$i] .= " ".$field_desc['extra'];
930  $i++;
931  }
932  if ($primary_key != "")
933  $pk = "primary key(".$primary_key.")";
934 
935  if (is_array($unique_keys))
936  {
937  $i = 0;
938  foreach ($unique_keys as $key => $value)
939  {
940  $sqluq[$i] = "UNIQUE KEY '".$key."' ('".$this->escape($value)."')";
941  $i++;
942  }
943  }
944  if (is_array($keys))
945  {
946  $i = 0;
947  foreach ($keys as $key => $value)
948  {
949  $sqlk[$i] = "KEY ".$key." (".$value.")";
950  $i++;
951  }
952  }
953  $sql .= implode(',', $sqlfields);
954  if ($primary_key != "")
955  $sql .= ",".$pk;
956  if (is_array($unique_keys))
957  $sql .= ",".implode(',', $sqluq);
958  if (is_array($keys))
959  $sql .= ",".implode(',', $sqlk);
960  $sql .= ") type=".$type;
961 
962  dol_syslog($sql, LOG_DEBUG);
963  if (!$this -> query($sql))
964  return -1;
965  return 1;
966  }
967 
968  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
975  public function DDLDropTable($table)
976  {
977  // phpcs:enable
978  $sql = "DROP TABLE ".$table;
979 
980  if (!$this->query($sql))
981  return -1;
982  else return 1;
983  }
984 
985  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
993  public function DDLDescTable($table, $field = "")
994  {
995  // phpcs:enable
996  $sql = "DESC ".$table." ".$field;
997 
998  dol_syslog(get_class($this)."::DDLDescTable ".$sql, LOG_DEBUG);
999  $this->_results = $this->query($sql);
1000  return $this->_results;
1001  }
1002 
1003  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1013  public function DDLAddField($table, $field_name, $field_desc, $field_position = "")
1014  {
1015  // phpcs:enable
1016  // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
1017  // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
1018  $sql = "ALTER TABLE ".$table." ADD ".$field_name." ";
1019  $sql .= $field_desc['type'];
1020  if (preg_match("/^[^\s]/i", $field_desc['value']))
1021  if (!in_array($field_desc['type'], array('date', 'datetime')))
1022  {
1023  $sql .= "(".$field_desc['value'].")";
1024  }
1025  if (preg_match("/^[^\s]/i", $field_desc['attribute']))
1026  $sql .= " ".$field_desc['attribute'];
1027  if (preg_match("/^[^\s]/i", $field_desc['null']))
1028  $sql .= " ".$field_desc['null'];
1029  if (preg_match("/^[^\s]/i", $field_desc['default']))
1030  {
1031  if (preg_match("/null/i", $field_desc['default']))
1032  $sql .= " default ".$field_desc['default'];
1033  else $sql .= " default '".$this->escape($field_desc['default'])."'";
1034  }
1035  if (preg_match("/^[^\s]/i", $field_desc['extra']))
1036  $sql .= " ".$field_desc['extra'];
1037  $sql .= " ".$field_position;
1038 
1039  dol_syslog(get_class($this)."::DDLAddField ".$sql, LOG_DEBUG);
1040  if (!$this->query($sql))
1041  {
1042  return -1;
1043  }
1044  return 1;
1045  }
1046 
1047  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1056  public function DDLUpdateField($table, $field_name, $field_desc)
1057  {
1058  // phpcs:enable
1059  $sql = "ALTER TABLE ".$table;
1060  $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
1061  if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') {
1062  $sql .= "(".$field_desc['value'].")";
1063  }
1064 
1065  dol_syslog(get_class($this)."::DDLUpdateField ".$sql, LOG_DEBUG);
1066  if (!$this->query($sql))
1067  return -1;
1068  return 1;
1069  }
1070 
1071  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1079  public function DDLDropField($table, $field_name)
1080  {
1081  // phpcs:enable
1082  $sql = "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`";
1083  dol_syslog(get_class($this)."::DDLDropField ".$sql, LOG_DEBUG);
1084  if (!$this->query($sql))
1085  {
1086  $this->error = $this->lasterror();
1087  return -1;
1088  }
1089  return 1;
1090  }
1091 
1092 
1093  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1103  public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
1104  {
1105  // phpcs:enable
1106  $sql = "INSERT INTO user ";
1107  $sql .= "(Host,User,password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)";
1108  $sql .= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_user)."',password('".addslashes($dolibarr_main_db_pass)."')";
1109  $sql .= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')";
1110 
1111  dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
1112  $resql = $this->query($sql);
1113  if (!$resql)
1114  {
1115  return -1;
1116  }
1117 
1118  $sql = "INSERT INTO db ";
1119  $sql .= "(Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)";
1120  $sql .= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_name)."','".addslashes($dolibarr_main_db_user)."'";
1121  $sql .= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')";
1122 
1123  dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);
1124  $resql = $this->query($sql);
1125  if (!$resql)
1126  {
1127  return -1;
1128  }
1129 
1130  $sql = "FLUSH Privileges";
1131 
1132  dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);
1133  $resql = $this->query($sql);
1134  if (!$resql)
1135  {
1136  return -1;
1137  }
1138  return 1;
1139  }
1140 
1146  public function getDefaultCharacterSetDatabase()
1147  {
1148  return 'UTF-8';
1149  }
1150 
1156  public function getListOfCharacterSet()
1157  {
1158  $liste = array();
1159  $i = 0;
1160  $liste[$i]['charset'] = 'UTF-8';
1161  $liste[$i]['description'] = 'UTF-8';
1162  return $liste;
1163  }
1164 
1170  public function getDefaultCollationDatabase()
1171  {
1172  return 'UTF-8';
1173  }
1174 
1180  public function getListOfCollation()
1181  {
1182  $liste = array();
1183  $i = 0;
1184  $liste[$i]['charset'] = 'UTF-8';
1185  $liste[$i]['description'] = 'UTF-8';
1186  return $liste;
1187  }
1188 
1194  public function getPathOfDump()
1195  {
1196  // FIXME: not for SQLite
1197  $fullpathofdump = '/pathtomysqldump/mysqldump';
1198 
1199  $resql = $this->query('SHOW VARIABLES LIKE \'basedir\'');
1200  if ($resql)
1201  {
1202  $liste = $this->fetch_array($resql);
1203  $basedir = $liste['Value'];
1204  $fullpathofdump = $basedir.(preg_match('/\/$/', $basedir) ? '' : '/').'bin/mysqldump';
1205  }
1206  return $fullpathofdump;
1207  }
1208 
1214  public function getPathOfRestore()
1215  {
1216  // FIXME: not for SQLite
1217  $fullpathofimport = '/pathtomysql/mysql';
1218 
1219  $resql = $this->query('SHOW VARIABLES LIKE \'basedir\'');
1220  if ($resql)
1221  {
1222  $liste = $this->fetch_array($resql);
1223  $basedir = $liste['Value'];
1224  $fullpathofimport = $basedir.(preg_match('/\/$/', $basedir) ? '' : '/').'bin/mysql';
1225  }
1226  return $fullpathofimport;
1227  }
1228 
1235  public function getServerParametersValues($filter = '')
1236  {
1237  $result = array();
1238  static $pragmas;
1239  if (!isset($pragmas)) {
1240  // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur
1241  // indépendante de la base de données.
1242  // cf. http://www.sqlite.org/pragma.html
1243  $pragmas = array(
1244  'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size',
1245  'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list',
1246  'compile_options', 'data_version', /*'database_list',*/
1247  'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count',
1248  'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check',
1249  'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode',
1250  'max_page_count', 'page_count', 'page_size', 'parser_trace',
1251  'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers',
1252  'reverse_unordered_selects', 'schema_version', 'user_version',
1253  'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit',
1254  'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads',
1255  'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace',
1256  'wal_autocheckpoint',
1257  );
1258  }
1259 
1260  // TODO prendre en compte le filtre
1261  foreach ($pragmas as $var) {
1262  $sql = "PRAGMA $var";
1263  $resql = $this->query($sql);
1264  if ($resql)
1265  {
1266  $obj = $this->fetch_row($resql);
1267  //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG);
1268  $result[$var] = $obj[0];
1269  } else {
1270  // TODO Récupérer le message
1271  $result[$var] = 'FAIL';
1272  }
1273  }
1274  return $result;
1275  }
1276 
1283  public function getServerStatusValues($filter = '')
1284  {
1285  $result = array();
1286  /*
1287  $sql='SHOW STATUS';
1288  if ($filter) $sql.=" LIKE '".$this->escape($filter)."'";
1289  $resql=$this->query($sql);
1290  if ($resql)
1291  {
1292  while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value;
1293  }
1294  */
1295 
1296  return $result;
1297  }
1298 
1308  private function addCustomFunction($name, $arg_count = -1)
1309  {
1310  if ($this->db)
1311  {
1312  $newname = preg_replace('/_/', '', $name);
1313  $localname = __CLASS__.'::db'.$newname;
1314  $reflectClass = new ReflectionClass(__CLASS__);
1315  $reflectFunction = $reflectClass->getMethod('db'.$newname);
1316  if ($arg_count < 0) {
1317  $arg_count = $reflectFunction->getNumberOfParameters();
1318  }
1319  if (!$this->db->createFunction($name, $localname, $arg_count))
1320  {
1321  $this->error = "unable to create custom function '$name'";
1322  }
1323  }
1324  }
1325 
1326  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1335  private static function calc_daynr($year, $month, $day)
1336  {
1337  // phpcs:enable
1338  $y = $year;
1339  if ($y == 0 && $month == 0) return 0;
1340  $num = (365 * $y + 31 * ($month - 1) + $day);
1341  if ($month <= 2) {
1342  $y--; } else {
1343  $num -= floor(($month * 4 + 23) / 10);
1344  }
1345  $temp = floor(($y / 100 + 1) * 3 / 4);
1346  return $num + floor($y / 4) - $temp;
1347  }
1348 
1349  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1357  private static function calc_weekday($daynr, $sunday_first_day_of_week)
1358  {
1359  // phpcs:enable
1360  $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7);
1361  return $ret;
1362  }
1363 
1364  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1371  private static function calc_days_in_year($year)
1372  {
1373  // phpcs:enable
1374  return (($year & 3) == 0 && ($year % 100 || ($year % 400 == 0 && $year)) ? 366 : 365);
1375  }
1376 
1377  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1388  private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year)
1389  {
1390  // phpcs:enable
1391  $daynr = self::calc_daynr($year, $month, $day);
1392  $first_daynr = self::calc_daynr($year, 1, 1);
1393  $monday_first = ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0;
1394  $week_year = ($week_behaviour & self::WEEK_YEAR) ? 1 : 0;
1395  $first_weekday = ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0;
1396 
1397  $weekday = self::calc_weekday($first_daynr, !$monday_first);
1398  $calc_year = $year;
1399 
1400  if ($month == 1 && $day <= 7 - $weekday) {
1401  if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)))
1402  return 0;
1403  $week_year = 1;
1404  $calc_year--;
1405  $first_daynr -= ($days = self::calc_days_in_year($calc_year));
1406  $weekday = ($weekday + 53 * 7 - $days) % 7;
1407  }
1408 
1409  if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) {
1410  $days = $daynr - ($first_daynr + (7 - $weekday));
1411  } else {
1412  $days = $daynr - ($first_daynr - $weekday);
1413  }
1414 
1415  if ($week_year && $days >= 52 * 7) {
1416  $weekday = ($weekday + self::calc_days_in_year($calc_year)) % 7;
1417  if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0)) {
1418  $calc_year++;
1419  return 1;
1420  }
1421  }
1422  return floor($days / 7 + 1);
1423  }
1424 }
addCustomFunction($name, $arg_count=-1)
Permet le chargement d&#39;une fonction personnalisee dans le moteur de base de donnees.
const LABEL
Database label.
lastqueryerror()
Return last query in error.
getDriverInfo()
Return version of database client driver.
select_db($database)
Select a database.
last_insert_id($tab, $fieldid= 'rowid')
Get last ID after an insert INSERT.
</td > param sortfield sortorder printFieldListOption< tdclass="liste_titremaxwidthsearchright"></td ></tr >< trclass="liste_titre">< inputtype="checkbox"onClick="toggle(this)"/> Ref p ref Label p label Duration p duration center DesiredStock p desiredstock right StockLimitShort p seuil_stock_alerte right stock_physique right stock_real_warehouse right Ordered right StockToBuy right SupplierRef right param sortfield sortorder printFieldListTitle warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow StockTooLow help help help< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"> stock</td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:750
error()
Renvoie le texte de l&#39;erreur mysql de l&#39;operation precedente.
escape($stringtoencode)
Escape a string to insert data.
lastquery()
Return last request executed with query()
encrypt($fieldorvalue, $withQuotes=0)
Encrypt sensitive data in database Warning: This function includes the escape, so it must use direct ...
</td >< tdcolspan="3">< spanclass="opacitymedium"></span ></td ></tr >< trclass="liste_total"> CREANCES DETTES< tdcolspan="3"class="right"></td >< tdcolspan="3"class="right"></td ></tr > CREANCES DETTES RECETTES DEPENSES trips CREANCES DETTES Y m expensereport p date_valid Y m expensereport pe datep $db idate($date_start)."' AND $column < p rowid
$type
Database type.
Class to manage Dolibarr database access.
static calc_days_in_year($year)
calc_days_in_year
connect($host, $login, $passwd, $name, $port=0)
Connexion to server.
lasterror()
Return last error label.
$conf db
API class for accounts.
Definition: inc.php:54
close()
Close database connexion.
free($resultset=null)
Free last resultset used.
getServerParametersValues($filter= '')
Return value of server parameters.
const VERSIONMIN
Version min database.
static calc_week($year, $month, $day, $week_behaviour, &$calc_year)
calc_week
fetch_array($resultset)
Return datas as an array.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
getPathOfRestore()
Return full path of restore program.
fetch_row($resultset)
Return datas as an array.
fetch_object($resultset)
Renvoie la ligne courante (comme un objet) pour le curseur resultset.
num_rows($resultset)
Return number of lines for result of a SELECT.
affected_rows($resultset)
Return number of lines for result of a SELECT.
__construct($type, $host, $user, $pass, $name= '', $port=0)
Constructor.
query($query, $usesavepoint=0, $type= 'auto')
Execute a SQL request and return the resultset.
static calc_weekday($daynr, $sunday_first_day_of_week)
calc_weekday
static convertSQLFromMysql($line, $type= 'ddl')
Convert a SQL request in Mysql syntax to native syntax.
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
lasterrno()
Return last error code.
Class to manage Dolibarr database access for a SQLite database.
getServerStatusValues($filter= '')
Return value of server status.
static calc_daynr($year, $month, $day)
calc_daynr
errno()
Renvoie le code erreur generique de l&#39;operation precedente.
getVersion()
Return version of database server.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:105