From e271e3e4fb86419c06dbe0d33dfc3aef2b23cc1a Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Sun, 24 Apr 2016 17:36:36 +0200 Subject: [PATCH 1/5] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ed9c3a23..bf637473 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ sqlpp11 requires a certain api in order to connect with the database, see databa * MySQL: https://github.com/rbock/sqlpp11-connector-mysql * Sqlite3: https://github.com/rbock/sqlpp11-connector-sqlite3 * PostgreSQL: https://github.com/matthijs/sqlpp11-connector-postgresql + * ODBC: https://github.com/Erroneous1/sqlpp11-connector-odbc (experimental) To demonstrate that sqlpp11 can work with other backends as well, here is an experimental backend for structs in standard containers: From f32dd7a65c6e1da6a5e50784cb78e964724ebb56 Mon Sep 17 00:00:00 2001 From: strangeqargo <“strangeqargo@gmail.com”> Date: Tue, 3 May 2016 15:42:02 +0300 Subject: [PATCH 2/5] -m --- scripts/ddl2cpp | 79 ++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index c4d41584..87fccc4f 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -34,10 +34,12 @@ import pprint 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] ') -if len(sys.argv) not in (4,5): +def usage(): + print('Usage: ddl2cpp [-no-timestamp-warning] \ + ') + +if len(sys.argv) not in (4, 5): usage() sys.exit(1) @@ -63,16 +65,19 @@ 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 toClassName(s): + +def to_class_name(s): return re.sub("(^|\s|[_0-9])(\S)", repl_func, s) -def toMemberName(s): + +def to_member_name(s): return re.sub("(\s|_|[0-9])(\S)", repl_func, s) @@ -80,16 +85,19 @@ def toMemberName(s): def ddlWord(string): return WordStart(alphanums + "_") + CaselessLiteral(string) + WordEnd(alphanums + "_") -ddlString = Or([QuotedString("'"), QuotedString("\"", escQuote='""'), QuotedString("`")]) +def ddlFunctionWord(string): + return CaselessLiteral(string) + OneOrMore("(") + ZeroOrMore(" ") + OneOrMore(")") + +ddlString = Or([QuotedString("'"), QuotedString("\"", escQuote='""'), QuotedString("`")]) negativeSign = Literal('-') -ddlNum = Combine(Optional(negativeSign) + Word(nums + ".")) -ddlTerm = Word(alphas, alphanums + "_$") -ddlName = Or([ddlTerm, ddlString]) +ddlNum = Combine(Optional(negativeSign) + Word(nums + ".")) +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"); -ddlColumnComment = Group(ddlWord("COMMENT") + ddlString).setResultsName("comment") +ddlDefaultValue = ddlWord("DEFAULT").setResultsName("hasDefaultValue") +ddlAutoValue = ddlWord("AUTO_INCREMENT").setResultsName("hasAutoValue") +ddlColumnComment = Group(ddlWord("COMMENT") + ddlString).setResultsName("comment") ddlConstraint = Or([ ddlWord("CONSTRAINT"), ddlWord("PRIMARY"), @@ -98,7 +106,9 @@ ddlConstraint = Or([ ddlWord("INDEX"), ddlWord("UNIQUE"), ]) -ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments]))) +ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst( + [ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlFunctionWord("NOW"), ddlTerm, ddlNum, ddlColumnComment, ddlString, + ddlArguments]))) createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlName.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create") @@ -125,12 +135,12 @@ types = { 'boolean': 'boolean', 'double': 'floating_point', 'float': 'floating_point', - 'date' : 'day_point', - 'datetime' : 'time_point', - 'timestamp' : 'time_point', - 'enum' : 'text', # MYSQL - 'set' : 'text', # MYSQL - } + 'date': 'day_point', + 'datetime': 'time_point', + 'timestamp': 'time_point', + 'enum': 'text', # MYSQL + 'set': 'text', # MYSQL +} # PROCESS DDL @@ -147,11 +157,11 @@ 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) - tableMember = toMemberName(sqlTableName) + tableClass = to_class_name(sqlTableName) + tableMember = to_member_name(sqlTableName) tableNamespace = tableClass + '_' tableTemplateParameters = tableClass print(' namespace ' + tableNamespace, file=header) @@ -160,9 +170,9 @@ for create in tableCreations: if column.isConstraint: continue sqlColumnName = column[0] - columnClass = toClassName(sqlColumnName) + columnClass = to_class_name(sqlColumnName) tableTemplateParameters += ',\n ' + tableNamespace + '::' + columnClass - columnMember = toMemberName(sqlColumnName) + columnMember = to_member_name(sqlColumnName) sqlColumnType = column[1].lower() if sqlColumnType == 'timestamp' and timestampWarning: print("Warning: timestamp is mapped to sqlpp::time_point like datetime") @@ -184,22 +194,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) @@ -223,10 +233,11 @@ for create in tableCreations: print('}', file=header) print('#endif', file=header) -if (DataTypeError): +if DataTypeError: print("Error: unsupported datatypes." ) print("Possible solutions:") - print("A) Implement this datatype (examples: sqlpp11/data_types)" ) - print("B) Extend/upgrade ddl2cpp (edit types map)" ) + print("A) Implement this datatype (examples: sqlpp11/data_types)") + print("B) Extend/upgrade ddl2cpp (edit types map)") print("C) Raise an issue on github" ) - sys.exit(10) #return non-zero error code, we might need it for automation + sys.exit(10) # return non-zero error code, we might need it for automation + From 94945cc9502599f7896a1701666c1d8601207a92 Mon Sep 17 00:00:00 2001 From: strangeqargo <“strangeqargo@gmail.com”> Date: Tue, 3 May 2016 15:42:02 +0300 Subject: [PATCH 3/5] ddl2cpp mysql now() support, minor PEP-8 edits --- scripts/ddl2cpp | 79 ++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index c4d41584..87fccc4f 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -34,10 +34,12 @@ import pprint 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] ') -if len(sys.argv) not in (4,5): +def usage(): + print('Usage: ddl2cpp [-no-timestamp-warning] \ + ') + +if len(sys.argv) not in (4, 5): usage() sys.exit(1) @@ -63,16 +65,19 @@ 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 toClassName(s): + +def to_class_name(s): return re.sub("(^|\s|[_0-9])(\S)", repl_func, s) -def toMemberName(s): + +def to_member_name(s): return re.sub("(\s|_|[0-9])(\S)", repl_func, s) @@ -80,16 +85,19 @@ def toMemberName(s): def ddlWord(string): return WordStart(alphanums + "_") + CaselessLiteral(string) + WordEnd(alphanums + "_") -ddlString = Or([QuotedString("'"), QuotedString("\"", escQuote='""'), QuotedString("`")]) +def ddlFunctionWord(string): + return CaselessLiteral(string) + OneOrMore("(") + ZeroOrMore(" ") + OneOrMore(")") + +ddlString = Or([QuotedString("'"), QuotedString("\"", escQuote='""'), QuotedString("`")]) negativeSign = Literal('-') -ddlNum = Combine(Optional(negativeSign) + Word(nums + ".")) -ddlTerm = Word(alphas, alphanums + "_$") -ddlName = Or([ddlTerm, ddlString]) +ddlNum = Combine(Optional(negativeSign) + Word(nums + ".")) +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"); -ddlColumnComment = Group(ddlWord("COMMENT") + ddlString).setResultsName("comment") +ddlDefaultValue = ddlWord("DEFAULT").setResultsName("hasDefaultValue") +ddlAutoValue = ddlWord("AUTO_INCREMENT").setResultsName("hasAutoValue") +ddlColumnComment = Group(ddlWord("COMMENT") + ddlString).setResultsName("comment") ddlConstraint = Or([ ddlWord("CONSTRAINT"), ddlWord("PRIMARY"), @@ -98,7 +106,9 @@ ddlConstraint = Or([ ddlWord("INDEX"), ddlWord("UNIQUE"), ]) -ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments]))) +ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst( + [ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlFunctionWord("NOW"), ddlTerm, ddlNum, ddlColumnComment, ddlString, + ddlArguments]))) createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlName.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create") @@ -125,12 +135,12 @@ types = { 'boolean': 'boolean', 'double': 'floating_point', 'float': 'floating_point', - 'date' : 'day_point', - 'datetime' : 'time_point', - 'timestamp' : 'time_point', - 'enum' : 'text', # MYSQL - 'set' : 'text', # MYSQL - } + 'date': 'day_point', + 'datetime': 'time_point', + 'timestamp': 'time_point', + 'enum': 'text', # MYSQL + 'set': 'text', # MYSQL +} # PROCESS DDL @@ -147,11 +157,11 @@ 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) - tableMember = toMemberName(sqlTableName) + tableClass = to_class_name(sqlTableName) + tableMember = to_member_name(sqlTableName) tableNamespace = tableClass + '_' tableTemplateParameters = tableClass print(' namespace ' + tableNamespace, file=header) @@ -160,9 +170,9 @@ for create in tableCreations: if column.isConstraint: continue sqlColumnName = column[0] - columnClass = toClassName(sqlColumnName) + columnClass = to_class_name(sqlColumnName) tableTemplateParameters += ',\n ' + tableNamespace + '::' + columnClass - columnMember = toMemberName(sqlColumnName) + columnMember = to_member_name(sqlColumnName) sqlColumnType = column[1].lower() if sqlColumnType == 'timestamp' and timestampWarning: print("Warning: timestamp is mapped to sqlpp::time_point like datetime") @@ -184,22 +194,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) @@ -223,10 +233,11 @@ for create in tableCreations: print('}', file=header) print('#endif', file=header) -if (DataTypeError): +if DataTypeError: print("Error: unsupported datatypes." ) print("Possible solutions:") - print("A) Implement this datatype (examples: sqlpp11/data_types)" ) - print("B) Extend/upgrade ddl2cpp (edit types map)" ) + print("A) Implement this datatype (examples: sqlpp11/data_types)") + print("B) Extend/upgrade ddl2cpp (edit types map)") print("C) Raise an issue on github" ) - sys.exit(10) #return non-zero error code, we might need it for automation + sys.exit(10) # return non-zero error code, we might need it for automation + From f0d2bf6189bea5f96262a8ce9ba2b616e1cff363 Mon Sep 17 00:00:00 2001 From: strangeqargo <“strangeqargo@gmail.com”> Date: Tue, 3 May 2016 15:49:42 +0300 Subject: [PATCH 4/5] ddl2cpp mysql now(). Too many commits. --- scripts/ddl2cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index c4d41584..c0f973dc 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -80,6 +80,9 @@ def toMemberName(s): def ddlWord(string): return WordStart(alphanums + "_") + CaselessLiteral(string) + WordEnd(alphanums + "_") +def ddlFunctionWord(string): + return CaselessLiteral(string) + OneOrMore("(") + ZeroOrMore(" ") + OneOrMore(")") + ddlString = Or([QuotedString("'"), QuotedString("\"", escQuote='""'), QuotedString("`")]) negativeSign = Literal('-') ddlNum = Combine(Optional(negativeSign) + Word(nums + ".")) @@ -98,7 +101,7 @@ ddlConstraint = Or([ ddlWord("INDEX"), ddlWord("UNIQUE"), ]) -ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments]))) +ddlColumn = Group(Optional(ddlConstraint).setResultsName("isConstraint") + OneOrMore(MatchFirst([ddlNotNull, ddlAutoValue, ddlDefaultValue, ddlFunctionWord("NOW"), ddlTerm, ddlNum, ddlColumnComment, ddlString, ddlArguments]))) createTable = Group(ddlWord("CREATE") + ddlWord("TABLE") + ddlName.setResultsName("tableName") + "(" + Group(delimitedList(ddlColumn)).setResultsName("columns") + ")").setResultsName("create") From 101a02e9e8df68044997416ca335821674ac2c1f Mon Sep 17 00:00:00 2001 From: strangeqargo <“strangeqargo@gmail.com”> Date: Wed, 4 May 2016 23:13:17 +0300 Subject: [PATCH 5/5] adding comment --- scripts/ddl2cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index c0f973dc..7810fa70 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -80,6 +80,8 @@ def toMemberName(s): def ddlWord(string): return WordStart(alphanums + "_") + CaselessLiteral(string) + WordEnd(alphanums + "_") +# This function should be refactored if we find some database function which needs parameters +# Right now it works only for something like NOW() in MySQL default field value def ddlFunctionWord(string): return CaselessLiteral(string) + OneOrMore("(") + ZeroOrMore(" ") + OneOrMore(")")