Features and enhancements

1. The method function FindField(const FieldName: string): TFIBXSQLVAR has been implemented in TpFIBQuery. If the required field is not found, the function returns nil instead of the exception.

2. The property GroupByClause: string has been added to TpFIBQuery. It returns the text of GROUP BY from the current SQL text.

3. Now TpFIBQuery and TpFIBDataSet enable to work with macros in DDL queries.

4. The directive {$DEFINE NO_GUI} has been added to FIBPlus.inc. If it is enabled, the library files are generated without VCL-modules and visual components.

5. Now the TpFIBDataSet.GenerateSQLs method works even when the field collection is empty. This feature may help to generate SQL before opening a dataset, if the fields are not created in design-time.

6. TpFIBDataSet includes a new function LocatePrior (const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean. It enables to search a record in the local buffer (from the current record to the buffer beginning).

7. The TpFIBDataSet.Options property now has a psSetEmptyStrToNull option. If it is active, new string fields of this dataset have the EmptyStrToNull property activated.

8. The TpFIBDataSet.Options property has a poFreeHandlesAfterClose option. If this option is active and when Eof is True (i.e. after getting all records of the query result) Handle releases in TpFIBDataSet. This feature helps to avoid the server report «Object in use» on altering database objects. Note: Handle release causes the query close.

9. An analogous option (poFreeHandlesAfterClose) has been added to TpFIBQuery. If it is used, Handle is released immediately after calling of the Execute method.

10. An ability to set the transaction parameter isc_tpb_no_auto_undo has been added to TpFIBTransaction.

11. A new property TAutoUpdateOptions.SeparateBlobUpdate: Boolean has been implemented. If it is active, BLOB-fields are saved in the following way:

a) Texts of modifying queries are generated without BLOB-fields.

b) Modifying queries are generated separately together with the BLOB-fields.

c) On executing Post the query is started without the BLOB-fields, and then an empty BLOB is being created. After it is saved in the database, UPDATE is started in order to save a real BLOB-field value. As a rule, BLOB-fields are saved by an ordinary modifying query. In case this query was rejected by the server and an exception arose, the BLOB-fields must be queried to the server anew. Due to a new approach, this situation is avoided. The BLOB-field is not queried to the server unless the main query INSERT/UPDATE is a success, and unless the developer encounters no problem during this step (i.e. if the server does not reject the operation in general).

12. A new mode of TpFIBDataSet internal buffer organization has been implemented. For more details see the paragraph «TpFIBDataSet mode "Confined local buffer"».

13. An ability of automatic caching of BLOB-fields at the client has been implemented. For more details see the paragraph «Caching BLOB-fields at the client side».

14. Now one may write a table name with an alias, for instance, as «TABLE1 AAA» in the AutoUpdateOptions.UpdateTableName property. This feature may be useful for correct generation of modifying queries by the SelectSQL text, with the modified table mentioned two times or more.

Example:

SELECT
AAA.*, BBB.*
FROM
TABLE1 AAA, TABLE1 BBB
WHERE …….

Previous FIBPlus versions cannot make correct modifying queries for such queries. In FIBPlus 6.0 it's enough to write AutoUpdateOptions.UpdateTableName := 'TABLE1 AAA'.

15. SQLEditor has the button 'To Code Editor'. On pressing it, the query text is opened in a standard IDE code editor, and the editor is closed. The side effect for TpFIBDataSet is shown when using a standard code editor: all the queries are saved in corresponding properties (implicit saving mechanism).

16. Now SQLEditor has CodeProposal if the Editors package uses Sy nEdit. pFIBPropEd.inc has new directives for different SynEdit versions.

17. Changes in SQLNavigator:

a) The SQLNavigator window is StayOnTop, not modal.

b) A function of access to the component from the code editor on the form has been added. One may point the cursor to the component name (e.g. to pFIBQuery1), press Ctrl-W and SQLNavigator will focus on the form with this component. Then the component will be selected and chosen in Object Inspector. If the SQL code editor is open, the form and the component with the corresponding property will also be opened.

c) Similar to the changes in b), the combination Ctrl-Shift-W has been added. The search is done by all project forms. If more than one component is found, a list of forms with the required component name will be shown there. Double-click a form to open it and stand on the required component.

18. Some methods and properties in the TpFIBDatabase and TpFIBTransaction components are declared out-of-date and will not be supported in the following versions. In particular this concerns:

procedure RemoveDataSet(Idx: Integer);
procedure RemoveDataSets;
function AddDataSet(ds: TFIBBase): Integer; deprecated;
property DataSetCount: Integer read GetFIBBasesCount;
property DataSets[Index: Integer]: TFIBBase read GetFIBBase;

They were replaced by:

procedure RemoveFIBBase(Idx: Integer);
procedure RemoveFIBBases;
function AddFIBBase(ds: TFIBBase): Integer;
property FIBBaseCount: Integer read GetFIBBasesCount;
property FIBBases[Index: Integer]: TFIBBase read GetFIBBase;

The change was done in order to clear up the confusion between method names and property names and their functions. In spite of the facts, that these methods are hardly ever used in applications and this enhancement will scarcely influence the existing projects, for compatibility with earlier versions one may use the command {$DEFINE USE_DEPRECATE_METHODS1} in FIBPlus.inc.

19. TpFIBDataSet and TpFIBQuery have the RestoreMacroDefaultValues methods, which restore macro default values.

20. The TpFIBDataSet behaviour has become more stable if the poPersistentSorting option is active. Only if after macro changes, the sorting fields are replaced by new ones, and the sorting result also changes. Otherwise, the result holds true.

21. A new declaration for the OpenWP method in TpFIBDataSet has been added.

procedure OpenWP(const ParamNames:array of string;const ParamValues: array of Variant); overload;

This enhancement enables to set parameter names in the ParamNames variable. In ParamValues you should set parameter values.

22. TpFIBQuery has an analogous method:

procedure ExecWP(const ParamNames: array of string; ParamValues: array of Variant); overload;

23. TpFIBDataSet has new methods:

procedure ReOpenWP(const ParamValues: array of Variant); overload;
procedure ReOpenWP(const ParamNames: array of string; const ParamValues: array of Variant); overload;
procedure ReOpenWPS(const ParamSources: array of ISQLObject);

They are similar to OpenWP, OpenWPS, though they close TpFIBDataSet, if it is open.

24. TFIBBlobField has a read-only Blob_id property.

25. Now FIBPlus supports string fields and connections with charset UNICODE_FSS. For full support of multi language text data there are added:

a) New classes of TpFIBDataSet fields:

TFIBWideStringField = class(TWideStringField) - for field types VARCHAR,CHAR; TFIBMemoField = class(TMemoField, IWideStringField) - for BLOB-fields, where IWideStringField is an interface handled by visual TNT components (http://tnt.ccci.org/delphi_unicode_controls)

b) A new psSupportUnicodeBlobs option in DataSet.PrepareOptions, which enables to work with UNICODE_FSS BLOB-fields. By default this option is not active, as an additional query is required to check the charset of each BLOB-field. This query will be excess if you don't work with UNICODE.

c) A new method TFIBDatabase - function IsUnicodeCharSet: Boolean has been added. It returns True, if the connection uses UNICODE_FSS.

d) A new property FIBXSQLVAR.AsWideString: WideString; has been added.

Bugs fixed:

1. Some events were ignored on working with TSIBfibEventAlerter1. Fixed.

2. The CancelUpdates method worked incorrectly on recurring calling of ApplyUpdates after Commit: there were shown records, deleted before Commit. Fixed.

3. Some internal queries have been changed for compatibility with ñ Borland InterBase 4.

4. An implementation error of AutoUpdateOptions.AutoParamsToFields. Fixed.

5. An error «Invalid Blob_id» on attempting to execute the recurring UPDATE query after the first failure. Fixed.

6. The FIBDataSet.LockRecord method generated an incorrect query if there was more than one key field set. Fixed.

7. If the ORDER BY statement was formed in a macro, the SortFields property was not set. This error caused incorrect work of poKeepSorting. Fixed.

8. Incorrect error coordinates were returned in the SQL text on attempting to execute Prepare. Fixed.

9. An error of saving the DefaultFormats.DateTimeDisplayFormat property in .dfm file occurred. Fixed.

10. Wrong change of the current record position after editing in TpFIBDataSet with the poKeepSorting option. Sometimes the position changed even if the sorted field values did not. Fixed.

11. The Field.OldValue property returned chance values at dsInsert. Now under such circumstances this property is always null.

12. An error in the TFIBInputRawFile.ReadParameters method, which caused incorrect class work, if the file being read had any saved BLOB-fields. Fixed.

13. Now BlobField.OldValue shows its real value. Earlier it returned the current value of the BLOB-field.

14. Incorrect work of TpFIBDataSet on concurrently active poKeepSorting and poProtectedEdit options in queries, sorted by calculating fields. Fixed.

15. An error of the poKeepSorting mode on adding a new record to an empty dataset. Fixed.

16. The Resync method has been corrected. Earlier if TpFIBDataSet was closed, Resync caused errors while trying to handle lost connection to the database.

17. Errors on UpdateOnlyModifiedFields. Fixed.

18. An error of the RefreshSQL generation when using macros. Fixed.

19. Array-fields didn't work in TpFIBDataSet with shared transactions. Fixed.

20. Array-fields of the NUMERIC(18,xxx) type were not handled in Dialect 3. Fixed.

21. The CheckSQLS button didn't work in SQLNavigator. Fixed.

TpFIBDataSet mode "Confined local buffer"

The mode was first suggested by Sergey Spirin in gb_Datasets components. Now FIBPlus is also capable of this solution. This feature enables to navigate on TpFIBDataSet without fetching all the records. In fact it is simulation of random access to records by means of supplementary queries. The technology sets a number of query requirements. In particular, one of the obligatory requirements is use of ORDER BY in SelectSQL. First, in ORDER BY it's important to make the combination of field values unique. Second, to speed up data transfer time it's better to have two indices - ascending and descending - for this field combination.

This simple example illustrates the technology. Having such a query in SelectSQL:

SELECT * FROM TABLE
ORDER BY FIELD

You may get some first records, fetching them successively. To see the last records immediately, you may execute an additional query with descending sorting instead of querying all the records from the server,:

SELECT * FROM TABLE
ORDER BY FIELD DESC

Obviously successive fetching of several records will result the last records (in relation to the initial query). Similar queries are for exact positioning on any record, as well as on records below and above the current one:

SELECT * FROM TABLE
WHERE (FIELD = x)

SELECT * FROM TABLE
WHERE (FIELD < x)
ORDER BY FIELD DESC

SELECT * FROM TABLE
WHERE (FIELD > x)
ORDER BY FIELD

To carry out this technology TpFIBDataSet has a new property:

property CacheModelOptions:TCacheModelOptions, where

TCacheModelOptions = class(TPersistent)
property BufferChunks: Integer ;
property CacheModelKind: TCacheModelKind ;
property PlanForDescSQLs: string ;
end;

BufferChunks replaces the existing property BufferChunks of TpFIBDataSet. The TCacheModelKind type can have a cmkStandard value for the standard local buffer work and a cmkLimitedBufferSize value for the new technology of the confined local buffer. The buffer size is a number of records set in BufferChunks.

The PlanForDescSQLs property enables to set a separate plan for queries with descending sorting.

Note: when using the technology of the confined local buffer,

a) You must not activate the CachedUpdate mode;

b) The RecNo property will return incorrect values;

c) Local filtering will not be supported;

d) Work with BLOB-fields may be not stable in the present version;

e) You should activate the psGetOrderInfo option in PrepareOptions.

BLOB-field cache at client side

BLOB-field support in InterBase and Firebird API suggested implementation of this idea. Executing any SELECT query with BLOB-fields, the client application gets only BLOB_ID instead of real values of these fields. If the application attempts explicit reading of some BLOB-field, the server returns the value by BLOB_ID. So actually BLOB-fields are already handled separately from other field types. This is done to avoid superfluous net traffic as in most cases BLOB-fields are rather huge.

Further improvement of this mechanism enable to avoid resending BLOB-fields, queried from the server before and remained unchanged. The approach is based on the fact that BLOB_ID is changing together with the BLOB-field on changing its value. Thus the application only compares the old and new BLOB_ID, in order to decide whether to get the BLOB-filed from the database or not. The queried BLOB-fields are saved in some directory at the local disk and then taken from it rather than from the server.

TpFIBDatabase has a new BlobSwapSupport: TBlobSwapSupport; property, where

TBlobSwapSupport = class(TPersistent)
property Active: boolean default False;
property SwapDir: string;
property MinBlobSizeToSwap: integer default 0;
end;

If BlobSwapSupport.Active := True, FIBPlus will automatically save queried BLOB-fields in some directory (the SwapDir property). By default the SwapDir property is {APP_PATH}, it is equal to the directory with the executed application. It is also possible to set the subdirectory to save BLOB-fields. For example, SwapDir := '{APP_PATH}' + '\BLOB_FILES\'

Besides the new property TpFIBDatabase has four new events:

property BeforeSaveBlobToSwap: TBeforeSaveBlobToSwap;
property AfterSaveBlobToSwap: TAfterSaveLoadBlobSwap;
property AfterLoadBlobFromSwap: TAfterSaveLoadBlobSwap;
property BeforeLoadBlobFromSwap: TBeforeLoadBlobFromSwap;

where

TBeforeSaveBlobToSwap = procedure(const TableName, FieldName: string; RecordKeyValues: array of variant; Stream: TStream; var FileName: string; var CanSave: boolean) of object;

TAfterSaveLoadBlobSwap = procedure(const TableName, FieldName: string; RecordKeyValues: array of variant; const FileName: string) of object;

TBeforeLoadBlobFromSwap = procedure(const TableName, FieldName: string; RecordKeyValues: array of variant; var FileName: string; var CanLoad: boolean) of object;

The handlers enable flexible control of saving BLOB-fields at and reading them from the disk. In particular one may inhibit saving a particular BLOB-field in handlers, depending on table names and field names values of other record fields and free disk space, etc. Using the MinBlobSizeToSwap property one may control the saving process too. There you may set a minimal size of BLOB-fields saved on the disk.

The technology has a number of restrictions:

1. A table must have a primary key.

2. BLOB-fields must be read by TpFIBDataSet.

3. The application must control free disk space itself. In particular this function can be realized in the BeforeSaveBlobToSwap event handler.

4. Unfortunately after database backup/restore all BLOB_ID's are changed, so the local cache has not point and is automatically purged. On every connection to the database there is a special thread which checks the cache on corresponding BLOB-fields in a separate connection. If a BLOB-field does not exist, the corresponding file is deleted.


Preview text: New features, bug-fixes
Prices in Euro:

235 (1 copy)
1250 (unlimited)

Volume discounts are available...

Navigation



Our 911 dispatch center needed a program to monitor the status of equipment used in emergency situations. If one dispatcher modified the status of a piece of equipment, all the other dispatchers needed to see this change immediately. The most elegant way to implement this was by using Firebird Events to asynchronously notify all the users whenever a pertinent change had occurred at the database server. After failing to implement this myself using the Firebird API, I bought a copy of FIBPlus. I dropped a Database, EventAlert and ErrorHandler control into a C++ Builder DataModule and within minutes I had all the functionality I needed. I was able to complete the project quickly and the users are thrilled with the results because I gave them more features than they originally asked for. >>

Darryl Caillouet Programmer City of Little Rock
FOR CUSTOMERS
Download full versions and updates in your Personal Area