quickfix_ruby 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/quickfix/Acceptor.cpp +248 -0
- data/ext/quickfix/Acceptor.h +127 -0
- data/ext/quickfix/Allocator.h +9 -0
- data/ext/quickfix/Application.h +127 -0
- data/ext/quickfix/AtomicCount.h +109 -0
- data/ext/quickfix/DOMDocument.h +74 -0
- data/ext/quickfix/DataDictionary.cpp +618 -0
- data/ext/quickfix/DataDictionary.h +539 -0
- data/ext/quickfix/DataDictionaryProvider.cpp +71 -0
- data/ext/quickfix/DataDictionaryProvider.h +70 -0
- data/ext/quickfix/DatabaseConnectionID.h +105 -0
- data/ext/quickfix/DatabaseConnectionPool.h +91 -0
- data/ext/quickfix/Dictionary.cpp +162 -0
- data/ext/quickfix/Dictionary.h +94 -0
- data/ext/quickfix/Event.h +95 -0
- data/ext/quickfix/Exceptions.h +299 -0
- data/ext/quickfix/Field.h +672 -0
- data/ext/quickfix/FieldConvertors.h +863 -0
- data/ext/quickfix/FieldMap.cpp +238 -0
- data/ext/quickfix/FieldMap.h +244 -0
- data/ext/quickfix/FieldNumbers.h +46 -0
- data/ext/quickfix/FieldTypes.cpp +64 -0
- data/ext/quickfix/FieldTypes.h +698 -0
- data/ext/quickfix/Fields.h +31 -0
- data/ext/quickfix/FileLog.cpp +200 -0
- data/ext/quickfix/FileLog.h +112 -0
- data/ext/quickfix/FileStore.cpp +332 -0
- data/ext/quickfix/FileStore.h +129 -0
- data/ext/quickfix/FixFieldNumbers.h +1537 -0
- data/ext/quickfix/FixFields.h +1538 -0
- data/ext/quickfix/FixValues.h +3281 -0
- data/ext/quickfix/FlexLexer.h +188 -0
- data/ext/quickfix/Group.cpp +64 -0
- data/ext/quickfix/Group.h +73 -0
- data/ext/quickfix/HtmlBuilder.h +186 -0
- data/ext/quickfix/HttpConnection.cpp +739 -0
- data/ext/quickfix/HttpConnection.h +78 -0
- data/ext/quickfix/HttpMessage.cpp +149 -0
- data/ext/quickfix/HttpMessage.h +133 -0
- data/ext/quickfix/HttpParser.cpp +49 -0
- data/ext/quickfix/HttpParser.h +54 -0
- data/ext/quickfix/HttpServer.cpp +169 -0
- data/ext/quickfix/HttpServer.h +78 -0
- data/ext/quickfix/Initiator.cpp +289 -0
- data/ext/quickfix/Initiator.h +149 -0
- data/ext/quickfix/Log.cpp +77 -0
- data/ext/quickfix/Log.h +179 -0
- data/ext/quickfix/Message.cpp +580 -0
- data/ext/quickfix/Message.h +370 -0
- data/ext/quickfix/MessageCracker.h +188 -0
- data/ext/quickfix/MessageSorters.cpp +105 -0
- data/ext/quickfix/MessageSorters.h +156 -0
- data/ext/quickfix/MessageStore.cpp +146 -0
- data/ext/quickfix/MessageStore.h +174 -0
- data/ext/quickfix/Mutex.h +131 -0
- data/ext/quickfix/MySQLConnection.h +194 -0
- data/ext/quickfix/MySQLLog.cpp +275 -0
- data/ext/quickfix/MySQLLog.h +145 -0
- data/ext/quickfix/MySQLStore.cpp +331 -0
- data/ext/quickfix/MySQLStore.h +142 -0
- data/ext/quickfix/NullStore.cpp +54 -0
- data/ext/quickfix/NullStore.h +99 -0
- data/ext/quickfix/OdbcConnection.h +266 -0
- data/ext/quickfix/OdbcLog.cpp +252 -0
- data/ext/quickfix/OdbcLog.h +117 -0
- data/ext/quickfix/OdbcStore.cpp +338 -0
- data/ext/quickfix/OdbcStore.h +113 -0
- data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
- data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
- data/ext/quickfix/Parser.cpp +103 -0
- data/ext/quickfix/Parser.h +57 -0
- data/ext/quickfix/PostgreSQLConnection.h +176 -0
- data/ext/quickfix/PostgreSQLLog.cpp +276 -0
- data/ext/quickfix/PostgreSQLLog.h +144 -0
- data/ext/quickfix/PostgreSQLStore.cpp +334 -0
- data/ext/quickfix/PostgreSQLStore.h +141 -0
- data/ext/quickfix/Queue.h +75 -0
- data/ext/quickfix/QuickfixRuby.cpp +252066 -0
- data/ext/quickfix/QuickfixRuby.h +34 -0
- data/ext/quickfix/Responder.h +43 -0
- data/ext/quickfix/Session.cpp +1487 -0
- data/ext/quickfix/Session.h +335 -0
- data/ext/quickfix/SessionFactory.cpp +274 -0
- data/ext/quickfix/SessionFactory.h +86 -0
- data/ext/quickfix/SessionID.h +170 -0
- data/ext/quickfix/SessionSettings.cpp +189 -0
- data/ext/quickfix/SessionSettings.h +171 -0
- data/ext/quickfix/SessionState.h +231 -0
- data/ext/quickfix/Settings.cpp +100 -0
- data/ext/quickfix/Settings.h +53 -0
- data/ext/quickfix/SharedArray.h +150 -0
- data/ext/quickfix/SocketAcceptor.cpp +222 -0
- data/ext/quickfix/SocketAcceptor.h +75 -0
- data/ext/quickfix/SocketConnection.cpp +238 -0
- data/ext/quickfix/SocketConnection.h +103 -0
- data/ext/quickfix/SocketConnector.cpp +116 -0
- data/ext/quickfix/SocketConnector.h +67 -0
- data/ext/quickfix/SocketInitiator.cpp +260 -0
- data/ext/quickfix/SocketInitiator.h +81 -0
- data/ext/quickfix/SocketMonitor.cpp +335 -0
- data/ext/quickfix/SocketMonitor.h +111 -0
- data/ext/quickfix/SocketServer.cpp +177 -0
- data/ext/quickfix/SocketServer.h +100 -0
- data/ext/quickfix/ThreadedSocketAcceptor.cpp +258 -0
- data/ext/quickfix/ThreadedSocketAcceptor.h +98 -0
- data/ext/quickfix/ThreadedSocketConnection.cpp +209 -0
- data/ext/quickfix/ThreadedSocketConnection.h +82 -0
- data/ext/quickfix/ThreadedSocketInitiator.cpp +268 -0
- data/ext/quickfix/ThreadedSocketInitiator.h +84 -0
- data/ext/quickfix/TimeRange.cpp +173 -0
- data/ext/quickfix/TimeRange.h +258 -0
- data/ext/quickfix/Utility.cpp +537 -0
- data/ext/quickfix/Utility.h +219 -0
- data/ext/quickfix/Values.h +62 -0
- data/ext/quickfix/config.h +0 -0
- data/ext/quickfix/config_windows.h +0 -0
- data/ext/quickfix/extconf.rb +12 -0
- data/ext/quickfix/index.h +37 -0
- data/ext/quickfix/pugiconfig.hpp +72 -0
- data/ext/quickfix/pugixml.cpp +10765 -0
- data/ext/quickfix/pugixml.hpp +1341 -0
- data/ext/quickfix/strptime.h +7 -0
- data/lib/quickfix40.rb +274 -0
- data/lib/quickfix41.rb +351 -0
- data/lib/quickfix42.rb +1184 -0
- data/lib/quickfix43.rb +3504 -0
- data/lib/quickfix44.rb +10721 -0
- data/lib/quickfix50.rb +13426 -0
- data/lib/quickfix50sp1.rb +15629 -0
- data/lib/quickfix50sp2.rb +17068 -0
- data/lib/quickfix_fields.rb +19853 -0
- data/lib/quickfix_ruby.rb +82 -0
- data/lib/quickfixt11.rb +70 -0
- data/spec/FIX40.xml +862 -0
- data/spec/FIX41.xml +1285 -0
- data/spec/FIX42.xml +2746 -0
- data/spec/FIX43.xml +4229 -0
- data/spec/FIX44.xml +6596 -0
- data/spec/FIX50.xml +8137 -0
- data/spec/FIX50SP1.xml +9496 -0
- data/spec/FIX50SP2.xml +10011 -0
- data/spec/FIXT11.xml +313 -0
- data/test/test_DataDictionaryTestCase.rb +268 -0
- data/test/test_DictionaryTestCase.rb +112 -0
- data/test/test_FieldBaseTestCase.rb +24 -0
- data/test/test_MessageTestCase.rb +368 -0
- data/test/test_SessionSettingsTestCase.rb +41 -0
- metadata +193 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/****************************************************************************
|
|
2
|
+
** Copyright (c) 2001-2014
|
|
3
|
+
**
|
|
4
|
+
** This file is part of the QuickFIX FIX Engine
|
|
5
|
+
**
|
|
6
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
7
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
8
|
+
** LICENSE included in the packaging of this file.
|
|
9
|
+
**
|
|
10
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
11
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
**
|
|
13
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
14
|
+
**
|
|
15
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
16
|
+
** not clear to you.
|
|
17
|
+
**
|
|
18
|
+
****************************************************************************/
|
|
19
|
+
|
|
20
|
+
#ifdef _MSC_VER
|
|
21
|
+
#include "stdafx.h"
|
|
22
|
+
#else
|
|
23
|
+
#include "config.h"
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#ifdef HAVE_MYSQL
|
|
27
|
+
|
|
28
|
+
#include "MySQLStore.h"
|
|
29
|
+
#include "SessionID.h"
|
|
30
|
+
#include "SessionSettings.h"
|
|
31
|
+
#include "FieldConvertors.h"
|
|
32
|
+
#include "Parser.h"
|
|
33
|
+
#include "Utility.h"
|
|
34
|
+
#include "strptime.h"
|
|
35
|
+
#include <fstream>
|
|
36
|
+
|
|
37
|
+
namespace FIX
|
|
38
|
+
{
|
|
39
|
+
|
|
40
|
+
const std::string MySQLStoreFactory::DEFAULT_DATABASE = "quickfix";
|
|
41
|
+
const std::string MySQLStoreFactory::DEFAULT_USER = "";
|
|
42
|
+
const std::string MySQLStoreFactory::DEFAULT_PASSWORD = "";
|
|
43
|
+
const std::string MySQLStoreFactory::DEFAULT_HOST = "localhost";
|
|
44
|
+
const short MySQLStoreFactory::DEFAULT_PORT = 3306;
|
|
45
|
+
|
|
46
|
+
MySQLStore::MySQLStore
|
|
47
|
+
( const SessionID& s, const DatabaseConnectionID& d, MySQLConnectionPool* p )
|
|
48
|
+
: m_pConnectionPool( p ), m_sessionID( s )
|
|
49
|
+
{
|
|
50
|
+
m_pConnection = m_pConnectionPool->create( d );
|
|
51
|
+
populateCache();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
MySQLStore::MySQLStore
|
|
55
|
+
( const SessionID& s, const std::string& database, const std::string& user,
|
|
56
|
+
const std::string& password, const std::string& host, short port )
|
|
57
|
+
: m_pConnectionPool( 0 ), m_sessionID( s )
|
|
58
|
+
{
|
|
59
|
+
m_pConnection = new MySQLConnection( database, user, password, host, port );
|
|
60
|
+
populateCache();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
MySQLStore::~MySQLStore()
|
|
64
|
+
{
|
|
65
|
+
if( m_pConnectionPool )
|
|
66
|
+
m_pConnectionPool->destroy( m_pConnection );
|
|
67
|
+
else
|
|
68
|
+
delete m_pConnection;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
void MySQLStore::populateCache()
|
|
72
|
+
{
|
|
73
|
+
std::stringstream queryString;
|
|
74
|
+
|
|
75
|
+
queryString << "SELECT creation_time, incoming_seqnum, outgoing_seqnum FROM sessions WHERE "
|
|
76
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
77
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
78
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
79
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\"";
|
|
80
|
+
|
|
81
|
+
MySQLQuery query( queryString.str() );
|
|
82
|
+
if( !m_pConnection->execute(query) )
|
|
83
|
+
throw ConfigError( "No entries found for session in database" );
|
|
84
|
+
|
|
85
|
+
int rows = query.rows();
|
|
86
|
+
if( rows > 1 )
|
|
87
|
+
throw ConfigError( "Multiple entries found for session in database" );
|
|
88
|
+
|
|
89
|
+
if( rows == 1 )
|
|
90
|
+
{
|
|
91
|
+
struct tm time;
|
|
92
|
+
std::string sqlTime = query.getValue( 0, 0 );
|
|
93
|
+
strptime( sqlTime.c_str(), "%Y-%m-%d %H:%M:%S", &time );
|
|
94
|
+
m_cache.setCreationTime (UtcTimeStamp (&time));
|
|
95
|
+
m_cache.setNextTargetMsgSeqNum( atol( query.getValue( 0, 1 ) ) );
|
|
96
|
+
m_cache.setNextSenderMsgSeqNum( atol( query.getValue( 0, 2 ) ) );
|
|
97
|
+
}
|
|
98
|
+
else
|
|
99
|
+
{
|
|
100
|
+
UtcTimeStamp time = m_cache.getCreationTime();
|
|
101
|
+
char sqlTime[ 20 ];
|
|
102
|
+
int year, month, day, hour, minute, second, millis;
|
|
103
|
+
time.getYMD (year, month, day);
|
|
104
|
+
time.getHMS (hour, minute, second, millis);
|
|
105
|
+
STRING_SPRINTF( sqlTime, "%d-%02d-%02d %02d:%02d:%02d",
|
|
106
|
+
year, month, day, hour, minute, second );
|
|
107
|
+
std::stringstream queryString2;
|
|
108
|
+
queryString2 << "INSERT INTO sessions (beginstring, sendercompid, targetcompid, session_qualifier,"
|
|
109
|
+
<< "creation_time, incoming_seqnum, outgoing_seqnum) VALUES("
|
|
110
|
+
<< "\"" << m_sessionID.getBeginString().getValue() << "\","
|
|
111
|
+
<< "\"" << m_sessionID.getSenderCompID().getValue() << "\","
|
|
112
|
+
<< "\"" << m_sessionID.getTargetCompID().getValue() << "\","
|
|
113
|
+
<< "\"" << m_sessionID.getSessionQualifier() << "\","
|
|
114
|
+
<< "'" << sqlTime << "',"
|
|
115
|
+
<< m_cache.getNextTargetMsgSeqNum() << ","
|
|
116
|
+
<< m_cache.getNextSenderMsgSeqNum() << ")";
|
|
117
|
+
|
|
118
|
+
MySQLQuery query2( queryString2.str() );
|
|
119
|
+
if( !m_pConnection->execute(query2) )
|
|
120
|
+
throw ConfigError( "Unable to create session in database" );
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
MessageStore* MySQLStoreFactory::create( const SessionID& s )
|
|
125
|
+
{
|
|
126
|
+
if( m_useSettings )
|
|
127
|
+
return create( s, m_settings.get(s) );
|
|
128
|
+
else if( m_useDictionary )
|
|
129
|
+
return create( s, m_dictionary );
|
|
130
|
+
else
|
|
131
|
+
{
|
|
132
|
+
DatabaseConnectionID id( m_database, m_user, m_password, m_host, m_port );
|
|
133
|
+
return new MySQLStore( s, id, m_connectionPoolPtr.get() );
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
MessageStore* MySQLStoreFactory::create( const SessionID& s, const Dictionary& settings )
|
|
138
|
+
{
|
|
139
|
+
std::string database = DEFAULT_DATABASE;
|
|
140
|
+
std::string user = DEFAULT_USER;
|
|
141
|
+
std::string password = DEFAULT_PASSWORD;
|
|
142
|
+
std::string host = DEFAULT_HOST;
|
|
143
|
+
short port = DEFAULT_PORT;
|
|
144
|
+
|
|
145
|
+
try { database = settings.getString( MYSQL_STORE_DATABASE ); }
|
|
146
|
+
catch( ConfigError& ) {}
|
|
147
|
+
|
|
148
|
+
try { user = settings.getString( MYSQL_STORE_USER ); }
|
|
149
|
+
catch( ConfigError& ) {}
|
|
150
|
+
|
|
151
|
+
try { password = settings.getString( MYSQL_STORE_PASSWORD ); }
|
|
152
|
+
catch( ConfigError& ) {}
|
|
153
|
+
|
|
154
|
+
try { host = settings.getString( MYSQL_STORE_HOST ); }
|
|
155
|
+
catch( ConfigError& ) {}
|
|
156
|
+
|
|
157
|
+
try { port = ( short ) settings.getInt( MYSQL_STORE_PORT ); }
|
|
158
|
+
catch( ConfigError& ) {}
|
|
159
|
+
|
|
160
|
+
DatabaseConnectionID id( database, user, password, host, port );
|
|
161
|
+
return new MySQLStore( s, id, m_connectionPoolPtr.get() );
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void MySQLStoreFactory::destroy( MessageStore* pStore )
|
|
165
|
+
{
|
|
166
|
+
delete pStore;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
bool MySQLStore::set( int msgSeqNum, const std::string& msg )
|
|
170
|
+
throw ( IOException )
|
|
171
|
+
{
|
|
172
|
+
char* msgCopy = new char[ (msg.size() * 2) + 1 ];
|
|
173
|
+
mysql_escape_string( msgCopy, msg.c_str(), msg.size() );
|
|
174
|
+
|
|
175
|
+
std::stringstream queryString;
|
|
176
|
+
queryString << "INSERT INTO messages "
|
|
177
|
+
<< "(beginstring, sendercompid, targetcompid, session_qualifier, msgseqnum, message) "
|
|
178
|
+
<< "VALUES ("
|
|
179
|
+
<< "\"" << m_sessionID.getBeginString().getValue() << "\","
|
|
180
|
+
<< "\"" << m_sessionID.getSenderCompID().getValue() << "\","
|
|
181
|
+
<< "\"" << m_sessionID.getTargetCompID().getValue() << "\","
|
|
182
|
+
<< "\"" << m_sessionID.getSessionQualifier() << "\","
|
|
183
|
+
<< msgSeqNum << ","
|
|
184
|
+
<< "\"" << msgCopy << "\")";
|
|
185
|
+
|
|
186
|
+
delete [] msgCopy;
|
|
187
|
+
|
|
188
|
+
MySQLQuery query( queryString.str() );
|
|
189
|
+
if( !m_pConnection->execute(query) )
|
|
190
|
+
{
|
|
191
|
+
std::stringstream queryString2;
|
|
192
|
+
queryString2 << "UPDATE messages SET message=\"" << msg << "\" WHERE "
|
|
193
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
194
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
195
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
196
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\" and "
|
|
197
|
+
<< "msgseqnum=" << msgSeqNum;
|
|
198
|
+
MySQLQuery query2( queryString2.str() );
|
|
199
|
+
if( !m_pConnection->execute(query2) )
|
|
200
|
+
query2.throwException();
|
|
201
|
+
}
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
void MySQLStore::get( int begin, int end,
|
|
206
|
+
std::vector < std::string > & result ) const
|
|
207
|
+
throw ( IOException )
|
|
208
|
+
{
|
|
209
|
+
result.clear();
|
|
210
|
+
std::stringstream queryString;
|
|
211
|
+
queryString << "SELECT message FROM messages WHERE "
|
|
212
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
213
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
214
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
215
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\" and "
|
|
216
|
+
<< "msgseqnum>=" << begin << " and " << "msgseqnum<=" << end << " "
|
|
217
|
+
<< "ORDER BY msgseqnum";
|
|
218
|
+
|
|
219
|
+
MySQLQuery query( queryString.str() );
|
|
220
|
+
if( !m_pConnection->execute(query) )
|
|
221
|
+
query.throwException();
|
|
222
|
+
|
|
223
|
+
int rows = query.rows();
|
|
224
|
+
for( int row = 0; row < rows; row++ )
|
|
225
|
+
result.push_back( query.getValue( row, 0 ) );
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
int MySQLStore::getNextSenderMsgSeqNum() const throw ( IOException )
|
|
229
|
+
{
|
|
230
|
+
return m_cache.getNextSenderMsgSeqNum();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
int MySQLStore::getNextTargetMsgSeqNum() const throw ( IOException )
|
|
234
|
+
{
|
|
235
|
+
return m_cache.getNextTargetMsgSeqNum();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
void MySQLStore::setNextSenderMsgSeqNum( int value ) throw ( IOException )
|
|
239
|
+
{
|
|
240
|
+
std::stringstream queryString;
|
|
241
|
+
queryString << "UPDATE sessions SET outgoing_seqnum=" << value << " WHERE "
|
|
242
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
243
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
244
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
245
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\"";
|
|
246
|
+
MySQLQuery query( queryString.str() );
|
|
247
|
+
if( !m_pConnection->execute(query) )
|
|
248
|
+
query.throwException();
|
|
249
|
+
m_cache.setNextSenderMsgSeqNum( value );
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
void MySQLStore::setNextTargetMsgSeqNum( int value ) throw ( IOException )
|
|
253
|
+
{
|
|
254
|
+
std::stringstream queryString;
|
|
255
|
+
queryString << "UPDATE sessions SET incoming_seqnum=" << value << " WHERE "
|
|
256
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
257
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
258
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
259
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\"";
|
|
260
|
+
|
|
261
|
+
MySQLQuery query( queryString.str() );
|
|
262
|
+
if( !m_pConnection->execute(query) )
|
|
263
|
+
query.throwException();
|
|
264
|
+
|
|
265
|
+
m_cache.setNextTargetMsgSeqNum( value );
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
void MySQLStore::incrNextSenderMsgSeqNum() throw ( IOException )
|
|
269
|
+
{
|
|
270
|
+
m_cache.incrNextSenderMsgSeqNum();
|
|
271
|
+
setNextSenderMsgSeqNum( m_cache.getNextSenderMsgSeqNum() );
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
void MySQLStore::incrNextTargetMsgSeqNum() throw ( IOException )
|
|
275
|
+
{
|
|
276
|
+
m_cache.incrNextTargetMsgSeqNum();
|
|
277
|
+
setNextTargetMsgSeqNum( m_cache.getNextTargetMsgSeqNum() );
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
UtcTimeStamp MySQLStore::getCreationTime() const throw ( IOException )
|
|
281
|
+
{
|
|
282
|
+
return m_cache.getCreationTime();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
void MySQLStore::reset() throw ( IOException )
|
|
286
|
+
{
|
|
287
|
+
std::stringstream queryString;
|
|
288
|
+
queryString << "DELETE FROM messages WHERE "
|
|
289
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
290
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
291
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
292
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\"";
|
|
293
|
+
|
|
294
|
+
MySQLQuery query( queryString.str() );
|
|
295
|
+
if( !m_pConnection->execute(query) )
|
|
296
|
+
query.throwException();
|
|
297
|
+
|
|
298
|
+
m_cache.reset();
|
|
299
|
+
UtcTimeStamp time = m_cache.getCreationTime();
|
|
300
|
+
|
|
301
|
+
int year, month, day, hour, minute, second, millis;
|
|
302
|
+
time.getYMD( year, month, day );
|
|
303
|
+
time.getHMS( hour, minute, second, millis );
|
|
304
|
+
|
|
305
|
+
char sqlTime[ 20 ];
|
|
306
|
+
STRING_SPRINTF( sqlTime, "%d-%02d-%02d %02d:%02d:%02d",
|
|
307
|
+
year, month, day, hour, minute, second );
|
|
308
|
+
|
|
309
|
+
std::stringstream queryString2;
|
|
310
|
+
queryString2 << "UPDATE sessions SET creation_time='" << sqlTime << "', "
|
|
311
|
+
<< "incoming_seqnum=" << m_cache.getNextTargetMsgSeqNum() << ", "
|
|
312
|
+
<< "outgoing_seqnum=" << m_cache.getNextSenderMsgSeqNum() << " WHERE "
|
|
313
|
+
<< "beginstring=" << "\"" << m_sessionID.getBeginString().getValue() << "\" and "
|
|
314
|
+
<< "sendercompid=" << "\"" << m_sessionID.getSenderCompID().getValue() << "\" and "
|
|
315
|
+
<< "targetcompid=" << "\"" << m_sessionID.getTargetCompID().getValue() << "\" and "
|
|
316
|
+
<< "session_qualifier=" << "\"" << m_sessionID.getSessionQualifier() << "\"";
|
|
317
|
+
|
|
318
|
+
MySQLQuery query2( queryString2.str() );
|
|
319
|
+
if( !m_pConnection->execute(query2) )
|
|
320
|
+
query2.throwException();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
void MySQLStore::refresh() throw ( IOException )
|
|
324
|
+
{
|
|
325
|
+
m_cache.reset();
|
|
326
|
+
populateCache();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
#endif
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/* -*- C++ -*- */
|
|
2
|
+
|
|
3
|
+
/****************************************************************************
|
|
4
|
+
** Copyright (c) 2001-2014
|
|
5
|
+
**
|
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
|
7
|
+
**
|
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
10
|
+
** LICENSE included in the packaging of this file.
|
|
11
|
+
**
|
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
**
|
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
16
|
+
**
|
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
18
|
+
** not clear to you.
|
|
19
|
+
**
|
|
20
|
+
****************************************************************************/
|
|
21
|
+
|
|
22
|
+
#ifndef HAVE_MYSQL
|
|
23
|
+
#error MySQLStore.h included, but HAVE_MYSQL not defined
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#ifdef HAVE_MYSQL
|
|
27
|
+
#ifndef FIX_MYSQLSTORE_H
|
|
28
|
+
#define FIX_MYSQLSTORE_H
|
|
29
|
+
|
|
30
|
+
#ifdef _MSC_VER
|
|
31
|
+
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
32
|
+
#pragma comment( lib, "libMySQL" )
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
#include "MessageStore.h"
|
|
36
|
+
#include "SessionSettings.h"
|
|
37
|
+
#include "MySQLConnection.h"
|
|
38
|
+
#include <fstream>
|
|
39
|
+
#include <string>
|
|
40
|
+
|
|
41
|
+
namespace FIX
|
|
42
|
+
{
|
|
43
|
+
/// Creates a MySQL based implementation of MessageStore.
|
|
44
|
+
class MySQLStoreFactory : public MessageStoreFactory
|
|
45
|
+
{
|
|
46
|
+
public:
|
|
47
|
+
static const std::string DEFAULT_DATABASE;
|
|
48
|
+
static const std::string DEFAULT_USER;
|
|
49
|
+
static const std::string DEFAULT_PASSWORD;
|
|
50
|
+
static const std::string DEFAULT_HOST;
|
|
51
|
+
static const short DEFAULT_PORT;
|
|
52
|
+
|
|
53
|
+
MySQLStoreFactory( const SessionSettings& settings )
|
|
54
|
+
: m_settings( settings ), m_useSettings( true ), m_useDictionary( false )
|
|
55
|
+
{
|
|
56
|
+
bool poolConnections = false;
|
|
57
|
+
try { poolConnections = settings.get().getBool(MYSQL_STORE_USECONNECTIONPOOL); }
|
|
58
|
+
catch( ConfigError& ) {}
|
|
59
|
+
|
|
60
|
+
m_connectionPoolPtr = MySQLConnectionPoolPtr
|
|
61
|
+
( new MySQLConnectionPool(poolConnections) );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
MySQLStoreFactory( const Dictionary& dictionary )
|
|
65
|
+
: m_dictionary( dictionary ), m_useSettings( false ), m_useDictionary( true )
|
|
66
|
+
{
|
|
67
|
+
m_connectionPoolPtr = MySQLConnectionPoolPtr
|
|
68
|
+
( new MySQLConnectionPool(false) );
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
MySQLStoreFactory( const std::string& database, const std::string& user,
|
|
72
|
+
const std::string& password, const std::string& host,
|
|
73
|
+
short port )
|
|
74
|
+
: m_database( database ), m_user( user ), m_password( password ), m_host( host ), m_port( port ),
|
|
75
|
+
m_useSettings( false ), m_useDictionary( false )
|
|
76
|
+
{
|
|
77
|
+
m_connectionPoolPtr = MySQLConnectionPoolPtr
|
|
78
|
+
( new MySQLConnectionPool(false) );
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
MySQLStoreFactory()
|
|
82
|
+
: m_database( DEFAULT_DATABASE ), m_user( DEFAULT_USER ), m_password( DEFAULT_PASSWORD ),
|
|
83
|
+
m_host( DEFAULT_HOST ), m_port( DEFAULT_PORT ), m_useSettings( false ), m_useDictionary( false )
|
|
84
|
+
{
|
|
85
|
+
m_connectionPoolPtr = MySQLConnectionPoolPtr
|
|
86
|
+
( new MySQLConnectionPool(false) );
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
MessageStore* create( const SessionID& );
|
|
90
|
+
void destroy( MessageStore* );
|
|
91
|
+
private:
|
|
92
|
+
MessageStore* create( const SessionID& s, const Dictionary& );
|
|
93
|
+
|
|
94
|
+
MySQLConnectionPoolPtr m_connectionPoolPtr;
|
|
95
|
+
SessionSettings m_settings;
|
|
96
|
+
Dictionary m_dictionary;
|
|
97
|
+
std::string m_database;
|
|
98
|
+
std::string m_user;
|
|
99
|
+
std::string m_password;
|
|
100
|
+
std::string m_host;
|
|
101
|
+
short m_port;
|
|
102
|
+
bool m_useSettings;
|
|
103
|
+
bool m_useDictionary;
|
|
104
|
+
};
|
|
105
|
+
/*! @} */
|
|
106
|
+
|
|
107
|
+
/// MySQL based implementation of MessageStore.
|
|
108
|
+
class MySQLStore : public MessageStore
|
|
109
|
+
{
|
|
110
|
+
public:
|
|
111
|
+
MySQLStore( const SessionID& s, const DatabaseConnectionID& d, MySQLConnectionPool* p );
|
|
112
|
+
MySQLStore( const SessionID& s, const std::string& database, const std::string& user,
|
|
113
|
+
const std::string& password, const std::string& host, short port );
|
|
114
|
+
~MySQLStore();
|
|
115
|
+
|
|
116
|
+
bool set( int, const std::string& ) throw ( IOException );
|
|
117
|
+
void get( int, int, std::vector < std::string > & ) const throw ( IOException );
|
|
118
|
+
|
|
119
|
+
int getNextSenderMsgSeqNum() const throw ( IOException );
|
|
120
|
+
int getNextTargetMsgSeqNum() const throw ( IOException );
|
|
121
|
+
void setNextSenderMsgSeqNum( int value ) throw ( IOException );
|
|
122
|
+
void setNextTargetMsgSeqNum( int value ) throw ( IOException );
|
|
123
|
+
void incrNextSenderMsgSeqNum() throw ( IOException );
|
|
124
|
+
void incrNextTargetMsgSeqNum() throw ( IOException );
|
|
125
|
+
|
|
126
|
+
UtcTimeStamp getCreationTime() const throw ( IOException );
|
|
127
|
+
|
|
128
|
+
void reset() throw ( IOException );
|
|
129
|
+
void refresh() throw ( IOException );
|
|
130
|
+
|
|
131
|
+
private:
|
|
132
|
+
void populateCache();
|
|
133
|
+
|
|
134
|
+
MemoryStore m_cache;
|
|
135
|
+
MySQLConnection* m_pConnection;
|
|
136
|
+
MySQLConnectionPool* m_pConnectionPool;
|
|
137
|
+
SessionID m_sessionID;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#endif //FIX_MYSQLSTORE_H
|
|
142
|
+
#endif //HAVE_MYSQL
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/****************************************************************************
|
|
2
|
+
** Copyright (c) 2001-2014
|
|
3
|
+
**
|
|
4
|
+
** This file is part of the QuickFIX FIX Engine
|
|
5
|
+
**
|
|
6
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
7
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
8
|
+
** LICENSE included in the packaging of this file.
|
|
9
|
+
**
|
|
10
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
11
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
12
|
+
**
|
|
13
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
14
|
+
**
|
|
15
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
16
|
+
** not clear to you.
|
|
17
|
+
**
|
|
18
|
+
****************************************************************************/
|
|
19
|
+
|
|
20
|
+
#ifdef _MSC_VER
|
|
21
|
+
#include "stdafx.h"
|
|
22
|
+
#else
|
|
23
|
+
#include "config.h"
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#include "NullStore.h"
|
|
27
|
+
|
|
28
|
+
namespace FIX
|
|
29
|
+
{
|
|
30
|
+
|
|
31
|
+
MessageStore* NullStoreFactory::create( const SessionID& )
|
|
32
|
+
{
|
|
33
|
+
return new NullStore();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
void NullStoreFactory::destroy( MessageStore* pStore )
|
|
37
|
+
{
|
|
38
|
+
delete pStore;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
bool NullStore::set( int msgSeqNum, const std::string& msg )
|
|
42
|
+
throw( IOException )
|
|
43
|
+
{
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
void NullStore::get( int begin, int end,
|
|
48
|
+
std::vector < std::string > & messages ) const
|
|
49
|
+
throw( IOException )
|
|
50
|
+
{
|
|
51
|
+
messages.clear();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
} //namespace FIX
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* -*- C++ -*- */
|
|
2
|
+
|
|
3
|
+
/****************************************************************************
|
|
4
|
+
** Copyright (c) 2001-2014
|
|
5
|
+
**
|
|
6
|
+
** This file is part of the QuickFIX FIX Engine
|
|
7
|
+
**
|
|
8
|
+
** This file may be distributed under the terms of the quickfixengine.org
|
|
9
|
+
** license as defined by quickfixengine.org and appearing in the file
|
|
10
|
+
** LICENSE included in the packaging of this file.
|
|
11
|
+
**
|
|
12
|
+
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
13
|
+
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
14
|
+
**
|
|
15
|
+
** See http://www.quickfixengine.org/LICENSE for licensing information.
|
|
16
|
+
**
|
|
17
|
+
** Contact ask@quickfixengine.org if any conditions of this licensing are
|
|
18
|
+
** not clear to you.
|
|
19
|
+
**
|
|
20
|
+
****************************************************************************/
|
|
21
|
+
|
|
22
|
+
#ifndef FIX_NULLSTORE_H
|
|
23
|
+
#define FIX_NULLSTORE_H
|
|
24
|
+
|
|
25
|
+
#ifdef _MSC_VER
|
|
26
|
+
#pragma warning( disable : 4503 4355 4786 4290 )
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#include "MessageStore.h"
|
|
30
|
+
#include "SessionSettings.h"
|
|
31
|
+
#include <string>
|
|
32
|
+
|
|
33
|
+
namespace FIX
|
|
34
|
+
{
|
|
35
|
+
class Session;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Null implementation of MessageStore.
|
|
39
|
+
*
|
|
40
|
+
* Will not actually store messages. Useful for admin-only or market
|
|
41
|
+
* data-only applications.
|
|
42
|
+
*/
|
|
43
|
+
class NullStoreFactory : public MessageStoreFactory
|
|
44
|
+
{
|
|
45
|
+
public:
|
|
46
|
+
MessageStore* create( const SessionID& );
|
|
47
|
+
void destroy( MessageStore* );
|
|
48
|
+
};
|
|
49
|
+
/*! @} */
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Null implementation of MessageStore.
|
|
54
|
+
*
|
|
55
|
+
* Will not actually store messages. Useful for admin-only or market
|
|
56
|
+
* data-only applications.
|
|
57
|
+
*/
|
|
58
|
+
class NullStore : public MessageStore
|
|
59
|
+
{
|
|
60
|
+
public:
|
|
61
|
+
NullStore() : m_nextSenderMsgSeqNum( 1 ), m_nextTargetMsgSeqNum( 1 ) {}
|
|
62
|
+
|
|
63
|
+
bool set( int, const std::string& ) throw ( IOException );
|
|
64
|
+
void get( int, int, std::vector < std::string > & ) const throw ( IOException );
|
|
65
|
+
|
|
66
|
+
int getNextSenderMsgSeqNum() const throw ( IOException )
|
|
67
|
+
{ return m_nextSenderMsgSeqNum; }
|
|
68
|
+
int getNextTargetMsgSeqNum() const throw ( IOException )
|
|
69
|
+
{ return m_nextTargetMsgSeqNum; }
|
|
70
|
+
void setNextSenderMsgSeqNum( int value ) throw ( IOException )
|
|
71
|
+
{ m_nextSenderMsgSeqNum = value; }
|
|
72
|
+
void setNextTargetMsgSeqNum( int value ) throw ( IOException )
|
|
73
|
+
{ m_nextTargetMsgSeqNum = value; }
|
|
74
|
+
void incrNextSenderMsgSeqNum() throw ( IOException )
|
|
75
|
+
{ ++m_nextSenderMsgSeqNum; }
|
|
76
|
+
void incrNextTargetMsgSeqNum() throw ( IOException )
|
|
77
|
+
{ ++m_nextTargetMsgSeqNum; }
|
|
78
|
+
|
|
79
|
+
void setCreationTime( const UtcTimeStamp& creationTime ) throw ( IOException )
|
|
80
|
+
{ m_creationTime = creationTime; }
|
|
81
|
+
UtcTimeStamp getCreationTime() const throw ( IOException )
|
|
82
|
+
{ return m_creationTime; }
|
|
83
|
+
|
|
84
|
+
void reset() throw ( IOException )
|
|
85
|
+
{
|
|
86
|
+
m_nextSenderMsgSeqNum = 1; m_nextTargetMsgSeqNum = 1;
|
|
87
|
+
m_creationTime.setCurrent();
|
|
88
|
+
}
|
|
89
|
+
void refresh() throw ( IOException ) {}
|
|
90
|
+
|
|
91
|
+
private:
|
|
92
|
+
int m_nextSenderMsgSeqNum;
|
|
93
|
+
int m_nextTargetMsgSeqNum;
|
|
94
|
+
UtcTimeStamp m_creationTime;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#endif // FIX_NULLSTORE_H
|
|
99
|
+
|