2007-08-17 19:45:55 +02:00
< ? php
/* Copyright ( C ) 2002 - 2007 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2008-01-25 18:40:07 +01:00
* Copyright ( C ) 2004 - 2008 Laurent Destailleur < eldy @ users . sourceforge . net >
2012-12-30 15:13:49 +01:00
* Copyright ( C ) 2005 - 2007 Regis Houssin < regis . houssin @ capnetworks . com >
2007-09-08 15:01:03 +02:00
* Copyright ( C ) 2007 Simon Desee < simon @ dedisoft . com >
2015-02-14 16:33:05 +01:00
* Copyright ( C ) 2015 Cedric GROSS < c . gross @ kreiz - it . fr >
2007-08-17 19:45: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
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2007-08-17 19:45:55 +02:00
* ( 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
2011-08-01 01:24:38 +02:00
* along with this program . If not , see < http :// www . gnu . org / licenses />.
2007-08-17 19:45:55 +02:00
*/
/**
2011-10-24 18:40:28 +02:00
* \file htdocs / core / db / mssql . class . php
2015-05-12 18:13:24 +02:00
* \brief Fichier de la classe permettant de gerer une base MSSQL
2008-09-06 01:08:07 +02:00
*/
2009-07-22 15:35:09 +02:00
2013-09-10 12:29:55 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/db/DoliDB.class.php' ;
2007-08-17 19:45:55 +02:00
/**
2013-02-21 21:04:20 +01:00
* Classe de gestion de la database de dolibarr
2008-09-06 01:08:07 +02:00
*/
2013-09-10 12:29:55 +02:00
class DoliDBMssql extends DoliDB
2007-08-17 19:45:55 +02:00
{
2009-10-26 02:29:00 +01:00
//! Database type
2011-12-21 19:34:16 +01:00
public $type = 'mssql' ;
2009-10-26 02:29:00 +01:00
//! Database label
2014-08-01 00:53:29 +02:00
const LABEL = 'MSSQL' ;
2008-10-09 19:29:32 +02:00
//! Charset used to force charset when creating database
2012-04-28 18:04:55 +02:00
var $forcecharset = 'latin1' ; // Can't be static as it may be forced with a dynamic value
2008-10-09 19:29:32 +02:00
//! Collate used to force collate when creating database
2012-04-28 18:04:55 +02:00
var $forcecollate = 'latin1_swedish_ci' ; // Can't be static as it may be forced with a dynamic value
2008-09-06 01:08:07 +02:00
//! Version min database
2014-08-01 00:53:29 +02:00
const VERSIONMIN = '2000' ;
2015-05-12 19:51:41 +02:00
/** @var resource Resultset of last query */
2012-02-15 13:55:00 +01:00
private $_results ;
2008-09-06 01:08:07 +02:00
2011-09-03 01:09:39 +02:00
/**
* Constructor .
* This create an opened connexion to a database server and eventually to a database
*
* @ param string $type Type of database ( mysql , pgsql ... )
* @ param string $host Address of database server
* @ param string $user Nom de l ' utilisateur autorise
* @ param string $pass Mot de passe
* @ param string $name Nom de la database
* @ param int $port Port of database server
*/
2012-07-30 17:17:33 +02:00
function __construct ( $type , $host , $user , $pass , $name = '' , $port = 0 )
2008-09-06 01:08:07 +02:00
{
2015-05-12 19:47:15 +02:00
global $langs ;
2008-09-06 01:08:07 +02:00
$this -> database_user = $user ;
2014-10-26 19:41:06 +01:00
$this -> database_host = $host ;
$this -> database_port = $port ;
2008-09-06 01:08:07 +02:00
$this -> transaction_opened = 0 ;
if ( ! function_exists ( " mssql_connect " ))
{
2015-05-12 19:01:01 +02:00
$this -> connected = false ;
$this -> ok = false ;
2008-09-06 01:08:07 +02:00
$this -> error = " Mssql PHP functions for using MSSql driver are not available in this version of PHP " ;
2011-12-19 11:57:09 +01:00
dol_syslog ( get_class ( $this ) . " ::DoliDBMssql : MSsql PHP functions for using MSsql driver are not available in this version of PHP " , LOG_ERR );
2008-09-06 01:08:07 +02:00
return $this -> ok ;
}
if ( ! $host )
{
2015-05-12 19:01:01 +02:00
$this -> connected = false ;
$this -> ok = false ;
2008-09-06 01:08:07 +02:00
$this -> error = $langs -> trans ( " ErrorWrongHostParameter " );
2011-12-19 11:57:09 +01:00
dol_syslog ( get_class ( $this ) . " ::DoliDBMssql : Erreur Connect, wrong host parameters " , LOG_ERR );
2008-09-06 01:08:07 +02:00
return $this -> ok ;
}
// Essai connexion serveur
$this -> db = $this -> connect ( $host , $user , $pass , $name , $port );
if ( $this -> db )
{
2009-10-23 12:44:19 +02:00
// Si client connecte avec charset different de celui de la base Dolibarr
// (La base Dolibarr a ete forcee en this->forcecharset a l'install)
2015-05-12 19:01:01 +02:00
$this -> connected = true ;
$this -> ok = true ;
2008-09-06 01:08:07 +02:00
}
else
{
// host, login ou password incorrect
2015-05-12 19:01:01 +02:00
$this -> connected = false ;
$this -> ok = false ;
2008-09-06 01:08:07 +02:00
$this -> error = mssql_get_last_message ();
2011-12-19 11:57:09 +01:00
dol_syslog ( get_class ( $this ) . " ::DoliDBMssql : Erreur Connect mssql_get_last_message= " . $this -> error , LOG_ERR );
2008-09-06 01:08:07 +02:00
}
2009-10-23 12:44:19 +02:00
// Si connexion serveur ok et si connexion base demandee, on essaie connexion base
2008-09-06 01:08:07 +02:00
if ( $this -> connected && $name )
{
if ( $this -> select_db ( $name ))
{
2015-05-12 19:01:01 +02:00
$this -> database_selected = true ;
2008-09-06 01:08:07 +02:00
$this -> database_name = $name ;
2015-05-12 19:01:01 +02:00
$this -> ok = true ;
2008-09-06 01:08:07 +02:00
}
else
{
2015-05-12 19:01:01 +02:00
$this -> database_selected = false ;
2008-09-06 01:08:07 +02:00
$this -> database_name = '' ;
2015-05-12 19:01:01 +02:00
$this -> ok = false ;
2008-09-06 01:08:07 +02:00
$this -> error = $this -> error ();
2011-12-19 11:57:09 +01:00
dol_syslog ( get_class ( $this ) . " ::DoliDBMssql : Erreur Select_db " . $this -> error , LOG_ERR );
2008-09-06 01:08:07 +02:00
}
}
else
{
// Pas de selection de base demandee, ok ou ko
2015-05-12 19:01:01 +02:00
$this -> database_selected = false ;
2008-09-06 01:08:07 +02:00
}
return $this -> ok ;
}
2010-11-15 20:08:35 +01:00
/**
2011-09-03 01:09:39 +02:00
* Convert a SQL request in Mysql syntax to native syntax
*
* @ param string $line SQL request line to convert
* @ param string $type Type of SQL order ( 'ddl' for insert , update , select , delete or 'dml' for create , alter ... )
* @ return string SQL request line converted
2010-11-15 20:08:35 +01:00
*/
2012-05-13 14:30:11 +02:00
static function convertSQLFromMysql ( $line , $type = 'ddl' )
2008-09-06 01:08:07 +02:00
{
2008-09-06 01:38:14 +02:00
return $line ;
2008-09-06 01:08:07 +02:00
}
/**
2011-09-03 01:09:39 +02:00
* Select a database
*
* @ param string $database Name of database
* @ return boolean true if OK , false if KO
2008-12-11 22:40:21 +01:00
*/
2008-09-06 01:08:07 +02:00
function select_db ( $database )
{
2015-02-14 16:27:00 +01:00
return @ mssql_select_db ( $database , $this -> db );
2008-09-06 01:08:07 +02:00
}
/**
2011-09-03 01:09:39 +02:00
* Connexion to server
*
* @ param string $host database server host
* @ param string $login login
* @ param string $passwd password
* @ param string $name name of database ( not used for mysql , used for pgsql )
2015-05-12 18:13:24 +02:00
* @ param int $port Port of database server
* @ return false | resource | true Database access handler
2011-09-03 01:09:39 +02:00
* @ see close
2008-12-11 22:40:21 +01:00
*/
2008-09-06 01:08:07 +02:00
function connect ( $host , $login , $passwd , $name , $port = 0 )
{
2011-12-19 11:57:09 +01:00
dol_syslog ( get_class ( $this ) . " ::connect host= $host , port= $port , login= $login , passwd=--hidden--, name= $name " );
2008-09-06 01:08:07 +02:00
$newhost = $host ;
if ( $port ) $newhost .= ':' . $port ;
$this -> db = @ mssql_connect ( $newhost , $login , $passwd );
2009-10-23 12:44:19 +02:00
//force les enregistrement en latin1 si la base est en utf8 par defaut
// Supprime car plante sur mon PHP-Mysql. De plus, la base est forcement en latin1 avec
// les nouvelles version de Dolibarr car force par l'install Dolibarr.
2008-09-06 01:08:07 +02:00
//$this->query('SET NAMES '.$this->forcecharset);
//print "Resultat fonction connect: ".$this->db;
2015-02-14 16:27:00 +01:00
$set_options = array ( 'SET ANSI_PADDING ON;' ,
" SET ANSI_NULLS ON; " ,
" SET ANSI_WARNINGS ON; " ,
" SET ARITHABORT ON; " ,
" SET CONCAT_NULL_YIELDS_NULL ON; " ,
" SET QUOTED_IDENTIFIER ON; "
);
mssql_query ( implode ( ' ' , $set_options ), $this -> db );
2015-02-14 16:33:05 +01:00
2008-09-06 01:08:07 +02:00
return $this -> db ;
}
2009-10-26 02:33:00 +01:00
/**
2011-09-03 01:09:39 +02:00
* Return version of database server
*
* @ return string Version string
2008-12-11 22:40:21 +01:00
*/
2008-09-06 01:08:07 +02:00
function getVersion ()
{
$resql = $this -> query ( " SELECT @@VERSION " );
2016-05-17 23:14:30 +02:00
if ( $resql )
{
$version = $this -> fetch_array ( $resql );
return $version [ 'computed' ];
}
else return '' ;
2008-09-06 01:08:07 +02:00
}
2013-06-12 11:59:55 +02:00
/**
* Return version of database client driver
*
* @ return string Version string
*/
function getDriverInfo ()
{
2016-05-17 23:14:30 +02:00
return 'php mssql driver' ;
2013-06-07 19:19:11 +02:00
}
2014-02-06 20:40:01 +01:00
2011-03-09 16:01:39 +01:00
/**
* Close database connexion
2011-09-03 01:09:39 +02:00
*
2015-05-12 18:13:24 +02:00
* @ return bool True if disconnect successfull , false otherwise
2011-03-09 16:01:39 +01:00
* @ see connect
*/
function close ()
{
if ( $this -> db )
{
2012-02-10 16:37:41 +01:00
if ( $this -> transaction_opened > 0 ) dol_syslog ( get_class ( $this ) . " ::close Closing a connection with an opened transaction depth= " . $this -> transaction_opened , LOG_ERR );
2015-05-12 19:01:01 +02:00
$this -> connected = false ;
2011-03-09 16:01:39 +01:00
return mssql_close ( $this -> db );
}
return false ;
}
2008-09-06 01:08:07 +02:00
2007-08-17 19:45:55 +02:00
2007-11-18 23:10:19 +01:00
/**
2011-09-03 01:09:39 +02:00
* Start transaction
*
2015-05-12 18:13:24 +02:00
* @ return bool true if transaction successfuly opened or already opened , false if error
2010-11-15 20:08:35 +01:00
*/
2007-11-18 23:10:19 +01:00
function begin ()
{
2015-02-14 16:27:00 +01:00
$res = mssql_query ( 'select @@TRANCOUNT' );
$this -> transaction_opened = mssql_result ( $res , 0 , 0 );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
if ( $this -> transaction_opened == 0 )
2007-11-18 23:10:19 +01:00
{
2015-03-06 01:30:46 +01:00
//return 1; //There is a mess with auto_commit and 'SET IMPLICIT_TRANSACTIONS ON' generate also a mess
2015-02-14 16:27:00 +01:00
$ret = mssql_query ( " SET IMPLICIT_TRANSACTIONS OFF;BEGIN TRANSACTION; " , $this -> db );
2007-11-18 23:10:19 +01:00
if ( $ret )
{
2009-02-20 23:53:15 +01:00
dol_syslog ( " BEGIN Transaction " , LOG_DEBUG );
2007-11-18 23:10:19 +01:00
}
return $ret ;
}
else
{
2015-05-12 18:13:24 +02:00
return true ;
2007-11-18 23:10:19 +01:00
}
}
2007-08-17 19:45:55 +02:00
2007-11-18 23:10:19 +01:00
/**
2010-11-15 20:08:35 +01:00
* Validate a database transaction
2011-09-03 01:09:39 +02:00
*
2012-01-04 14:35:41 +01:00
* @ param string $log Add more log to default log line
2015-05-12 18:13:24 +02:00
* @ return bool true if validation is OK or transaction level no started , false if ERROR
2010-11-15 20:08:35 +01:00
*/
2011-09-03 01:09:39 +02:00
function commit ( $log = '' )
2007-11-18 23:10:19 +01:00
{
2015-02-14 16:27:00 +01:00
$res = mssql_query ( 'select @@TRANCOUNT' );
$this -> transaction_opened = mssql_result ( $res , 0 , 0 );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
if ( $this -> transaction_opened == 1 )
2007-11-18 23:10:19 +01:00
{
2015-02-14 16:27:00 +01:00
//return 1; //There is a mess with auto_commit and 'SET IMPLICIT_TRANSACTION ON' generate also a mess
$ret = mssql_query ( " COMMIT TRANSACTION " , $this -> db );
2008-09-06 01:08:07 +02:00
if ( $ret )
2007-11-18 23:10:19 +01:00
{
2009-02-20 23:53:15 +01:00
dol_syslog ( " COMMIT Transaction " , LOG_DEBUG );
2015-05-12 18:13:24 +02:00
return true ;
2014-10-05 01:22:17 +02:00
}
else
{
2015-05-12 18:13:24 +02:00
return false ;
2007-11-18 23:10:19 +01:00
}
}
2015-02-14 16:27:00 +01:00
elseif ( $this -> transaction_opened > 1 )
2007-11-18 23:10:19 +01:00
{
2015-05-12 18:13:24 +02:00
return true ;
2015-05-12 19:10:47 +02:00
}
trigger_error ( " Commit requested but no transaction remain " );
return false ;
2007-11-18 23:10:19 +01:00
}
2008-09-06 01:08:07 +02:00
/**
2011-09-03 01:09:39 +02:00
* Annulation d ' une transaction et retour aux anciennes valeurs
*
2014-02-21 14:40:10 +01:00
* @ param string $log Add more log to default log line
2015-05-12 18:13:24 +02:00
* @ return bool true si annulation ok ou transaction non ouverte , false en cas d ' erreur
2008-12-11 22:40:21 +01:00
*/
2014-02-21 14:40:10 +01:00
function rollback ( $log = '' )
2008-09-06 01:08:07 +02:00
{
2015-02-14 16:27:00 +01:00
$res = mssql_query ( 'select @@TRANCOUNT' );
$this -> transaction_opened = mssql_result ( $res , 0 , 0 );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
if ( $this -> transaction_opened == 1 )
2008-09-06 01:08:07 +02:00
{
2015-02-14 16:27:00 +01:00
$ret = mssql_query ( " ROLLBACK TRANSACTION " , $this -> db );
2014-02-21 14:40:10 +01:00
dol_syslog ( " ROLLBACK Transaction " . ( $log ? ' ' . $log : '' ), LOG_DEBUG );
2008-09-06 01:08:07 +02:00
return $ret ;
}
2015-02-14 16:27:00 +01:00
elseif ( $this -> transaction_opened > 1 )
2008-09-06 01:08:07 +02:00
{
2015-05-12 18:13:24 +02:00
return true ;
2015-05-12 19:10:47 +02:00
}
trigger_error ( " Rollback requested but no transaction remain " );
return false ;
2008-09-06 01:08:07 +02:00
}
/**
2010-11-15 20:08:35 +01:00
* Execute a SQL request and return the resultset
2011-09-03 01:09:39 +02:00
*
2012-01-04 14:35:41 +01:00
* @ param string $query SQL query string
* @ param int $usesavepoint 0 = Default mode , 1 = Run a savepoint before and a rollbock to savepoint if error ( this allow to have some request with errors inside global transactions ) .
* Note that with Mysql , this parameter is not used as Myssql can already commit a transaction even if one request is in error , without using savepoints .
* @ param string $type Type of SQL order ( 'ddl' for insert , update , select , delete or 'dml' for create , alter ... )
2015-05-12 18:13:24 +02:00
* @ return false | resource | true Resultset of answer
2008-12-11 22:40:21 +01:00
*/
2010-12-01 22:16:28 +01:00
function query ( $query , $usesavepoint = 0 , $type = 'auto' )
2008-09-06 01:08:07 +02:00
{
$query = trim ( $query );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
if ( preg_match ( '/^--/' , $query )) return true ;
2008-09-06 01:08:07 +02:00
// Conversion syntaxe MySql vers MSDE.
$query = str_ireplace ( " now() " , " getdate() " , $query );
// Erreur SQL: cannot update timestamp field
$query = str_ireplace ( " , tms = tms " , " " , $query );
2015-02-14 16:27:00 +01:00
$query = preg_replace ( " /([. , \t (])(percent|file|public)([. ,= \t )])/ " , " $ 1[ $ 2] $ 3 " , $query );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
if ( $type == " auto " || $type = 'dml' )
{
$query = preg_replace ( '/AUTO_INCREMENT/i' , 'IDENTITY' , $query );
$query = preg_replace ( '/double/i' , 'float' , $query );
$query = preg_replace ( '/float\((.*)\)/' , 'numeric($1)' , $query );
$query = preg_replace ( '/([ \t])unsigned|IF NOT EXISTS[ \t]/i' , '$1' , $query );
$query = preg_replace ( '/([ \t])(MEDIUM|TINY|LONG){0,1}TEXT([ \t,])/i' , " $ 1VARCHAR(MAX) $ 3 " , $query );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
$matches = array ();
$original_query = '' ;
if ( preg_match ( '/ALTER TABLE\h+(\w+?)\h+ADD\h+(?:(UNIQUE)|INDEX)\h+(?:INDEX)?\h*(\w+?)\h*\((.+)\)/is' , $query , $matches ))
{
$original_query = $query ;
$query = " CREATE " . trim ( $matches [ 2 ]) . " INDEX [ " . trim ( $matches [ 3 ]) . " ] ON [ " . trim ( $matches [ 1 ]) . " ] ( " . trim ( $matches [ 4 ]) . " ) " ;
if ( $matches [ 2 ]) {
//check if columun is nullable cause Sql server only allow 1 null value if unique index.
$fields = explode ( " , " , trim ( $matches [ 4 ]));
$fields_clear = array_map ( 'trim' , $fields );
$infos = $this -> GetFieldInformation ( trim ( $matches [ 1 ]), $fields_clear );
$query_comp = array ();
foreach ( $infos as $fld ) {
if ( $fld -> IS_NULLABLE == 'YES' ) {
$query_comp [] = $fld -> COLUMN_NAME . " IS NOT NULL " ;
}
}
2016-05-17 23:19:57 +02:00
if ( ! empty ( $query_comp ))
2015-02-14 16:27:00 +01:00
$query .= " WHERE " . implode ( " AND " , $query_comp );
}
2015-03-06 01:30:46 +01:00
}
2015-02-14 16:27:00 +01:00
else
{
if ( preg_match ( '/ALTER TABLE\h+(\w+?)\h+ADD\h+PRIMARY\h+KEY\h+(\w+?)\h*\((.+)\)/is' , $query , $matches ))
{
$original_query = $query ;
$query = " ALTER TABLE [ " . $matches [ 1 ] . " ] ADD CONSTRAINT [ " . $matches [ 2 ] . " ] PRIMARY KEY CLUSTERED ( " . $matches [ 3 ] . " ) " ;
}
}
2015-03-06 01:30:46 +01:00
2008-09-06 01:08:07 +02:00
}
2015-02-14 16:27:00 +01:00
if ( $type == " auto " || $type = 'ddl' )
{
$itemfound = stripos ( $query , " limit " );
if ( $itemfound !== false ) {
// Extraire le nombre limite
$number = stristr ( $query , " limit " );
$number = substr ( $number , 7 );
// Inserer l'instruction TOP et le nombre limite
$query = str_ireplace ( " select " , " select top " . $number . " " , $query );
// Supprimer l'instruction MySql
$query = str_ireplace ( " limit " . $number , " " , $query );
}
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
$itemfound = stripos ( $query , " week( " );
if ( $itemfound !== false ) {
// Recreer une requete sans instruction Mysql
$positionMySql = stripos ( $query , " week( " );
$newquery = substr ( $query , 0 , $positionMySql );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
// Recuperer la date passee en parametre
$extractvalue = stristr ( $query , " week( " );
$extractvalue = substr ( $extractvalue , 6 );
$positionMySql = stripos ( $extractvalue , " ) " );
// Conserver la fin de la requete
$endofquery = substr ( $extractvalue , $positionMySql );
$extractvalue = substr ( $extractvalue , 0 , $positionMySql );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
// Remplacer l'instruction MySql en Sql Server
// Inserer la date en parametre et le reste de la requete
$query = $newquery . " DATEPART(week, " . $extractvalue . $endofquery ;
}
if ( preg_match ( '/^insert\h+(?:INTO)?\h*(\w+?)\h*\(.*\b(?:row)?id\b.*\)\h+VALUES/i' , $query , $matches ))
{
//var_dump($query);
//var_dump($matches);
2015-03-06 01:30:46 +01:00
//if (stripos($query,'llx_c_departements') !== false) var_dump($query);
2015-02-14 16:27:00 +01:00
$sql = 'SET IDENTITY_INSERT [' . trim ( $matches [ 1 ]) . '] ON;' ;
@ mssql_query ( $sql , $this -> db );
$post_query = 'SET IDENTITY_INSERT [' . trim ( $matches [ 1 ]) . '] OFF;' ;
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
}
}
2008-09-06 01:08:07 +02:00
//print "<!--".$query."-->";
2014-08-15 19:29:19 +02:00
if ( ! in_array ( $query , array ( 'BEGIN' , 'COMMIT' , 'ROLLBACK' ))) dol_syslog ( 'sql=' . $query , LOG_DEBUG );
2014-07-27 23:23:29 +02:00
2008-09-06 01:08:07 +02:00
if ( ! $this -> database_name )
{
2009-10-23 12:44:19 +02:00
// Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE)
2008-09-06 01:08:07 +02:00
$ret = mssql_query ( $query , $this -> db );
}
else
{
$ret = mssql_query ( $query , $this -> db );
}
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
if ( ! empty ( $post_query ))
{
@ mssql_query ( $post_query , $this -> db );
}
2008-09-06 01:08:07 +02:00
2009-10-23 12:44:19 +02:00
if ( ! preg_match ( " /^COMMIT/i " , $query ) && ! preg_match ( " /^ROLLBACK/i " , $query ))
2008-09-06 01:08:07 +02:00
{
// Si requete utilisateur, on la sauvegarde ainsi que son resultset
if ( ! $ret )
{
$result = mssql_query ( " SELECT @@ERROR as code " , $this -> db );
$row = mssql_fetch_array ( $result );
2009-01-25 18:56:42 +01:00
2010-08-22 15:32:38 +02:00
$this -> lastqueryerror = $query ;
2008-09-06 01:08:07 +02:00
$this -> lasterror = $this -> error ();
$this -> lasterrno = $row [ " code " ];
2014-06-13 01:34:39 +02:00
2014-06-13 01:52:57 +02:00
dol_syslog ( get_class ( $this ) . " ::query SQL Error query: " . $query , LOG_ERR );
2015-02-14 16:27:00 +01:00
if ( $original_query ) dol_syslog ( get_class ( $this ) . " ::query SQL Original query: " . $original_query , LOG_ERR );
2014-06-13 01:52:57 +02:00
dol_syslog ( get_class ( $this ) . " ::query SQL Error message: " . $this -> lasterror . " ( " . $this -> lasterrno . " ) " , LOG_ERR );
2008-09-06 01:08:07 +02:00
}
$this -> lastquery = $query ;
2012-02-15 13:55:00 +01:00
$this -> _results = $ret ;
2008-09-06 01:08:07 +02:00
}
2015-02-14 16:33:05 +01:00
2008-09-06 01:08:07 +02:00
return $ret ;
}
/**
2011-09-03 01:09:39 +02:00
* Renvoie la ligne courante ( comme un objet ) pour le curseur resultset
*
2015-05-12 18:13:24 +02:00
* @ param resource $resultset Curseur de la requete voulue
* @ return object | false Object result line or false if KO or end of cursor
2008-09-06 01:08:07 +02:00
*/
2010-08-09 17:59:55 +02:00
function fetch_object ( $resultset )
2008-09-06 01:08:07 +02:00
{
2009-10-23 12:44:19 +02:00
// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
2012-02-15 13:55:00 +01:00
if ( ! is_resource ( $resultset )) { $resultset = $this -> _results ; }
2008-09-06 01:08:07 +02:00
return mssql_fetch_object ( $resultset );
}
/**
2012-01-04 14:35:41 +01:00
* Return datas as an array
*
2015-05-12 18:13:24 +02:00
* @ param resource $resultset Resultset of request
* @ return array | false Array or false if KO or end of cursor
2008-09-06 01:08:07 +02:00
*/
2010-08-09 17:59:55 +02:00
function fetch_array ( $resultset )
2008-09-06 01:08:07 +02:00
{
2009-10-23 12:44:19 +02:00
// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
2012-02-15 13:55:00 +01:00
if ( ! is_resource ( $resultset )) { $resultset = $this -> _results ; }
2008-09-06 01:08:07 +02:00
return mssql_fetch_array ( $resultset );
}
/**
2012-01-04 14:35:41 +01:00
* Return datas as an array
*
2015-05-12 18:13:24 +02:00
* @ param resource $resultset Resultset of request
* @ return array | false Array or false if KO or end of cursor
2008-09-06 01:08:07 +02:00
*/
2010-08-09 18:07:23 +02:00
function fetch_row ( $resultset )
2008-09-06 01:08:07 +02:00
{
2009-10-23 12:44:19 +02:00
// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
2012-02-15 13:55:00 +01:00
if ( ! is_resource ( $resultset )) { $resultset = $this -> _results ; }
2008-09-06 01:08:07 +02:00
return @ mssql_fetch_row ( $resultset );
}
/**
2012-01-04 14:35:41 +01:00
* Return number of lines for result of a SELECT
*
2015-05-12 18:13:24 +02:00
* @ param resource $resultset Resulset of requests
2012-01-04 14:35:41 +01:00
* @ return int Nb of lines
* @ see affected_rows
2008-09-06 01:08:07 +02:00
*/
2010-08-09 18:07:23 +02:00
function num_rows ( $resultset )
2008-09-06 01:08:07 +02:00
{
2009-10-23 12:44:19 +02:00
// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
2012-02-15 13:55:00 +01:00
if ( ! is_resource ( $resultset )) { $resultset = $this -> _results ; }
2008-09-06 01:08:07 +02:00
return mssql_num_rows ( $resultset );
}
/**
2012-01-28 17:22:02 +01:00
* Renvoie le nombre de lignes dans le resultat d ' une requete INSERT , DELETE ou UPDATE
*
2015-05-12 18:13:24 +02:00
* @ param resource $resultset Curseur de la requete voulue
2012-01-28 17:22:02 +01:00
* @ return int Nombre de lignes
* @ see num_rows
2008-09-06 01:08:07 +02:00
*/
2010-08-09 18:07:24 +02:00
function affected_rows ( $resultset )
2008-09-06 01:08:07 +02:00
{
2009-10-20 15:14:44 +02:00
// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
2012-02-15 13:55:00 +01:00
if ( ! is_resource ( $resultset )) { $resultset = $this -> _results ; }
2008-09-06 01:08:07 +02:00
// mssql necessite un link de base pour cette fonction contrairement
// a pqsql qui prend un resultset
$rsRows = mssql_query ( " select @@rowcount as rows " , $this -> db );
return mssql_result ( $rsRows , 0 , " rows " );
//return mssql_affected_rows($this->db);
}
/**
2012-01-28 17:22:02 +01:00
* Free last resultset used .
*
2015-05-12 18:13:24 +02:00
* @ param resource $resultset Curseur de la requete voulue
* @ return bool
2008-09-06 01:08:07 +02:00
*/
2015-05-12 18:13:24 +02:00
function free ( $resultset = null )
2008-09-06 01:08:07 +02:00
{
2009-10-20 15:14:44 +02:00
// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
2012-02-15 13:55:00 +01:00
if ( ! is_resource ( $resultset )) { $resultset = $this -> _results ; }
2009-10-20 15:14:44 +02:00
// Si resultset en est un, on libere la memoire
2008-09-06 01:08:07 +02:00
if ( is_resource ( $resultset )) mssql_free_result ( $resultset );
}
2008-04-21 15:17:36 +02:00
/**
2012-01-28 17:22:02 +01:00
* Escape a string to insert data
2011-12-12 16:26:47 +01:00
*
2012-01-28 17:22:02 +01:00
* @ param string $stringtoencode String to escape
* @ return string String escaped
2008-09-06 01:08:07 +02:00
*/
function escape ( $stringtoencode )
2008-04-21 15:17:36 +02:00
{
return addslashes ( $stringtoencode );
}
2008-09-06 01:08:07 +02:00
/**
2011-04-17 15:26:12 +02:00
* Convert ( by PHP ) a GM Timestamp date into a PHP server TZ to insert into a date field .
* Function to use to build INSERT , UPDATE or WHERE predica
2011-12-12 16:26:47 +01:00
*
* @ param string $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
2008-09-06 01:08:07 +02:00
*/
function idate ( $param )
{
2011-12-13 00:23:48 +01:00
return dol_print_date ( $param , " %Y-%m-%d %H:%M:%S " );
2008-09-06 01:08:07 +02:00
}
/**
2012-01-28 17:22:02 +01:00
* Return generic error code of last operation .
*
* @ return string Error code ( Exemples : DB_ERROR_TABLE_ALREADY_EXISTS , DB_ERROR_RECORD_ALREADY_EXISTS ... )
2008-09-06 01:08:07 +02:00
*/
function errno ()
{
2012-01-28 17:22:02 +01:00
if ( ! $this -> connected )
{
2008-09-06 01:08:07 +02:00
// Si il y a eu echec de connexion, $this->db n'est pas valide.
return 'DB_ERROR_FAILED_TO_CONNECT' ;
}
2012-01-28 17:22:02 +01:00
else
{
2008-09-06 01:08:07 +02:00
// Constants to convert a MSSql error code to a generic Dolibarr error code
$errorcode_map = array (
1004 => 'DB_ERROR_CANNOT_CREATE' ,
1005 => 'DB_ERROR_CANNOT_CREATE' ,
1006 => 'DB_ERROR_CANNOT_CREATE' ,
1007 => 'DB_ERROR_ALREADY_EXISTS' ,
1008 => 'DB_ERROR_CANNOT_DROP' ,
1025 => 'DB_ERROR_NO_FOREIGN_KEY_TO_DROP' ,
1046 => 'DB_ERROR_NODBSELECTED' ,
1048 => 'DB_ERROR_CONSTRAINT' ,
2714 => 'DB_ERROR_TABLE_ALREADY_EXISTS' ,
1051 => 'DB_ERROR_NOSUCHTABLE' ,
1054 => 'DB_ERROR_NOSUCHFIELD' ,
1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS' ,
1061 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS' ,
2627 => 'DB_ERROR_RECORD_ALREADY_EXISTS' ,
102 => 'DB_ERROR_SYNTAX' ,
8120 => 'DB_ERROR_GROUP_BY_SYNTAX' ,
1068 => 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS' ,
1075 => 'DB_ERROR_CANT_DROP_PRIMARY_KEY' ,
1091 => 'DB_ERROR_NOSUCHFIELD' ,
1100 => 'DB_ERROR_NOT_LOCKED' ,
1136 => 'DB_ERROR_VALUE_COUNT_ON_ROW' ,
1146 => 'DB_ERROR_NOSUCHTABLE' ,
1216 => 'DB_ERROR_NO_PARENT' ,
1217 => 'DB_ERROR_CHILD_EXISTS' ,
2015-02-14 16:27:00 +01:00
1451 => 'DB_ERROR_CHILD_EXISTS' ,
1913 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS'
2008-12-11 22:40:21 +01:00
);
2009-01-25 18:56:42 +01:00
2008-09-06 01:49:40 +02:00
if ( isset ( $errorcode_map [ $this -> lasterrno ]))
2008-09-06 01:08:07 +02:00
{
2008-09-06 01:49:40 +02:00
return $errorcode_map [ $this -> lasterrno ];
2008-09-06 01:08:07 +02:00
}
$errno = $this -> lasterrno ;
return ( $errno ? 'DB_ERROR_' . $errno : '0' );
}
}
/**
2012-01-28 17:22:02 +01:00
* Return description of last error
*
* @ return string Error text
2008-09-06 01:08:07 +02:00
*/
function error ()
{
if ( ! $this -> connected ) {
// Si il y a eu echec de connexion, $this->db n'est pas valide pour mssql_get_last_message.
return 'Not connected. Check setup parameters in conf/conf.php file and your mssql client and server versions' ;
}
else {
2015-02-14 16:27:00 +01:00
return mssql_get_last_message ();
2008-09-06 01:08:07 +02:00
}
}
/**
2011-12-19 23:32:24 +01:00
* Get last ID after an insert INSERT
*
* @ param string $tab Table name concerned by insert . Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql
* @ param string $fieldid Field name
2015-05-12 18:13:24 +02:00
* @ return int Id of row or - 1 on error
2008-09-06 01:08:07 +02:00
*/
2011-12-19 23:32:24 +01:00
function last_insert_id ( $tab , $fieldid = 'rowid' )
2008-09-06 01:08:07 +02:00
{
$res = $this -> query ( " SELECT @@IDENTITY as id " );
2016-05-17 23:14:30 +02:00
if ( $res && $data = $this -> fetch_array ( $res ))
2008-09-06 01:08:07 +02:00
{
return $data [ " id " ];
}
else
{
return - 1 ;
}
}
2007-08-17 19:45:55 +02:00
2009-09-07 16:03:19 +02:00
/**
2010-09-02 00:45:10 +02:00
* Encrypt sensitive data in database
* Warning : This function includes the escape , so it must use direct value
2012-01-28 17:22:02 +01:00
*
* @ param string $fieldorvalue Field name or value to encrypt
* @ param int $withQuotes Return string with quotes
2015-05-12 18:13:24 +02:00
* @ return string XXX ( field ) or XXX ( 'value' ) or field or 'value'
2009-09-07 16:03:19 +02:00
*/
2009-12-23 02:12:47 +01:00
function encrypt ( $fieldorvalue , $withQuotes = 0 )
2009-09-07 16:03:19 +02:00
{
2009-12-23 02:12:47 +01:00
global $conf ;
2010-02-03 03:22:15 +01:00
2009-12-23 02:12:47 +01:00
// Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
$cryptType = ( $conf -> db -> dolibarr_main_db_encryption ? $conf -> db -> dolibarr_main_db_encryption : 0 );
2010-02-03 03:22:15 +01:00
2009-12-23 02:12:47 +01:00
//Encryption key
$cryptKey = ( ! empty ( $conf -> db -> dolibarr_main_db_cryptkey ) ? $conf -> db -> dolibarr_main_db_cryptkey : '' );
2010-02-03 03:22:15 +01:00
2009-09-07 16:03:19 +02:00
$return = $fieldorvalue ;
2010-09-02 00:45:10 +02:00
return ( $withQuotes ? " ' " : " " ) . $this -> escape ( $return ) . ( $withQuotes ? " ' " : " " );
2009-09-07 16:03:19 +02:00
}
2007-08-17 19:45:55 +02:00
2009-09-07 16:03:19 +02:00
/**
2012-01-28 17:22:02 +01:00
* Decrypt sensitive data in database
*
* @ param string $value Value to decrypt
* @ return string Decrypted value if used
2009-09-07 16:03:19 +02:00
*/
2009-12-23 02:12:47 +01:00
function decrypt ( $value )
2009-09-07 16:03:19 +02:00
{
2009-12-23 02:12:47 +01:00
global $conf ;
2010-02-03 03:22:15 +01:00
2009-12-23 02:12:47 +01:00
// Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
$cryptType = ( $conf -> db -> dolibarr_main_db_encryption ? $conf -> db -> dolibarr_main_db_encryption : 0 );
2010-02-03 03:22:15 +01:00
2009-12-23 02:12:47 +01:00
//Encryption key
$cryptKey = ( ! empty ( $conf -> db -> dolibarr_main_db_cryptkey ) ? $conf -> db -> dolibarr_main_db_cryptkey : '' );
2010-02-03 03:22:15 +01:00
2009-12-23 02:12:47 +01:00
$return = $value ;
2009-09-07 16:03:19 +02:00
return $return ;
}
2007-08-17 19:45:55 +02:00
2008-04-21 15:17:36 +02:00
/**
2012-01-28 17:22:02 +01:00
* Return connexion ID
*
* @ return string Id connexion
2009-09-07 16:03:19 +02:00
*/
2008-04-21 15:17:36 +02:00
function DDLGetConnectId ()
{
$resql = $this -> query ( 'SELECT CONNECTION_ID()' );
2016-05-17 23:14:30 +02:00
if ( $resql )
{
$row = $this -> fetch_row ( $resql );
return $row [ 0 ];
}
else return '?' ;
2008-04-21 15:17:36 +02:00
}
2007-08-17 19:45:55 +02:00
2008-04-21 15:17:36 +02:00
/**
2012-01-28 17:22:02 +01:00
* Create a new database
* Do not use function xxx_create_db ( xxx = mysql , ... ) as they are deprecated
* We force to create database with charset this -> forcecharset and collate this -> forcecollate
*
* @ param string $database Database name to create
* @ param string $charset Charset used to store data
* @ param string $collation Charset used to sort data
* @ param string $owner Username of database owner
2015-05-12 18:13:24 +02:00
* @ return false | resource | true resource defined if OK , false if KO
2008-12-21 22:19:49 +01:00
*/
2012-01-28 17:22:02 +01:00
function DDLCreateDb ( $database , $charset = '' , $collation = '' , $owner = '' )
2008-04-21 15:17:36 +02:00
{
2015-02-14 16:27:00 +01:00
/* if ( empty ( $charset )) $charset = $this -> forcecharset ;
2012-04-30 09:33:43 +02:00
if ( empty ( $collation )) $collation = $this -> forcecollate ;
2015-02-14 16:27:00 +01:00
*/
2012-04-30 09:33:43 +02:00
2015-02-14 16:27:00 +01:00
$sql = 'CREATE DATABASE ' . $this -> EscapeFieldName ( $database );
//TODO: Check if we need to force a charset
//$sql.= ' DEFAULT CHARACTER SET '.$charset.' DEFAULT COLLATE '.$collation;
2008-04-21 15:17:36 +02:00
$ret = $this -> query ( $sql );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
$this -> select_db ( $database );
$sql = " CREATE USER [ $owner ] FOR LOGIN [ $owner ] " ;
mssql_query ( $sql , $this -> db );
$sql = " ALTER ROLE [db_owner] ADD MEMBER [ $owner ] " ;
mssql_query ( $sql , $this -> db );
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
$sql = " ALTER DATABASE [ $database ] SET ANSI_NULL_DEFAULT ON; " ;
@ mssql_query ( $sql , $this -> db );
$sql = " ALTER DATABASE [ $database ] SET ANSI_NULL ON; " ;
@ mssql_query ( $sql , $this -> db );
2015-02-14 16:33:05 +01:00
return $ret ;
2008-04-21 15:17:36 +02:00
}
2008-09-06 01:08:07 +02:00
2008-04-21 15:17:36 +02:00
/**
2012-01-06 14:51:09 +01:00
* List tables into a database
*
* @ param string $database Name of database
* @ param string $table Nmae of table filter ( 'xxx%' )
2014-10-05 01:22:17 +02:00
* @ return array List of tables in an array
2010-04-30 19:31:46 +02:00
*/
function DDLListTables ( $database , $table = '' )
2008-04-21 15:17:36 +02:00
{
2012-02-15 13:55:00 +01:00
$this -> _results = mssql_list_tables ( $database , $this -> db );
return $this -> _results ;
2008-04-21 15:17:36 +02:00
}
2014-02-21 14:41:00 +01:00
/**
* List information of columns into a table .
*
* @ param string $table Name of table
* @ return array Tableau des informations des champs de la table
*/
function DDLInfoTable ( $table )
{
// FIXME: Dummy method
// TODO: Implement
// May help: https://stackoverflow.com/questions/600446/sql-server-how-do-you-return-the-column-names-from-a-table
$infotables = array ();
return $infotables ;
}
2008-04-21 15:17:36 +02:00
/**
2011-09-12 19:08:02 +02:00
* Create a table into database
*
* @ param string $table Nom de la table
* @ param array $fields Tableau associatif [ nom champ ][ tableau des descriptions ]
* @ param string $primary_key Nom du champ qui sera la clef primaire
* @ param string $type Type de la table
* @ param array $unique_keys Tableau associatifs Nom de champs qui seront clef unique => valeur
* @ param array $fulltext_keys Tableau des Nom de champs qui seront indexes en fulltext
2015-05-12 18:13:24 +02:00
* @ param array $keys Tableau des champs cles noms => valeur
2011-09-12 19:08:02 +02:00
* @ return int < 0 if KO , >= 0 if OK
2008-09-06 01:08:07 +02:00
*/
2015-05-12 18:13:24 +02:00
function DDLCreateTable ( $table , $fields , $primary_key , $type , $unique_keys = null , $fulltext_keys = null , $keys = null )
2007-08-17 19:45:55 +02:00
{
2015-05-12 18:13:24 +02:00
// FIXME: $fulltext_keys parameter is unused
2009-10-23 12:44:19 +02:00
// cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
2007-08-17 19:45:55 +02:00
// ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
$sql = " create table " . $table . " ( " ;
$i = 0 ;
foreach ( $fields as $field_name => $field_desc )
{
$sqlfields [ $i ] = $field_name . " " ;
$sqlfields [ $i ] .= $field_desc [ 'type' ];
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'value' ]))
2007-08-17 19:45:55 +02:00
$sqlfields [ $i ] .= " ( " . $field_desc [ 'value' ] . " ) " ;
2009-10-23 12:44:19 +02:00
else if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'attribute' ]))
2007-08-17 19:45:55 +02:00
$sqlfields [ $i ] .= " " . $field_desc [ 'attribute' ];
2009-10-23 12:44:19 +02:00
else if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'default' ]))
2007-08-17 19:45:55 +02:00
{
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /null/i " , $field_desc [ 'default' ]))
2007-08-17 19:45:55 +02:00
$sqlfields [ $i ] .= " default " . $field_desc [ 'default' ];
else
$sqlfields [ $i ] .= " default ' " . $field_desc [ 'default' ] . " ' " ;
}
2009-10-23 12:44:19 +02:00
else if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'null' ]))
2007-08-17 19:45:55 +02:00
$sqlfields [ $i ] .= " " . $field_desc [ 'null' ];
2008-09-06 01:08:07 +02:00
2009-10-23 12:44:19 +02:00
else if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'extra' ]))
2007-08-17 19:45:55 +02:00
$sqlfields [ $i ] .= " " . $field_desc [ 'extra' ];
$i ++ ;
}
if ( $primary_key != " " )
$pk = " primary key( " . $primary_key . " ) " ;
2008-09-06 01:08:07 +02:00
2015-05-12 18:13:24 +02:00
if ( is_array ( $unique_keys ))
2007-08-17 19:45:55 +02:00
{
$i = 0 ;
foreach ( $unique_keys as $key => $value )
{
$sqluq [ $i ] = " UNIQUE KEY ' " . $key . " ' (' " . $value . " ') " ;
$i ++ ;
}
}
2015-05-12 18:13:24 +02:00
if ( is_array ( $keys ))
2007-08-17 19:45:55 +02:00
{
$i = 0 ;
foreach ( $keys as $key => $value )
{
$sqlk [ $i ] = " KEY " . $key . " ( " . $value . " ) " ;
$i ++ ;
}
}
$sql .= implode ( ',' , $sqlfields );
if ( $primary_key != " " )
$sql .= " , " . $pk ;
2015-05-12 18:13:24 +02:00
if ( is_array ( $unique_keys ))
2007-08-17 19:45:55 +02:00
$sql .= " , " . implode ( ',' , $sqluq );
2015-05-12 18:13:24 +02:00
if ( is_array ( $keys ))
2007-08-17 19:45:55 +02:00
$sql .= " , " . implode ( ',' , $sqlk );
$sql .= " ) type= " . $type ;
2008-09-06 01:08:07 +02:00
2009-02-20 23:53:15 +01:00
dol_syslog ( $sql );
2007-08-17 19:45:55 +02:00
if ( ! $this -> query ( $sql ))
2008-09-06 01:08:07 +02:00
return - 1 ;
2007-08-17 19:45:55 +02:00
else
2008-09-06 01:08:07 +02:00
return 1 ;
2007-08-17 19:45:55 +02:00
}
2017-11-21 11:50:57 +01:00
/**
* Drop a table into database
*
* @ param string $table Name of table
* @ return int < 0 if KO , >= 0 if OK
*/
function DDLDropTable ( $table )
{
$sql = " DROP TABLE " . $table ;
if ( ! $this -> query ( $sql ))
return - 1 ;
else
return 1 ;
}
2007-08-17 19:45:55 +02:00
/**
2012-01-06 14:51:09 +01:00
* Return a pointer of line with description of a table or field
*
* @ param string $table Name of table
* @ param string $field Optionnel : Name of field if we want description of field
2015-05-12 18:13:24 +02:00
* @ return false | resource | true Resource
2012-01-06 14:51:09 +01:00
*/
2007-08-17 19:45:55 +02:00
function DDLDescTable ( $table , $field = " " )
2008-09-06 01:08:07 +02:00
{
2007-08-17 19:45:55 +02:00
$sql = " DESC " . $table . " " . $field ;
2009-02-20 23:53:15 +01:00
dol_syslog ( $sql );
2012-02-15 13:55:00 +01:00
$this -> _results = $this -> query ( $sql );
return $this -> _results ;
2008-09-06 01:08:07 +02:00
}
2007-08-17 19:45:55 +02:00
/**
2012-01-06 14:51:09 +01:00
* Create a new field into table
*
* @ param string $table Name of table
* @ param string $field_name Name of field to add
* @ param string $field_desc Tableau associatif de description du champ a inserer [ nom du parametre ][ valeur du parametre ]
* @ param string $field_position Optionnel ex .: " after champtruc "
* @ return int < 0 if KO , > 0 if OK
2009-01-27 00:52:37 +01:00
*/
2007-08-17 19:45:55 +02:00
function DDLAddField ( $table , $field_name , $field_desc , $field_position = " " )
{
2009-10-23 12:44:19 +02:00
// cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
2007-08-17 19:45:55 +02:00
// ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
$sql = " ALTER TABLE " . $table . " ADD " . $field_name . " " ;
$sql .= $field_desc [ 'type' ];
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'value' ]))
2008-09-06 01:08:07 +02:00
$sql .= " ( " . $field_desc [ 'value' ] . " ) " ;
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'attribute' ]))
2008-09-06 01:08:07 +02:00
$sql .= " " . $field_desc [ 'attribute' ];
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'null' ]))
2008-09-06 01:08:07 +02:00
$sql .= " " . $field_desc [ 'null' ];
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'default' ]))
if ( preg_match ( " /null/i " , $field_desc [ 'default' ]))
2008-09-06 01:08:07 +02:00
$sql .= " default " . $field_desc [ 'default' ];
else
$sql .= " default ' " . $field_desc [ 'default' ] . " ' " ;
2009-10-23 12:44:19 +02:00
if ( preg_match ( " /^[^ \ s]/i " , $field_desc [ 'extra' ]))
2008-09-06 01:08:07 +02:00
$sql .= " " . $field_desc [ 'extra' ];
2007-08-17 19:45:55 +02:00
$sql .= " " . $field_position ;
if ( ! $this -> query ( $sql ))
2008-09-06 01:08:07 +02:00
return - 1 ;
2007-08-17 19:45:55 +02:00
else
2008-09-06 01:08:07 +02:00
return 1 ;
2007-08-17 19:45:55 +02:00
}
2008-09-06 01:08:07 +02:00
2011-03-08 11:33:43 +01:00
/**
* Update format of a field into a table
2012-01-06 14:51:09 +01:00
*
* @ param string $table Name of table
* @ param string $field_name Name of field to modify
* @ param string $field_desc Array with description of field format
* @ return int < 0 if KO , > 0 if OK
2011-03-08 11:33:43 +01:00
*/
function DDLUpdateField ( $table , $field_name , $field_desc )
{
2011-03-08 11:48:53 +01:00
$sql = " ALTER TABLE " . $table ;
2011-03-08 11:33:43 +01:00
$sql .= " MODIFY COLUMN " . $field_name . " " . $field_desc [ 'type' ];
2012-11-11 15:10:01 +01:00
if ( $field_desc [ 'type' ] == 'tinyint' || $field_desc [ 'type' ] == 'int' || $field_desc [ 'type' ] == 'varchar' ) {
$sql .= " ( " . $field_desc [ 'value' ] . " ) " ;
}
2009-01-27 00:52:37 +01:00
2011-03-08 11:33:43 +01:00
dol_syslog ( $sql , LOG_DEBUG );
if ( ! $this -> query ( $sql ))
return - 1 ;
else
return 1 ;
}
2011-03-09 16:01:39 +01:00
2009-01-27 00:52:37 +01:00
/**
2012-01-06 14:51:09 +01:00
* Drop a field from table
*
* @ param string $table Name of table
* @ param string $field_name Name of field to drop
* @ return int < 0 if KO , > 0 if OK
2009-01-27 00:52:37 +01:00
*/
function DDLDropField ( $table , $field_name )
{
$sql = " ALTER TABLE " . $table . " DROP COLUMN ` " . $field_name . " ` " ;
2009-02-20 23:53:15 +01:00
dol_syslog ( $sql , LOG_DEBUG );
2009-01-27 00:52:37 +01:00
if ( ! $this -> query ( $sql ))
{
$this -> error = $this -> lasterror ();
return - 1 ;
}
else return 1 ;
}
2014-02-21 14:41:00 +01:00
/**
* Create a user and privileges to connect to database ( even if database does not exists yet )
*
* @ param string $dolibarr_main_db_host Ip serveur
* @ param string $dolibarr_main_db_user Nom user a creer
* @ param string $dolibarr_main_db_pass Mot de passe user a creer
* @ param string $dolibarr_main_db_name Database name where user must be granted
* @ return int < 0 if KO , >= 0 if OK
*/
function DDLCreateUser ( $dolibarr_main_db_host , $dolibarr_main_db_user , $dolibarr_main_db_pass , $dolibarr_main_db_name )
{
2015-02-14 16:27:00 +01:00
$sql = " CREATE LOGIN " . $this -> EscapeFieldName ( $dolibarr_main_db_user ) . " WITH PASSWORD=' $dolibarr_main_db_pass ' " ;
dol_syslog ( get_class ( $this ) . " ::DDLCreateUser " , LOG_DEBUG ); // No sql to avoid password in log
$resql = $this -> query ( $sql );
if ( ! $resql )
{
if ( $this -> lasterrno != '15025' )
{
return - 1 ;
}
else
{
// If user already exists, we continue to set permissions
dol_syslog ( get_class ( $this ) . " ::DDLCreateUser sql= " . $sql , LOG_WARNING );
}
}
$sql = " SELECT name from sys.databases where name=' " . $dolibarr_main_db_name . " ' " ;
$ressql = $this -> query ( $sql );
2015-03-06 01:30:46 +01:00
if ( ! $ressql )
2015-02-14 16:27:00 +01:00
{
dol_syslog ( get_class ( $this ) . " ::DDLCreateUser sql= " . $sql , LOG_WARNING );
return - 1 ;
2015-03-06 01:30:46 +01:00
}
else
2015-02-14 16:27:00 +01:00
{
if ( $num )
{
$this -> select_db ( $dolibarr_main_db_name );
$sql = " CREATE USER [ $dolibarr_main_db_user ] FOR LOGIN [ $dolibarr_main_db_user ] " ;
$this -> query ( $sql );
$sql = " ALTER ROLE [db_owner] ADD MEMBER [ $dolibarr_main_db_user ] " ;
$this -> query ( $sql );
}
}
return 1 ;
2014-02-21 14:41:00 +01:00
}
2009-01-27 00:52:37 +01:00
2012-01-06 14:51:09 +01:00
/**
* Return charset used to store data in database
*
* @ return string Charset
*/
function getDefaultCharacterSetDatabase ()
{
2014-02-21 14:57:19 +01:00
// FIXME: Dummy method
// TODO: Implement
2008-09-06 01:08:07 +02:00
return '' ;
}
2012-01-06 14:51:09 +01:00
/**
* Return list of available charset that can be used to store data in database
*
* @ return array List of Charset
*/
function getListOfCharacterSet ()
{
2014-02-21 14:57:19 +01:00
// FIXME: Dummy method
// TODO: Implement
return '' ;
2007-08-17 21:19:26 +02:00
}
2008-09-06 01:08:07 +02:00
2012-01-06 14:51:09 +01:00
/**
* Return collation used in database
*
* @ return string Collation value
*/
2009-11-29 20:32:16 +01:00
function getDefaultCollationDatabase ()
{
2007-08-20 20:00:15 +02:00
$resql = $this -> query ( " SELECT SERVERPROPERTY('collation') " );
2008-09-06 01:08:07 +02:00
if ( ! $resql )
{
2007-08-17 21:19:26 +02:00
return $this -> forcecollate ;
2008-09-06 01:08:07 +02:00
}
$liste = $this -> fetch_array ( $resql );
return $liste [ 'computed' ];
2007-08-17 21:19:26 +02:00
}
2008-09-06 01:08:07 +02:00
2012-01-06 14:51:09 +01:00
/**
* Return list of available collation that can be used for database
*
* @ return array Liste of Collation
*/
2009-11-29 20:32:16 +01:00
function getListOfCollation ()
{
2014-02-21 14:57:19 +01:00
// FIXME: Dummy method
// TODO: Implement
2015-05-12 18:13:24 +02:00
return array ();
2008-09-06 01:08:07 +02:00
}
2012-01-06 14:51:09 +01:00
/**
* Return full path of dump program
*
2011-08-04 15:58:14 +02:00
* @ return string Full path of dump program
*/
2009-11-29 20:32:16 +01:00
function getPathOfDump ()
{
2014-02-21 14:57:19 +01:00
// FIXME: Dummy method
// TODO: Implement
2009-11-29 20:32:16 +01:00
2011-08-04 15:58:14 +02:00
return '' ;
2009-11-29 20:32:16 +01:00
}
2012-01-06 14:51:09 +01:00
/**
* Return full path of restore program
*
* @ return string Full path of restore program
*/
2009-11-29 20:32:16 +01:00
function getPathOfRestore ()
{
2014-02-21 14:57:19 +01:00
// FIXME: Dummy method
// TODO: Implement
2009-11-29 20:32:16 +01:00
2011-08-04 15:58:14 +02:00
return '' ;
2009-11-29 20:32:16 +01:00
}
2014-02-21 14:41:00 +01:00
/**
2014-02-24 09:52:48 +01:00
* Return value of server parameters
2014-02-21 14:41:00 +01:00
*
2014-02-24 09:52:48 +01:00
* @ param string $filter Filter list on a particular value
* @ return array Array of key - values ( key => value )
2014-02-21 14:41:00 +01:00
*/
function getServerParametersValues ( $filter = '' )
{
// FIXME: Dummy method
// TODO: Implement
// May help: SELECT SERVERPROPERTY
$result = array ();
return $result ;
}
/**
2014-02-24 09:52:48 +01:00
* Return value of server status
2014-02-21 14:41:00 +01:00
*
2014-02-24 09:52:48 +01:00
* @ param string $filter Filter list on a particular value
* @ return array Array of key - values ( key => value )
2014-02-21 14:41:00 +01:00
*/
function getServerStatusValues ( $filter = '' )
{
// FIXME: Dummy method
// TODO: Implement
// May help: http://www.experts-exchange.com/Database/MS-SQL-Server/Q_20971756.html
2014-02-24 09:52:48 +01:00
return array ();
2014-02-21 14:41:00 +01:00
}
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
/**
* Escape a field name according to escape ' s syntax
*
* @ param string $fieldname Field ' s name to escape
* @ return string field ' s name escaped
*/
function EscapeFieldName ( $fieldname ) {
return " [ " . $fieldname . " ] " ;
}
2015-03-06 01:30:46 +01:00
2015-02-14 16:27:00 +01:00
/**
* Get information on field
2015-03-06 01:30:46 +01:00
*
2015-02-14 16:27:00 +01:00
* @ param string $table Table name which contains fields
* @ param mixed $fields String for one field or array of string for multiple field
2015-05-12 18:13:24 +02:00
* @ return false | object
2015-02-14 16:27:00 +01:00
*/
function GetFieldInformation ( $table , $fields ) {
$sql = " SELECT * from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=' " . $this -> escape ( $table ) . " ' AND COLUMN_NAME " ;
2015-03-06 01:30:46 +01:00
if ( is_array ( $fields ))
2015-02-14 16:27:00 +01:00
{
$where = " IN (' " . implode ( " ',' " , $fields ) . " ') " ;
}
else
{
$where = " =' " . $this -> escape ( $fields ) . " ' " ;
}
$result = array ();
$ret = mssql_query ( $sql . $where , $this -> db );
if ( $ret )
{
while ( $obj = mssql_fetch_object ( $ret ))
{
$result [] = $obj ;
}
}
2015-03-06 01:30:46 +01:00
else
2015-02-14 16:27:00 +01:00
return false ;
return $result ;
}
2007-08-17 19:45:55 +02:00
}