/**
 * Executes a SQL command with placeholders, parsing the plain-text delimited result into an array of arrays.
 */
import Evaluate from "./evaluate";

function ExecuteSql(sql: string, ...bindings: any[]): Promise<string[][]> {
	const p = bindings.map((o) => ' ; ' + JSON.stringify(o)).join('');
	const colDelim = '|' + Math.random() + '|';
	const rowDelim = '~' + Math.random() + '~';
	return Evaluate('ExecuteSQL(' + JSON.stringify(sql) + ' ; "' + colDelim + '" ; "' + rowDelim + '"' + p + ' )', {}, {alwaysReturnString: true})
		.then((rawData:string) => {
			return rawData.length === 0 ? [] : rawData.split(rowDelim).map((r) => r.split(colDelim));
		});

}



/**
 * Convenience method for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">template-literal</a>
 * SQL queries with inline-style parameters, but still escaping user input. <br>
 * For example, to find Bobby Tables:
 * <pre>
 *     let q = ';drop table students';
 *     let resultSet = fmPromise.executeSqlTemplate`select * from students where name=${q}`
 * </pre>
 * @return {Promise<String[][]>}
 */
function ExecuteSqlTemplate(strings:string[], ...args:string[]): Promise<string[][]> {
	if ( !Array.isArray(strings) || args.length !== strings.length-1) {
		throw new FMPromiseError({code:-1,message:'Invalid template literal for executeSqlTemplate'})
	}
	return ExecuteSql(strings.join('?'), args);
}

export {ExecuteSql,ExecuteSqlTemplate};
