summaryrefslogtreecommitdiff
path: root/tests/test9.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test9.cpp')
-rw-r--r--tests/test9.cpp104
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, ? )" )