root / nephthys_db.php

View | Annotate | Download (16.6 KB)

1
<?php
2
3
/***************************************************************************
4
 *
5
 * Nephthys - file sharing management
6
 * Copyright (c) by Andreas Unterkircher, unki@netshadow.at
7
 *
8
 *  This file is part of Nephthys.
9
 *
10
 *  Nephthys is free software: you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation, either version 3 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  Nephthys is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with Nephthys. If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 ***************************************************************************/
24
25
class NEPHTHYS_DB {
26
27
   private $db;
28
   private $cfg;
29
   private $is_connected;
30
   private $last_error;
31
   private $parent;
32
33
   /**
34
    * NEPHTHYS_DB class constructor
35
    *
36
    * This constructor initially connect to the database.
37
    */
38
   public function __construct()
39
   {
40
      global $nephthys;
41
      $this->parent =& $nephthys;
42
43
      $this->cfg = $this->parent->cfg;
44
45
      /* We are starting disconnected */
46
      $this->setConnStatus(false);
47
48
      /* Connect to MySQL Database */
49
      $this->db_connect();
50
51
   } // __construct()
52
         
53
   /**
54
    * NEPHTHYS_DB class deconstructor
55
    *
56
    * This destructor will close the current database connection.
57
    */ 
58
   public function __destruct()
59
   {
60
      $this->db_disconnect();
61
62
   } // _destruct()
63
64
   /**
65
    * NEPHTHYS_DB database connect
66
    *
67
    * This function will connect to the database via MDB2
68
    */
69
   private function db_connect()
70
   {
71
      $options = array(
72
         'debug' => 2,
73
         'portability' => 'DB_PORTABILITY_ALL'
74
      );
75
76
      switch($this->cfg->db_type) {
77
         default:
78
         case 'mysql':
79
            $dsn = "mysqli://"
80
               . $this->cfg->mysql_user .":"
81
               . $this->cfg->mysql_pass ."@"
82
               . $this->cfg->mysql_host ."/"
83
               . $this->cfg->mysql_db;
84
            break;
85
         case 'sqlite':
86
            $dsn = "sqlite:///"
87
               . $this->cfg->sqlite_path;
88
            break;
89
90
      }
91
92
      $this->db = MDB2::connect($dsn, $options);
93
94
      if(PEAR::isError($this->db)) {
95
         $this->throwError("Unable to connect to database: ". $this->db->getMessage() .' - '. $this->db->getUserInfo());
96
         $this->setConnStatus(false);
97
      }
98
99
      $this->setConnStatus(true);
100
101
   } // db_connect()
102
103
   /**
104
    * NEPHTHYS_DB database disconnect
105
    *
106
    * This function will disconnected an established database connection.
107
    */
108
   private function db_disconnect()
109
   {
110
      $this->db->disconnect();
111
112
   } // db_disconnect()
113
114
   /**
115
    * NEPHTHYS_DB database query
116
    *
117
    * This function will execute a SQL query and return the result as
118
    * object.
119
    */
120
   public function db_query($query = "", $mode = MDB2_FETCHMODE_OBJECT)
121
   {
122
      if($this->getConnStatus()) {
123
124
         $this->db->setFetchMode($mode);
125
126
         /* for manipulating queries use exec instead of query. can save
127
          * some resource because nothing has to be allocated for results.
128
          */
129
         if(preg_match('/^(update|insert)i/', $query)) {
130
            $result = $this->db->exec($query);
131
         }
132
         else {
133
            $result = $this->db->query($query);
134
         }
135
                        
136
         if(PEAR::isError($result))
137
            $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
138
        
139
         return $result;
140
      }
141
      else 
142
         $this->throwError("Can't execute query - we are not connected!");
143
144
   } // db_query()
145
146
   /**
147
    * NEPHTHYS_DB database prepare query
148
    *
149
    * This function will prepare a SQL query to be executed
150
    * @param string $query
151
    * @param int $mode
152
    * @return mixed
153
    */
154
   public function db_prepare($query = "")
155
   {
156
      if($this->getConnStatus()) {
157
158
         $this->db->prepare($query);
159
160
         /* for manipulating queries use exec instead of query. can save
161
          * some resource because nothing has to be allocated for results.
162
          */
163
         if(preg_match('/^(update|insert|delete)i/', $query)) {
164
            $sth = $this->db->prepare($query, MDB2_PREPARE_MANIP);
165
         }
166
         else {
167
            $sth = $this->db->prepare($query, MDB2_PREPARE_RESULT);
168
         }
169
170
         if(PEAR::isError($sth))
171
            $this->throwError($sth->getMessage() .' - '. $sth->getUserInfo());
172
173
         return $sth;
174
      }
175
      else
176
         $this->throwError("Can't prepare query - we are not connected!");
177
178
   } // db_prepare()
179
180
   /**
181
    * NEPHTHYS_DB database execute a prepared query
182
    *
183
    * This function will execute a previously prepared SQL query
184
    * @param mixed $sth
185
    * @param mixed $data
186
    */
187
   public function db_execute($sth, $data)
188
   {
189
      if($this->getConnStatus()) {
190
191
         $result = $sth->execute($data);
192
193
         if(PEAR::isError($result))
194
            $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
195
196
      }
197
      else
198
         $this->throwError("Can't prepare query - we are not connected!");
199
200
   } // db_execute()
201
202
   /**
203
    * NEPHTHYS_DB database query & execute
204
    *
205
    * This function will execute a SQL query and return nothing.
206
    */
207
   public function db_exec($query = "")
208
   {
209
      if(!$this->getConnStatus())
210
         return false;
211
212
      $affected =& $this->db->exec($query);
213
214
      if(PEAR::isError($affected)) {
215
         $this->throwError($affected->getMessage());
216
         return false;
217
      }
218
219
      return true;
220
221
   } // db_exec()
222
223
   /**
224
    * NEPHTHYS_DB fetch ONE row
225
    *
226
    * This function will execute the given but only return the
227
    * first result.
228
    */
229
   public function db_fetchSingleRow($query = "", $mode = MDB2_FETCHMODE_OBJECT)
230
   {
231
      if($this->getConnStatus()) {
232
233
         $row = $this->db->queryRow($query, array(), $mode);
234
235
         if(PEAR::isError($row))
236
            $this->throwError($row->getMessage() .' - '. $row->getUserInfo());
237
238
         return $row;
239
        
240
      }
241
      else {
242
   
243
         $this->throwError("Can't fetch row - we are not connected!");
244
      
245
      }
246
      
247
   } // db_fetchSingleRow()
248
249
   /**
250
    * NEPHTHYS_DB number of affected rows
251
    *
252
    * This functions returns the number of affected rows but the
253
    * given SQL query.
254
    */
255
   public function db_getNumRows($query = "")
256
   {
257
      /* Execute query */
258
      $result = $this->db_query($query);
259
260
      /* Errors? */
261
      if(PEAR::isError($result))
262
         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
263
264
      return $result->numRows();
265
266
   } // db_getNumRows()
267
268
   /**
269
    * NEPHTHYS_DB get primary key
270
    *
271
    * This function returns the primary key of the last
272
    * operated insert SQL query.
273
    */
274
   public function db_getid($table_name = null)
275
   {
276
      /* Get the last primary key ID from execute query */
277
      $id = $this->db->lastInsertID($table_name);
278
      if (PEAR::isError($id)) {
279
          $this->throwError($id->getMessage());
280
      }
281
282
      return $id;
283
      
284
   } // db_getid()
285
286
   /**
287
    * NEPHTHYS_DB check table exists
288
    *
289
    * This function checks if the given table exists in the
290
    * database
291
    * @param string, table name
292
    * @return true if table found otherwise false
293
    */
294
   public function db_check_table_exists($table_name = "")
295
   {
296
      if(!$this->getConnStatus())
297
         return false;
298
299
      switch($this->cfg->db_type) {
300
         default:
301
         case 'mysql':
302
            $result = $this->db_query("SHOW TABLES");
303
            $tables_in = "Tables_in_". $this->cfg->mysql_db;
304
            while($row = $result->fetchRow()) {
305
               if($row->$tables_in == $table_name)
306
                  return true;
307
            }
308
            break;
309
         case 'sqlite':
310
            $result = $this->db_query("SELECT name FROM sqlite_master WHERE type='table'");
311
            while($row = $result->fetchRow()) {
312
               if($row->name == $table_name)
313
                  return true;
314
            }
315
            break;
316
      }
317
318
      return false;
319
         
320
   } // db_check_table_exists()
321
322
   /**
323
    * NEPHTHYS_DB rename table
324
    * 
325
    * This function will rename an database table
326
    * @param old_name, new_name
327
    */
328
   public function db_rename_table($old, $new)
329
   {
330
      if($this->db_check_table_exists($old)) {
331
         if(!$this->db_check_table_exists($new))
332
            $this->db_query("RENAME TABLE ". $old ." TO ". $new);
333
         else
334
            $this->throwError("Can't rename table ". $old ." - ". $new ." already exists!");
335
      }
336
         
337
   } // db_rename_table()
338
339
   /**
340
    * NEPHTHYS_DB drop table
341
    *
342
    * This function will delete the given table from database
343
    */
344
   public function db_drop_table($table_name)
345
   {
346
      if($this->db_check_table_exists($table_name))
347
         $this->db_query("DROP TABLE ". $table_name);
348
349
   } // db_drop_table()
350
351
   /**
352
    * NEPHTHYS_DB truncate table
353
    *
354
    * This function will truncate (reset) the given table
355
    */
356
   public function db_truncate_table($table_name)
357
   {
358
      if($this->db_check_table_exists($table_name)) 
359
         $this->db_query("TRUNCATE TABLE ". $table_name);
360
361
   } // db_truncate_table()
362
363
   /**
364
    * NEPHTHYS_DB check column exist
365
    *
366
    * This function checks if the given column exists within
367
    * the specified table.
368
    */
369
   public function db_check_column_exists($table_name, $column)
370
   {
371
      if(!$this->getConnStatus())
372
         return false;
373
374
      switch($this->cfg->db_type) {
375
         default:
376
         case 'mysql':
377
            $result = $this->db_query("DESC ". $table_name, MDB2_FETCHMODE_ORDERED);
378
            while($row = $result->fetchRow()) {
379
            if(in_array($column, $row))
380
               return true;
381
            }
382
            break;
383
         case 'sqlite':
384
            $result = $this->db_query("
385
               SELECT sql
386
               FROM
387
                  (SELECT * FROM sqlite_master UNION ALL
388
                   SELECT * FROM sqlite_temp_master)
389
               WHERE
390
                  tbl_name LIKE '". $table_name ."'
391
               AND type!='meta'
392
               AND sql NOT NULL
393
               AND name NOT LIKE 'sqlite_%'
394
               ORDER BY substr(type,2,1), name
395
            ");
396
            while($row = $result->fetchRow()) {
397
               /* CREATE TABLE xx ( col1 int, col2 bool, col3 ...) */
398
               if(strstr($row->sql, " ". $column ." ") !== false)
399
                  return true;
400
            }
401
            break;
402
      }
403
404
      return false;
405
406
   } // db_check_column_exists()
407
408
   /**
409
    * NEPHTHYS_DB check index exists
410
    *
411
    * This function checks if the given index can be found
412
    * within the specified table.
413
    */
414
   public function db_check_index_exists($table_name, $index_name)
415
   {
416
      $result = $this->db_query("DESC ". $table_name, MDB2_FETCHMODE_ORDERED);
417
418
      while($row = $result->fetchRow()) {
419
         if(in_array("KEY `". $index_name ."`", $row))
420
            return 1;
421
      }
422
423
      return 0;
424
425
   } // db_check_index_exists()
426
427
   /**
428
    * NEPHTHYS_DB alter table
429
    *
430
    * This function offers multiple methods to alter a table.
431
    * * add/modify/delete columns
432
    * * drop index
433
    */
434
   public function db_alter_table($table_name, $option, $column, $param1 = "", $param2 = "")
435
   {
436
      if(!$this->db_check_table_exists($table_name)) {
437
         $this->throwError("Table ". $table_name ." does not exist!");
438
         return false;
439
      }
440
441
      switch($this->cfg->db_type) {
442
         default:
443
         case 'mysql':
444
445
            switch(strtolower($option)) {
446
447
               case 'add':
448
                  if(!$this->db_check_column_exists($table_name, $column))
449
                     $this->db_query("ALTER TABLE ". $table_name ." ADD ". $column ." ". $param1);
450
                  break;
451
452
               case 'change':
453
                  if($this->db_check_column_exists($table_name, $column))
454
                     $this->db_query("ALTER TABLE ". $table_name ." CHANGE ". $column ." ". $param1);
455
                  break;
456
457
               case 'drop':
458
                  if($this->db_check_column_exists($table_name, $column))
459
                     $this->db_query("ALTER TABLE ". $table_name ." DROP ". $column);
460
                  break;
461
462
               case 'dropidx':
463
                  if($this->db_check_index_exists($table_name, $column))
464
                     $this->db_query("ALTER TABLE ". $table_name ." DROP INDEX ". $column);
465
                  break;
466
467
            }
468
            break;
469
470
         case 'sqlite':
471
472
            $this->throwError("SQLite only support ALTER TABLE rudimentary with version 3, so no support here right now.");
473
            break;
474
475
      }
476
477
   } // db_alter_table()
478
479
   /**
480
    * NEPHTHYS_DB get database version
481
    *
482
    * This functions returns the current database version
483
    */
484
   public function getVersion()
485
   {
486
      if($this->db_check_table_exists(MYSQL_PREFIX ."settings")) {
487
         $result = $this->db_fetchSingleRow("
488
            SELECT setting_value 
489
            FROM ". MYSQL_PREFIX ."settings 
490
            WHERE setting_key LIKE 'version'
491
         ");
492
         return $result->setting_value;
493
      }
494
      else
495
         return 0;
496
         
497
   } // getVersion()
498
499
   /**
500
    * NEPHTHYS_DB set version
501
    *
502
    * This function sets the version of database
503
    */
504
   public function setVersion($version)
505
   {
506
      $this->db_query("
507
         REPLACE INTO ". MYSQL_PREFIX ."settings 
508
            (setting_key, setting_value)
509
         VALUES ('version', '". $version ."')
510
      ");
511
      
512
   } // setVersion()
513
514
   /**
515
    * NEPHTHYS_DB get connection status
516
    *
517
    * This function checks the internal state variable if already
518
    * connected to database.
519
    */
520
   private function setConnStatus($status)
521
   {
522
      $this->is_connected = $status;
523
      
524
   } // setConnStatus()
525
526
   /**
527
    * NEPHTHYS_DB set connection status
528
    * This function sets the internal state variable to indicate
529
    * current database connection status.
530
    */
531
   private function getConnStatus()
532
   {
533
      return $this->is_connected;
534
535
   } // getConnStatus()
536
537
   /**
538
    * NEPHTHYS_DB throw error
539
    *
540
    * This function shows up error messages and afterwards through exceptions.
541
    */
542
   private function throwError($string)
543
   {
544
      if(!defined('DB_NOERROR'))  {
545
546
         $this->parent->_error($string);
547
548
         try {
549
            throw new NEPHTHYS_EXCEPTION;
550
         }
551
         catch(NEPHTHYS_EXCEPTION $e) {
552
            print "<br /><br />\n";
553
            $this->parent->_error($e);
554
            die;
555
         }
556
      }
557
558
      $this->last_error = $string;
559
         
560
   } // throwError()
561
562
   /**
563
    * quote string
564
    *
565
    * this function handsover the provided string to the MDB2
566
    * quote() function which will return the, for the selected
567
    * database system, correctly quoted string.
568
    *
569
    * @param string $query
570
    * @return string
571
    */
572
   public function db_quote($obj)
573
   {
574
      return $this->db->quote($obj);
575
576
   } // db_quote()
577
578
   /**
579
    * start transaction
580
    *
581
    * this will start a transaction on ACID-supporting database
582
    * systems.
583
    *
584
    * @return bool
585
    */
586
   public function db_start_transaction()
587
   {
588
      if(!$this->getConnStatus())
589
         return false;
590
591
      if(!$this->db->supports('transactions'))
592
         return false;
593
594
      $result = $this->db->beginTransaction();
595
596
      /* Errors? */
597
      if(PEAR::isError($result))
598
         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
599
600
      return true;
601
602
   } // db_start_transaction()
603
604
   /**
605
    * commit transaction
606
    *
607
    * this will commit an ongoing transaction on ACID-supporting
608
    * database systems
609
    *
610
    * @return bool
611
    */
612
   public function db_commit_transaction()
613
   {
614
      if(!$this->getConnStatus())
615
         return false;
616
617
      if(!$this->db->inTransaction())
618
         return false;
619
620
      $result = $this->db->commit();
621
622
      /* Errors? */
623
      if(PEAR::isError($result))
624
         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
625
626
      return true;
627
628
   } // db_commit_transaction()
629
630
   /**
631
    * rollback transaction()
632
    *
633
    * this function aborts a on going transaction
634
    *
635
    * @return bool
636
    */
637
   public function db_rollback_transaction()
638
   {
639
      if(!$this->getConnStatus())
640
         return false;
641
642
      if(!$this->db->inTransaction())
643
         return false;
644
645
      $result = $this->db->rollback();
646
647
      /* Errors? */
648
      if(PEAR::isError($result))
649
         $this->throwError($result->getMessage() .' - '. $result->getUserInfo());
650
651
      return true;
652
653
   } // db_rollback_transaction()
654
655
} // NEPHTHYS_DB()
656
657
// vim: set filetype=php expandtab softtabstop=3 tabstop=3 shiftwidth=3 autoindent smartindent:
658
?>
659