v7.5 + v8.0.1 Break Existing db Creation code

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
FredS
Posts: 272
Joined: Mon 10 Nov 2014 17:52

v7.5 + v8.0.1 Break Existing db Creation code

Post by FredS » Fri 26 Jul 2019 18:59

Code: Select all

CREATE DATABASE 'C:\ProgramData\mydb\PA.fdb'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 16384
default character set UTF8 collation UNICODE_CI_AI ;
Same code works when I compile with v7.4 but generates this with the others:

Code: Select all

---------------------------
Debugger Exception Notification
---------------------------
Project App.exe raised exception class EIBCError with message 'I/O error during "CreateFile (open)" operation for file "C:\PROGRAMDATA\MYDB\PA.FDB"
Error while trying to open file
The system cannot find the file specified. '.
---------------------------
Break   Continue   Help   
---------------------------

Stellar
Devart Team
Posts: 496
Joined: Tue 03 Oct 2017 11:00

Re: v7.5 + v8.0.1 Break Existing db Creation code

Post by Stellar » Fri 02 Aug 2019 09:30

Unfortunately, we couldn't reproduce the issue. We've succesfully create a database with your script and UniDAC 8.0.1. Please try to create a database using the following code:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
begin
  UniConnection1.Server := 'localhost';
  UniConnection1.Username := 'sysdba';
  UniConnection1.Password := 'masterkey';
  UniConnection1.LoginPrompt := False;

  UniScript1.Connection := UniConnection1;
  UniScript1.NoPreconnect := True;
  UniScript1.SQL.Text := ' CREATE DATABASE ''C:\ProgramData\mydb\PA.fdb'' ' +
                         ' USER ''SYSDBA'' ' +
                         ' PASSWORD ''masterkey'' ' +
                         ' PAGE_SIZE 16384 ' +
                         ' default character set UTF8 ' +
                         ' collation UNICODE_CI_AI;';
  UniScript1.Execute;
end;
Please inform us about the results.

FredS
Posts: 272
Joined: Mon 10 Nov 2014 17:52

Re: v7.5 + v8.0.1 Break Existing db Creation code

Post by FredS » Fri 02 Aug 2019 14:47

Demo:

Code: Select all

type
  [TestFixture]
  TFirebirdFixture = class(TObject)
  private
    FCon: TUniConnection;
    FUniScript: TUniScript;
    FDbFiles : TArray<string>;
    const CRLF = #13#10;
  public
    [SetupFixture]
    procedure SetupFixture;
    [TearDownFixture]
    procedure TearDownFixture;
    /// <summary>
    ///   Third time since 2014 that db creation failed, someone is NOT testing.
    /// </summary>
    [Test]
    [TestCase('Embedded (No Pooling)',   ',.\NoPooling.fdb,SYSDBA,masterkey,False')]
    [TestCase('Embedded (With Pooling)', ',.\WithPooling.fdb,SYSDBA,masterkey,True')]
    procedure TestDbCreation(const AServer, AFileName, AUser, APwd: string; const AWithPooling: Boolean);
  end;

implementation


procedure TFirebirdFixture.SetupFixture;
begin
  FCon := TUniConnection.Create(nil);
  FCon.ProviderName      := InterBaseUniProvider.TInterBaseUniProvider.GetProviderName;
  FCon.PoolingOptions.MinPoolSize := 4;
  FCon.PoolingOptions.MaxPoolSize := 100;
  FUniScript             := TUniScript.Create(FCon);
  FUniScript.Connection  := FCon;
  FUniScript.Transaction := FCon.DefaultTransaction;
end;

procedure TFirebirdFixture.TearDownFixture;
var LFileName : string;
begin
  FCon.Free;
  for LFileName in FDbFiles do DeleteFile(LFileName);
end;

procedure TFirebirdFixture.TestDbCreation(const AServer, AFileName, AUser, APwd: string; const AWithPooling: Boolean);
const script = 'CREATE DATABASE :Filename' + CRLF +
               'USER :User PASSWORD :Pwd' + CRLF +
               'PAGE_SIZE 16384' + CRLF +
               'default character set UTF8 collation UNICODE_CI_AI ;';
var LFileName : string;
begin
  if AServer.IsEmpty then begin
      LFileName := ExpandFileName(AFileName);
  end else LFileName := AFileName;
  // Will ignore non rooted files
  if FileExists(LFileName) then Assert.IsTrue(DeleteFile(LFileName), 'Unable to create the DB, it already exists and cannot be deleted.');

  FCon.Server   := AServer;
  FCon.Pooling  := AWithPooling;
  FUniScript.NoPreconnect := True; // executes DDL without connecting to an existing db
  FUniScript.SQL.Text := script;
  FUniScript.SQL.ReplaceParams([LFileName, AUser, APwd]); << You'll need to replace this
  Assert.WillNotRaiseAny(procedure begin FUniScript.Execute; end);
  FDbFiles := FDbFiles + [LFileName];
end;

initialization
  TDUnitX.RegisterTestFixture(TFirebirdFixture);
end.

Stellar
Devart Team
Posts: 496
Joined: Tue 03 Oct 2017 11:00

Re: v7.5 + v8.0.1 Break Existing db Creation code

Post by Stellar » Thu 08 Aug 2019 08:29

Thank you for the information. The issue is caused by connection pooling when creating a database. We'll consider adding the capability to create a database when connection pooling is used in future versions of UniDAC. At the moment, you can create a database without using pooling.

FredS
Posts: 272
Joined: Mon 10 Nov 2014 17:52

Re: v7.5 + v8.0.1 Break Existing db Creation code

Post by FredS » Thu 08 Aug 2019 15:46

We'll consider adding
Of course that breaks existing UNI code since at least two other Providers can, and for a long time have. created dbs with Pooling On..

FredS
Posts: 272
Joined: Mon 10 Nov 2014 17:52

Another Pooling issue

Post by FredS » Mon 12 Aug 2019 18:17

Gbak can't restore the DB after closing the connection if Pooling was on during the connection.

'Restart Manager' tells me the db is still locked by my app.

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: v7.5 + v8.0.1 Break Existing db Creation code

Post by ViktorV » Thu 15 Aug 2019 13:00

FredS wrote: Thu 08 Aug 2019 15:46
We'll consider adding
Of course that breaks existing UNI code since at least two other Providers can, and for a long time have. created dbs with Pooling On..
Thank you for the information. We have already fixed the issue.
This fix will be included into the next UniDAC.
We have answered you via e-mail.

Post Reply