dolibarr  9.0.0
sqlite3.class.php
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 <http://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  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  }
115  else
116  {
117  // host, login ou password incorrect
118  $this->connected = false;
119  $this->ok = false;
120  $this->database_selected = false;
121  $this->database_name = '';
122  //$this->error=sqlite_connect_error();
123  dol_syslog(get_class($this)."::DoliDBSqlite3 : Error Connect ".$this->error,LOG_ERR);
124  }
125 
126  return $this->ok;
127  }
128 
129 
137  static function convertSQLFromMysql($line,$type='ddl')
138  {
139  // Removed empty line if this is a comment line for SVN tagging
140  if (preg_match('/^--\s\$Id/i',$line)) {
141  return '';
142  }
143  // Return line if this is a comment
144  if (preg_match('/^#/i',$line) || preg_match('/^$/i',$line) || preg_match('/^--/i',$line))
145  {
146  return $line;
147  }
148  if ($line != "")
149  {
150  if ($type == 'auto')
151  {
152  if (preg_match('/ALTER TABLE/i',$line)) $type='dml';
153  else if (preg_match('/CREATE TABLE/i',$line)) $type='dml';
154  else if (preg_match('/DROP TABLE/i',$line)) $type='dml';
155  }
156 
157  if ($type == 'dml')
158  {
159  $line=preg_replace('/\s/',' ',$line); // Replace tabulation with space
160 
161  // we are inside create table statement so lets process datatypes
162  if (preg_match('/(ISAM|innodb)/i',$line)) { // end of create table sequence
163  $line=preg_replace('/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line);
164  $line=preg_replace('/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb);/i',');',$line);
165  $line=preg_replace('/,$/','',$line);
166  }
167 
168  // Process case: "CREATE TABLE llx_mytable(rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY,code..."
169  if (preg_match('/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i',$line,$reg)) {
170  $newline=preg_replace('/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i','\\1 \\2 integer PRIMARY KEY AUTOINCREMENT',$line);
171  //$line = "-- ".$line." replaced by --\n".$newline;
172  $line=$newline;
173  }
174 
175  // tinyint type conversion
176  $line=str_replace('tinyint','smallint',$line);
177 
178  // nuke unsigned
179  $line=preg_replace('/(int\w+|smallint)\s+unsigned/i','\\1',$line);
180 
181  // blob -> text
182  $line=preg_replace('/\w*blob/i','text',$line);
183 
184  // tinytext/mediumtext -> text
185  $line=preg_replace('/tinytext/i','text',$line);
186  $line=preg_replace('/mediumtext/i','text',$line);
187 
188  // change not null datetime field to null valid ones
189  // (to support remapping of "zero time" to null
190  $line=preg_replace('/datetime not null/i','datetime',$line);
191  $line=preg_replace('/datetime/i','timestamp',$line);
192 
193  // double -> numeric
194  $line=preg_replace('/^double/i','numeric',$line);
195  $line=preg_replace('/(\s*)double/i','\\1numeric',$line);
196  // float -> numeric
197  $line=preg_replace('/^float/i','numeric',$line);
198  $line=preg_replace('/(\s*)float/i','\\1numeric',$line);
199 
200  // unique index(field1,field2)
201  if (preg_match('/unique index\s*\((\w+\s*,\s*\w+)\)/i',$line))
202  {
203  $line=preg_replace('/unique index\s*\((\w+\s*,\s*\w+)\)/i','UNIQUE\(\\1\)',$line);
204  }
205 
206  // We remove end of requests "AFTER fieldxxx"
207  $line=preg_replace('/AFTER [a-z0-9_]+/i','',$line);
208 
209  // We remove start of requests "ALTER TABLE tablexxx" if this is a DROP INDEX
210  $line=preg_replace('/ALTER TABLE [a-z0-9_]+ DROP INDEX/i','DROP INDEX',$line);
211 
212  // Translate order to rename fields
213  if (preg_match('/ALTER TABLE ([a-z0-9_]+) CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i',$line,$reg))
214  {
215  $line = "-- ".$line." replaced by --\n";
216  $line.= "ALTER TABLE ".$reg[1]." RENAME COLUMN ".$reg[2]." TO ".$reg[3];
217  }
218 
219  // Translate order to modify field format
220  if (preg_match('/ALTER TABLE ([a-z0-9_]+) MODIFY(?: COLUMN)? ([a-z0-9_]+) (.*)$/i',$line,$reg))
221  {
222  $line = "-- ".$line." replaced by --\n";
223  $newreg3=$reg[3];
224  $newreg3=preg_replace('/ DEFAULT NULL/i','',$newreg3);
225  $newreg3=preg_replace('/ NOT NULL/i','',$newreg3);
226  $newreg3=preg_replace('/ NULL/i','',$newreg3);
227  $newreg3=preg_replace('/ DEFAULT 0/i','',$newreg3);
228  $newreg3=preg_replace('/ DEFAULT \'[0-9a-zA-Z_@]*\'/i','',$newreg3);
229  $line.= "ALTER TABLE ".$reg[1]." ALTER COLUMN ".$reg[2]." TYPE ".$newreg3;
230  // TODO Add alter to set default value or null/not null if there is this in $reg[3]
231  }
232 
233  // alter table add primary key (field1, field2 ...) -> We create a unique index instead as dynamic creation of primary key is not supported
234  // ALTER TABLE llx_dolibarr_modules ADD PRIMARY KEY pk_dolibarr_modules (numero, entity);
235  if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i',$line,$reg))
236  {
237  $line = "-- ".$line." replaced by --\n";
238  $line.= "CREATE UNIQUE INDEX ".$reg[2]." ON ".$reg[1]."(".$reg[3];
239  }
240 
241  // Translate order to drop foreign keys
242  // ALTER TABLE llx_dolibarr_modules DROP FOREIGN KEY fk_xxx;
243  if (preg_match('/ALTER\s+TABLE\s*(.*)\s*DROP\s+FOREIGN\s+KEY\s*(.*)$/i',$line,$reg))
244  {
245  $line = "-- ".$line." replaced by --\n";
246  $line.= "ALTER TABLE ".$reg[1]." DROP CONSTRAINT ".$reg[2];
247  }
248 
249  // alter table add [unique] [index] (field1, field2 ...)
250  // ALTER TABLE llx_accountingaccount ADD INDEX idx_accountingaccount_fk_pcg_version (fk_pcg_version)
251  if (preg_match('/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i',$line,$reg))
252  {
253  $fieldlist=$reg[4];
254  $idxname=$reg[3];
255  $tablename=$reg[1];
256  $line = "-- ".$line." replaced by --\n";
257  $line.= "CREATE ".(preg_match('/UNIQUE/',$reg[2])?'UNIQUE ':'')."INDEX ".$idxname." ON ".$tablename." (".$fieldlist.")";
258  }
259  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)) {
260  // Pour l'instant les contraintes ne sont pas créées
261  dol_syslog(get_class().'::query line emptied');
262  $line = 'SELECT 0;';
263  }
264 
265  //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) {
266  //preg_replace('/(rowid\s+.*\s+PRIMARY\s+KEY\s*,)/i', '/* \\1 */', $line);
267  //}
268  }
269 
270  // Delete using criteria on other table must not declare twice the deleted table
271  // DELETE FROM tabletodelete USING tabletodelete, othertable -> DELETE FROM tabletodelete USING othertable
272  if (preg_match('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i',$line,$reg))
273  {
274  if ($reg[1] == $reg[2]) // If same table, we remove second one
275  {
276  $line=preg_replace('/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i','DELETE FROM \\1 USING \\3', $line);
277  }
278  }
279 
280  // Remove () in the tables in FROM if one table
281  $line=preg_replace('/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i','FROM \\1',$line);
282  //print $line."\n";
283 
284  // Remove () in the tables in FROM if two table
285  $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);
286  //print $line."\n";
287 
288  // Remove () in the tables in FROM if two table
289  $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);
290  //print $line."\n";
291 
292  //print "type=".$type." newline=".$line."<br>\n";
293  }
294 
295  return $line;
296  }
297 
298  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
305  function select_db($database)
306  {
307  // phpcs:enable
308  dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG);
309  // sqlite_select_db() does not exist
310  //return sqlite_select_db($this->db,$database);
311  return true;
312  }
313 
314 
326  function connect($host, $login, $passwd, $name, $port=0)
327  {
328  global $main_data_dir;
329 
330  dol_syslog(get_class($this)."::connect name=".$name,LOG_DEBUG);
331 
332  $dir=$main_data_dir;
333  if (empty($dir)) $dir=DOL_DATA_ROOT;
334  // With sqlite, port must be in connect parameters
335  //if (! $newport) $newport=3306;
336  $database_name = $dir.'/database_'.$name.'.sdb';
337  try {
338  /*** connect to SQLite database ***/
339  //$this->db = new PDO("sqlite:".$dir.'/database_'.$name.'.sdb');
340  $this->db = new SQLite3($database_name);
341  //$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
342  }
343  catch(Exception $e)
344  {
345  $this->error= self::LABEL.' '.$e->getMessage().' current dir='.$database_name;
346  return '';
347  }
348 
349  //print "Resultat fonction connect: ".$this->db;
350  return $this->db;
351  }
352 
353 
359  function getVersion()
360  {
361  $tmp=$this->db->version();
362  return $tmp['versionString'];
363  }
364 
370  function getDriverInfo()
371  {
372  return 'sqlite3 php driver';
373  }
374 
375 
382  function close()
383  {
384  if ($this->db)
385  {
386  if ($this->transaction_opened > 0) dol_syslog(get_class($this)."::close Closing a connection with an opened transaction depth=".$this->transaction_opened,LOG_ERR);
387  $this->connected=false;
388  $this->db->close();
389  unset($this->db); // Clean this->db
390  return true;
391  }
392  return false;
393  }
394 
404  function query($query,$usesavepoint=0,$type='auto')
405  {
406  $ret=null;
407  $query = trim($query);
408  $this->error = 0;
409 
410  // Convert MySQL syntax to SQLite syntax
411  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)) {
412  // Ajout d'une clef étrangère à la table
413  // procédure de remplacement de la table pour ajouter la contrainte
414  // Exemple : ALTER TABLE llx_adherent ADD CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid)
415  // -> CREATE TABLE ( ... ,CONSTRAINT adherent_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid))
416  $foreignFields = $reg[5];
417  $foreignTable = $reg[4];
418  $localfields = $reg[3];
419  $constraintname=trim($reg[2]);
420  $tablename=trim($reg[1]);
421 
422  $descTable = $this->db->querySingle("SELECT sql FROM sqlite_master WHERE name='" . $tablename . "'");
423 
424  // 1- Renommer la table avec un nom temporaire
425  $this->query('ALTER TABLE ' . $tablename . ' RENAME TO tmp_' . $tablename);
426 
427  // 2- Recréer la table avec la contrainte ajoutée
428 
429  // on bricole la requete pour ajouter la contrainte
430  $descTable = substr($descTable, 0, strlen($descTable) - 1);
431  $descTable .= ", CONSTRAINT " . $constraintname . " FOREIGN KEY (" . $localfields . ") REFERENCES " .$foreignTable . "(" . $foreignFields . ")";
432 
433  // fermeture de l'instruction
434  $descTable .= ')';
435 
436  // Création proprement dite de la table
437  $this->query($descTable);
438 
439  // 3- Transférer les données
440  $this->query('INSERT INTO ' . $tablename . ' SELECT * FROM tmp_' . $tablename);
441 
442  // 4- Supprimer la table temporaire
443  $this->query('DROP TABLE tmp_' . $tablename);
444 
445  // dummy statement
446  $query="SELECT 0";
447  } else {
448  $query=$this->convertSQLFromMysql($query,$type);
449  }
450  //print "After convertSQLFromMysql:\n".$query."<br>\n";
451 
452  dol_syslog('sql='.$query, LOG_DEBUG);
453 
454  // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE)
455  try {
456  //$ret = $this->db->exec($query);
457  $ret = $this->db->query($query); // $ret is a Sqlite3Result
458  if ($ret) {
459  $ret->queryString = $query;
460  }
461  }
462  catch(Exception $e)
463  {
464  $this->error=$this->db->lastErrorMsg();
465  }
466 
467  if (! preg_match("/^COMMIT/i",$query) && ! preg_match("/^ROLLBACK/i",$query))
468  {
469  // Si requete utilisateur, on la sauvegarde ainsi que son resultset
470  if (! is_object($ret) || $this->error)
471  {
472  $this->lastqueryerror = $query;
473  $this->lasterror = $this->error();
474  $this->lasterrno = $this->errno();
475 
476  dol_syslog(get_class($this)."::query SQL Error query: ".$query, LOG_ERR);
477 
478  $errormsg = get_class($this)."::query SQL Error message: ".$this->lasterror;
479 
480  if (preg_match('/[0-9]/',$this->lasterrno)) {
481  $errormsg .= ' ('.$this->lasterrno.')';
482  }
483 
484  dol_syslog($errormsg, LOG_ERR);
485  }
486  $this->lastquery=$query;
487  $this->_results = $ret;
488  }
489 
490  return $ret;
491  }
492 
493  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
500  function fetch_object($resultset)
501  {
502  // phpcs:enable
503  // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
504  if (! is_object($resultset)) { $resultset=$this->_results; }
505  //return $resultset->fetch(PDO::FETCH_OBJ);
506  $ret = $resultset->fetchArray(SQLITE3_ASSOC);
507  if ($ret) {
508  return (object) $ret;
509  }
510  return false;
511  }
512 
513 
514  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
521  function fetch_array($resultset)
522  {
523  // phpcs:enable
524  // If resultset not provided, we take the last used by connexion
525  if (! is_object($resultset)) { $resultset=$this->_results; }
526  //return $resultset->fetch(PDO::FETCH_ASSOC);
527  $ret = $resultset->fetchArray(SQLITE3_ASSOC);
528  return $ret;
529  }
530 
531  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
538  function fetch_row($resultset)
539  {
540  // phpcs:enable
541  // If resultset not provided, we take the last used by connexion
542  if (! is_bool($resultset))
543  {
544  if (! is_object($resultset)) { $resultset=$this->_results; }
545  return $resultset->fetchArray(SQLITE3_NUM);
546  }
547  else
548  {
549  // si le curseur est un booleen on retourne la valeur 0
550  return false;
551  }
552  }
553 
554  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
562  function num_rows($resultset)
563  {
564  // phpcs:enable
565  // FIXME: SQLite3Result does not have a queryString member
566 
567  // If resultset not provided, we take the last used by connexion
568  if (! is_object($resultset)) { $resultset=$this->_results; }
569  if (preg_match("/^SELECT/i", $resultset->queryString)) {
570  return $this->db->querySingle("SELECT count(*) FROM (" . $resultset->queryString . ") q");
571  }
572  return 0;
573  }
574 
575  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
583  function affected_rows($resultset)
584  {
585  // phpcs:enable
586  // FIXME: SQLite3Result does not have a queryString member
587 
588  // If resultset not provided, we take the last used by connexion
589  if (! is_object($resultset)) { $resultset=$this->_results; }
590  if (preg_match("/^SELECT/i", $resultset->queryString)) {
591  return $this->num_rows($resultset);
592  }
593  // mysql necessite un link de base pour cette fonction contrairement
594  // a pqsql qui prend un resultset
595  return $this->db->changes();
596  }
597 
598 
605  function free($resultset=null)
606  {
607  // If resultset not provided, we take the last used by connexion
608  if (! is_object($resultset)) { $resultset=$this->_results; }
609  // Si resultset en est un, on libere la memoire
610  if ($resultset && is_object($resultset)) $resultset->finalize();
611  }
612 
619  function escape($stringtoencode)
620  {
621  return Sqlite3::escapeString($stringtoencode);
622  }
623 
629  function errno()
630  {
631  if (! $this->connected) {
632  // Si il y a eu echec de connexion, $this->db n'est pas valide.
633  return 'DB_ERROR_FAILED_TO_CONNECT';
634  }
635  else {
636  // Constants to convert error code to a generic Dolibarr error code
637  /*$errorcode_map = array(
638  1004 => 'DB_ERROR_CANNOT_CREATE',
639  1005 => 'DB_ERROR_CANNOT_CREATE',
640  1006 => 'DB_ERROR_CANNOT_CREATE',
641  1007 => 'DB_ERROR_ALREADY_EXISTS',
642  1008 => 'DB_ERROR_CANNOT_DROP',
643  1025 => 'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
644  1044 => 'DB_ERROR_ACCESSDENIED',
645  1046 => 'DB_ERROR_NODBSELECTED',
646  1048 => 'DB_ERROR_CONSTRAINT',
647  'HY000' => 'DB_ERROR_TABLE_ALREADY_EXISTS',
648  1051 => 'DB_ERROR_NOSUCHTABLE',
649  1054 => 'DB_ERROR_NOSUCHFIELD',
650  1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS',
651  1061 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
652  1062 => 'DB_ERROR_RECORD_ALREADY_EXISTS',
653  1064 => 'DB_ERROR_SYNTAX',
654  1068 => 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
655  1075 => 'DB_ERROR_CANT_DROP_PRIMARY_KEY',
656  1091 => 'DB_ERROR_NOSUCHFIELD',
657  1100 => 'DB_ERROR_NOT_LOCKED',
658  1136 => 'DB_ERROR_VALUE_COUNT_ON_ROW',
659  1146 => 'DB_ERROR_NOSUCHTABLE',
660  1216 => 'DB_ERROR_NO_PARENT',
661  1217 => 'DB_ERROR_CHILD_EXISTS',
662  1451 => 'DB_ERROR_CHILD_EXISTS'
663  );
664 
665  if (isset($errorcode_map[$this->db->errorCode()]))
666  {
667  return $errorcode_map[$this->db->errorCode()];
668  }*/
669  $errno=$this->db->lastErrorCode();
670  if ($errno=='HY000' || $errno == 0)
671  {
672  if (preg_match('/table.*already exists/i',$this->error)) return 'DB_ERROR_TABLE_ALREADY_EXISTS';
673  elseif (preg_match('/index.*already exists/i',$this->error)) return 'DB_ERROR_KEY_NAME_ALREADY_EXISTS';
674  elseif (preg_match('/syntax error/i',$this->error)) return 'DB_ERROR_SYNTAX';
675  }
676  if ($errno=='23000')
677  {
678  if (preg_match('/column.* not unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS';
679  elseif (preg_match('/PRIMARY KEY must be unique/i',$this->error)) return 'DB_ERROR_RECORD_ALREADY_EXISTS';
680  }
681  if ($errno > 1) {
682  // TODO Voir la liste des messages d'erreur
683  }
684 
685  return ($errno?'DB_ERROR_'.$errno:'0');
686  }
687  }
688 
694  function error()
695  {
696  if (! $this->connected) {
697  // Si il y a eu echec de connexion, $this->db n'est pas valide pour sqlite_error.
698  return 'Not connected. Check setup parameters in conf/conf.php file and your sqlite version';
699  }
700  else {
701  return $this->error;
702  }
703  }
704 
705  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
713  function last_insert_id($tab,$fieldid='rowid')
714  {
715  // phpcs:enable
716  return $this->db->lastInsertRowId();
717  }
718 
727  function encrypt($fieldorvalue, $withQuotes=0)
728  {
729  global $conf;
730 
731  // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
732  $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0);
733 
734  //Encryption key
735  $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:'');
736 
737  $return = ($withQuotes?"'":"").$this->escape($fieldorvalue).($withQuotes?"'":"");
738 
739  if ($cryptType && !empty($cryptKey))
740  {
741  if ($cryptType == 2)
742  {
743  $return = 'AES_ENCRYPT('.$return.',\''.$cryptKey.'\')';
744  }
745  else if ($cryptType == 1)
746  {
747  $return = 'DES_ENCRYPT('.$return.',\''.$cryptKey.'\')';
748  }
749  }
750 
751  return $return;
752  }
753 
760  function decrypt($value)
761  {
762  global $conf;
763 
764  // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
765  $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0);
766 
767  //Encryption key
768  $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:'');
769 
770  $return = $value;
771 
772  if ($cryptType && !empty($cryptKey))
773  {
774  if ($cryptType == 2)
775  {
776  $return = 'AES_DECRYPT('.$value.',\''.$cryptKey.'\')';
777  }
778  else if ($cryptType == 1)
779  {
780  $return = 'DES_DECRYPT('.$value.',\''.$cryptKey.'\')';
781  }
782  }
783 
784  return $return;
785  }
786 
787 
788  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
794  function DDLGetConnectId()
795  {
796  // phpcs:enable
797  return '?';
798  }
799 
800 
801  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
813  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.NotCamelCaps
843  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.NotCamelCaps
871  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.NotCamelCaps
903  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  else if( preg_match("/^[^\s]/i",$field_desc['attribute']))
919  $sqlfields[$i] .= " ".$field_desc['attribute'];
920  else if( 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
925  $sqlfields[$i] .= " default '".$field_desc['default']."'";
926  }
927  else if( preg_match("/^[^\s]/i",$field_desc['null']))
928  $sqlfields[$i] .= " ".$field_desc['null'];
929 
930  else if( preg_match("/^[^\s]/i",$field_desc['extra']))
931  $sqlfields[$i] .= " ".$field_desc['extra'];
932  $i++;
933  }
934  if($primary_key != "")
935  $pk = "primary key(".$primary_key.")";
936 
937  if(is_array($unique_keys))
938  {
939  $i = 0;
940  foreach($unique_keys as $key => $value)
941  {
942  $sqluq[$i] = "UNIQUE KEY '".$key."' ('".$value."')";
943  $i++;
944  }
945  }
946  if(is_array($keys))
947  {
948  $i = 0;
949  foreach($keys as $key => $value)
950  {
951  $sqlk[$i] = "KEY ".$key." (".$value.")";
952  $i++;
953  }
954  }
955  $sql .= implode(',',$sqlfields);
956  if($primary_key != "")
957  $sql .= ",".$pk;
958  if(is_array($unique_keys))
959  $sql .= ",".implode(',',$sqluq);
960  if(is_array($keys))
961  $sql .= ",".implode(',',$sqlk);
962  $sql .=") type=".$type;
963 
964  dol_syslog($sql,LOG_DEBUG);
965  if(! $this -> query($sql))
966  return -1;
967  return 1;
968  }
969 
970  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
977  function DDLDropTable($table)
978  {
979  // phpcs:enable
980  $sql = "DROP TABLE ".$table;
981 
982  if (! $this->query($sql))
983  return -1;
984  else
985  return 1;
986  }
987 
988  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
996  function DDLDescTable($table,$field="")
997  {
998  // phpcs:enable
999  $sql="DESC ".$table." ".$field;
1000 
1001  dol_syslog(get_class($this)."::DDLDescTable ".$sql,LOG_DEBUG);
1002  $this->_results = $this->query($sql);
1003  return $this->_results;
1004  }
1005 
1006  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1016  function DDLAddField($table,$field_name,$field_desc,$field_position="")
1017  {
1018  // phpcs:enable
1019  // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
1020  // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
1021  $sql= "ALTER TABLE ".$table." ADD ".$field_name." ";
1022  $sql.= $field_desc['type'];
1023  if(preg_match("/^[^\s]/i",$field_desc['value']))
1024  if (! in_array($field_desc['type'],array('date','datetime')))
1025  {
1026  $sql.= "(".$field_desc['value'].")";
1027  }
1028  if(preg_match("/^[^\s]/i",$field_desc['attribute']))
1029  $sql.= " ".$field_desc['attribute'];
1030  if(preg_match("/^[^\s]/i",$field_desc['null']))
1031  $sql.= " ".$field_desc['null'];
1032  if(preg_match("/^[^\s]/i",$field_desc['default']))
1033  {
1034  if(preg_match("/null/i",$field_desc['default']))
1035  $sql.= " default ".$field_desc['default'];
1036  else
1037  $sql.= " default '".$field_desc['default']."'";
1038  }
1039  if(preg_match("/^[^\s]/i",$field_desc['extra']))
1040  $sql.= " ".$field_desc['extra'];
1041  $sql.= " ".$field_position;
1042 
1043  dol_syslog(get_class($this)."::DDLAddField ".$sql,LOG_DEBUG);
1044  if(! $this->query($sql))
1045  {
1046  return -1;
1047  }
1048  return 1;
1049  }
1050 
1051  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1060  function DDLUpdateField($table,$field_name,$field_desc)
1061  {
1062  // phpcs:enable
1063  $sql = "ALTER TABLE ".$table;
1064  $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
1065  if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') {
1066  $sql.="(".$field_desc['value'].")";
1067  }
1068 
1069  dol_syslog(get_class($this)."::DDLUpdateField ".$sql,LOG_DEBUG);
1070  if (! $this->query($sql))
1071  return -1;
1072  return 1;
1073  }
1074 
1075  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1083  function DDLDropField($table,$field_name)
1084  {
1085  // phpcs:enable
1086  $sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`";
1087  dol_syslog(get_class($this)."::DDLDropField ".$sql,LOG_DEBUG);
1088  if (! $this->query($sql))
1089  {
1090  $this->error=$this->lasterror();
1091  return -1;
1092  }
1093  return 1;
1094  }
1095 
1096 
1097  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
1107  function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name)
1108  {
1109  // phpcs:enable
1110  $sql = "INSERT INTO user ";
1111  $sql.= "(Host,User,password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)";
1112  $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_user)."',password('".addslashes($dolibarr_main_db_pass)."')";
1113  $sql.= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')";
1114 
1115  dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
1116  $resql=$this->query($sql);
1117  if (! $resql)
1118  {
1119  return -1;
1120  }
1121 
1122  $sql = "INSERT INTO db ";
1123  $sql.= "(Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)";
1124  $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_name)."','".addslashes($dolibarr_main_db_user)."'";
1125  $sql.= ",'Y','Y','Y','Y','Y','Y','Y','Y','Y')";
1126 
1127  dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);
1128  $resql=$this->query($sql);
1129  if (! $resql)
1130  {
1131  return -1;
1132  }
1133 
1134  $sql="FLUSH Privileges";
1135 
1136  dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);
1137  $resql=$this->query($sql);
1138  if (! $resql)
1139  {
1140  return -1;
1141  }
1142  return 1;
1143  }
1144 
1150  function getDefaultCharacterSetDatabase()
1151  {
1152  return 'UTF-8';
1153  }
1154 
1160  function getListOfCharacterSet()
1161  {
1162  $liste = array();
1163  $i=0;
1164  $liste[$i]['charset'] = 'UTF-8';
1165  $liste[$i]['description'] = 'UTF-8';
1166  return $liste;
1167  }
1168 
1174  function getDefaultCollationDatabase()
1175  {
1176  return 'UTF-8';
1177  }
1178 
1184  function getListOfCollation()
1185  {
1186  $liste = array();
1187  $i=0;
1188  $liste[$i]['charset'] = 'UTF-8';
1189  $liste[$i]['description'] = 'UTF-8';
1190  return $liste;
1191  }
1192 
1198  function getPathOfDump()
1199  {
1200  // FIXME: not for SQLite
1201  $fullpathofdump='/pathtomysqldump/mysqldump';
1202 
1203  $resql=$this->query('SHOW VARIABLES LIKE \'basedir\'');
1204  if ($resql)
1205  {
1206  $liste=$this->fetch_array($resql);
1207  $basedir=$liste['Value'];
1208  $fullpathofdump=$basedir.(preg_match('/\/$/',$basedir)?'':'/').'bin/mysqldump';
1209  }
1210  return $fullpathofdump;
1211  }
1212 
1218  function getPathOfRestore()
1219  {
1220  // FIXME: not for SQLite
1221  $fullpathofimport='/pathtomysql/mysql';
1222 
1223  $resql=$this->query('SHOW VARIABLES LIKE \'basedir\'');
1224  if ($resql)
1225  {
1226  $liste=$this->fetch_array($resql);
1227  $basedir=$liste['Value'];
1228  $fullpathofimport=$basedir.(preg_match('/\/$/',$basedir)?'':'/').'bin/mysql';
1229  }
1230  return $fullpathofimport;
1231  }
1232 
1239  function getServerParametersValues($filter='')
1240  {
1241  $result=array();
1242  static $pragmas;
1243  if (! isset($pragmas)) {
1244  // Définition de la liste des pragmas utilisés qui ne retournent qu'une seule valeur
1245  // indépendante de la base de données.
1246  // cf. http://www.sqlite.org/pragma.html
1247  $pragmas = array(
1248  'application_id', 'auto_vacuum', 'automatic_index', 'busy_timeout', 'cache_size',
1249  'cache_spill', 'case_sensitive_like', 'checkpoint_fullsync', 'collation_list',
1250  'compile_options', 'data_version', /*'database_list',*/
1251  'defer_foreign_keys', 'encoding', 'foreign_key_check', 'freelist_count',
1252  'full_column_names', 'fullsync', 'ingore_check_constraints', 'integrity_check',
1253  'journal_mode', 'journal_size_limit', 'legacy_file_format', 'locking_mode',
1254  'max_page_count', 'page_count', 'page_size', 'parser_trace',
1255  'query_only', 'quick_check', 'read_uncommitted', 'recursive_triggers',
1256  'reverse_unordered_selects', 'schema_version', 'user_version',
1257  'secure_delete', 'short_column_names', 'shrink_memory', 'soft_heap_limit',
1258  'synchronous', 'temp_store', /*'temp_store_directory',*/ 'threads',
1259  'vdbe_addoptrace', 'vdbe_debug', 'vdbe_listing', 'vdbe_trace',
1260  'wal_autocheckpoint',
1261  );
1262  }
1263 
1264  // TODO prendre en compte le filtre
1265  foreach($pragmas as $var) {
1266  $sql = "PRAGMA $var";
1267  $resql=$this->query($sql);
1268  if ($resql)
1269  {
1270  $obj = $this->fetch_row($resql);
1271  //dol_syslog(get_class($this)."::select_db getServerParametersValues $var=". print_r($obj, true), LOG_DEBUG);
1272  $result[$var] = $obj[0];
1273  }
1274  else {
1275  // TODO Récupérer le message
1276  $result[$var] = 'FAIL';
1277  }
1278  }
1279  return $result;
1280  }
1281 
1288  function getServerStatusValues($filter='')
1289  {
1290  $result=array();
1291  /*
1292  $sql='SHOW STATUS';
1293  if ($filter) $sql.=" LIKE '".$this->escape($filter)."'";
1294  $resql=$this->query($sql);
1295  if ($resql)
1296  {
1297  while ($obj=$this->fetch_object($resql)) $result[$obj->Variable_name]=$obj->Value;
1298  }
1299  */
1300 
1301  return $result;
1302  }
1303 
1313  private function addCustomFunction($name, $arg_count = -1)
1314  {
1315  if ($this->db)
1316  {
1317  $newname=preg_replace('/_/','',$name);
1318  $localname = __CLASS__ . '::' . 'db' . $newname;
1319  $reflectClass = new ReflectionClass(__CLASS__);
1320  $reflectFunction = $reflectClass->getMethod('db' . $newname);
1321  if ($arg_count < 0) {
1322  $arg_count = $reflectFunction->getNumberOfParameters();
1323  }
1324  if (!$this->db->createFunction($name, $localname, $arg_count))
1325  {
1326  $this->error = "unable to create custom function '$name'";
1327  }
1328  }
1329  }
1330 
1331  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1340  private static function calc_daynr($year, $month, $day)
1341  {
1342  // phpcs:enable
1343  $y = $year;
1344  if ($y == 0 && $month == 0) return 0;
1345  $num = (365* $y + 31 * ($month - 1) + $day);
1346  if ($month <= 2) {
1347  $y--; }
1348  else {
1349  $num -= floor(($month * 4 + 23) / 10);
1350  }
1351  $temp = floor(($y / 100 + 1) * 3 / 4);
1352  return $num + floor($y / 4) - $temp;
1353  }
1354 
1355  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1363  private static function calc_weekday($daynr, $sunday_first_day_of_week)
1364  {
1365  // phpcs:enable
1366  $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7);
1367  return $ret;
1368  }
1369 
1370  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1377  private static function calc_days_in_year($year)
1378  {
1379  // phpcs:enable
1380  return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365);
1381  }
1382 
1383  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1394  private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year)
1395  {
1396  // phpcs:enable
1397  $daynr=self::calc_daynr($year,$month,$day);
1398  $first_daynr=self::calc_daynr($year,1,1);
1399  $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0;
1400  $week_year= ($week_behaviour & self::WEEK_YEAR) ? 1 : 0;
1401  $first_weekday= ($week_behaviour & self::WEEK_FIRST_WEEKDAY) ? 1 : 0;
1402 
1403  $weekday=self::calc_weekday($first_daynr, !$monday_first);
1404  $calc_year=$year;
1405 
1406  if ($month == 1 && $day <= 7-$weekday)
1407  {
1408  if (!$week_year && (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)))
1409  return 0;
1410  $week_year= 1;
1411  $calc_year--;
1412  $first_daynr-= ($days=self::calc_days_in_year($calc_year));
1413  $weekday= ($weekday + 53*7- $days) % 7;
1414  }
1415 
1416  if (($first_weekday && $weekday != 0) || (!$first_weekday && $weekday >= 4)) {
1417  $days= $daynr - ($first_daynr+ (7-$weekday));
1418  }
1419  else {
1420  $days= $daynr - ($first_daynr - $weekday);
1421  }
1422 
1423  if ($week_year && $days >= 52*7)
1424  {
1425  $weekday= ($weekday + self::calc_days_in_year($calc_year)) % 7;
1426  if ((!$first_weekday && $weekday < 4) || ($first_weekday && $weekday == 0))
1427  {
1428  $calc_year++;
1429  return 1;
1430  }
1431  }
1432  return floor($days/7+1);
1433  }
1434 }
addCustomFunction($name, $arg_count=-1)
Permet le chargement d&#39;une fonction personnalisee dans le moteur de base de donnees.
last_insert_id($tab, $fieldid='rowid')
Get last ID after an insert INSERT.
const LABEL
Database label.
lastqueryerror()
Return last query in error.
getDriverInfo()
Return version of database client driver.
select_db($database)
Select a database.
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->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) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
__construct($type, $host, $user, $pass, $name='', $port=0)
Constructor.
</td >< td class="liste_titre" align="right"></td ></tr >< tr class="liste_titre">< input type="checkbox" onClick="toggle(this)"/> Ref p ref Label p label Duration p duration warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow img yes disabled img no img no< tr class="oddeven">< td >< input type="checkbox" class="check" name="' . $i . '"' . $disabled . '></td >< td >< input type="checkbox" class="check" name="choose'.$i.'"></td >< td class="nowrap"></td >< td >< input type="hidden" name="desc' . $i . '" value="' . dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:573
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 ...
static convertSQLFromMysql($line, $type='ddl')
Convert a SQL request in Mysql syntax to native syntax.
$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.
query($query, $usesavepoint=0, $type='auto')
Execute a SQL request and return the resultset.
close()
Close database connexion.
free($resultset=null)
Free last resultset used.
getServerStatusValues($filter='')
Return value of server status.
const VERSIONMIN
Version min database.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
type
Definition: viewcat.php:284
static calc_week($year, $month, $day, $week_behaviour, &$calc_year)
calc_week
fetch_array($resultset)
Return datas as an array.
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.
static calc_weekday($daynr, $sunday_first_day_of_week)
calc_weekday
lasterrno()
Return last error code.
Class to manage Dolibarr database access for a SQLite database.
getServerParametersValues($filter='')
Return value of server parameters.
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.