1/*
2 * The contents of this file are subject to the Initial
3 * Developer's Public License Version 1.0 (the "License");
4 * you may not use this file except in compliance with the
5 * License. You may obtain a copy of the License at
6 * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
7 *
8 * Software distributed under the License is distributed AS IS,
9 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
10 * See the License for the specific language governing rights
11 * and limitations under the License.
12 *
13 * The Original Code was created by Alex Peshkov
14 * for the Firebird Open Source RDBMS project.
15 *
16 * Copyright (c) 2011 Alex Peshkov <peshkoff@mail.ru>
17 * and all contributors signed below.
18 *
19 * All Rights Reserved.
20 * Contributor(s): ______________________________________.
21 */
22
23#ifndef JRD_ENGINE_INTERFACE_H
24#define JRD_ENGINE_INTERFACE_H
25
26#include "firebird/Provider.h"
27#include "../common/classes/ImplementHelper.h"
28#include "../common/StatementMetadata.h"
29#include "../common/classes/RefCounted.h"
30
31#define CURRENT_ENGINE "Engine12"
32
33namespace Jrd {
34
35// Engine objects used by interface objects
36class blb;
37class jrd_tra;
38class dsql_req;
39class JrdStatement;
40class Attachment;
41class Service;
42
43// forward declarations
44class JStatement;
45class JAttachment;
46class JProvider;
47
48class JBlob FB_FINAL : public Firebird::RefCntIface<Firebird::IBlob, FB_BLOB_VERSION>
49{
50public:
51 // IBlob implementation
52 virtual int FB_CARG release();
53 virtual void FB_CARG getInfo(Firebird::IStatus* status,
54 unsigned int itemsLength, const unsigned char* items,
55 unsigned int bufferLength, unsigned char* buffer);
56 virtual unsigned int FB_CARG getSegment(Firebird::IStatus* status, unsigned int length, void* buffer); // returns real length
57 virtual void FB_CARG putSegment(Firebird::IStatus* status, unsigned int length, const void* buffer);
58 virtual void FB_CARG cancel(Firebird::IStatus* status);
59 virtual void FB_CARG close(Firebird::IStatus* status);
60 virtual int FB_CARG seek(Firebird::IStatus* status, int mode, int offset); // returns position
61
62public:
63 JBlob(blb* handle, JAttachment* ja)
64 : blob(handle), jAtt(ja)
65 {
66 }
67
68 JAttachment* getAttachment()
69 {
70 return jAtt;
71 }
72
73 blb* getHandle() throw()
74 {
75 return blob;
76 }
77
78private:
79 blb* blob;
80 Firebird::RefPtr<JAttachment> jAtt;
81
82 void freeEngineData(Firebird::IStatus* status);
83};
84
85class JTransaction FB_FINAL : public Firebird::RefCntIface<Firebird::ITransaction, FB_TRANSACTION_VERSION>
86{
87public:
88 // ITransaction implementation
89 virtual int FB_CARG release();
90 virtual void FB_CARG getInfo(Firebird::IStatus* status,
91 unsigned int itemsLength, const unsigned char* items,
92 unsigned int bufferLength, unsigned char* buffer);
93 virtual void FB_CARG prepare(Firebird::IStatus* status,
94 unsigned int msg_length = 0, const unsigned char* message = 0);
95 virtual void FB_CARG commit(Firebird::IStatus* status);
96 virtual void FB_CARG commitRetaining(Firebird::IStatus* status);
97 virtual void FB_CARG rollback(Firebird::IStatus* status);
98 virtual void FB_CARG rollbackRetaining(Firebird::IStatus* status);
99 virtual void FB_CARG disconnect(Firebird::IStatus* status);
100 virtual Firebird::ITransaction* FB_CARG join(Firebird::IStatus* status, Firebird::ITransaction* transaction);
101 virtual JTransaction* FB_CARG validate(Firebird::IStatus* status, Firebird::IAttachment* testAtt);
102 virtual JTransaction* FB_CARG enterDtc(Firebird::IStatus* status);
103
104public:
105 JTransaction(jrd_tra* handle, JAttachment* ja)
106 : transaction(handle), jAtt(ja)
107 {
108 }
109
110 jrd_tra* getHandle() throw()
111 {
112 return transaction;
113 }
114
115 void setHandle(jrd_tra* handle)
116 {
117 transaction = handle;
118 }
119
120 JAttachment* getAttachment()
121 {
122 return jAtt;
123 }
124
125 void clear()
126 {
127 transaction = NULL;
128 release();
129 }
130
131private:
132 jrd_tra* transaction;
133 Firebird::RefPtr<JAttachment> jAtt;
134
135 JTransaction(JTransaction* from)
136 : transaction(from->transaction), jAtt(from->jAtt)
137 {
138 }
139
140 void freeEngineData(Firebird::IStatus* status);
141};
142
143class JResultSet FB_FINAL : public Firebird::RefCntIface<Firebird::IResultSet, FB_RESULTSET_VERSION>
144{
145public:
146 // IResultSet implementation
147 virtual int FB_CARG release();
148 virtual FB_BOOLEAN FB_CARG fetchNext(Firebird::IStatus* status, void* message);
149 virtual FB_BOOLEAN FB_CARG fetchPrior(Firebird::IStatus* status, void* message);
150 virtual FB_BOOLEAN FB_CARG fetchFirst(Firebird::IStatus* status, void* message);
151 virtual FB_BOOLEAN FB_CARG fetchLast(Firebird::IStatus* status, void* message);
152 virtual FB_BOOLEAN FB_CARG fetchAbsolute(Firebird::IStatus* status, unsigned int position, void* message);
153 virtual FB_BOOLEAN FB_CARG fetchRelative(Firebird::IStatus* status, int offset, void* message);
154 virtual FB_BOOLEAN FB_CARG isEof(Firebird::IStatus* status);
155 virtual FB_BOOLEAN FB_CARG isBof(Firebird::IStatus* status);
156 virtual Firebird::IMessageMetadata* FB_CARG getMetadata(Firebird::IStatus* status);
157 virtual void FB_CARG setCursorName(Firebird::IStatus* status, const char* name);
158 virtual void FB_CARG close(Firebird::IStatus* status);
159
160public:
161 JResultSet(JStatement* aStatement)
162 : statement(aStatement), eof(false)
163 {
164 }
165
166 JStatement* getStatement()
167 {
168 return statement;
169 }
170
171 JAttachment* getAttachment();
172
173 // Change after adding separate handle for cursor in dsql
174 dsql_req* getHandle() throw();
175
176private:
177 Firebird::RefPtr<JStatement> statement;
178 bool eof;
179
180 void freeEngineData(Firebird::IStatus* status);
181};
182
183class JStatement FB_FINAL : public Firebird::RefCntIface<Firebird::IStatement, FB_STATEMENT_VERSION>
184{
185public:
186 // IStatement implementation
187 virtual int FB_CARG release();
188 virtual void FB_CARG getInfo(Firebird::IStatus* status,
189 unsigned int itemsLength, const unsigned char* items,
190 unsigned int bufferLength, unsigned char* buffer);
191 virtual void FB_CARG free(Firebird::IStatus* status);
192 virtual ISC_UINT64 FB_CARG getAffectedRecords(Firebird::IStatus* userStatus);
193 virtual Firebird::IMessageMetadata* FB_CARG getOutputMetadata(Firebird::IStatus* userStatus);
194 virtual Firebird::IMessageMetadata* FB_CARG getInputMetadata(Firebird::IStatus* userStatus);
195 virtual unsigned FB_CARG getType(Firebird::IStatus* status);
196 virtual const char* FB_CARG getPlan(Firebird::IStatus* status, FB_BOOLEAN detailed);
197 virtual JTransaction* FB_CARG execute(Firebird::IStatus* status,
198 Firebird::ITransaction* transaction, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
199 Firebird::IMessageMetadata* outMetadata, void* outBuffer);
200 virtual JResultSet* FB_CARG openCursor(Firebird::IStatus* status,
201 Firebird::ITransaction* transaction, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
202 Firebird::IMessageMetadata* outMetadata);
203 virtual unsigned FB_CARG getFlags(Firebird::IStatus* status);
204
205public:
206 JStatement(dsql_req* handle, JAttachment* ja, Firebird::Array<UCHAR>& meta);
207
208 JAttachment* getAttachment()
209 {
210 return jAtt;
211 }
212
213 dsql_req* getHandle() throw()
214 {
215 return statement;
216 }
217
218private:
219 dsql_req* statement;
220 Firebird::RefPtr<JAttachment> jAtt;
221 Firebird::StatementMetadata metadata;
222
223 void freeEngineData(Firebird::IStatus* status);
224};
225
226inline JAttachment* JResultSet::getAttachment()
227{
228 return statement->getAttachment();
229}
230
231// Change after adding separate handle for cursor in dsql
232inline dsql_req* JResultSet::getHandle() throw()
233{
234 return statement->getHandle();
235}
236
237class JRequest FB_FINAL : public Firebird::RefCntIface<Firebird::IRequest, FB_REQUEST_VERSION>
238{
239public:
240 // IRequest implementation
241 virtual int FB_CARG release();
242 virtual void FB_CARG receive(Firebird::IStatus* status, int level, unsigned int msg_type,
243 unsigned int length, unsigned char* message);
244 virtual void FB_CARG send(Firebird::IStatus* status, int level, unsigned int msg_type,
245 unsigned int length, const unsigned char* message);
246 virtual void FB_CARG getInfo(Firebird::IStatus* status, int level,
247 unsigned int itemsLength, const unsigned char* items,
248 unsigned int bufferLength, unsigned char* buffer);
249 virtual void FB_CARG start(Firebird::IStatus* status, Firebird::ITransaction* tra, int level);
250 virtual void FB_CARG startAndSend(Firebird::IStatus* status, Firebird::ITransaction* tra, int level, unsigned int msg_type,
251 unsigned int length, const unsigned char* message);
252 virtual void FB_CARG unwind(Firebird::IStatus* status, int level);
253 virtual void FB_CARG free(Firebird::IStatus* status);
254
255public:
256 JRequest(JrdStatement* handle, JAttachment* ja)
257 : rq(handle), jAtt(ja)
258 {
259 }
260
261 JAttachment* getAttachment()
262 {
263 return jAtt;
264 }
265
266 JrdStatement* getHandle() throw()
267 {
268 return rq;
269 }
270
271private:
272 JrdStatement* rq;
273 Firebird::RefPtr<JAttachment> jAtt;
274
275 void freeEngineData(Firebird::IStatus* status);
276};
277
278class JEvents FB_FINAL : public Firebird::RefCntIface<Firebird::IEvents, FB_EVENTS_VERSION>
279{
280public:
281 // IEvents implementation
282 virtual int FB_CARG release();
283 virtual void FB_CARG cancel(Firebird::IStatus* status);
284
285public:
286 JEvents(int aId, JAttachment* ja, Firebird::IEventCallback* aCallback)
287 : id(aId), jAtt(ja), callback(aCallback)
288 {
289 }
290
291 JEvents* getHandle() throw()
292 {
293 return this;
294 }
295
296 JAttachment* getAttachment()
297 {
298 return jAtt;
299 }
300
301private:
302 int id;
303 Firebird::RefPtr<JAttachment> jAtt;
304 Firebird::RefPtr<Firebird::IEventCallback> callback;
305
306 void freeEngineData(Firebird::IStatus* status);
307};
308
309class JAttachment : public Firebird::RefCntIface<Firebird::IAttachment, FB_ATTACHMENT_VERSION>
310{
311public:
312 // IAttachment implementation
313 virtual int FB_CARG release();
314 virtual void FB_CARG getInfo(Firebird::IStatus* status,
315 unsigned int itemsLength, const unsigned char* items,
316 unsigned int bufferLength, unsigned char* buffer);
317 virtual JTransaction* FB_CARG startTransaction(Firebird::IStatus* status,
318 unsigned int tpbLength, const unsigned char* tpb);
319 virtual JTransaction* FB_CARG reconnectTransaction(Firebird::IStatus* status, unsigned int length, const unsigned char* id);
320 virtual JRequest* FB_CARG compileRequest(Firebird::IStatus* status, unsigned int blr_length, const unsigned char* blr);
321 virtual void FB_CARG transactRequest(Firebird::IStatus* status, Firebird::ITransaction* transaction,
322 unsigned int blr_length, const unsigned char* blr,
323 unsigned int in_msg_length, const unsigned char* in_msg,
324 unsigned int out_msg_length, unsigned char* out_msg);
325 virtual JBlob* FB_CARG createBlob(Firebird::IStatus* status, Firebird::ITransaction* transaction,
326 ISC_QUAD* id, unsigned int bpbLength = 0, const unsigned char* bpb = 0);
327 virtual JBlob* FB_CARG openBlob(Firebird::IStatus* status, Firebird::ITransaction* transaction,
328 ISC_QUAD* id, unsigned int bpbLength = 0, const unsigned char* bpb = 0);
329 virtual int FB_CARG getSlice(Firebird::IStatus* status, Firebird::ITransaction* transaction, ISC_QUAD* id,
330 unsigned int sdl_length, const unsigned char* sdl,
331 unsigned int param_length, const unsigned char* param,
332 int sliceLength, unsigned char* slice);
333 virtual void FB_CARG putSlice(Firebird::IStatus* status, Firebird::ITransaction* transaction, ISC_QUAD* id,
334 unsigned int sdl_length, const unsigned char* sdl,
335 unsigned int param_length, const unsigned char* param,
336 int sliceLength, unsigned char* slice);
337 virtual void FB_CARG executeDyn(Firebird::IStatus* status, Firebird::ITransaction* transaction, unsigned int length,
338 const unsigned char* dyn);
339 virtual JStatement* FB_CARG prepare(Firebird::IStatus* status, Firebird::ITransaction* tra,
340 unsigned int stmtLength, const char* sqlStmt, unsigned int dialect, unsigned int flags);
341 virtual Firebird::ITransaction* FB_CARG execute(Firebird::IStatus* status,
342 Firebird::ITransaction* transaction, unsigned int stmtLength, const char* sqlStmt,
343 unsigned int dialect, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
344 Firebird::IMessageMetadata* outMetadata, void* outBuffer);
345 virtual Firebird::IResultSet* FB_CARG openCursor(Firebird::IStatus* status,
346 Firebird::ITransaction* transaction, unsigned int stmtLength, const char* sqlStmt,
347 unsigned int dialect, Firebird::IMessageMetadata* inMetadata, void* inBuffer,
348 Firebird::IMessageMetadata* outMetadata);
349 virtual JEvents* FB_CARG queEvents(Firebird::IStatus* status, Firebird::IEventCallback* callback,
350 unsigned int length, const unsigned char* events);
351 virtual void FB_CARG cancelOperation(Firebird::IStatus* status, int option);
352 virtual void FB_CARG ping(Firebird::IStatus* status);
353 virtual void FB_CARG detach(Firebird::IStatus* status);
354 virtual void FB_CARG dropDatabase(Firebird::IStatus* status);
355
356public:
357 explicit JAttachment(Attachment* handle);
358
359 Attachment* getHandle() throw()
360 {
361 return att;
362 }
363
364 JAttachment* getAttachment()
365 {
366 return this;
367 }
368
369 Firebird::Mutex* getMutex(bool useAsync = false, bool forceAsync = false)
370 {
371 if (useAsync && !forceAsync)
372 {
373 fb_assert(!mainMutex.locked());
374 }
375 return useAsync ? &asyncMutex : &mainMutex;
376 }
377
378 void cancel()
379 {
380 fb_assert(asyncMutex.locked());
381 fb_assert(mainMutex.locked());
382
383 att = NULL;
384 }
385
386 JTransaction* getTransactionInterface(Firebird::IStatus* status, Firebird::ITransaction* tra);
387 jrd_tra* getEngineTransaction(Firebird::IStatus* status, Firebird::ITransaction* tra);
388
389 void manualLock(ULONG& flags);
390 void manualUnlock(ULONG& flags);
391 void manualAsyncUnlock(ULONG& flags);
392
393private:
394 Attachment* att;
395 // These mutexes guarantee attachment existence. After releasing both of them with possibly
396 // zero att_use_count one should check does attachment still exists calling getHandle().
397 Firebird::Mutex mainMutex, asyncMutex;
398
399 void freeEngineData(Firebird::IStatus* status);
400};
401
402// internal class used in system background threads
403class SysAttachment FB_FINAL : public JAttachment
404{
405public:
406 explicit SysAttachment(Attachment* handle)
407 : JAttachment(handle)
408 {
409 }
410
411 void initDone();
412
413 virtual int FB_CARG release()
414 {
415 if (--refCounter != 0)
416 return 1;
417
418 Attachment* attachment = getHandle();
419 if (attachment)
420 {
421 destroy(attachment);
422 }
423
424 delete this;
425 return 0;
426 }
427
428private:
429 void destroy(Attachment* attachment);
430};
431
432class JService FB_FINAL : public Firebird::RefCntIface<Firebird::IService, FB_SERVICE_VERSION>
433{
434public:
435 // IService implementation
436 virtual int FB_CARG release();
437 virtual void FB_CARG detach(Firebird::IStatus* status);
438 virtual void FB_CARG query(Firebird::IStatus* status,
439 unsigned int sendLength, const unsigned char* sendItems,
440 unsigned int receiveLength, const unsigned char* receiveItems,
441 unsigned int bufferLength, unsigned char* buffer);
442 virtual void FB_CARG start(Firebird::IStatus* status,
443 unsigned int spbLength, const unsigned char* spb);
444
445public:
446 explicit JService(Service* handle);
447
448private:
449 Service* svc;
450
451 void freeEngineData(Firebird::IStatus* status);
452};
453
454class JProvider FB_FINAL : public Firebird::StdPlugin<Firebird::IProvider, FB_PROVIDER_VERSION>
455{
456public:
457 explicit JProvider(Firebird::IPluginConfig* pConf)
458 : cryptCallback(NULL), pluginConfig(pConf)
459 {
460 }
461
462 static Firebird::RefPtr<JProvider> getInstance()
463 {
464 Firebird::RefPtr<JProvider> p(new JProvider(NULL));
465 return p;
466 }
467
468 // IProvider implementation
469 virtual JAttachment* FB_CARG attachDatabase(Firebird::IStatus* status, const char* fileName,
470 unsigned int dpbLength, const unsigned char* dpb);
471 virtual JAttachment* FB_CARG createDatabase(Firebird::IStatus* status, const char* fileName,
472 unsigned int dpbLength, const unsigned char* dpb);
473 virtual JService* FB_CARG attachServiceManager(Firebird::IStatus* status, const char* service,
474 unsigned int spbLength, const unsigned char* spb);
475 virtual void FB_CARG shutdown(Firebird::IStatus* status, unsigned int timeout, const int reason);
476 virtual void FB_CARG setDbCryptCallback(Firebird::IStatus* status,
477 Firebird::ICryptKeyCallback* cryptCallback);
478
479 virtual int FB_CARG release();
480
481private:
482 Firebird::ICryptKeyCallback* cryptCallback;
483 Firebird::IPluginConfig* pluginConfig;
484};
485
486inline JStatement::JStatement(dsql_req* handle, JAttachment* ja, Firebird::Array<UCHAR>& meta)
487 : statement(handle), jAtt(ja), metadata(getPool(), this, ja)
488{
489 metadata.parse(meta.getCount(), meta.begin());
490}
491
492} // namespace Jrd
493
494#endif // JRD_ENGINE_INTERFACE_H
495