From 0f7244e2959810e1182f4bdf64f958785536e748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Sun, 20 Mar 2016 17:41:05 +0300 Subject: [PATCH 01/10] fix README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9325106e..a7c8f53c 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ Basic usage: __Linux install:__ git clone date library, needed connectors, cmake and make install them. -create DDL files (like mysql: 'show create table MyDatabase.MyTable', but remove backticks), create headers for them with provided python script: +create DDL files (like mysql: 'show create table MyDatabase.MyTable'), create headers for them with provided python script: ``` %sqlpp11_dir%/scripts/ddl2cpp ~/temp/MyTable.ddl ~/temp/MyTable %DatabaseNamespaceForExample% ``` From dc9f03fb56955c6b35ae2d78e3add8f82cf6633a Mon Sep 17 00:00:00 2001 From: rbock Date: Sun, 20 Mar 2016 18:27:38 +0100 Subject: [PATCH 02/10] Added enum and set to be interpreted as text Maybe we will need a better mapping one fine day... --- scripts/ddl2cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 2b422078..65f50687 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -128,6 +128,8 @@ types = { 'date' : 'day_point', 'datetime' : 'time_point', 'timestamp' : 'time_point', + 'enum' : 'text', # MYSQL + 'set' : 'text', # MYSQL } From b7b651e98b068e64262b836f4ef742255a270856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Mon, 21 Mar 2016 21:38:37 +0300 Subject: [PATCH 03/10] readme/ddl2cpp KeyError handling --- README.md | 15 +++++++++++++-- scripts/ddl2cpp | 5 ++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a7c8f53c..03f6fc3f 100644 --- a/README.md +++ b/README.md @@ -138,11 +138,22 @@ Basic usage: __Linux install:__ git clone date library, needed connectors, cmake and make install them. -create DDL files (like mysql: 'show create table MyDatabase.MyTable'), create headers for them with provided python script: + +__Create DDL files__: +``` +mysql: 'show create table MyDatabase.MyTable' +mysqldump --no-data MyDatabase > MyDatabase.sql ca + +``` +Create headers for them with provided python script: ``` %sqlpp11_dir%/scripts/ddl2cpp ~/temp/MyTable.ddl ~/temp/MyTable %DatabaseNamespaceForExample% ``` -include generated header (MyTable.h), that's all +(In case you're getting notes about unsupported column type take a look at the other datatypes in sqlpp11/data_types. They are not hard to implement.) + +Include generated header (MyTable.h), that's all + + License: diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 2b422078..f558cebf 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -181,7 +181,10 @@ for create in tableCreations: print(' const T& operator()() const { return ' + columnMember + '; }', file=header) print(' };', file=header) print(' };', file=header) - traitslist = [NAMESPACE + '::' + types[sqlColumnType]]; + try: + traitslist = [NAMESPACE + '::' + types[sqlColumnType]]; + except KeyError as e: + print ('Error: datatype "' + sqlColumnType + '"" is not supported. Implement it (examples: sqlpp11/data_types) or raise an issue on github') requireInsert = True if column.hasAutoValue: traitslist.append(NAMESPACE + '::tag::must_not_insert'); From 0ed744d70ba740735fa455ad78b3c7e3ff287d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Mon, 21 Mar 2016 21:48:11 +0300 Subject: [PATCH 04/10] readme/ddl2cpp KeyError handling --- scripts/ddl2cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index f558cebf..22635f72 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -127,7 +127,7 @@ types = { 'float': 'floating_point', 'date' : 'day_point', 'datetime' : 'time_point', - 'timestamp' : 'time_point', + #'timestamp' : 'time_point', } @@ -154,6 +154,7 @@ for create in tableCreations: tableTemplateParameters = tableClass print(' namespace ' + tableNamespace, file=header) print(' {', file=header) + DataTypeError = False; for column in create.columns: if column.isConstraint: continue @@ -185,6 +186,7 @@ for create in tableCreations: traitslist = [NAMESPACE + '::' + types[sqlColumnType]]; except KeyError as e: print ('Error: datatype "' + sqlColumnType + '"" is not supported. Implement it (examples: sqlpp11/data_types) or raise an issue on github') + DataTypeError = True requireInsert = True if column.hasAutoValue: traitslist.append(NAMESPACE + '::tag::must_not_insert'); @@ -220,4 +222,6 @@ for create in tableCreations: print('}', file=header) print('#endif', file=header) - +if (DataTypeError): + print("Error: unsupported datatypes." ) + sys.exit(10) #return non-zero error code, we might need it for automation From 51f125e7637877c97e16fd301586507f85dc2de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Mon, 21 Mar 2016 22:02:41 +0300 Subject: [PATCH 05/10] readme/ddl2cpp KeyError handling --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 03f6fc3f..25c8bb2a 100644 --- a/README.md +++ b/README.md @@ -141,8 +141,8 @@ git clone date library, needed connectors, cmake and make install them. __Create DDL files__: ``` -mysql: 'show create table MyDatabase.MyTable' -mysqldump --no-data MyDatabase > MyDatabase.sql ca +mysql: 'show create table MyDatabase.MyTable' #or +mysqldump --no-data MyDatabase > MyDatabase.sql ``` Create headers for them with provided python script: From c43b8272ba5172b43be1c8798e03e31c1138c880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Mon, 21 Mar 2016 22:04:34 +0300 Subject: [PATCH 06/10] readme/ddl2cpp KeyError handling, merging --- scripts/ddl2cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 22635f72..370a6ba5 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -127,7 +127,7 @@ types = { 'float': 'floating_point', 'date' : 'day_point', 'datetime' : 'time_point', - #'timestamp' : 'time_point', + 'timestamp' : 'time_point', } From 64a122b64a49f4c8dfd8c1890a3fc83888e5a0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Tue, 22 Mar 2016 00:27:01 +0300 Subject: [PATCH 07/10] ddl2cpp solutions --- scripts/ddl2cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 370a6ba5..4c2d0b1c 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -127,7 +127,7 @@ types = { 'float': 'floating_point', 'date' : 'day_point', 'datetime' : 'time_point', - 'timestamp' : 'time_point', + #'timestamp' : 'time_point', } @@ -185,7 +185,7 @@ for create in tableCreations: try: traitslist = [NAMESPACE + '::' + types[sqlColumnType]]; except KeyError as e: - print ('Error: datatype "' + sqlColumnType + '"" is not supported. Implement it (examples: sqlpp11/data_types) or raise an issue on github') + print ('Error: datatype "' + sqlColumnType + '"" is not supported.') DataTypeError = True requireInsert = True if column.hasAutoValue: @@ -224,4 +224,8 @@ print('}', file=header) print('#endif', file=header) 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("C) Raise an issue on github" ) sys.exit(10) #return non-zero error code, we might need it for automation From 772109fc8720b596ebccbc4dbe79ce3534754a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Tue, 22 Mar 2016 00:28:06 +0300 Subject: [PATCH 08/10] ddl2cpp solutions --- scripts/ddl2cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index 4c2d0b1c..1da4e505 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -127,7 +127,7 @@ types = { 'float': 'floating_point', 'date' : 'day_point', 'datetime' : 'time_point', - #'timestamp' : 'time_point', + 'timestamp' : 'time_point', } From 6b7bdb1e62d890f61e9dccb4bd12ca0361b986b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdigitalist=2Eru=E2=80=9D?= <“strangeqargo@gmail.com”> Date: Sat, 26 Mar 2016 14:51:25 +0300 Subject: [PATCH 09/10] fix my mistake --- scripts/ddl2cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/ddl2cpp b/scripts/ddl2cpp index bddb6e12..c4d41584 100755 --- a/scripts/ddl2cpp +++ b/scripts/ddl2cpp @@ -147,7 +147,7 @@ print('#include <' + INCLUDE + '/char_sequence.h>', file=header) print('', file=header) print('namespace ' + namespace, file=header) print('{', file=header) - +DataTypeError = False; for create in tableCreations: sqlTableName = create.tableName tableClass = toClassName(sqlTableName) @@ -156,7 +156,6 @@ for create in tableCreations: tableTemplateParameters = tableClass print(' namespace ' + tableNamespace, file=header) print(' {', file=header) - DataTypeError = False; for column in create.columns: if column.isConstraint: continue From 5899dbf19abaf7b7a5a68194befe97bc154ad0de Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Fri, 8 Apr 2016 21:21:28 +0200 Subject: [PATCH 10/10] Create ChangeLog.md --- ChangeLog.md | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 ChangeLog.md diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 00000000..8aa06f0b --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,109 @@ +Important changes in sqlpp11 +============================ + +Breaking changes in 0.36: +------------------------- +__Abstract__: + +One of the main motivations of sqlpp11 is to prevent SQL programming mistakes at compile time. The following changes prevent reported mishaps. + * `from(a,b)` not allowed anymore, please use explicit joins + * `where(true)` not allowed anymore, please use `.unconditionally()` or sqlpp::value(true) + * `some_sql_expression and true` not allowed anymore, please use `tab.col == sqlpp::value(true)` if you really want to express this. + * `having(expression)` requires `expression` to be made of aggregates, e.g. columns named in `group_by()` or aggregate functions like `count()` or constant values. + * `where()` and `having` accept only one parameter + +__Explicit joins required__: + +Up until sqlpp11-0.35 you could write something like + +``` +auto result = db(select(all_of(a), all_of(b)) + .from(a,b) + .where(true)); +``` + +Using this syntax in `from()`, it was expected to have the join condition implicitly in the `where()` call. +But there is no reliable way to tell whether or not that condition is there. Or, if there definitely is none, whether +it was omitted on purpose or by accident. +In one case, an accidentally omitted join condition in the `where()` brought a production system to a screeching halt. + +In order to prevent this in the future, sqlpp11 now requires you to join table explicitly, including an explicit join condition, e.g. + +``` +auto result = db(select(all_of(a), all_of(b)) + .from(a.join(b).on(a.b == b.id)) + .where(true)); +``` + +Most joins, (`join`/`inner_join`, `left_outer_join`, `right_outer_join` and `outer_join`) require a join condition to given via `on()`. +The join condition has to be some sqlpp11 boolean expression. + +In those rare cases, when you really need a cross join, you can also use `cross_join()` which has no join condition, of course. + +``` +auto result = db(select(all_of(a), all_of(b)) + .from(a.cross_join(b)) + .where(true)); +``` + +__Use `.unconditionally()`__ + +If you want to select/update/remove all rows, earlier versions of sqlpp11 required the use of `where(true)`. Since version 0.36, use `unconditionally()`, for instance: +``` +auto result = db(select(all_of(t)).from(t).unconditionally()); +``` + +__Use `sqlpp::value()` to wrap bool values in boolean expressions__ + +Lets say you had + +``` +struct X +{ + int a; + int b; +}; +auto x = X{}; +``` + +Then earlier versions of sqlpp11 would compile the following expression: + +``` +select(all_of(t)).from(t).where(x.a == x.a or t.b == t.b); +``` + +What you probably meant was: + +``` +select(all_of(t)).from(t).where(t.a == x.a and t.b == x.b); +``` + +In order to prevent this kind of mistake, boolean operators in sql expressions require sqlpp boolean expressions as operators. +The library also requires the types of the left/right hand side operands of a comparison to be different, so that `t.a < t.a` does not compile any more. + +In the rare case you really have a bool value that you want to use a boolean sql expression, you have to wrap it in sqlpp::value(x), e.g. + +``` +select(all_of(t)).from(t).where(sqlpp::value(x.a == 17) and t.b == x.b); +``` + +__`having()` requires aggregate expressions__ + +In older versions, the following code was allowed: + +``` +select(all_of(t)).from(t).where(t.a > 7).having(t.b != ""); +``` + +As of sqlpp11-0.36, the having argument must be made of aggregate columns or functions, e.g. + +``` +select(all_of(t)).from(t).unconditionally().group_by(t.b).having(t.b != "", avg(t.c) < 42); +``` + +__`where()` and `having` accept only one expression__ + +In older versions, `where()` and `having()` would accept more than one argument and combine those arguments with `and`. +I am not sure this was ever used. So it just made life harder for the compiler. + +As of version 0.36, `where()` and `having()` accept only one parameter.