Database.c.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. <?php
  2. define('ERR_DB_RES','0');
  3. define('ERR_DB_ERR','1');
  4. require_once 'OExceptions.php';
  5. /**
  6. * Wrapper per le funzioni di libreria php mysqli
  7. *
  8. * @author gine
  9. * @original author: Micah Carrick
  10. * @version: 1.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 == ERR_DB_RES)
  103. throw new DbResException($err['text'],$err['code']);
  104. elseif($e_type == ERR_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. * @param [String cMsg] : customMessage
  148. * @throws DbResException
  149. * @return mixed
  150. */
  151. function selectOneRow($sql,$cMsg=NULL) {
  152. $msg=$sMsg=NULL;
  153. $r = self::select($sql);
  154. if ($this->row_count > 1)
  155. $sMsg=_(" more than one result.");
  156. elseif ($this->row_count < 1)
  157. $sMsg=_(" query returned less than one result.");
  158. if($sMsg!=NULL && $cMsg==NULL)
  159. $msg=_("Your query returned").$sMsg;
  160. elseif ($sMsg!=NULL && $cMsg != NULL)
  161. $msg=$cMsg;
  162. if($msg!=NULL)
  163. $this->callException($msg,ERR_DB_RES);
  164. return mysqli_fetch_row($r);
  165. }
  166. /**
  167. * Esegue una SELECT il cui risultato deve essere 1 sola cella.
  168. * Ritorna la cella. Solleva un eccezzione DbResException altrimenti.
  169. *
  170. * @param SqlQuery $sql
  171. * @throws DbResException
  172. * @return mixed
  173. */
  174. function selectFirstRowFirstCell($sql) {
  175. $r = $this->select($sql);
  176. if ($this->row_count > 1 or $this->row_count < 1)
  177. $this->callException(_("Your query returned more or less that one result."),ERR_DB_RES);
  178. $ret = mysqli_fetch_row($r);
  179. if ($this->auto_slashes)
  180. return stripslashes($ret[0]);
  181. else
  182. return $ret[0];
  183. }
  184. /**
  185. * Esegue una select il cui risultato deve essere un array composto da
  186. * una sola cella per riga. Solleva un eccezzione DbResException altrimenti.
  187. *
  188. * @param SqlQuery $sql
  189. * @throws DbResException
  190. * @return array
  191. */
  192. function selectArrayOneElem($sql) {
  193. $arr=array();
  194. $r= $this->select($sql);
  195. for ($i=0; $i<$this->row_count;$i++){
  196. $row=mysqli_fetch_row($r);
  197. if (isset($row[1]))
  198. $this->callException(_("Your query return more than 1 element for row."),ERR_DB_RES);
  199. $arr[$i]=$row[0];
  200. }
  201. return $arr;
  202. }
  203. /**
  204. * Esegue una select il cui risultato deve essere un array composto da
  205. * una $n celle per riga. Solleva un eccezzione DbResException altrimenti.
  206. * Se $n non è specificato non viene effettuato nessun controllo sul
  207. * numero di elementi per riga.
  208. *
  209. * @param SqlQuery $sql
  210. * @throws DbResException
  211. * @return array
  212. */
  213. function selectArrayNElem($sql,$n=NULL) {
  214. $arr=array();
  215. $r= $this->select($sql);
  216. for ($i=0; $i<$this->row_count;$i++){
  217. $row=mysqli_fetch_row($r);
  218. if($n!=NULL){
  219. if (isset($row[$n]))
  220. $this->callException(sprintf(_("Your query return more than %s element for row."),$n),ERR_RES);
  221. }
  222. $arr[$i]=$row;
  223. }
  224. return $arr;
  225. }
  226. /**
  227. * Torna il numero di righe affette dalla query.
  228. * Da utilizzare con INSERT DELETE e UPDATE
  229. *
  230. * @param SqlQuery $sql
  231. * @throws DbResException
  232. * @return int
  233. */
  234. function execQuery($sql) {
  235. $this->last_query = $sql;
  236. $r = mysqli_query($this->db_link,$sql);
  237. if (!$r)
  238. $this->callException(_("Query error"),ERR_DB_ERR);
  239. return $this->row_count = mysqli_affected_rows($this->db_link);
  240. }
  241. /**
  242. * Eseque una SqlQuery il cui risultato deve aver avuto effetto su 1 sola riga.
  243. * Ritorna TRUE o solleva una eccezione altrimenti.
  244. *
  245. * @param SqlQuery $sql
  246. * @param [String cMsg] : customMessage
  247. * @throws DbResException
  248. * @return boolean
  249. */
  250. function execQueryOneRow($sql,$cMsg=NULL) {
  251. $msg=$sMsg=NULL;
  252. self::execQuery($sql);
  253. if ($this->row_count == 0)
  254. $sMsg=_("No row affected");
  255. elseif($this->row_count > 1)
  256. $sMsg=_("More than 1 row are affected");
  257. if($sMsg!=NULL && $cMsg==NULL)
  258. $msg=$sMsg;
  259. elseif ($sMsg!=NULL && $cMsg != NULL)
  260. $msg=$cMsg;
  261. if($msg!=NULL)
  262. $this->callException($msg,ERR_DB_RES);
  263. }
  264. /**
  265. * Eseque una execQueryOneRow e ritorna l'ID della riga inserita.
  266. * Ottenuto tramite AUTOINCREMENT; comoda per le INSERT.
  267. *
  268. * @param SqlQuery $sql
  269. */
  270. function execQueryRetId($sql) {
  271. $this->execQueryOneRow($sql);
  272. return mysqli_insert_id($this->db_link);
  273. }
  274. /**
  275. * Esegue una SELECT con $sql per verificare la presenza di un "id", se non esiste torna FALSE.
  276. * Altrimenti torna l'ID cercato con la select.
  277. * Se ritornano più risultati solleva un DbResException.
  278. *
  279. * @param SelectSqlQuery $sql
  280. * @return mixed
  281. */
  282. function isThereAlready($sql){
  283. $id=FALSE;
  284. $res=self::select($sql);
  285. if($this->row_count == 1){
  286. $row=mysqli_fetch_row($res);
  287. $id=$row[0];
  288. } elseif($this->row_count > 1 ) {
  289. $this->callException(_("Are present more than 1 row"),ERR_DB_RES);
  290. }
  291. return $id;
  292. }
  293. function escapeString($string){
  294. return mysqli_real_escape_string($this->db_link,$string);
  295. }
  296. /**
  297. * Esegue un flush dei privilegi degli utenti mysql.
  298. * Serve per assicurare che le operazioni effettuate con altre funzioni,
  299. * come la creazione o la eliminazione di un utente, siano attive.
  300. */
  301. function flushPrivileges(){
  302. self::execQuery("FLUSH PRIVILEGES");
  303. }
  304. /**
  305. * Se $debug è TRUE stampa la query $sql altrimenti tramite reflection esegue il metodo $action sulla query.
  306. *
  307. * @param boolean $debug TRUE|FALSE
  308. * @param String $action Metodi della Classe Database
  309. * @param SqlQuery $sql
  310. */
  311. function sqlOrDebug($debug,$action,$sql){
  312. if (! $debug)
  313. self::$action($sql);
  314. else
  315. echo "DEBUG:OR: ".str_replace(array("\n","\r","\t","/\s\s+/"),"",$sql)."\n";
  316. }
  317. /**
  318. * Se $debug è FALSE esegue tramite reflection il metodo $action sulla query $sql, altrimenti stampa anche la query.
  319. *
  320. * @param boolean $debug TRUE|FALSE
  321. * @param String $action Metodi della Classe Database
  322. * @param SqlQuery $sql
  323. */
  324. function sqlAndDebug($debug,$action,$sql){
  325. if ($debug)
  326. echo "DEBUG:AND: ".str_replace(array("\n","\r","\t","/\s\s+/"),"",$sql)."\n";
  327. return self::$action($sql);
  328. }
  329. /**
  330. * Ritorna l'ultimo errore ottenuto durante le azioni precedenti sul database.
  331. */
  332. public function getLastError() {
  333. return $this->last_error;
  334. }
  335. /**
  336. * Ritorna l'ultima query effettuata
  337. */
  338. public function getLastQuery() {
  339. return $this->last_query;
  340. }
  341. }
  342. ?>