Paul,

I am not surprised that you wrote "it is more difficult than I thought". When I set out to upgrade IBX for Lazarus to the new Firebird 3 OO API, I thought that it would be a relatively straightforward task. My intention was to separate out the parts of IBX that were specific to the VCL/LCL from those that were concerned with converting Firebird data types to Pascal data types and for handling the intricacies of the low level API - surely moving to the new API was just a matter of moving from the XSQLDA oriented approach to unpacking and packing buffers.

I ended up creating a new (Firebird Pascal) API with almost 37K lines of Pascal code of which 4K was specific to the support of the legacy Firebird API and another 4K for the test suite. The "sloccount" utility reckons it would cost $1.1M to create. Some of this code is there because of a decision to use COM interface types for the API (driven by a desire to have a common core API for both Firebird 2.5 and Firebird 3 OO style interfaces). However, this is only a small part of the codebase.

I did not set out intending to create such a large codebase - it simply the result of what needed to be done - and its size will hopefully give some perspective to your task. I have positioned the API at the same level as IBPP and I believe that that is the correct level for programmers that want direct access to the Firebird API but without having to work out how to use the low level API.

As to the question about VCL integration - my advice is do not even go there unless you are intending to create a rival to IBX (which weighs in at a further 51K lines). The TDataset model is not for the faint-hearted and takes you into a whole new realm of buffer management and SQL manipulation. The TDataset model is also grossly OTT unless you want to use Delphi's data aware controls. In practice, I have found myself using my Firebird Pascal API for all programmatic database access other than GUI support.

Having gone through all this pain, I have published the Firebird Pascal API as an API separate from IBX for Lazarus, and under the Interbase Public Licence. It compiles and  is tested for both FPC and Delphi, and comes with a comprehensive user manual. You can find it at

https://mwasoftware.co.uk/fb-pascal-api

The real question is who is the audience for the examples? Is it the application programmer or is it the maintainers of packages such as  IBPP, Jaybird and the Firebird Pascal API? The answer to that question should determine your objectives for the examples.

Notes:

When you look at what has to be done for a comprehensive native Pascal API for Firebird you find that:

1. You need data type conversion rules for all Firebird data types. This includes character strings where the Firebird character set has to be translated into an AnsiString code page (a property of the AnsiString type) with transliteration if necessary.

2. Input/output buffer management from the statement metadata. My API additionally includes an intermediate layer for the Firebird OO API (like an XSQLDA) so that the user does not have to read/write the values in strict column order.

3. Code to manage the myriad parameter block formats (input and output) each with their own idiosyncrasies.  I found Pascal Generic (template) classes very useful here. The issues here are all about converting from Pascal data types to the encoding format used for each class of parameter block - it is amazing how many different ways Firebird parameter blocks have for encoding integer and string types.

4. Event Management requires thread management and process synchronisation - and the resulting platform dependencies that you could introduce.

5. Blobs have their own handling issues with text blobs having to appear as Pascal AnsiStrings (codepage and transliteration issues as above) while binary blobs are best converted into TStream descendents.

6. Arrays are do-able but there is no documentation that I could find and had to reverse engineer the legacy Firebird API to work out the SDL format.

7. At least the database connection and transaction APIs are pretty straightforward - once you have a way of handling the parameter blocks.

8. And then there is the services API... Client side database backup/restore is another fun problem.

9. Finally, you also need to think about how you load and access the Firebird Client library from a Pascal Program. The Firebird.pas source code takes a basic approach which only really works well with static linking. IBX traditionally used dynamic loading and dynamic API binding. I have kept with that style for the Firebird Pascal API. It allows the API to search for the Firebird DLL/SO according to a platform specific algorithm and then to determine the version number of the low level interface and adapt accordingly. This was original useful for deciding if the Interbase 6 extensions were present. It is now used to determine if the Firebird 3 OO API is present and in the latest (beta) versions to adapt to the use of the Firebird 4 extensions. It also allows the same system to host multiple copies of the Firebird library - I exploit this to readily permit automated testing against different versions of the Firebird Client library.

I guess examples will only scratch the surface of these issues. You will probably end up concentrating on opening an example database using a basic DPB and reading/writing a limited set of data types.

Regards

Tony Whyman

MWA

On 17/08/2020 16:25, Paul Reeves wrote:
I thought I would port the OO API examples to Object Pascal. After all, they
are quite simple, so how hard could it be?

In fact it is more difficult than I thought and I am not happy with the
results. I've done two examples - update and select - and I would like to
commit them but before doing so I'd like to discuss how we should proceed.

In my opinion we should start a new sub-directory to contain all the object
pascal code. This is because the examples will actually need several
supporting files in a common directory. It would be best if the were kept
clearly separate from other examples.

But the main problem I have found is that if I try to copy the C++ style too
closely all we end up with is very bad object pascal. It succeeds in
demonstrating the new API but does not demonstrate good programming practice.

However, if we want to demonstrate good programming practice we should
probably integrate the examples into the VCL. And that might be a step too
far.

Does anyone have any thoughts on this?


Paul


Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to