소스 검색

pqconnection: use also EPQDatabaseError for Execute and UnPrepareStatement to deliver complete error info

git-svn-id: trunk@22610 -
ludob 12 년 전
부모
커밋
707e19b81d
1개의 변경된 파일56개의 추가작업 그리고 42개의 파일을 삭제
  1. 56 42
      packages/fcl-db/src/sqldb/postgres/pqconnection.pp

+ 56 - 42
packages/fcl-db/src/sqldb/postgres/pqconnection.pp

@@ -31,6 +31,16 @@ type
     FieldBinding : array of integer;
   end;
 
+  EPQDatabaseError = class(EDatabaseError)
+    public
+      SEVERITY:string;
+      SQLSTATE: string;
+      MESSAGE_PRIMARY:string;
+      MESSAGE_DETAIL:string;
+      MESSAGE_HINT:string;
+      STATEMENT_POSITION:string;
+  end;
+
   { TPQConnection }
 
   TPQConnection = class (TSQLConnection)
@@ -40,6 +50,7 @@ type
     FSQLDatabaseHandle   : pointer;
     FIntegerDateTimes    : boolean;
     procedure CheckResultError(res: PPGresult; conn:PPGconn; ErrMsg: string);
+    function GetPQDatabaseError(res : PPGresult;ErrMsg: string):EPQDatabaseError;
     function TranslateFldType(res : PPGresult; Tuple : integer; out Size : integer) : TFieldType;
     procedure ExecuteDirectPG(const Query : String);
   protected
@@ -90,16 +101,6 @@ type
     Class Function UnLoadFunction : TLibraryUnLoadFunction; override;
   end;
 
-  EPQDatabaseError = class(EDatabaseError)
-    public
-      SEVERITY:string;
-      SQLSTATE: string;
-      MESSAGE_PRIMARY:string;
-      MESSAGE_DETAIL:string;
-      MESSAGE_HINT:string;
-      STATEMENT_POSITION:string;
-  end;
-
 implementation
 
 uses math, strutils, FmtBCD;
@@ -348,47 +349,56 @@ end;
 procedure TPQConnection.CheckResultError(res: PPGresult; conn: PPGconn;
   ErrMsg: string);
 var
-  serr:string;
   E: EPQDatabaseError;
-  CompName: string;
-  SEVERITY:string;
-  SQLSTATE: string;
-  MESSAGE_PRIMARY:string;
-  MESSAGE_DETAIL:string;
-  MESSAGE_HINT:string;
-  STATEMENT_POSITION:string;
 
 begin
   if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
     begin
-    SEVERITY:=PQresultErrorField(res,ord('S'));
-    SQLSTATE:=PQresultErrorField(res,ord('C'));
-    MESSAGE_PRIMARY:=PQresultErrorField(res,ord('M'));
-    MESSAGE_DETAIL:=PQresultErrorField(res,ord('D'));
-    MESSAGE_HINT:=PQresultErrorField(res,ord('H'));
-    STATEMENT_POSITION:=PQresultErrorField(res,ord('P'));
-    serr:=PQresultErrorMessage(res)+LineEnding+
-      'Severity: '+ SEVERITY +LineEnding+
-      'SQL State: '+ SQLSTATE +LineEnding+
-      'Primary Error: '+ MESSAGE_PRIMARY +LineEnding+
-      'Error Detail: '+ MESSAGE_DETAIL +LineEnding+
-      'Hint: '+ MESSAGE_HINT +LineEnding+
-      'Character: '+ STATEMENT_POSITION +LineEnding;
+    E:=GetPQDatabaseError(res,ErrMsg);
     pqclear(res);
     if assigned(conn) then
       PQFinish(conn);
-    if Self.Name = '' then CompName := Self.ClassName else CompName := Self.Name;
-    E:=EPQDatabaseError.CreateFmt('%s : %s  (PostgreSQL: %s)', [CompName,ErrMsg, serr]);
-    E.SEVERITY:=SEVERITY;
-    E.SQLSTATE:=SQLSTATE;
-    E.MESSAGE_PRIMARY:=MESSAGE_PRIMARY;
-    E.MESSAGE_DETAIL:=MESSAGE_DETAIL;
-    E.MESSAGE_HINT:=MESSAGE_HINT;
-    E.STATEMENT_POSITION:=STATEMENT_POSITION;
     raise E;
     end;
 end;
 
+function TPQConnection.GetPQDatabaseError(res: PPGresult; ErrMsg: string
+  ): EPQDatabaseError;
+var
+  serr:string;
+  E: EPQDatabaseError;
+  CompName: string;
+  SEVERITY:string;
+  SQLSTATE: string;
+  MESSAGE_PRIMARY:string;
+  MESSAGE_DETAIL:string;
+  MESSAGE_HINT:string;
+  STATEMENT_POSITION:string;
+begin
+  SEVERITY:=PQresultErrorField(res,ord('S'));
+  SQLSTATE:=PQresultErrorField(res,ord('C'));
+  MESSAGE_PRIMARY:=PQresultErrorField(res,ord('M'));
+  MESSAGE_DETAIL:=PQresultErrorField(res,ord('D'));
+  MESSAGE_HINT:=PQresultErrorField(res,ord('H'));
+  STATEMENT_POSITION:=PQresultErrorField(res,ord('P'));
+  serr:=PQresultErrorMessage(res)+LineEnding+
+    'Severity: '+ SEVERITY +LineEnding+
+    'SQL State: '+ SQLSTATE +LineEnding+
+    'Primary Error: '+ MESSAGE_PRIMARY +LineEnding+
+    'Error Detail: '+ MESSAGE_DETAIL +LineEnding+
+    'Hint: '+ MESSAGE_HINT +LineEnding+
+    'Character: '+ STATEMENT_POSITION +LineEnding;
+  if Self.Name = '' then CompName := Self.ClassName else CompName := Self.Name;
+  E:=EPQDatabaseError.CreateFmt('%s : %s  (PostgreSQL: %s)', [CompName,ErrMsg, serr]);
+  E.SEVERITY:=SEVERITY;
+  E.SQLSTATE:=SQLSTATE;
+  E.MESSAGE_PRIMARY:=MESSAGE_PRIMARY;
+  E.MESSAGE_DETAIL:=MESSAGE_DETAIL;
+  E.MESSAGE_HINT:=MESSAGE_HINT;
+  E.STATEMENT_POSITION:=STATEMENT_POSITION;
+  result:=E;
+end;
+
 function TPQConnection.TranslateFldType(res : PPGresult; Tuple : integer; out Size : integer) : TFieldType;
 const VARHDRSZ=sizeof(longint);
 var li : longint;
@@ -579,6 +589,8 @@ begin
 end;
 
 procedure TPQConnection.UnPrepareStatement(cursor : TSQLCursor);
+var
+  E: EPQDatabaseError;
 
 begin
   with (cursor as TPQCursor) do if FPrepared then
@@ -589,8 +601,9 @@ begin
       res := pqexec(tr.PGConn,pchar('deallocate '+StmtName));
       if (PQresultStatus(res) <> PGRES_COMMAND_OK) then
         begin
+          E:=GetPQDatabaseError(res,SErrPrepareFailed);
           pqclear(res);
-          DatabaseError(SErrPrepareFailed + ' (PostgreSQL: ' + PQerrorMessage(tr.PGConn) + ')',self)
+          raise E;
         end
       else
         pqclear(res);
@@ -608,6 +621,7 @@ var ar  : array of pchar;
     ParamNames,
     ParamValues : array of string;
     cash: int64;
+    E: EPQDatabaseError;
 
 begin
   with cursor as TPQCursor do
@@ -686,14 +700,14 @@ begin
       end;
     if assigned(res) and not (PQresultStatus(res) in [PGRES_COMMAND_OK,PGRES_TUPLES_OK]) then
       begin
-      s := PQerrorMessage(tr.PGConn);
+      E:=GetPQDatabaseError(res,SErrExecuteFailed);
       pqclear(res);
 
       tr.ErrorOccured := True;
 // Don't perform the rollback, only make it possible to do a rollback.
 // The other databases also don't do this.
 //      atransaction.Rollback;
-      DatabaseError(SErrExecuteFailed + ' (PostgreSQL: ' + s + ')',self);
+      raise E;
       end;
     end;
 end;