Lazarus

Free Pascal => Database => Topic started by: HappyLarry on August 08, 2016, 10:51:49 am

Title: BufDataSet - LoadFromFile problem
Post by: HappyLarry on August 08, 2016, 10:51:49 am
In BufDataSet, I can not get LoadFromFile to work.
I have tried both
Code: Pascal  [Select][+][-]
  1.      T.LoadFromFile('Names.bds');

and
Code: Pascal  [Select][+][-]
  1.      
  2.      T.Edit;
  3.      T.LoadFromFile('Names.bds');
  4.      T.Post;
but neither shows the record.

All help gratefully received.

Here is my test program
Code: Pascal  [Select][+][-]
  1. program Loadtest;
  2. uses
  3.   db,BufDataset;
  4.  
  5. var
  6.   T:TBufDataSet;
  7.  
  8. begin
  9.      //Create a dataset, add a record and save it
  10.      T:=TBufDataset.Create(nil);
  11.      T.FieldDefs.Add('Name',ftString,20);
  12.      T.CreateDataset;
  13.      T.Append;
  14.      T.Fields[0].value:='Fred';
  15.      T.Post;
  16.  
  17.      writeln('Before Save :',T.Fields.FieldByName('Name').AsString);
  18.  
  19.      T.SaveToFile('Names.bds');
  20.      T.Free;
  21.  
  22.      //Create a dataset, load the file and show it
  23.      T:=TBufDataset.Create(nil);
  24.      T.FieldDefs.Add('Name',ftString,20);
  25.      T.CreateDataset;
  26.      //T.Edit;
  27.      T.LoadFromFile('Names.bds');
  28.      //T.Post;
  29.      writeln('After Load :',T.Fields.FieldByName('Name').AsString);
  30.  
  31.      T.free;
  32.  
  33.    writeln('------ done ----------');
  34.    readln;
  35. end.
  36.  



Title: Re: BufDataSet - LoadFromFile problem
Post by: howardpc on August 08, 2016, 11:06:04 am
LoadFromFile creates the data set.
All you want after saving the data set to file is this:

Code: Pascal  [Select][+][-]
  1. //Create a dataset, load the file and show it
  2.   T:=TBufDataset.Create(nil);
  3.   T.LoadFromFile('Names.bds');
  4.   writeln('After Load :',T.Fields.FieldByName('Name').AsString);
  5.   T.free;    
Title: Re: BufDataSet - LoadFromFile problem
Post by: ttomas on August 08, 2016, 11:06:54 am
This work OK
Code: Pascal  [Select][+][-]
  1.   //Create a dataset, load the file and show it
  2.   T:=TBufDataset.Create(nil);
  3. //---->  T.FieldDefs.Add('Name',ftString,20);  
  4. //---->  T.CreateDataset;
  5.   //T.Edit;
  6.   T.LoadFromFile('Names.bds');
  7.  
Title: Re: BufDataSet - LoadFromFile problem
Post by: wp on August 08, 2016, 11:27:22 am
Or do this:
Code: Pascal  [Select][+][-]
  1. T := TBufDataset.Create(nil);
  2. T.FileName := 'Names.bds';
  3. T.Open;
Having specified the filename will cause automatic saving of the file if the dataset is closed later.
Title: Re: BufDataSet - LoadFromFile problem
Post by: HappyLarry on August 08, 2016, 02:22:40 pm
@ All
Great answers - Thanks

Another problem: I have tried to write a procedure to load a text file. The text file record structure is (String, Integer, Real). I have written:
Code: Pascal  [Select][+][-]
  1. procedure LoadTextFile(Filename:string; var T:TBufDataSet);
  2. var
  3.   MyFile:Text;
  4.   C1:string;
  5.   P1:integer;
  6.   A1:real;
  7.  
  8. begin
  9.       Assignfile(MyFile,FileName);
  10.       Reset(MyFile);
  11.       While not System.EOF(MyFile) do
  12.       begin
  13.         readln(MyFile,C1);
  14.         readln(MyFile,P1);
  15.         readln(MyFile,A1);
  16.         T.AppendRecord([C1, P1, A1]);
  17.       end;
  18.       CloseFile(MyFile);
  19. end;
  20.  

This works but is not generally usable, because it relies on the record structure being(String, Integer, Real),
Is there a way of writing it so that it works whatever the record structure, for instance if the record structure was (String, Integer, Integer, String);?

If it helps, here is the full program code.
Code: Pascal  [Select][+][-]
  1. program Loadtest;
  2. uses
  3.   db,BufDataset;
  4.  
  5. var
  6.   T:TBufDataSet;
  7.  
  8. procedure SaveTextFile(Filename:string; T:TBufDataSet);
  9. var
  10.   j:integer;
  11.   MyFile:text;
  12. begin
  13.   Assignfile(MyFile,FileName);
  14.   Rewrite(MyFile);
  15.   T.First;
  16.   While not T.EOF do
  17.   begin
  18.     For j:= 0 to T.FieldCount-1 do
  19.     begin
  20.         writeln(MyFile,T.Fields[j].Value);
  21.     end;
  22.     T.next;
  23.   end;
  24.   CloseFile(MyFile);
  25. end;
  26.  
  27. procedure LoadTextFile(Filename:string; var T:TBufDataSet);
  28. var
  29.   MyFile:Text;
  30.   C1:string;
  31.   P1:integer;
  32.   A1:real;
  33.  
  34. begin
  35.       Assignfile(MyFile,FileName);
  36.       Reset(MyFile);
  37.       While not System.EOF(MyFile) do
  38.       begin
  39.         readln(MyFile,C1);
  40.         readln(MyFile,P1);
  41.         readln(MyFile,A1);
  42.         T.AppendRecord([C1, P1, A1]);
  43.       end;
  44.       CloseFile(MyFile);
  45. end;
  46.  
  47.  
  48.  
  49.  
  50. begin
  51.      //Create a dataset,
  52.      T:=TBufDataset.Create(nil);
  53.      T.FieldDefs.Add('C',ftString,20);
  54.      T.FieldDefs.Add('P',ftInteger);
  55.      T.FieldDefs.Add('A',ftFloat);
  56.  
  57.      //add a record
  58.      T.CreateDataset;
  59.      T.Append;
  60.      T.Fields[0].value:='Belgium';
  61.      T.Fields[1].value:=11;
  62.      T.Fields[2].value:=32.5;
  63.      T.Post;
  64.  
  65.      //Save
  66.      writeln('Before Save :',T.Fields.FieldByName('C').AsString);
  67.      SaveTextFile('Countries.txt', T);
  68.  
  69.      //Clear Table
  70.      T.Delete;
  71.      writeln('After Delete :',T.RecordCount,' records');
  72.  
  73.      //Reload
  74.      LoadTextFile('Countries.txt',T);
  75.      writeln('After Load :',T.Fields.FieldByName('C').AsString);
  76.  
  77.      T.free;
  78.  
  79.    writeln('------ done ----------');
  80.    readln;
  81. end.
  82.  
Title: Re: BufDataSet - LoadFromFile problem
Post by: howardpc on August 08, 2016, 02:52:49 pm
For persistent data saved to a textfile you can organise your file so that the first line saved with SaveToText represents the field structure (fieldname, type, and length). Your LoadTextFile procedure would then parse the first line read as a special composite value whose individual parts enable you to reconstruct the correct TFieldDefs for your BufDataSet. Or you can save this information as a separate schema file which LoadTextFile opens and reads first.

Either way, once the correct database structure is determined, LoadTextFile can continue to read individual records using ReadLn, parsing each record into its constituent fields which are appended to the dataset in memory.

Note that best practice is to use TextFile (rather than Text) as the file type. If you ever migrate your code to a GUI app, use of Text will most likely produce  unwelcome name clashes with the Text properties of numerous classes.
TinyPortal © 2005-2018