Created
January 31, 2011 18:42
-
-
Save finsterthecat/804548 to your computer and use it in GitHub Desktop.
Drops certain options and qualifiers from create table statements. Could this be any more complicated?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re, sys, getopt | |
from collections import deque | |
DEFAULT_STATEMENT_TERMINATOR = ';' | |
OPTION_PATTERN = re.compile('''^--<ScriptOptions (.*)/>''', re.I) | |
TERM_OPTION_PATTERN = re.compile('''^--<ScriptOptions.*statementTerminator="(.*)"/>''', re.I) | |
TERM_OPTION = '''--<ScriptOptions statementTerminator="%s"/>''' | |
LOGGING_PATTERN = re.compile('''(.*)^\s+LOGGING\s*$(.*)''', re.I + re.S + re.M) | |
PCTFREE_PATTERN = re.compile('''(.*)^\s+PCTFREE\s+\d+$(.*)''', re.I + re.S + re.M) | |
PCTUSED_PATTERN = re.compile('''(.*)^\s+PCTUSED\s+\d+$(.*)''', re.I + re.S + re.M) | |
STORAGE_PATTERN = re.compile('''(.*)^\s+STORAGE\s*\(.*?\)\s*$(.*)''', re.I + re.S + re.M) | |
class DDL: | |
def __init__(self, source, term=DEFAULT_STATEMENT_TERMINATOR): | |
self.source = source | |
self.options = [] | |
self.term = term | |
self.ddlterm = None | |
self.__ahead = deque() | |
self.__read_options() | |
def __read_options(self): | |
while True: | |
line = self.source.next() | |
if line: | |
if not OPTION_PATTERN.match(line.strip()): | |
self.__ahead.append(line) | |
return | |
else: | |
line = line.strip() | |
term = TERM_OPTION_PATTERN.match(line) | |
if term: self.term = self.ddlterm = term.group(1) | |
else: self.options.append(line) | |
def __iter__(self): | |
return self | |
def next(self): | |
stmt = '' | |
while True: | |
try: | |
if self.__ahead: line = self.__ahead.popleft() | |
else: line = self.source.next() | |
_line = line.rstrip() | |
if _line and _line[-1] == self.term: | |
stmt += _line[0:-1] | |
return stmt | |
else: stmt += line | |
except StopIteration: | |
if stmt.strip(): return stmt | |
else: raise StopIteration | |
def process_ddl(ifile, ofile, patterns, term=DEFAULT_STATEMENT_TERMINATOR, newterm=None): | |
ddl = DDL(ifile, term) | |
if ddl.ddlterm: | |
term = ddl.ddlterm | |
if not newterm: newterm = term | |
if ddl.ddlterm: print >> ofile, TERM_OPTION % newterm | |
for option in ddl.options: | |
print >> ofile, option | |
for stmt in ddl: | |
for pattern in patterns: | |
match = pattern.match(stmt) | |
if match: stmt = match.group(1).rstrip() + match.group(2).rstrip() | |
print >> ofile, '%s%s' % (stmt, newterm) | |
HELP = '''\ | |
DDL Post-Processing Tool v1.0 | |
Usage: ppddl [OPTIONS] <input DDL file> <output DDL file> | |
OPTIONS: | |
--all suppresses all qualifiers | |
("LOGGING", "PCTFREE", "PCTUSED", "STORAGE") | |
--logging suppresses "LOGGING" qualifiers | |
--pctfree suppresses "PCTFREE" qualifiers | |
--pctused suppresses "PCTUSED" qualifiers | |
--storage suppresses "STORAGE" qualifiers | |
--term=TERM specifies statement terminator character. | |
If terminator is not specified "ScriptOptions" headers | |
of input DDL script will be used to detect it. | |
If appropriate "ScriptOptions" header is not present | |
";" will be used | |
--new-term=TERM specifies new statement terminator character | |
to replace existing. | |
EXAMPLES: | |
Read "script.ddl" file, auto-detect statement terminator, | |
suppress all qualifiers, write the result to "new-script.ddl" | |
ppddl --all script.ddl new-script.ddl | |
Read "script.ddl" file, use "!" as a statement terminator, | |
suppress all qualifiers, write the result to "new-script.ddl" | |
ppddl --all --term="!" script.ddl new-script.ddl | |
Read "script.ddl" file, auto-detect statement terminator, | |
suppress "STORAGE" and "LOGGING" qualifiers, | |
write the result to "new-script.ddl" | |
using ";" as a statement terminator | |
ppddl --storage --logging --new-term=";" script.ddl new-script.ddl | |
''' | |
def report_help(): | |
print HELP | |
sys.exit(0) | |
USAGE = '''\ | |
DDL Post-Processing Tool v1.0 | |
Usage: ppddl [OPTIONS] <input DDL file> <output DDL file> | |
Try "ppddl --help" for more options. | |
''' | |
def report_usage_error(error): | |
print error | |
print USAGE | |
sys.exit(2) | |
def init(options): | |
try: | |
opts, args = getopt.getopt(options, '', ['help', 'all', 'logging', 'pctfree', 'pctused', 'storage', 'term=', 'new-term=']) | |
except getopt.GetoptError, err: | |
report_usage_error(str(err)) | |
patterns = [] | |
term = DEFAULT_STATEMENT_TERMINATOR | |
newterm = None | |
for opt, value in opts: | |
if opt == "--help": report_help() | |
elif opt == '--all': patterns.extend([LOGGING_PATTERN, PCTFREE_PATTERN, PCTUSED_PATTERN, STORAGE_PATTERN]) | |
elif opt == '--logging': patterns.append(LOGGING_PATTERN) | |
elif opt == '--pctfree': patterns.append(PCTFREE_PATTERN) | |
elif opt == '--pctused': patterns.append(PCTUSED_PATTERN) | |
elif opt == '--storage': patterns.append(STORAGE_PATTERN) | |
elif opt == '--term': term = value | |
elif opt == '--new-term': newterm = value | |
else: | |
report_usage_error("Unknown option : '%s'" % opt) | |
if len(args) != 2: | |
report_usage_error("Two arguments are required: input DDL and output DDL files") | |
if not patterns: | |
patterns.extend([LOGGING_PATTERN, PCTFREE_PATTERN, PCTUSED_PATTERN, STORAGE_PATTERN]) | |
return args[0], args[1], patterns, term, newterm | |
if __name__ == '__main__': | |
ifile, ofile, patterns, term, newterm = init(sys.argv[1:]) | |
ifile, ofile = open(ifile, 'r'), open(ofile, 'w') | |
try: | |
process_ddl(ifile, ofile, patterns, term, newterm) | |
finally: | |
ifile.close() | |
ofile.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment