FoxInCloud
Load again
Gravatar is a globally recognized avatar based on your email address. Load again
  Tuvia Vinitsky
  All
  Apr 26, 2012 @ 04:57am
there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Tuvia Vinitsky
  Apr 26, 2012 @ 10:13am

I could really use a good solution to this if anyone has one.


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  Apr 27, 2012 @ 05:21am
In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,


-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  Apr 27, 2012 @ 06:28am

Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,


Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  Apr 27, 2012 @ 06:50am
Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,




-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  Apr 27, 2012 @ 06:55am

Do you have it running with an alias> IOW
use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,




Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Tuvia Vinitsky
  Apr 27, 2012 @ 07:04am

I looked in PropsSave_DS_cXML_Alias, and it does not seem that the underlying DBF() property is saved or restored. Is that necessary?

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,





Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  Apr 27, 2012 @ 07:26am
As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,






-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  Apr 27, 2012 @ 07:58am
IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,






Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  May 2, 2012 @ 02:17am
it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,








-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  May 2, 2012 @ 03:07am
See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,








Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  May 2, 2012 @ 03:13am
This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,










-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  May 2, 2012 @ 03:24am
NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,










Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  May 2, 2012 @ 03:37am
NO, sorry
awAJAX.PropsSave/Restore_DataSession takes care of Recno(), Filter() and Order() for each Alias()


NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,












-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  May 2, 2012 @ 04:00am
OK. Me, my staff, Andy, his staff, are all just imagining it then. Why we would make that up? the grids we are dealing with routinely have 30,000 + records.


NO, sorry
awAJAX.PropsSave/Restore_DataSession takes care of Recno(), Filter() and Order() for each Alias()


NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,












Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  May 2, 2012 @ 04:59am
It works on other applications, it may eventually not work in your particular case, but what can we do without a reproducible test case from which we can see if implemented support works or not?

Asserting a problem is fine, but it does not help us see when and where it may occur, and the reason for that and, if proven, a fix for it.


OK. Me, my staff, Andy, his staff, are all just imagining it then. Why we would make that up? the grids we are dealing with routinely have 30,000 + records.


NO, sorry
awAJAX.PropsSave/Restore_DataSession takes care of Recno(), Filter() and Order() for each Alias()


NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,














-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  May 2, 2012 @ 07:16am
I agree. My point was not to automatically jump and say "oh, we have code for that, there cannot be a bug in it."


It works on other applications, it may eventually not work in your particular case, but what can we do without a reproducible test case from which we can see if implemented support works or not?

Asserting a problem is fine, but it does not help us see when and where it may occur, and the reason for that and, if proven, a fix for it.


OK. Me, my staff, Andy, his staff, are all just imagining it then. Why we would make that up? the grids we are dealing with routinely have 30,000 + records.


NO, sorry
awAJAX.PropsSave/Restore_DataSession takes care of Recno(), Filter() and Order() for each Alias()


NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alais that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,














Gravatar is a globally recognized avatar based on your email address. Re: Load again
  FoxInCloud Support - Thierry N.
  Tuvia Vinitsky
  May 2, 2012 @ 07:36am
OK;
When you write "not supported", I understand "no code for that"
Maybe a vocabulary issue.

When in doubt about what is supported or not, you may browse through roadmap and source code.
We've done our best to choose self-explanatory method names based on a consistent, object-oriented naming scheme, e.g.:
PropsRestore_DS_Aliases() means "Restore Datasession Aliases", an Alias properties include Recno(), Filter(), Order(), etc.



I agree. My point was not to automatically jump and say "oh, we have code for that, there cannot be a bug in it."


It works on other applications, it may eventually not work in your particular case, but what can we do without a reproducible test case from which we can see if implemented support works or not?

Asserting a problem is fine, but it does not help us see when and where it may occur, and the reason for that and, if proven, a fix for it.


OK. Me, my staff, Andy, his staff, are all just imagining it then. Why we would make that up? the grids we are dealing with routinely have 30,000 + records.


NO, sorry
awAJAX.PropsSave/Restore_DataSession takes care of Recno(), Filter() and Order() for each Alias()


NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alias that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,
















-- thn (FoxInCloud)

Gravatar is a globally recognized avatar based on your email address. Re: Load again
  Tuvia Vinitsky
  Thierry Nivelet (FoxInCloud)
  May 2, 2012 @ 07:53am
I should have been more clear, not supported was a poor choice of words.

When I am posting your business day, it is often 2-4 am here and I have worked all night.


OK;
When you write "not supported", I understand "no code for that"
Maybe a vocabulary issue.

When in doubt about what is supported or not, you may browse through roadmap and source code.
We've done our best to choose self-explanatory method names based on a consistent, object-oriented naming scheme, e.g.:
PropsRestore_DS_Aliases() means "Restore Datasession Aliases", an Alias properties include Recno(), Filter(), Order(), etc.



I agree. My point was not to automatically jump and say "oh, we have code for that, there cannot be a bug in it."


It works on other applications, it may eventually not work in your particular case, but what can we do without a reproducible test case from which we can see if implemented support works or not?

Asserting a problem is fine, but it does not help us see when and where it may occur, and the reason for that and, if proven, a fix for it.


OK. Me, my staff, Andy, his staff, are all just imagining it then. Why we would make that up? the grids we are dealing with routinely have 30,000 + records.


NO, sorry
awAJAX.PropsSave/Restore_DataSession takes care of Recno(), Filter() and Order() for each Alias()


NO! It does not work fine for the userl. The grid might have been on record 6000 at the bottom. Change the tables and requery and the grid is now sitting at record number one.


This works fine:
grid.RecordSource = view
view is based on different tables according to the user
wUserSet() USEs the right table for each user
FAS's wwAJAX.PropsRestore takes care of Requery(view) automatically


See elsewhere, ruins the grids and and recordpointer


it is supported as long as you implement wUserSet() the way we have shown earlier


IOW using an alias that could have different source tables is not supported.


As explained earlier, as it depends on the user, this should be done in wUserSet() rather that Init()
You need some table naming scheme based on userID, or table address stored in USERS table

Do you have it running with an alias> IOW

use tmp101.dbf alias webtemp
then the next user/session on Init issues
use trmp102.dbf alias webtemp
then the third user/session issues
use tmp103.dbf alias webtemp
? The problem is different sessions have the same alias with a different underlying dbf behind the alias.


Set('FILTER') is saved by awServer.prg!awAJAX.PropsSave_DS_cXML_Alias() and restored by awServer.prg!awAJAX.PropsRestore_DS_Aliases()
I see nothing in this code that could confuse dataSession with another.
To figure out how this 'issue' can occur, we lack details, e.g. debugger screenshots, trace, test case that we can reproduce.

We have FoxinCloud applications in production using SET FILTER without the issue you seem to report.


Thank you for the reply. However it is not enlightening me; I already understood about stateless. Every request must be accompanied by a recreation of all data by me. The whole point, as I understood, of FiC and data was that I could open tables, views, cursors, etc. on a form like I did in VFP, and FiC would manage the maintaining of the data with each request while the form is 'open".

I also understand that resetting a recordsouirce requires resetting all the column properties. That is hundreds of lines of code. In VFP there is an easy workaround for that, but not in FiC.

I also understand that I can requery views.

Unfortunately none of that answers my main question. I simply need to issue a SET FILTER TO against the currently open table. I can do all kinds of operations against tables and FiC properly restores the datasession. But set filter to causes the datasessions to get mixed up.


In any web application, data session needs be 'reconstructed', or 'restored' on each user request.
wConnect's basic principle is to always OPEN DATABASE and USE tables/views at the beginning of the request, and close them at the end.
This is called a 'stateless' server: each request writes on a new blank page.

FoxInCloud makes no exception to that principle, though it implements it slightly differently, very similar to regular form operation:

1- awFrm.Load() and/or DataEnvironment USE tables and views, probably NODATA

Form.Load() is executed once for all users, when the form instance is created for the server lifetime.
No difference with regular app operation: as .Load() accepts no parameter, coding user-based variations is very unlikely.

2- With Form.Init(parms) you can requery the views based on some parameters.
This only thing to take care of is to replace

parm1=value1
parm2=value2
Requery(myView)

by
thisForm.wViewParmSet(myView, 'parm1', value1)
thisForm.wViewParmSet(myView, 'parm2', value2, .T.) && .T. triggers the actual requery()

This way FAS knows the view's parameters names and values, and is able to restore the view in the same state when user comes back for a new request.

Form.Init() is executed each time a user first needs a form, exactly like in regular LAN operation;
- parameters are passed as in normal LAN operation;
- .Refresh() is executed as in normal LAN operation.
The only difference is that the .Show() is not executed in Web mode. But awFrm.wFormShow() is executed, you can move your code there, and call this.wFormShow() from .Show().

3- awFrm.wUserSet(userID) allows you to adapt the form environment (including data) to user's profile - e.g. you may reUSE different tables or views based on userID, like in your scenario.
Care must just be taken with grids:

Grid.RecordSource = ''
USE IN commonAlias
USE currentUserTable/View ALIAS commonAlias
Grid.RecordSource = 'commonAlias'

In this scenario is when you have a Grid with dynamically populated columns (not in the Class/Form designer) - As columns are destroyed when clearing Grid.RecordSource, you need to restore everything like .Header.Caption, .CurrentControl, etc.
[by the way, I think we could create a standard method for reUSEing an alias with a different table/view and take care of Grid(s).RecordSource and .Columns definitions]

awFrm.wUserSet(userID) is called at the very beginning of each request, before form state is restored, thus before any user event is executed.
awFrm.wUserGet() is called at the very end of each request
[All this can be seen in awAJAX.FormRequest() source code.]

You would probably move to awFrm.wUserSet(userID) the code you usually run in Form.Init() based on user ID.

This is a straight application of the 'stateless principle' we recalled at the beginning of this post: everything user-dependent must be restored on each request.

HTH,


there needs to be some way of emulating what Load does. for multi data sets, you want to initialize grid data sources before the grid initializes. if you have a private data session in the form, I see no way to do this. You can now create a data source in Load and update it in init, but that does not help this issue. I see no place to ever create a grid data source after the initial Load without a whole bunch of manual coding in the Init.

Multi data sets rely typically on the fact that there are X copies of the complete data set, each located in a unique location, but with the exact same data names and structures. Like deciding to drive a car down Highyway 1 or a parallel highway called Highway 1. Once on the highway, the car functions exactly the same. The 2 highways are parallel and never meet. Once on one of them you are committed to staying on that road.

Since forms are instatiated only once, it is like only having one highway. Therefore in the Init we have to build a new highway as we go by manually creating the grid. Yuck,
















© 1996-2024