Recent

Author Topic: ZMSQL - TBufDataset SQL enhanced in-memory database  (Read 129319 times)

HeDiBo

  • New Member
  • *
  • Posts: 44
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #90 on: January 24, 2014, 04:46:51 pm »
So, you might test it. At least we will know whether the problem is inside BufDataset.

It must be something in your system. Rebuilding your test application with the new TZMBufDataset still works OK.

I had to replace the two occurrences of TZMZMBufDatasetParser into TZMBufDatasetParser.

To be sure we're testing with the same test project, I'm attaching mine
Kind regards ;-}
Dick

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #91 on: January 24, 2014, 07:28:32 pm »
HeDIBo, sorry, it's my fault, now I see I introduced a bug in meantime...
Well, you were right, in your first post - if CreatePersistentFields is called explicetely then it works.
However, it makes no sence, since persistent fields should be created only in design-time...
So...back to investigation...

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #92 on: January 25, 2014, 12:51:49 pm »
HeDIBo,
Yes, you are right, the problem is in TBufDataset's InternalOpen procedure.
Code: [Select]
  // If there is a field with FieldNo=0 then the fields are not found to the
  // FieldDefs which is a sign that there is no dataset created. (Calculated and
  // lookup fields have FieldNo=-1)
  for i := 0 to Fields.Count-1 do
    if Fields[i].FieldNo=0 then
      begin
        { TODO : To find a way to set FieldNo for persistent fields. }
        //Here is the problem with persisten fields,  because FieldNo is read-only property and is not published, neither streamed....
        DatabaseError(SErrNoDataset);}
      end
    else
      if (FAutoIncValue>-1) and (Fields[i] is TAutoIncField) and not assigned(FAutoIncField) then
        FAutoIncField := TAutoIncField(Fields[i]);
Property FieldNo is 0. And FieldNo is read-only property that is not saved in .lfm, so all persistent fields are initiated with FieldNo=0.
If this is commented in T(ZM)BufDataset, than what happens is that all fields are loaded as the last one field in Fields.
Since FieldNo can't be set in ZMQueryDataset as it is read-only, defined deeply in DB unit...I really have no idea how to solve this.
If someone knows how to set FieldNo after persistent fields are loaded from .lfm?

Current zmsql is attached.

HeDiBo

  • New Member
  • *
  • Posts: 44
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #93 on: January 25, 2014, 05:44:02 pm »
I think there's a bug.

I could trace the creation of the fields from fielddefs in CreatePersistentFieldsFromFieldDefs. In DoCreatePersistentFieldsFromFieldDefs at the end there's a Self.BindFields(True); However directly after the call in CreatePersistentFieldsFromFieldDefs, there's another BindFields(True);

This is not the cause of your problem, but I thought I mention it anyway.

Kind regards ;-}
Dick

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #94 on: January 25, 2014, 07:31:02 pm »
Hi again. I think I solved it, with a trick though.
I introduced a method InitializePersistentFields which recreates persistent fields so that original names and properties are copied to new persistent fields while old persistent fields are deleted.
New zmsql version is attached.
Please, could you test and confirm that it works?
Thanks.
« Last Edit: January 25, 2014, 07:42:24 pm by tatamata »

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #95 on: January 25, 2014, 09:31:04 pm »
In zmsql wiki page, added chapter explainig JanSQL SQL dialect:
http://wiki.lazarus.freepascal.org/ZMSQL#JanSQL_SQL_language

HeDiBo

  • New Member
  • *
  • Posts: 44
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #96 on: January 27, 2014, 04:36:15 pm »
Please, could you test and confirm that it works?

First of all: it works. But very strangely.
The property PersistentFieldsCreated won't stay True. So, it will always be False when loaded for the first time. Therefore, it serves no purpose anymore, does it? Unless you want the designer to set it True every time the project ios loaded.

The purpose of creating persistent fields at design time was to improve speed, if I'm correct. I wonder what speed you're trying to improve when the dataset itself uses JanSQL which does only sequential searches as far as I know. Isn't that a bit penny wise and pound foolish?

Using a fixed type of CSV format is not very nice. The purpose of ZMSQL is to serve a single user. But that user will produce CSV files as output from a spreadsheet, for instance. He may not have the possibility to specify the output format. Also, more than half of the world uses a comma for the decimal "point". That cannot be specified either. Someone suggested to make that a programmer's task. That is not a valid proposition. The programmer should not have to translate the written table back to native notation. He should ask the environment about the decimal point, the thousands separator and the list separator and have a component like ZMSQL where he can pass that specification.

Maybe you can replace JanSQL by a better component. I don't know.

Keep up the good work!

Kind regards ;-}
Dick

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #97 on: January 28, 2014, 12:41:24 am »
Quote
First of all: it works. But very strangely.
The property PersistentFieldsCreated won't stay True. So, it will always be False when loaded for the first time. Therefore, it serves no purpose anymore, does it? Unless you want the designer to set it True every time the project ios loaded.
This was intentionally. It creates persistent fields and revert property value to false, but hey, persistent fields are there :-) Why? Well, just because I couldn't figure out how to prevent it that when loading it does not create persistent fields twice (once from stream and second time from setting this property to true...
Anyway, the property itself is not important, the intention was just to enable programmer in design-time to create all persistent fields from fielddefs at once and then just set additional properties...All that can be done by using editor, but this should be faster and you don't miss any fields by mistake...
Quote
The purpose of creating persistent fields at design time was to improve speed, if I'm correct. I wonder what speed you're trying to improve when the dataset itself uses JanSQL which does only sequential searches as far as I know. Isn't that a bit penny wise and pound foolish?
No, speed was not in my mind. Only ability to set some additional properties for fields in design-time, that you can't set for Fielddefs - this can be useful when multiple data controls (DBGrids for example) connected to the same dataset. Otherwise, you have to set it for any data control separately...
Regarding jansql, it is only one option for loading data into zmquerydataset - there are all other possiblities inherited from TBufDataset like streaming from files, copying from other datasets, loading from .csv files...
And you can combine all dataset's methods with jansql...it is not excluding one another...
Quote
Using a fixed type of CSV format is not very nice. The purpose of ZMSQL is to serve a single user. But that user will produce CSV files as output from a spreadsheet, for instance. He may not have the possibility to specify the output format. Also, more than half of the world uses a comma for the decimal "point". That cannot be specified either. Someone suggested to make that a programmer's task. That is not a valid proposition. The programmer should not have to translate the written table back to native notation. He should ask the environment about the decimal point, the thousands separator and the list separator and have a component like ZMSQL where he can pass that specification.
Actually, I was just working on those issues last few days :D
First of all, there is SysUtils.DefaultFormatSettings.DecimalSeparator and SysUtils.DefaultFormatSettings.ThousandSeparator, which you can read and write in your program. In Windows system settings are deduced correctly automatically, in Linux, clocale unit must be in uses. So I put it in zmsql. Also, I have just changed in zmsql that system setting for decimal separator is used always (both in zmquerydataset and jansql, so that these two are consistent with each other). Also, I added piece of code that enables correct loading of float values, no matter what decimal separator was in the .csv file. The function is the following:
Code: [Select]
function TZMQueryDataSet.FormatStringToFloat(pFloatString: string):Double;
//Transform float value inside a string with adequate decimal separator.
var
  fs:TFormatSettings;
  vFloatString, vLeftPart, vRightPart:String;
  vFloatValue:Double;
  vDelimiterPos:Integer;
begin
  fs.DecimalSeparator := SysUtils.DefaultFormatSettings.DecimalSeparator;
  {fs.ThousandSeparator := SysUtils.DefaultFormatSettings.ThousandSeparator;}

  {
  ShowMessage('DecimalSeparator: '+SysUtils.DefaultFormatSettings.DecimalSeparator);
  ShowMessage('ThousandSeparator: '+SysUtils.DefaultFormatSettings.ThousandSeparator);
  }

  case SysUtils.DefaultFormatSettings.DecimalSeparator of
     '.':
       begin
         //Replace decimal separator
         vFloatString:=StringReplace(pFloatString,',','.',[rfReplaceAll, rfIgnoreCase]);
       end;
     ',':
       begin
         //Replace decimal separator
         vFloatString:=StringReplace(pFloatString,'.',',',[rfReplaceAll, rfIgnoreCase]);
       end;
  end;

  //Aditional check for remaining thousand separators. If they exist, they should be removed.
  vDelimiterPos:=Rpos(SysUtils.DefaultFormatSettings.DecimalSeparator,vFloatString);
  vLeftPart:=AnsiLeftStr(vFloatString,vDelimiterPos-1);
  vRightPart:=AnsiRightStr(vFloatString,Length(vFloatString)-vDelimiterPos+1);
  if AnsiContainsStr(vLeftPart,SysUtils.DefaultFormatSettings.DecimalSeparator) then begin
    vLeftPart:=AnsiReplaceStr(vLeftPart,SysUtils.DefaultFormatSettings.DecimalSeparator,'');
    vFloatString:=vLeftPart+vRightPart;
  end;

  //Get result.
  vFloatValue:=StrToFloat(vFloatString, fs);
  Result:=vFloatValue;
end;
So, by using this function, zmquerydataset will be able to load correctly any float value, whether "." or "," was decimal separator. It will even load if someone left thousand separator in CSV file...
So, only ";" column separator in .CSV files will remain mandatory for the CSV file format. That's because jansql requires that. Although, this could be propably easily changed too...For instance, this is a function from Lazarus Book, that can be used for automatic separator detection in a CSV file:
Code: [Select]
function DetermineSeparator(AFileName: String; var HasFieldNames: Boolean): Char;
const Seps: array[1..5] of Char = (',',';',#9,'@','#');
var F:TextFile;
   S,S2,T:String;
   I:Integer;
begin
  AssignFile(F,AFileName);
  Reset(F);
  try
    Readln(F,S);
  finally
    CloseFile(F);
  end;
  Result:=#0;
  //Scan the line for the separator character:
  I:=0;
  while (Result=#0) and (I<5) do
  begin
    Inc(I);
    if Pos(Seps[i],S)<>0 then Result:=Seps[i];
  end;
  //Try and detect the presence of fieldnames:
  //no spaces or double separator:
  if Result<>#0 then
    HasFieldNames:=(Pos('',S)=0) and
                   (Pos(Result+Result,S)=0);
end;

Regarding jansql SQL engine...I hoped someone more experienced programmer from Lazarus community will improve it.

after all, I'm just a hobbiest :)
« Last Edit: January 28, 2014, 12:50:41 am by tatamata »

HeDiBo

  • New Member
  • *
  • Posts: 44
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #98 on: January 28, 2014, 01:16:08 pm »
This was intentionally. It creates persistent fields and revert property value to false, but hey, persistent fields are there :-) Why? Well, just because I couldn't figure out how to prevent it that when loading it does not create persistent fields twice (once from stream and second time from setting this property to true...
Anyway, the property itself is not important, the intention was just to enable programmer in design-time to create all persistent fields from fielddefs at once and then just set additional properties...All that can be done by using editor, but this should be faster and you don't miss any fields by mistake...
I'm not sure I understand this. Persistent fields are there and then setting the property they are created again. Why is this a good thing?

No, speed was not in my mind. Only ability to set some additional properties for fields in design-time, that you can't set for Fielddefs - this can be useful when multiple data controls (DBGrids for example) connected to the same dataset. Otherwise, you have to set it for any data control separately...
Again, you lost me. %)
Regarding jansql, it is only one option for loading data into zmquerydataset - there are all other possiblities inherited from TBufDataset like streaming from files, copying from other datasets, loading from .csv files...
And you can combine all dataset's methods with jansql...it is not excluding one another...
But correct me if I'm wrong, searching the ZMSQL dataset is a sequential search, isn't it? Because if it is, that's way too slow for datasets of considerable size.
Quote
Also, I have just changed in zmsql that system setting for decimal separator is used always (both in zmquerydataset and jansql, so that these two are consistent with each other).
That's OK for defaults, but not for definitive implementation. The input file may come from elsewhere, for instance, where the decimal separator is different. Or the file may come from a single minded program that can only produce files with one type of representation.

The DetermineSeparator function you give for finding the column separator is totally inadequate. Try it with this line:
1234,56;5432,10;"abcdef" (the comma's are decimal comma's)
Quote
after all, I'm just a hobbiest :)
It doesn't show  8) Congrats!
Kind regards ;-}
Dick

HeDiBo

  • New Member
  • *
  • Posts: 44
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #99 on: February 11, 2014, 12:37:09 pm »
I came across this old article http://edn.embarcadero.com/article/29056 about the TClientDataset. There you can find how they handle a persistent index. Quite interesting, I thought  8)
Kind regards ;-}
Dick

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #100 on: March 08, 2014, 11:43:59 am »
Hello, everybody.
With help of Mario Ferrari (mario.ferrari@edis.it), as constributor (thanks, Mario!), new version (0.1.17) of zmsql is out.
Download from:
http://sourceforge.net/projects/lazarus-ccr/files/zmsql/
See changes here:
http://wiki.lazarus.freepascal.org/ZMSQL#Change_Log

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #101 on: April 10, 2014, 09:06:49 am »
Hello everybody.
zmsql 0.1.18 is just released
http://sourceforge.net/projects/lazarus-ccr/files/zmsql/

This is bugfix release. There was a silly bug in zmquerydataset destroy method, that caused creating phantom copies of underlying csv files...It is solved now.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #102 on: April 10, 2014, 01:59:40 pm »
Thanks! Is the status of the release still Alpha as the wiki page says? Perhaps it's time to make it at least beta if enough users have tested it/if it is stable enough...
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

tatamata

  • Hero Member
  • *****
  • Posts: 804
    • ZMSQL - SQL enhanced in-memory database
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #103 on: April 10, 2014, 02:07:57 pm »
Thanks! Is the status of the release still Alpha as the wiki page says? Perhaps it's time to make it at least beta if enough users have tested it/if it is stable enough...
Hi, BigChimp!
I don't know.
I think it deserves beta status in it's overall functionality, but the janSQL engine itself has not been improved.
If someone could improve jansql engine so it has outer left and outer right joins, then I would surely say: "yes".

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: ZMSQL - TBufDataset SQL enhanced in-memory database
« Reply #104 on: April 10, 2014, 02:12:57 pm »
Well, IMO alpha or beta says more about the quality of the existing functionality: unreliable means alpha, more reliable means beta.
Once all needed functionality is there and working ok, it's no longer beta but production/gamma.

The reason why I asked is because alpha quality software is regarded with (justified) suspicion by many programmers; I think it would be unfair to zmsql if it is working ok, just missing some features.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

 

TinyPortal © 2005-2018