Skip to content

Support DELIMITER syntax #1683

Open
Open
@Awk34

Description

@Awk34

Disclaimer: I don't know a whole lot of SQL

So my dev team decided that we wanted a Node script that could drop and re-create all of our stored procedures whenever something changes. The problem was that this library doesn't support the delimiter syntax. I made a kind of hacky way to split statements from my .sql (loaded to an in-memory string) file by custom delimiters into an array of separate statements.

Do you guys have a suggested way of working with something like this? How about suggestions for where to start for a PR?

Ex:

DELIMITER $$
DROP PROCEDURE IF EXISTS `Thing_Insert`$$
CREATE PROCEDURE `Thing_Insert`(
	argA int,
	argB nvarchar(50),
	argC nvarchar(50),
	argD datetime,
	argE bit)
BEGIN

	insert into Thing (A, B, C, D, E)
		select argA, argB, argC, argD, argE;

END$$
DELIMITER ;

...etc
/**
 * Separates individual SQL statements, split by a delimiter, into an array of statements
 * @param {String} text
 * @returns {String[]}
 */
function separateSqlCommands(text) {
    let lines = text.split('\n')
        .filter(str => {
            return str.length
                && !/^\n*$/.test(str);
        });

    let delimiter = ';';
    const DELIMITER_REGEX = /DELIMITER (.+)/;

    let statements = [];

    let accumulator = '';

    for(const line of lines) {
        let regexpResult = DELIMITER_REGEX.exec(line);
        if(regexpResult) {
            statements = statements.concat(accumulator.split(delimiter));

            accumulator = '';
            delimiter = regexpResult[1];
        } else {
            accumulator += line + ' ';
        }
    }

    statements = statements.filter(statement => !/^\s*$/.test(statement))
        .map(statement => {
            if(statement[0] === ' ') statement = statement.substr(1);

            return statement.replace(/\t/g, ' ')
                .replace(/ +/g, ' ');
        })
        .map(statement => statement.replace(/ +/g, ' '));

    return statements;
}

example output:

[ 'drop procedure `Thing_Insert`',
  'CREATE PROCEDURE `Thing_Insert`( argA int, argB nvarchar(50), argC nvarchar(50), argD datetime, argE bit) BEGIN insert into Thing (A, B, C, D, E) select argA, argB, argC, argD, argE; END' ]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions