mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
argument parsing, fail on parsing
This commit is contained in:
parent
6b7bdb1e62
commit
42dfa6cddc
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea
|
134
scripts/ddl2cpp
134
scripts/ddl2cpp
@ -31,40 +31,28 @@ import re
|
||||
import os
|
||||
import pprint
|
||||
|
||||
# error codes, we should refactor this later
|
||||
ERROR_DATA_TYPE = 10
|
||||
ERROR_STRANGE_PARSING = 20
|
||||
|
||||
from pyparsing import CaselessLiteral, Literal, SkipTo, restOfLine, oneOf, ZeroOrMore, Optional, Combine, Suppress, \
|
||||
WordStart, WordEnd, Word, alphas, alphanums, nums, QuotedString, nestedExpr, MatchFirst, OneOrMore, delimitedList, Or, Group
|
||||
|
||||
def usage():
|
||||
print('Usage: ddl2cpp [-no-timestamp-warning] <path to ddl> <path to target (without extension, e.g. /tmp/MyTable)> <namespace>')
|
||||
|
||||
if len(sys.argv) not in (4,5):
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
firstPositional = 1
|
||||
timestampWarning = True
|
||||
if len(sys.argv) == 5:
|
||||
if sys.argv[1] == '-no-timestamp-warning':
|
||||
firstPositional += 1
|
||||
timestampWarning = False
|
||||
else:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
pathToDdl = sys.argv[firstPositional]
|
||||
pathToHeader = sys.argv[firstPositional + 1] + '.h'
|
||||
namespace = sys.argv[firstPositional + 2]
|
||||
|
||||
INCLUDE = 'sqlpp11'
|
||||
NAMESPACE = 'sqlpp'
|
||||
WordStart, WordEnd, Word, alphas, alphanums, nums, QuotedString, nestedExpr, MatchFirst, OneOrMore, delimitedList, Or, Group, ParseException
|
||||
|
||||
# HELPERS
|
||||
|
||||
def get_include_guard_name(namespace, inputfile):
|
||||
val = re.sub("[^A-Za-z]+", "_", namespace + '_' + os.path.basename(inputfile))
|
||||
return val.upper()
|
||||
|
||||
|
||||
def repl_func(m):
|
||||
if (m.group(1) == '_'):
|
||||
if m.group(1) == '_':
|
||||
return m.group(2).upper()
|
||||
else:
|
||||
return m.group(1) + m.group(2).upper()
|
||||
|
||||
def repl_func_for_args(m):
|
||||
if m.group(1) == '-':
|
||||
return m.group(2).upper()
|
||||
else:
|
||||
return m.group(1) + m.group(2).upper()
|
||||
@ -72,10 +60,61 @@ def repl_func(m):
|
||||
def toClassName(s):
|
||||
return re.sub("(^|\s|[_0-9])(\S)", repl_func, s)
|
||||
|
||||
|
||||
def toMemberName(s):
|
||||
return re.sub("(\s|_|[0-9])(\S)", repl_func, s)
|
||||
|
||||
|
||||
def setArgumentBool(s, bool_value):
|
||||
first_lower = lambda s: s[:1].lower() + s[1:] if s else '' # http://stackoverflow.com/a/3847369/5006740
|
||||
var_name = first_lower(re.sub("(\s|-|[0-9])(\S)", repl_func_for_args, s))
|
||||
globals()[var_name] = bool_value
|
||||
|
||||
|
||||
def usage():
|
||||
print('Usage: ddl2cpp [-no-timestamp-warning] <path to ddl> <path to target (without extension, e.g. /tmp/MyTable)> <namespace>')
|
||||
|
||||
# ARGUMENT PARSING
|
||||
if len(sys.argv) < (4):
|
||||
usage()
|
||||
sys.exit(20)
|
||||
|
||||
firstPositional = 1
|
||||
timestampWarning = True
|
||||
failOnParse = True
|
||||
|
||||
optionalArgs = {
|
||||
# if -some-key is present, it will set variable someKey to True
|
||||
# if -no-some-key is present, it will set variable someKey to False
|
||||
'timestamp-warning', # timeStampWarning = True
|
||||
# '-no-time-stamp-warning' # timeStampWarning = False
|
||||
'fail-on-parse' # failOnParse = True
|
||||
# 'no-fail-on-parse' # failOnParse = False
|
||||
|
||||
}
|
||||
|
||||
if len(sys.argv) >= 4:
|
||||
|
||||
for arg in sys.argv:
|
||||
noArg = arg.replace('-no-', '')
|
||||
|
||||
if arg in optionalArgs:
|
||||
setArgumentBool(arg, True)
|
||||
firstPositional += 1
|
||||
elif noArg in optionalArgs:
|
||||
setArgumentBool(noArg, False)
|
||||
firstPositional += 1
|
||||
|
||||
#sys.exit(0)
|
||||
pathToDdl = sys.argv[firstPositional]
|
||||
pathToHeader = sys.argv[firstPositional + 1] + '.h'
|
||||
namespace = sys.argv[firstPositional + 2]
|
||||
|
||||
INCLUDE = 'sqlpp11'
|
||||
NAMESPACE = 'sqlpp'
|
||||
|
||||
|
||||
|
||||
# PARSER
|
||||
def ddlWord(string):
|
||||
return WordStart(alphanums + "_") + CaselessLiteral(string) + WordEnd(alphanums + "_")
|
||||
@ -87,8 +126,8 @@ ddlTerm = Word(alphas, alphanums + "_$")
|
||||
ddlName = Or([ddlTerm, ddlString])
|
||||
ddlArguments = "(" + delimitedList(Or([ddlString, ddlTerm, ddlNum])) + ")"
|
||||
ddlNotNull = Group(ddlWord("NOT") + ddlWord("NULL")).setResultsName("notNull")
|
||||
ddlDefaultValue = ddlWord("DEFAULT").setResultsName("hasDefaultValue");
|
||||
ddlAutoValue = ddlWord("AUTO_INCREMENT").setResultsName("hasAutoValue");
|
||||
ddlDefaultValue = ddlWord("DEFAULT").setResultsName("hasDefaultValue")
|
||||
ddlAutoValue = ddlWord("AUTO_INCREMENT").setResultsName("hasAutoValue")
|
||||
ddlColumnComment = Group(ddlWord("COMMENT") + ddlString).setResultsName("comment")
|
||||
ddlConstraint = Or([
|
||||
ddlWord("CONSTRAINT"),
|
||||
@ -98,14 +137,6 @@ ddlConstraint = Or([
|
||||
ddlWord("INDEX"),
|
||||
ddlWord("UNIQUE"),
|
||||
])
|
||||
ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments])))
|
||||
createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlName.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create")
|
||||
|
||||
|
||||
ddl = ZeroOrMore(Suppress(SkipTo(createTable, False)) + createTable)
|
||||
|
||||
ddlComment = oneOf(["--", "#"]) + restOfLine
|
||||
ddl.ignore(ddlComment)
|
||||
|
||||
# MAP SQL TYPES
|
||||
types = {
|
||||
@ -132,9 +163,26 @@ types = {
|
||||
'set': 'text', # MYSQL
|
||||
}
|
||||
|
||||
ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments])))
|
||||
createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlName.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create")
|
||||
ddlComment = oneOf(["--", "#"]) + restOfLine
|
||||
|
||||
if failOnParse:
|
||||
ddl = OneOrMore(Suppress(SkipTo(createTable, False)) + createTable)
|
||||
ddl.ignore(ddlComment)
|
||||
try:
|
||||
tableCreations = ddl.parseFile(pathToDdl)
|
||||
except ParseException as e:
|
||||
print("parsing error, possible reason: can't parse default value for a field")
|
||||
sys.exit()
|
||||
else:
|
||||
ddl = ZeroOrMore(Suppress(SkipTo(createTable, False)) + createTable)
|
||||
ddl.ignore(ddlComment)
|
||||
tableCreations = ddl.parseFile(pathToDdl)
|
||||
|
||||
# PROCESS DDL
|
||||
tableCreations = ddl.parseFile(pathToDdl)
|
||||
|
||||
|
||||
|
||||
header = open(pathToHeader, 'w')
|
||||
print('// generated by ' + ' '.join(sys.argv), file=header)
|
||||
@ -147,7 +195,7 @@ print('#include <' + INCLUDE + '/char_sequence.h>', file=header)
|
||||
print('', file=header)
|
||||
print('namespace ' + namespace, file=header)
|
||||
print('{', file=header)
|
||||
DataTypeError = False;
|
||||
DataTypeError = False
|
||||
for create in tableCreations:
|
||||
sqlTableName = create.tableName
|
||||
tableClass = toClassName(sqlTableName)
|
||||
@ -184,22 +232,22 @@ for create in tableCreations:
|
||||
print(' };', file=header)
|
||||
print(' };', file=header)
|
||||
try:
|
||||
traitslist = [NAMESPACE + '::' + types[sqlColumnType]];
|
||||
traitslist = [NAMESPACE + '::' + types[sqlColumnType]]
|
||||
except KeyError as e:
|
||||
print ('Error: datatype "' + sqlColumnType + '"" is not supported.')
|
||||
DataTypeError = True
|
||||
requireInsert = True
|
||||
if column.hasAutoValue:
|
||||
traitslist.append(NAMESPACE + '::tag::must_not_insert');
|
||||
traitslist.append(NAMESPACE + '::tag::must_not_update');
|
||||
traitslist.append(NAMESPACE + '::tag::must_not_insert')
|
||||
traitslist.append(NAMESPACE + '::tag::must_not_update')
|
||||
requireInsert = False
|
||||
if not column.notNull:
|
||||
traitslist.append(NAMESPACE + '::tag::can_be_null');
|
||||
traitslist.append(NAMESPACE + '::tag::can_be_null')
|
||||
requireInsert = False
|
||||
if column.hasDefaultValue:
|
||||
requireInsert = False
|
||||
if requireInsert:
|
||||
traitslist.append(NAMESPACE + '::tag::require_insert');
|
||||
traitslist.append(NAMESPACE + '::tag::require_insert')
|
||||
print(' using _traits = ' + NAMESPACE + '::make_traits<' + ', '.join(traitslist) + '>;', file=header)
|
||||
print(' };', file=header)
|
||||
print(' }', file=header)
|
||||
|
Loading…
Reference in New Issue
Block a user