0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/db/db.cpp

618 lines
15 KiB
C++
Raw Normal View History

2007-10-20 01:35:48 +02:00
// db.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "db.h"
#include "../grid/message.h"
#include "../util/mmap.h"
#include "../util/hashtab.h"
2007-11-05 20:44:26 +01:00
#include "../util/goodies.h"
2007-10-20 01:35:48 +02:00
#include "pdfile.h"
#include "jsobj.h"
2008-03-23 10:06:02 +01:00
#include "javajs.h"
2007-10-20 01:35:48 +02:00
#include "query.h"
2008-03-17 01:59:19 +01:00
#include "introspect.h"
2007-10-20 01:35:48 +02:00
2007-11-27 21:30:51 +01:00
extern const char *dbpath;
2008-02-10 22:28:48 +01:00
extern int curOp;
2007-11-27 21:30:51 +01:00
2007-12-08 21:50:47 +01:00
boost::mutex dbMutex;
2007-10-20 01:35:48 +02:00
struct MyStartupTests {
MyStartupTests() {
assert( sizeof(OID) == 12 );
}
} mystartupdbcpp;
/* example for
var zz = { x: 3, y: "foo", v: { z:5, arr: [1, 2] } }
zz.v.arr.prop = "zoo";
*/
void quicktest() {
2007-10-30 16:35:17 +01:00
cout << "quicktest()\n";
2007-10-20 01:35:48 +02:00
MemoryMappedFile mmf;
2007-11-27 21:32:02 +01:00
char *m = (char *) mmf.map("/tmp/quicktest", 16384);
2007-10-20 01:35:48 +02:00
// cout << "mmf reads: " << m << endl;
strcpy_s(m, 1000, "hello worldz");
}
void pdfileInit();
class DbMessage {
public:
DbMessage(Message& _m) : m(_m) {
2007-10-28 19:42:59 +01:00
theEnd = _m.data->_data + _m.data->dataLen();
int *r = (int *) _m.data->_data;
2007-10-20 01:35:48 +02:00
reserved = *r;
r++;
data = (const char *) r;
nextjsobj = data;
}
const char * getns() { return data; }
void getns(Namespace& ns) {
ns = data;
}
2007-10-28 21:38:06 +01:00
int pullInt() {
if( nextjsobj == data )
nextjsobj += strlen(data) + 1; // skip namespace
int i = *((int *)nextjsobj);
nextjsobj += 4;
return i;
}
2007-11-04 22:17:44 +01:00
long long pullInt64() {
if( nextjsobj == data )
nextjsobj += strlen(data) + 1; // skip namespace
long long i = *((long long *)nextjsobj);
nextjsobj += 8;
return i;
}
2007-10-28 21:38:06 +01:00
2007-10-20 01:35:48 +02:00
OID* getOID() {
return (OID *) (data + strlen(data) + 1); // skip namespace
}
void getQueryStuff(const char *&query, int& ntoreturn) {
int *i = (int *) (data + strlen(data) + 1);
ntoreturn = *i;
i++;
query = (const char *) i;
}
/* for insert and update msgs */
bool moreJSObjs() { return nextjsobj != 0; }
JSObj nextJsObj() {
if( nextjsobj == data )
nextjsobj += strlen(data) + 1; // skip namespace
JSObj js(nextjsobj);
2008-02-05 23:33:35 +01:00
assert( js.objsize() < ( theEnd - data ) );
2007-10-29 03:20:57 +01:00
if( js.objsize() <= 0 )
2007-10-20 01:35:48 +02:00
nextjsobj = null;
2007-10-28 19:42:59 +01:00
else {
2007-11-01 22:44:26 +01:00
nextjsobj += js.objsize();
2007-10-28 19:42:59 +01:00
if( nextjsobj >= theEnd )
nextjsobj = 0;
}
2007-10-20 01:35:48 +02:00
return js;
}
private:
Message& m;
int reserved;
const char *data;
const char *nextjsobj;
2007-10-28 19:42:59 +01:00
const char *theEnd;
2007-10-20 01:35:48 +02:00
};
#pragma pack(push)
#pragma pack(1)
struct EmptyObject {
EmptyObject() { len = 5; jstype = EOO; }
int len;
char jstype;
} emptyObject;
#pragma pack(pop)
2008-02-13 06:26:39 +01:00
void killCursors(int n, long long *ids);
void receivedKillCursors(Message& m) {
int *x = (int *) m.data->_data;
x++; // reserved
int n = *x++;
2008-03-05 22:51:27 +01:00
assert( n >= 1 );
if( n > 2000 ) {
cout << "Assertion failure, receivedKillCursors, n=" << n << endl;
assert( n < 30000 );
}
2008-02-13 06:26:39 +01:00
killCursors(n, (long long *) x);
}
2008-03-17 01:59:19 +01:00
void receivedUpdate(Message& m, stringstream& ss) {
2007-10-30 10:50:14 +01:00
DbMessage d(m);
const char *ns = d.getns();
2008-03-29 22:49:13 +01:00
assert(*ns);
2008-01-20 23:42:26 +01:00
setClient(ns);
2008-03-17 01:59:19 +01:00
if( client->profile )
ss << ns << ' ';
2007-10-30 10:50:14 +01:00
int flags = d.pullInt();
JSObj query = d.nextJsObj();
assert( d.moreJSObjs() );
2008-03-17 01:59:19 +01:00
assert( query.objsize() < m.data->dataLen() );
2007-10-30 10:50:14 +01:00
JSObj toupdate = d.nextJsObj();
2008-03-17 01:59:19 +01:00
assert( toupdate.objsize() < m.data->dataLen() );
assert( query.objsize() + toupdate.objsize() < m.data->dataLen() );
updateObjects(ns, toupdate, query, flags & 1, ss);
2007-10-30 10:50:14 +01:00
}
void receivedDelete(Message& m) {
DbMessage d(m);
const char *ns = d.getns();
2008-03-29 22:49:13 +01:00
assert(*ns);
2008-01-20 23:42:26 +01:00
setClient(ns);
2007-10-30 10:50:14 +01:00
int flags = d.pullInt();
assert( d.moreJSObjs() );
JSObj pattern = d.nextJsObj();
deleteObjects(ns, pattern, flags & 1);
}
2008-03-24 23:04:22 +01:00
void receivedQuery(AbstractMessagingPort& dbMsgPort, Message& m, stringstream& ss) {
2007-10-20 01:35:48 +02:00
DbMessage d(m);
2007-10-28 21:38:06 +01:00
const char *ns = d.getns();
2008-01-20 23:42:26 +01:00
setClient(ns);
2008-02-01 01:10:52 +01:00
int ntoskip = d.pullInt();
2007-10-28 21:38:06 +01:00
int ntoreturn = d.pullInt();
2007-11-05 04:34:37 +01:00
JSObj query = d.nextJsObj();
auto_ptr< set<string> > fields;
if( d.moreJSObjs() ) {
fields = auto_ptr< set<string> >(new set<string>());
d.nextJsObj().getFieldNames(*fields);
}
QueryResult* msgdata;
try {
msgdata = runQuery(ns, ntoskip, ntoreturn, query, fields, ss);
}
catch( AssertionException ) {
2008-03-17 01:59:19 +01:00
ss << " exception ";
cout << " Caught Assertion in runQuery, continuing" << endl;
cout << " ntoskip:" << ntoskip << " ntoreturn:" << ntoreturn << endl;
cout << " ns:" << ns << endl;
cout << " query:" << query.toString() << endl;
msgdata = (QueryResult*) malloc(sizeof(QueryResult));
QueryResult *qr = msgdata;
qr->_data[0] = 0;
qr->_data[1] = 0;
qr->_data[2] = 0;
qr->_data[3] = 0;
qr->len = sizeof(QueryResult);
qr->operation = opReply;
qr->cursorId = 0;
qr->startingFrom = 0;
qr->nReturned = 0;
}
2007-10-20 01:35:48 +02:00
Message resp;
resp.setData(msgdata, true); // transport will free
2008-03-17 01:59:19 +01:00
if( client->profile ) {
ss << " bytes:" << resp.data->dataLen();
}
2007-10-20 01:35:48 +02:00
dbMsgPort.reply(m, resp);
}
2008-03-24 23:04:22 +01:00
void receivedGetMore(AbstractMessagingPort& dbMsgPort, Message& m, stringstream& ss) {
2007-11-04 22:17:44 +01:00
DbMessage d(m);
const char *ns = d.getns();
2008-03-17 01:59:19 +01:00
ss << ns;
2008-01-20 23:42:26 +01:00
setClient(ns);
2007-11-04 22:17:44 +01:00
int ntoreturn = d.pullInt();
2008-03-17 01:59:19 +01:00
ss << " ntoreturn:" << ntoreturn;
2007-11-04 22:17:44 +01:00
long long cursorid = d.pullInt64();
QueryResult* msgdata = getMore(ns, ntoreturn, cursorid);
Message resp;
resp.setData(msgdata, true);
2008-03-17 01:59:19 +01:00
ss << " bytes:" << resp.data->dataLen();
2007-11-04 22:17:44 +01:00
dbMsgPort.reply(m, resp);
}
2008-02-01 20:07:55 +01:00
void receivedInsert(Message& m, stringstream& ss) {
2007-12-08 21:56:25 +01:00
// cout << "GOT MSG id:" << m.data->id << endl;
2007-10-20 01:35:48 +02:00
DbMessage d(m);
while( d.moreJSObjs() ) {
JSObj js = d.nextJsObj();
2007-12-01 17:44:42 +01:00
// cout << " temp dbinsert: got js object, size=" << js.objsize() << " ns:" << d.getns() << endl;
2008-01-20 23:42:26 +01:00
const char *ns = d.getns();
2008-03-29 22:49:13 +01:00
assert(*ns);
2008-01-20 23:42:26 +01:00
setClient(ns);
2008-02-01 20:07:55 +01:00
ss << ns;
2008-01-20 23:42:26 +01:00
theDataFileMgr.insert(ns, (void*) js.objdata(), js.objsize());
2007-10-20 01:35:48 +02:00
}
}
2007-10-30 10:50:14 +01:00
void testTheDb() {
2008-03-17 01:59:19 +01:00
stringstream ss;
2008-01-20 23:42:26 +01:00
setClient("sys.unittest.pdfile");
2007-10-30 10:50:14 +01:00
/* this is not validly formatted, if you query this namespace bad things will happen */
theDataFileMgr.insert("sys.unittest.pdfile", (void *) "hello worldx", 13);
2007-10-30 18:43:44 +01:00
theDataFileMgr.insert("sys.unittest.pdfile", (void *) "hello worldx", 13);
2007-10-20 01:35:48 +02:00
2007-10-30 10:50:14 +01:00
JSObj j1((const char *) &js1);
deleteObjects("sys.unittest.delete", j1, false);
theDataFileMgr.insert("sys.unittest.delete", &js1, sizeof(js1));
deleteObjects("sys.unittest.delete", j1, false);
2008-03-17 01:59:19 +01:00
updateObjects("sys.unittest.delete", j1, j1, true,ss);
updateObjects("sys.unittest.delete", j1, j1, false,ss);
2007-10-20 01:35:48 +02:00
2007-11-02 03:34:44 +01:00
auto_ptr<Cursor> c = theDataFileMgr.findAll("sys.unittest.pdfile");
while( c->ok() ) {
Record* r = c->_current();
c->advance();
2007-10-20 01:35:48 +02:00
}
cout << endl;
2008-01-20 23:42:26 +01:00
client = 0;
2007-10-30 10:50:14 +01:00
}
2007-12-08 21:50:47 +01:00
int port = DBPort;
2007-11-27 21:30:51 +01:00
2007-12-08 21:50:47 +01:00
MessagingPort *grab = 0;
2008-03-24 23:04:22 +01:00
void connThread();
2007-10-30 10:50:14 +01:00
2007-12-08 21:50:47 +01:00
class OurListener : public Listener {
public:
OurListener(int p) : Listener(p) { }
virtual void accepted(MessagingPort *mp) {
assert( grab == 0 );
grab = mp;
2008-03-24 23:04:22 +01:00
boost::thread thr(connThread);
2007-12-08 21:50:47 +01:00
while( grab )
sleepmillis(1);
}
};
2007-10-30 10:50:14 +01:00
2007-12-08 21:50:47 +01:00
void listen(int port) {
2008-03-30 05:30:44 +02:00
cout << "db version: 103 mar2008 minilex" << endl;
2007-12-08 21:50:47 +01:00
pdfileInit();
2007-10-30 10:50:14 +01:00
testTheDb();
2007-12-08 21:50:47 +01:00
cout << curTimeMillis() % 10000 << " waiting for connections...\n" << endl;
OurListener l(port);
l.listen();
}
2008-02-14 18:50:13 +01:00
int ctr = 0;
2008-03-24 23:04:22 +01:00
extern int callDepth;
2008-02-14 18:50:13 +01:00
2008-03-24 23:04:22 +01:00
class JniMessagingPort : public AbstractMessagingPort {
public:
JniMessagingPort(Message& _container) : container(_container) { }
void reply(Message& received, Message& response) {
container = response;
}
2008-03-27 22:48:07 +01:00
Message & container;
2008-03-24 23:04:22 +01:00
};
/* a call from java/js to the database locally.
m - inbound message
out - outbound message, if there is any, will be set here.
if there is one, out.data will be non-null on return.
The out.data buffer will automatically clean up when out
goes out of scope (out.freeIt==true)
*/
void jniCallback(Message& m, Message& out)
{
Client *clientOld = client;
JniMessagingPort jmp(out);
callDepth++;
int curOpOld = curOp;
try {
stringstream ss;
char buf[64];
time_t_to_String(time(0), buf);
buf[20] = 0; // don't want the year
ss << buf << " dbjs ";
{
Timer t;
bool log = false;
curOp = m.data->operation;
if( m.data->operation == dbQuery ) {
receivedQuery(jmp, m, ss);
}
else if( m.data->operation == dbInsert ) {
ss << "insert ";
receivedInsert(m, ss);
}
else if( m.data->operation == dbUpdate ) {
ss << "update ";
receivedUpdate(m, ss);
}
else if( m.data->operation == dbDelete ) {
ss << "remove ";
receivedDelete(m);
}
else if( m.data->operation == dbGetMore ) {
log = true;
ss << "getmore ";
receivedGetMore(jmp, m, ss);
}
else if( m.data->operation == dbKillCursors ) {
try {
log = true;
ss << "killcursors ";
receivedKillCursors(m);
}
catch( AssertionException ) {
cout << "Caught Assertion in kill cursors, continuing" << endl;
ss << " exception ";
}
}
else {
cout << " jnicall: operation isn't supported: " << m.data->operation << endl;
assert(false);
}
int ms = t.millis();
log = log || ctr++ % 128 == 0;
if( log || ms > 100 ) {
ss << ' ' << t.millis() << "ms";
cout << ss.str().c_str() << endl;
}
if( client && client->profile >= 1 ) {
if( client->profile >= 2 || ms >= 100 ) {
// profile it
profile(ss.str().c_str()+20/*skip ts*/, ms);
}
}
}
}
catch( AssertionException ) {
cout << "Caught AssertionException in jniCall()" << endl;
}
curOp = curOpOld;
callDepth--;
if( client != clientOld ) {
client = clientOld;
wassert(false);
}
2008-03-24 23:04:22 +01:00
}
void connThread()
2007-12-08 21:50:47 +01:00
{
2008-02-10 22:28:48 +01:00
try {
2007-12-08 21:50:47 +01:00
MessagingPort& dbMsgPort = *grab;
grab = 0;
2007-10-20 01:35:48 +02:00
Message m;
while( 1 ) {
2008-03-17 01:59:19 +01:00
client = 0;
2008-02-26 01:13:30 +01:00
curOp = 0;
2007-10-20 01:35:48 +02:00
m.reset();
2007-12-01 17:44:42 +01:00
stringstream ss;
2007-10-20 01:35:48 +02:00
if( !dbMsgPort.recv(m) ) {
2007-12-08 21:50:47 +01:00
cout << "MessagingPort::recv(): returned false" << endl;
dbMsgPort.shutdown();
2007-10-20 01:35:48 +02:00
break;
}
2007-11-18 19:33:00 +01:00
2008-02-24 17:29:42 +01:00
char buf[64];
time_t_to_String(time(0), buf);
buf[20] = 0; // don't want the year
ss << buf;
// ss << curTimeMillis() % 10000 << ' ';
2007-12-01 17:44:42 +01:00
2007-12-08 21:50:47 +01:00
{
lock lk(dbMutex);
Timer t;
2008-02-29 18:03:03 +01:00
bool log = false;
2008-02-10 22:28:48 +01:00
curOp = m.data->operation;
2007-12-08 21:50:47 +01:00
if( m.data->operation == dbMsg ) {
ss << "msg ";
char *p = m.data->_data;
int len = strlen(p);
if( len > 400 )
cout << curTimeMillis() % 10000 <<
" long msg received, len:" << len <<
" ends with: " << p + len - 10 << endl;
bool end = strcmp("end", p) == 0;
Message resp;
resp.setData(opReply, "i am fine");
dbMsgPort.reply(m, resp);
if( end ) {
cout << curTimeMillis() % 10000 << " end msg" << endl;
dbMsgPort.shutdown();
sleepmillis(500);
exit(1);
}
}
else if( m.data->operation == dbQuery ) {
2008-02-29 18:03:03 +01:00
#if defined(_WIN32)
2008-03-17 01:59:19 +01:00
log = true;
2008-02-29 18:03:03 +01:00
#endif
2007-12-08 21:50:47 +01:00
receivedQuery(dbMsgPort, m, ss);
}
else if( m.data->operation == dbInsert ) {
2008-02-17 04:23:37 +01:00
try {
ss << "insert ";
receivedInsert(m, ss);
}
2008-03-17 01:59:19 +01:00
catch( AssertionException ) {
cout << "Caught Assertion, continuing" << endl;
ss << " exception ";
}
2007-12-08 21:50:47 +01:00
}
else if( m.data->operation == dbUpdate ) {
2008-02-17 04:23:37 +01:00
try {
ss << "update ";
2008-03-17 01:59:19 +01:00
receivedUpdate(m, ss);
}
catch( AssertionException ) {
cout << "Caught Assertion, continuing" << endl;
ss << " exception ";
2008-02-17 04:23:37 +01:00
}
2007-12-08 21:50:47 +01:00
}
else if( m.data->operation == dbDelete ) {
2008-02-17 04:23:37 +01:00
try {
ss << "remove ";
receivedDelete(m);
}
2008-03-17 01:59:19 +01:00
catch( AssertionException ) {
cout << "Caught Assertion, continuing" << endl;
ss << " exception ";
}
2007-12-08 21:50:47 +01:00
}
else if( m.data->operation == dbGetMore ) {
2008-02-29 18:03:03 +01:00
log = true;
2007-12-08 21:50:47 +01:00
ss << "getmore ";
2008-03-17 01:59:19 +01:00
receivedGetMore(dbMsgPort, m, ss);
2007-12-08 21:50:47 +01:00
}
2008-02-13 06:26:39 +01:00
else if( m.data->operation == dbKillCursors ) {
2008-03-05 22:51:27 +01:00
try {
log = true;
ss << "killcursors ";
receivedKillCursors(m);
}
2008-03-17 01:59:19 +01:00
catch( AssertionException ) {
cout << "Caught Assertion in kill cursors, continuing" << endl;
ss << " exception ";
}
2008-02-13 06:26:39 +01:00
}
2007-12-08 21:50:47 +01:00
else {
2008-02-26 01:13:30 +01:00
cout << " operation isn't supported: " << m.data->operation << endl;
assert(false);
2007-10-20 01:35:48 +02:00
}
2007-12-01 17:44:42 +01:00
2008-02-14 18:50:13 +01:00
int ms = t.millis();
2008-03-17 01:59:19 +01:00
log = log || ctr++ % 128 == 0;
if( log || ms > 100 ) {
2008-02-14 18:50:13 +01:00
ss << ' ' << t.millis() << "ms";
cout << ss.str().c_str() << endl;
}
2008-03-17 01:59:19 +01:00
if( client && client->profile >= 1 ) {
if( client->profile >= 2 || ms >= 100 ) {
// profile it
profile(ss.str().c_str()+20/*skip ts*/, ms);
}
}
2007-12-08 21:50:47 +01:00
}
2007-10-20 01:35:48 +02:00
}
2008-02-10 22:28:48 +01:00
}
catch( AssertionException ) {
cout << "Caught AssertionException, terminating" << endl;
exit(-7);
}
2007-10-20 01:35:48 +02:00
}
2007-11-05 21:12:45 +01:00
void msg(const char *m, int extras = 0) {
2007-12-08 21:50:47 +01:00
SockAddr db("127.0.0.1", DBPort);
2007-11-27 01:38:14 +01:00
// SockAddr db("192.168.37.1", MessagingPort::DBPort);
2007-11-05 17:29:12 +01:00
// SockAddr db("10.0.21.60", MessagingPort::DBPort);
2007-11-05 21:12:45 +01:00
// SockAddr db("172.16.0.179", MessagingPort::DBPort);
2007-10-20 01:35:48 +02:00
MessagingPort p;
2007-12-08 21:50:47 +01:00
if( !p.connect(db) )
return;
for( int q = 0; q < 3; q++ ) {
Message send;
Message response;
send.setData( dbMsg , m);
int len = send.data->dataLen();
for( int i = 0; i < extras; i++ )
p.say(db, send);
Timer t;
bool ok = p.call(db, send, response);
double tm = t.micros() + 1;
cout << " ****ok. response.data:" << ok << " time:" << tm / 1000.0 << "ms " <<
((double) len) * 8 / 1000000 / (tm/1000000) << "Mbps" << endl;
if( q+1 < 3 ) {
cout << "\t\tSLEEP 8 then sending again" << endl;
sleepsecs(8);
}
}
2007-11-26 22:19:50 +01:00
2007-11-18 19:33:00 +01:00
p.shutdown();
2007-10-20 01:35:48 +02:00
}
int main(int argc, char* argv[], char *envp[] )
{
2007-11-18 03:10:00 +01:00
srand(curTimeMillis());
2007-10-20 01:35:48 +02:00
if( argc >= 2 ) {
2007-11-27 21:32:02 +01:00
if( strcmp(argv[1], "quicktest") == 0 ) {
quicktest();
return 0;
2007-11-27 21:32:02 +01:00
}
2007-10-20 01:35:48 +02:00
if( strcmp(argv[1], "msg") == 0 ) {
msg(argc >= 3 ? argv[2] : "ping");
2007-11-18 03:10:00 +01:00
goingAway = true;
2007-10-20 01:35:48 +02:00
return 0;
}
2007-11-05 21:12:45 +01:00
if( strcmp(argv[1], "msglots") == 0 ) {
msg(argc >= 3 ? argv[2] : "ping", 1000);
2007-11-18 03:10:00 +01:00
goingAway = true;
2007-11-05 21:12:45 +01:00
return 0;
}
2007-11-27 21:30:51 +01:00
if( strcmp(argv[1], "dev") == 0 ) {
2007-12-01 04:04:04 +01:00
dbpath = "/home/dwight/db/";
cout << "dev mode: expect db files in " << dbpath << endl;
quicktest();
2007-11-27 21:30:51 +01:00
port++;
cout << "listening on port " << port << endl;
2007-12-08 21:50:47 +01:00
listen(port);
2007-11-27 21:30:51 +01:00
goingAway = true;
return 0;
}
2007-10-20 01:35:48 +02:00
if( strcmp(argv[1], "run") == 0 ) {
2008-03-30 05:30:44 +02:00
JavaJS = new JavaJSImpl();
javajstest();
2007-12-08 21:50:47 +01:00
listen(port);
2007-11-18 03:10:00 +01:00
goingAway = true;
2007-10-20 01:35:48 +02:00
return 0;
}
2007-11-05 17:29:12 +01:00
if( strcmp(argv[1], "longmsg") == 0 ) {
2007-11-26 22:19:50 +01:00
char buf[800000];
memset(buf, 'a', 799999);
buf[799999] = 0;
buf[799998] = 'b';
2007-11-18 19:33:00 +01:00
buf[0] = 'c';
2007-11-05 17:29:12 +01:00
msg(buf);
2007-11-18 03:10:00 +01:00
goingAway = true;
2007-11-05 17:29:12 +01:00
return 0;
}
2007-10-20 01:35:48 +02:00
}
cout << "usage:\n";
cout << " quicktest just check basic assertions and exit" << endl;
cout << " msg [msg] send a request to the db server" << endl;
cout << " msg end shut down" << endl;
cout << " run run db" << endl;
2007-12-01 04:04:04 +01:00
cout << " dev run in dev mode (diff db loc, diff port #)" << endl;
2007-11-05 17:29:12 +01:00
cout << " longmsg send a long test message to the db server" << endl;
2008-03-09 16:05:25 +01:00
cout << " msglots send a bunch of test messages, and then wait for answer on the last one" << endl;
2007-11-18 03:10:00 +01:00
goingAway = true;
2007-10-20 01:35:48 +02:00
return 0;
}
//#if !defined(_WIN32)
//int main( int argc, char *argv[], char *envp[] ) {
// return _tmain(argc, 0);
//}
//#endif