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.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/ext/quickfix/Acceptor.cpp +248 -0
  3. data/ext/quickfix/Acceptor.h +127 -0
  4. data/ext/quickfix/Allocator.h +9 -0
  5. data/ext/quickfix/Application.h +127 -0
  6. data/ext/quickfix/AtomicCount.h +109 -0
  7. data/ext/quickfix/DOMDocument.h +74 -0
  8. data/ext/quickfix/DataDictionary.cpp +618 -0
  9. data/ext/quickfix/DataDictionary.h +539 -0
  10. data/ext/quickfix/DataDictionaryProvider.cpp +71 -0
  11. data/ext/quickfix/DataDictionaryProvider.h +70 -0
  12. data/ext/quickfix/DatabaseConnectionID.h +105 -0
  13. data/ext/quickfix/DatabaseConnectionPool.h +91 -0
  14. data/ext/quickfix/Dictionary.cpp +162 -0
  15. data/ext/quickfix/Dictionary.h +94 -0
  16. data/ext/quickfix/Event.h +95 -0
  17. data/ext/quickfix/Exceptions.h +299 -0
  18. data/ext/quickfix/Field.h +672 -0
  19. data/ext/quickfix/FieldConvertors.h +863 -0
  20. data/ext/quickfix/FieldMap.cpp +238 -0
  21. data/ext/quickfix/FieldMap.h +244 -0
  22. data/ext/quickfix/FieldNumbers.h +46 -0
  23. data/ext/quickfix/FieldTypes.cpp +64 -0
  24. data/ext/quickfix/FieldTypes.h +698 -0
  25. data/ext/quickfix/Fields.h +31 -0
  26. data/ext/quickfix/FileLog.cpp +200 -0
  27. data/ext/quickfix/FileLog.h +112 -0
  28. data/ext/quickfix/FileStore.cpp +332 -0
  29. data/ext/quickfix/FileStore.h +129 -0
  30. data/ext/quickfix/FixFieldNumbers.h +1537 -0
  31. data/ext/quickfix/FixFields.h +1538 -0
  32. data/ext/quickfix/FixValues.h +3281 -0
  33. data/ext/quickfix/FlexLexer.h +188 -0
  34. data/ext/quickfix/Group.cpp +64 -0
  35. data/ext/quickfix/Group.h +73 -0
  36. data/ext/quickfix/HtmlBuilder.h +186 -0
  37. data/ext/quickfix/HttpConnection.cpp +739 -0
  38. data/ext/quickfix/HttpConnection.h +78 -0
  39. data/ext/quickfix/HttpMessage.cpp +149 -0
  40. data/ext/quickfix/HttpMessage.h +133 -0
  41. data/ext/quickfix/HttpParser.cpp +49 -0
  42. data/ext/quickfix/HttpParser.h +54 -0
  43. data/ext/quickfix/HttpServer.cpp +169 -0
  44. data/ext/quickfix/HttpServer.h +78 -0
  45. data/ext/quickfix/Initiator.cpp +289 -0
  46. data/ext/quickfix/Initiator.h +149 -0
  47. data/ext/quickfix/Log.cpp +77 -0
  48. data/ext/quickfix/Log.h +179 -0
  49. data/ext/quickfix/Message.cpp +580 -0
  50. data/ext/quickfix/Message.h +370 -0
  51. data/ext/quickfix/MessageCracker.h +188 -0
  52. data/ext/quickfix/MessageSorters.cpp +105 -0
  53. data/ext/quickfix/MessageSorters.h +156 -0
  54. data/ext/quickfix/MessageStore.cpp +146 -0
  55. data/ext/quickfix/MessageStore.h +174 -0
  56. data/ext/quickfix/Mutex.h +131 -0
  57. data/ext/quickfix/MySQLConnection.h +194 -0
  58. data/ext/quickfix/MySQLLog.cpp +275 -0
  59. data/ext/quickfix/MySQLLog.h +145 -0
  60. data/ext/quickfix/MySQLStore.cpp +331 -0
  61. data/ext/quickfix/MySQLStore.h +142 -0
  62. data/ext/quickfix/NullStore.cpp +54 -0
  63. data/ext/quickfix/NullStore.h +99 -0
  64. data/ext/quickfix/OdbcConnection.h +266 -0
  65. data/ext/quickfix/OdbcLog.cpp +252 -0
  66. data/ext/quickfix/OdbcLog.h +117 -0
  67. data/ext/quickfix/OdbcStore.cpp +338 -0
  68. data/ext/quickfix/OdbcStore.h +113 -0
  69. data/ext/quickfix/PUGIXML_DOMDocument.cpp +112 -0
  70. data/ext/quickfix/PUGIXML_DOMDocument.h +81 -0
  71. data/ext/quickfix/Parser.cpp +103 -0
  72. data/ext/quickfix/Parser.h +57 -0
  73. data/ext/quickfix/PostgreSQLConnection.h +176 -0
  74. data/ext/quickfix/PostgreSQLLog.cpp +276 -0
  75. data/ext/quickfix/PostgreSQLLog.h +144 -0
  76. data/ext/quickfix/PostgreSQLStore.cpp +334 -0
  77. data/ext/quickfix/PostgreSQLStore.h +141 -0
  78. data/ext/quickfix/Queue.h +75 -0
  79. data/ext/quickfix/QuickfixRuby.cpp +252066 -0
  80. data/ext/quickfix/QuickfixRuby.h +34 -0
  81. data/ext/quickfix/Responder.h +43 -0
  82. data/ext/quickfix/Session.cpp +1487 -0
  83. data/ext/quickfix/Session.h +335 -0
  84. data/ext/quickfix/SessionFactory.cpp +274 -0
  85. data/ext/quickfix/SessionFactory.h +86 -0
  86. data/ext/quickfix/SessionID.h +170 -0
  87. data/ext/quickfix/SessionSettings.cpp +189 -0
  88. data/ext/quickfix/SessionSettings.h +171 -0
  89. data/ext/quickfix/SessionState.h +231 -0
  90. data/ext/quickfix/Settings.cpp +100 -0
  91. data/ext/quickfix/Settings.h +53 -0
  92. data/ext/quickfix/SharedArray.h +150 -0
  93. data/ext/quickfix/SocketAcceptor.cpp +222 -0
  94. data/ext/quickfix/SocketAcceptor.h +75 -0
  95. data/ext/quickfix/SocketConnection.cpp +238 -0
  96. data/ext/quickfix/SocketConnection.h +103 -0
  97. data/ext/quickfix/SocketConnector.cpp +116 -0
  98. data/ext/quickfix/SocketConnector.h +67 -0
  99. data/ext/quickfix/SocketInitiator.cpp +260 -0
  100. data/ext/quickfix/SocketInitiator.h +81 -0
  101. data/ext/quickfix/SocketMonitor.cpp +335 -0
  102. data/ext/quickfix/SocketMonitor.h +111 -0
  103. data/ext/quickfix/SocketServer.cpp +177 -0
  104. data/ext/quickfix/SocketServer.h +100 -0
  105. data/ext/quickfix/ThreadedSocketAcceptor.cpp +258 -0
  106. data/ext/quickfix/ThreadedSocketAcceptor.h +98 -0
  107. data/ext/quickfix/ThreadedSocketConnection.cpp +209 -0
  108. data/ext/quickfix/ThreadedSocketConnection.h +82 -0
  109. data/ext/quickfix/ThreadedSocketInitiator.cpp +268 -0
  110. data/ext/quickfix/ThreadedSocketInitiator.h +84 -0
  111. data/ext/quickfix/TimeRange.cpp +173 -0
  112. data/ext/quickfix/TimeRange.h +258 -0
  113. data/ext/quickfix/Utility.cpp +537 -0
  114. data/ext/quickfix/Utility.h +219 -0
  115. data/ext/quickfix/Values.h +62 -0
  116. data/ext/quickfix/config.h +0 -0
  117. data/ext/quickfix/config_windows.h +0 -0
  118. data/ext/quickfix/extconf.rb +12 -0
  119. data/ext/quickfix/index.h +37 -0
  120. data/ext/quickfix/pugiconfig.hpp +72 -0
  121. data/ext/quickfix/pugixml.cpp +10765 -0
  122. data/ext/quickfix/pugixml.hpp +1341 -0
  123. data/ext/quickfix/strptime.h +7 -0
  124. data/lib/quickfix40.rb +274 -0
  125. data/lib/quickfix41.rb +351 -0
  126. data/lib/quickfix42.rb +1184 -0
  127. data/lib/quickfix43.rb +3504 -0
  128. data/lib/quickfix44.rb +10721 -0
  129. data/lib/quickfix50.rb +13426 -0
  130. data/lib/quickfix50sp1.rb +15629 -0
  131. data/lib/quickfix50sp2.rb +17068 -0
  132. data/lib/quickfix_fields.rb +19853 -0
  133. data/lib/quickfix_ruby.rb +82 -0
  134. data/lib/quickfixt11.rb +70 -0
  135. data/spec/FIX40.xml +862 -0
  136. data/spec/FIX41.xml +1285 -0
  137. data/spec/FIX42.xml +2746 -0
  138. data/spec/FIX43.xml +4229 -0
  139. data/spec/FIX44.xml +6596 -0
  140. data/spec/FIX50.xml +8137 -0
  141. data/spec/FIX50SP1.xml +9496 -0
  142. data/spec/FIX50SP2.xml +10011 -0
  143. data/spec/FIXT11.xml +313 -0
  144. data/test/test_DataDictionaryTestCase.rb +268 -0
  145. data/test/test_DictionaryTestCase.rb +112 -0
  146. data/test/test_FieldBaseTestCase.rb +24 -0
  147. data/test/test_MessageTestCase.rb +368 -0
  148. data/test/test_SessionSettingsTestCase.rb +41 -0
  149. metadata +193 -0
@@ -0,0 +1,144 @@
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_POSTGRESQL
23
+ #error PostgreSQLLog.h included, but HAVE_POSTGRESQL not defined
24
+ #endif
25
+
26
+ #ifdef HAVE_POSTGRESQL
27
+ #ifndef FIX_POSTGRESQLLOG_H
28
+ #define FIX_POSTGRESQLLOG_H
29
+
30
+ #ifdef _MSC_VER
31
+ #pragma warning( disable : 4503 4355 4786 4290 )
32
+ #endif
33
+
34
+ #include "Log.h"
35
+ #include "SessionSettings.h"
36
+ #include "PostgreSQLConnection.h"
37
+ #include <fstream>
38
+ #include <string>
39
+
40
+ namespace FIX
41
+ {
42
+ /// PostgreSQL based implementation of Log.
43
+ class PostgreSQLLog : public Log
44
+ {
45
+ public:
46
+ PostgreSQLLog( const SessionID& s, const DatabaseConnectionID& d, PostgreSQLConnectionPool* p );
47
+ PostgreSQLLog( const DatabaseConnectionID& d, PostgreSQLConnectionPool* p );
48
+ PostgreSQLLog( const SessionID& s, const std::string& database, const std::string& user,
49
+ const std::string& password, const std::string& host, short port );
50
+ PostgreSQLLog( const std::string& database, const std::string& user,
51
+ const std::string& password, const std::string& host, short port );
52
+
53
+ ~PostgreSQLLog();
54
+
55
+ void clear();
56
+ void backup();
57
+ void setIncomingTable( const std::string& incomingTable )
58
+ { m_incomingTable = incomingTable; }
59
+ void setOutgoingTable( const std::string& outgoingTable )
60
+ { m_outgoingTable = outgoingTable; }
61
+ void setEventTable( const std::string& eventTable )
62
+ { m_eventTable = eventTable; }
63
+
64
+ void onIncoming( const std::string& value )
65
+ { insert( m_incomingTable, value ); }
66
+ void onOutgoing( const std::string& value )
67
+ { insert( m_outgoingTable, value ); }
68
+ void onEvent( const std::string& value )
69
+ { insert( m_eventTable, value ); }
70
+
71
+ private:
72
+ void init();
73
+ void insert( const std::string& table, const std::string value );
74
+
75
+ std::string m_incomingTable;
76
+ std::string m_outgoingTable;
77
+ std::string m_eventTable;
78
+ PostgreSQLConnection* m_pConnection;
79
+ PostgreSQLConnectionPool* m_pConnectionPool;
80
+ SessionID* m_pSessionID;
81
+ };
82
+
83
+ /// Creates a MySQL based implementation of Log.
84
+ class PostgreSQLLogFactory : public LogFactory
85
+ {
86
+ public:
87
+ static const std::string DEFAULT_DATABASE;
88
+ static const std::string DEFAULT_USER;
89
+ static const std::string DEFAULT_PASSWORD;
90
+ static const std::string DEFAULT_HOST;
91
+ static const short DEFAULT_PORT;
92
+
93
+ PostgreSQLLogFactory( const SessionSettings& settings )
94
+ : m_settings( settings ), m_useSettings( true )
95
+ {
96
+ bool poolConnections = false;
97
+ try { poolConnections = settings.get().getBool(POSTGRESQL_LOG_USECONNECTIONPOOL); }
98
+ catch( ConfigError& ) {}
99
+
100
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
101
+ ( new PostgreSQLConnectionPool(poolConnections) );
102
+ }
103
+
104
+ PostgreSQLLogFactory( const std::string& database, const std::string& user,
105
+ const std::string& password, const std::string& host,
106
+ short port )
107
+ : m_database( database ), m_user( user ), m_password( password ), m_host( host ), m_port( port ),
108
+ m_useSettings( false )
109
+ {
110
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
111
+ ( new PostgreSQLConnectionPool(false) );
112
+ }
113
+
114
+ PostgreSQLLogFactory()
115
+ : m_database( DEFAULT_DATABASE ), m_user( DEFAULT_USER ), m_password( DEFAULT_PASSWORD ),
116
+ m_host( DEFAULT_HOST ), m_port( DEFAULT_PORT ), m_useSettings( false )
117
+ {
118
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
119
+ ( new PostgreSQLConnectionPool(false) );
120
+ }
121
+
122
+ Log* create();
123
+ Log* create( const SessionID& );
124
+ void destroy( Log* );
125
+ private:
126
+ void init( const Dictionary& settings, std::string& database,
127
+ std::string& user, std::string& password,
128
+ std::string& host, short& port );
129
+
130
+ void initLog( const Dictionary& settings, PostgreSQLLog& log );
131
+
132
+ PostgreSQLConnectionPoolPtr m_connectionPoolPtr;
133
+ SessionSettings m_settings;
134
+ std::string m_database;
135
+ std::string m_user;
136
+ std::string m_password;
137
+ std::string m_host;
138
+ short m_port;
139
+ bool m_useSettings;
140
+ };
141
+ }
142
+
143
+ #endif //FIX_POSTGRESQLLOG_H
144
+ #endif //HAVE_POSTGRESQL
@@ -0,0 +1,334 @@
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_POSTGRESQL
27
+
28
+ #include "PostgreSQLStore.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 PostgreSQLStoreFactory::DEFAULT_DATABASE = "quickfix";
41
+ const std::string PostgreSQLStoreFactory::DEFAULT_USER = "postgres";
42
+ const std::string PostgreSQLStoreFactory::DEFAULT_PASSWORD = "";
43
+ const std::string PostgreSQLStoreFactory::DEFAULT_HOST = "localhost";
44
+ const short PostgreSQLStoreFactory::DEFAULT_PORT = 0;
45
+
46
+ PostgreSQLStore::PostgreSQLStore
47
+ ( const SessionID& s, const DatabaseConnectionID& d, PostgreSQLConnectionPool* p )
48
+ : m_pConnectionPool( p ), m_sessionID( s )
49
+ {
50
+ m_pConnection = m_pConnectionPool->create( d );
51
+ populateCache();
52
+ }
53
+
54
+ PostgreSQLStore::PostgreSQLStore
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 PostgreSQLConnection( database, user, password, host, port );
60
+ populateCache();
61
+ }
62
+
63
+ PostgreSQLStore::~PostgreSQLStore()
64
+ {
65
+ if( m_pConnectionPool )
66
+ m_pConnectionPool->destroy( m_pConnection );
67
+ else
68
+ delete m_pConnection;
69
+ }
70
+
71
+ void PostgreSQLStore::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
+ PostgreSQLQuery 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
+ PostgreSQLQuery query2( queryString2.str() );
119
+ if( !m_pConnection->execute(query2) )
120
+ throw ConfigError( "Unable to create session in database" );
121
+ }
122
+ }
123
+
124
+ MessageStore* PostgreSQLStoreFactory::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 PostgreSQLStore( s, id, m_connectionPoolPtr.get() );
134
+ }
135
+ }
136
+
137
+ MessageStore* PostgreSQLStoreFactory::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( POSTGRESQL_STORE_DATABASE ); }
146
+ catch( ConfigError& ) {}
147
+
148
+ try { user = settings.getString( POSTGRESQL_STORE_USER ); }
149
+ catch( ConfigError& ) {}
150
+
151
+ try { password = settings.getString( POSTGRESQL_STORE_PASSWORD ); }
152
+ catch( ConfigError& ) {}
153
+
154
+ try { host = settings.getString( POSTGRESQL_STORE_HOST ); }
155
+ catch( ConfigError& ) {}
156
+
157
+ try { port = ( short ) settings.getInt( POSTGRESQL_STORE_PORT ); }
158
+ catch( ConfigError& ) {}
159
+
160
+ DatabaseConnectionID id( database, user, password, host, port );
161
+ return new PostgreSQLStore( s, id, m_connectionPoolPtr.get() );
162
+ }
163
+
164
+ void PostgreSQLStoreFactory::destroy( MessageStore* pStore )
165
+ {
166
+ delete pStore;
167
+ }
168
+
169
+ bool PostgreSQLStore::set( int msgSeqNum, const std::string& msg )
170
+ throw ( IOException )
171
+ {
172
+ char* msgCopy = new char[ (msg.size() * 2) + 1 ];
173
+ PQescapeString( 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
+ PostgreSQLQuery 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
+ PostgreSQLQuery query2( queryString2.str() );
199
+ if( !m_pConnection->execute(query2) )
200
+ query2.throwException();
201
+ }
202
+
203
+ return true;
204
+ }
205
+
206
+ void PostgreSQLStore::get( int begin, int end,
207
+ std::vector < std::string > & result ) const
208
+ throw ( IOException )
209
+ {
210
+ result.clear();
211
+ std::stringstream queryString;
212
+ queryString << "SELECT message FROM messages WHERE "
213
+ << "beginstring=" << "'" << m_sessionID.getBeginString().getValue() << "' and "
214
+ << "sendercompid=" << "'" << m_sessionID.getSenderCompID().getValue() << "' and "
215
+ << "targetcompid=" << "'" << m_sessionID.getTargetCompID().getValue() << "' and "
216
+ << "session_qualifier=" << "'" << m_sessionID.getSessionQualifier() << "' and "
217
+ << "msgseqnum>=" << begin << " and " << "msgseqnum<=" << end << " "
218
+ << "ORDER BY msgseqnum";
219
+
220
+ PostgreSQLQuery query( queryString.str() );
221
+ if( !m_pConnection->execute(query) )
222
+ query.throwException();
223
+
224
+ int rows = query.rows();
225
+ for( int row = 0; row < rows; row++ )
226
+ result.push_back( query.getValue( row, 0 ) );
227
+ }
228
+
229
+ int PostgreSQLStore::getNextSenderMsgSeqNum() const throw ( IOException )
230
+ {
231
+ return m_cache.getNextSenderMsgSeqNum();
232
+ }
233
+
234
+ int PostgreSQLStore::getNextTargetMsgSeqNum() const throw ( IOException )
235
+ {
236
+ return m_cache.getNextTargetMsgSeqNum();
237
+ }
238
+
239
+ void PostgreSQLStore::setNextSenderMsgSeqNum( int value ) throw ( IOException )
240
+ {
241
+ std::stringstream queryString;
242
+ queryString << "UPDATE sessions SET outgoing_seqnum=" << value << " WHERE "
243
+ << "beginstring=" << "'" << m_sessionID.getBeginString().getValue() << "' and "
244
+ << "sendercompid=" << "'" << m_sessionID.getSenderCompID().getValue() << "' and "
245
+ << "targetcompid=" << "'" << m_sessionID.getTargetCompID().getValue() << "' and "
246
+ << "session_qualifier=" << "'" << m_sessionID.getSessionQualifier() << "'";
247
+
248
+ PostgreSQLQuery query( queryString.str() );
249
+ if( !m_pConnection->execute(query) )
250
+ query.throwException();
251
+
252
+ m_cache.setNextSenderMsgSeqNum( value );
253
+ }
254
+
255
+ void PostgreSQLStore::setNextTargetMsgSeqNum( int value ) throw ( IOException )
256
+ {
257
+ std::stringstream queryString;
258
+ queryString << "UPDATE sessions SET incoming_seqnum=" << value << " WHERE "
259
+ << "beginstring=" << "'" << m_sessionID.getBeginString().getValue() << "' and "
260
+ << "sendercompid=" << "'" << m_sessionID.getSenderCompID().getValue() << "' and "
261
+ << "targetcompid=" << "'" << m_sessionID.getTargetCompID().getValue() << "' and "
262
+ << "session_qualifier=" << "'" << m_sessionID.getSessionQualifier() << "'";
263
+
264
+ PostgreSQLQuery query( queryString.str() );
265
+ if( !m_pConnection->execute(query) )
266
+ query.throwException();
267
+
268
+ m_cache.setNextTargetMsgSeqNum( value );
269
+ }
270
+
271
+ void PostgreSQLStore::incrNextSenderMsgSeqNum() throw ( IOException )
272
+ {
273
+ m_cache.incrNextSenderMsgSeqNum();
274
+ setNextSenderMsgSeqNum( m_cache.getNextSenderMsgSeqNum() );
275
+ }
276
+
277
+ void PostgreSQLStore::incrNextTargetMsgSeqNum() throw ( IOException )
278
+ {
279
+ m_cache.incrNextTargetMsgSeqNum();
280
+ setNextTargetMsgSeqNum( m_cache.getNextTargetMsgSeqNum() );
281
+ }
282
+
283
+ UtcTimeStamp PostgreSQLStore::getCreationTime() const throw ( IOException )
284
+ {
285
+ return m_cache.getCreationTime();
286
+ }
287
+
288
+ void PostgreSQLStore::reset() throw ( IOException )
289
+ {
290
+ std::stringstream queryString;
291
+ queryString << "DELETE FROM messages WHERE "
292
+ << "beginstring=" << "'" << m_sessionID.getBeginString().getValue() << "' and "
293
+ << "sendercompid=" << "'" << m_sessionID.getSenderCompID().getValue() << "' and "
294
+ << "targetcompid=" << "'" << m_sessionID.getTargetCompID().getValue() << "' and "
295
+ << "session_qualifier=" << "'" << m_sessionID.getSessionQualifier() << "'";
296
+
297
+ PostgreSQLQuery query( queryString.str() );
298
+ if( !m_pConnection->execute(query) )
299
+ query.throwException();
300
+
301
+ m_cache.reset();
302
+ UtcTimeStamp time = m_cache.getCreationTime();
303
+
304
+ int year, month, day, hour, minute, second, millis;
305
+ time.getYMD( year, month, day );
306
+ time.getHMS( hour, minute, second, millis );
307
+
308
+ char sqlTime[ 20 ];
309
+ STRING_SPRINTF( sqlTime, "%d-%02d-%02d %02d:%02d:%02d",
310
+ year, month, day, hour, minute, second );
311
+
312
+ std::stringstream queryString2;
313
+ queryString2 << "UPDATE sessions SET creation_time='" << sqlTime << "', "
314
+ << "incoming_seqnum=" << m_cache.getNextTargetMsgSeqNum() << ", "
315
+ << "outgoing_seqnum=" << m_cache.getNextSenderMsgSeqNum() << " WHERE "
316
+ << "beginstring=" << "'" << m_sessionID.getBeginString().getValue() << "' and "
317
+ << "sendercompid=" << "'" << m_sessionID.getSenderCompID().getValue() << "' and "
318
+ << "targetcompid=" << "'" << m_sessionID.getTargetCompID().getValue() << "' and "
319
+ << "session_qualifier=" << "'" << m_sessionID.getSessionQualifier() << "'";
320
+
321
+ PostgreSQLQuery query2( queryString2.str() );
322
+ if( !m_pConnection->execute(query2) )
323
+ query2.throwException();
324
+ }
325
+
326
+ void PostgreSQLStore::refresh() throw ( IOException )
327
+ {
328
+ m_cache.reset();
329
+ populateCache();
330
+ }
331
+
332
+ }
333
+
334
+ #endif
@@ -0,0 +1,141 @@
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_POSTGRESQL
23
+ #error PostgreSQLStore.h included, but HAVE_POSTGRESQL not defined
24
+ #endif
25
+
26
+ #ifdef HAVE_POSTGRESQL
27
+ #ifndef FIX_POSTGRESQLSTORE_H
28
+ #define FIX_POSTGRESQLSTORE_H
29
+
30
+ #ifdef _MSC_VER
31
+ #pragma warning( disable : 4503 4355 4786 4290 )
32
+ #endif
33
+
34
+ #include "MessageStore.h"
35
+ #include "SessionSettings.h"
36
+ #include "PostgreSQLConnection.h"
37
+ #include <fstream>
38
+ #include <string>
39
+
40
+ namespace FIX
41
+ {
42
+ /// Creates a PostgreSQL based implementation of MessageStore.
43
+ class PostgreSQLStoreFactory : public MessageStoreFactory
44
+ {
45
+ public:
46
+ static const std::string DEFAULT_DATABASE;
47
+ static const std::string DEFAULT_USER;
48
+ static const std::string DEFAULT_PASSWORD;
49
+ static const std::string DEFAULT_HOST;
50
+ static const short DEFAULT_PORT;
51
+
52
+ PostgreSQLStoreFactory( const SessionSettings& settings )
53
+ : m_settings( settings ), m_useSettings( true ), m_useDictionary( false )
54
+ {
55
+ bool poolConnections = false;
56
+ try { poolConnections = settings.get().getBool(POSTGRESQL_STORE_USECONNECTIONPOOL); }
57
+ catch( ConfigError& ) {}
58
+
59
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
60
+ ( new PostgreSQLConnectionPool(poolConnections) );
61
+ }
62
+
63
+ PostgreSQLStoreFactory( const Dictionary& dictionary )
64
+ : m_dictionary( dictionary ), m_useSettings( false ), m_useDictionary( true )
65
+ {
66
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
67
+ ( new PostgreSQLConnectionPool(false) );
68
+ }
69
+
70
+ PostgreSQLStoreFactory( const std::string& database, const std::string& user,
71
+ const std::string& password, const std::string& host,
72
+ short port )
73
+ : m_database( database ), m_user( user ), m_password( password ), m_host( host ), m_port( port ),
74
+ m_useSettings( false ), m_useDictionary( false )
75
+ {
76
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
77
+ ( new PostgreSQLConnectionPool(false) );
78
+ }
79
+
80
+ PostgreSQLStoreFactory()
81
+ : m_database( DEFAULT_DATABASE ), m_user( DEFAULT_USER ), m_password( DEFAULT_PASSWORD ),
82
+ m_host( DEFAULT_HOST ), m_port( DEFAULT_PORT ), m_useSettings( false ), m_useDictionary( false )
83
+ {
84
+ m_connectionPoolPtr = PostgreSQLConnectionPoolPtr
85
+ ( new PostgreSQLConnectionPool(false) );
86
+ }
87
+
88
+ MessageStore* create( const SessionID& );
89
+ void destroy( MessageStore* );
90
+ private:
91
+ MessageStore* create( const SessionID& s, const Dictionary& );
92
+
93
+ PostgreSQLConnectionPoolPtr m_connectionPoolPtr;
94
+ SessionSettings m_settings;
95
+ Dictionary m_dictionary;
96
+ std::string m_database;
97
+ std::string m_user;
98
+ std::string m_password;
99
+ std::string m_host;
100
+ short m_port;
101
+ bool m_useSettings;
102
+ bool m_useDictionary;
103
+ };
104
+ /*! @} */
105
+
106
+ /// PostgreSQL based implementation of MessageStore.
107
+ class PostgreSQLStore : public MessageStore
108
+ {
109
+ public:
110
+ PostgreSQLStore( const SessionID& s, const DatabaseConnectionID& d, PostgreSQLConnectionPool* p );
111
+ PostgreSQLStore( const SessionID& s, const std::string& database, const std::string& user,
112
+ const std::string& password, const std::string& host, short port );
113
+ ~PostgreSQLStore();
114
+
115
+ bool set( int, const std::string& ) throw ( IOException );
116
+ void get( int, int, std::vector < std::string > & ) const throw ( IOException );
117
+
118
+ int getNextSenderMsgSeqNum() const throw ( IOException );
119
+ int getNextTargetMsgSeqNum() const throw ( IOException );
120
+ void setNextSenderMsgSeqNum( int value ) throw ( IOException );
121
+ void setNextTargetMsgSeqNum( int value ) throw ( IOException );
122
+ void incrNextSenderMsgSeqNum() throw ( IOException );
123
+ void incrNextTargetMsgSeqNum() throw ( IOException );
124
+
125
+ UtcTimeStamp getCreationTime() const throw ( IOException );
126
+
127
+ void reset() throw ( IOException );
128
+ void refresh() throw ( IOException );
129
+
130
+ private:
131
+ void populateCache();
132
+
133
+ MemoryStore m_cache;
134
+ PostgreSQLConnection* m_pConnection;
135
+ PostgreSQLConnectionPool* m_pConnectionPool;
136
+ SessionID m_sessionID;
137
+ };
138
+ }
139
+
140
+ #endif //FIX_POSTGRESQLSTORE_H
141
+ #endif //HAVE_POSTGRESQL
@@ -0,0 +1,75 @@
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_QUEUE_H
23
+ #define FIX_QUEUE_H
24
+
25
+ #include "Utility.h"
26
+ #include "Event.h"
27
+ #include "Mutex.h"
28
+ #include <queue>
29
+
30
+ namespace FIX
31
+ {
32
+ /// A thread safe monitored queue
33
+ template < typename T > class Queue
34
+ {
35
+ public:
36
+ void push( const T& value )
37
+ {
38
+ Locker locker( m_mutex );
39
+ m_queue.push( value );
40
+ signal();
41
+ }
42
+
43
+ bool pop( T& value )
44
+ {
45
+ Locker locker( m_mutex );
46
+ if ( !m_queue.size() ) return false;
47
+ value = m_queue.front();
48
+ m_queue.pop();
49
+ return true;
50
+ }
51
+
52
+ int size()
53
+ {
54
+ Locker locker( m_mutex );
55
+ return m_queue.size();
56
+ }
57
+
58
+ void wait( double s )
59
+ {
60
+ m_event.wait( s );
61
+ }
62
+
63
+ void signal()
64
+ {
65
+ m_event.signal();
66
+ }
67
+
68
+ private:
69
+ Event m_event;
70
+ Mutex m_mutex;
71
+ std::queue < T > m_queue;
72
+ };
73
+ }
74
+
75
+ #endif