Subject ANN: New: IBExpert Developer Studio 2006.03.15
Author HKlemt
New: IBExpert Developer Studio 2006.03.15

Today we uploaded a new Version of IBExpert Developer
Studio on

If you are registered customer and cannot
access the customer area, please check the
update end date from your registration form.

If you update right is already expired,
you can extend it for the next two years
with buying the same license(s) again in
our shop. See details on our Web Site

What is IBExpert Developer Studio?

IBExpert Developer Studio is a combination of IBExpert and other
Modules for professional Database Development. All customers of
IBExpert have access to all modules, such as

-IBExpert Integerated Development Environment
-IBEScript.exe Commandlineversion for Executing Scripts
-IBEScript.dll Script API for using IBExpert Script in your own
-IBExpertSQLMonitor: A Proxy Server to monitor all SQL Statements send
from any clientsoftware
-IBExpertLive: Watch the Videos from Firebird Conferences and other Events
-IBExpertBackupRestore: Automate your daily Backup Restore Jobs
-IBExpertTransactionMonitor: Avoid the Oldest Active Transaction
Problem automatically
-IBExpertDemoDB: A collection of useful Demodatabases

In Non Customer Versions you will only have access to IBExpert IDE and
IBExpertLive. The other Modules will only work on licensed computers.

New: The name of the installer file has changed, now there is only one
called ibexpert_xxx.exe, where xxx is replaced by customer, educational,
trial or personal.

IBExpert 2006.03.15

1. Since this version IBExpert uses an alternative memory manager -
FastMM (

2. SP/Trigger Analyzer:

* Added possibility to analyze compatibility of types
of return values and variables for SELECT...INTO and
FOR SELECT...INTO statements.

* Added possibility to select actions (SELECT/UPDATE/DELETE/INSERT)
to be analyzed.

* Added possibility to filter results of analysis.

* Performance of analysis was improved.

3. DB Explorer:

* Now when you drag-n-drop objects from DB Explorer into Code
Editors IBExpert takes into account the charcase of keywords
and identifiers specified in Options | Editor Options | Code Insight.

4. Database Comparer:

* Fixed problem with missing AS within trigger bodies when
comparing scripts.

5. Database Object Editors:

* Added Comparison tab which allows to compare an object
with the one in another (comparative) database.
You can specify a comparative database in DB Registration Info |
Comparative Database.

6. IBEBlock. Added following functions to handle work with ini-files:

* function ibec_ini_Open(FileName : string) : variant;

ibec_ini_Open instantiates an ini-file object. FileName is the
name of the INI file
which will be used. ibec_ini_Open loads a copy of the INI file
into memory if
the specified file exists.
ibec_ini_Open returns the handle of ini-file object if succeeded,
it returns NULL.

* function ibec_ini_Close(IniFile : variant) : variant;

ibec_ini_Close frees the memory associated with the ini-file object.
No updates of associated file on disk is made, you must use
ibec_ini_UpdateFile to flush buffered INI file data to disk.

* function ibec_ini_Clear(IniFile : variant) : variant;

Erases all data from the INI file in memory.
Call ibec_ini_Clear to erase all data from the INI file that is
buffered in memory. All sections, keys, and values are erased. No
is generated when using Clear and the data has not been saved to
the INI file
with the ibec_ini_UpdateFile function.

* function ibec_ini_UpdateFile(IniFile : variant) : variant;

ibec_ini_UpdateFile flushes buffered INI file data to disk.
Call ibec_ini_UpdateFile to copy INI file data stored in memory
to the copy of
the INI file on disk. ibec_ini_UpdateFile overwrites all data in
the disk copy
of the INI file with the INI file data stored in memory.
If the file does not already exist, it is created. If the new
file already
exists, it is overwritten.

* function ibec_ini_EraseSection(IniFile : variant; Section :
string) : variant;

Erases an entire section of an INI file. Call
ibec_ini_EraseSection to remove
a section, all its keys, and their data values from an INI file.
Section identifies the INI file section to remove. If a section
cannot be removed,
an exception is raised.
ibec_ini_EraseSection only affects the in-memory copy of the INI
not the copy on disk.

* function ibec_ini_ReadString(IniFile : variant; Section, Ident,
Default : string) : string;

Retrieves a string value from an INI file.
Call ibec_ini_ReadString to read a string value from an INI file.
Section identifies the section in the file that contains the
desired key.
Ident is the name of the key from which to retrieve the value.
Default is the string value to return if the Section does not
exist or key doesn't
exist or data value for the key is not assigned.

* function ibec_ini_WriteString(IniFile : variant; Section, Ident,
Value : string) : variant;

Writes a string value to an INI file.
Call ibec_ini_WriteString to write a string value to an INI file.
Section identifies the section in the file that contain the key
to which to write.
Ident is the name of the key for which to set a value.
Value is the string value to write.
Attempting to write a data value to a non-existent section or
attempting to write
data to a non-existent key are not errors. In these cases,
creates the section and key and sets its initial value to Value.

All ibec_ini_xxx functions, except ibec_ini_ReadString and
return NULL.

7. IBEBlock. Added following functions to handle work with Windows

* function ibec_reg_Open(RootKey : HKEY; Access : LongWord) :

ibec_reg_Opent instantiates a registry object.
RootKey determines the hierarchy of subkeys an application can
possible values are __HKEY_CLASSES_ROOT, __HKEY_CURRENT_USER,
Access determines the level of security access to use when
opening keys,
currently is ignored, that is KEY_ALL_ACCESS is used.

* function ibec_reg_Close(Registry : variant) : variant;

ibec_reg_Close closes the current key and frees the resources
for a registry object when it is no longer needed.

* function ibec_reg_OpenKey(Registry : variant; Key: String;
CanCreate: Boolean) : boolean;

Call ibec_reg_OpenKey to make a specified key the current key.
Key is the name of the
key to open. CanCreate specifies whether to create the
specified key if it does not exist.
If CanCreate is True, the key is created if necessary.
ibec_reg_OpenKey returns True if the key is successfully opened
or created.

* function ibec_reg_CloseKey(Registry : variant) : variant;

Call ibec_reg_CloseKey to write the current key to the registry
and close the key.

* function ibec_reg_DeleteKey(Registry : variant; Key: String) :

Removes a specified key and its associated data from the registry.
Call ibec_reg_DeleteKey to remove a specified key and its
associated data,
if any, from the registry. ibec_reg_DeleteKey returns True if
key deletion is
successful. On error, ibec_reg_DeleteKey returns False.

* function ibec_reg_CreateKey(Registry : variant; Key: String) :

Creates a new key in the registry.
Use ibec_reg_CreateKey to add a new key to the registry. Key is
the name of the key to create.
Key can be an absolute or relative name. An absolute key begins
with a backslash (\) and
is a subkey of the root key. A relative key is a subkey of the
current key.
ibec_reg_CreateKey returns True if key creation is successful.
On error, an exception is raised.
Attempting to create a key that already exists has no effect.

Following functions are intended for reading and writing data
from/to the
Windows Registry:

* function ibec_reg_WriteString(Registry : variant; Name, Value:
string) : variant;
* function ibec_reg_ReadString(Registry : variant; Key: String) :
* function ibec_reg_WriteBool(Registry : variant; Name: String;
Value: boolean) : variant;
* function ibec_reg_ReadBool(Registry : variant; Key: String) :
* function ibec_reg_WriteDate(Registry : variant; Name: String;
Value: date) : variant;
* function ibec_reg_ReadDate(Registry : variant; Key: String) : date;
* function ibec_reg_WriteDateTime(Registry : variant; Name:
String; Value: timestamp) : variant;
* function ibec_reg_ReadDateTime(Registry : variant; Key: String)
: timestamp;
* function ibec_reg_WriteTime(Registry : variant; Name: String;
Value: time) : variant;
* function ibec_reg_ReadTime(Registry : variant; Key: String) : time;
* function ibec_reg_WriteInteger(Registry : variant; Name:
String; Value: integer) : variant;
* function ibec_reg_ReadInteger(Registry : variant; Key: String)
: integer;
* function ibec_reg_WriteFloat(Registry : variant; Name: String;
Value: double precision) : variant;
* function ibec_reg_ReadFloat(Registry : variant; Key: String) :
double precision;

The following example demonstrates usage of ibec_reg_xxx
functions to perform
a daily backup of the IBExpert User Database:

execute ibeblock
CurrentDate = ibec_Date();

reg = ibec_reg_Open(__HKEY_CURRENT_USER, 0);
if (ibec_reg_OpenKey(reg, 'Software\HK
Software\IBExpert\CurrentData', FALSE)) then
UDBLastBackupDate = ibec_reg_ReadDate(reg,
if (UDBLastBackupDate = CurrentDate) then
UDBConnectString = ibec_reg_ReadString(reg,
UDBClientLib = ibec_reg_ReadString(reg, 'UDBClientLib');
UDBUserName = ibec_reg_ReadString(reg, 'UDBUserName');
UDBPassword = ibec_reg_ReadString(reg, 'UDBPassword');

if ((UDBConnectString is null) or (UDBConnectString = '')) then

ibec_Progress('Starting backup of IBExpert User Database...');
BackupDir = 'D:\Backups\IBExpert User Database\';

ibec_DecodeDate(CurrentDate, iYear, iMonth, iDay);
BackupFileName = BackupDir || iDay || '-' || iMonth || '-' ||
iYear || '.fbk';

res = ibec_BackupDatabase(UDBConnectString, BackupFileName,
'ClientLib=' || UDBClientLib || ';
Password=' ||
UDBPassword || '; User=' ||

if (ibec_FileExists(BackupFileName)) then
ibec_Progress('Compressing ' || BackupFileName || '...');
res = ibec_Exec('"C:\Program Files\WinRAR\rar.exe" a "' ||
BackupFileName || '.rar" "' ||
BackupFileName || '" -m5 -ri1', '', null);
if (res = 0) then

if (res = 0) then
reg = ibec_reg_Open(__HKEY_CURRENT_USER, 0);
if (ibec_reg_OpenKey(reg, 'Software\HK
Software\IBExpert\CurrentData', FALSE)) then
ibec_reg_WriteDate(reg, 'UDBLastBackupDate', CurrentDate);

8. IBEBlock. Added following functions to manage IB/FB users:

* function ibec_CreateUser(ConnectOptions, UserData : string) :
* function ibec_AlterUser(ConnectOptions, UserData : string) : variant;
* function ibec_RecreateUser(ConnectOptions, UserData : string) :
* function ibec_DropUser(ConnectOptions, UserName : string) : variant;

These functions use the IB/FB Services Manager therefore they
will not
work with servers that do not support the Services Manager API.

All functions return NULL if there were no errors, otherwise they
return an error message text.

ConnectOptions - list of parameters to connect to the Services
delimited with semicolon. Possible options:
Server=<server_name> - the name of the server. Also you can use
ServerName=<server_name> to specify the server name.
Protocol=<protocol> - the network protocol with which to connect
to the server. Possible values are 'Local', 'TCP', 'SPX'
and 'NamedPipe'.
User=<user_name> - the user name.
Password=<password> - the password.
ClientLib=<client_lib_name> - the name of client library dll, by
default GDS32.DLL.


ibec_DropUser('Server=localhost; User=SYSDBA; Password=masterkey;
Protocol=TCP; ClientLib=gds32.dll',

If the server name is not specified the connection will be
with the local server using Local protocol.
If the protocol not specified TCP/IP will be used in case of the
server name is specified.

UserData - list of user properties, delimited with semicolon.
Possible properties are:
UserName=<user_name> - user name to create or modify;
maximum 31 characters
Password=<password> - password for the user; maximum 31
only first 8 characters are significant
FirstName=<first_name> - optional first name of person using
this user name
MiddleName=<middle_name> - optional middle name of person
using this user name
LastName=<last_name> - optional last name of person using
this user name
UserID=<user_id> - optional user ID number, defined in
to assign to the user; reserved for future
GroupID=<group_id> - optional groupID number, defined in
to assign to the user; reserved for future


ibec_CreateUser('Server=localhost; User=SYSDBA;
'UserName=BILL_GATES; Password=microsoft;

ibec_RecreateUser function first tests whether specified user
or not. In case of specified user exists it deletes his login
and recreates it again using specified properties. Otherwise
it just
creates a new login record.

9. IBEBlock. Support for TRY...EXCEPT and TRY...FINALLY statements added:

* The syntax of a TRY...FINALLY statement is


where each statementList is a sequence of statements delimited by
The TRY...FINALLY statement executes the statements in
(the TRY clause). If statementList1 finishes without raising
statementList2 (the FINALLY clause) is executed. If an exception
is raised
during execution of statementList1, control is transferred to
once statementList2 finishes executing, the exception is re-raised.
If a call to the Exit procedure causes control to leave
statementList2 is automatically executed. Thus the FINALLY clause
is always
executed, regardless of how the TRY clause terminates.


execute ibeblock
i = 1;
i = i/0; <-- Here will be an exception raised...
i = 2; <-- ... but this statement will be executed anyway
i = 3; <-- This statement will not be executed

* The syntax of a TRY...EXCEPT statement is


where statements is a sequence of statements (delimited by
semicolons) and
exceptionBlock another sequence of statements.

A TRY...EXCEPT statement executes the statements in the initial
list. If no exceptions are raised, the exception block
(exceptionBlock) is
ignored and control passes to the next part of the IBEBlock.
If an exception is raised during execution of the initial
statements list,
control passes to the first statement in the exceptionBlock. Here you
can handle an exception occured using following functions:

function ibec_err_Message() - returns an exception message
function ibec_err_SQLCode() - returns an SQLCode of an exception
if there was an SQL error.
function ibec_err_Name() - returns an exception name (for exceptions
raised with EXCEPTION statement; see below)

Also you can re-raise an exception using RAISE statement.


execute ibeblock
-- Attempt to insert into non-existent table
insert into missing_table (f1) values (1);
ibec_ShowMessage('There were no errors...');
ErrSQLCode = ibec_err_SQLCode();
if (ErrSQLCode = -204) then

* EXCEPTION statement is similar to Firebird dynamic exceptions.
Its syntax is

EXCEPTION <exception_name> [<exception_text>]

<exception_name> is a name of an exception which may be tested
using ibec_err_Name function.


execute ibeblock (divisor double precision)
i = 1;
if ((divisor is null) or (divisor = 0)) then
exception INVALID_DIVISOR 'The divisor is invalid: NULL or 0';
i = i/divisor;
if (ibec_err_name() = 'INVALID_DIVISOR') then
i = 0;

10. IBEBlock. Following date/time functions added:

* function ibec_Date : Date;
ibec_Date returns the current date (without time part).

* function ibec_Now : TimeStamp;
ibec_Now returns the current timestamp.

* function ibec_Time : Time;
ibec_Time returns the current time.

* function ibec_DayOfWeek(Date : TimeStamp) : integer;
ibec_DayOfWeek returns the day of the week of the specified date as
an integer between 1 and 7, where Sunday is the first day of the
week and
Saturday is the seventh.

* function ibec_CopyFile(ExistingFileName, NewFileName : string;
FailIfExists : boolean) : boolean;
The ibec_CopyFile function copies an existing file to a new file.
If FailIfExists parameter is TRUE and the new file already exists,
the function fails. If this parameter is FALSE and the new file
already exists, the function overwrites the existing file and

11. IBEScript.exe\IBEScript.dll updated accordingly.

12. A lot of minor bugfixes and improvements...

13. Firebird Database Certification Training 2006

Die Themen unseres n�chsten Firebird Certification Trainings in Oldenburg:

1. Firebird: SQL Grundlagen `(1 Tag)
2. Firebird: Grundlagen f�r Entwickler (2 Tage)
3. Firebird: Grundlagen f�r Datenbankadministratoren (2 Tage)
4. Firebird: Leistungssteigerung und Optimierung (1 Tag)
5. Datenbankportierung von Paradox, dBase und MS Access auf Firebird
(1 Tag)
6. Delphi Datenbankanwendungen portieren von BDE auf Firebird (1 Tag)
7. Datenbankauswertungen mit Delphi, Firebird und Fastreport (1 Tag)
8. Dynamische Webanwendungen mit Firebird und PHP (1 Tag)

N�chste Termine:
15.-19.5.2006 + 29.5.-2.6.2006

Anmeldung und Details unter

14. Distribution of IBExpert Modules

* To be allowed to distribute any of the IBExpert Modules
(ibexpert.exe, ibescript.exe, ibescript.dll, ibeextract.exe
and ibecompare.exe) together with your application, you
-IBExpert Site License, if the distribution is located only on
computers in your own company
-IBExpert VAR License, if the distribution is located on
any computer outside your company

If you are already IBExpert customer, you can upgrade to
Site or VAR License and directly buy the 24 month
Extension Product.

See Purchase Area for Details

Some functions of the new IBExpert Modules do not work
on Non licensed Computers, so you can only use them,
where your IBExpert License is valid.

Customers with Site License are allowed to make them
work on every computer in their company just by
copying the License file to the path, where the
module (such as ibescript.exe) should run.

VAR License Customers may also integrate these modules
and the License file in their Software installation.

The IBExpert Team

The most Expert for InterBase and Firebird
HK Software - Gerhard Stalling Strasse 47a - 26135 Oldenburg - Germany
Phone/Fax +49 700 IBEXPERT (42397378) info@...
Training and Support for Delphi, InterBase, Firebird, AS/400