TraceableDB.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. <?php
  2. require_once DOL_DOCUMENT_ROOT.'/core/db/DoliDB.class.php';
  3. /**
  4. * TraceableDB class
  5. *
  6. * Used to log queries into DebugBar
  7. */
  8. class TraceableDB extends DoliDB
  9. {
  10. /**
  11. * @var DoliDb Database handler
  12. */
  13. public $db; // cannot be protected because of parent declaration
  14. /**
  15. * @var array Queries array
  16. */
  17. public $queries;
  18. /**
  19. * @var int Request start time
  20. */
  21. protected $startTime;
  22. /**
  23. * @var int Request start memory
  24. */
  25. protected $startMemory;
  26. /**
  27. * @var string type
  28. */
  29. public $type;
  30. /**
  31. * @const Database label
  32. */
  33. const LABEL = ''; // TODO: the right value should be $this->db::LABEL (but this is a constant? o_O)
  34. /**
  35. * @const Version min database
  36. */
  37. const VERSIONMIN = ''; // TODO: the same thing here, $this->db::VERSIONMIN is the right value
  38. /**
  39. * Constructor
  40. *
  41. * @param DoliDB $db Database handler
  42. */
  43. public function __construct($db)
  44. {
  45. $this->db = $db;
  46. $this->type = $this->db->type;
  47. $this->queries = array();
  48. }
  49. /**
  50. * Format a SQL IF
  51. *
  52. * @param string $test Test string (example: 'cd.statut=0', 'field IS NULL')
  53. * @param string $resok resultat si test egal
  54. * @param string $resko resultat si test non egal
  55. * @return string SQL string
  56. */
  57. public function ifsql($test, $resok, $resko)
  58. {
  59. return $this->db->ifsql($test, $resok, $resko);
  60. }
  61. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  62. /**
  63. * Return datas as an array
  64. *
  65. * @param resource $resultset Resultset of request
  66. * @return array Array
  67. */
  68. public function fetch_row($resultset)
  69. {
  70. // phpcs:enable
  71. return $this->db->fetch_row($resultset);
  72. }
  73. /**
  74. * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field.
  75. * Function to use to build INSERT, UPDATE or WHERE predica
  76. *
  77. * @param int $param Date TMS to convert
  78. * @param mixed $gm 'gmt'=Input informations are GMT values, 'tzserver'=Local to server TZ
  79. * @return string Date in a string YYYY-MM-DD HH:MM:SS
  80. */
  81. public function idate($param, $gm = 'tzserver')
  82. {
  83. return $this->db->idate($param, $gm);
  84. }
  85. /**
  86. * Return last error code
  87. *
  88. * @return string lasterrno
  89. */
  90. public function lasterrno()
  91. {
  92. return $this->db->lasterrno();
  93. }
  94. /**
  95. * Start transaction
  96. *
  97. * @return int 1 if transaction successfuly opened or already opened, 0 if error
  98. */
  99. public function begin()
  100. {
  101. return $this->db->begin();
  102. }
  103. /**
  104. * Create a new database
  105. * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
  106. * We force to create database with charset this->forcecharset and collate this->forcecollate
  107. *
  108. * @param string $database Database name to create
  109. * @param string $charset Charset used to store data
  110. * @param string $collation Charset used to sort data
  111. * @param string $owner Username of database owner
  112. * @return resource resource defined if OK, null if KO
  113. */
  114. public function DDLCreateDb($database, $charset = '', $collation = '', $owner = '')
  115. {
  116. return $this->db->DDLCreateDb($database, $charset, $collation, $owner);
  117. }
  118. /**
  119. * Return version of database server into an array
  120. *
  121. * @return array Version array
  122. */
  123. public function getVersionArray()
  124. {
  125. return $this->db->getVersionArray();
  126. }
  127. /**
  128. * Convert a SQL request in Mysql syntax to native syntax
  129. *
  130. * @param string $line SQL request line to convert
  131. * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
  132. * @return string SQL request line converted
  133. */
  134. public static function convertSQLFromMysql($line, $type = 'ddl')
  135. {
  136. return self::$db->convertSQLFromMysql($line);
  137. }
  138. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  139. /**
  140. * Return the number o flines into the result of a request INSERT, DELETE or UPDATE
  141. *
  142. * @param resource $resultset Curseur de la requete voulue
  143. * @return int Number of lines
  144. * @see num_rows()
  145. */
  146. public function affected_rows($resultset)
  147. {
  148. // phpcs:enable
  149. return $this->db->affected_rows($resultset);
  150. }
  151. /**
  152. * Return description of last error
  153. *
  154. * @return string Error text
  155. */
  156. public function error()
  157. {
  158. return $this->db->error();
  159. }
  160. /**
  161. * List tables into a database
  162. *
  163. * @param string $database Name of database
  164. * @param string $table Nmae of table filter ('xxx%')
  165. * @return array List of tables in an array
  166. */
  167. public function DDLListTables($database, $table = '')
  168. {
  169. return $this->db->DDLListTables($database, $table);
  170. }
  171. /**
  172. * Return last request executed with query()
  173. *
  174. * @return string Last query
  175. */
  176. public function lastquery()
  177. {
  178. return $this->db->lastquery();
  179. }
  180. /**
  181. * Define sort criteria of request
  182. *
  183. * @param string $sortfield List of sort fields
  184. * @param string $sortorder Sort order
  185. * @return string String to provide syntax of a sort sql string
  186. */
  187. public function order($sortfield = null, $sortorder = null)
  188. {
  189. return $this->db->order($sortfield, $sortorder);
  190. }
  191. /**
  192. * Decrypt sensitive data in database
  193. *
  194. * @param string $value Value to decrypt
  195. * @return string Decrypted value if used
  196. */
  197. public function decrypt($value)
  198. {
  199. return $this->db->decrypt($value);
  200. }
  201. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  202. /**
  203. * Return datas as an array
  204. *
  205. * @param resource $resultset Resultset of request
  206. * @return array Array
  207. */
  208. public function fetch_array($resultset)
  209. {
  210. // phpcs:enable
  211. return $this->db->fetch_array($resultset);
  212. }
  213. /**
  214. * Return last error label
  215. *
  216. * @return string lasterror
  217. */
  218. public function lasterror()
  219. {
  220. return $this->db->lasterror();
  221. }
  222. /**
  223. * Escape a string to insert data
  224. *
  225. * @param string $stringtoencode String to escape
  226. * @return string String escaped
  227. */
  228. public function escape($stringtoencode)
  229. {
  230. return $this->db->escape($stringtoencode);
  231. }
  232. /**
  233. * Escape a string to insert data
  234. *
  235. * @param string $stringtoencode String to escape
  236. * @return string String escaped
  237. * @deprecated
  238. */
  239. public function escapeunderscore($stringtoencode)
  240. {
  241. return $this->db->escapeunderscore($stringtoencode);
  242. }
  243. /**
  244. * Escape a string to insert data into a like
  245. *
  246. * @param string $stringtoencode String to escape
  247. * @return string String escaped
  248. */
  249. public function escapeforlike($stringtoencode)
  250. {
  251. return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode);
  252. }
  253. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  254. /**
  255. * Get last ID after an insert INSERT
  256. *
  257. * @param string $tab Table name concerned by insert. Ne sert pas sous MySql mais requis pour compatibilite avec Postgresql
  258. * @param string $fieldid Field name
  259. * @return int Id of row
  260. */
  261. public function last_insert_id($tab, $fieldid = 'rowid')
  262. {
  263. // phpcs:enable
  264. return $this->db->last_insert_id($tab, $fieldid);
  265. }
  266. /**
  267. * Return full path of restore program
  268. *
  269. * @return string Full path of restore program
  270. */
  271. public function getPathOfRestore()
  272. {
  273. return $this->db->getPathOfRestore();
  274. }
  275. /**
  276. * Cancel a transaction and go back to initial data values
  277. *
  278. * @param string $log Add more log to default log line
  279. * @return resource|int 1 if cancelation is ok or transaction not open, 0 if error
  280. */
  281. public function rollback($log = '')
  282. {
  283. return $this->db->rollback($log);
  284. }
  285. /**
  286. * Execute a SQL request and return the resultset
  287. *
  288. * @param string $query SQL query string
  289. * @param int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
  290. * 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.
  291. * @param string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
  292. * @param int $result_mode Result mode
  293. * @return resource Resultset of answer
  294. */
  295. public function query($query, $usesavepoint = 0, $type = 'auto', $result_mode = 0)
  296. {
  297. $this->startTracing();
  298. $resql = $this->db->query($query, $usesavepoint, $type, $result_mode);
  299. $this->endTracing($query, $resql);
  300. return $resql;
  301. }
  302. /**
  303. * Start query tracing
  304. *
  305. * @return void
  306. */
  307. protected function startTracing()
  308. {
  309. $this->startTime = microtime(true);
  310. $this->startMemory = memory_get_usage(true);
  311. }
  312. /**
  313. * End query tracing
  314. *
  315. * @param string $sql query string
  316. * @param string $resql query result
  317. * @return void
  318. */
  319. protected function endTracing($sql, $resql)
  320. {
  321. $endTime = microtime(true);
  322. $duration = $endTime - $this->startTime;
  323. $endMemory = memory_get_usage(true);
  324. $memoryDelta = $endMemory - $this->startMemory;
  325. $this->queries[] = array(
  326. 'sql' => $sql,
  327. 'duration' => $duration,
  328. 'memory_usage' => $memoryDelta,
  329. 'is_success' => $resql ? true : false,
  330. 'error_code' => $resql ? null : $this->db->lasterrno(),
  331. 'error_message' => $resql ? null : $this->db->lasterror()
  332. );
  333. }
  334. /**
  335. * Connexion to server
  336. *
  337. * @param string $host database server host
  338. * @param string $login login
  339. * @param string $passwd password
  340. * @param string $name name of database (not used for mysql, used for pgsql)
  341. * @param int $port Port of database server
  342. * @return resource Database access handler
  343. * @see close()
  344. */
  345. public function connect($host, $login, $passwd, $name, $port = 0)
  346. {
  347. return $this->db->connect($host, $login, $passwd, $name, $port);
  348. }
  349. /**
  350. * Define limits and offset of request
  351. *
  352. * @param int $limit Maximum number of lines returned (-1=conf->liste_limit, 0=no limit)
  353. * @param int $offset Numero of line from where starting fetch
  354. * @return string String with SQL syntax to add a limit and offset
  355. */
  356. public function plimit($limit = 0, $offset = 0)
  357. {
  358. return $this->db->plimit($limit, $offset);
  359. }
  360. /**
  361. * Return value of server parameters
  362. *
  363. * @param string $filter Filter list on a particular value
  364. * @return array Array of key-values (key=>value)
  365. */
  366. public function getServerParametersValues($filter = '')
  367. {
  368. return $this->db->getServerParametersValues($filter);
  369. }
  370. /**
  371. * Return value of server status
  372. *
  373. * @param string $filter Filter list on a particular value
  374. * @return array Array of key-values (key=>value)
  375. */
  376. public function getServerStatusValues($filter = '')
  377. {
  378. return $this->db->getServerStatusValues($filter);
  379. }
  380. /**
  381. * Return collation used in database
  382. *
  383. * @return string Collation value
  384. */
  385. public function getDefaultCollationDatabase()
  386. {
  387. return $this->db->getDefaultCollationDatabase();
  388. }
  389. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  390. /**
  391. * Return number of lines for result of a SELECT
  392. *
  393. * @param resource $resultset Resulset of requests
  394. * @return int Nb of lines
  395. * @see affected_rows()
  396. */
  397. public function num_rows($resultset)
  398. {
  399. // phpcs:enable
  400. return $this->db->num_rows($resultset);
  401. }
  402. /**
  403. * Return full path of dump program
  404. *
  405. * @return string Full path of dump program
  406. */
  407. public function getPathOfDump()
  408. {
  409. return $this->db->getPathOfDump();
  410. }
  411. /**
  412. * Return version of database client driver
  413. *
  414. * @return string Version string
  415. */
  416. public function getDriverInfo()
  417. {
  418. return $this->db->getDriverInfo();
  419. }
  420. /**
  421. * Return generic error code of last operation.
  422. *
  423. * @return string Error code (Exemples: DB_ERROR_TABLE_ALREADY_EXISTS, DB_ERROR_RECORD_ALREADY_EXISTS...)
  424. */
  425. public function errno()
  426. {
  427. return $this->db->errno();
  428. }
  429. /**
  430. * Create a table into database
  431. *
  432. * @param string $table Name of table
  433. * @param array $fields Tableau associatif [nom champ][tableau des descriptions]
  434. * @param string $primary_key Nom du champ qui sera la clef primaire
  435. * @param string $type Type de la table
  436. * @param array $unique_keys Tableau associatifs Nom de champs qui seront clef unique => valeur
  437. * @param array $fulltext_keys Tableau des Nom de champs qui seront indexes en fulltext
  438. * @param array $keys Tableau des champs cles noms => valeur
  439. * @return int <0 if KO, >=0 if OK
  440. */
  441. public function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null)
  442. {
  443. return $this->db->DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys, $fulltext_keys, $keys);
  444. }
  445. /**
  446. * Drop a table into database
  447. *
  448. * @param string $table Name of table
  449. * @return int <0 if KO, >=0 if OK
  450. */
  451. public function DDLDropTable($table)
  452. {
  453. return $this->db->DDLDropTable($table);
  454. }
  455. /**
  456. * Return list of available charset that can be used to store data in database
  457. *
  458. * @return array List of Charset
  459. */
  460. public function getListOfCharacterSet()
  461. {
  462. return $this->db->getListOfCharacterSet();
  463. }
  464. /**
  465. * Create a new field into table
  466. *
  467. * @param string $table Name of table
  468. * @param string $field_name Name of field to add
  469. * @param string $field_desc Tableau associatif de description du champ a inserer[nom du parametre][valeur du parametre]
  470. * @param string $field_position Optionnel ex.: "after champtruc"
  471. * @return int <0 if KO, >0 if OK
  472. */
  473. public function DDLAddField($table, $field_name, $field_desc, $field_position = "")
  474. {
  475. return $this->db->DDLAddField($table, $field_name, $field_desc, $field_position);
  476. }
  477. /**
  478. * Drop a field from table
  479. *
  480. * @param string $table Name of table
  481. * @param string $field_name Name of field to drop
  482. * @return int <0 if KO, >0 if OK
  483. */
  484. public function DDLDropField($table, $field_name)
  485. {
  486. return $this->db->DDLDropField($table, $field_name);
  487. }
  488. /**
  489. * Update format of a field into a table
  490. *
  491. * @param string $table Name of table
  492. * @param string $field_name Name of field to modify
  493. * @param string $field_desc Array with description of field format
  494. * @return int <0 if KO, >0 if OK
  495. */
  496. public function DDLUpdateField($table, $field_name, $field_desc)
  497. {
  498. return $this->db->DDLUpdateField($table, $field_name, $field_desc);
  499. }
  500. /**
  501. * Return list of available collation that can be used for database
  502. *
  503. * @return array List of Collation
  504. */
  505. public function getListOfCollation()
  506. {
  507. return $this->db->getListOfCollation();
  508. }
  509. /**
  510. * Return a pointer of line with description of a table or field
  511. *
  512. * @param string $table Name of table
  513. * @param string $field Optionnel : Name of field if we want description of field
  514. * @return resource Resource
  515. */
  516. public function DDLDescTable($table, $field = "")
  517. {
  518. return $this->db->DDLDescTable($table, $field);
  519. }
  520. /**
  521. * Return version of database server
  522. *
  523. * @return string Version string
  524. */
  525. public function getVersion()
  526. {
  527. return $this->db->getVersion();
  528. }
  529. /**
  530. * Return charset used to store data in database
  531. *
  532. * @return string Charset
  533. */
  534. public function getDefaultCharacterSetDatabase()
  535. {
  536. return $this->db->getDefaultCharacterSetDatabase();
  537. }
  538. /**
  539. * Create a user and privileges to connect to database (even if database does not exists yet)
  540. *
  541. * @param string $dolibarr_main_db_host Ip serveur
  542. * @param string $dolibarr_main_db_user Nom user a creer
  543. * @param string $dolibarr_main_db_pass Mot de passe user a creer
  544. * @param string $dolibarr_main_db_name Database name where user must be granted
  545. * @return int <0 if KO, >=0 if OK
  546. */
  547. public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
  548. {
  549. return $this->db->DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name);
  550. }
  551. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  552. /**
  553. * Convert (by PHP) a PHP server TZ string date into a Timestamps date (GMT if gm=true)
  554. * 19700101020000 -> 3600 with TZ+1 and gmt=0
  555. * 19700101020000 -> 7200 whaterver is TZ if gmt=1
  556. *
  557. * @param string $string Date in a string (YYYYMMDDHHMMSS, YYYYMMDD, YYYY-MM-DD HH:MM:SS)
  558. * @param bool $gm 1=Input informations are GMT values, otherwise local to server TZ
  559. * @return int|string Date TMS or ''
  560. */
  561. public function jdate($string, $gm = false)
  562. {
  563. // phpcs:enable
  564. return $this->db->jdate($string, $gm);
  565. }
  566. /**
  567. * Encrypt sensitive data in database
  568. * Warning: This function includes the escape and add the SQL simple quotes on strings.
  569. *
  570. * @param string $fieldorvalue Field name or value to encrypt
  571. * @param int $withQuotes Return string including the SQL simple quotes. This param must always be 1 (Value 0 is bugged and deprecated).
  572. * @return string XXX(field) or XXX('value') or field or 'value'
  573. */
  574. public function encrypt($fieldorvalue, $withQuotes = 1)
  575. {
  576. return $this->db->encrypt($fieldorvalue, $withQuotes);
  577. }
  578. /**
  579. * Validate a database transaction
  580. *
  581. * @param string $log Add more log to default log line
  582. * @return int 1 if validation is OK or transaction level no started, 0 if ERROR
  583. */
  584. public function commit($log = '')
  585. {
  586. return $this->db->commit($log);
  587. }
  588. /**
  589. * List information of columns into a table.
  590. *
  591. * @param string $table Name of table
  592. * @return array Array with inforation on table
  593. */
  594. public function DDLInfoTable($table)
  595. {
  596. return $this->db->DDLInfoTable($table);
  597. }
  598. /**
  599. * Free last resultset used.
  600. *
  601. * @param resource $resultset Fre cursor
  602. * @return void
  603. */
  604. public function free($resultset = null)
  605. {
  606. return $this->db->free($resultset);
  607. }
  608. /**
  609. * Close database connexion
  610. *
  611. * @return boolean True if disconnect successfull, false otherwise
  612. * @see connect()
  613. */
  614. public function close()
  615. {
  616. return $this->db->close();
  617. }
  618. /**
  619. * Return last query in error
  620. *
  621. * @return string lastqueryerror
  622. */
  623. public function lastqueryerror()
  624. {
  625. return $this->db->lastqueryerror();
  626. }
  627. /**
  628. * Return connexion ID
  629. *
  630. * @return string Id connexion
  631. */
  632. public function DDLGetConnectId()
  633. {
  634. return $this->db->DDLGetConnectId();
  635. }
  636. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  637. /**
  638. * Returns the current line (as an object) for the resultset cursor
  639. *
  640. * @param resource|Connection $resultset Handler of the desired SQL request
  641. * @return Object Object result line or false if KO or end of cursor
  642. */
  643. public function fetch_object($resultset)
  644. {
  645. // phpcs:enable
  646. return $this->db->fetch_object($resultset);
  647. }
  648. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  649. /**
  650. * Select a database
  651. *
  652. * @param string $database Name of database
  653. * @return boolean true if OK, false if KO
  654. */
  655. public function select_db($database)
  656. {
  657. // phpcs:enable
  658. return $this->db->select_db($database);
  659. }
  660. }