diff options
Diffstat (limited to 'tests/test9.cpp')
-rw-r--r-- | tests/test9.cpp | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/tests/test9.cpp b/tests/test9.cpp index af4a035..5b57a87 100644 --- a/tests/test9.cpp +++ b/tests/test9.cpp @@ -27,10 +27,80 @@ #if !defined _WIN32 #include <unistd.h> #endif /* !defined _WIN32 */ +#include "threads.h" using namespace sqlite3xx; using namespace std; +const int NOF_PRODUCERS = 2; +const int NOF_CONSUMERS = 2; +const int NOF_PRODUCER_TRANSACTIONS = 10; +const int NOF_PRODUCER_OPS = 10; +const int NOF_CONSUMER_TRANSACTIONS = 10; +const int NOF_CONSUMER_OPS = 10; + +#define UNUSED( x ) if( 0 && (x) ) { } + +MUTEX_TYPE cout_mutex; + +static THREAD_FUNC_DECL produce( void *thread_data ) +{ + UNUSED( thread_data ); + + try { + connection c( "test9.db" ); + c.prepare( "ins", "insert into x values( ? )" )( "text", sqlite3xx::prepare::treat_direct ); + + for( int i = 0; i < NOF_PRODUCER_TRANSACTIONS; i++ ) { + work t( c, "ins" ); + MUTEX_LOCK( cout_mutex ); + cout << "producer transaction " << i << " started" << endl; + MUTEX_UNLOCK( cout_mutex ); + for( int j = 0; j < NOF_PRODUCER_OPS; j++ ) { + result r = t.prepared( "ins" )( i * 1000 + j ).exec( ); + assert( r.affected_rows( ) == 1 ); + } + t.commit( ); + } + } catch( sql_error& e ) { + cerr << "producer error, " << e.msg( ) << ": " << e.query( ) << endl; + } + + THREAD_FUNC_RETURN; +} + +static THREAD_FUNC_DECL consume( void *thread_data ) +{ + UNUSED( thread_data ); + + try { + connection c( "test9.db" ); + c.prepare( "sel", "select * from x" ); + + for( int i = 0; i < NOF_CONSUMER_TRANSACTIONS; i++ ) { + work t( c, "sel" ); + MUTEX_LOCK( cout_mutex ); + cout << "consumer transaction " << i << " started" << endl; + MUTEX_UNLOCK( cout_mutex ); + for( int j = 0; j < NOF_CONSUMER_OPS; j++ ) { + result r = t.prepared( "sel" ).exec( ); + for( result::const_iterator it = r.begin( ); it < r.end( ); it++ ) { + int x; + it["x"].to( x ); + } + MUTEX_LOCK( cout_mutex ); + cout << "consumer transaction got " << r.size( ) << " rows." << endl; + MUTEX_UNLOCK( cout_mutex ); + } + t.commit( ); + } + } catch( sql_error& e ) { + cerr << "consumer error, " << e.msg( ) << ": " << e.query( ) << endl; + } + + THREAD_FUNC_RETURN; +} + int main( ) { (void)unlink( "test9.db" ); @@ -39,7 +109,34 @@ int main( ) { connection c( "test9.db" ); cout << "connection object is " << c << endl; + cout << "create table.." << endl; c.exec( "create table x( x integer )" ); + + // now have some threads creating data and some others + // consuming it. stupid, but should nicely stress the thing + THREAD_TYPE prod[NOF_PRODUCERS]; + THREAD_TYPE cons[NOF_CONSUMERS]; + + MUTEX_SETUP( cout_mutex ); + + for( int i = 0; i < NOF_PRODUCERS; i++ ) { + THREAD_CREATE( &prod[i], produce, NULL ); + } + + for( int i = 0; i < NOF_CONSUMERS; i++ ) { + THREAD_CREATE( &cons[i], consume, NULL ); + } + + for( int i = 0; i < NOF_PRODUCERS; i++ ) { + THREAD_JOIN( prod[i] ); + } + + for( int i = 0; i < NOF_CONSUMERS; i++ ) { + THREAD_JOIN( cons[i] ); + } + + MUTEX_CLEANUP( cout_mutex ); + } catch( sql_error& e ) { cerr << e.msg( ) << ": " << e.query( ) << endl; } @@ -48,13 +145,6 @@ int main( ) { /* try { - cout << "starting transaction.." << endl; - work wc( c, "create" ); - - cout << "create table.." << endl; - wc.exec( "create table a( i integer, d double, s text, t text )" ); - wc.commit( ); - work wi( c, "insert" ); cout << "insert some data.." << endl; c.prepare( "ins", "insert into a( i, d, s, t ) values( NULL, NULL, NULL, ? )" ) |