Jump to content

DB Handler Concept.


eddedwards

Recommended Posts

Ive been studying abstract classes and interfaces and was trying to come up with a good way of using it for a database handler. I want it for a cms project im doing and would like to know if this is a good way of doing it.

 

c_db_handler.php:

1. Function for getting the handler.

2. Abstract db_handler class.

3+ Supported db extension classes.

(Currently working with SQLite and MySql skeleton in place)

<?php

function get_db_handler ($db_type) {
   $args = func_get_args();
   switch ($args[0]) {
      case "SQLite" :
         if (func_num_args() == 3) return new sqlite_handler($args[1],$args[2]);
      break;
      case "MySQL" :
         return new mysql_handler();
      break;
   }
}

abstract class db_handler {

   // Possible data connection requirements.
   protected $db_name;
   protected $db_path;
   protected $db_perm;
   protected $db_server;
   protected $db_user;
   protected $db_pass;

   // DB Handler Variables.
   protected $handle;
   protected $result;
   protected $errors = array();
   protected $result_type;

   abstract protected function connect();
   abstract protected function disconnect();
   abstract protected function parse_query($sql);
   abstract protected function parse_query_exec($sql);
   abstract public function fetch_result($fetch_type);

   function set_data($name=NULL,$path=NULL,$perm=NULL,$server=NULL,$user=NULL,$pass=NULL,$res_type=SQLITE_ASSOC) {
      if ($name) $this->db_name = $name;
      if ($path) $this->db_path = $path;
      if ($perm) $this->db_perm = $perm;
      if ($server) $this->db_server = $server;
      if ($user) $this->db_user = $user;
      if ($pass) $this->db_pass = $pass;
      $this->result_type = $res_type;
   }

}

class sqlite_handler extends db_handler {

   function __construct($db_path,$db_name) {
      $this->set_data($db_name,$db_path,0666,NULL,NULL,NULL);
   }  
   
   function connect() {
      if ($this->handle = sqlite_open($this->db_path . $this->db_name,$this->db_perm,&$this->errors[])) {
         return true;
      } else {
         return false;
      }
   }
   
   function disconnect() {
      sqlite_close($this->handle);
   }   
   
   function parse_query($sql) {
      if ($this->result = sqlite_query($this->handle,$sql,$this->result_type,&$this->errors[])) {
         return true;
      } else {
         return false;
      }
   }
   
   function parse_query_exec ($sql) {
      if ($this->result = sqlite_exec($this->handle,$sql,&$this->errors[])) {
         return true;
      } else {
         return false;
      }
   }
   
   function fetch_result($fetch_type) {
      $data = false;
      switch (strtolower($fetch_type)) {
         case "all" :
            if ($data = sqlite_fetch_all($this->result, $this->result_type)) return $data;
         break;

         case "array" :
            if ($data = sqlite_fetch_array($this->result, $this->result_type)) return $data;
         break;

         case "string" OR "single" :
            if ($data = sqlite_fetch_single($this->result)) return $data;
         break;
      }
      return $data;
   }
   
}

class mysql_handler extends db_handler {

   function connect() {
   }

   function disconnect() {
   }   
   
   function parse_query($sql) {
   }
   
   function parse_query_exec ($sql) {
   }
   
   function fetch_result($fetch_type) {
   }
   
}

?>

 

index.php:

Usage code.

<?php

include_once("./inc/c_db_handler.php");

$sql[1] = <<<SQL
BEGIN;
CREATE TABLE test ( 
   foo VARCHAR(10),
   bar VARCHAR(10)
);

INSERT INTO test (foo,bar) VALUES ("test1","test2");
COMMIT;
SQL;

$sql[2] = <<<SQL
SELECT * FROM test;
SQL;

$db = get_db_handler("SQLite",NULL,":memory:");
$db->connect();
$db->parse_query_exec($sql[1]);
$db->parse_query($sql[2]);

//$end = $db->fetch_result("all");

while ($row = $db->fetch_result("array") ) {
   $end .= "<pre>" . print_r($row,true) . "</pre>";
}

$db->disconnect();

echo "<pre>" . print_r($db,true) . "</pre>";
echo "<pre>" . print_r($end,true) . "</pre>";

?>

 

output of this test:

sqlite_handler Object
(
    [db_name:protected] => :memory:
    [db_path:protected] => 
    [db_perm:protected] => 438
    [db_server:protected] => 
    [db_user:protected] => 
    [db_pass:protected] => 
    [handle:protected] => Resource id #3
    [result:protected] => Resource id #4
    [errors:protected] => Array
        (
            [0] => 
            [1] => 
            [2] => 
        )

    [result_type:protected] => 1
)

Array
(
    [foo] => test1
    [bar] => test2
)

Link to comment
Share on other sites

I don't like how get_db_handler is a function floating around in the global scope.

 

function fetch_result($fetch_type) {
      $data = false;
      switch (strtolower($fetch_type)) {
         case "all" :
            if ($data = sqlite_fetch_all($this->result, $this->result_type)) return $data;
         break;

         case "array" :
            if ($data = sqlite_fetch_array($this->result, $this->result_type)) return $data;
         break;

         case "string" OR "single" :
            if ($data = sqlite_fetch_single($this->result)) return $data;
         break;
      }
      return $data;
   }

 

 

 

That just seems kinda... Not elegant for lack of a better word.  Setting $res_type earlier and then passing an arg again and what not.  Also, all the switching....  I would probably put each in its own function.  fetch_array(), fetch_assoc(), fetch_row(), so on.

 

I don't remember if I saw anything else when I read through it....  Don't feel like glancing through it again, so I'm going to assume everything else was good ;p.

Link to comment
Share on other sites

Cheers for the input. Id like some clarification if possible.

 

1: get_db_handler was in the global scope because I could figure out a way of doing it another way. I need to pass a database type from a config array then load the right extension. I didn't think it would work from inside the db_handler class or its extensions unless something like this is possible:

 

<?php
class db_h {

   var $db_type;

   function __construct($type) {
      $class = $type . "_h";
      $this->db_type = new $class();
   }

}

class sqlite_h {
}

$test = new db_h("sqlite");
?>

 

 

2: I can see what you mean about the set_data & the switching though I shall look into tidying that up.

 

Thanks again im going to go test my theory.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.