2013-09-10 12:29:55 +02:00
|
|
|
|
<?php
|
|
|
|
|
|
/*
|
2015-05-12 19:01:01 +02:00
|
|
|
|
* Copyright (C) 2013-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
2015-03-10 14:09:29 +01:00
|
|
|
|
* Copyright (C) 2014-2015 Laurent Destailleur <eldy@users.sourceforge.net>
|
2013-09-10 12:29:55 +02:00
|
|
|
|
*
|
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
*
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2014-09-27 16:00:11 +02:00
|
|
|
|
* \file htdocs/core/db/DoliDB.class.php
|
|
|
|
|
|
* \brief Class file to manage Dolibarr database access
|
2013-09-10 12:29:55 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
2014-02-21 12:38:43 +01:00
|
|
|
|
require_once DOL_DOCUMENT_ROOT .'/core/db/Database.interface.php';
|
|
|
|
|
|
|
2013-09-10 12:29:55 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Class to manage Dolibarr database access
|
|
|
|
|
|
*/
|
2014-02-21 12:38:43 +01:00
|
|
|
|
abstract class DoliDB implements Database
|
2013-09-10 12:29:55 +02:00
|
|
|
|
{
|
2015-05-12 19:01:01 +02:00
|
|
|
|
/** @var resource Database handler */
|
|
|
|
|
|
public $db;
|
|
|
|
|
|
/** @var string Database type */
|
|
|
|
|
|
public $type;
|
|
|
|
|
|
/** @var string Charset used to force charset when creating database */
|
|
|
|
|
|
public $forcecharset='utf8';
|
|
|
|
|
|
/** @var string Collate used to force collate when creating database */
|
2016-11-07 01:53:34 +01:00
|
|
|
|
public $forcecollate='utf8_unicode_ci';
|
2015-05-12 19:01:01 +02:00
|
|
|
|
/** @var resource Resultset of last query */
|
|
|
|
|
|
private $_results;
|
|
|
|
|
|
/** @var bool true if connected, else false */
|
|
|
|
|
|
public $connected;
|
|
|
|
|
|
/** @var bool true if database selected, else false */
|
|
|
|
|
|
public $database_selected;
|
|
|
|
|
|
/** @var string Selected database name */
|
|
|
|
|
|
public $database_name;
|
|
|
|
|
|
/** @var string Database username */
|
|
|
|
|
|
public $database_user;
|
|
|
|
|
|
/** @var string Database host */
|
|
|
|
|
|
public $database_host;
|
|
|
|
|
|
/** @var int Database port */
|
|
|
|
|
|
public $database_port;
|
|
|
|
|
|
/** @var int >=1 if a transaction is opened, 0 otherwise */
|
|
|
|
|
|
public $transaction_opened;
|
|
|
|
|
|
/** @var string Last successful query */
|
|
|
|
|
|
public $lastquery;
|
2015-06-06 14:34:57 +02:00
|
|
|
|
/** @var string Last failed query */
|
2015-05-12 19:01:01 +02:00
|
|
|
|
public $lastqueryerror;
|
|
|
|
|
|
/** @var string Last error message */
|
|
|
|
|
|
public $lasterror;
|
2017-10-16 09:29:10 +02:00
|
|
|
|
/** @var string Last error number. For example: 'DB_ERROR_RECORD_ALREADY_EXISTS', '12345', ... */
|
2015-05-12 19:01:01 +02:00
|
|
|
|
public $lasterrno;
|
2013-09-10 12:29:55 +02:00
|
|
|
|
|
2015-05-12 19:01:01 +02:00
|
|
|
|
/** @var bool Status */
|
|
|
|
|
|
public $ok;
|
|
|
|
|
|
/** @var string */
|
|
|
|
|
|
public $error;
|
2014-02-06 20:40:01 +01:00
|
|
|
|
|
2014-03-15 05:54:13 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Format a SQL IF
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $test Test string (example: 'cd.statut=0', 'field IS NULL')
|
|
|
|
|
|
* @param string $resok resultat si test egal
|
|
|
|
|
|
* @param string $resko resultat si test non egal
|
|
|
|
|
|
* @return string SQL string
|
|
|
|
|
|
*/
|
|
|
|
|
|
function ifsql($test,$resok,$resko)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 'IF('.$test.','.$resok.','.$resko.')';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-15 06:04:16 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field.
|
|
|
|
|
|
* Function to use to build INSERT, UPDATE or WHERE predica
|
|
|
|
|
|
*
|
2017-11-07 13:33:24 +01:00
|
|
|
|
* @param int $param Date TMS to convert
|
2018-01-14 01:40:12 +01:00
|
|
|
|
* @return string Date in a string YYYY-MM-DD HH:MM:SS
|
2014-03-15 06:04:16 +01:00
|
|
|
|
*/
|
|
|
|
|
|
function idate($param)
|
|
|
|
|
|
{
|
2018-01-14 03:12:22 +01:00
|
|
|
|
// TODO GMT $param should be gmt, so we should add tzouptut to 'gmt'
|
2017-11-07 13:33:24 +01:00
|
|
|
|
return dol_print_date($param,"%Y-%m-%d %H:%M:%S");
|
2014-03-15 06:04:16 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-15 06:07:46 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Return last error code
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return string lasterrno
|
|
|
|
|
|
*/
|
|
|
|
|
|
function lasterrno()
|
|
|
|
|
|
{
|
|
|
|
|
|
return $this->lasterrno;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-15 06:17:12 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Start transaction
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return int 1 if transaction successfuly opened or already opened, 0 if error
|
|
|
|
|
|
*/
|
|
|
|
|
|
function begin()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (! $this->transaction_opened)
|
|
|
|
|
|
{
|
|
|
|
|
|
$ret=$this->query("BEGIN");
|
|
|
|
|
|
if ($ret)
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->transaction_opened++;
|
|
|
|
|
|
dol_syslog("BEGIN Transaction",LOG_DEBUG);
|
|
|
|
|
|
dol_syslog('',0,1);
|
|
|
|
|
|
}
|
|
|
|
|
|
return $ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->transaction_opened++;
|
|
|
|
|
|
dol_syslog('',0,1);
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-23 11:12:06 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Validate a database transaction
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $log Add more log to default log line
|
|
|
|
|
|
* @return int 1 if validation is OK or transaction level no started, 0 if ERROR
|
|
|
|
|
|
*/
|
|
|
|
|
|
function commit($log='')
|
|
|
|
|
|
{
|
|
|
|
|
|
dol_syslog('',0,-1);
|
|
|
|
|
|
if ($this->transaction_opened<=1)
|
|
|
|
|
|
{
|
|
|
|
|
|
$ret=$this->query("COMMIT");
|
|
|
|
|
|
if ($ret)
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->transaction_opened=0;
|
|
|
|
|
|
dol_syslog("COMMIT Transaction".($log?' '.$log:''),LOG_DEBUG);
|
2014-10-05 01:22:17 +02:00
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
2014-04-23 11:12:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->transaction_opened--;
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Annulation d'une transaction et retour aux anciennes valeurs
|
|
|
|
|
|
*
|
2014-11-15 15:19:37 +01:00
|
|
|
|
* @param string $log Add more log to default log line
|
|
|
|
|
|
* @return resource|int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur
|
2014-04-23 11:12:06 +02:00
|
|
|
|
*/
|
|
|
|
|
|
function rollback($log='')
|
|
|
|
|
|
{
|
|
|
|
|
|
dol_syslog('',0,-1);
|
|
|
|
|
|
if ($this->transaction_opened<=1)
|
|
|
|
|
|
{
|
|
|
|
|
|
$ret=$this->query("ROLLBACK");
|
|
|
|
|
|
$this->transaction_opened=0;
|
|
|
|
|
|
dol_syslog("ROLLBACK Transaction".($log?' '.$log:''),LOG_DEBUG);
|
|
|
|
|
|
return $ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
$this->transaction_opened--;
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-23 12:15:13 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Define limits and offset of request
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param int $limit Maximum number of lines returned (-1=conf->liste_limit, 0=no limit)
|
|
|
|
|
|
* @param int $offset Numero of line from where starting fetch
|
|
|
|
|
|
* @return string String with SQL syntax to add a limit and offset
|
|
|
|
|
|
*/
|
|
|
|
|
|
function plimit($limit=0,$offset=0)
|
|
|
|
|
|
{
|
|
|
|
|
|
global $conf;
|
|
|
|
|
|
if (empty($limit)) return "";
|
|
|
|
|
|
if ($limit < 0) $limit=$conf->liste_limit;
|
|
|
|
|
|
if ($offset > 0) return " LIMIT $offset,$limit ";
|
|
|
|
|
|
else return " LIMIT $limit ";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-15 06:40:13 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Return version of database server into an array
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return array Version array
|
|
|
|
|
|
*/
|
|
|
|
|
|
function getVersionArray()
|
|
|
|
|
|
{
|
2015-02-14 12:24:16 +01:00
|
|
|
|
return preg_split("/[\.,-]/",$this->getVersion());
|
2014-03-15 06:40:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-15 06:48:39 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Return last request executed with query()
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return string Last query
|
|
|
|
|
|
*/
|
|
|
|
|
|
function lastquery()
|
|
|
|
|
|
{
|
|
|
|
|
|
return $this->lastquery;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-02-06 20:40:01 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Define sort criteria of request
|
|
|
|
|
|
*
|
2018-04-28 19:54:41 +02:00
|
|
|
|
* @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb'
|
|
|
|
|
|
* @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC';
|
2017-11-25 16:21:44 +01:00
|
|
|
|
* @return string String to provide syntax of a sort sql string
|
2014-02-06 20:40:01 +01:00
|
|
|
|
*/
|
2015-05-12 19:01:01 +02:00
|
|
|
|
function order($sortfield=null,$sortorder=null)
|
2014-02-06 20:40:01 +01:00
|
|
|
|
{
|
2015-10-13 14:40:02 +02:00
|
|
|
|
if (! empty($sortfield))
|
2014-02-06 20:40:01 +01:00
|
|
|
|
{
|
|
|
|
|
|
$return='';
|
|
|
|
|
|
$fields=explode(',',$sortfield);
|
2017-04-29 00:44:25 +02:00
|
|
|
|
$orders=explode(',',$sortorder);
|
|
|
|
|
|
$i=0;
|
2014-02-06 20:40:01 +01:00
|
|
|
|
foreach($fields as $val)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (! $return) $return.=' ORDER BY ';
|
2017-04-29 00:44:25 +02:00
|
|
|
|
else $return.=', ';
|
2014-02-06 20:40:01 +01:00
|
|
|
|
|
|
|
|
|
|
$return.=preg_replace('/[^0-9a-z_\.]/i','',$val);
|
2017-10-16 09:29:10 +02:00
|
|
|
|
|
2017-04-29 00:44:25 +02:00
|
|
|
|
$tmpsortorder = trim($orders[$i]);
|
2017-10-16 09:29:10 +02:00
|
|
|
|
|
2015-12-02 21:12:23 +01:00
|
|
|
|
// Only ASC and DESC values are valid SQL
|
2017-04-29 00:44:25 +02:00
|
|
|
|
if (strtoupper($tmpsortorder) === 'ASC') {
|
2015-12-02 21:12:23 +01:00
|
|
|
|
$return .= ' ASC';
|
2017-04-29 00:44:25 +02:00
|
|
|
|
} elseif (strtoupper($tmpsortorder) === 'DESC') {
|
2015-12-02 21:12:23 +01:00
|
|
|
|
$return .= ' DESC';
|
2015-05-12 19:01:01 +02:00
|
|
|
|
}
|
2017-10-16 09:29:10 +02:00
|
|
|
|
|
2017-04-29 00:44:25 +02:00
|
|
|
|
$i++;
|
2014-02-06 20:40:01 +01:00
|
|
|
|
}
|
|
|
|
|
|
return $return;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-03-15 05:47:17 +01:00
|
|
|
|
|
2014-03-15 07:11:45 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Return last error label
|
|
|
|
|
|
*
|
2014-10-05 01:22:17 +02:00
|
|
|
|
* @return string Last error
|
2014-03-15 07:11:45 +01:00
|
|
|
|
*/
|
|
|
|
|
|
function lasterror()
|
|
|
|
|
|
{
|
|
|
|
|
|
return $this->lasterror;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-15 05:47:17 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Convert (by PHP) a PHP server TZ string date into a Timestamps date (GMT if gm=true)
|
|
|
|
|
|
* 19700101020000 -> 3600 with TZ+1 and gmt=0
|
|
|
|
|
|
* 19700101020000 -> 7200 whaterver is TZ if gmt=1
|
|
|
|
|
|
*
|
2014-10-05 01:22:17 +02:00
|
|
|
|
* @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS)
|
2015-05-12 19:01:01 +02:00
|
|
|
|
* @param bool $gm 1=Input informations are GMT values, otherwise local to server TZ
|
2015-04-06 11:28:06 +02:00
|
|
|
|
* @return int|string Date TMS or ''
|
2014-03-15 05:47:17 +01:00
|
|
|
|
*/
|
|
|
|
|
|
function jdate($string, $gm=false)
|
|
|
|
|
|
{
|
2018-01-14 03:12:22 +01:00
|
|
|
|
// TODO GMT must set param gm to true by default
|
2015-03-11 03:55:46 +01:00
|
|
|
|
if ($string==0 || $string=="0000-00-00 00:00:00") return '';
|
2014-03-15 05:47:17 +01:00
|
|
|
|
$string=preg_replace('/([^0-9])/i','',$string);
|
|
|
|
|
|
$tmp=$string.'000000';
|
|
|
|
|
|
$date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),$gm);
|
|
|
|
|
|
return $date;
|
|
|
|
|
|
}
|
2014-03-15 07:20:00 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Return last query in error
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return string lastqueryerror
|
|
|
|
|
|
*/
|
|
|
|
|
|
function lastqueryerror()
|
|
|
|
|
|
{
|
|
|
|
|
|
return $this->lastqueryerror;
|
|
|
|
|
|
}
|
2013-09-10 12:29:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|