Recent

Author Topic: IBX 2.3.4 is now available for download  (Read 3014 times)

tonyw

  • Sr. Member
  • ****
  • Posts: 319
    • MWA Software
IBX 2.3.4 is now available for download
« on: April 18, 2020, 03:07:34 pm »
MWA Software is pleased to announce that release 2.3.4 of IBX for Lazarus is now available for download from https://mwasoftware.co.uk/ibx.

This is the first update in over a year and provides a consolidated set of minor bug fixes. The changelog for IBX itself is available from https://svn.mwasoftware.co.uk/viewvc/public/ibx/trunk/changelog?view=markup and the changelog for the Firebird Pascal API is available from https://svn.mwasoftware.co.uk/viewvc/public/ibx/trunk/fbintf/changelog?view=markup.

The next release of IBX should be available in the near future and will focus on support for the forthcoming Firebird 4. It will provide support for the new Firebird data types including TIMESTAMP WITH TIME ZONE and extended precision numerics (DecFloat).

patyit

  • New Member
  • *
  • Posts: 27
Re: IBX 2.3.4 is now available for download
« Reply #1 on: April 18, 2020, 07:59:05 pm »
Thanks, I appreciate your work !

zeljkoc

  • Full Member
  • ***
  • Posts: 145
    • Zeljko Cvijanovic
Re: IBX 2.3.4 is now available for download
« Reply #2 on: April 18, 2020, 08:42:37 pm »

Thank you for your work!

devEric69

  • Hero Member
  • *****
  • Posts: 648
Re: IBX 2.3.4 is now available for download
« Reply #3 on: April 18, 2020, 10:54:23 pm »
Thank you!
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

zoltanleo

  • Sr. Member
  • ****
  • Posts: 486
Re: IBX 2.3.4 is now available for download
« Reply #4 on: April 18, 2020, 11:02:42 pm »
Thank U Tony
Win10 LTSC x64/Deb 11 amd64(gtk2/qt5)/Darwin Cocoa (Monterey):
Lazarus x32/x64 2.3(trunk); FPC 3.3.1 (trunk), FireBird 3.0.10; IBX by TonyW

Sorry for my bad English, I'm using translator ;)

lazdeveloper

  • Jr. Member
  • **
  • Posts: 61
Re: IBX 2.3.4 is now available for download
« Reply #5 on: April 21, 2020, 01:28:52 am »
Thanks for the great work

jujibo

  • Full Member
  • ***
  • Posts: 114
Re: IBX 2.3.4 is now available for download
« Reply #6 on: April 21, 2020, 12:25:07 pm »
Great. Thank you!

Zoran

  • Hero Member
  • *****
  • Posts: 1829
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: IBX 2.3.4 is now available for download
« Reply #7 on: April 24, 2020, 10:32:43 am »
Hello, Tony,

Thank you!

Now, although you added SQLSavePoint to TIBSQLStatementTypes enumeration, TIBDataSet.ExecSQL still raises SIGSEGV with "savepoint" type statements (see attached screenshot).

However, API has no problem with it, so workaround similar to what I mentioned in the other thread works (only now, we should ask "if DataSet.StatementType = SQLSavePoint" -- it is no more "out of bounds"):

Code: Pascal  [Select][+][-]
  1. var
  2.   SomeStatement: String;
  3.  
  4. ...
  5.  
  6. SomeStatement := 'savepoint abcd';
  7.  
  8. Dataset.SelectSQL.Text := SomeStatement;
  9.  
  10. Dataset.Prepare; // no problem in prepare phase, so the following works:
  11. case DataSet.StatementType of
  12.   SQLSelect:
  13.     DataSet.Open;
  14.   SQLSavePoint:
  15.     begin
  16.     // DataSet.ExecSQL; // NO. Access Violation!
  17.       DataSet.UnPrepare; // Give up the dataset, go to api.
  18.       // API works well:
  19.       DataSet.Database.Attachment.ExecImmediate(
  20.           DataSet.Transaction.TransactionIntf,
  21.           SomeStatement
  22.           );
  23.     end;
  24. else
  25.   DataSet.ExecSQL;
  26. end;
  27.  
« Last Edit: April 24, 2020, 10:41:29 am by Zoran »

tonyw

  • Sr. Member
  • ****
  • Posts: 319
    • MWA Software
Re: IBX 2.3.4 is now available for download
« Reply #8 on: April 24, 2020, 11:13:22 am »
Zoran,

I would be interested to see the "call stack" for the exception. The exception is raised when a call is made to the underlying Firebird client to build the metadata structure. This should not happen for ExecImmediate and is anyway inappropriate for a SAVEPOINT statement - which has no input or output params. So I am not surprised about the exception - it's how it gets to this point that I am interested in. My guess is that TIBDataSet itself is trying to open a database based on this statement and is not checking for a SAVEPOINT.

If you remove the line "Dataset.SelectSQL.Text := SomeStatement" then it will probably work OK. If you want to test a statement type then TIBSQL is the best way to do this - and not TIBDataSet.

FYI, I am seriously thinking about deprecating the TIBDataSet.ExecSQL method. It's inherited from Borland IBX and I do not know a good use for it. A TIBDataSet should always have a SELECT statement (as its SelectSQL property and anything else is asking for trouble. If you want to call SAVEPOINT then either TIBSQL should be used if you want to use the visual designer, or make direct use of the Attachment.ExecImmediate interface as you have done..

Zoran

  • Hero Member
  • *****
  • Posts: 1829
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: IBX 2.3.4 is now available for download
« Reply #9 on: April 24, 2020, 11:48:27 am »
If you remove the line "Dataset.SelectSQL.Text := SomeStatement" then it will probably work OK. If you want to test a statement type then TIBSQL is the best way to do this - and not TIBDataSet.

In beginning I do not know what the statement type is. To detect its type I need to prepare the statement first. If it is a select, the Dataset is opened and linked to DataSource and DBGrid. Otherwise the statement is executed and the user gets appropriate message.

I think that if I first prepare the statement without a dataset, then check its type, and then only when its type is SQLSelect use the Dataset, then the statement will have to be prepared again with Dataset... or not?

So, I thought it is convenient to use the Dataset in the first place, to avoid preparing the same statement twice, in case it returns the resultset (in which case I need it in DBGrid).
Then, if it is not a select statement, as it is prepared already with Dataset, I can just use Dataset.ExecSQL.

Perhaps I got it wrong?

tonyw

  • Sr. Member
  • ****
  • Posts: 319
    • MWA Software
Re: IBX 2.3.4 is now available for download
« Reply #10 on: April 24, 2020, 01:04:17 pm »
The easiest way to test the statement type is to use something like:

case IBDatabase1.attachment.prepare([isc_tpb_read],SomeStatement).StatementType of
SQLSavePoint:
....

SQLSelect:
...

else
....
end;

You can do something very similar with a TIBSQL - but more verbose. The above is the most succinct way of getting a statement type.

The IAttachment.Prepare method sets up a simple read only transaction and creates and returns an IStatement interface from the prepared query (SomeStatement). IStatement.StatementType is a property of the interface and always contains the SQL statement type for the prepared query. As IStatement is a COM interface, you do not have to separately release it. The transaction also ends as soon as the statement is released (i.e. automatically once execution moves to the next line of the program).

This should be a good example of the power of the underlying  Firebird Pascal Interface.

Zoran

  • Hero Member
  • *****
  • Posts: 1829
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: IBX 2.3.4 is now available for download
« Reply #11 on: April 24, 2020, 02:19:06 pm »
Thanks, Tony.
I know about the automatic lifecycle of these interfaces.
What I still don't understand is -- can I use this prepared statement with this dataset?
If I get SQLSelect type, I still need a TIBDataset to open it and connect DBGrid to it.

I mean, it would be something like this:

Code: Pascal  [Select][+][-]
  1. var
  2.   Stm: IStatement;
  3.   Trn: ITransaction;
  4. ..
  5.  
  6. Trn := IBDataBase1.Attachment.StartTransaction(
  7.         [isc_tpb_write, isc_tpb_nowait, isc_tpb_rec_version, isc_tpb_read_committed]
  8.         , TACommit);
  9.  
  10. Stm := IBDatabase1.Attachment.Prepare(Trn, SomeStatement);
  11.  
  12. // Now I have the prepared statement. I know what to do if it is not select:
  13. if Stm.StatementType <> SQLSelect then
  14.   Stm.Execute
  15. else begin
  16.   // But in this case I need a dataset. Let's assume that it's created already and its Database property is set to IBDatabase1.
  17.   DataSet.Transaction := Trn;
  18.  
  19.   // Now, can I use the statement I prepared above?
  20.   DataSet.SelectStmtHandle := Stm; // No. this cannot be done. It is read-only property.
  21.   // instead, I have to set DataSet.SelectSQL
  22.   DataSet.SelectSQL.Text := SomeStatement;
  23.   //and before opennig, DataSet will internally prepare its own IStatement object again, right?
  24.   DataSet.Open;
  25. end;
  26.  

See, with this approach, for same sql, the statement is prepared twice. How to avoid this?
That is why I took approach I described in my previous post -- use Dataset in the first place and use its own internal Statement for all work.
Can this be done differently?

tonyw

  • Sr. Member
  • ****
  • Posts: 319
    • MWA Software
Re: IBX 2.3.4 is now available for download
« Reply #12 on: April 24, 2020, 02:30:35 pm »
The way it works at present is that in order to do what you want, you have to prepare and test an SQL Statement to determine its SQLStatementType and, if it is a select statement, only then can you use it a TIBDataSet. To use it with a TIBDataSet, you then have to separately assign the SQL to the SelectSQL property and prepare the dataset query. Currently, there is no way to assign an IStatement interface to a dataset.

You can argue that this is a bug - maybe it is - but at present when you call TIBDataSet.Prepare, it will always try to initialise the fielddefs and hence the problem with setting up the metadata. There is no check at this point to make sure that the SelectSQL is an SQL statement that has metadata. The underlying point is that the assumption is that the SQL Statement will have metadata. So it works with a select query or for that matter an EXEC PROCEDURE, UPDATE, INSERT or DELETE. But it does not work with a SAVEPOINT.

Zoran

  • Hero Member
  • *****
  • Posts: 1829
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: IBX 2.3.4 is now available for download
« Reply #13 on: April 24, 2020, 02:42:37 pm »
The way it works at present is that in order to do what you want, you have to prepare and test an SQL Statement to determine its SQLStatementType and, if it is a select statement, only then can you use it a TIBDataSet. To use it with a TIBDataSet, you then have to separately assign the SQL to the SelectSQL property and prepare the dataset query. Currently, there is no way to assign an IStatement interface to a dataset.

You can argue that this is a bug - maybe it is - but at present when you call TIBDataSet.Prepare, it will always try to initialise the fielddefs and hence the problem with setting up the metadata. There is no check at this point to make sure that the SelectSQL is an SQL statement that has metadata. The underlying point is that the assumption is that the SQL Statement will have metadata. So it works with a select query or for that matter an EXEC PROCEDURE, UPDATE, INSERT or DELETE. But it does not work with a SAVEPOINT.

Thanks a lot.
Sorry for bothering you with this. I only suspected that I didn't see something, that this can be done smarter. Now it is clear that it cannot.

tonyw

  • Sr. Member
  • ****
  • Posts: 319
    • MWA Software
Re: IBX 2.3.4 is now available for download
« Reply #14 on: April 24, 2020, 03:34:39 pm »
Having thought about your problem - there is a workaround you may be interested in:

try
  DataSet.Prepare
except
   //ignore
end;
case DataSet.StatementType of //etc

This should work if I am correct in assuming that its the InitFieldDefs that's causing the problem. The exception will occur after the statement has been prepared and hence DataSet.StatementType should be valid.

If you knew the engine code that was causing the exception, then you could refine the exception handler as

try
 DataSet.Prepare;
except
  on E: EIBInterBaseError do
    if E.IBErrorCode <> {engine code} then
     raise;
  on E: Exception do
   raise;
end;

Note: the unit IBErrorCodes contains the symbolic constants for the error codes. A candidate error code is:
isc_metadata_corrupt = 335544346

 

TinyPortal © 2005-2018