From: Alex P. <pes...@ma...> - 2011-03-28 09:11:01
|
On 03/27/11 20:03, Adriano dos Santos Fernandes wrote: > On 27-03-2011 10:11, Alex Peshkoff wrote: >>>> I know your mind that all calls must pass through yValve. But I have not >>>> seen any explanation of this requirement. The only reason I remember is >>>> 'other types of providers need access to this calls'. But this >>>> requirement is rather strange. Let's take a look at SP. It executes some >>>> SQL operators, and (I hope) nobody requires this calls to go to yValve. >>> Yvalve defines Firebird API requirements, may check handles (objects >>> too), may do extra things. >> With VTable-based API checking handles makes almost no sense. If we >> reached some function (it's virtual function) in the object, this means >> that a region of memory where user's pointer to that interface points >> has correct VTable. That is ehough guarantee that the object is OK. >> > Not true. > > Let say I have: > IAttachment* attachment = ...; // attachment from yvalve > ITransaction* transaction = ...; // transaction from provider or any > other instance of an ITransaction > > And we call attachment->createBlob(transaction, ...); > > Yvalve would use the transaction as an YTransaction, and it obviously is > not. > This need happened due to my attempt to emulate old ISC API too careful :-) All the cases when we need both attachment & transaction are due to my wrong understanding (when writing interfaces for yvalve) of how should multiDb transaction work. Such transaction should have same interface as single database one, but absolutely other implementation. This implementation is provider-independent, therefore can be placed in master interface. startMultiDbTransaction() creates a container holding pairs - IAttachment* which started transaction and started ITransaction*. All functions like createBlob() go to ITransaction. Normal implementation ignores IAttachment* parameter. MultiDb implementation searchs in internal container for appropriate IAttachment* and calls same function for found transaction. No more casts - and therefore no need in additonal checks. And yes - one can safely mix attachments, created by different providers, in such MultiDb transaction. I.e. I still do not see where do we need to do additional checks. >>> Also, let say external code receives an engine IAttachment which was >>> registered in yvalve and now has a handle. Then external code starts to >>> use this handle and start new transaction with legacy API. If this >>> IAttachment is not from yvalve, now yvalve gained another responsibility >>> which is to coordinate engine provider objects. >> If external code start transaction, using legacy handle created for >> current attachment, then isc_start_transaction(legHandle) will find >> IAttachment* curAtt, appropriate for that legHandle, and call >> curAtt->startTransaction(). Certainly, if curAtt is not yValve's but >> engine's object, this means that transaction is started not under yvalve >> control. And telling true I see absolutely no problems that this >> transaction did not pass through yValve. >> > I do not agree this is easy or make code simple. Many times simpler than adding artificial yValve control interface. > Using "YObjects" in the > yvalve makes sense, and this case introduces an exception that makes > things harder. I do not understand what this phrase about? What "YObjects", how makes sense? Your solution to pass pointers to yValve objects into engine when working with ISC API was unavoidable hack when using ISC API. With new providers interfaces we should avoid such hacks. Removing old (or new) hacks is one of the reasons to add new interface. I do not understand why do you protect that old hack so intensively, and try to push it into new code. |