11.03.2014 11:56, Alex Peshkoff wrote: > whole libc is one big "architectural mistake". But usually it's called > implementation detail :)
It is rather missing fool-proof. >> As the example: common/calsses/InternalMessageBuffer produces message >> metadata from BLR >> using MetadataFromBlr(). After that remote/client/BlrFromMessage produces >> _different_ BLR >> from input message metadata, but the rest of interface code works with >> assumption, that >> new BLR is compatible with old buffer, created for old BLR. > > Is it really incompatible? What specific format causes troubles? Public API receives BLR and data buffer from external API. It cannot expect that user will always follow internal rules for creating them. So, it cannot be sure if transformation "external BLR->metadata" and "metadata->internal BLR" is completely symmetric. > Certainly this should be fixed. Fix every user application using API to create data buffers in exact format? It is not good because a) won't let change this format ever and b) too cruel. Much better would be to hide internal buffer format from user by interface that allow to get and set data and null indicators. Something like this: class IDataBuffer: IRefCounted { public: IMesageMetadata* getMetadata() = 0; void* getDataPointer(unsigned Index) = 0; SSHORT* getNullIndPointer(unsigned Index) = 0; } or better class IDataBuffer: IRefCounted { public: IMesageMetadata* getMetadata() = 0; void* getDataPointer(unsigned Index) = 0; bool isNull(unsigned Index) = 0; vois setIsNull(unsigned Index, bool value) = 0; } Even better would be interface which has getters and setters for every supported data type, but, probably, it will be hard to make such interface easily expandable for new data types. > If we collect all nulls in the beginning of the record not changing ODS, > we will get unreadable databases. If we do it changing ODS, we have no > problems. Same for data transfered over network - if we change protocol > version when changing format of messages traveling between server and > client - we have no problems. We can (and I think that we should) separate these things: data received from user application, data traveling through network, data processed by engine and data stored on disk. Yes, it will add complexity at junctions, but allow to change one module without affecting the rest. To accomplish that, every module should work with objects (interfaces) coming from outside without attempts to guess their implementation and using only their API. > Yes, but it's not related with how we provide metadata information to > client. I'm not worried about metadata provided to application, but about metadata received from application. For example, currently IStatement::execute() receives pointer to IMessageMetadata and plain buffer. It can be (more of less) sure that every single value in buffer is placed at offset it get from metadata. But there is no way to check if this metadata return offsets according to network buffer rules. No way to check if data in buffer is placed in right order. Nevertheless, this buffer is transfered to remote module without doubts. > Certainly, it's possible to transfer offsets in message over the wire > together with the rest data in getInfo() call. But except ability to > sort fields in record in arbitrary order (suppose more changes will be > needed to make it work) we win nothing with that change. No, offsets in wire is really insanity. Transformation of data between API and wire can improve stability. Firebird ship should be separated with bulkheads for insubmersibility. -- WBR, SD. ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/13534_NeoTech Firebird-Devel mailing list, web interface at https://lists.sourceforge.net/lists/listinfo/firebird-devel