File size: 8.29Kb
<?php
namespace Core\App\Install\Database;
use Phpfox;
/**
* Class Table
* @author Neil
* @version 4.5.0
* @package Core\App\Install\Database
*/
abstract class Table
{
/**
* @var string name of the table
*/
protected $_table_name;
/**
* @var string engine of table
*/
protected $_engine = 'InnoDB';
/**
* @var string charset of table
*/
protected $_charset = 'latin1';
/**
* @var Field is a Field of auto increment
*
*/
private $_auto_increment = '';
/**
* @var string is the field name of primary key
*/
private $_primary_key = '';
/**
* @var array of keys
*/
private $_key = [];
/**
* @var array structure of table in array
*/
protected $_aFieldParams = [];
/**
* @var array of Field, store all fields of this table
*/
protected $_aFields = [];
/**
* Table constructor.
*/
public function __construct()
{
$this->setTableName();
$this->setFieldParams();
$this->_table_name = Phpfox::getT($this->_table_name);
foreach ($this->_aFieldParams as $key => $aParam) {
$aParam['name'] = $key;
$newField = new Field($aParam);
if (!$newField->isValid()) {
continue;
}
$this->addField($newField);
if (isset($aParam['primary_key'])) {
$bAuto = (isset($aParam['auto_increment'])) ? $aParam['auto_increment'] : false;
$this->addPrimaryKey($newField, $bAuto);
}
}
}
/**
* Set name of this table, can't missing
*/
abstract protected function setTableName();
/**
* Set all fields of table
*/
abstract protected function setFieldParams();
/**
* Add a new field for this table
*
* @param Field $field
*
* @return bool
*/
private function addField($field)
{
if ($field->isValid()) {
$this->_aFields[] = $field;
return true;
} else {
return false;
}
}
/**
* Add a primary and auto increment for this table
*
* @param Field $field
* @param bool $bAutoIncrement
*/
private function addPrimaryKey($field, $bAutoIncrement = true)
{
$this->_primary_key = $field->getName();
if ($bAutoIncrement) {
$this->_auto_increment = $field;
}
}
/**
* Add a key for this table
*
* @param string $name
* @param array $listKey of Field
*
* @return bool
*/
protected function addKey($name, $listKey)
{
if (count($listKey) == 0) {
return false;
}
$aKey = [];
foreach ($listKey as $key) {
if (!is_a($key, '\Apps\PHPfox_Backup_Restore\Install\Database\Field')) {
continue;
}
$aKey[] = $key->getName();
}
if (count($aKey)) {
$this->_key[$name] = $aKey;
} else {
//Don't have any valid key
return false;
}
return true;
}
/**
* Generate the sql code for create new database only
*
* @return bool|array
*/
public function generate()
{
$aQuery = [];
$sQuery = "CREATE TABLE `" . $this->_table_name . "` (";
if (count($this->_aFields) == 0) {
return false;
}
foreach ($this->_aFields as $field) {
if (!is_a($field, '\Core\App\Install\Database\Field') || !$field->isValid()) {
return false;
}
$sQuery .= $field->getCode() . ',';
}
$sQuery = rtrim($sQuery, ',');
$sQuery .= ')';
$sQuery .= "ENGINE=$this->_engine DEFAULT CHARSET=$this->_charset;";
$aQuery[] = $sQuery;
if (!empty($this->_primary_key)) {
$sQuery = '';
$sQuery .= "ALTER TABLE `" . $this->_table_name . "`
ADD PRIMARY KEY (`" . $this->_primary_key . "`);";
$aQuery[] = $sQuery;
}
$sQuery = '';
if (is_a($this->_auto_increment, '\Core\App\Install\Database\Field')) {
$sAutoType = $this->_auto_increment->getType();
if ($this->_auto_increment->getTypeValue() > 0) {
$sAutoType .= '(' . $this->_auto_increment->getTypeValue() . ')';
}
$sQuery .= "ALTER TABLE `" . $this->_table_name . "`
MODIFY `" . $this->_auto_increment->getName() . "` " . $sAutoType . " AUTO_INCREMENT;";
}
if (!empty($sQuery)) {
$aQuery[] = $sQuery;
}
return $aQuery;
}
/**
* Truncate this table, use for reset
*/
public function truncate()
{
db()->truncateTable($this->_table_name);
}
/**
* Drop this table, use for uninstall
*/
public function drop()
{
db()->dropTable($this->_table_name);
}
/**
* Create/upgrade database when install/upgrade
*/
public function install()
{
$sOldFieldName = '';
if (!db()->tableExists($this->_table_name)) {
$aQueryCode = $this->generate();
foreach ($aQueryCode as $query) {
//TODO @Neil convert $this->generate() to dba
db()->query($query);
}
} else {
foreach ($this->_aFields as $field) {
if (!db()->isField($this->_table_name, $field->getName())) {
$aField = [
'table' => $this->_table_name,
'field' => $field->getName(),
'type' => $field->getFullType(),
'attribute' => $field->getOther()
];
if (!empty($sOldFieldName)) {
$aField['after'] = $sOldFieldName;
}
//Add new field
db()->addField($aField);
} else {
//Update an exist field
//Todo do this later
}
$sOldFieldName = $field->getName();
}
}
}
/**
* Check configuration set is correct
*
* @return bool
*/
public function isValid()
{
if (empty($this->_table_name)) {
return false;
}
//a table at least have two fields
if (count($this->_aFields) < 2) {
return false;
}
//a table has to have a primary key
if (!isset($this->_primary_key) || empty($this->_primary_key)) {
return false;
}
foreach ($this->_aFields as $field) {
if (!is_a($field, '\Core\App\Install\Database\Field')) {
return false;
}
}
return true;
}
public function insert($aParam)
{
foreach ($this->_aFieldParams as $sKey => $value) {
if (!isset($value['auto_increment']) && !isset($aParam[$sKey])) {
return false;
}
}
$iId = db()->insert($this->_table_name, $aParam);
return $iId;
}
public function search($aConditions, $bCount = false, $iLimit = null)
{
$sConds = '';
foreach ($aConditions as $sKey => $aCondition) {
if (!isset($this->_aFieldParams[$sKey])) {
continue;
}
if (!isset($aCondition['operator']) || !isset($aCondition['data'])) {
continue;
}
if (!empty($sConds)) {
$sConds .= ' AND ';
}
$sConds .= "`$sKey` " . $aCondition['operator'] . " \"" . $aCondition['data'] ."\"";
}
if (empty($sConds)) {
$sConds = "true";
}
$oDb = db();
if ($bCount) {
$oDb->select('COUNT(*)');
} else {
$oDb->select('*');
}
$oDb->from($this->_table_name)
->where($sConds);
if ($bCount){
$aResults = $oDb->execute('getSlaveField');
} else {
if (isset($iLimit) && $iLimit) {
$oDb->limit($iLimit);
}
$aResults = $oDb->execute('getSlaveRows');
}
return $aResults;
}
}