Page 1 of 3
DBServer replacement
Posted: Fri Jan 24, 2020 12:30 pm
by wriedmann
Hi Robert,
currently my CoreDBServer uses the VO compatible DBServer class.
Is there any class in the RDD I can use for an fully object oriented DBF access, so I don't have to deal with workareas?
Wolfgang
P.S. of course the CoreDBServer class will be published as well when finished
DBServer replacement
Posted: Fri Jan 24, 2020 1:26 pm
by robert
Wolfgang
Although the RDDs themselves are classes, it will still be difficult to access DBF data without workareas. Especially if you also want to deal with indexes, since the indexes have index keys that are processed by the macro compiler, and this macro compiler will translate calls to index expressions such as 'Upper(LastName)' to a function call 'Upper(__FieldGet("LastName")) '.
This function depends on the "Current workarea" because it needs to lookup the fieldname in the current workarea and translate it to a field position.
In theory (and with a lot of work) you could subclass the RDD and override the Compile() method of the RDD and the EvalBlock() method of the RDD , so you could use your own "macro compiler" and bypass the workarea system.
But that will not be easy....
Of course if you have a suggestion on how we can do things differently then I am all ears.
Robert
DBServer replacement
Posted: Fri Jan 24, 2020 1:40 pm
by wriedmann
Hi Robert,
yes, I agree that the DBF access will be difficult without the workarea concept, but that should be hidden in the class, like the VO DBServer class does.
Would it be a solution to use the WorkArea class or I'm still missing something there?
The goal of the operation is to have a fully working class that can work in Core dialect and permits full access to DBFs without relying on VO classes.
Currently my CoreDBServer class acts as proxy to the VO DBServer class and returns only typed values.
Wolfgang
DBServer replacement
Posted: Fri Jan 24, 2020 1:52 pm
by wriedmann
Hi Robert,
I've looked better - it seems that the WorkArea class is too low level (there is no FieldGet()/FieldPut() method), but maybe the WrapperRDD class is better suited.
Wolfgang
DBServer replacement
Posted: Fri Jan 24, 2020 1:52 pm
by robert
Wolfgang,
wriedmann wrote:Hi Robert,
yes, I agree that the DBF access will be difficult without the workarea concept, but that should be hidden in the class, like the VO DBServer class does.
Would it be a solution to use the WorkArea class or I'm still missing something there?
The goal of the operation is to have a fully working class that can work in Core dialect and permits full access to DBFs without relying on VO classes.
Currently my CoreDBServer class acts as proxy to the VO DBServer class and returns only typed values.
Your class can still use the core dialect but in the background the runtime and macro compiler will use the XSharp.RT assembly as well. But that does not mean that your code has to be weakly typed.
I recommend that your RDD keeps track of the RDD objects as IRDD (but 'AS Workarea' should work too, since all current RDDs inherit from Workarea).
If you retrieve the RDD object from the current workarea, you can bypass the runtime for operations such as FieldGet() and FieldPut() and directly call oRdd:GetValue() and oRdd:PutValue() etc.
But (unfortunately) the RDD has to be registered in the workareas list (which is also inside the XSharp.Core part of the runtime) so the code generated by the macro compiler is able to locate fields based on the current workarea. And this also means that you have to keep the "current workarea" number in sync because that is what the runtime expects. So if you have the RDD object in your server you should have some code like this:
Code: Select all
RuntimeState.CurrentWorkarea := self:oRDD:Area
This will most likely not be necessary when reading data, but most certainly when updating data, since that can and will trigger updates to index expressions.
Robert
DBServer replacement
Posted: Fri Jan 24, 2020 1:53 pm
by robert
Wolfgang,
wriedmann wrote:Hi Robert,
I've looked better - it seems that the WorkArea class is too low level (there is no FieldGet()/FieldPut() method), but maybe the WrapperRDD class is better suited.
That will not help you. See my other reply.
Robert
DBServer replacement
Posted: Fri Jan 24, 2020 1:55 pm
by wriedmann
Hi Robert,
thank you very much! I have now a better idea what to do.
Wolfgang
DBServer replacement
Posted: Fri Jan 24, 2020 7:43 pm
by SHirsch
Hi Wolfgang,
I have written a replacement for cDBServer (classmate) with ADS native functions. So no DBWorkArea is involved. It is still inherited from cDBServer but this could be changed because nearly every method is overridden.
Stefan
DBServer replacement
Posted: Fri Jan 24, 2020 7:50 pm
by wriedmann
Hi Stefan,
this is great, thank you!
Unfortunately I need both ADS and DBFCDX in my applications.
With ADS, it is the server that maintains the indexes. That removes the need for the macro compiler in the application, and gives much, much more speed and data security, but unfortunately there is no support for UDCs and memo fields in the index expression, and the ADS Local Server does not works in remote desktop sessions (that is a pity for me in development).
But it could be an idea to start from the cDBServer (I have a never used ClassMate license), but it is copyrighted software from DataPro and therefore it cannot be used when other can see the code.
Wolfgang
DBServer replacement
Posted: Sat Jan 25, 2020 8:24 am
by wriedmann
Hi Robert.
I'm using ILSpy do find out how to build my DBFServer class.
Currently I'm battling a bit how to open a DBF file.
Unfortunately thos code does not works, it gives "Variable does not exist" in the :Open() call:
Code: Select all
local lReturn as logic
local cAlias as string
local oOpenInfo as DbOpenInfo
cAlias := DBFHelper.ConstructUniqueAlias( cFileName )
_nWorkArea := RuntimeState.Workareas:FindEmptyArea( true )
oOpenInfo := DbOpenInfo{ cFileName, cAlias, dword( _nWorkArea ), lShared, lReadOnly }
_oDBF := ( DBF ) CreateInstance( cDriver )
lReturn := _oDBF:Open( oOpenInfo )
What I'm doing wrong?
Or ist there a better method to do that?
Wolfgang