Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save otengkwame/0673c114becc64421bba298bd873d2e8 to your computer and use it in GitHub Desktop.
Save otengkwame/0673c114becc64421bba298bd873d2e8 to your computer and use it in GitHub Desktop.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Dinabase Class
*
* @package CodeIgniter
* @subpackage Libraries
* @author Kader Bouyakoub <[email protected]>
* @link http://www.bkader.com/
* @license MIT, DBAD
*
* INFORMATIONS:
*
* This library allow you to get rid of other database engine
* as its uses flat-files with content encoded usin json_ecode
* or bson_encode (if the function exists - php mongo ext needed)
*
* Make sure to create a config file for this library and name it
* "dinabase.php" inside which you put:
*
* $config['path'] path to your data folder with trailing slash.
* $config['database'] name of the main database folder.
*
* That's it! Feel free to use it by please, DBAD.
*
* HOW TO USE:
*
* You simply need to load the library inside your controller or another
* library and pass the tablename so it works.
*
* i.e: $this->load->library('dinabase', array('tablename' => 'users'));
*
* 'users' folder will be automatically created inside your data folder
* and you can after proceed to using the library.
*
* Dinabase tables accept any values types because the result will be
* either a JSON encoded or BSON encoded if you have Mongodb extension
* enabled.
*
*/
class Dinabase
{
protected $CI;
/**
* @var string - folder where database files will be stored
*/
protected $path = null;
/**
* @var string - database name
*/
protected $database = null;
/**
* @var string - table name
*/
protected $tablename = null;
/**
* @var string - path to data folder
*/
protected $data_dir = null;
/**
* @var string - path to table folder
*/
protected $table_dir = null;
/**
* Creates a new database instance
* @access public
* @param string $data_path
* @param string $dbname
*/
public function __construct($config = array())
{
// Prepare CI object
$this->CI =& get_instance();
// Load library configuration file
$this->CI->load->config('dinabase');
// Prepare path to data folder
$config['path'] = config_item('path')
? config_item('path')
: APPPATH.'data'.DS;
$this->path = $config['path'];
// Create data folder if it does not already exist.
if ( ! is_dir($this->path))
{
// Create the data folder
if ( ! mkdir($this->path, 0777, true))
{
throw new Exception("Could not create data folder. Permission Denied!");
}
// Write our protection index.php
else
{
$this->_create_index($this->path);
}
}
// Set database connection
$config['database'] = config_item('database')
? config_item('database')
: 'main';
$this->database = $config['database'];
// Make sure the database folder exists or create it
if ( ! is_dir($this->path.$this->database))
{
if ( ! mkdir($this->path.$this->database, 0755, true))
{
throw new Exception("Could not create database. Permission Denied!");
}
else
{
$this->_create_index($this->path.$this->database);
}
}
// Prepare table name
isset($config['tablename']) or $config['tablename'] = null;
if ($config['tablename'] !== null)
{
$this->tablename = $config['tablename'];
//debug($this->data_dir.$this->tablename, true);
// Create the table now
if ( ! is_dir($this->data_dir.$this->tablename))
if ( ! @mkdir($this->data_dir.$this->tablename, 0755, true))
throw new Exception("Could not create database table. Permission Denied!");
else
$this->_create_index($this->data_dir.$this->tablename);
}
$this->data_dir = $this->path.$this->database.DS;
if ($this->tablename !== null)
{
$this->table_dir = $this->data_dir.$this->tablename.DS;
}
}
/**
* Insert new record into table
* @access public
* @param array $data array of key=>value
* @param string $tablename table name
* @return boolean
*/
public function insert(array $data, $tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($tablename !== null)
{
$guid = $this->_generate_guid();
$data = array_merge(array('id' => $guid), $data);
$row_file = $this->table_dir.md5($guid).'.dat';
// return serialize($data);
if ( ! file_put_contents($row_file, bson_encode($data)))
throw new Exception("Could not insert new record.");
return true;
}
return false;
}
/**
* Retrieves a single row by its ID
* @access public
* @param string $id ID of the row to retrieve
* @param string $tablename
* @return array
*/
public function find($id, $tablename = null)
{
$tablename or $tablename = $this->tablename;
return $this->find_one('id', $id, $tablename);
}
/**
* Retrieves multiple rows by conditions
* @access public
* @param mixed $field field name or array of WHERE
* @param mixed
* @param string $tablename
* @return array
*/
public function find_one($field, $match = null, $tablename = null)
{
$tablename or $tablename = $this->tablename;
if($rows = $this->_read_rows($tablename))
{
$where = (is_array($field) and $match === null)
? $field : array($field => $match);
if ($indexes = $this->_search_array($rows, $where))
{
return $rows[$indexes[0]];
}
return false;
}
return false;
}
/**
* Retrieves multiple or all rows inside a table
* @access public
* @param array $where array of WHERE statements
* @param string $tablename
* @return array
*/
public function find_all($where = array(), $tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($rows = $this->_read_rows($tablename))
{
$_found = false;
if ($indexes = $this->_search_array($rows, $where))
{
foreach ($indexes as $index)
{
$_found[$index] = $rows[$index];
}
}
return $_found;
}
return false;
}
/**
* Alias of the method above for CI active records fans
* @access public
* @param array
* @param string
* @return array
*/
public function get_where($where = array(), $tablename = null)
{
return $this->find_all($where, $tablename);
}
/**
* Alias of the find_all but it takes only table name
* so it retrieves all records.
* @access public
* @param string $tablename
* @return array
*/
public function all($tablename = null)
{
return $this->find_all(array(), $tablename);
}
/**
* Updates an existing row by its ID
* @access public
* @param string $id ID of the row to update
* @param array $data array of SET statements
* @param string $tablename
* @return boolean
*/
public function update($id, array $data, $tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($row = $this->find($id))
{
foreach($data as $key => $value)
{
$row[$key] = $value;
}
$file = $this->data_dir.$tablename.DS.md5($row['id']).'.dat';
$content = function_exists('bson_encode')
? bson_encode($row)
: json_encode($row);
if (file_put_contents($file, $content))
return true;
return false;
}
return false;
}
/**
* Updates multiple or all rows
* @access public
* @param array $data array of SET statements
* @param array $where array of WHERE statements
* @param string $tablename
* @return boolean
*/
public function update_all(array $data, $where = array(), $tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($rows = $this->find_all($where))
{
foreach($rows as $id => $row)
$this->update($id, $data, $tablename);
return true;
}
return false;
}
/**
* Deletes a single existing row by its ID
* @access public
* @param string $id ID of the row to delete
* @param string $tablename
* @return boolean
*/
public function delete($id, $tablename = null)
{
$tablename or $tablename = $this->tablename;
return $this->delete_all(array('id' => $id), $tablename);
}
/**
* Deletes multiple or all rows by conditions
* @access public
* @param array $where array of WHERE statements
* @param string $tablename
* @return boolean
*/
public function delete_all($where = array(), $tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($tablename !== null and $rows = $this->find_all($where))
{
foreach($rows as $id => $row)
{
if (isset($row['deleted']))
{
if ((bool) $row['deleted'] === false)
{
$this->update($id, array(
'deleted' => true,
'deleted_at' => time(),
));
}
}
else
{
$this->remove($id, $tablename);
}
}
return true;
}
return false;
}
/**
* Completely removes a single row bypassing soft delete
* @access public
* @param string $id ID of the row to delete
* @param string $tablename
* @return boolean
*/
public function remove($id, $tablename = null)
{
$tablename or $tablename = $this->tablename;
return $this->remove_all(array('id' => $id));
}
/**
* Completely remove multiple or all rows bypassing soft delete
* @access public
* @param array $where array of where statements
* @param string $tablename
* @return boolean
*/
public function remove_all(array $where, $tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($tablename !== null and $rows = $this->find_all($where))
{
$files = array();
foreach($rows as $id => $row)
{
$files[] = $this->table_dir.md5($row['id']).'.dat';
}
if ( ! empty($files))
{
foreach($files as $file)
@unlink($file);
return true;
}
return false;
}
return false;
}
/**
* Searches inside an array
* @access protected
* @param array $array
* @param array $where
*/
protected function _search_array(array $array, array $where)
{
$found = false;
foreach ($array as $aKey => $aVal)
{
$coincidences = 0;
foreach ($where as $pKey => $pVal)
{
if (array_key_exists($pKey, $aVal) && $aVal[$pKey] == $pVal)
{
$coincidences++;
}
}
if ($coincidences == count($where))
{
$found[] = $aKey;
}
}
return $found;
}
/**
* Read all row inside table folder
* @access protected
* @param string $tablename
* @return array
*/
protected function _read_rows($tablename = null)
{
$tablename or $tablename = $this->tablename;
if ($tablename !== null)
{
$rows = array();
foreach(glob($this->table_dir.'*.dat') as $row)
{
$index = preg_replace('/\\.[^.\\s]{3,4}$/', '', basename($row));
$row = file_get_contents($row);
$decoded = function_exists('bson_decode')
? bson_decode($row)
: json_decode($row);
$rows[$decoded['id']] = $decoded;
}
return $rows;
}
return false;
}
/**
* Create the index.php protection file
* @access protected
* @param string $path path where the create the file
* @return void
*/
protected function _create_index($path)
{
$o = umask(0);
file_put_contents(
$path.DS.'index.php',
'<?php'."\n".'die("Directory access is forbidden.");'."\n"
);
umask($o);
}
/**
* Generates a fresh new GUID
* @access protected
* @param none
* @return string
*/
protected function _generate_guid($striped = true)
{
$guid = '%04x%04x-%04x-%04x-%04x-%04x%04x%04x';
if ($striped === true)
$guid = '%04x%04x%04x%04x%04x%04x%04x%04x';
return vsprintf($guid, array(
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff),
));
}
}
/* End of file Dinabase.php */
/* Location: ./application/libraries/Dinabase.php */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment