Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-10

WebData

22 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Leonardo M. Ramé

Hi, I was reading /packages/fcl-web/src/webdata/readme.txt and tried to test it, and created an TFPWebProviderDataModule, with an database connection, joined to a TSqlQuery, TSqlTransaction, and a Datasource, then added a TSQLDBWebDataProvider linking it to the datasource.

The cgi executable name is tarjeta.cgi, the TFPwebProviderDataModule is named "clientesProviderDM" and the TSQLWebDataProvider's name is "SQLDBWebDataProvider1". when I call it with this url, it gives en Access Violation without any hint about the problem that's causing it.

According to the readme.txt, this should be the url I have to call to execute this provider:

http://localhost/cgi-bin/tarjeta.cgi/clientesProviderDM/SQLDBWebDataProvider1

I attached my project to let you check it.

Leonardo M. Ram? http://leonardorame.blogspot.com -------------- next part -------------- A non-text attachment was scrubbed... Name: tarjeta.tar.gz Type: application/octet-stream Size: 20480 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20101010/aeb79c40/attachment-0001.obj>

Reply by email

Michael Van Canneyt
to Leonardo M. Ramé
Leonardo M. Ram? wrote 14 lines
Hi, I was reading /packages/fcl-web/src/webdata/readme.txt and tried to test it, and created an TFPWebProviderDataModule, with an database connection, joined to a TSqlQuery, TSqlTransaction, and a Datasource, then added a TSQLDBWebDataProvider linking it to the datasource. The cgi executable name is tarjeta.cgi, the TFPwebProviderDataModule is named "clientesProviderDM" and the TSQLWebDataProvider's name is "SQLDBWebDataProvider1". when I call it with this url, it gives en Access Violation without any hint about the problem that's causing it. According to the readme.txt, this should be the url I have to call to execute this provider: http://localhost/cgi-bin/tarjeta.cgi/clientesProviderDM/SQLDBWebDataProvider1

Actually, it should be

http://localhost/cgi-bin/tarjeta.cgi/clientesProviderDM/SQLDBWebDataProvider1/Read

to read the data.

I will check your .

Reply by email

Leonardo M. Ramé
to Michael Van Canneyt
Michael Van Canneyt wrote 24 lines
On Sun, 10 Oct 2010, Leonardo M. Ram? wrote: >Hi, I was reading /packages/fcl-web/src/webdata/readme.txt and tried to >test it, and created an TFPWebProviderDataModule, with an database >connection, joined to a TSqlQuery, TSqlTransaction, and a Datasource, >then added a TSQLDBWebDataProvider linking it to the datasource. > >The cgi executable name is tarjeta.cgi, the TFPwebProviderDataModule is >named "clientesProviderDM" and the TSQLWebDataProvider's name is >"SQLDBWebDataProvider1". when I call it with this url, it gives en >Access Violation without any hint about the problem that's causing it. > >According to the readme.txt, this should be the url I have to call to >execute this provider: > >http://localhost/cgi-bin/tarjeta.cgi/clientesProviderDM/SQLDBWebDataProvider1 Actually, it should be http://localhost/cgi-bin/tarjeta.cgi/clientesProviderDM/SQLDBWebDataProvider1/Read to read the data.

Yes, I used that, and I get the same Access Violation.

I will check your project at noon. Michael.

Thanks.

Reply by email

waldo kitty
to Leonardo M. Ramé
Leonardo M. Ram? wrote 14 lines
On 2010-10-14 13:00:29 -0300, Leonardo M. Ram? wrote: > On 2010-10-11 10:47:05 -0300, Leonardo M. Ram? wrote: > > >>> I will check your project at noon. >>> >>> Michael. >> >> Thanks. >> > > Hi Michael, did you check my example? > Nevermind, I found the solution.

*the* solution or /a/ solution?

Reply by email

Leonardo M. Ramé
to waldo kitty
waldo kitty wrote 18 lines
On 10/14/2010 19:47, Leonardo M. Ram? wrote: >On 2010-10-14 13:00:29 -0300, Leonardo M. Ram? wrote: >>On 2010-10-11 10:47:05 -0300, Leonardo M. Ram? wrote: >> > >>>>I will check your project at noon. >>>> >>>>Michael. >>> >>>Thanks. >>> >> >>Hi Michael, did you check my example? >> > >Nevermind, I found the solution. *the* solution or /a/ solution?

In this case, I think is *the* solution, because without it, the module just don't work.

The problem was that I was missing placing an ExtJSJSONDataFormatter, and a ExtJSJsonWebdataInputAdaptor, both linked to the TFPWebProviderDataModule's ContentProducer and InputAdaptor properties.

It was easy to find it after I noted there was an "wmdebug" define turned off in sqldbwebdata.pp, I turned it on and compiled. When I'd run the code again, the Access Violation I was getting was more informative with a detailed stacktrace who pointed me to fpwebdata.pp, line 828, where I saw the need of a TCustomWebDataInputAdaptor.

Reply by email

Michael Van Canneyt
to Leonardo M. Ramé
Leonardo M. Ram? wrote 32 lines
On 2010-10-14 21:22:59 -0400, waldo kitty wrote: > On 10/14/2010 19:47, Leonardo M. Ram? wrote: >> On 2010-10-14 13:00:29 -0300, Leonardo M. Ram? wrote: >>> On 2010-10-11 10:47:05 -0300, Leonardo M. Ram? wrote: >>> > >>>>> I will check your project at noon. >>>>> >>>>> Michael. >>>> >>>> Thanks. >>>> >>> >>> Hi Michael, did you check my example? >>> >> >> Nevermind, I found the solution. > > *the* solution or /a/ solution? > In this case, I think is *the* solution, because without it, the module just don't work. The problem was that I was missing placing an ExtJSJSONDataFormatter, and a ExtJSJsonWebdataInputAdaptor, both linked to the TFPWebProviderDataModule's ContentProducer and InputAdaptor properties. It was easy to find it after I noted there was an "wmdebug" define turned off in sqldbwebdata.pp, I turned it on and compiled. When I'd run the code again, the Access Violation I was getting was more informative with a detailed stacktrace who pointed me to fpwebdata.pp, line 828, where I saw the need of a TCustomWebDataInputAdaptor.

Exactly. Glad you found it.

My apologies for not getting back to you earlier, it's been very busy days lately :(

You also don't need the query component if you use the TSQLDBWebdataProvider, and definitely do not activate it, it serves no purpose (but I suspect this is the result of you trying to get it to work).

Attached a screenshot of what it looks like in my browser after I dropped JSON formatters and input provider on the module - check out the URL I used. (changed the query and database name of course)

I will change the implementation so it will give a more informative error, because like this, people will be confused - just like you were.

Michael.

Reply by email

Michael Van Canneyt
to Michael Van Canneyt

Forgot the screenshot.

Michael.

Michael Van Canneyt wrote 54 lines
On Thu, 14 Oct 2010, Leonardo M. Ram? wrote: > On 2010-10-14 21:22:59 -0400, waldo kitty wrote: >> On 10/14/2010 19:47, Leonardo M. Ram? wrote: >>> On 2010-10-14 13:00:29 -0300, Leonardo M. Ram? wrote: >>>> On 2010-10-11 10:47:05 -0300, Leonardo M. Ram? wrote: >>>> > >>>>>> I will check your project at noon. >>>>>> >>>>>> Michael. >>>>> >>>>> Thanks. >>>>> >>>> >>>> Hi Michael, did you check my example? >>>> >>> >>> Nevermind, I found the solution. >> >> *the* solution or /a/ solution? >> > > In this case, I think is *the* solution, because without it, the module > just don't work. > > The problem was that I was missing placing an ExtJSJSONDataFormatter, and a > ExtJSJsonWebdataInputAdaptor, both linked to the TFPWebProviderDataModule's > ContentProducer and InputAdaptor properties. > > It was easy to find it after I noted there was an "wmdebug" define turned > off in sqldbwebdata.pp, I turned it on and compiled. When I'd run the code > again, the Access Violation I was getting was more informative with a > detailed stacktrace who pointed me to fpwebdata.pp, line 828, where I saw > the need of a TCustomWebDataInputAdaptor. Exactly. Glad you found it. My apologies for not getting back to you earlier, it's been very busy days lately :( You also don't need the query component if you use the TSQLDBWebdataProvider, and definitely do not activate it, it serves no purpose (but I suspect this is the result of you trying to get it to work). Attached a screenshot of what it looks like in my browser after I dropped JSON formatters and input provider on the module - check out the URL I used. (changed the query and database name of course) I will change the implementation so it will give a more informative error, because like this, people will be confused - just like you were. Michael.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: webdata.png
Type: image/png
Size: 153169 bytes
Desc:
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20101015/b7edb64e/attachment-0001.png>

Reply by email

Leonardo M. Ramé
to Michael Van Canneyt: Exactly. Glad you found it. My apologies for not getting back to you earlier, it's been…
Michael Van Canneyt wrote 19 lines
Exactly. Glad you found it. My apologies for not getting back to you earlier, it's been very busy days lately :( You also don't need the query component if you use the TSQLDBWebdataProvider, and definitely do not activate it, it serves no purpose (but I suspect this is the result of you trying to get it to work). Attached a screenshot of what it looks like in my browser after I dropped JSON formatters and input provider on the module - check out the URL I used. (changed the query and database name of course) I will change the implementation so it will give a more informative error, because like this, people will be confused - just like you were. Michael.

Thanks, I love this package, it makes so easy to create the server side part of ExtJs apps. Until now I had to create the JSon by hand (using fcl-json, of course).

After removing the TSqlQuery and TSQLTransaction components from my app, a new question came to my mind, in the case of complex inserts/updates that involves more than one database table, is it possible to use transactions?.

Reply by email

Michael Van Canneyt
to Leonardo M. Ramé
Leonardo M. Ram? wrote 24 lines
On 2010-10-15 09:38:12 +0200, Michael Van Canneyt wrote: > > > Exactly. Glad you found it. > > My apologies for not getting back to you earlier, it's been very busy days > lately :( > > You also don't need the query component if you use the > TSQLDBWebdataProvider, and definitely do not activate it, it serves no > purpose (but I suspect this is the result of you trying to get it to work). > > Attached a screenshot of what it looks like in my browser after I dropped > JSON formatters and input provider on the module - check out the URL I used. > (changed the query and database name of course) > > I will change the implementation so it will give a more informative error, > because like this, people will be confused - just like you were. > > Michael. Thanks, I love this package, it makes so easy to create the server side part of ExtJs apps. Until now I had to create the JSon by hand (using fcl-json, of course).

That's because I am very lazy, I create components to do the work for me =-)

Show quoted text 5 lines
After removing the TSqlQuery and TSQLTransaction components from my app, a new question came to my mind, in the case of complex inserts/updates that involves more than one database table, is it possible to use transactions?.

Hm. Not if you use the TSQLDBWebDataProvider. To do that, you would have to use TSQLSuery and a regular TWebDataProvider, and hook into the Before/after post events of the TSQLQuery.

But I'm certainly open for suggestions for improvements.

Michael.

Reply by email

Leonardo M. Ramé
to Michael Van Canneyt
Michael Van Canneyt wrote 12 lines
>After removing the TSqlQuery and TSQLTransaction components from my app, >a new question came to my mind, in the case of complex inserts/updates >that involves more than one database table, is it possible to use >transactions?. Hm. Not if you use the TSQLDBWebDataProvider. To do that, you would have to use TSQLSuery and a regular TWebDataProvider, and hook into the Before/after post events of the TSQLQuery. But I'm certainly open for suggestions for improvements. Michael.

Well, It's not an issue at all, I could create a stored procedure in charge of receiveing the params from the dataprovider, then adapt them to their respective tables. It's not an issue because I usually work with Firebird and PostgreSql, and they have stored procedures.

I ask this because I'm thinking of adding a new layer of abstraction by letting the TFPWebProviderDataModule load a configuration from, say, an XML file with the list of Providers and its Select, Insert, Update, and Delete statements, like this:

<Module name="ClientesProvider">
<Provider name="all-customers">
<Select>select * from customers</Select>
</Provider>
<Provider name="one-customer">
<Select>
select * from customers where IdCustomer=:IdCustomer </Select>
<Insert>
insert into customers(Name, Age)
values(:Name, :Age)
</Insert>
<Update>
update customers set Name=:Name, Age=:Age
where IdCustomer=:IdCustomer
</Update>
<Delete>
delete from customers where IdCustomer=:IdCustomer </Delete>
</Provider>
</Module>

With this data, the cgi/fcgi app could dynamically create the TPWebProviderDataModule and everything else.

What do you think about this?

Reply by email

Michael Van Canneyt
to Leonardo M. Ramé
Leonardo M. Ram? wrote 23 lines
On 2010-10-15 14:24:48 +0200, Michael Van Canneyt wrote: >> After removing the TSqlQuery and TSQLTransaction components from my app, >> a new question came to my mind, in the case of complex inserts/updates >> that involves more than one database table, is it possible to use >> transactions?. > > Hm. Not if you use the TSQLDBWebDataProvider. To do that, you would > have to use TSQLSuery and a regular TWebDataProvider, and hook into > the Before/after post events of the TSQLQuery. > > But I'm certainly open for suggestions for improvements. > > Michael. Well, It's not an issue at all, I could create a stored procedure in charge of receiveing the params from the dataprovider, then adapt them to their respective tables. It's not an issue because I usually work with Firebird and PostgreSql, and they have stored procedures. I ask this because I'm thinking of adding a new layer of abstraction by letting the TFPWebProviderDataModule load a configuration from, say, an XML file with the list of Providers and its Select, Insert, Update, and Delete statements, like this:

Aha !! I have this on my todo list as well :-)

Only I wasn't going to use XML, but .INI format.
In fact the file format is irrelevant; I planned to do it in 2 levels:

TFileWebDataProvider
+- TIniFileWebdataProvider

I was going to put it in a separate component, but make the TFPWebProviderDataModule aware of this component. Gives more options.

Michael.

Reply by email

ABorka
to Leonardo M. Ramé: Well, It's not an issue at all, I could create a stored procedure in charge of receiveing…
Leonardo M. Ram? wrote 50 lines
On 2010-10-15 14:24:48 +0200, Michael Van Canneyt wrote: >> After removing the TSqlQuery and TSQLTransaction components from my app, >> a new question came to my mind, in the case of complex inserts/updates >> that involves more than one database table, is it possible to use >> transactions?. > > Hm. Not if you use the TSQLDBWebDataProvider. To do that, you would > have to use TSQLSuery and a regular TWebDataProvider, and hook into > the Before/after post events of the TSQLQuery. > > But I'm certainly open for suggestions for improvements. > > Michael. Well, It's not an issue at all, I could create a stored procedure in charge of receiveing the params from the dataprovider, then adapt them to their respective tables. It's not an issue because I usually work with Firebird and PostgreSql, and they have stored procedures. I ask this because I'm thinking of adding a new layer of abstraction by letting the TFPWebProviderDataModule load a configuration from, say, an XML file with the list of Providers and its Select, Insert, Update, and Delete statements, like this: <Module name="ClientesProvider"> <Provider name="all-customers"> <Select>select * from customers</Select> </Provider> <Provider name="one-customer"> <Select> select * from customers where IdCustomer=:IdCustomer </Select> <Insert> insert into customers(Name, Age) values(:Name, :Age) </Insert> <Update> update customers set Name=:Name, Age=:Age where IdCustomer=:IdCustomer </Update> <Delete> delete from customers where IdCustomer=:IdCustomer </Delete> </Provider> </Module> With this data, the cgi/fcgi app could dynamically create the TPWebProviderDataModule and everything else. What do you think about this?

But you can do these things already, I believe.
I had multiple tables and some simple access rights to different people so my SQL statements had to be different for everyone to get different records from the tables.

What I did is, I started from the first demo example found in fcl-web/examples/webdata/demo/

and created ONE action called "CRUD" that handles all the crud request from the extjs clients. However, I am passing some additional parameters that specifies which table is to be used and what needs to be done (Create, Read, Update, Delete). From the session I got who is the user, so I was able to prepare the proper SQL statements myself.

For example, the extjs data store proxy looks like this in the client side extjs:
===========
var myproxy = new Ext.data.HttpProxy ( {
api : {
//XML
// create: GetCGIURL('/CRUD?format=xml&t=0&d=0'), // read: GetCGIURL('/CRUD?format=xml&t=0&d=1'), // update: GetCGIURL('/CRUD?format=xml&t=0&d=2'), // destroy: GetCGIURL('/CRUD?format=xml&t=0&d=3') //end of XML
//JSON
create: GetCGIURL('/CRUD?t=0&d=0'),
read: GetCGIURL('/CRUD?t=0&d=1'),
update: GetCGIURL('/CRUD?t=0&d=2'),
destroy: GetCGIURL('/CRUD?t=0&d=3')
//end of JSON
}

   });

==========
You can see that I am passing the "t" and "d" additional parameters. "t" can be the table/database to use and "d" can be the action to be performed (create, read, update, delete), etc. In the web module "crud" action I just need a case statement for the different SQL statements based on these passed parameters.
Of course it is more complicated to build the actually executed SQL statements in my app, because I also process the sort order, the number of records to be returned, and have some record filtering coming form the extjs client, and as mentioned above, based on the user different records needs to be returned, etc.

Plus, I created some additional actions in the webmodule for other things like a "keepalive" call from the client so the session is not closed if the user uses the client for a long time but there are no server calls to refresh the session, and so on for other things and responses, web pages with templates, like login/logout, etc.

AB

Reply by email

Leonardo M. Ramé
to Michael Van Canneyt: Aha !! I have this on my todo list as well :-) Only I wasn't going to use XML, but .INI…
Michael Van Canneyt wrote 26 lines
> >Well, It's not an issue at all, I could create a stored procedure in >charge of receiveing the params from the dataprovider, then adapt them to >their respective tables. It's not an issue because I usually work with >Firebird and PostgreSql, and they have stored procedures. > >I ask this because I'm thinking of adding a new layer of abstraction by >letting the TFPWebProviderDataModule load a configuration from, say, an >XML file with the list of Providers and its Select, Insert, Update, and >Delete statements, like this: Aha !! I have this on my todo list as well :-) Only I wasn't going to use XML, but .INI format. In fact the file format is irrelevant; I planned to do it in 2 levels: TFileWebDataProvider +- TIniFileWebdataProvider I was going to put it in a separate component, but make the TFPWebProviderDataModule aware of this component. Gives more options. Michael.

I attached a proof of concept, take a look and comment.

Leonardo M. Ram? http://leonardorame.blogspot.com -------------- next part -------------- A non-text attachment was scrubbed... Name: test.tar.gz Type: application/octet-stream Size: 4686 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20101015/e52a92cd/attachment.obj>

Reply by email

ABorka
to Joshua Lim
Joshua Lim wrote
Hi, fetching data from the database aside, how about web session management for a multiple user website? Web scripts like php come with session management built-in. What is the best way to do that using pascal? Thanks.

Also built-in into fpweb (the cookie sessions management that is).

You can see examples under /lazarus/components/fpweb/demo/session and
/lazarus/components/fpweb/demo/fptemplate/sessions/cookiesessions... /lazarus/components/fpweb/demo/fptemplate/sessions/urlsessions...

AB

Reply by email

Michael Van Canneyt
to ABorka
ABorka wrote 12 lines
On 10/15/2010 12:23, Joshua Lim wrote: > Hi, fetching data from the database aside, how about web session > management for a multiple user website? Web scripts like php come with > session management built-in. What is the best way to do that using > pascal? Thanks. Also built-in into fpweb (the cookie sessions management that is). You can see examples under /lazarus/components/fpweb/demo/session and /lazarus/components/fpweb/demo/fptemplate/sessions/cookiesessions... /lazarus/components/fpweb/demo/fptemplate/sessions/urlsessions...

Aha. I didn't know about those. Good to know :-)

On my todo list is still storing the cookies in a database, because ini files are nice, but rather slow.
Should be implemented by christmas.

Michael.

Reply by email

Michael Van Canneyt
to Leonardo M. Ramé: I attached a proof of concept, take a look and comment. Leonardo M. Ram?…
Leonardo M. Ram? wrote 29 lines
On 2010-10-15 15:06:12 +0200, Michael Van Canneyt wrote: > > >> >> Well, It's not an issue at all, I could create a stored procedure in >> charge of receiveing the params from the dataprovider, then adapt them to >> their respective tables. It's not an issue because I usually work with >> Firebird and PostgreSql, and they have stored procedures. >> >> I ask this because I'm thinking of adding a new layer of abstraction by >> letting the TFPWebProviderDataModule load a configuration from, say, an >> XML file with the list of Providers and its Select, Insert, Update, and >> Delete statements, like this: > > Aha !! I have this on my todo list as well :-) > > Only I wasn't going to use XML, but .INI format. > In fact the file format is irrelevant; I planned to do it in 2 levels: > > TFileWebDataProvider > +- TIniFileWebdataProvider > > I was going to put it in a separate component, but make the > TFPWebProviderDataModule aware of this component. Gives more > options. > > Michael. I attached a proof of concept, take a look and comment.

Seems like a very good start, some suggestions:

1. You created something which is by definition non-visual ? Why not make the TDynamicSQLWebProvider a component which you can drop on a webmodule ?

2. Having done 1, you could rework TModuleProvider so it recognizes and uses a TDynamicSQLWebProvider dropped on it. (if I understand correctly, there is no need to do anything, it would be automatic if the TDynamicSQLWebProvider uses it's owner as the owner for the providers)

3. Why not create the providers on an as-needed basis ? Now you create all registered providers.
If you override the GetProvider method in TModuleProvider, you can simply create the instance you actually need.

My projects contain typically 1000+ providers.
If I would create them all in memory per connection - memory consumption would rocket sky high :-)

I would simply load the definitions - once - and then create providers on an as-needed basis.

4. You forgot the XMLprovider unit :-)
Seems like you make it a procedural interface to load the definitions. I would expect that TSqlWebDataProviders has a virtual abstract method which loads the definitions from file:

    Procedure LoadFromFile(Const AFileName : String); virtual; Abstract;
    In the case of a component, there could even be a 'FileName' property, read in the 'Loaded' method.
    then create a descendent which loads from whatever file format is fitting.

5. Advanced concept:
Why didn't you use the TFPWebDataProviderManager factory class ? (see demo5)

It is built for this kind of thing. (I currently use that at work) : you register all providers there. TFPWebProviderDataModule knows about this class and fetches a provider there on-demand. All you'd need to do is register 1 TModuleProvider instance there. This is optional of course. So in fact, there are 2 paths you could follow.

I hope all this makes sense :-)

Michael.

Reply by email

Michael Van Canneyt
to ABorka: But you can do these things already, I believe. I had multiple tables and some simple…
ABorka wrote 32 lines
On 10/15/2010 05:40, Leonardo M. Ram? wrote: > On 2010-10-15 14:24:48 +0200, Michael Van Canneyt wrote: >>> After removing the TSqlQuery and TSQLTransaction components from my app, >>> a new question came to my mind, in the case of complex inserts/updates >>> that involves more than one database table, is it possible to use >>> transactions?. >> >> Hm. Not if you use the TSQLDBWebDataProvider. To do that, you would >> have to use TSQLSuery and a regular TWebDataProvider, and hook into >> the Before/after post events of the TSQLQuery. >> >> But I'm certainly open for suggestions for improvements. >> >> Michael. > > Well, It's not an issue at all, I could create a stored procedure in > What do you think about this? But you can do these things already, I believe. I had multiple tables and some simple access rights to different people so my SQL statements had to be different for everyone to get different records from the tables. What I did is, I started from the first demo example found in fcl-web/examples/webdata/demo/ and created ONE action called "CRUD" that handles all the crud request from the extjs clients. However, I am passing some additional parameters that specifies which table is to be used and what needs to be done (Create, Read, Update, Delete). From the session I got who is the user, so I was able to prepare the proper SQL statements myself.

Is there any chance to put this in a kind of component that does most of the boilerplate work ? I would imagine 2 events:

OnGetConnection = Procedure (Sender : TObject; Var AConnection : TSQLConnection) of object;
OnGetQuery = Procedure (Sender : TObject; UpdateKind : TUpdateKind; SQL : TStrings); of object;

Michael.

Reply by email

ABorka
to Michael Van Canneyt
Michael Van Canneyt wrote 47 lines
On Fri, 15 Oct 2010, ABorka wrote: > On 10/15/2010 05:40, Leonardo M. Ram? wrote: >> On 2010-10-15 14:24:48 +0200, Michael Van Canneyt wrote: >>>> After removing the TSqlQuery and TSQLTransaction components from my >>>> app, >>>> a new question came to my mind, in the case of complex inserts/updates >>>> that involves more than one database table, is it possible to use >>>> transactions?. >>> >>> Hm. Not if you use the TSQLDBWebDataProvider. To do that, you would >>> have to use TSQLSuery and a regular TWebDataProvider, and hook into >>> the Before/after post events of the TSQLQuery. >>> >>> But I'm certainly open for suggestions for improvements. >>> >>> Michael. >> >> Well, It's not an issue at all, I could create a stored procedure in >> What do you think about this? > > But you can do these things already, I believe. > I had multiple tables and some simple access rights to different > people so my SQL statements had to be different for everyone to get > different records from the tables. > > What I did is, I started from the first demo example found in > fcl-web/examples/webdata/demo/ > > and created ONE action called "CRUD" that handles all the crud request > from the extjs clients. However, I am passing some additional > parameters that specifies which table is to be used and what needs to > be done (Create, Read, Update, Delete). From the session I got who is > the user, so I was able to prepare the proper SQL statements myself. > Is there any chance to put this in a kind of component that does most of the boilerplate work ? I would imagine 2 events: OnGetConnection = Procedure (Sender : TObject; Var AConnection : TSQLConnection) of object; OnGetQuery = Procedure (Sender : TObject; UpdateKind : TUpdateKind; SQL : TStrings); of object; Michael.

Yes, theoretically it can be made a bit cleaner and easier by improving the webdata components, but there are a lot of additional parameters that can come in from Extjs.
For example, I am using Extjs grids and processing the following incoming parameters when creating my SQL statements:

table(s) to use /an id number what data is needed/ operation to perform /c, r, u, d/
start /starting record/
limit /number of records to return/
sort /sort by this field, this can be tricky for calculated fields/ dir /sort order if needed: ASC DESC/
fields /filter on these fields/
query /value(s) to look for in the filtered fields/

So creating the proper SQL statements definitely involves some work for the different Extjs client grids I use. The access rights for the users for the different database records also need to be taken into account. Additionally, a separate SQL statement is needed to get the total number of records and properly replace it in the response that is returned to the Extjs client.
That is, because not all the records are returned, just the ones that fit into one grid page. With thousands plus records it is necessary, so the communication and response time is relatively fast.

AB

Reply by email

Leonardo M. Ramé
to Michael Van Canneyt: Seems like a very good start, some suggestions: 1. You created something which is by…
Michael Van Canneyt wrote 41 lines
>I attached a proof of concept, take a look and comment. Seems like a very good start, some suggestions: 1. You created something which is by definition non-visual ? Why not make the TDynamicSQLWebProvider a component which you can drop on a webmodule ? 2. Having done 1, you could rework TModuleProvider so it recognizes and uses a TDynamicSQLWebProvider dropped on it. (if I understand correctly, there is no need to do anything, it would be automatic if the TDynamicSQLWebProvider uses it's owner as the owner for the providers) 3. Why not create the providers on an as-needed basis ? Now you create all registered providers. If you override the GetProvider method in TModuleProvider, you can simply create the instance you actually need. My projects contain typically 1000+ providers. If I would create them all in memory per connection - memory consumption would rocket sky high :-) I would simply load the definitions - once - and then create providers on an as-needed basis. 4. You forgot the XMLprovider unit :-) Seems like you make it a procedural interface to load the definitions. I would expect that TSqlWebDataProviders has a virtual abstract method which loads the definitions from file: Procedure LoadFromFile(Const AFileName : String); virtual; Abstract; In the case of a component, there could even be a 'FileName' property, read in the 'Loaded' method. then create a descendent which loads from whatever file format is fitting. 5. Advanced concept: Why didn't you use the TFPWebDataProviderManager factory class ? (see demo5) It is built for this kind of thing. (I currently use that at work) : you register all providers there. TFPWebProviderDataModule knows about this class and fetches a provider there on-demand. All you'd need to do is register 1 TModuleProvider instance there. This is optional of course. So in fact, there are 2 paths you could follow. I hope all this makes sense :-) Michael.

Thanks, I'll try to implement this next week.

Reply by email