[gsoc2008] Database Library (asynchronous)

Database access has been discussed quite often in the Boost mailing list. I read through the discussions from Oct 2004 and Jul/Aug 2005 and I am well aware of the fact that there is a lot of disagreement concerning the interface presented to the programmer. So I just hope you don't bite my head off if I propose this as a GSoC project. ;) Things I would like to implement: * generic binding of parameters and results (using Boost.Fusion) * asynchronous access (using Boost.Asio) * odbc, postgres, firebird, mysql and sqlite3 backends (using their proper C API) * DATE, TIME and DATETIME fields (using Boost.Date_Time or struct tm) Surely other backends can be added, but these are the ones I am (more or less) familiar with. BLOBs would be interesting to implement but I am afraid time won't permit it. The following code snippet is a quick draft using sqlite3 as a backend. This is not the interface I am going to propose, please read on. boost::asio::io_service io_service; boost::database::sqlite3::connection conn(io_service); conn.open( "testdb" ); std::cout << "client version: " << conn.client_version() << std::endl; std::cout << "server version: " << conn.server_version() << std::endl; boost::database::sqlite3::statement stmt = db.statement(); stmt.prepare( "CREATE TABLE employee" "(id INT,name CHAR(20),salary INT,PRIMARY KEY(id))" ); stmt.execute(); // prepared statement with placeholders stmt.prepare( "INSERT INTO employee (id,name,salary) VALUES (?,?,?)" ); stmt.execute( boost::fusion::make_vector( 27, "Horst Zwiebelhacker", 5000) ); stmt.prepare( "SELECT name, salary FROM employee" ); stmt.execute(); // fetch directly into specified results std::string name; int salary; while( stmt.fetch( boost::fusion::vector_tie(name,salary) ) ) { std::cout << name << " gets " << salary << " pebbles." << std::endl; } The "open", "prepare" and "execute" functions have "async_" counterparts. The sync functions throw exceptions while the async ones pass an error to the bound handle as the first parameter. Both the synchronous and the asynchronous test programs run fine, though they are not thread safe (the final library definitely will be). I checked if it would be straightforward to implement other backends, which turned out to be true for most of them. I struggled with PostgreSQL where the type of the parameters has to be known when the statement is prepared. The syntax suggested by Tito Villalobos for declaring a statement seems to be a better approach (slightly modified by me): statement< parameters<...>, // query/stored procedure parameter types results<...> // recordset column types
my_stmt(connection, query_string);
This would make it easier to prepare statements in PostgreSQL and can be a benefit for other backends too. Statements could be automatically prepared when their execute function is called the first time. Finally, variadic templates in C++0x allow to hide the functions boost::fusion::make_vector and boost::fusion::vector_tie from the programmer, which makes the interface much more intuitive. Imagine stmt.execute(27, "Horst Zwiebelhacker", 50000); or while( stmt.fetch(name,salary) ) ... isn't that lovely? Just for clarity: The design I have in mind will provide the programmer with an easy way to use SQL. Still the programmer has to write her own SQL strings. A library which provides STL functionality by abstracting SQL could be built on top of this one. I would like to concentrate on making it asynchronous rather than on the STL part. Cheers. Daniel Pfeifer

Daniel Pfeifer <daniel <at> pfeifer-mail.de> writes:
Database access has been discussed quite often in the Boost mailing list. I read through the discussions from Oct 2004 and Jul/Aug 2005 and I am well aware of the fact that there is a lot of disagreement concerning the interface presented to the programmer. So I just hope you don't bite my head off if I propose this as a GSoC project. ;)
Things I would like to implement: * generic binding of parameters and results (using Boost.Fusion) * asynchronous access (using Boost.Asio) * odbc, postgres, firebird, mysql and sqlite3 backends (using their proper C API) * DATE, TIME and DATETIME fields (using Boost.Date_Time or struct tm)
Have you seen my half baked attempt, SqlCli: http://svn.boost.org/trac/boost/browser/sandbox/sql_cli Would you consider it as a starting point? I'm not sure I'd qualify as a Boost mentor, nor if I'd be able to put in the required time, but I do believe that a database access library would be a very welcome addition to Boost (and to the C++ standard, by the way). Cheers, Nicola Musatti

Nicola Musatti wrote:
Daniel Pfeifer <daniel <at> pfeifer-mail.de> writes:
Database access has been discussed quite often in the Boost mailing list. I read through the discussions from Oct 2004 and Jul/Aug 2005 and I am well aware of the fact that there is a lot of disagreement concerning the interface presented to the programmer. So I just hope you don't bite my head off if I propose this as a GSoC project. ;)
Things I would like to implement: * generic binding of parameters and results (using Boost.Fusion) * asynchronous access (using Boost.Asio) * odbc, postgres, firebird, mysql and sqlite3 backends (using their proper C API) * DATE, TIME and DATETIME fields (using Boost.Date_Time or struct tm)
Have you seen my half baked attempt, SqlCli: http://svn.boost.org/trac/boost/browser/sandbox/sql_cli
Would you consider it as a starting point?
I'm not sure I'd qualify as a Boost mentor,
The main criterion is that you be a Boost author. That said we've had other boosters help a student even though they weren't the official author.
nor if I'd be able to put in the required time, but I do believe that a database access library would be a very welcome addition to Boost (and to the C++ standard, by the way).
For sure... Jeff

Hi Nicola,
Have you seen my half baked attempt, SqlCli?
Yes, I already know this one.
Would you consider it as a starting point?
I am sure your library can help me very much with the odbc backend. However, I plan to use compile time polymorphy. Thanks for your reply! Daniel

Daniel Pfeifer wrote:
Database access has been discussed quite often in the Boost mailing list. I read through the discussions from Oct 2004 and Jul/Aug 2005 and I am well aware of the fact that there is a lot of disagreement concerning the interface presented to the programmer.
Yep....
So I just hope you don't bite my head off if I propose this as a GSoC project. ;)
No, but I would expect varied opinions. BTW in case you didn't catch it the leading candidate for a boost database access library is soci: http://soci.sourceforge.net/ That said one has to wonder if the authors are ever going to bring it for review....
Things I would like to implement: * generic binding of parameters and results (using Boost.Fusion) * asynchronous access (using Boost.Asio) * odbc, postgres, firebird, mysql and sqlite3 backends (using their proper C API) * DATE, TIME and DATETIME fields (using Boost.Date_Time or struct tm)
Surely other backends can be added, but these are the ones I am (more or less) familiar with. BLOBs would be interesting to implement but I am afraid time won't permit it.
3 months is a short time. I'd suggest you pick a smaller number of backends if you're going to propose this. The design should support expansion to the others, but my sense is that 5 backends in 3 months isn't doable.
The following code snippet is a quick draft using sqlite3 as a backend. This is not the interface I am going to propose, please read on.
boost::asio::io_service io_service; boost::database::sqlite3::connection conn(io_service);
conn.open( "testdb" );
std::cout << "client version: " << conn.client_version() << std::endl; std::cout << "server version: " << conn.server_version() << std::endl;
boost::database::sqlite3::statement stmt = db.statement();
stmt.prepare( "CREATE TABLE employee" "(id INT,name CHAR(20),salary INT,PRIMARY KEY(id))" ); stmt.execute();
// prepared statement with placeholders stmt.prepare( "INSERT INTO employee (id,name,salary) VALUES (?,?,?)" ); stmt.execute( boost::fusion::make_vector( 27, "Horst Zwiebelhacker", 5000) );
stmt.prepare( "SELECT name, salary FROM employee" ); stmt.execute();
// fetch directly into specified results std::string name; int salary; while( stmt.fetch( boost::fusion::vector_tie(name,salary) ) ) { std::cout << name << " gets " << salary << " pebbles." << std::endl; }
The "open", "prepare" and "execute" functions have "async_" counterparts. The sync functions throw exceptions while the async ones pass an error to the bound handle as the first parameter.
That's an interesting capability that AFAIK soci doesn't support.
Both the synchronous and the asynchronous test programs run fine, though they are not thread safe (the final library definitely will be). I checked if it would be straightforward to implement other backends, which turned out to be true for most of them. I struggled with PostgreSQL where the type of the parameters has to be known when the statement is prepared.
The syntax suggested by Tito Villalobos for declaring a statement seems to be a better approach (slightly modified by me):
statement< parameters<...>, // query/stored procedure parameter types results<...> // recordset column types
my_stmt(connection, query_string);
This would make it easier to prepare statements in PostgreSQL and can be a benefit for other backends too. Statements could be automatically prepared when their execute function is called the first time. Finally, variadic templates in C++0x allow to hide the functions boost::fusion::make_vector and boost::fusion::vector_tie from the programmer, which makes the interface much more intuitive. Imagine stmt.execute(27, "Horst Zwiebelhacker", 50000); or while( stmt.fetch(name,salary) ) ... isn't that lovely?
Yeah, that's cool :-)
Just for clarity: The design I have in mind will provide the programmer with an easy way to use SQL. Still the programmer has to write her own SQL strings. A library which provides STL functionality by abstracting SQL could be built on top of this one. I would like to concentrate on making it asynchronous rather than on the STL part.
This is a difficult area as I'd like to suggest you work on extending SOCI to do this, but given that soci isn't a Boost library I can't really do that. I think the biggest issue you have is keeping a reasonable scope -- in general a full database binding library is too large for SoC. That said I see some good ideas in your proposal so I'm not going to discourage you -- the mentors and other boosters can help you refine your proposal down to something useful and doable. Thanks! Jeff

Hi Jeff,
[...] the leading candidate [...] is soci.
I know about that. SOCI surely is a great library with high potential. However, there are two things, that I disagree with it: 1) overloads of operator<< and operator, It confuses me to use operator<< to get information _out_ of something. 2) Runtime polymorphy I agree that is is important to switch easily between implementations, but usually you don't need this flexibility at runtime, do you? I don't want to start a discussion about soci here. I just want to point out why I would prefer a different approach.
3 months is a short time. I'd suggest you pick a smaller number of backends if you're going to propose this. The design should support expansion to the others, but my sense is that 5 backends in 3 months isn't doable.
Agreed. It is good to know what is doable in a fixed timeframe and what is not. Now I'm spoilt for choice... Thanks for your reply! Daniel

On Sat, Mar 22, 2008 at 7:37 AM, Daniel Pfeifer <daniel@pfeifer-mail.de> wrote:
Hi Jeff,
[...] the leading candidate [...] is soci.
I know about that. SOCI surely is a great library with high potential. However, there are two things, that I disagree with it: 1) overloads of operator<< and operator, It confuses me to use operator<< to get information _out_ of something.
Ok, but I don't think SOCI does that. It uses operator<< on an SQL statement to bind variables -- the variables can be input or output depending on what you're doing.
2) Runtime polymorphy I agree that is is important to switch easily between implementations, but usually you don't need this flexibility at runtime, do you?
No, but I'm not clear that there's much of a disadvantage -- a few extra instructions is very likely to be totally overwelmed by the cost
I don't want to start a discussion about soci here. I just want to point out why I would prefer a different approach.
That's fair, but the discussion will come up. You need to have reasons, and you do, why you are going a different direction. As it stands, I haven't seen enough examples of your proposed interface to understand the contrast. In particular, I'd like to see how you are going to bind user defined types (eg: boost::posix_time::ptime), STL collections of objects -- or say a Boost.Multiindex collection of values, bulk operations, etc. Jeff

Jeff Garland wrote:
1) overloads of operator<< and operator, It confuses me to use operator<< to get information _out_ of something.
Ok, but I don't think SOCI does that. It uses operator<< on an SQL statement to bind variables -- the variables can be input or output depending on what you're doing.
Well, not exactly. :-) string name; int id = ...; sql << "select name from persons where id = :id", into(name), use(id); Above: - operator<< is used to *send* query to the server, - "into element" is used to bind variable that will get results, - "use element" binds variable that provides data for the query, - operator, is used to bunch all parts of the query together. In other words, operator<< is not used to "get something out" (into elements serve this purpose instead), but to "make things happen". -- Maciej Sobczak * www.msobczak.com * www.inspirel.com

On Sat, Mar 22, 2008 at 11:37 AM, Daniel Pfeifer <daniel@pfeifer-mail.de> wrote:
Hi Jeff,
[...] the leading candidate [...] is soci.
I know about that. SOCI surely is a great library with high potential. However, there are two things, that I disagree with it:
Would you consider creating a compile-time SQL library? This should allow for *really portable* SQL in multiple back-ends with zero overhead. [snip]
Agreed. It is good to know what is doable in a fixed timeframe and what is not. Now I'm spoilt for choice...
Thanks for your reply!
Daniel
-- Felipe Magno de Almeida

Daniel, Just as a prefix: I've been using Soci in a couple of projects now and I'm very satisfied.
[...] the leading candidate [...] is soci.
I know about that. SOCI surely is a great library with high potential. However, there are two things, that I disagree with it: 1) overloads of operator<< and operator, It confuses me to use operator<< to get information _out_ of something.
Hmmm. Operator overloading is always a matter of taste. But as Spirit shows 'it grows on you over time' In this sense I think that this argument shouldn't be sufficient to start a new library effort.
2) Runtime polymorphy I agree that is is important to switch easily between implementations, but usually you don't need this flexibility at runtime, do you?
That's one point which makes Soci compelling for me in my projects. I want to decide at runtime what DB backend to use. Regards Hartmut
I don't want to start a discussion about soci here. I just want to point out why I would prefer a different approach.
3 months is a short time. I'd suggest you pick a smaller number of backends if you're going to propose this. The design should support expansion to the others, but my sense is that 5 backends in 3 months isn't doable.
Agreed. It is good to know what is doable in a fixed timeframe and what is not. Now I'm spoilt for choice...
Thanks for your reply!
Daniel
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Daniel Pfeifer wrote:
SOCI surely is a great library with high potential. However, there are two things, that I disagree with it: 1) overloads of operator<< and operator, It confuses me to use operator<< to get information _out_ of something.
You got confused, because you have already confused different levels of abstractions. :-) Getting something *out* of the database is a high level abstraction. SOCI does not support it directly. Instead, SOCI supports a lower level, where the client-server relation is explicit and you *send* something to the server so that the server does something for you. This "doing something" can produce some results that you can fetch back to your application, but anyway you have to *send* the query to the server first. This *sending* is explicit in the choice of operator<<. Note also that there are lots of other things that the server can do for you in addition to "getting something out". Putting something to the database (insert) is one obvious thing. Copying things from one table to another (so-called "insert from select") is a less obvious example, and DDL queries like "drop ..." or "alter ..." are completely incompatible with simplified "in" and "out" abstractions. Now, if you consider the fact that SOCI does not interpret queries (and therefore it has no idea what the server is actually doing), then you will see that all these different queries need consistent handling and operator<< provides it. If you start differentiating between "in" and "out" queries, you will have to actually interpret the SQL - or even *build* it to implement any given higher-level abstractions. This is not what SOCI does - and from what I understand, it is not what you want to do, either. What you can do, however, is to implement a high-level framework for "in" and "out" abstractions that is build on top of SOCI (or any other library). In this case, the high-level framework can provide whatever syntax is most appropriate for the high-level abstractions, while internally using operator<< for *sending* necessary commands to the server, possibly many times for a single high-level unit of work. This division of responsibilities is what you have probably missed. If you design your own database library, you have to first clearly state the level of abstraction you want to target. There are too many of them to fit in a single framework.
2) Runtime polymorphy I agree that is is important to switch easily between implementations, but usually you don't need this flexibility at runtime, do you?
Actually, our users demanded dynamic backend loading. Consider: session sql("postgresql://dbname=myfunnydatabase"); The string provided to the session constructor defines not only the connection parameters, but also the "protocol", which is handled by the dynamically loaded backend. You still have to face incompatibilities between different servers at the SQL level, but once this is done, the opportunities for system deployment, configuration, etc. are much wider. Not mentioning the fact that the whole system can be extended for new backends without even touching the existing parts. I have to admit that I never thought about this, but after being presented with the actual use case I find it awesome. The point is that tricks like the above require run-time polymorphism. The big question you have to answer is what do you want to achieve by avoiding it? Do you think you will gain on performance? You won't. The database server is amongst the slowest parts of any system. It is dead slow. It is infinitely slow. How much performance you can gain by doing things at compile time there? Did you measure anything? Having said that, it makes sense to apply compile-time techniques in places where data transfer is involved, like binding variables, fetching data into bound objects, etc. This is because for a single statement execution, the data can be transferred and/or converted *many* times. Optimize this part. Don't bother with optimizing things that happen relatively rarely - like session creation or statement execution and use old good run-time polymorphism if it brings some benefits on its own.
I don't want to start a discussion about soci here.
Let's agree that the above was *not* a discussion about SOCI, but some useful comments from those who already made their share of mistakes. ;-) -- Maciej Sobczak * www.msobczak.com * www.inspirel.com

Jeff Garland wrote:
No, but I would expect varied opinions. BTW in case you didn't catch it the leading candidate for a boost database access library is soci:
That said one has to wonder if the authors are ever going to bring it for review....
Thank you for these nice words. Yes, we are heading towards the next major release (3.0) which brings some new fundamental features. Integration with Boost is high on the list and the code that is currently in CVS allows to use boost::optional for working with nulls as well as boost::tuple for fetching the whole row. We are now processing two important features (Unicode support and dynamic loading of backends) that look quite straightforward at first sight, but can have far-fetching consequences in their interactions with other parts of the library. We would like to better understand what we are really trying to achieve before casting things in stone. In any case, mills are grinding and I hope to be able to present the next major release before summer.
The "open", "prepare" and "execute" functions have "async_" counterparts. The sync functions throw exceptions while the async ones pass an error to the bound handle as the first parameter.
That's an interesting capability that AFAIK soci doesn't support.
Right. SOCI does not offer any asynchronous operations at the library level. Note that you can always complicate the discussion with synchronous SQL queries that trigger asynchronous operation at the server side. ;-) Daniel, if you use the SOCI code for reference or for any other reason, please use the one in CVS-head. -- Maciej Sobczak * www.msobczak.com * www.inspirel.com

Hi Daniel, Daniel Pfeifer wrote:
Database access has been discussed quite often in the Boost mailing list. I read through the discussions from Oct 2004 and Jul/Aug 2005 and I am well aware of the fact that there is a lot of disagreement concerning the interface presented to the programmer. So I just hope you don't bite my head off if I propose this as a GSoC project. ;)
Go for it, if you already have your own vision of how it should look. If you spend a lot of time listening to other people and attempting to make a compromise, you'll run out of time before you've even started. Did you see this thread from last year? http://lists.boost.org/Archives/boost/2007/03/117939.php
stmt.prepare( "INSERT INTO employee (id,name,salary) VALUES (?,?,?)" );
In PostgreSQL, you use $1,$2,$3 in place of ?,?,?. So of course you could convert the ?s to $ns in your PostgreSQL back-end, but that means that you lose the ability to re-order parameters and to use some more than once. So, you could use the PostgreSQL syntax and convert for the other back-ends. Or you could do what Apache's database backend does and use printf-like % escapes. But that's just a detail.
The syntax suggested by Tito Villalobos for declaring a statement seems to be a better approach (slightly modified by me):
statement< parameters<...>, // query/stored procedure parameter types results<...> // recordset column types
my_stmt(connection, query_string);
Here's approximately how my PostgreSQL wrapper would do your example: class EmployeeDatabase: public Database { typedef int id_t; typedef string name_t; typedef int salary_t; Query<> create_table; Query<id_t, name_t, salary_t> insert_employee; Query<> select_all_employees; EmployeeDatabase(): Database("...pgsql connection string..."), create_table(*this, "CREATE TABLE employee (id INT,name CHAR(20),salary INT,PRIMARY KEY(id))"), insert_employee(*this, "INSERT INTO employee (id,name,salary) VALUES ($1,$2,$3)"), select_all_employees(*this, "SELECT name, salary FROM employee") {} }; EmployeeDatabase db; db.create_table(); db.insert_employee(27, "Horst Zwiebelhacker", 5000); EmployeeDatabase::Result r = db.select_all_employees(); for (int i=0; i<r.rows; ++i) { cout << r.get<string>(i,0) << " gets " << r.get<int>(i,1) << " pebbles.\n"; } I never got around to using tuples in multi-column results, hence the get<>() above. It has type-checked and more concise single-column results though. Thinking back, the reason why I didn't implement tuples for returned rows was that I really wanted structs, so that I could access fields by name not number, and the necessary fusion-magic to do that was beyond me. I used the Boost preprocessor library to support up-to-N parameters; it would be much simpler using variadic templates.
Statements could be automatically prepared when their execute function is called the first time.
I think this is what I do; however, if you prepare them as soon as possible you'll detect SQL syntax errors earlier, which could be useful. I also have a runonce() method that you can use if you don't want to prepare the statement, which can sometimes be useful.
Finally, variadic templates in C++0x allow to hide the functions boost::fusion::make_vector and boost::fusion::vector_tie from the programmer, which makes the interface much more intuitive. Imagine stmt.execute(27, "Horst Zwiebelhacker", 50000);
Just use operator() and write stmt(27, "Horst Zwiebelhacker", 50000);
Just for clarity: The design I have in mind will provide the programmer with an easy way to use SQL. Still the programmer has to write her own SQL strings.
Good plan. However, if someone else were considering writing "SQL in C++" then Proto will now make that job easier than it would have been before.
A library which provides STL functionality by abstracting SQL could be built on top of this one. I would like to concentrate on making it asynchronous rather than on the STL part.
It's easy enough to make the query results look like STL containers (e.g. when iterating through them). As it happens, I've never needed asynchronous database functions; generally I block waiting for the results and if there's other work to do at the same time it's in another thread. Do you have an application using asio that's driving this? Regards, Phil.

Hi Phil,
Go for it, if you already have your own vision of how it should look. If you spend a lot of time listening to other people and attempting to make a compromise, you'll run out of time before you've even started.
Thanks for your encouragement! I am ready to start. All I need is to be accepted for GSoC. If I'm not accepted, I will code it anyway, just for fun. But I really could use the money. ;-)
Did you see this thread from last year?
No, I did not know this one. Thanks for the link! The threads I read before where those listed in the Boost Wiki under Relational_Database_Access. I also looked at the implementation of most of the libraries linked there.
In PostgreSQL, you use $1,$2,$3 in place of ?,?,?. So of course you could convert the ?s to $ns in your PostgreSQL back-end, but that means that you lose the ability to re-order parameters and to use some more than once. So, you could use the PostgreSQL syntax and convert for the other back-ends. Or you could do what Apache's database backend does and use printf-like % escapes. But that's just a detail.
My plan was abstracting the different APIs but not touching the strings. Also I plan to use compile time polymorphy. A boost::db::mysql::statement will have exactly the same interface as a boost::db::postgres::statement, thus it will be easy to change to another backend. The only thing a programmer has to be aware of, is the SQL "dialect" of the used backend. "CREATE TABLE ... ENGINE=InnoDB" is fine in MySQL, but will signal an error in SQLite. Using the PostgreSQL backend the following code would be correct: statement< parameters<int,string>, results<>
my_stmt(connection, "INSERT...VALUES ($1,$2,$1)");
To implement the same functionality for another backend one would have to write statement< parameters<int,string,int>, // <- mind the additional int results<>
my_stmt(connection, "INSERT...VALUES (?,?,?)"); and pass the first parameter again as the third one.
It should be possible to build another library which hides these differences by abstracting the strings. Be it as an SQL DSEL or a relational database library which completely hides SQL (better in my opinion).
Here's approximately how my PostgreSQL wrapper would do your example...
I like the object oriented look and feel of your design very much! Also, I found out, that I could change my examples to this look without touching a single line of my library! Awesome!
Just use operator() and write stmt(27,"Horst Zwiebelhacker",50000);
It is a good idea to use operator() as an alias to execute(). Still I don't want to drop execute() because I want every async_ function to have a synchronous counterpart.
It's easy enough to make the query results look like STL containers (e.g. when iterating through them).
As you wrote last year, you can implement STL-compatible containers for results with essentially no overhead in PostgreSQL. In SQLite no overhead is required when the iteration is forward only. ODBC and MySQL make random access iteration possible, but both require information "where to write the results". The same form of overhead is required for Firebird, which also is limited to forward only iteration. Using libpq (Postres' C API) a result can easily be decoupled from a statement. In other APIs they are bound together, so if you exequte your query again, the first result is invalidated. The simplest workaround would be to copy the whole result set to an STL compatible container. In fact, this is what many libraries do. Why not copy it over if you need and otherwise don't? struct employee{ int id, string name, int salary }; std::vector<employee> employees; employee e; while( stmt.fetch(e.id,e.name,e.salary) ) employees.push_back(e); I would like to stick to my "stmt.fetch(put,results,here)" interface. Maybe it is less flexible, but it is definitely more lightweight.
As it happens, I've never needed asynchronous database functions; generally I block waiting for the results and if there's other work to do at the same time it's in another thread. Do you have an application using asio that's driving this?
No, I just thought that it might be useful. What do others think about asynchronous database access? Cheers, Daniel

Hello, 2008/3/22, Daniel Pfeifer <daniel@pfeifer-mail.de>:
As it happens, I've never needed asynchronous database functions; generally I block waiting for the results and if there's other work to do at the same time it's in another thread. Do you have an application using asio that's driving this?
No, I just thought that it might be useful. What do others think about asynchronous database access?
If the the asynchronous api fits well into the demultiplexer service of asio, I would always prefer the async over the sync approach. kind regards Andreas Pokorny

On Sat, Mar 22, 2008 at 7:37 AM, Daniel Pfeifer <daniel@pfeifer-mail.de> wrote:
Hi Phil,
Go for it, if you already have your own vision of how it should look. If you spend a lot of time listening to other people and attempting to make a compromise, you'll run out of time before you've even started.
Thanks for your encouragement! I am ready to start. All I need is to be accepted for GSoC. If I'm not accepted, I will code it anyway, just for fun. But I really could use the money. ;-)
Don't forget to submit your application starting on the 24th.
As it happens, I've never needed asynchronous database functions;
generally I block waiting for the results and if there's other work to do at the same time it's in another thread. Do you have an application using asio that's driving this?
No, I just thought that it might be useful. What do others think about asynchronous database access?
I think it's useful -- I'd prefer not to resort to managing my own threads to do this. Jeff
participants (9)
-
Andreas Pokorny
-
Daniel Pfeifer
-
Felipe Magno de Almeida
-
Hartmut Kaiser
-
Jeff Garland
-
Jeff Garland
-
Maciej Sobczak
-
Nicola Musatti
-
Phil Endecott