Alternc  3.2
Alternc logiel libre pour l'hébergement
 All Data Structures Namespaces Files Functions Variables Pages
db_mysql.php
Go to the documentation of this file.
1 <?php
2 
3 /**
4  * Session Management for PHP3
5  *
6  * Copyright (c) 1998-2000 NetUSE AG
7  * Boris Erdmann, Kristian Koehntopp
8  *
9  * $Id: db_mysql.php,v 1.3 2005/03/05 16:27:30 said Exp $
10  *
11  */
12 
13 class DB_Sql {
14 
15  /* public: connection parameters */
16  var $Host = "";
17  var $Database = "";
18  var $User = "";
19  var $Password = "";
20 
21  /* public: configuration parameters */
22  var $Auto_Free = 0; ## Set to 1 for automatic mysql_free_result()
23  var $Debug = 0; ## Set to 1 for debugging messages.
24  var $Halt_On_Error = "no"; ## "yes" (halt with message), "no" (ignore errors quietly), "report" (ignore errror, but spit a warning)
25  var $Seq_Table = "db_sequence";
26 
27  /* public: result array and current row number */
28  var $Record = array();
29  var $Row;
30 
31  /* public: current error number and error text */
32  var $Errno = 0;
33  var $Error = "";
34 
35  /* public: this is an api revision, not a CVS revision. */
36  var $type = "mysql";
37  var $revision = "1.2";
38 
39  /* private: link and query handles */
40  var $Link_ID = 0;
41  var $Query_ID = 0;
42  var $Query_String = "";
43 
44 
45 
46  /**
47  * Constructor
48  */
49  function DB_Sql($query = "") {
50  $this->query($query);
51  }
52 
53  /**
54  * @return the class variable Link_ID
55  */
56  function link_id() {
57  return $this->Link_ID;
58  }
59 
60  /**
61  * @return the class variable Query_ID
62  */
63  function query_id() {
64  return $this->Query_ID;
65  }
66 
67  /**
68  * function for MySQL database connection management
69  *
70  * This function manages the connection to the MySQL database.
71  *
72  * @param $Database name of the database
73  * @param $Host DNS of the MySQL hosting server
74  * @param $User the user's name
75  * @param $Password the user's password
76  *
77  * @return the class variable $Link_ID
78  */
79  function connect($Database = "", $Host = "", $User = "", $Password = "") {
80  /* Handle defaults */
81  if ("" == $Database)
83  if ("" == $Host)
85  if ("" == $User)
87  if ("" == $Password)
89 
90  /* establish connection, select database */
91  if ( 0 == $this->Link_ID ) {
92 
93  $this->Link_ID=mysql_pconnect($Host, $User, $Password);
94  if (!$this->Link_ID) {
95  $this->halt("pconnect($Host, $User, \$Password) failed.");
96  return 0;
97  }
98 
99  if (!@mysql_select_db($Database,$this->Link_ID)) {
100  $this->halt("cannot use database ".$this->Database);
101  return 0;
102  }
103  }
104 
105  //persistent connection don't conserve database selection
106  //if needed do a correct database selection
107  $db_connected = @mysql_fetch_array(@mysql_query("SELECT DATABASE();",$this->Link_ID));
108  if ($db_connected[0] != $this->Database)
109  mysql_select_db($Database,$this->Link_ID);
110 
111  return $this->Link_ID;
112  }
113 
114  /**
115  * Discard the query result
116  *
117  * This function discards the last query result.
118  */
119  function free() {
120  @mysql_free_result($this->Query_ID);
121  $this->Query_ID = 0;
122  }
123 
124  /**
125  * Perform a query
126  *
127  * This function performs the MySQL query described in the string parameter
128  *
129  * @param a string describing the MySQL query
130  * @return the $Query_ID class variable (null if fails)
131  */
132  function query($Query_String) {
133  global $debug_alternc;
134 
135  /* No empty queries, please, since PHP4 chokes on them. */
136  if ($Query_String == "")
137  /* The empty query string is passed on from the constructor,
138  * when calling the class without a query, e.g. in situations
139  * like these: '$db = new DB_Sql_Subclass;'
140  */
141  return 0;
142 
143  if (!$this->connect()) {
144  return 0; /* we already complained in connect() about that. */
145  };
146 
147  # New query, discard previous result.
148  if ($this->Query_ID) {
149  $this->free();
150  $this->Query_String = $Query_String;
151  }
152 
153  if ($this->Debug)
154  printf("Debug: query = %s<br />\n", $Query_String);
155 
156  $debug_chrono_start = microtime(true);
157  $this->Query_ID = @mysql_query($Query_String,$this->Link_ID);
158  $debug_chrono_start = (microtime(true) - $debug_chrono_start)*1000;
159  $this->Row = 0;
160  $this->Errno = mysql_errno();
161  $this->Error = mysql_error();
162  if( 0 != $this->Errno ){
163  if( defined("THROW_EXCEPTIONS") && THROW_EXCEPTIONS ){
164  throw new \Exception("Mysql query failed : $this->Error");
165  }
166  $this->halt("SQL Error: ".$Query_String);
167  return FALSE;
168  }
169  if (!$this->Query_ID) {
170  $this->halt("Invalid SQL: ".$Query_String);
171  }
172 
173  if (isset($debug_alternc)) {
174  $debug_alternc->add("SQL Query : (".substr($debug_chrono_start,0,5)." ms)\t $Query_String");
175  $debug_alternc->nb_sql_query++;
176  $debug_alternc->tps_sql_query += $debug_chrono_start;
177  }
178 
179  # Will return nada if it fails. That's fine.
180  return $this->Query_ID;
181  }
182 
183  /**
184  * walk result set
185  *
186  * This function tests if a new record is available in the current
187  * query result.
188  *
189  * @return TRUE if a new record is available
190  */
191  function next_record() {
192  if (!$this->Query_ID) {
193  $this->halt("next_record called with no query pending.");
194  return 0;
195  }
196 
197  $this->Record = @mysql_fetch_array($this->Query_ID);
198  $this->Row += 1;
199  $this->Errno = mysql_errno();
200  $this->Error = mysql_error();
201 
202  $stat = is_array($this->Record);
203  if (!$stat && $this->Auto_Free) {
204  $this->free();
205  }
206  return $stat;
207  }
208 
209  /**
210  *
211  * public: position in result set
212  */
213 
214  function seek($pos = 0) {
215  $status = @mysql_data_seek($this->Query_ID, $pos);
216  if ($status)
217  $this->Row = $pos;
218  else {
219  $this->halt("seek($pos) failed: result has ".$this->num_rows()." rows");
220 
221  /* half assed attempt to save the day,
222  * but do not consider this documented or even
223  * desireable behaviour.
224  */
225  @mysql_data_seek($this->Query_ID, $this->num_rows());
226  $this->Row = $this->num_rows;
227  return 0;
228  }
229 
230  return 1;
231  }
232 
233  /* public: table locking */
234  function lock($table, $mode="write") {
235  $this->connect();
236 
237  $query="lock tables ";
238  if (is_array($table)) {
239  while (list($key,$value)=each($table)) {
240  if ($key=="read" && $key!=0) {
241  $query.="$value read, ";
242  } else {
243  $query.="$value $mode, ";
244  }
245  }
246  $query=substr($query,0,-2);
247  } else {
248  $query.="$table $mode";
249  }
250  $res = @mysql_query($query, $this->Link_ID);
251  if (!$res) {
252  $this->halt("lock($table, $mode) failed.");
253  return 0;
254  }
255  return $res;
256  }
257 
258  function unlock() {
259  $this->connect();
260 
261  $res = @mysql_query("unlock tables", $this->Link_ID);
262  if (!$res) {
263  $this->halt("unlock() failed.");
264  return 0;
265  }
266  return $res;
267  }
268 
269 
270  /* public: evaluate the result (size, width) */
271  function affected_rows() {
272  return @mysql_affected_rows($this->Link_ID);
273  }
274 
275  function num_rows() {
276  return @mysql_num_rows($this->Query_ID);
277  }
278 
279  function num_fields() {
280  return @mysql_num_fields($this->Query_ID);
281  }
282 
283  /* public: shorthand notation */
284  function nf() {
285  return $this->num_rows();
286  }
287 
288  function np() {
289  print $this->num_rows();
290  }
291 
292  function f($Name) {
293  return $this->Record[$Name];
294  }
295 
296  function p($Name) {
297  print $this->Record[$Name];
298  }
299 
300  function lastid() {
301  return @mysql_insert_id($this->Link_ID);
302  }
303 
304  /* public: sequence numbers */
305  function nextid($seq_name) {
306  $this->connect();
307 
308  if ($this->lock($this->Seq_Table)) {
309  /* get sequence number (locked) and increment */
310  $q = sprintf("select nextid from %s where seq_name = '%s'",
311  $this->Seq_Table,
312  $seq_name);
313  $id = @mysql_query($q, $this->Link_ID);
314  $res = @mysql_fetch_array($id);
315 
316  /* No current value, make one */
317  if (!is_array($res)) {
318  $currentid = 0;
319  $q = sprintf("insert into %s values('%s', %s)",
320  $this->Seq_Table,
321  $seq_name,
322  $currentid);
323  $id = @mysql_query($q, $this->Link_ID);
324  } else {
325  $currentid = $res["nextid"];
326  }
327  $nextid = $currentid + 1;
328  $q = sprintf("update %s set nextid = '%s' where seq_name = '%s'",
329  $this->Seq_Table,
330  $nextid,
331  $seq_name);
332  $id = @mysql_query($q, $this->Link_ID);
333  $this->unlock();
334  } else {
335  $this->halt("cannot lock ".$this->Seq_Table." - has it been created?");
336  return 0;
337  }
338  return $nextid;
339  }
340 
341  /* public: return table metadata */
342  function metadata($table='',$full=false) {
343  $count = 0;
344  $id = 0;
345  $res = array();
346 
347  /*
348  * Due to compatibility problems with Table we changed the behavior
349  * of metadata();
350  * depending on $full, metadata returns the following values:
351  *
352  * - full is false (default):
353  * $result[]:
354  * [0]["table"] table name
355  * [0]["name"] field name
356  * [0]["type"] field type
357  * [0]["len"] field length
358  * [0]["flags"] field flags
359  *
360  * - full is true
361  * $result[]:
362  * ["num_fields"] number of metadata records
363  * [0]["table"] table name
364  * [0]["name"] field name
365  * [0]["type"] field type
366  * [0]["len"] field length
367  * [0]["flags"] field flags
368  * ["meta"][field name] index of field named "field name"
369  * The last one is used, if you have a field name, but no index.
370  * Test: if (isset($result['meta']['myfield'])) { ...
371  */
372 
373  // if no $table specified, assume that we are working with a query
374  // result
375  if ($table) {
376  $this->connect();
377  $id = @mysql_list_fields($this->Database, $table);
378  if (!$id)
379  $this->halt("Metadata query failed.");
380  } else {
381  $id = $this->Query_ID;
382  if (!$id)
383  $this->halt("No query specified.");
384  }
385 
386  $count = @mysql_num_fields($id);
387 
388  // made this IF due to performance (one if is faster than $count if's)
389  if (!$full) {
390  for ($i=0; $i<$count; $i++) {
391  $res[$i]["table"] = @mysql_field_table ($id, $i);
392  $res[$i]["name"] = @mysql_field_name ($id, $i);
393  $res[$i]["type"] = @mysql_field_type ($id, $i);
394  $res[$i]["len"] = @mysql_field_len ($id, $i);
395  $res[$i]["flags"] = @mysql_field_flags ($id, $i);
396  }
397  } else { // full
398  $res["num_fields"]= $count;
399 
400  for ($i=0; $i<$count; $i++) {
401  $res[$i]["table"] = @mysql_field_table ($id, $i);
402  $res[$i]["name"] = @mysql_field_name ($id, $i);
403  $res[$i]["type"] = @mysql_field_type ($id, $i);
404  $res[$i]["len"] = @mysql_field_len ($id, $i);
405  $res[$i]["flags"] = @mysql_field_flags ($id, $i);
406  $res["meta"][$res[$i]["name"]] = $i;
407  }
408  }
409 
410  // free the result only if we were called on a table
411  if ($table) @mysql_free_result($id);
412  return $res;
413  }
414 
415 /********************************************************************************************************/
416 // AJOUT PERSO : TEST
417 
418 /* public: return table metadata
419  function retourneNameField($this->Query_ID,$full=false) {
420  $count = 0;
421  $id = 0;
422  $res = array();
423 
424 
425  $count = @mysql_num_fields($this->Query_ID);
426 
427  // made this IF due to performance (one if is faster than $count if's)
428  if (!$full) {
429  for ($i=0; $i<$count; $i++) {
430  $res[$i]["table"] = @mysql_field_table ($id, $i);
431  $res[$i]["name"] = @mysql_field_name ($id, $i);
432  $res[$i]["type"] = @mysql_field_type ($id, $i);
433  $res[$i]["len"] = @mysql_field_len ($id, $i);
434  $res[$i]["flags"] = @mysql_field_flags ($id, $i);
435  }
436  } else { // full
437  $res["num_fields"]= $count;
438 
439  for ($i=0; $i<$count; $i++) {
440  $res[$i]["table"] = @mysql_field_table ($id, $i);
441  $res[$i]["name"] = @mysql_field_name ($id, $i);
442  $res[$i]["type"] = @mysql_field_type ($id, $i);
443  $res[$i]["len"] = @mysql_field_len ($id, $i);
444  $res[$i]["flags"] = @mysql_field_flags ($id, $i);
445  $res["meta"][$res[$i]["name"]] = $i;
446  }
447  }
448 
449  // free the result only if we were called on a table
450  if ($table) @mysql_free_result($id);
451  return $res;
452  }*/
453 
454 /********************************************************************************************************/
455  /* private: error handling */
456  function halt($msg) {
457  $this->Error = @mysql_error($this->Link_ID);
458  $this->Errno = @mysql_errno($this->Link_ID);
459  if ($this->Halt_On_Error == "no")
460  return;
461 
462  $this->haltmsg($msg);
463 
464  if ($this->Halt_On_Error != "report")
465  die("Session halted.");
466  }
467 
468  function haltmsg($msg) {
469  printf("</td></tr></table><b>Database error:</b> %s<br />\n", $msg);
470  printf("<b>MySQL Error</b>: %s (%s)<br />\n",
471  $this->Errno,
472  $this->Error);
473  }
474 
475  function table_names() {
476  $this->query("SHOW TABLES");
477  $i=0;
478  while ($info=mysql_fetch_row($this->Query_ID))
479  {
480  $return[$i]["table_name"]= $info[0];
481  $return[$i]["tablespace_name"]=$this->Database;
482  $return[$i]["database"]=$this->Database;
483  $i++;
484  }
485  return $return;
486  }
487 }
488 ?>