PHP-SQL-Parser icon indicating copy to clipboard operation
PHP-SQL-Parser copied to clipboard

Multi queries in one

Open wapmorgan opened this issue 7 years ago • 2 comments

Does library support multi CREATE queries? What if I pass a query lile

CREATE TABLE IF NOT EXISTS `migration` (
  `type` varchar(25) NOT NULL,
  `name` varchar(50) NOT NULL,
  `migration` varchar(100) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `users_groups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `user_id` int(11) NOT NULL DEFAULT '0',
  `created_at` int(11) NOT NULL DEFAULT '0',
  `updated_at` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;

PHPSQLParser returns TABLE configuration only for last query. Does it support multi CREATE TABLE queries?

wapmorgan avatar May 24 '17 10:05 wapmorgan

Example: SQL:

CREATE TABLE IF NOT EXISTS `migration` (  `type` varchar(25) NOT NULL,  `name` varchar(50
) NOT NULL, `migration` varchar(100) NOT NULL DEFAULT \'\' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXI
STS `abregation` (  `type` varchar(25) NOT NULL,  `name` varchar(50) NOT NULL, `migration` varchar(100) NOT NULL DEFAULT
 \'\' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Code:

var_dump($parser->parse('-here goes this sql-'));

Output:

array(2) {
  ["CREATE"]=>
  array(4) {
    ["expr_type"]=>
    string(5) "table"
    ["not-exists"]=>
    bool(true)
    ["base_expr"]=>
    string(196) "TABLE IF NOT EXISTS TABLE `migration` (  `type` varchar(25) NOT NULL,  `name` varchar(50) NOT NULL, `migration` varchar(100) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=utf8  IF NOT EXISTS"
...
...
  }
  ["TABLE"]=>
  array(5) {
    ["base_expr"]=>
    string(12) "`abregation`"
    ["name"]=>
    string(12) "`abregation`"
    ["no_quotes"]=>
    array(2) {
      ["delim"]=>
      bool(false)
      ["parts"]=>
      array(1) {
        [0]=>
        string(10) "abregation"
      }
    }
...
...
...

wapmorgan avatar May 24 '17 10:05 wapmorgan

I'm using this piece of code to split up multiple queries first:

<?php

use PHPSQLParser\lexer\PHPSQLLexer;
use PHPSQLParser\PHPSQLCreator;
use PHPSQLParser\PHPSQLParser;

class SqlParser
{
    /** @var string */
    protected $_sql;

    /** @var string[] */
    protected $_queryList;

    /**
     * @param string $sql
     */
    public function __construct($sql)
    {
        $this->_sql = (string)$sql;
    }

    /**
     * @return string[]
     */
    public function getQueryList()
    {
        if (!isset($this->_queryList)) {
            $lexer = new PHPSQLLexer();
            $sqlTokenList = $lexer->split($this->_sql);
            $this->_queryList = [];
            $query = '';
            foreach ($sqlTokenList as $sqlToken) {
                if (';' === $sqlToken) {
                    if ('' !== trim($query)) {
                        $this->_queryList[] = trim($query);
                    }
                    $query = '';
                } else {
                    $query .= $sqlToken;
                }
            }
            if ('' !== trim($query)) {
                $this->_queryList[] = trim($query);
            }
        }
        return $this->_queryList;
    }

    /**
     * @return array[]
     */
    public function getParsedQueryList()
    {
        $parsedQueryList = [];
        foreach ($this->getQueryList() as $query) {
            $parser = new PHPSQLParser();
            $parsedQueryList[] = $parser->parse($query);
        }
        return $parsedQueryList;
    }

    /**
     * @param array $parsedQuery
     * @return string
     */
    public static function unparseQuery($parsedQuery)
    {
        $creator = new PHPSQLCreator();
        return $creator->create($parsedQuery);
    }
}

Probably someone should make an AbstractProcessor out of this.

sebastien-fauvel avatar Dec 18 '18 20:12 sebastien-fauvel