Re: [boost] SQL: next iteration of sqlpp11
On 2014-02-03 16:03, Roland Bock wrote: In most usecases I encountered so far, it is totally OK to interpret NULL values like default values, e.g. NULL strings and empty strings, or NULL foreign keys or 0LL. For those usecases it would be quite annoying to have to check if there really is a value, or always use get_optional_value_or...
Hi Roland, while I can very well imagine that these "use-cases" exist, I would not like the library to make this the default. I think using boost::optional is the canonical solution that is also impossible to misinterpret. Treating non-existent values the same as default-initialized values seems error-prone if not wrong in general. The library should not prevent me from treating string "" differently from NULL, which currently it does. On the other hand, if the library did return optionals, implementing the behaviour you describe on top of it is trivial: boost::optional<T> t; t.get_value_or( T() ); If it helps my argument, both Scala Anorm and Scala Slick represent nullable columns as optional types: http://www.playframework.com/documentation/2.0/ScalaAnorm http://slick.typesafe.com/doc/2.0.0/schemas.html Regards Sebastian PS: I hope to look at your library in more detail in the coming weeks and I am really looking forward to that. Great work so far. -- Dr. Sebastian Theophil | stheophil@think-cell.com Senior Software Engineer think-cell Sales GmbH & Co. KG | Chausseestr. 8/E | 10115 Berlin | Germany http://www.think-cell.com | phone +49 30 666473-10 | US phone +1 800 891 8091 Amtsgericht Berlin-Charlottenburg, HRA 44531 | European Union VAT Id DE815233792 General partner: think-cell Operations GmbH | Amtsgericht Berlin-Charlottenburg HRB 129917 Directors: Dr. Markus Hannebauer, Dr. Arno Sch?dl
On 2014-02-04 10:40, Sebastian Theophil wrote:
On 2014-02-03 16:03, Roland Bock wrote: In most usecases I encountered so far, it is totally OK to interpret NULL values like default values, e.g. NULL strings and empty strings, or NULL foreign keys or 0LL. For those usecases it would be quite annoying to have to check if there really is a value, or always use get_optional_value_or... Hi Roland,
while I can very well imagine that these "use-cases" exist, I would not like the library to make this the default. I think using boost::optional is the canonical solution that is also impossible to misinterpret. As stated in other replies, please take a look here:
https://github.com/rbock/sqlpp11/wiki/NULL I think this comes pretty close to what you and several others prefer, without adding too much noise in my case.
Treating non-existent values the same as default-initialized values seems error-prone if not wrong in general. The library should not prevent me from treating string "" differently from NULL, which currently it does.
Well, it does not /prevent/ you from differentiating between NULL and "". It currently does not /force/ you to treat them differently. But as stated above, I am willing to change that.
On the other hand, if the library did return optionals, implementing the behaviour you describe on top of it is trivial:
boost::optional<T> t; t.get_value_or( T() );
If it helps my argument, both Scala Anorm and Scala Slick represent nullable columns as optional types:
http://www.playframework.com/documentation/2.0/ScalaAnorm http://slick.typesafe.com/doc/2.0.0/schemas.html Got that :-) Regards Sebastian
PS: I hope to look at your library in more detail in the coming weeks and I am really looking forward to that. Great work so far.
Thanks! I am looking forward to your future comments, bug reports, etc. Regards from Munich, Roland
On 04-02-2014 10:40, Sebastian Theophil wrote:
On 2014-02-03 16:03, Roland Bock wrote: In most usecases I encountered so far, it is totally OK to interpret NULL values like default values, e.g. NULL strings and empty strings, or NULL foreign keys or 0LL. For those usecases it would be quite annoying to have to check if there really is a value, or always use get_optional_value_or...
Hi Roland,
while I can very well imagine that these "use-cases" exist, I would not like the library to make this the default. I think using boost::optional is the canonical solution that is also impossible to misinterpret.
+ 1. -Thorsten
On Tue, Feb 4, 2014 at 7:40 AM, Sebastian Theophil wrote: using boost::optional is the canonical solution that is also impossible to
misinterpret. +1
This is the solution that the competing library SOCI uses [1].
Regards,
Rodrigo Madera
[1] http://soci.sourceforge.net/doc/3.2/boost.html
On 4 February 2014 17:46, Rodrigo Madera
On Tue, Feb 4, 2014 at 7:40 AM, Sebastian Theophil
wrote:
using boost::optional is the canonical solution that is also impossible to misinterpret.
+1
This is the solution that the competing library SOCI uses [1].
Regards, Rodrigo Madera
I'd suggest to not to consider the two as competing libraries, but rather complementing. Please, refer to Roland's comparison [1] w/ major difference outlined "sqlpp11 assumes that you know your tables at compile time" In fact, there is room for some collaboration [2] "option would be to write a sqlpp11 connector library for SOCI" [1] http://lists.boost.org/Archives/boost/2013/11/208391.php [2] http://lists.boost.org/Archives/boost/2013/11/208394.php Best regards, -- Mateusz Łoskot, http://mateusz.loskot.net
On Tue, Feb 4, 2014 at 6:11 PM, Mateusz Łoskot
I'd suggest to not to consider the two as competing libraries, but rather complementing.
I agree. I just thought of SOCI as a library that has already solved that problem. Thinking about it, I agree that they can complement each other. Since sqlpp11 enforces compile time syntax it could help catch subtle errors very early.
In fact, there is room for some collaboration [2] "option would be to write a sqlpp11 connector library for SOCI"
The idea that it could build on SOCI would make it faster to develop and quite more stable, IMHO. It would give "instant support" for all SOCI backends. Roland, What are your thoughts on this? Regards, Rodrigo Madera
On 2014-02-04 21:25, Rodrigo Madera wrote:
On Tue, Feb 4, 2014 at 6:11 PM, Mateusz Łoskot
wrote: I'd suggest to not to consider the two as competing libraries, but rather complementing.
I agree. I just thought of SOCI as a library that has already solved that problem. Thinking about it, I agree that they can complement each other.
Since sqlpp11 enforces compile time syntax it could help catch subtle errors very early.
In fact, there is room for some collaboration [2] "option would be to write a sqlpp11 connector library for SOCI"
The idea that it could build on SOCI would make it faster to develop and quite more stable, IMHO. It would give "instant support" for all SOCI backends.
Roland, What are your thoughts on this?
Regards, Rodrigo Madera
Mateusz and I exchanged a few mails. The consensus is that it is a very good idea and we want to do it. The main issue is time. We just don't have enough of it. So if you (or others) have time on your hands and are interest in this topic, why not write a SOCI connector for sqlpp11? A first version could probably be written without touching either sqlpp11 or SOCI. Cheers, Roland
On 4 February 2014 20:57, Roland Bock
On 2014-02-04 21:25, Rodrigo Madera wrote:
On Tue, Feb 4, 2014 at 6:11 PM, Mateusz Łoskot
wrote: I'd suggest to not to consider the two as competing libraries, but rather complementing.
I agree. I just thought of SOCI as a library that has already solved that problem. Thinking about it, I agree that they can complement each other.
Since sqlpp11 enforces compile time syntax it could help catch subtle errors very early.
In fact, there is room for some collaboration [2] "option would be to write a sqlpp11 connector library for SOCI"
The idea that it could build on SOCI would make it faster to develop and quite more stable, IMHO. It would give "instant support" for all SOCI backends.
Roland, What are your thoughts on this?
Regards, Rodrigo Madera
Mateusz and I exchanged a few mails. The consensus is that it is a very good idea and we want to do it. The main issue is time. We just don't have enough of it.
Indeed, unfortunately, but I'm staying hopeful about lots of improvements for SOCI 4 some time this year. (Please, help!)
So if you (or others) have time on your hands and are interest in this topic, why not write a SOCI connector for sqlpp11? A first version could probably be written without touching either sqlpp11 or SOCI.
I second that, this is great idea. It would also serve as a good test for soci through sqlpp11. By the way, there is another aspect of collaboration which I'd like to point out: maintenance of multi-DBMS abstraction layers is time consuming and testing it can easily become an ungrateful task, especially integration tests (including maintenance of required environments). So, tests and testing setups could be something to share. Best regards, -- Mateusz Łoskot, http://mateusz.loskot.net
On Tue, Feb 4, 2014 at 6:57 PM, Roland Bock
Mateusz and I exchanged a few mails. The consensus is that it is a very good idea and we want to do it. The main issue is time. We just don't have enough of it.
So if you (or others) have time on your hands and are interest in this topic, why not write a SOCI connector for sqlpp11? A first version could probably be written without touching either sqlpp11 or SOCI.
Unfortunately, I am on the same situation as most professional C++ programmers at the time, which is the 24 hour per day limitation. This is a serious flaw which keeps projects around the world behind schedule! ;-) Seriously, though, I wish I could help in the future. But right now it's impossible for me. General Boosters, What are the thoughts on C++11-only libraries right now? What about sqlpp11 dependencies on SOCI, if they work along? Will SOCI need to be incorporated to Boost as well? Regards, Rodrigo Madera
On Tue, Feb 4, 2014 at 6:57 PM, Roland Bock
wrote: Mateusz and I exchanged a few mails. The consensus is that it is a very good idea and we want to do it. The main issue is time. We just don't have enough of it.
So if you (or others) have time on your hands and are interest in this topic, why not write a SOCI connector for sqlpp11? A first version could probably be written without touching either sqlpp11 or SOCI.
Unfortunately, I am on the same situation as most professional C++ programmers at the time, which is the 24 hour per day limitation. This is a serious flaw which keeps projects around the world behind schedule! ;-) Seriously, though, I wish I could help in the future. But right now it's impossible for me. Hi Rodrigo, General Boosters, What are the thoughts on C++11-only libraries right now? Or even, how about C++14-only libraries? By the time the library will be ready for review, it might very well be
On 2014-02-05 15:30, Rodrigo Madera wrote: based on C++14.
What about sqlpp11 dependencies on SOCI, if they work along? Will SOCI need to be incorporated to Boost as well?
If someone writes an sqlpp11-connector for SOCI, the connector will depend on both SOCI and sqlpp11. But neither sqlpp11 nor SOCI will depend on the connector or each other. That is one of the beauties of the approach :-) Regards, Roland
On Wed, Feb 5, 2014 at 3:16 PM, Roland Bock
If someone writes an sqlpp11-connector for SOCI, the connector will depend on both SOCI and sqlpp11. But neither sqlpp11 nor SOCI will depend on the connector or each other. That is one of the beauties of the approach :-)
But wouldn't that duplicate work? For instance, SOCI has an Oracle backend. If sqlpp uses SOCI as a backend, it would have support for Oracle, and all other RDBMs for that matter. But if sqlpp has a other connectors bypassing SOCI, then what is the advantage? Would sqlpp have direct Oracle connectors besides SOCI's? If so, I begin to question the usefulness of integrating sqlpp with SOCI. Madera
On 2014-02-05 18:22, Rodrigo Madera wrote:
On Wed, Feb 5, 2014 at 3:16 PM, Roland Bock
wrote: If someone writes an sqlpp11-connector for SOCI, the connector will depend on both SOCI and sqlpp11. But neither sqlpp11 nor SOCI will depend on the connector or each other. That is one of the beauties of the approach :-)
But wouldn't that duplicate work?
For instance, SOCI has an Oracle backend. If sqlpp uses SOCI as a backend, it would have support for Oracle, and all other RDBMs for that matter.
But if sqlpp has a other connectors bypassing SOCI, then what is the advantage? Would sqlpp have direct Oracle connectors besides SOCI's?
If so, I begin to question the usefulness of integrating sqlpp with SOCI. OK, very, very short recap: sqlpp11 is a frontend which does not depend on any specific backend. sqlpp11 is totally vendor-agnostic. It creates expression trees that can easily interpreted by the connector/backend. During this interpretation all the vendor specific stuff is taken care of. Similarly with select results, sqlpp11 provides a unified way of accessing and interpreting results. The connector/backend feed the values into the structure.
Connectors are not part sqlpp11. They are specific for one or more databases. With that: It is quite simple to create connectors, actually. For instance, the first working connector for sqlite3 was done within a day. The first connector to postgres (based on sqlpp11-0.6) was created by Poul within a day or two after I announced the library in November. A connector to SOCI would be nice, because it could connect to several database systems at once. So you don't have to switch libraries if you want to switch to another database. On the other hand, in our company for instance, we have our own connector because we want to use very specific configuration options. So there is always room for several competing backend connectors, in my opinion. In short: I'd like to see connectors to SOCI, to CppDb, and other multi-database libraries, as well as directly to databases. Competition is good. All these connectors live outside of sqlpp11. Best, Roland
On Wed, Feb 5, 2014 at 4:22 PM, Roland Bock
OK, very, very short recap:
Very nice explanation, thanks. Looks very good. But then again, it's really what I said: duplicate work. Competition is good, no doubt about it. But it's duplicate effort nonetheless. Maybe if SOCI creates it's own expression grammar for SQL queries it would be a faster and more practical solution, since SOCI has been around for quite some time and has solved several issues along the way. And the expression tree for SQL queries is the fastest part of such a library. The eye candy and sugar should be easy to convert to string and use the SOCI engine for it. Sqlpp11 will still need to reimplement what SOCI has done several years ago. So I hope both sqlpp11 and SOCI get their work done and offer us such a nice combination. They will inspire each other. Best wishes, Rodrigo Madera
On Wed, Feb 5, 2014 at 4:22 PM, Roland Bock
wrote: OK, very, very short recap:
Very nice explanation, thanks.
Looks very good. But then again, it's really what I said: duplicate work. Competition is good, no doubt about it. But it's duplicate effort nonetheless. Yes, but you see, there are literally hundreds of SQL databases out
On 2014-02-05 19:55, Rodrigo Madera wrote: there and also hundreds of C/C++ libraries to talk to them. Those are all big effort. sqlpp11 also is a big effort. But the connector libraries between sqlpp11 and one of those libraries? That is mostly glue code, nothing big really. Thus, to have a few more connector libraries probably is duplicate effort, but is not really a big deal in comparison, IMHO, since the connectors are rather small.
Maybe if SOCI creates it's own expression grammar for SQL queries it would be a faster and more practical solution, since SOCI has been around for quite some time and has solved several issues along the way. And the expression tree for SQL queries is the fastest part of such a library. The eye candy and sugar should be easy to convert to string and use the SOCI engine for it.
Sqlpp11 will still need to reimplement what SOCI has done several years ago.
No. It will not. sqlpp11 will not touch databases, but only glue code...
So I hope both sqlpp11 and SOCI get their work done and offer us such a nice combination. They will inspire each other.
That's the plan, but it will take quite some time, unless someone steps in to help :-) Best regards, Roland
On Wed, Feb 5, 2014 at 9:57 PM, Roland Bock
Maybe if SOCI creates it's own expression grammar for SQL queries it would be a faster and more practical solution, since SOCI has been around for quite some time and has solved several issues along the way. And the expression tree for SQL queries is the fastest part of such a library. The eye candy and sugar should be easy to convert to string and use the SOCI engine for it.
Sqlpp11 will still need to reimplement what SOCI has done several years ago. No. It will not. sqlpp11 will not touch databases, but only glue code...
I would add that SOCI would still have to handle raw string for SQL, because there are things that are specific to one database and cannot even be expressed in another DBMS. And we often need them. It's bad to say to someone "you have to stuck to the lowest common denominator" if he only uses one DBMS. So, you would have two different syntax for the same library... quite strange. Better to split it in 2 differents lib parts like this I think. -- Cheers Johan
On 2014-02-05 22:07, Johan Baltié wrote:
On Wed, Feb 5, 2014 at 9:57 PM, Roland Bock
wrote: Maybe if SOCI creates it's own expression grammar for SQL queries it would be a faster and more practical solution, since SOCI has been around for quite some time and has solved several issues along the way. And the expression tree for SQL queries is the fastest part of such a library. The eye candy and sugar should be easy to convert to string and use the SOCI engine for it.
Sqlpp11 will still need to reimplement what SOCI has done several years ago. No. It will not. sqlpp11 will not touch databases, but only glue code... I would add that SOCI would still have to handle raw string for SQL, because there are things that are specific to one database and cannot even be expressed in another DBMS. And we often need them. It's bad to say to someone "you have to stuck to the lowest common denominator" if he only uses one DBMS.
So, you would have two different syntax for the same library... quite strange. Better to split it in 2 differents lib parts like this I think. Not sure if I fully understand your meaning, but here are some additional comments:
Lowest common denominator: sqlpp11 builds an expression tree. Whoever interprets the expression tree can decide how to interpret it and what to accept. So for instance, sqlpp11 supports outer join (of course), sqlite3 does not. If you give an expression containing an outer join to the sqlite3 connector, a static assert will inform you that this won't work. In a multi-database connector, you might need to replace the static assert by a runtime exception. Specific features: There are quite a few ways to extend sqlpp11. You could add new value types, or new functions. For example, last November, Dominique Devienne was asking about array binding for high performance inserts into an Oracle database. As written in the post that started this thread, that feature is not part of sqlpp11. But I am convinced that it would be easy to add a different kind of parameter struct to add the feature. I don't know if SOCI supports it though, so maybe you would have to use a different connector. Can you give me a few examples of the specific things you have in mind? I probably won't add them to sqlpp11 directly, but I would like to provide the means to add them without pain. Cheers, Roland
On Wed, Feb 5, 2014 at 11:24 PM, Roland Bock
Not sure if I fully understand your meaning, but here are some additional comments:
I was just saying that I prefer to have a library where the database connector is implemented and where you can do classic stuff using raw strings and having no compile time check and another one built on top that allows you to have that compile time check/expression tree builder.
Lowest common denominator: sqlpp11 builds an expression tree. Whoever interprets the expression tree can decide how to interpret it and what to accept. So for instance, sqlpp11 supports outer join (of course), sqlite3 does not. If you give an expression containing an outer join to the sqlite3 connector, a static assert will inform you that this won't work. In a multi-database connector, you might need to replace the static assert by a runtime exception.
That's great I think.
Can you give me a few examples of the specific things you have in mind? I probably won't add them to sqlpp11 directly, but I would like to provide the means to add them without pain.
The thing I was thinking of when writing the previous mail was: http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm -- Cheers Johan
On 2014-02-06 09:26, Johan Baltié wrote:
Not sure if I fully understand your meaning, but here are some additional comments: I was just saying that I prefer to have a library where the database connector is implemented and where you can do classic stuff using raw strings and having no compile time check and another one built on top
On Wed, Feb 5, 2014 at 11:24 PM, Roland Bock
wrote: that allows you to have that compile time check/expression tree builder. Thanks for the explanation :-) Lowest common denominator: sqlpp11 builds an expression tree. Whoever interprets the expression tree can decide how to interpret it and what to accept. So for instance, sqlpp11 supports outer join (of course), sqlite3 does not. If you give an expression containing an outer join to the sqlite3 connector, a static assert will inform you that this won't work. In a multi-database connector, you might need to replace the static assert by a runtime exception.
That's great I think.
Can you give me a few examples of the specific things you have in mind? I probably won't add them to sqlpp11 directly, but I would like to provide the means to add them without pain. The thing I was thinking of when writing the previous mail was:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm That's looks like a really a nice feature!
I have to give it some more thought, but I believe that it would be possible to write an appropriate extension even today via composition template<....> struct oracle_select { [forward standard calls to select_t] [add your vendor specific stuff] sqlpp::select_t<...> _select; }; Another option would be to use policies to add features. That is not possible today, but shouldn't be too hard to do either. Thanks for the link! That's given me a lot to think about and may very well result in a more flexible design with leaner classes. Too bad I have to do my day job first ;-) Regards, Roland
On Wed, Feb 5, 2014 at 7:22 PM, Roland Bock
sqlpp11 is a frontend which does not depend on any specific backend. sqlpp11 is totally vendor-agnostic. It creates expression trees that can easily interpreted by the connector/backend. During this interpretation all the vendor specific stuff is taken care of. Similarly with select results, sqlpp11 provides a unified way of accessing and interpreting results. The connector/backend feed the values into the structure.
Connectors are not part sqlpp11. They are specific for one or more databases.
Side question: if I understand correctly, nothing would prevent implementing a backend to a NoSql database, for example MongoDB, as that backend could just generate the right equivalent commands to the sql request provided by the expression tree. Am I correct?
On 2014-02-06 00:32, Klaim - Joël Lamotte wrote:
On Wed, Feb 5, 2014 at 7:22 PM, Roland Bock
wrote: sqlpp11 is a frontend which does not depend on any specific backend. sqlpp11 is totally vendor-agnostic. It creates expression trees that can easily interpreted by the connector/backend. During this interpretation all the vendor specific stuff is taken care of. Similarly with select results, sqlpp11 provides a unified way of accessing and interpreting results. The connector/backend feed the values into the structure.
Connectors are not part sqlpp11. They are specific for one or more databases.
Side question: if I understand correctly, nothing would prevent implementing a backend to a NoSql database, for example MongoDB, as that backend could just generate the right equivalent commands to the sql request provided by the expression tree. Am I correct?
Yes, that is absolutely correct. And it is not a side question in my eyes :-)
participants (7)
-
Johan Baltié
-
Klaim - Joël Lamotte
-
Mateusz Łoskot
-
Rodrigo Madera
-
Roland Bock
-
Sebastian Theophil
-
Thorsten Ottosen