From 9c7c944c86efa4098c845faec5f6c8e2b05c28ed Mon Sep 17 00:00:00 2001 From: SmiSoft Date: Sat, 31 Mar 2018 14:39:04 +0300 Subject: [PATCH] Added support for table prefix --- README.md | 43 +++++++++++------ src/PHPixie/Database/Type/SQL/Parser.php | 47 ++++++++++++------- .../Database/Type/SQL/Parser/Fragment.php | 33 +++++++++++-- 3 files changed, 87 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index f1096c4..f7769bd 100755 --- a/README.md +++ b/README.md @@ -44,26 +44,41 @@ return array( //each with a different name 'default' => array( 'driver' => 'pdo', - + //MySQL 'connection' => 'mysql:host=localhost;dbname=phpixie', - + //or SQLite 'connection' => 'sqlite:/some/file', - + //or Postgres 'connection' => 'pgsql:dbname=exampledb', - + 'user' => 'root', - 'password' => 'password' + 'password' => 'password', + + // if non-standart port used + 'port' => 3306, + + // if non-UTF-8 charset used + 'charset' => 'utf8', + + // if you use unix sockets to connect to your MySQL database + 'unixSocket' => '...', + + // prefix for all tables, useful, if you have only one DB and more than one project + 'prefix' => 'prefix_', ), - + 'other' => array( //connecting to MongoDD 'driver' => 'mongo', 'database' => 'phpixie', 'user' => 'pixie', - 'password' => 'password' + 'password' => 'password', + // additional options + 'uriOptions' => array(), + 'driverOptions' => array(), ) ); ``` @@ -84,7 +99,7 @@ $posts = $query ->limit(5) ->offset(1) ->execute(); - + // Specifying fields $query->fields(array('id')); @@ -101,7 +116,7 @@ $query ->where('status', 'published') ->orWhereNot('status', 'deleted') ->xorWhere('id', 5); - + //Shorthand functions $query ->and('status', 'published') @@ -125,7 +140,7 @@ $query ->where('id', 4) ->and('views', 4); }); - + // More verbose syntax // Useful for programmatic filters $query @@ -199,7 +214,7 @@ $query->join('categories', 'c', 'left') $query ->on('p.categoryId', 'c.categoryId'); - + // The on() conditions can be used in // the same way as where(), and apply // to the last join() statement @@ -209,7 +224,7 @@ $query ->or('p.parentCategoryId', 'c.id') ->join('authors') ->on('p.authorId', 'authors.id'); - + // You can use subqueries as tables, // but you must supply the alias parameter @@ -353,7 +368,7 @@ $connection->updateQuery() ->set('done', true) ->unset(array('started', 'inProgress')) ->execute(); - + $connection->insertQuery() ->collection('posts') ->batchData(array( @@ -375,7 +390,7 @@ $query ->startOrNotSubdocumentGroup('author') ->where('name', 'Dracony') ->endGroup(); - + //setting conditions for subarray items $query ->startOrNotSubarrayItemGroup('authors') diff --git a/src/PHPixie/Database/Type/SQL/Parser.php b/src/PHPixie/Database/Type/SQL/Parser.php index 74f5319..6112b52 100755 --- a/src/PHPixie/Database/Type/SQL/Parser.php +++ b/src/PHPixie/Database/Type/SQL/Parser.php @@ -21,6 +21,8 @@ public function __construct($database, $driver, $config, $fragmentParser, $condi { parent::__construct($database, $driver, $config); $this->fragmentParser = $fragmentParser; + if(is_object($config)) // while unittest, $config is a string 'config' and $fragmentParser is 'fragmentParser' + $fragmentParser->setPrefix($config->get('prefix')); $this->conditionsParser = $conditionsParser; } @@ -32,6 +34,17 @@ public function __construct($database, $driver, $config, $fragmentParser, $condi */ public function parse($query) { + // this prevent fails while unittest, because thile testing, $this->fragmentParser is a string 'fragmentParser' + if(is_object($this->fragmentParser) and method_exists($query,'getJoins')) { + // build "real" table names list. They will be prepended with prefix. All other names are alias, they won't be changed + $tables=array(); + $tables[]=$query->getTable('table')['table']; + foreach($query->getJoins() as $joinTable){ + $tables[]=$joinTable['table']; + } + $this->fragmentParser->setTables($tables); + } + $expr = $this->database->sqlExpression(); $type = $query->type(); @@ -184,52 +197,52 @@ protected function appendInsertValues($query, $expr) if (($insertData = $query->getBatchData()) !== null) { $columns = $insertData['columns']; $rows = $insertData['rows']; - + }elseif(($data = $query->getData()) !== null) { $columns = array_keys($data); $rows = array(array_values($data)); - + }else{ $columns = array(); $rows = array(); } - + if (empty($columns) && empty($rows) ) { return $this->appendEmptyInsertValues($expr); } if (!empty($columns)) { $expr->sql .= "("; - + foreach ($columns as $key => $column) { if($key > 0) $expr->sql.= ', '; $this->fragmentParser->appendColumn($column, $expr); } - + $expr->sql .= ")"; - + } - + $expr->sql .= " "; if (!$this->appendSubquery($expr, $rows)) { $expr->sql .="VALUES "; $columnsCount = count($columns); - + foreach ($rows as $rowKey => $row) { - + if (count($row) != $columnsCount) throw new \PHPixie\Database\Exception\Parser("The number of keys does not match the number of values for bulk insert."); - + if($rowKey > 0) $expr->sql.= ', '; - + $expr->sql.= '('; foreach ($row as $valueKey => $value) { if($valueKey > 0) $expr->sql.= ', '; - + $this->fragmentParser->appendValue($value, $expr); } $expr->sql.= ')'; @@ -393,7 +406,7 @@ protected function appendLimitOffsetValues($expr, $limit, $offset) if ($limit !== null) { $expr->sql.= " LIMIT $limit"; } - + if ($offset !== null) { $expr->sql.=" OFFSET $offset"; } @@ -413,7 +426,7 @@ protected function appendUnion($query, $expr) $expr->sql.= " UNION "; if ($all) $expr->sql.= "ALL "; - + if (!$this->appendSubquery($expr, $query)) { throw new \PHPixie\Database\Exception\Parser("Union parameter must be either a SELECT Query object or SQL expression object"); } @@ -430,14 +443,14 @@ protected function appendSubquery($expr, $query) { if ($query instanceof \PHPixie\Database\Type\SQL\Query && $query->type() === 'select') { $expr->append($query->parse()); - + } elseif ($query instanceof \PHPixie\Database\Type\SQL\Expression) { $expr->append($query); - + }else{ return false; } - + return true; } diff --git a/src/PHPixie/Database/Type/SQL/Parser/Fragment.php b/src/PHPixie/Database/Type/SQL/Parser/Fragment.php index 1d0d959..64be534 100755 --- a/src/PHPixie/Database/Type/SQL/Parser/Fragment.php +++ b/src/PHPixie/Database/Type/SQL/Parser/Fragment.php @@ -5,6 +5,27 @@ abstract class Fragment { protected $quote; + protected $prefix=''; + protected $realtables=array(); + + public function setPrefix($prefix) + { + $this->prefix=$prefix; + } + + public function setTables($tables) + { + $this->realtables=array_map(function($data){ + return is_string($data)?strtolower($data):''; + }, $tables); + } + + protected function addPrefix($tableOrAlias) + { + return in_array(strtolower($tableOrAlias),$this->realtables)? + $this->prefix.$tableOrAlias: + $tableOrAlias; + } public function quote($str) { @@ -18,7 +39,7 @@ public function appendColumn($column, $expr) if (strpos($column, '.')) { $column = explode('.', $column); - $expr->sql.= $this->quote($column[0]).'.'; + $expr->sql.= $this->quote($this->addPrefix($column[0])).'.'; $column = $column[1]; } @@ -36,13 +57,15 @@ public function appendTable($table, $expr, $alias = null) $table = explode('.', $table); foreach($table as $key => $part) { if($key !== 0) { - $expr->sql.= '.'; + $expr->sql.= '.'; + }else{ + $part=$this->addPrefix($part); } $expr->sql.= $this->quote($part); } - - } elseif ( - ($isQuery = $table instanceof \PHPixie\Database\Type\SQL\Query) || + + } elseif ( + ($isQuery = $table instanceof \PHPixie\Database\Type\SQL\Query) || $table instanceof \PHPixie\Database\Type\SQL\Expression ) {