Boost logo

Boost :

Subject: Re: [boost] sqlpp11: SQL for C++
From: Roland Bock (rbock_at_[hidden])
Date: 2013-11-11 15:40:25


On 2013-11-11 19:00, Larry Evans wrote:
> On 11/11/13 09:44, Roland Bock wrote:
>> On 2013-11-11 16:16, Larry Evans wrote:
>>> On 11/11/13 09:01, Roland Bock wrote:
>>>> On 2013-11-11 15:36, Edward Diener wrote:
>>>>> On 11/11/2013 7:53 AM, Roland Bock wrote:
>>> [snip]
>>>>>> Result rows are currently to be returned from the connector's result
>>>>>> object as const char**, see database_api/api.h.
>>>>>
>>>>> You are kidding ? Is std::vector<std::string> too advanced ? Why C++
>>>>> programmers are still using C null-terminated strings I will never
>>>>> understand.
>>>> No kidding. The database client libraries I've used so far are C
>>>> libraries yielding char**. That is why the current connector interface
>>>> also uses const char**. BTW: These are typically not
>>>> null-terminated but
>>>> are delivered with a size_t* or similar to inform about the length...
>>>>
>>>> But:
>>>>
>>>> 1. As a user of the library you don't get in touch with those. The
>>>> members of a row are NOT char*, of course. You get integers as
>>>> integers, floats as floats and of course you get text as
>>>> std::string. I wouldn't dare to use char* there ;-)
>>>
>>> Since the return values from the database are char**, these must be
>>> parsed and converted into a vector of, for example, TabSample,
>>> where TabSample is from:
>>>
>>> https://github.com/rbock/sqlpp11/blob/master/tests/TabSample.h
>>>
>>> Sounds like a job for spirit. However, I guess this option was
>>> rejected for reasons similar to why proto was rejected for
>>> creating the sql string to the dbms, as expressed in your
>>> reply to my other post:
>>>
>>> http://article.gmane.org/gmane.comp.lib.boost.devel/246117
>>>
>>> Is that right?
>>
>> First, the result is not a sequence of TabSample. The result row type is
>> created based on what you select. That could be analogous to TabSample's
>> rows, but you could select fewer or more columns or different orders...
>>
>> The current status is that the members of the result row parse "their"
>> part of the char**, based on the position and the type of the selected
>> column, see for instance:
>>
>> https://github.com/rbock/sqlpp11/blob/master/include/sqlpp11/integral.h
>>
>> Look for struct _result_entry_t, currently at line 51.
>>
>> There are respective classes for floating_point, text and bool.
>>
>>
>> These classes could certainly be optimized. Spirit might be able to help
>> here, but yes, you are right, I fear the compile times. In our code base
>> we have hundreds of queries to compile. So compile time is an issue for
>> continuous integration.
>>
>
> After some more thought, I think Spirit (really spirit's qi) would be
> overkill since really only parsing primitive types (e.g. int, float,
> string) are needed.
>
> I ran the SelectTest and got:
> -{--cut here--
> ------------------------
> SELECT tab_sample.alpha,tab_sample.beta,tab_sample.gamma FROM
> tab_sample WHERE ((tab_sample.alpha>7)AND(tab_sample.alpha=ANY(SELECT
> tab_sample.alpha FROM tab_sample WHERE (tab_sample.alpha<3)))) LIMIT
> 3------------------------
> SELECT
> tab_sample.alpha(tab_sample.beta||'hallenhalma')(tab_sample.beta||'hallenhalma')tab_sample.alpha
> 3
> (SELECT DISTINCT STRAIGHT_JOIN left.alpha,left.beta,(SELECT right.a
> FROM (SELECT (tab_sample.gamma) AS a FROM tab_sample WHERE
> (tab_sample.gamma=1)) AS right) FROM (tab_sample) AS left,(SELECT
> (tab_sample.gamma) AS a FROM tab_sample WHERE (tab_sample.gamma=1)) AS
> right WHERE ((tab_sample.beta='hello world')ANDSELECT
> tab_sample.gamma FROM tab_sample) GROUP BY left.gamma,right.a HAVING
> (right.a!=1) ORDER BY left.beta ASC LIMIT 17 OFFSET 3) AS a
> Compilation finished at Mon Nov 11 11:08:27
> -}--cut here--
>
> It would really help if the outputs were prefixed with some title.
> That way, one could look where the title in the source is output,
> and easily find the output from the code.
>
> I assume that the output bracketed by the:
> ------------
> lines are produced by lines 305-316:
> -{--cut here--
> {
> auto s = dynamic_select(db,
> all_of(t)).dynamic_from().dynamic_where().dynamic_limit().dynamic_offset();
> s = s.add_from(t);
> s = s.add_where(t.alpha > 7 and t.alpha ==
> any(select(t.alpha).from(t).where(t.alpha < 3)));
> s = s.set_limit(30);
> s = s.set_limit(3);
> std::cerr << "------------------------\n";
> s.serialize(std::cerr, db);
> std::cerr << "------------------------\n";
> using T = decltype(s);
> static_assert(sqlpp::is_regular<T>::value, "type requirement");
> -}--cut here--
> Is there an actual run against a real database somewhere in the tests?
> The 2 .cpp files I checked (SelectTest.cpp and UpdateTest.cpp) both
> use db of type MockDb, which doesn't seem to be connected to any real
> database.
> [snip]
>
> -Larry

Hi Larry,

those tests are really just tests, mostly compile time test to ensure
that expressions yield the right types. I will have to add quite a few
additional ones which check the generated strings.

There are two connector libraries (MySQL/MariaDb and Sqlite3) listed here:

https://github.com/rbock/sqlpp11#requirements

They also contain tests, and those tests actually do something, even
though it is not much :-)

Based on that it should be rather simple to create a connector library
for other databases.

What environment (OS, compiler) are you using, btw?

Cheers,

Roland


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk