fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1
  • 2

TOPIC: DBServer replacement

DBServer replacement 1 month 2 days ago #12910

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
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
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 days ago #12911

  robert's Avatar robert Offline Posts: 1502
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
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 days ago #12913

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
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
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 days ago #12914

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
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
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 days ago #12915

  robert's Avatar robert Offline Posts: 1502
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:
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
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 days ago #12916

  robert's Avatar robert Offline Posts: 1502
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
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 days ago #12917

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Robert,

thank you very much! I have now a better idea what to do.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 1 day ago #12920

  SHirsch's Avatar SHirsch Away Posts: 145
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

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 1 day ago #12921

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
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
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 1 day ago #12922

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
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:
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
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 1 month 2 hours ago #12929

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Robert,
I'm now a step further, I think.
protected method Initialize( cFileName as string, lShared as logic, lReadOnly as logic, cDriver as string ) as logic          
local lReturn as logic  
local cAlias as string 
	
lReturn := true
	
try                             
		                               
cAlias := DBFHelper.ConstructUniqueAlias( cFileName )
lReturn := CoreDB.UseArea( true, cDriver, cFileName, cAlias, lShared, lReadOnly )
if lReturn
  _nWorkArea := CoreDB.SymSelect( cAlias )      
  _oRDD := RuntimeState.Workareas:GetRDD( dword( _nWorkArea ) )
else
  _nWorkArea := -1
endif      
	
catch oEx as Exception	   
		
lReturn := false
self:ProcessException( oEx )
		
end try
	
_lInitialized := lReturn
	
return lReturn
Currently I'm trying to implement the SetOrder() method.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12930

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Robert,
I have now tried to implement the FieldPut() method:
public virtual method FieldPut( cFieldName, oValue as object ) as logic
local lReturn as logic
local nFieldPos as int
local nSaveArea as dword

nSaveArea := RuntimeState.CurrentWorkArea
if ( lReturn := self:Used ) .and. ( nFieldPos := self:FieldPos( cFieldName ) ) > 0
  try
    if RuntimeState.CurrentWorkArea != _nWorkArea
      RuntimeState.CurrentWorkArea := _nWorkArea
    endif
    lReturn := _oRDD:PutValue( nFieldPos, oValue )
  catch oEx as Exception
   self:ProcessException( oEx )
   end try
else
   lReturn := false
endif
if RuntimeState.CurrentWorkArea != nSaveArea
  RuntimeState.CurrentWorkArea := nSaveArea
endif

return lReturn
I'm doing that correctly?
Currently I don't have tested that code - have to do it.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12931

  FFF's Avatar FFF Away Posts: 832
cFieldname AS STRING
I suppose?
Regards
Karl

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12933

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Karl,

yes, of course! Thanks!
Unfortunately I had copied the function header from my AppDbServer class that inherited from DBServer, and there it was not possible to do it. Now I have changed it.
Wolfgang
P.S. I have named the class DBFAccess, so everywhere can use it, even people without VO background.
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12934

  FFF's Avatar FFF Away Posts: 832

wriedmann wrote: Hi Wolfgang,

P.S. I have named the class DBFAccess, so everywhere can use it, even people without VO background.

Hm, i would probably re-think that, as it might imply, "Access" to be envolved...

Regards
Karl

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12935

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Karl,
do you have a better idea?
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12936

  FFF's Avatar FFF Away Posts: 832
No idea, wether "better" ;)...
CoreDBServer
XDBServer
X#DBServer
xDBF
CoreDBF
Regards
Karl

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 2 days ago #12937

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Karl,
I would discard "Server" because it may sound for non VO people like a "database server" - and it is not that.
The internally used class is CoreDB, and maybe CoreDBF would be the best option.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 1 day ago #12948

  wriedmann's Avatar Topic Author wriedmann Away Posts: 2123
Hi Robert,
my code seems to work, including creating DBF files and the relative orders.
If I understand you correctly, I have to switch the current workarea every time I do some write into the table, including order creation.
It may be important to include the code switching the workarea in a try - catch statement, and restore it afterwards.
Please let me know if this code has any drawbacks or errors (I have to add some more error checking and exception handling):
public virtual method FieldPut( cFieldName as string, oValue as object ) as logic
local lReturn as logic
local nFieldPos as int
local nSaveArea as dword

nSaveArea := RuntimeState.CurrentWorkArea
if ( lReturn := self:Used ) .and. ( nFieldPos := self:FieldPos( cFieldName ) ) > 0
  try
    if RuntimeState.CurrentWorkArea != _nWorkArea
      RuntimeState.CurrentWorkArea := dword( _nWorkArea )
    endif
     lReturn := _oRDD:PutValue( nFieldPos, oValue )
  catch oEx as Exception
  self:ProcessException( oEx )
  end try
else
  lReturn := false
endif
if RuntimeState.CurrentWorkArea != nSaveArea
  RuntimeState.CurrentWorkArea := nSaveArea
endif
return lReturn

Thank you very much!

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy

www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

DBServer replacement 4 weeks 1 day ago #12949

  robert's Avatar robert Offline Posts: 1502
Wolfgang,
If you want to be sure that the code to restore the workarea always runs, I would add it to a FINALLY clause.
And I am not sure why you are testing for the workarea number. Assigning should not have any negative effects.
And if you already have the RDD object then you don't need a variable for the area number as well. The number is a property of the RDD object:

Something like
nSaveArea := RuntimeState.CurrentWorkArea 
try
     RuntimeState.CurrentWorkArea := _oRDD:Area
     lReturn := _oRDD:PutValue( nFieldPos, oValue )
catch oEx as Exception
    self:ProcessException( oEx )
finally
      RuntimeState.CurrentWorkArea := nSaveArea
end try
XSharp Development Team
The Netherlands

Please Log in or Create an account to join the conversation.

  • Page:
  • 1
  • 2