Database.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. <?php
  2. require_once 'OExceptions.php';
  3. define('E_DB_RES','0');
  4. define('E_DB_ERR','1');
  5. /**
  6. * Wrapper per le funzioni di libreria php mysqli
  7. *
  8. * @author gine
  9. * @original author: Micah Carrick
  10. * @version: 1.1
  11. * @licence: GPL 2
  12. *
  13. */
  14. class Database {
  15. /**
  16. * Ricordati di settarla a FALSE per tutti i programmi
  17. * in cui usi questa classe.
  18. */
  19. private $debug=FALSE;
  20. private static $m_pInstance = array();
  21. private $last_query; // last query executed.
  22. var $row_count; // last number of rows
  23. var $db_link; // current/last database link identifier
  24. private $auto_slashes; // the class will add/strip slashes when it can
  25. private $host, $user, $pw, $db, $port;
  26. /**
  27. * Costruttore della classe che si interfaccia con il dbms. Privata per via del Singleton.
  28. *
  29. * @param string $db
  30. */
  31. private function Database($db) {
  32. $dbConfPath=dirname(__FILE__).'/../config/';
  33. include($dbConfPath.'db.php');
  34. if ($db == "dns")
  35. include($dbConfPath.'smdns_db.php');
  36. elseif ($db == "db") {
  37. include($dbConfPath.'mysql_db.php');
  38. require_once dirname(__FILE__).'/../lib/terminal.php';
  39. $dbms_password=prompt_silent();
  40. } elseif ($db == "ot")
  41. include($dbConfPath.'ot_db.php');
  42. elseif($db == "std")
  43. include($dbConfPath.'config.php');
  44. $this->host = $dbms_server;
  45. $this->user = $dbms_user;
  46. $this->pw = $dbms_password;
  47. $this->db = $dbms_db;
  48. $this->port = $dbms_port;
  49. $this->auto_slashes = true;
  50. self::connect();
  51. }
  52. /**
  53. * Singleton multiplo del costruttore della classe Database. Ritorna un istanza della classe.
  54. * $db può essere: ot, dns, db, ftp. Default: ot
  55. *
  56. * @param string $db
  57. * @return Mysqli_link $m_pInstance
  58. */
  59. public static function getInstance($db='ot'){
  60. if (!isset(self::$m_pInstance[$db])){
  61. self::$m_pInstance[$db] = new Database($db);
  62. }
  63. return self::$m_pInstance[$db];
  64. }
  65. /**
  66. * Esegue la connect al dbms.
  67. * I parametri, se configurato il costruttore correttamente, sono opzionali. Ritorna un mysqli_link.
  68. *
  69. * Solleva un eccezione se ci sono problemi di connessione.
  70. *
  71. * @param url $host
  72. * @param string $user
  73. * @param string $pw
  74. * @param string $db
  75. * @param int $port
  76. * @throws DbErrException
  77. * @return Mysqli_link $db_link
  78. *
  79. */
  80. function connect($host='', $user='', $pw='', $db='', $port='') {
  81. if (!empty($host)) $this->host = $host;
  82. if (!empty($user)) $this->user = $user;
  83. if (!empty($pw)) $this->pw = $pw;
  84. if (!empty($pw)) $this->port = $port;
  85. $this->db_link = mysqli_init();
  86. mysqli_real_connect($this->db_link , $this->host, $this->user, $this->pw, $this->db, $this->port);
  87. if (!$this->db_link)
  88. $this->callException(_("Database connection problem."),E_DB_ERR);
  89. return $this->db_link;
  90. }
  91. private function setDebugErr($msg){
  92. $err['text']=$msg;
  93. $err['code']=0;
  94. if($this->debug){
  95. $err['text'].="\n".$this->last_query;
  96. $err['code']=mysqli_errno($this->db_link);
  97. }
  98. return $err;
  99. }
  100. private function callException($msg,$e_type){
  101. $err=$this->setDebugErr($msg);
  102. if($e_type == E_DB_RES)
  103. throw new DbResException($err['text'],$err['code']);
  104. elseif($e_type == E_DB_ERR)
  105. throw new DbErrException($err['text'],$err['code']);
  106. else {
  107. die(_("what shit?!"));
  108. exit;
  109. }
  110. }
  111. /**
  112. * Selezioziona il database ritorna TRUE se selezionato correttamente.
  113. * Solleva una Exception in caso di fallimento.
  114. *
  115. * @param string $db
  116. * @throws DbErrException
  117. * @return boolean
  118. */
  119. function selectDb($db='') {
  120. if (!empty($db)) $this->db = $db;
  121. if (!mysqli_select_db($this->db_link,$this->db))
  122. $this->callException(_("Database selection problem."),E_DB_ERR);
  123. return true;
  124. }
  125. /**
  126. * Esegue una SELECT espressa con una SqlQuery.
  127. * Utile quando non si conosce in numero di righe o colonne che potrebbero tornare.
  128. * Ritorna un oggetto mysqli_result. Solleva una eccezione sul fallimento.
  129. *
  130. * @param SqlQuery $sql
  131. * @throws DbErrException
  132. * @return mixed
  133. */
  134. function select($sql) {
  135. $this->last_query = $sql;
  136. $r = mysqli_query($this->db_link,$sql);
  137. if (!$r)
  138. $this->callException(_("Query select error."),E_DB_ERR);
  139. $this->row_count = mysqli_num_rows($r);
  140. return $r;
  141. }
  142. /**
  143. * Esegue una SELECT il cui risultato deve essere 1 sola riga.
  144. * Ritorna la riga. Solleva un eccezzione DbResException altrimenti.
  145. *
  146. * @param SqlQuery $sql
  147. * @throws DbResException
  148. * @return mixed
  149. */
  150. function selectOneRow($sql) {
  151. $oi=_("Your query returned ");
  152. $r = self::select($sql);
  153. if ($this->row_count > 1)
  154. $this->callException($oi._("more than one result."),ERR_DB_RES);
  155. elseif ($this->row_count < 1)
  156. $this->callException($oi._("less than one result."),ERR_DB_RES);
  157. return mysqli_fetch_row($r);
  158. }
  159. /**
  160. * Esegue una SELECT il cui risultato deve essere 1 sola cella.
  161. * Ritorna la cella. Solleva un eccezzione DbResException altrimenti.
  162. *
  163. * @param SqlQuery $sql
  164. * @throws DbResException
  165. * @return mixed
  166. */
  167. function selectFirstRowFirstCell($sql) {
  168. $r = $this->select($sql);
  169. if ($this->row_count > 1 or $this->row_count < 1)
  170. $this->callException(_("Your query returned more or less that one result."),ERR_DB_RES);
  171. $ret = mysqli_fetch_row($r);
  172. if ($this->auto_slashes)
  173. return stripslashes($ret[0]);
  174. else
  175. return $ret[0];
  176. }
  177. /**
  178. * Esegue una select il cui risultato deve essere un array composto da
  179. * una sola cella per riga. Solleva un eccezzione DbResException altrimenti.
  180. *
  181. * @param SqlQuery $sql
  182. * @throws DbResException
  183. * @return array
  184. */
  185. function selectArrayOneElem($sql) {
  186. $arr=array();
  187. $r= $this->select($sql);
  188. for ($i=0; $i<$this->row_count;$i++){
  189. $row=mysqli_fetch_row($r);
  190. if (isset($row[1]))
  191. $this->callException(_("Your query return more than 1 element for row."),ERR_DB_RES);
  192. $arr[$i]=$row[0];
  193. }
  194. return $arr;
  195. }
  196. /**
  197. * Esegue una select il cui risultato deve essere un array composto da
  198. * una $n celle per riga. Solleva un eccezzione DbResException altrimenti.
  199. * Se $n non è specificato non viene effettuato nessun controllo sul
  200. * numero di elementi per riga.
  201. *
  202. * @param SqlQuery $sql
  203. * @throws DbResException
  204. * @return array
  205. */
  206. function selectArrayNElem($sql,$n=NULL) {
  207. $arr=array();
  208. $r= $this->select($sql);
  209. for ($i=0; $i<$this->row_count;$i++){
  210. $row=mysqli_fetch_row($r);
  211. if($n!=NULL){
  212. if (isset($row[$n]))
  213. $this->callException(sprintf(_("Your query return more than %s element for row."),$n),ERR_RES);
  214. }
  215. $arr[$i]=$row;
  216. }
  217. return $arr;
  218. }
  219. /**
  220. * Torna il numero di righe affette dalla query.
  221. * Da utilizzare con INSERT DELETE e UPDATE
  222. *
  223. * @param SqlQuery $sql
  224. * @throws DbResException
  225. * @return int
  226. */
  227. function execQuery($sql) {
  228. $this->last_query = $sql;
  229. $r = mysqli_query($this->db_link,$sql);
  230. if (!$r)
  231. $this->callException(_("Query error."),E_DB_ERR);
  232. return $this->row_count = mysqli_affected_rows($this->db_link);
  233. }
  234. /**
  235. * Eseque una SqlQuery il cui risultato deve aver avuto effetto su 1 sola riga.
  236. * Ritorna TRUE o solleva una eccezione altrimenti.
  237. *
  238. * @param SqlQuery $sql
  239. * @throws DbResException
  240. * @return boolean
  241. */
  242. function execQueryOneRow($sql) {
  243. self::execQuery($sql);
  244. if ($this->row_count == 0)
  245. $this->callException(_("No row affected."),ERR_RES);
  246. elseif($this->row_count > 1)
  247. $this->callException(_("More than 1 row are affected."),ERR_DB_RES);
  248. }
  249. /**
  250. * Eseque una execQueryOneRow e ritorna l'ID della riga inserita.
  251. * Ottenuto tramite AUTOINCREMENT; comoda per le INSERT.
  252. *
  253. * @param SqlQuery $sql
  254. */
  255. function execQueryRetId($sql) {
  256. $this->execQueryOneRow($sql);
  257. return mysqli_insert_id($this->db_link);
  258. }
  259. /**
  260. * Esegue una SELECT con $sql per verificare la presenza di un "id", se non esiste torna FALSE.
  261. * Altrimenti torna l'ID cercato con la select.
  262. * Se ritornano più risultati solleva un DbResException.
  263. *
  264. * @param SelectSqlQuery $sql
  265. * @return mixed
  266. */
  267. function isThereAlready($sql){
  268. $id=FALSE;
  269. $res=self::select($sql);
  270. if($this->row_count == 1){
  271. $row=mysqli_fetch_row($res);
  272. $id=$row[0];
  273. } elseif($this->row_count > 1 ) {
  274. $this->callException(_("Are present more than 1 row."),ERR_DB_RES);
  275. }
  276. return $id;
  277. }
  278. function escapeString($string){
  279. return mysqli_real_escape_string($this->db_link,$string);
  280. }
  281. /**
  282. * Esegue un flush dei privilegi degli utenti mysql.
  283. * Serve per assicurare che le operazioni effettuate con altre funzioni,
  284. * come la creazione o la eliminazione di un utente, siano attive.
  285. */
  286. function flushPrivileges(){
  287. self::execQuery("FLUSH PRIVILEGES");
  288. }
  289. /**
  290. * Se $debug è TRUE stampa la query $sql altrimenti tramite reflection esegue il metodo $action sulla query.
  291. *
  292. * @param boolean $debug TRUE|FALSE
  293. * @param String $action Metodi della Classe Database
  294. * @param SqlQuery $sql
  295. */
  296. function sqlOrDebug($debug,$action,$sql){
  297. $debug=true;
  298. if (! $debug)
  299. return self::$action($sql);
  300. else
  301. echo "DEBUG:OR: ".str_replace(array("\n","\r","\t","/\s\s+/"),"",$sql)."\n";
  302. }
  303. /**
  304. * Se $debug è FALSE esegue tramite reflection il metodo $action sulla query $sql, altrimenti stampa anche la query.
  305. *
  306. * @param boolean $debug TRUE|FALSE
  307. * @param String $action Metodi della Classe Database
  308. * @param SqlQuery $sql
  309. */
  310. function sqlAndDebug($debug,$action,$sql){
  311. $debug=true;
  312. if ($debug)
  313. echo "DEBUG:AND: ".str_replace(array("\n","\r","\t","/\s\s+/"),"",$sql)."\n";
  314. return self::$action($sql);
  315. }
  316. /**
  317. * Ritorna l'ultimo errore ottenuto durante le azioni precedenti sul database.
  318. */
  319. public function getLastError() {
  320. return $this->last_error;
  321. }
  322. /**
  323. * Ritorna l'ultima query effettuata
  324. */
  325. public function getLastQuery() {
  326. return $this->last_query;
  327. }
  328. }
  329. ?>