Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 5 of 5 total
Thread List index out of bounds error. Am I use function correctly?
Tue, Jun 3 2008 9:42 AMPermanent Link

Tomas
Hello,

I think my problem is not caused by DBISAM itself but rather by me, I am not sure if I use function ExecSQL and DBISAM corretclly in multi-
threaded application.

While using function ExecSQL in Multi-threaded application sometimes I get "List index out of bounds" error at


function TDBISAMSession.FindDatabase(const DatabaseName: string): TDBISAMDatabase;
var
  I: Integer;
begin
  for I:=0 to FDatabases.Count-1 do
     begin
     Result:=FDatabases[I]; <-------------------------Error here "List index out of bounds (4)"
     if ContainsDirectory(DatabaseName) and (not MemoryDirectory(DatabaseName)) then
        begin
        if ((Result.DatabaseName <> '') or Result.Temporary) and
           (OSCompareFileNames(Result.DatabaseName,DatabaseName)=0) then
           Exit;
        end
     else

Could anyone help me with this? ExecSQL function is declarated in global unit and I use this function from Threads.

function ExecSQL(SQL: string): Integer;
var sSession: TDBISAMSession;
 dbDatabase: TDBISAMDatabase;
 qQuery: TDBISAMQuery;
 ADynamicSessionName: string;
begin
 sSession := TDBISAMSession.Create(nil);
 dbDatabase := TDBISAMDatabase.Create(nil);
 qQuery := TDBISAMQuery.Create(nil);
 try
   sSession.RemoteAddress := ADBServerIP;
   sSession.RemotePort := StrToInt(ADBServerPort);
   sSession.RemoteUser := ADBUser;
   sSession.RemotePassword := ADBPass;
   dbDatabase.RemoteDatabase := ADBDatabase;

   sSession.SessionType := stRemote;
   sSession.AutoSessionName := true;
   sSession.PrivateDir := Path_UserTemp;


   sSession.Active := true;

   ADynamicSessionName := sSession.SessionName;

   dbDatabase.DatabaseName := ADynamicSessionName;
   dbDatabase.SessionName := ADynamicSessionName;
   qQuery.DatabaseName := dbDatabase.DatabaseName;
   qQuery.SessionName := ADynamicSessionName;
   qQuery.RequestLive := true;
   qQuery.Close;
   qQuery.SQL.Text := SQL;
   qQuery.ExecSQL;
   result := qQuery.RowsAffected;
 finally
   dbDatabase.Close;
   sSession.Active := false;
   qQuery.Free;
   dbDatabase.Free;
   sSession.Free;
 end;
end;

p.s. Version 4.25 Build 6
Regards,
Tomas
Tue, Jun 3 2008 12:35 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Tomas,

<< Could anyone help me with this? ExecSQL function is declarated in global
unit and I use this function from  Threads.>>

You need to set the SessionName *before* the DatabaseName for the
TDBISAMDatabase and TDBISAMQuery components.  If you don't, then they will
try to use the same global default session for finding the database and
accessing it.

--
Tim Young
Elevate Software
www.elevatesoft.com

Thu, Jun 5 2008 2:18 AMPermanent Link

Tomas
Tim, I have done as you suggested and "List index out of bounds" exception decreased dramatically.
But I still got one after update and I have found that new exception "Access violation"
throw several times at


function TDBISAMSession.FindDatabase(const DatabaseName: string): TDBISAMDatabase;
var
  I: Integer;
begin
  for I:=0 to FDatabases.Count-1 do
     begin
     Result:=FDatabases[I];
     if ContainsDirectory(DatabaseName) and (not MemoryDirectory(DatabaseName)) then
        begin
        if ((Result.DatabaseName <> '') or Result.Temporary) and
           (OSCompareFileNames(Result.DatabaseName,DatabaseName)=0) then
           Exit;
        end
     else
        begin
        if ((Result.DatabaseName <> '') or Result.Temporary) and  <------------ Access Violation
           (AnsiCompareText(Result.DatabaseName,DatabaseName)=0) then
           Exit;
        end;


I would like to note that ExecSQL function is used in file server automation software and executed about 100 000 times per day,
so exception frequency is not big but still we would like to find why it happens.
We have about one million records in tables and DBISAM in CS mode works very fast and stable in this condition.

Regards,
Tomas


function ExecSQL(SQL: string): Integer;
var sSession: TDBISAMSession;
 dbDatabase: TDBISAMDatabase;
 qQuery: TDBISAMQuery;
 ADynamicSessionName: string;
begin
 sSession := TDBISAMSession.Create(nil);
 dbDatabase := TDBISAMDatabase.Create(nil);
 qQuery := TDBISAMQuery.Create(nil);
 try
   sSession.RemoteAddress := ADBServerIP;
   sSession.RemotePort := StrToInt(ADBServerPort);
   sSession.RemoteUser := ADBUser;
   sSession.RemotePassword := ADBPass;
   dbDatabase.RemoteDatabase := ADBDatabase;

   sSession.SessionType := stRemote;
   sSession.AutoSessionName := true;
   sSession.PrivateDir := Path_UserTemp;


   sSession.Active := true;

   ADynamicSessionName := sSession.SessionName;

   dbDatabase.SessionName := ADynamicSessionName;
   qQuery.SessionName := ADynamicSessionName;

   dbDatabase.DatabaseName := ADynamicSessionName;
   qQuery.DatabaseName := dbDatabase.DatabaseName;
   
   qQuery.RequestLive := true;
   qQuery.Close;
   qQuery.SQL.Text := SQL;
   qQuery.ExecSQL;
   result := qQuery.RowsAffected;
 finally
   dbDatabase.Close;
   sSession.Active := false;
   qQuery.Free;
   dbDatabase.Free;
   sSession.Free;
 end;
end;
Thu, Jun 5 2008 9:31 AMPermanent Link

"John Hay"
Tomas
> But I still got one after update and I have found that new exception
"Access violation"
>  throw several times at
>
>
> function TDBISAMSession.FindDatabase(const DatabaseName: string):
TDBISAMDatabase;
> var
>    I: Integer;
> begin
>    for I:=0 to FDatabases.Count-1 do
>       begin
>       Result:=FDatabases[I];
>       if ContainsDirectory(DatabaseName) and (not
MemoryDirectory(DatabaseName)) then
>          begin
>          if ((Result.DatabaseName <> '') or Result.Temporary) and
>             (OSCompareFileNames(Result.DatabaseName,DatabaseName)=0) then
>             Exit;
>          end
>       else
>          begin
>          if ((Result.DatabaseName <> '') or Result.Temporary) and
<------------ Access Violation
>             (AnsiCompareText(Result.DatabaseName,DatabaseName)=0) then
>             Exit;
>          end;

If this is multi threaded the database could be freed between Result:=
fDatabases[I] and if ((Result.DatabaseName <> '')  etc.

John

Thu, Jun 5 2008 7:06 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Tomas,

<< Tim, I have done as you suggested and "List index out of bounds"
exception decreased dramatically. But I still got one after update and I
have found that new exception "Access violation" throw several times at  >>

Then you've still got something set incorrectly.  If you'd like to post or
send me the code, then I can tell you where the problem is.

--
Tim Young
Elevate Software
www.elevatesoft.com

Image