From 078754467e632be61c3fceee1d8290ec5ffb0884 Mon Sep 17 00:00:00 2001 From: Colin Dellow Date: Sun, 18 Mar 2018 14:28:31 -0400 Subject: [PATCH] Generate queries from templates Huzzah, a bunch of failures have appeared. --- .gitignore | 1 + tests/create-queries-from-templates | 65 +++++++++++++++++++++++++ tests/{create-query => create-template} | 0 3 files changed, 66 insertions(+) create mode 100755 tests/create-queries-from-templates rename tests/{create-query => create-template} (100%) diff --git a/.gitignore b/.gitignore index fcac65d..67af04b 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ /testcase-expected.txt /testcase-cmds.txt /testcases.txt +tests/queries diff --git a/tests/create-queries-from-templates b/tests/create-queries-from-templates new file mode 100755 index 0000000..f4f64d7 --- /dev/null +++ b/tests/create-queries-from-templates @@ -0,0 +1,65 @@ +#!/usr/bin/python3 + +import os.path +from os import makedirs +from glob import glob +import re +import itertools + +NULL_TOKENS = ['nulls1', 'nulls2', 'nulls3'] +NO_NULL_TOKENS = ['no_nulls1', 'no_nulls2', 'no_nulls3'] + +TOKEN_SET = NULL_TOKENS + NO_NULL_TOKENS + +def extract_tokens(line): + line = re.sub('[^a-zA-Z0-9_]', ' ', line).split(' ') + return list(set([token for token in line if token in TOKEN_SET])) + +def main(template_dir, query_dir): + try: + makedirs(query_dir) + except: + pass + + for f in glob(os.path.join(query_dir, '*')): + os.remove(f) + + for f in glob(os.path.join(template_dir, '*.sql')): + basename = os.path.basename(f) + + with open(f, 'r') as fptr: + content = fptr.readlines() + + # Sort tokens longest first so string replace will replace no_nullsX before nullsX + # (irrelevant ATM, but maybe useful later) + tokens = sorted(extract_tokens(content[0]), key=lambda x: -len(x)) + if not tokens: + raise ValueError('{} had no tokens'.format(content[0])) + + # For simplicity, we don't support mixing nulls and no_nulls + if not all(len(token) == len(tokens[0]) for token in tokens): + raise ValueError('cannot mix nulls and no_nulls: {}'.format(content[0])) + + + template = content[0] + for token in tokens: + template = template.replace(token, token.upper()) + + replacements = NULL_TOKENS + if tokens[0].startswith('no'): + replacements = NO_NULL_TOKENS + + for variant, choices in enumerate(itertools.combinations_with_replacement(replacements, len(tokens))): + query = template + for idx, token in enumerate(tokens): + query = query.replace(token.upper(), choices[idx]) + fname = basename.replace('.sql', '-{}.sql'.format(variant)) + + with open(os.path.join(query_dir, fname), 'w') as fptr: + content[0] = query + fptr.write(''.join(content)) + +if __name__ == '__main__': + template_dir = os.path.abspath(os.path.join(__file__, '..', 'templates')) + query_dir = os.path.abspath(os.path.join(__file__, '..', 'queries')) + main(template_dir, query_dir) diff --git a/tests/create-query b/tests/create-template similarity index 100% rename from tests/create-query rename to tests/create-template