insert fails on tDbf table lazarus / 16-Databases ---------------------------------------------------------------------- garydale · 2011-07-21 21:26 I'm using Lazarus 0.9.28.2-12 beta on a Debian/Wheezy AMD64 system. I'm attempting to append records from one .dbf file to another (both originally created using Visual dBASE 5.7). Whether I have a .mdx file with them or not, when I attempt to insert the first record in the empty database, I get an error: Project Myproject raised exception class 'eDatabaseError' with message: ###(gdb unparsed remainder:s 0xffffffffffec out of bounds>)### The database did open correctly and I can display a list of its fields. I've changed the Linux permissions on the database files to A+RWX but that didn't help. Using ShowMessage I have verified that it is the statement "mydbf.insert;" that is throwing the exception. Any ideas anyone? ---------------------------------------------------------------------- BigChimp · 2011-07-22 05:58 I'm not that knowledgeable about DBF - just wrote my first DBF program myself, but: Might be that you have an old FPC/Lazarus version with a bug that has since been fixed. What is your version?Might be your code (though I suspect not, based on your post). What exactly is the relevant code?Could even be that support for that version of DBF files is faulty. Does editing/updating records work? And selecting/reading them? If all else fails, you could try to write a simple test program with sample data and put it on the bugtracker... that will at least make sure the bug (if it is one) is tracked and dealt with by the devs. ---------------------------------------------------------------------- garydale · 2011-07-22 21:14 Got it. I tried running the Win32 version in a Virtual Machine and got a better error message that pointed to a bad file path. When I fixed that in Windows by removing the file path, it also fixed it in Linux. I also tried Lazarus under Wine but can't get my application to run. I'm not sure why the file opens and displays the fields when it has a "bad" file path. It's not actually bad - just handled that way. I had the full path to the file instead of a relative path from the application directory. ---------------------------------------------------------------------- garydale · 2011-07-23 19:39 Spoke too soon. It's giving me the same error under Linux as before. It runs fine under Win32 and under Wine however. ---------------------------------------------------------------------- garydale · 2011-07-30 16:24 OK, after making substantial changes to my program (but not to the part hat's giving me the problem), I'm now getting a more descriptive error message from the Linux executable. It's now telling me "Dataset is read-only." The code segment in question is:  Code: [Select]             if postalcodetable.Locate('POSTALCODE', CurPost, [loCaseInsensitive]) then begin showMessage('editing ' + postalcodetable.FieldByName('POSTALCODE').Text);                  postalcodetable.Edit;              end else begin showMessage('inserting ' + CurPost);                  postalcodetable.Insert; showMessage('inserted ' + CurPost);                  postalcodetable.FieldByName('POSTALCODE').AsString := CurPost;              end; The postalcodetable is of type TDbf and is opened with ReadOnly set to False. The .dbf and .mdx files are both a+rw (everyone has read-write privileges). When the above code runs, I get the "inserting" message directly before the database.Insert but not the "inserted" message immediately after it. Instead I get the "read-only" error popup message reported at the top. Any ideas? ---------------------------------------------------------------------- felipemdc · 2011-07-30 20:15 Maybe attaching here the project would help if someone wants to take a look ---------------------------------------------------------------------- garydale · 2011-07-31 00:09 The full source code is rather large. I've just refactored it to isolate a couple of classes and hide the implementation of persistence. It's still working under Windows/Wine but not under Linux. I notice that the Windows/Wine version is 9.30 while the Linux version is 9.28.2. Also, noted that I get the "Dataset is read-only" error when I launch my application from Dolphin (the KDE file explorer) while running it from Lazarus gives me the error I originally reported. I'm wondering if the error is related to the difference in version numbers? Unfortunately it looks like the Debian/Sid version of Lazarus (which is 9.30) isn't working right now. Anyway, here's the complete code for the unit that is failing: Code: [Select]unit PostalCodes; {$mode objfpc}{$H+} interface uses     Db, Dbf, Dialogs, Ridings, Classes, SysUtils; type   tPostCode = String;   tWard = Integer;   TPostalCode = Class(TObject)     private       PostalCode: tPostCode;       FederalRiding,       ProvincialRiding: tRidingCode;       MunicipalWard: tWard;     public       constructor Create(const pCode: tPostCode; const Fed, Prov: tRidingCode; const mWard: tWard);       procedure getPostalCode(var pCode: tPostCode);       procedure getFederalRiding(var Fed: tRidingCode);       procedure getProvincialRiding(var Prov: tRidingCode);       procedure getMunicipalWard(var mWard: tWard);       procedure getProvince(var Province: tRidingType);       procedure setPostalCode(const pCode: tPostCode);       procedure setFederalRiding(const Fed: tRidingCode);       procedure setProvincialRiding(const Prov: tRidingCode);       procedure setMunicipalWard(const mWard: tWard);       procedure load();       procedure save();       procedure maintain();    end; implementation const postalcodetablename = 'POSTAL.DBF';       postalcodetablepath = '';       postalcodefield     = 'POSTALCODE';       federalridingfield  = 'FEDERAL';       provincialridingfield = 'PROVINCIAL';       municipalwardfield  = 'MUNICIPAL'; var  postalcodetable: TDbf; Procedure OpenTable(var aTable: TDbf; const TablePath, TableName: String);    begin         aTable.FilePath  := TablePath;         aTable.TableName := TableName;         aTable.Open;    end; procedure rebuild(var aTable: TDbf);   begin       ShowMessage('rebuilding index for ' + aTable.TableName);       aTable.Exclusive := True;       aTable.PackTable;       aTable.RegenerateIndexes;       aTable.Exclusive := False;       ShowMessage('rebuilt index for ' + aTable.TableName);   end; { TPostalCode } constructor TPostalCode.Create(const pCode: tPostCode; const Fed, Prov: tRidingCode; const mWard: tWard);   begin       PostalCode := pCode;       FederalRiding := Fed;       ProvincialRiding := Prov;       MunicipalWard := mWard;   end; procedure TPostalCode.getPostalCode(var pCode: tPostCode);   begin        pCode := Self.PostalCode;   end; procedure TPostalCode.getFederalRiding(var Fed: tRidingCode);   begin        Fed := Self.FederalRiding;   end; procedure TPostalCode.getProvincialRiding(var Prov: tRidingCode);   begin        Prov := Self.ProvincialRiding;   end; procedure TPostalCode.getMunicipalWard(var mWard: tWard);   begin        mWard := Self.MunicipalWard;   end; Procedure TPostalCode.getProvince(var Province: tRidingType);   var First: Char;   begin       First := Self.PostalCode[1];       case First of          'A': Province := 'NL';          'B': Province := 'NS';          'C': Province := 'PE';          'E': Province := 'NB';          'G', 'H', 'J':               Province := 'QC';          'K', 'L', 'M', 'N', 'P' :               Province := 'ON';          'R': Province := 'MB';          'S': Province := 'SK';          'T': Province := 'AL';          'V': Province := 'BC';          'X': Province := 'NT';          'Y': Province := 'YT';       end;   end; procedure TPostalCode.setPostalCode(const pCode: tPostCode);   begin        Self.PostalCode := pCode;   end; procedure TPostalCode.setFederalRiding(const Fed: tRidingCode);   begin        Self.FederalRiding := Fed;   end; procedure TPostalCode.setProvincialRiding(const Prov: tRidingCode);   begin        Self.ProvincialRiding := Prov;   end; procedure TPostalCode.setMunicipalWard(const mWard: tWard);   begin        Self.MunicipalWard := mWard;   end; procedure TPostalCode.load();   begin      if Length(Self.PostalCode) <> 0 then         if postalcodetable.Locate(postalcodefield, Self.PostalCode, []) then begin            Self.FederalRiding    := postalcodetable.FieldByName(federalridingfield).Text;            Self.ProvincialRiding := postalcodetable.FieldByName(provincialridingfield).Text;            Self.MunicipalWard    := postalcodetable.FieldByName(municipalwardfield).AsInteger;         end else begin            Self.FederalRiding    := '';            Self.ProvincialRiding := '';            Self.MunicipalWard    := 0;         end   end; procedure TPostalCode.save();   begin        if postalcodetable.Locate(postalcodefield, Self.PostalCode, []) then           postalcodetable.Edit        else begin           postalcodetable.Insert;           postalcodetable.FieldByName(postalcodefield).AsString := Self.PostalCode;        end;        postalcodetable.FieldByName(federalridingfield).AsString := Self.FederalRiding;        postalcodetable.FieldByName(provincialridingfield).AsString := Self.ProvincialRiding;        postalcodetable.FieldByName(municipalwardfield).AsInteger := Self.MunicipalWard;        postalcodetable.Post;   end; procedure TPostalCode.maintain(); begin    postalcodetable.Close;    postalcodetable.Exclusive := True;    OpenTable(postalcodetable, postalcodetablepath, postalcodetablename);    postalcodetable.AddIndex(postalcodefield, postalcodefield, [ixPrimary, ixUnique]);    postalcodetable.AddIndex(federalridingfield, federalridingfield, []);    postalcodetable.AddIndex(provincialridingfield, provincialridingfield, []);    postalcodetable.AddIndex(municipalwardfield, municipalwardfield, []);    rebuild(postalcodetable);    postalcodetable.Close;    postalcodetable.Exclusive := False;    OpenTable(postalcodetable, postalcodetablepath, postalcodetablename); end; initialization;   postalcodetable := TDbf.Create(nil);   postalcodetable.ReadOnly  := False;   postalcodetable.Exclusive := False;   OpenTable(postalcodetable, postalcodetablepath, postalcodetablename); finalization;   postalcodetable.Close; end. ---------------------------------------------------------------------- garydale · 2011-07-31 19:50 OK, I got 9.30 to install under Linux but the problem is still there. Note: I can rebuild the indexes for the files even though the .mdx files have the same security settings as the .dbf files. It's just trying to edit or insert that seems to fail.