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 | |
33 | namespace Jrd { |
34 | |
35 | // Engine objects used by interface objects |
36 | class blb; |
37 | class jrd_tra; |
38 | class dsql_req; |
39 | class JrdStatement; |
40 | class Attachment; |
41 | class Service; |
42 | |
43 | // forward declarations |
44 | class JStatement; |
45 | class JAttachment; |
46 | class JProvider; |
47 | |
48 | class JBlob FB_FINAL : public Firebird::RefCntIface<Firebird::IBlob, FB_BLOB_VERSION> |
49 | { |
50 | public: |
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 | |
62 | public: |
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 | |
78 | private: |
79 | blb* blob; |
80 | Firebird::RefPtr<JAttachment> jAtt; |
81 | |
82 | void freeEngineData(Firebird::IStatus* status); |
83 | }; |
84 | |
85 | class JTransaction FB_FINAL : public Firebird::RefCntIface<Firebird::ITransaction, FB_TRANSACTION_VERSION> |
86 | { |
87 | public: |
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 | |
104 | public: |
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 | |
131 | private: |
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 | |
143 | class JResultSet FB_FINAL : public Firebird::RefCntIface<Firebird::IResultSet, FB_RESULTSET_VERSION> |
144 | { |
145 | public: |
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 | |
160 | public: |
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 | |
176 | private: |
177 | Firebird::RefPtr<JStatement> statement; |
178 | bool eof; |
179 | |
180 | void freeEngineData(Firebird::IStatus* status); |
181 | }; |
182 | |
183 | class JStatement FB_FINAL : public Firebird::RefCntIface<Firebird::IStatement, FB_STATEMENT_VERSION> |
184 | { |
185 | public: |
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 | |
205 | public: |
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 | |
218 | private: |
219 | dsql_req* statement; |
220 | Firebird::RefPtr<JAttachment> jAtt; |
221 | Firebird::StatementMetadata metadata; |
222 | |
223 | void freeEngineData(Firebird::IStatus* status); |
224 | }; |
225 | |
226 | inline JAttachment* JResultSet::getAttachment() |
227 | { |
228 | return statement->getAttachment(); |
229 | } |
230 | |
231 | // Change after adding separate handle for cursor in dsql |
232 | inline dsql_req* JResultSet::getHandle() throw() |
233 | { |
234 | return statement->getHandle(); |
235 | } |
236 | |
237 | class JRequest FB_FINAL : public Firebird::RefCntIface<Firebird::IRequest, FB_REQUEST_VERSION> |
238 | { |
239 | public: |
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 | |
255 | public: |
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 | |
271 | private: |
272 | JrdStatement* rq; |
273 | Firebird::RefPtr<JAttachment> jAtt; |
274 | |
275 | void freeEngineData(Firebird::IStatus* status); |
276 | }; |
277 | |
278 | class JEvents FB_FINAL : public Firebird::RefCntIface<Firebird::IEvents, FB_EVENTS_VERSION> |
279 | { |
280 | public: |
281 | // IEvents implementation |
282 | virtual int FB_CARG release(); |
283 | virtual void FB_CARG cancel(Firebird::IStatus* status); |
284 | |
285 | public: |
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 | |
301 | private: |
302 | int id; |
303 | Firebird::RefPtr<JAttachment> jAtt; |
304 | Firebird::RefPtr<Firebird::IEventCallback> callback; |
305 | |
306 | void freeEngineData(Firebird::IStatus* status); |
307 | }; |
308 | |
309 | class JAttachment : public Firebird::RefCntIface<Firebird::IAttachment, FB_ATTACHMENT_VERSION> |
310 | { |
311 | public: |
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 | |
356 | public: |
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 | |
393 | private: |
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 |
403 | class SysAttachment FB_FINAL : public JAttachment |
404 | { |
405 | public: |
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 | |
428 | private: |
429 | void destroy(Attachment* attachment); |
430 | }; |
431 | |
432 | class JService FB_FINAL : public Firebird::RefCntIface<Firebird::IService, FB_SERVICE_VERSION> |
433 | { |
434 | public: |
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 | |
445 | public: |
446 | explicit JService(Service* handle); |
447 | |
448 | private: |
449 | Service* svc; |
450 | |
451 | void freeEngineData(Firebird::IStatus* status); |
452 | }; |
453 | |
454 | class JProvider FB_FINAL : public Firebird::StdPlugin<Firebird::IProvider, FB_PROVIDER_VERSION> |
455 | { |
456 | public: |
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 | |
481 | private: |
482 | Firebird::ICryptKeyCallback* cryptCallback; |
483 | Firebird::IPluginConfig* pluginConfig; |
484 | }; |
485 | |
486 | inline 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 | |