OK you've finally got me, X# is very cool!
OK you've finally got me, X# is very cool!
Johan and Wolfgang -
I think it's important to remember that there are *two* distinct ways that each code sample must be reviewed, discussed, considered:
-> One is that it's a code example written to demonstrate what is a possible in X#, or perhaps even a best practice to get the most out of it when you have the luxury of writing new code.
-> The other is code that is presented as an example of what needs to be supported if there is hope of getting VFP people to use X# by way of porting their app code pretty much exactly the way it is written right now, and has been been written and maintained for many years.
There are lots of VFP people who have indeed used the old style XBase COMMAND/Functional DBF approach, and if they saw that VO/OO/Data Table code in Wolfang's example, their mind would be blown and they'll think they've landed on another planet.
I love the OO world and disconnected data, and all that. My VFP app is written with lots of those paradigms because I know it from 10 years of C# and Ruby on Rails and other Non-VFP exposure, but not all VFP people have had that luxury (or desire) and I just want to make sure that I demonstrate and discuss many of those XBase COMMAND/Functional DBF patters to the X# team and the FOX users so they see what is *required* to be supported in X# in order to on-board VFP apps written in that older style.
If there becomes a VFP Transporter tool that can scrape an entire app from an existing VFP code project, it will results in lots of XBase COMMAND/Functional DBF code patterns that will need to be supported.
Even if a magic VFP Transporter could do incredible transformations of their existing old-style code patterns into new X# paradigms, we still have to realize we'd be giving them a new fancy code base, but it would be one they won't understand.
I think it's important to remember that there are *two* distinct ways that each code sample must be reviewed, discussed, considered:
-> One is that it's a code example written to demonstrate what is a possible in X#, or perhaps even a best practice to get the most out of it when you have the luxury of writing new code.
-> The other is code that is presented as an example of what needs to be supported if there is hope of getting VFP people to use X# by way of porting their app code pretty much exactly the way it is written right now, and has been been written and maintained for many years.
There are lots of VFP people who have indeed used the old style XBase COMMAND/Functional DBF approach, and if they saw that VO/OO/Data Table code in Wolfang's example, their mind would be blown and they'll think they've landed on another planet.
I love the OO world and disconnected data, and all that. My VFP app is written with lots of those paradigms because I know it from 10 years of C# and Ruby on Rails and other Non-VFP exposure, but not all VFP people have had that luxury (or desire) and I just want to make sure that I demonstrate and discuss many of those XBase COMMAND/Functional DBF patters to the X# team and the FOX users so they see what is *required* to be supported in X# in order to on-board VFP apps written in that older style.
If there becomes a VFP Transporter tool that can scrape an entire app from an existing VFP code project, it will results in lots of XBase COMMAND/Functional DBF code patterns that will need to be supported.
Even if a magic VFP Transporter could do incredible transformations of their existing old-style code patterns into new X# paradigms, we still have to realize we'd be giving them a new fancy code base, but it would be one they won't understand.
OK you've finally got me, X# is very cool!
Hi Matt,
my sample was written for a specific request: for a VO programmer that would see how the VO specific data access could be bound to the .NET specific GUI.
Of course, VFP programmers need other samples, but infortunately I have not used commands for about 20 years now, so I'm not very used with them.
Personally, I think even people that uses the command/functional approach should adopt the OOP approach as fast as possible, not because I think it is the better approach (and yes, I'm convinced that software without OOP is much harder to maintain and to extend), but because the entire .NET Framework is built in classes.
For sure, for migrating code the compiler needs to be enhanced, and runtime libraries written, but in the long run only the use of the .NET Framework will justify the migration work.
Wolfgang
P.S. I will try to build another version of the sample for VFP programmers - or you could change it to make it easier to understand. Feel free to take the code, change it and publish it here or somewhere!
my sample was written for a specific request: for a VO programmer that would see how the VO specific data access could be bound to the .NET specific GUI.
Of course, VFP programmers need other samples, but infortunately I have not used commands for about 20 years now, so I'm not very used with them.
Personally, I think even people that uses the command/functional approach should adopt the OOP approach as fast as possible, not because I think it is the better approach (and yes, I'm convinced that software without OOP is much harder to maintain and to extend), but because the entire .NET Framework is built in classes.
For sure, for migrating code the compiler needs to be enhanced, and runtime libraries written, but in the long run only the use of the .NET Framework will justify the migration work.
Wolfgang
P.S. I will try to build another version of the sample for VFP programmers - or you could change it to make it easier to understand. Feel free to take the code, change it and publish it here or somewhere!
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
OK you've finally got me, X# is very cool!
Wolfgang -
I don’t yet know enough about X# myself to be writing samples or converting existing code.
It could lead to a confusing, and bad example.
But I’d love to see it converted, and I’m sure I’d learn a lot from it. And I could give feedback from a FoxPro dev perspective.
I don’t yet know enough about X# myself to be writing samples or converting existing code.
It could lead to a confusing, and bad example.
But I’d love to see it converted, and I’m sure I’d learn a lot from it. And I could give feedback from a FoxPro dev perspective.
OK you've finally got me, X# is very cool!
Hi Matt,
In VFP, you can do a simple
USE SomeTable.DBF Alias MyData
Grid.Recordsource = "MyData"
because, under the hood, this translates to (or, to be more correct, makes a call to) A LOT of code that has already been written by the VFP creators, in order to support this. Similar in VO, you can do the same thing as in VFP, people can easily do a very simple
LOCAL oCustomers := CusomerDataServer{}
oDataBrowser:Use(oCustomers)
which again calls a function that contains a lot of already written code (in the VO GUI and RDD classes) to take care of all the rest.
For VO programmers, all this code of the VO base classes has been ported to .Net, so people can use their existing code with no changes, they can still use "oDataBrowser:Use(oCustomers)" exactly as before, if they chose to continue using this way of doing this (which is a very good idea, especially when you consider apps with 100,000s or millions of lines of code...). Same goes for VFP, in order to properly support people with existing apps to port them to .Net/X#, we need to provide them with the equivalent of the framework you are using in VFP, now compiled in X#, running under .Net. That's the main part of the process for supporting VFP in X# that is gonna take the most effort.
About Wolfgang's code, if you are gonna use this approach, then of course you will not be rewriting the same code over and over again! That was just a sample on how to do this (DBF with DataTables), but if you're gonna use this extensively in an app, you would put all that code in just one function, declare it in a library, and then use only 2-3 lines of code in your actual app code, simply calling that functions. Exactly the same way as Grid.Recordsource = "MyData" and oDataBrowser:Use(oCustomers) already work.
In VFP, you can do a simple
USE SomeTable.DBF Alias MyData
Grid.Recordsource = "MyData"
because, under the hood, this translates to (or, to be more correct, makes a call to) A LOT of code that has already been written by the VFP creators, in order to support this. Similar in VO, you can do the same thing as in VFP, people can easily do a very simple
LOCAL oCustomers := CusomerDataServer{}
oDataBrowser:Use(oCustomers)
which again calls a function that contains a lot of already written code (in the VO GUI and RDD classes) to take care of all the rest.
For VO programmers, all this code of the VO base classes has been ported to .Net, so people can use their existing code with no changes, they can still use "oDataBrowser:Use(oCustomers)" exactly as before, if they chose to continue using this way of doing this (which is a very good idea, especially when you consider apps with 100,000s or millions of lines of code...). Same goes for VFP, in order to properly support people with existing apps to port them to .Net/X#, we need to provide them with the equivalent of the framework you are using in VFP, now compiled in X#, running under .Net. That's the main part of the process for supporting VFP in X# that is gonna take the most effort.
About Wolfgang's code, if you are gonna use this approach, then of course you will not be rewriting the same code over and over again! That was just a sample on how to do this (DBF with DataTables), but if you're gonna use this extensively in an app, you would put all that code in just one function, declare it in a library, and then use only 2-3 lines of code in your actual app code, simply calling that functions. Exactly the same way as Grid.Recordsource = "MyData" and oDataBrowser:Use(oCustomers) already work.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
OK you've finally got me, X# is very cool!
Hi Matt,
please look at this code to build the DataTable:
Wolfgang
please look at this code to build the DataTable:
Code: Select all
static method GetCustomerTableFunction() as DataTable
// creates a .NET DataTable from the DBF data
local oCustomer as DataTable
local nField as dword
local nFCount as dword
local aFields as array
local cFieldName as string
local oRow as DataRow
local cTableName as string
cTableName := "Customer"
// create the DataTable
oCustomer := DataTable{ cTableName }
// open the DBServer readonly and shared
if DBUseArea( true, ProgSettings.DefaultRDD, System.IO.Path.Combine( ProgSettings.DataPath, "Customer.dbf" ), cTableName, true, true )
DBSetOrder( "Cust1.ntx" )
DBGoTop()
// build the DataTable field structure, only string fields to keep thing simple
nFCount := FCount()
aFields := ArrayNew( nFCount )
for nField := 1 upto nFCount
cFieldName := Proper( FieldName( nField ) )
aFields[nField] := cFieldName
oCustomer:Columns:Add( cFieldName, System.Type.GetType( "System.String" ) )
next
// fill the DataTable with the DBF data
while ! EOF()
oRow := oCustomer:NewRow()
for nField := 1 upto nFCount
cFieldName := aFields[nField]
if IsString( FieldGet( nField ) ) // convert to string if needed
oRow[cFieldName] := AllTrim( FieldGet( nField ) )
else
oRow[cFieldName] := AsString( FieldGet( nField ) )
endif
next
oCustomer:Rows:Add( oRow )
DBSkip()
end
// and close the DBF file
DBCloseArea()
endif
return oCustomer
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
OK you've finally got me, X# is very cool!
Hi Matt,
please let me add that I would never write my code that way, because in a WIndows application nobody can make sure that this alias is not already used in another window or process. Therefore I had the build an unique alias first, before calling the DBUseArea() function.
I don't know how VFP handles these situations....
And there is another risk in a WIndows application: if somewhere in the reading loop is added a waitstate that transfers execution time to another process: nobody can exclude that the current active workarea is changed and the function gives unexpected results.
The VO DBServer class handles all these situations internally, and if I had not such a class already in the framework, I would build one.
But as I wrote: I don't know VFP and therefore I suspect it handles such things in another way.
Wolfgang
please let me add that I would never write my code that way, because in a WIndows application nobody can make sure that this alias is not already used in another window or process. Therefore I had the build an unique alias first, before calling the DBUseArea() function.
I don't know how VFP handles these situations....
And there is another risk in a WIndows application: if somewhere in the reading loop is added a waitstate that transfers execution time to another process: nobody can exclude that the current active workarea is changed and the function gives unexpected results.
The VO DBServer class handles all these situations internally, and if I had not such a class already in the framework, I would build one.
But as I wrote: I don't know VFP and therefore I suspect it handles such things in another way.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
OK you've finally got me, X# is very cool!
Chris wrote:
Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.
Once you have this type of VFP commands working in X# in Visual Studio, I think you can turn a lot of heads.
Here's what I'd consider a basic VFP command list that, when working in X#/VS, you'll attract *A LOT* of VFP lookers:
Next, FoxPro SQL command set (direct language commands against DBF Tables and Cursors, not SQL Strings sent to ODBC server)
Yes, yes, this is the part I am looking for if there is any hope for widespread FoxPro adoption. People are going to want their code to just magically run, with very little changes....especially when you consider apps with 100,000s or millions of lines of code...). Same goes for VFP, in order to properly support people with existing apps to port them to .Net/X#, we need to provide them with the equivalent of the framework you are using in VFP, now compiled in X#, running under .Net. That's the main part of the process for supporting VFP in X# that is gonna take the most effort.
Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.
Code: Select all
Select 0
Use Customers Order id
Select 0
Use Orders
Set Relation To Customer_id into Customers
Scan
? Orders.OrderNo " from " + Customers.Name
EndScan
Here's what I'd consider a basic VFP command list that, when working in X#/VS, you'll attract *A LOT* of VFP lookers:
Code: Select all
SELECT
USE
SET ORDER
SET RELATION
INDEX
LOCATE
REPLACE
SCAN/ENDSCAN
STORE
Code: Select all
SELECT, INSERT, UPDATE, DELETE
OK you've finally got me, X# is very cool!
Matt,
This is exactly what happened with VO, existing VO code "magically" runs now in X#! Of course there was no magic behind it, it is that we worked very hard to make the underlying VO classes compile under .Net and behave exactly the same way as they do in VO.
Something similar needs to be done about VFP, too. Obviously this is not a trivial task and of course we will need a lot of help from the VFP community and everybody else like Johan or anybody else who is interested in producing this. It will either involve compiling the underlying VFP system code in X#, or building a set of classes (with the same names, properties, functions etc as in VFP) which emulates the exact same behavior under .Net, using standard .Net classes. Or a combination of the two!
This is exactly what happened with VO, existing VO code "magically" runs now in X#! Of course there was no magic behind it, it is that we worked very hard to make the underlying VO classes compile under .Net and behave exactly the same way as they do in VO.
Something similar needs to be done about VFP, too. Obviously this is not a trivial task and of course we will need a lot of help from the VFP community and everybody else like Johan or anybody else who is interested in producing this. It will either involve compiling the underlying VFP system code in X#, or building a set of classes (with the same names, properties, functions etc as in VFP) which emulates the exact same behavior under .Net, using standard .Net classes. Or a combination of the two!
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
OK you've finally got me, X# is very cool!
That's the easy part, isn't that already working?mattslay wrote: Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.
Once you have this type of VFP commands working in X# in Visual Studio, I think you can turn a lot of heads.Code: Select all
Select 0 Use Customers Order id Select 0 Use Orders Set Relation To Customer_id into Customers Scan ? Orders.OrderNo " from " + Customers.Name EndScan
Here's what I'd consider a basic VFP command list that, when working in X#/VS, you'll attract *A LOT* of VFP lookers:
Code: Select all
SELECT USE SET ORDER SET RELATION INDEX LOCATE REPLACE SCAN/ENDSCAN STORE
That's the more difficult partmattslay wrote: Next, FoxPro SQL command set (direct language commands against DBF Tables and Cursors, not SQL Strings sent to ODBC server)
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
OK you've finally got me, X# is very cool!
Hi Chris,Chris wrote:That's the easy part, isn't that already working?mattslay wrote: Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.
Code: Select all
Select 0 Use Customers Order id Select 0 Use Orders Set Relation To Customer_id into Customers Scan ? Orders.OrderNo " from " + Customers.Name EndScan
Code: Select all
SELECT USE SET ORDER SET RELATION INDEX LOCATE REPLACE SCAN/ENDSCAN STORE
on GitHub i´ve found the UDC file dbcmd.xh . Wouldn´t it make sense to add it to the XSharp setup and install it in the include dir ?
https://github.com/X-Sharp/XSharpPublic ... n/dbcmd.xh
regards
Karl-Heinz