Skip to content

Repository files navigation

Nextras Multi Query Parser

BuildDownloads this MonthStable Version

A streaming PHP parser for splitting multi-query SQL files into individual statements. Handles database-specific syntax like custom delimiters, dollar-quoted strings, and BEGIN...END blocks. The parser reads input in small chunks and yields statements one by one -- it never loads the entire file into memory, making it suitable for large SQL dumps.

Supported Databases

  • MySQL -- backtick identifiers, DELIMITER command, # comments
  • PostgreSQL -- dollar-quoted strings ($BODY$...$BODY$), E'...' escape strings
  • SQL Server -- [bracketed] identifiers, BEGIN...END blocks
  • SQLite -- all three identifier styles ("double", `backtick`, [bracket]), BEGIN...END blocks for triggers

All parsers handle standard SQL comments (--, /* */), quoted strings, and semicolon delimiters.

Installation

composer require nextras/multi-query-parser

Requires PHP 8.0+.

Usage

Parse a SQL file:

useNextras\MultiQueryParser\MySqlMultiQueryParser;
$parser = newMySqlMultiQueryParser();
foreach ($parser->parseFile('migrations.sql') as$query) {
$connection->query($query);
}

Parse a string:

$sql = "CREATE TABLE users (id INT); INSERT INTO users VALUES (1);";
foreach ($parser->parseString($sql) as$query) {
$connection->query($query);
}

Parse from a file stream:

$stream = fopen('migrations.sql', 'r');
foreach ($parser->parseFileStream($stream) as$query) {
$connection->query($query);
}

Available parsers: MySqlMultiQueryParser, PostgreSqlMultiQueryParser, SqlServerMultiQueryParser, SqliteMultiQueryParser.

Keep leading comments:

By default, comments are stripped and only query strings are yielded. To control what happens to comments, pass a CommentStrategy to the parser constructor. The bundled PrependLeadingComments strategy keeps the comments preceding a query as a prefix of that query -- useful when comments carry meaningful annotations, e.g. so they remain visible in observability tools:

useNextras\MultiQueryParser\Strategy\PrependLeadingComments;
$parser = newMySqlMultiQueryParser(newPrependLeadingComments());
$sql = "-- create the users table\nCREATE TABLE users (id INT);";
foreach ($parser->parseString($sql) as$query) {
echo$query; // "-- create the users table\nCREATE TABLE users (id INT)"
}

All comment styles supported by the given dialect (--, /* */, and # for MySQL) that directly precede a query are preserved with their original formatting; only pure leading whitespace is stripped. A comment that sits between two queries is treated as preceding the following one. Comments not followed by any query (e.g. a trailing comment at the end of input) are dropped.

License

MIT. See full license.

Releases

Used by

Contributors

Languages