Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-05

Boring problem when I try to create a database using SQLdb (again)

5 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

silvioprog

Hello,

I need to create numbered databases like 09_0025, 09_0026 etc., that using any SQL tool like pgAdmin, I just execute this script, and it works fine:

CREATE DATABASE "09_0025" WITH ENCODING='UTF-8'
OWNER="postgres" TEMPLATE="template1" LC_COLLATE='English_United States.1252' LC_CTYPE='English_United States.1252' CONNECTION LIMIT=-1 TABLESPACE="pg_default"

Notice that I need to specify some details, like ENCODING, OWNER, LC_COLLATE/LC_CTYPE etc., so the TPQConnection.CreateDB can't be used because it doesn't allows to configure those details.

Another information before show my tests: this script above works fine in other libs like Zeos, UniDAC and JDBC, I tested it yesterday.

Now, please see my tests and their respective errors.

Test 1:

[code]
var
  VCon: TPQConnection;
begin
  VCon := TPQConnection.Create(nil);
  try
    VCon.HostName := '127.0.0.1';
    VCon.DatabaseName := 'postgres';
    VCon.UserName := 'postgres';
    VCon.Password := 'postgres';
    VCon.ExecuteDirect(
      'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' +
      '  OWNER="postgres" TEMPLATE="template1" LC_COLLATE=''English_United
States.1252'' LC_CTYPE=''English_United States.1252'' ' +
      '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');
  finally
    VCon.Free;
  end;
end;
[/code]

Error:

Transaction not set.

Test 2:

[code]
var
  VCon: TPQConnection;
begin
  VCon := TPQConnection.Create(nil);
  VCon.Transaction := TSQLTransaction.Create(VCon);
  try
    VCon.HostName := '127.0.0.1';
    VCon.DatabaseName := 'postgres';
    VCon.UserName := 'postgres';
    VCon.Password := 'postgres';
    VCon.ExecuteDirect(
      'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' +
      '  OWNER="postgres" TEMPLATE="template1" LC_COLLATE=''English_United
States.1252'' LC_CTYPE=''English_United States.1252'' ' +
      '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');
  finally
    VCon.Free;
  end;
end;
[/code]

Error:

TPQConnection : Execution of query failed (PostgreSQL: ERROR: CREATE DATABASE cannot run inside a transaction block
Severity: ERROR
SQL State: 25001
Primary Error: CREATE DATABASE cannot run inside a transaction block).

And the code that works fine in Zeos:

[code]
var
  VCon: TZConnection;
begin
  VCon := TZConnection.Create(nil);
  try
    VCon.Protocol := 'postgresql-9';
    VCon.HostName := '127.0.0.1';
    VCon.Database := 'postgres';
    VCon.User := 'postgres';
    VCon.Password := 'postgres';
    VCon.Connect;
    VCon.ExecuteDirect(
      'CREATE DATABASE "mydatabase" WITH ENCODING=''UTF8'' ' +
      '  OWNER="postgres" TEMPLATE="template1" LC_COLLATE=''English_United
States.1252'' LC_CTYPE=''English_United States.1252'' ' +
      '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');
  finally
    VCon.Free;
  end;
end;
[code/]

Taking a look at the internal TPQConnection code, I found the method "ExecuteDirectPG", and propositally I moved it to public area and tested again using it:

[code]
var
  VCon: TPQConnection;
begin
  VCon := TPQConnection.Create(nil);
  try
    VCon.HostName := '127.0.0.1';
    VCon.DatabaseName := 'postgres';
    VCon.UserName := 'postgres';
    VCon.Password := 'postgres';
    VCon.ExecuteDirectPG(
      'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' +
      '  OWNER="postgres" TEMPLATE="template1" LC_COLLATE=''English_United
States.1252'' LC_CTYPE=''English_United States.1252'' ' +
      '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');
  finally
    VCon.Free;
  end;
end;
[/code]

Finally, it worked fine. So I have two questions:

Using SQLdb, how to execute scripts directly in the driver outside a transaction?

Why methods like "ExecuteDirectPG", "CheckConnectionStatus", "CheckResultError", "TranslateFldType" and "GetExtendedFieldInfo" are not declared as protected methods?

Thank you!

PS. please apply this patch to fix a typo in dbconsts unit: http://bugs.freepascal.org/view.php?id=28107

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Michael Van Canneyt
to silvioprog
silvioprog wrote 69 lines
Hello, I need to create numbered databases like 09_0025, 09_0026 etc., that using any SQL tool like pgAdmin, I just execute this script, and it works fine: CREATE DATABASE "09_0025" WITH ENCODING='UTF-8'   OWNER="postgres" TEMPLATE="template1" LC_COLLATE='English_United States.1252' LC_CTYPE='English_United States.1252'   CONNECTION LIMIT=-1 TABLESPACE="pg_default"  Notice that I need to specify some details, like ENCODING, OWNER, LC_COLLATE/LC_CTYPE etc., so the TPQConnection.CreateDB can't be used because it doesn't allows to configure those details. Another information before show my tests: this script above works fine in other libs like Zeos, UniDAC and JDBC, I tested it yesterday. Now, please see my tests and their respective errors. Test 1: [code] var   VCon: TPQConnection; begin   VCon := TPQConnection.Create(nil);   try     VCon.HostName := '127.0.0.1';     VCon.DatabaseName := 'postgres';     VCon.UserName := 'postgres';     VCon.Password := 'postgres';     VCon.ExecuteDirect(       'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' +       '  OWNER="postgres" TEMPLATE="template1" LC_COLLATE=''English_United States.1252'' LC_CTYPE=''English_United States.1252'' ' +       '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');   finally     VCon.Free;   end; end; [/code] Error: Transaction not set. Test 2: [code] var   VCon: TPQConnection; begin   VCon := TPQConnection.Create(nil);   VCon.Transaction := TSQLTransaction.Create(VCon);   try     VCon.HostName := '127.0.0.1';     VCon.DatabaseName := 'postgres';     VCon.UserName := 'postgres';     VCon.Password := 'postgres';     VCon.ExecuteDirect(       'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' +       '  OWNER="postgres" TEMPLATE="template1" LC_COLLATE=''English_United States.1252'' LC_CTYPE=''English_United States.1252'' ' +       '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');   finally     VCon.Free;   end; end; [/code] Error: TPQConnection : Execution of query failed  (PostgreSQL: ERROR:  CREATE DATABASE cannot run inside a transaction block Severity: ERROR SQL State: 25001 Primary Error: CREATE DATABASE cannot run inside a transaction block).

Set the stoUseImplicit option on the transaction:

VCon.Transaction.options:=[stoUseImplicit]
Why methods like "ExecuteDirectPG", "CheckConnectionStatus", "CheckResultError", "TranslateFldType" and "GetExtendedFieldInfo" are not declared as protected methods?

No particular reason. That can be changed.

Michael.

Reply by email

silvioprog
to Michael Van Canneyt

On Sat, May 16, 2015 at 1:51 PM, Michael Van Canneyt <

Show quoted text 9 lines
wrote: On Sat, 16 May 2015, silvioprog wrote: > [...] > Set the stoUseImplicit option on the transaction: VCon.Transaction.options:=[stoUseImplicit]

Thanks for the fast reply buddy.

I have another problem: my FPC version is 2.6.4, and this option is not available in this version. =/

But just to test, I did it using FPC from trunk, and the following code returned another error:

[code]
var
  VCon: TPQConnection;
begin
  VCon := TPQConnection.Create(nil);
  VCon.Transaction := TSQLTransaction.Create(VCon);
  try
    VCon.Transaction.Options := VCon.Transaction.Options + [stoUseImplicit];
    VCon.HostName := '127.0.0.1';
    VCon.DatabaseName := 'postgres';
    VCon.UserName := 'postgres';
    VCon.Password := 'postgres';
    VCon.ExecuteDirect(
      'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' +
      '  OWNER="postgres" TEMPLATE="template1" ' +
      '  LC_COLLATE=''English_United States.1252'' ' +
      '  LC_CTYPE=''English_United States.1252'' '+
      '  CONNECTION LIMIT=-1 TABLESPACE="pg_default"');
  finally
    VCon.Free;
  end;
end;
[/code]

Error:

#0 PQCONNECTION$_$TPQTRANS_$__$$_REGISTERCURSOR$TPQCURSOR at :0 #1
PQCONNECTION$_$TPQCONNECTION_$__$$_EXECUTE$TSQLCURSOR$TSQLTRANSACTION$TPARAMS at :0
#2 SQLDB$_$TSQLCONNECTION_$__$$_EXECUTEDIRECT$ANSISTRING$TSQLTRANSACTION at :0
#3 SQLDB$_$TSQLCONNECTION_$__$$_EXECUTEDIRECT$ANSISTRING at :0 #4 TFORM1__BUTTON1CLICK(0x1dc248, <error reading variable>) at Unit1.pas:45 ...

Show quoted text 8 lines
Why methods like "ExecuteDirectPG", "CheckConnectionStatus", > "CheckResultError", "TranslateFldType" and "GetExtendedFieldInfo" are not > declared as protected methods? > No particular reason. That can be changed. Michael.

Very nice. I can create a patch to move this methods to the protected area. =)

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

silvioprog
to silvioprog
silvioprog wrote 71 lines
On Sat, May 16, 2015 at 1:51 PM, Michael Van Canneyt < > wrote: > > On Sat, 16 May 2015, silvioprog wrote: > >> [...] >> > Set the stoUseImplicit option on the transaction: > > VCon.Transaction.options:=[stoUseImplicit] Thanks for the fast reply buddy. I have another problem: my FPC version is 2.6.4, and this option is not available in this version. =/ But just to test, I did it using FPC from trunk, and the following code returned another error: [code] var VCon: TPQConnection; begin VCon := TPQConnection.Create(nil); VCon.Transaction := TSQLTransaction.Create(VCon); try VCon.Transaction.Options := VCon.Transaction.Options + [stoUseImplicit]; VCon.HostName := '127.0.0.1'; VCon.DatabaseName := 'postgres'; VCon.UserName := 'postgres'; VCon.Password := 'postgres'; VCon.ExecuteDirect( 'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' + ' OWNER="postgres" TEMPLATE="template1" ' + ' LC_COLLATE=''English_United States.1252'' ' + ' LC_CTYPE=''English_United States.1252'' '+ ' CONNECTION LIMIT=-1 TABLESPACE="pg_default"'); finally VCon.Free; end; end; [/code] Error: #0 PQCONNECTION$_$TPQTRANS_$__$$_REGISTERCURSOR$TPQCURSOR at :0 #1 PQCONNECTION$_$TPQCONNECTION_$__$$_EXECUTE$TSQLCURSOR$TSQLTRANSACTION$TPARAMS at :0 #2 SQLDB$_$TSQLCONNECTION_$__$$_EXECUTEDIRECT$ANSISTRING$TSQLTRANSACTION at :0 #3 SQLDB$_$TSQLCONNECTION_$__$$_EXECUTEDIRECT$ANSISTRING at :0 #4 TFORM1__BUTTON1CLICK(0x1dc248, <error reading variable>) at Unit1.pas:45 ... > Why methods like "ExecuteDirectPG", "CheckConnectionStatus", >> "CheckResultError", "TranslateFldType" and "GetExtendedFieldInfo" are not >> declared as protected methods? >> > > No particular reason. That can be changed. > > Michael. Very nice. I can create a patch to move this methods to the protected area. =)

Done:

http://bugs.freepascal.org/view.php?id=28125

Silvio Clécio My public projects - github.com/silvioprog

Reply by email

Ladislav Karrach
to silvioprog: On Sat, May 16, 2015 at 1:51 PM, Michael Van Canneyt < Thanks for the fast reply buddy. I…

Dňa 16.5.2015 o 19:19 silvioprog napísal(a):

Show quoted text 58 lines
On Sat, May 16, 2015 at 1:51 PM, Michael Van Canneyt < > wrote: On Sat, 16 May 2015, silvioprog wrote: [...] Set the stoUseImplicit option on the transaction: VCon.Transaction.options:=[stoUseImplicit] Thanks for the fast reply buddy. I have another problem: my FPC version is 2.6.4, and this option is not available in this version. =/ But just to test, I did it using FPC from trunk, and the following code returned another error: [code] var VCon: TPQConnection; begin VCon := TPQConnection.Create(nil); VCon.Transaction := TSQLTransaction.Create(VCon); try VCon.Transaction.Options := VCon.Transaction.Options + [stoUseImplicit]; VCon.HostName := '127.0.0.1'; VCon.DatabaseName := 'postgres'; VCon.UserName := 'postgres'; VCon.Password := 'postgres'; VCon.ExecuteDirect( 'CREATE DATABASE "09_0025" WITH ENCODING=''UTF8'' ' + ' OWNER="postgres" TEMPLATE="template1" ' + ' LC_COLLATE=''English_United States.1252'' ' + ' LC_CTYPE=''English_United States.1252'' '+ ' CONNECTION LIMIT=-1 TABLESPACE="pg_default"'); finally VCon.Free; end; end; [/code] Error: #0 PQCONNECTION$_$TPQTRANS_$__$$_REGISTERCURSOR$TPQCURSOR at :0 #1 PQCONNECTION$_$TPQCONNECTION_$__$$_EXECUTE$TSQLCURSOR$TSQLTRANSACTION$TPARAMS at :0 #2 SQLDB$_$TSQLCONNECTION_$__$$_EXECUTEDIRECT$ANSISTRING$TSQLTRANSACTION at :0 #3 SQLDB$_$TSQLCONNECTION_$__$$_EXECUTEDIRECT$ANSISTRING at :0 #4 TFORM1__BUTTON1CLICK(0x1dc248, <error reading variable>) at Unit1.pas:45 ...

Probably fixed in rev.30920
ExecuteDirect did not called StartImpicitTransaction, which leaves Transaction.Handle nil, which later leads to AV, when PQConnection uses transaction handle to register cursor during statement preparation. -Laco.

Reply by email