PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/core/db/mssql.class.php

https://github.com/asterix14/dolibarr
PHP | 1057 lines | 558 code | 100 blank | 399 comment | 80 complexity | 267e24521219c7d52f92a3218a1bc96b MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2002-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2005-2007 Regis Houssin <regis@dolibarr.fr>
  5. * Copyright (C) 2007 Simon Desee <simon@dedisoft.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * \file htdocs/core/db/mssql.class.php
  22. * \brief Fichier de la classe permettant de gerer une base mssql
  23. */
  24. /**
  25. * \class DoliDBMssql
  26. * \brief Classe de gestion de la database de dolibarr
  27. * \remarks Works with PHP5 Only
  28. */
  29. class DoliDBMssql
  30. {
  31. //! Database handler
  32. var $db;
  33. //! Database type
  34. var $type='mssql';
  35. //! Database label
  36. var $label='MSSQL';
  37. //! Charset used to force charset when creating database
  38. var $forcecharset='latin1';
  39. //! Collate used to force collate when creating database
  40. var $forcecollate='latin1_swedish_ci';
  41. //! Version min database
  42. var $versionmin=array(2000);
  43. //! Resultset de la derniere requete
  44. var $results;
  45. //! 1 si connecte, 0 sinon
  46. var $connected;
  47. //! 1 si base selectionne, 0 sinon
  48. var $database_selected;
  49. //! Nom base selectionnee
  50. var $database_name;
  51. //! Nom user base
  52. var $database_user;
  53. //! 1 si une transaction est en cours, 0 sinon
  54. var $transaction_opened;
  55. //! Derniere requete executee
  56. var $lastquery;
  57. //! Derniere requete executee avec echec
  58. var $lastqueryerror;
  59. //! Message erreur mysql
  60. var $lasterror;
  61. //! Message erreur mysql
  62. var $lasterrno;
  63. var $ok;
  64. var $error;
  65. /**
  66. * Constructor.
  67. * This create an opened connexion to a database server and eventually to a database
  68. *
  69. * @param string $type Type of database (mysql, pgsql...)
  70. * @param string $host Address of database server
  71. * @param string $user Nom de l'utilisateur autorise
  72. * @param string $pass Mot de passe
  73. * @param string $name Nom de la database
  74. * @param int $port Port of database server
  75. * @return int 1 if OK, 0 if not
  76. */
  77. function DoliDBMssql($type, $host, $user, $pass, $name='', $port=0)
  78. {
  79. global $conf,$langs;
  80. $this->database_user=$user;
  81. $this->transaction_opened=0;
  82. if (! function_exists("mssql_connect"))
  83. {
  84. $this->connected = 0;
  85. $this->ok = 0;
  86. $this->error="Mssql PHP functions for using MSSql driver are not available in this version of PHP";
  87. dol_syslog("DoliDB::DoliDB : MSsql PHP functions for using MSsql driver are not available in this version of PHP",LOG_ERR);
  88. return $this->ok;
  89. }
  90. if (! $host)
  91. {
  92. $this->connected = 0;
  93. $this->ok = 0;
  94. $this->error=$langs->trans("ErrorWrongHostParameter");
  95. dol_syslog("DoliDB::DoliDB : Erreur Connect, wrong host parameters",LOG_ERR);
  96. return $this->ok;
  97. }
  98. // Essai connexion serveur
  99. $this->db = $this->connect($host, $user, $pass, $name, $port);
  100. if ($this->db)
  101. {
  102. // Si client connecte avec charset different de celui de la base Dolibarr
  103. // (La base Dolibarr a ete forcee en this->forcecharset a l'install)
  104. $this->connected = 1;
  105. $this->ok = 1;
  106. }
  107. else
  108. {
  109. // host, login ou password incorrect
  110. $this->connected = 0;
  111. $this->ok = 0;
  112. $this->error=mssql_get_last_message();
  113. dol_syslog("DoliDB::DoliDB : Erreur Connect mssql_get_last_message=".$this->error,LOG_ERR);
  114. }
  115. // Si connexion serveur ok et si connexion base demandee, on essaie connexion base
  116. if ($this->connected && $name)
  117. {
  118. if ($this->select_db($name))
  119. {
  120. $this->database_selected = 1;
  121. $this->database_name = $name;
  122. $this->ok = 1;
  123. }
  124. else
  125. {
  126. $this->database_selected = 0;
  127. $this->database_name = '';
  128. $this->ok = 0;
  129. $this->error=$this->error();
  130. dol_syslog("DoliDB::DoliDB : Erreur Select_db ".$this->error,LOG_ERR);
  131. }
  132. }
  133. else
  134. {
  135. // Pas de selection de base demandee, ok ou ko
  136. $this->database_selected = 0;
  137. }
  138. return $this->ok;
  139. }
  140. /**
  141. * Convert a SQL request in Mysql syntax to native syntax
  142. *
  143. * @param string $line SQL request line to convert
  144. * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
  145. * @return string SQL request line converted
  146. */
  147. function convertSQLFromMysql($line,$type='ddl')
  148. {
  149. return $line;
  150. }
  151. /**
  152. * Select a database
  153. *
  154. * @param string $database Name of database
  155. * @return boolean true if OK, false if KO
  156. */
  157. function select_db($database)
  158. {
  159. return mssql_select_db($database, $this->db);
  160. }
  161. /**
  162. * Connexion to server
  163. *
  164. * @param string $host database server host
  165. * @param string $login login
  166. * @param string $passwd password
  167. * @param string $name name of database (not used for mysql, used for pgsql)
  168. * @param string $port Port of database server
  169. * @return resource Database access handler
  170. * @see close
  171. */
  172. function connect($host, $login, $passwd, $name, $port=0)
  173. {
  174. dol_syslog("DoliDB::connect host=$host, port=$port, login=$login, passwd=--hidden--, name=$name");
  175. $newhost=$host;
  176. if ($port) $newhost.=':'.$port;
  177. $this->db = @mssql_connect($newhost, $login, $passwd);
  178. //force les enregistrement en latin1 si la base est en utf8 par defaut
  179. // Supprime car plante sur mon PHP-Mysql. De plus, la base est forcement en latin1 avec
  180. // les nouvelles version de Dolibarr car force par l'install Dolibarr.
  181. //$this->query('SET NAMES '.$this->forcecharset);
  182. //print "Resultat fonction connect: ".$this->db;
  183. return $this->db;
  184. }
  185. /**
  186. * Return label of manager
  187. *
  188. * @return string Label
  189. */
  190. function getLabel()
  191. {
  192. return $this->label;
  193. }
  194. /**
  195. * Return version of database server
  196. *
  197. * @return string Version string
  198. */
  199. function getVersion()
  200. {
  201. $resql=$this->query("SELECT @@VERSION");
  202. $version=$this->fetch_array($resql);
  203. return $version['computed'];
  204. }
  205. /**
  206. * Return version of database server into an array
  207. *
  208. * @return array Version array
  209. */
  210. function getVersionArray()
  211. {
  212. return explode('.',$this->getVersion());
  213. }
  214. /**
  215. * Close database connexion
  216. *
  217. * @return boolean True if disconnect successfull, false otherwise
  218. * @see connect
  219. */
  220. function close()
  221. {
  222. if ($this->db)
  223. {
  224. //dol_syslog("DoliDB::disconnect",LOG_DEBUG);
  225. $this->connected=0;
  226. return mssql_close($this->db);
  227. }
  228. return false;
  229. }
  230. /**
  231. * Start transaction
  232. *
  233. * @return int 1 if transaction successfuly opened or already opened, 0 if error
  234. */
  235. function begin()
  236. {
  237. if (! $this->transaction_opened)
  238. {
  239. $ret=$this->query("BEGIN TRANSACTION");
  240. if ($ret)
  241. {
  242. $this->transaction_opened++;
  243. dol_syslog("BEGIN Transaction",LOG_DEBUG);
  244. }
  245. return $ret;
  246. }
  247. else
  248. {
  249. $this->transaction_opened++;
  250. return 1;
  251. }
  252. }
  253. /**
  254. * Validate a database transaction
  255. *
  256. * @param $log Add more log to default log line
  257. * @return int 1 if validation is OK or transaction level no started, 0 if ERROR
  258. */
  259. function commit($log='')
  260. {
  261. if ($this->transaction_opened <= 1)
  262. {
  263. $ret=$this->query("COMMIT TRANSACTION");
  264. if ($ret)
  265. {
  266. $this->transaction_opened=0;
  267. dol_syslog("COMMIT Transaction",LOG_DEBUG);
  268. }
  269. return $ret;
  270. }
  271. else
  272. {
  273. $this->transaction_opened--;
  274. return 1;
  275. }
  276. }
  277. /**
  278. * Annulation d'une transaction et retour aux anciennes valeurs
  279. *
  280. * @return int 1 si annulation ok ou transaction non ouverte, 0 en cas d'erreur
  281. */
  282. function rollback()
  283. {
  284. if ($this->transaction_opened<=1)
  285. {
  286. $ret=$this->query("ROLLBACK TRANSACTION");
  287. $this->transaction_opened=0;
  288. dol_syslog("ROLLBACK Transaction",LOG_DEBUG);
  289. return $ret;
  290. }
  291. else
  292. {
  293. $this->transaction_opened--;
  294. return 1;
  295. }
  296. }
  297. /**
  298. * Execute a SQL request and return the resultset
  299. *
  300. * @param query SQL query string
  301. * @param 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).
  302. * 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.
  303. * @param type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
  304. * @return resource Resultset of answer
  305. */
  306. function query($query,$usesavepoint=0,$type='auto')
  307. {
  308. $query = trim($query);
  309. // Conversion syntaxe MySql vers MSDE.
  310. $query = str_ireplace("now()", "getdate()", $query);
  311. // Erreur SQL: cannot update timestamp field
  312. $query = str_ireplace(", tms = tms", "", $query);
  313. // Voir si l'on peut directement utiliser $query = str_ireplace("file", "[file]", $query);
  314. // au lieu des 3 lignes ci-dessous
  315. $query = str_ireplace(".file", ".[file]", $query);
  316. $query = str_ireplace(" file ", " [file] ", $query);
  317. $query = str_ireplace(" file,", " [file],", $query);
  318. // Idem file
  319. $query = str_ireplace(".percent", ".[percent]", $query);
  320. $query = str_ireplace(" percent ", " [percent] ", $query);
  321. $query = str_ireplace("percent,", "[percent],", $query);
  322. $query = str_ireplace("percent=", "[percent]=", $query);
  323. $query = str_ireplace("\'", "''", $query);
  324. $itemfound = stripos($query, " limit ");
  325. if ($itemfound !== false) {
  326. // Extraire le nombre limite
  327. $number = stristr($query, " limit ");
  328. $number = substr($number, 7);
  329. // Inserer l'instruction TOP et le nombre limite
  330. $query = str_ireplace("select ", "select top ".$number." ", $query);
  331. // Supprimer l'instruction MySql
  332. $query = str_ireplace(" limit ".$number, "", $query);
  333. }
  334. $itemfound = stripos($query, " week(");
  335. if ($itemfound !== false) {
  336. // Recreer une requete sans instruction Mysql
  337. $positionMySql = stripos($query, " week(");
  338. $newquery = substr($query, 0, $positionMySql);
  339. // Recuperer la date passee en parametre
  340. $extractvalue = stristr($query, " week(");
  341. $extractvalue = substr($extractvalue, 6);
  342. $positionMySql = stripos($extractvalue, ")");
  343. // Conserver la fin de la requete
  344. $endofquery = substr($extractvalue, $positionMySql);
  345. $extractvalue = substr($extractvalue, 0, $positionMySql);
  346. // Remplacer l'instruction MySql en Sql Server
  347. // Inserer la date en parametre et le reste de la requete
  348. $query = $newquery." DATEPART(week, ".$extractvalue.$endofquery;
  349. }
  350. //print "<!--".$query."-->";
  351. if (! $this->database_name)
  352. {
  353. // Ordre SQL ne necessitant pas de connexion a une base (exemple: CREATE DATABASE)
  354. $ret = mssql_query($query, $this->db);
  355. }
  356. else
  357. {
  358. $ret = mssql_query($query, $this->db);
  359. }
  360. if (! preg_match("/^COMMIT/i",$query) && ! preg_match("/^ROLLBACK/i",$query))
  361. {
  362. // Si requete utilisateur, on la sauvegarde ainsi que son resultset
  363. if (! $ret)
  364. {
  365. $result = mssql_query("SELECT @@ERROR as code", $this->db);
  366. $row = mssql_fetch_array($result);
  367. $this->lastqueryerror = $query;
  368. $this->lasterror = $this->error();
  369. $this->lasterrno = $row["code"];
  370. dol_syslog("Mssql.lib::query SQL error: ".$query, LOG_WARNING);
  371. }
  372. $this->lastquery=$query;
  373. $this->results = $ret;
  374. }
  375. return $ret;
  376. }
  377. /**
  378. * Renvoie la ligne courante (comme un objet) pour le curseur resultset
  379. *
  380. * @param resultset Curseur de la requete voulue
  381. * @return object Object result line or false if KO or end of cursor
  382. */
  383. function fetch_object($resultset)
  384. {
  385. // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
  386. if (! is_resource($resultset)) { $resultset=$this->results; }
  387. return mssql_fetch_object($resultset);
  388. }
  389. /**
  390. * Renvoie les donnees dans un tableau
  391. *
  392. * @param resultset Curseur de la requete voulue
  393. * @return array
  394. */
  395. function fetch_array($resultset)
  396. {
  397. // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
  398. if (! is_resource($resultset)) { $resultset=$this->results; }
  399. return mssql_fetch_array($resultset);
  400. }
  401. /**
  402. * \brief Renvoie les donnees comme un tableau.
  403. * \param resultset Curseur de la requete voulue
  404. * \return array
  405. */
  406. function fetch_row($resultset)
  407. {
  408. // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
  409. if (! is_resource($resultset)) { $resultset=$this->results; }
  410. return @mssql_fetch_row($resultset);
  411. }
  412. /**
  413. * \brief Renvoie le nombre de lignes dans le resultat d'une requete SELECT
  414. * \see affected_rows
  415. * \param resultset Curseur de la requete voulue
  416. * \return int Nombre de lignes
  417. */
  418. function num_rows($resultset)
  419. {
  420. // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
  421. if (! is_resource($resultset)) { $resultset=$this->results; }
  422. return mssql_num_rows($resultset);
  423. }
  424. /**
  425. \brief Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE
  426. \see num_rows
  427. \param resultset Curseur de la requete voulue
  428. \return int Nombre de lignes
  429. */
  430. function affected_rows($resultset)
  431. {
  432. // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
  433. if (! is_resource($resultset)) { $resultset=$this->results; }
  434. // mssql necessite un link de base pour cette fonction contrairement
  435. // a pqsql qui prend un resultset
  436. $rsRows = mssql_query("select @@rowcount as rows", $this->db);
  437. return mssql_result($rsRows, 0, "rows");
  438. //return mssql_affected_rows($this->db);
  439. }
  440. /**
  441. * \brief Libere le dernier resultset utilise sur cette connexion.
  442. * \param resultset Curseur de la requete voulue
  443. */
  444. function free($resultset=0)
  445. {
  446. // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
  447. if (! is_resource($resultset)) { $resultset=$this->results; }
  448. // Si resultset en est un, on libere la memoire
  449. if (is_resource($resultset)) mssql_free_result($resultset);
  450. }
  451. /**
  452. * \brief Defini les limites de la requete.
  453. * \param limit nombre maximum de lignes retournees
  454. * \param offset numero de la ligne a partir de laquelle recuperer les ligne
  455. * \return string chaine exprimant la syntax sql de la limite
  456. */
  457. function plimit($limit=0,$offset=0)
  458. {
  459. global $conf;
  460. if (! $limit) $limit=$conf->liste_limit;
  461. if ($offset > 0) return " LIMIT $offset,$limit ";
  462. else return " LIMIT $limit ";
  463. }
  464. /**
  465. * Define sort criteria of request
  466. * @param sortfield List of sort fields
  467. * @param sortorder Sort order
  468. * @return string String to provide syntax of a sort sql string
  469. * TODO Mutualized this into a mother class
  470. */
  471. function order($sortfield=0,$sortorder=0)
  472. {
  473. if ($sortfield)
  474. {
  475. $return='';
  476. $fields=explode(',',$sortfield);
  477. foreach($fields as $val)
  478. {
  479. if (! $return) $return.=' ORDER BY ';
  480. else $return.=',';
  481. $return.=preg_replace('/[^0-9a-z_\.]/i','',$val);
  482. if ($sortorder) $return.=' '.preg_replace('/[^0-9a-z]/i','',$sortorder);
  483. }
  484. return $return;
  485. }
  486. else
  487. {
  488. return '';
  489. }
  490. }
  491. /**
  492. * Escape a string to insert data.
  493. * @param stringtoencode String to escape
  494. * @return string String escaped
  495. */
  496. function escape($stringtoencode)
  497. {
  498. return addslashes($stringtoencode);
  499. }
  500. /**
  501. * Convert (by PHP) a GM Timestamp date into a PHP server TZ to insert into a date field.
  502. * Function to use to build INSERT, UPDATE or WHERE predica
  503. * @param param Date TMS to convert
  504. * @return string Date in a string YYYYMMDDHHMMSS
  505. */
  506. function idate($param)
  507. {
  508. return adodb_strftime("%Y-%m-%d %H:%M:%S",$param);
  509. }
  510. /**
  511. * Convert (by PHP) a PHP server TZ string date into a GM Timestamps date
  512. * 19700101020000 -> 3600 with TZ+1
  513. * @param string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS)
  514. * @return date Date TMS
  515. */
  516. function jdate($string)
  517. {
  518. $string=preg_replace('/([^0-9])/i','',$string);
  519. $tmp=$string.'000000';
  520. $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));
  521. return $date;
  522. }
  523. /**
  524. * Formate a SQL IF
  525. * @param test chaine test
  526. * @param resok resultat si test egal
  527. * @param resko resultat si test non egal
  528. * @return string chaine formate SQL
  529. */
  530. function ifsql($test,$resok,$resko)
  531. {
  532. return 'IF('.$test.','.$resok.','.$resko.')';
  533. }
  534. /**
  535. * \brief Renvoie la derniere requete soumise par la methode query()
  536. * \return lastquery
  537. */
  538. function lastquery()
  539. {
  540. return $this->lastquery;
  541. }
  542. /**
  543. \brief Renvoie la derniere requete en erreur
  544. \return string lastqueryerror
  545. */
  546. function lastqueryerror()
  547. {
  548. return $this->lastqueryerror;
  549. }
  550. /**
  551. \brief Renvoie le libelle derniere erreur
  552. \return string lasterror
  553. */
  554. function lasterror()
  555. {
  556. return $this->lasterror;
  557. }
  558. /**
  559. \brief Renvoie le code derniere erreur
  560. \return string lasterrno
  561. */
  562. function lasterrno()
  563. {
  564. return $this->lasterrno;
  565. }
  566. /**
  567. \brief Renvoie le code erreur generique de l'operation precedente.
  568. \return error_num (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...)
  569. */
  570. function errno()
  571. {
  572. if (! $this->connected) {
  573. // Si il y a eu echec de connexion, $this->db n'est pas valide.
  574. return 'DB_ERROR_FAILED_TO_CONNECT';
  575. }
  576. else {
  577. // Constants to convert a MSSql error code to a generic Dolibarr error code
  578. $errorcode_map = array(
  579. 1004 => 'DB_ERROR_CANNOT_CREATE',
  580. 1005 => 'DB_ERROR_CANNOT_CREATE',
  581. 1006 => 'DB_ERROR_CANNOT_CREATE',
  582. 1007 => 'DB_ERROR_ALREADY_EXISTS',
  583. 1008 => 'DB_ERROR_CANNOT_DROP',
  584. 1025 => 'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
  585. 1046 => 'DB_ERROR_NODBSELECTED',
  586. 1048 => 'DB_ERROR_CONSTRAINT',
  587. 2714 => 'DB_ERROR_TABLE_ALREADY_EXISTS',
  588. 1051 => 'DB_ERROR_NOSUCHTABLE',
  589. 1054 => 'DB_ERROR_NOSUCHFIELD',
  590. 1060 => 'DB_ERROR_COLUMN_ALREADY_EXISTS',
  591. 1061 => 'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
  592. 2627 => 'DB_ERROR_RECORD_ALREADY_EXISTS',
  593. 102 => 'DB_ERROR_SYNTAX',
  594. 8120 => 'DB_ERROR_GROUP_BY_SYNTAX',
  595. 1068 => 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
  596. 1075 => 'DB_ERROR_CANT_DROP_PRIMARY_KEY',
  597. 1091 => 'DB_ERROR_NOSUCHFIELD',
  598. 1100 => 'DB_ERROR_NOT_LOCKED',
  599. 1136 => 'DB_ERROR_VALUE_COUNT_ON_ROW',
  600. 1146 => 'DB_ERROR_NOSUCHTABLE',
  601. 1216 => 'DB_ERROR_NO_PARENT',
  602. 1217 => 'DB_ERROR_CHILD_EXISTS',
  603. 1451 => 'DB_ERROR_CHILD_EXISTS'
  604. );
  605. if (isset($errorcode_map[$this->lasterrno]))
  606. {
  607. return $errorcode_map[$this->lasterrno];
  608. }
  609. $errno=$this->lasterrno;
  610. return ($errno?'DB_ERROR_'.$errno:'0');
  611. }
  612. }
  613. /**
  614. \brief Renvoie le texte de l'erreur mssql de l'operation precedente.
  615. \return error_text
  616. */
  617. function error()
  618. {
  619. if (! $this->connected) {
  620. // Si il y a eu echec de connexion, $this->db n'est pas valide pour mssql_get_last_message.
  621. return 'Not connected. Check setup parameters in conf/conf.php file and your mssql client and server versions';
  622. }
  623. else {
  624. return mssql_get_last_message($this->db);
  625. }
  626. }
  627. /**
  628. \brief Recupere l'id genere par le dernier INSERT.
  629. \param tab Nom de la table concernee par l'insert. Ne sert pas sous mssql mais requis pour compatibilite avec Postgresql
  630. \return int id
  631. */
  632. function last_insert_id($tab)
  633. {
  634. $res = $this->query("SELECT @@IDENTITY as id");
  635. if ($data = $this->fetch_array($res))
  636. {
  637. return $data["id"];
  638. }
  639. else
  640. {
  641. return -1;
  642. }
  643. }
  644. /**
  645. * Encrypt sensitive data in database
  646. * Warning: This function includes the escape, so it must use direct value
  647. * @param fieldorvalue Field name or value to encrypt
  648. * @param withQuotes Return string with quotes
  649. * @return return XXX(field) or XXX('value') or field or 'value'
  650. */
  651. function encrypt($fieldorvalue, $withQuotes=0)
  652. {
  653. global $conf;
  654. // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
  655. $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0);
  656. //Encryption key
  657. $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:'');
  658. $return = $fieldorvalue;
  659. return ($withQuotes?"'":"").$this->escape($return).($withQuotes?"'":"");
  660. }
  661. /**
  662. * \brief Decrypt sensitive data in database
  663. * \param value Value to decrypt
  664. * \return return Decrypted value if used
  665. */
  666. function decrypt($value)
  667. {
  668. global $conf;
  669. // Type of encryption (2: AES (recommended), 1: DES , 0: no encryption)
  670. $cryptType = ($conf->db->dolibarr_main_db_encryption?$conf->db->dolibarr_main_db_encryption:0);
  671. //Encryption key
  672. $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey)?$conf->db->dolibarr_main_db_cryptkey:'');
  673. $return = $value;
  674. return $return;
  675. }
  676. // Next function are not required. Only minor features use them.
  677. //--------------------------------------------------------------
  678. /**
  679. * \brief Renvoie l'id de la connexion
  680. * \return string Id connexion
  681. */
  682. function DDLGetConnectId()
  683. {
  684. $resql=$this->query('SELECT CONNECTION_ID()');
  685. $row=$this->fetch_row($resql);
  686. return $row[0];
  687. }
  688. /**
  689. * \brief Create a new database
  690. * \param database Database name to create
  691. * \param charset Charset used to store data
  692. * \param collation Charset used to sort data
  693. * \return resource resource defined if OK, null if KO
  694. * \remarks Ne pas utiliser les fonctions xxx_create_db (xxx=mssql, ...) car elles sont deprecated
  695. * On force creation de la base avec le charset forcecharset
  696. */
  697. function DDLCreateDb($database,$charset='',$collation='')
  698. {
  699. // ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci
  700. $sql = 'CREATE DATABASE '.$database;
  701. $sql.= ' DEFAULT CHARACTER SET '.$this->forcecharset.' DEFAULT COLLATE '.$this->forcecollate;
  702. $ret=$this->query($sql);
  703. if (! $ret)
  704. {
  705. // On reessaie pour compatibilite avec mssql < 5.0
  706. $sql = 'CREATE DATABASE '.$database;
  707. $ret=$this->query($sql);
  708. }
  709. return $ret;
  710. }
  711. /**
  712. * \brief List tables into a database.
  713. * \param database Name of database
  714. * \param table Filter on some tables
  715. * \return array Array list of tables
  716. */
  717. function DDLListTables($database,$table='')
  718. {
  719. $this->results = mssql_list_tables($database, $this->db);
  720. return $this->results;
  721. }
  722. /**
  723. * Create a table into database
  724. *
  725. * @param string $table Nom de la table
  726. * @param array $fields Tableau associatif [nom champ][tableau des descriptions]
  727. * @param string $primary_key Nom du champ qui sera la clef primaire
  728. * @param string $type Type de la table
  729. * @param array $unique_keys Tableau associatifs Nom de champs qui seront clef unique => valeur
  730. * @param array $fulltext_keys Tableau des Nom de champs qui seront indexes en fulltext
  731. * @param string $keys Tableau des champs cles noms => valeur
  732. * @return int <0 if KO, >=0 if OK
  733. */
  734. function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys="",$fulltext_keys="",$keys="")
  735. {
  736. // cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
  737. // ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
  738. $sql = "create table ".$table."(";
  739. $i=0;
  740. foreach($fields as $field_name => $field_desc)
  741. {
  742. $sqlfields[$i] = $field_name." ";
  743. $sqlfields[$i] .= $field_desc['type'];
  744. if( preg_match("/^[^\s]/i",$field_desc['value']))
  745. $sqlfields[$i] .= "(".$field_desc['value'].")";
  746. else if( preg_match("/^[^\s]/i",$field_desc['attribute']))
  747. $sqlfields[$i] .= " ".$field_desc['attribute'];
  748. else if( preg_match("/^[^\s]/i",$field_desc['default']))
  749. {
  750. if(preg_match("/null/i",$field_desc['default']))
  751. $sqlfields[$i] .= " default ".$field_desc['default'];
  752. else
  753. $sqlfields[$i] .= " default '".$field_desc['default']."'";
  754. }
  755. else if( preg_match("/^[^\s]/i",$field_desc['null']))
  756. $sqlfields[$i] .= " ".$field_desc['null'];
  757. else if( preg_match("/^[^\s]/i",$field_desc['extra']))
  758. $sqlfields[$i] .= " ".$field_desc['extra'];
  759. $i++;
  760. }
  761. if($primary_key != "")
  762. $pk = "primary key(".$primary_key.")";
  763. if($unique_keys != "")
  764. {
  765. $i = 0;
  766. foreach($unique_keys as $key => $value)
  767. {
  768. $sqluq[$i] = "UNIQUE KEY '".$key."' ('".$value."')";
  769. $i++;
  770. }
  771. }
  772. if($keys != "")
  773. {
  774. $i = 0;
  775. foreach($keys as $key => $value)
  776. {
  777. $sqlk[$i] = "KEY ".$key." (".$value.")";
  778. $i++;
  779. }
  780. }
  781. $sql .= implode(',',$sqlfields);
  782. if($primary_key != "")
  783. $sql .= ",".$pk;
  784. if($unique_keys != "")
  785. $sql .= ",".implode(',',$sqluq);
  786. if($keys != "")
  787. $sql .= ",".implode(',',$sqlk);
  788. $sql .=") type=".$type;
  789. dol_syslog($sql);
  790. if(! $this -> query($sql))
  791. return -1;
  792. else
  793. return 1;
  794. }
  795. /**
  796. \brief decrit une table dans une database.
  797. \param table Nom de la table
  798. \param field Optionnel : Nom du champ si l'on veut la desc d'un champ
  799. \return resource
  800. */
  801. function DDLDescTable($table,$field="")
  802. {
  803. $sql="DESC ".$table." ".$field;
  804. dol_syslog($sql);
  805. $this->results = $this->query($sql);
  806. return $this->results;
  807. }
  808. /**
  809. * \brief Insert a new field in table
  810. * \param table Nom de la table
  811. * \param field_name Nom du champ a inserer
  812. * \param field_desc Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre]
  813. * \param field_position Optionnel ex.: "after champtruc"
  814. * \return int <0 si KO, >0 si OK
  815. */
  816. function DDLAddField($table,$field_name,$field_desc,$field_position="")
  817. {
  818. // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
  819. // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
  820. $sql= "ALTER TABLE ".$table." ADD ".$field_name." ";
  821. $sql .= $field_desc['type'];
  822. if( preg_match("/^[^\s]/i",$field_desc['value']))
  823. $sql .= "(".$field_desc['value'].")";
  824. if( preg_match("/^[^\s]/i",$field_desc['attribute']))
  825. $sql .= " ".$field_desc['attribute'];
  826. if( preg_match("/^[^\s]/i",$field_desc['null']))
  827. $sql .= " ".$field_desc['null'];
  828. if( preg_match("/^[^\s]/i",$field_desc['default']))
  829. if(preg_match("/null/i",$field_desc['default']))
  830. $sql .= " default ".$field_desc['default'];
  831. else
  832. $sql .= " default '".$field_desc['default']."'";
  833. if( preg_match("/^[^\s]/i",$field_desc['extra']))
  834. $sql .= " ".$field_desc['extra'];
  835. $sql .= " ".$field_position;
  836. if(! $this -> query($sql))
  837. return -1;
  838. else
  839. return 1;
  840. }
  841. /**
  842. * Update format of a field into a table
  843. * @param table Name of table
  844. * @param field_name Name of field to modify
  845. * @param field_desc Array with description of field format
  846. * @return int <0 if KO, >0 if OK
  847. */
  848. function DDLUpdateField($table,$field_name,$field_desc)
  849. {
  850. $sql = "ALTER TABLE ".$table;
  851. $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
  852. if ($field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') $sql.="(".$field_desc['value'].")";
  853. dol_syslog($sql,LOG_DEBUG);
  854. if (! $this->query($sql))
  855. return -1;
  856. else
  857. return 1;
  858. }
  859. /**
  860. * \brief Drop a field in table
  861. * \param table Nom de la table
  862. * \param field_name Nom du champ a inserer
  863. * \return int <0 si KO, >0 si OK
  864. */
  865. function DDLDropField($table,$field_name)
  866. {
  867. $sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`";
  868. dol_syslog($sql,LOG_DEBUG);
  869. if (! $this->query($sql))
  870. {
  871. $this->error=$this->lasterror();
  872. return -1;
  873. }
  874. else return 1;
  875. }
  876. function getDefaultCharacterSetDatabase(){
  877. /*
  878. $resql=$this->query('SHOW VARIABLES LIKE \'character_set_database\'');
  879. if (!$resql)
  880. {
  881. return $this->forcecharset;
  882. }
  883. $liste=$this->fetch_array($resql);
  884. return $liste['Value'];
  885. */
  886. return '';
  887. }
  888. function getListOfCharacterSet(){
  889. /*
  890. $resql=$this->query('SHOW CHARSET');
  891. $liste = array();
  892. if ($resql)
  893. {
  894. $i = 0;
  895. while ($obj = $this->fetch_object($resql) )
  896. {
  897. $liste[$i]['charset'] = $obj->Charset;
  898. $liste[$i]['description'] = $obj->Description;
  899. $i++;
  900. }
  901. $this->free($resql);
  902. } else {
  903. return null;
  904. }
  905. return $liste;
  906. */
  907. return ''; // attente debuggage
  908. }
  909. function getDefaultCollationDatabase()
  910. {
  911. $resql=$this->query("SELECT SERVERPROPERTY('collation')");
  912. if (!$resql)
  913. {
  914. return $this->forcecollate;
  915. }
  916. $liste=$this->fetch_array($resql);
  917. return $liste['computed'];
  918. }
  919. function getListOfCollation()
  920. {
  921. /*
  922. $resql=$this->query('SHOW COLLATION');
  923. $liste = array();
  924. if ($resql)
  925. {
  926. $i = 0;
  927. while ($obj = $this->fetch_object($resql) )
  928. {
  929. $liste[$i]['collation'] = $obj->Collation;
  930. $i++;
  931. }
  932. $this->free($resql);
  933. } else {
  934. return null;
  935. }
  936. return $liste;
  937. */
  938. return ''; // attente debugage
  939. }
  940. /*
  941. * Return full path of dump program
  942. * @return string Full path of dump program
  943. */
  944. function getPathOfDump()
  945. {
  946. return '';
  947. }
  948. /**
  949. * Return full path of restore program
  950. * @return string Full path of restore program
  951. */
  952. function getPathOfRestore()
  953. {
  954. return '';
  955. }
  956. }
  957. ?>