Sign in Join

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

Mailing lists / fpc-pascal / 2010-06

The new book: "WEB and database programming with fpc and Lazarus for newbies and professionals"

8 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Burkhard Carstens

.. anybody knows where I can buy it? ;-)

I just started my first web application and .. well .. the basics work, but I have the feeling, I'm doing it the wrong way.

[Warning: Looong post]

What it's about:
It's a time-punch machine that registers when I'm working on which project. Data is stored in postgres tables and shall be reported preferably as nice pdf files per customer listing the projects and the times spent on them (and off course the money I'd like to have for that..)

Unfortunately, I'm new to all related topics.:
The only experience in DB programming is about 10 or 12 years ago (writing this time-punch machine as desktop app in Delphi <= 6). Played with fpc/laz and postgres a few times since then, but never got anything working.
There is some knowledge about XML and the concept of DOM but only basic html stuff and absolutely nothing about css and JavaScript, ajax, extjs, jQuery, JSON... well, there was nothing when I started a week ago.

This is my journey so far:
(all done with fpc and lazarus from trunk)

chapter 1 - Database programming

First, I created a desktop app to play with the database. All the DB components on a DataModule and some DBGrid, DBNavigator on a form.
* First problem:
Data changes in the grid don't get to the database.
* Solution:
in SQLQueryTimes.OnAfterPost add:

   SQLQueryTimes.ApplyUpdates;
   SQLTransactionTimes.CommitRetaining;

* Next problem:
When doing "insert, post, edit (the inserted row), post" the data doesn't get to DB.
* Found reason:
The primary key is an auto-increment. It is added by postgres when inserting the record, but not reported back. Therefore, the following Update statement uses (probably?) "UPDATE .. WHERE times_id = NULL .." while times_id actually got a non-NULL value in the DB. So the update statement does nothing, not even reporting an error.
* Solution:
none. According to http://bugs.freepascal.org/view.php?id=16076 this is not yet implemented.
* Workaround:
Do a "refresh" after the "insert, post". Downside: The cursor is lost, i.e. you have to navigate back to the just inserted record before further editing.

* Next Problem:
The "projects" are stored in a second table with id, name and some other info. Now I'd like to see (and deal with) the projects name instead of its ID in the times_grid. Some keywords came to memory: "Master/ Detail", "Lookup" and "JOIN" .. at this point, I decided to order some books:
"SQL von Kopf bis Fuss" ("Head first SQL"), a funny book, though a matter of taste whether one likes fun when searching technical information (I do). Sadly, the examples all refer to mySQL and pretty often there is a note like "not all RDBMS understand this syntax".. but still, very helpfull book.
"PostgreSQL", pretty dry admin doku ..
"Lazarus", very nice book, covering loads of topics. While it shed quite some light into my understanding of the database components, it unfortunately ends right there where my quest begins .. at least regarding WEB and DB programming .. hence the topic of this post :-)

* Solution:
none, at least not the way I intended. Seems like DBGrid is not (yet) able to offer a LookupCombo in a cell like Delphi does. (After I found out, I also saw the related bug report .. ) I got something working with a separate DBLookupList next to the grid ..

At this point, I stopped dealing with the desktop GUI and went over to fpWeb stuff. I just liked the idea of "open dataset, select/insert/ update, close dataset". SELECTing the data using a INNER JOIN statement did what I need for displaying ... and editing .. well that's still far away, it seems.

chapter 2 - web programming

Here is what I did and learn so far:
* New/Project/CGI Application, save as "cgitimes"
* Add action "main" (code and template mainly taken from the "listrecords" cgi example and adapted).
* Add action "switch"
* "main" produces a page with a status like this:

either
| working on {project name}
| click to pause or call it a day (href=switch?NewProjectId=0) or
| Inactive
| click to continue with {last_active_project_name} | (href=switch?NewProjectId=last_active_project_id)

and a table:
| .. or switch to a different project:
| project_name (href=switch?NewProjectId=1)
| project_name (href=switch?NewProjectId=2)
...

Now when clicking one of the links, I get to the "switch" page. The action does to the DB what it should do but I didn't intend to see a separate page. I only wanted the action to act on DB and refresh the main page.
So I tried to add a http-equiv="Refresh" content="3,URL=main" to AResponse.CustomHeaders and went crazy because it didn't work. Actually, setting any other header stuff (ContentType, ContentEncoding) also didn't work .. at least it didn't show up on "View document source" in the browser. ( hey, don't laugh so loud! ) It took me some time to realize that my web module descends from TSessionHTTPModule and not from any TxxHTMLModule .. so the headers I tried to change were actally HT*TP* headers and not HT*ML* headers.. This confusion was partly due to the fact that I thought, a HTML document needs a <head> .. </head> section but none of the templates got one. So I assumed, this is added automatically... After this enlightenment, I got further. Just adding a "<head> .. Refresh .. URL=main ..</head>" via "AResponse.contents.add" did the job. Still, this didn't look or feel right.
Back to the cgi chapter in Lazarus book, I saw the "Location" field in the HTTP header and tried setting
"AResponse.Location:=ARequest.Referer;" in the switch action handler. Heureka! That did the job! Still I don't know, wheter this is the correct way or not and whether I should return a specific HTTP status code (201, 205, 302, 303 or 307) ?

Now I want more functionality: edit field to add a note to the current time_record on main page, a way to add new projects (probably a separate page?), another page to manipulate the times table in a grid and of course: reports, reports, reports (Is it possible to use the LazReport in a cgi)?

So how to proceed? Should I change my FPWebModule to a THTMLModule? What happens, when I have multiple T[FPWeb,HTML]Modules in my cgi? Now I call it with http://myhost/cgi-bin/cgitimes/main (or even without the "main"). With multiple modules, I'd need to select the module like http://myhost/cgi-bin/cgitime/MODULE_1/main ?

After installing the lazwebextra package, there are lots of components (THTMLxxxProducers, TxxWebDataYY) .. well, precisely, there are 21 components on the fpWeb page + 5 different DataModules in file/new/module ... how are those supposed to gear into each other? which components must be placed on what kind of module?

Looking at the fpWeb examples as well as the webdesign package from Joost (which installs another DataModule + countless components), I realized that both use some JavaScript lib, namely "ExtJS" and "jQuery". So it seems, a decent interface can only be done using JavaScript. Ok .. I usually have this turned off in my browser but I'm willing to change my mind on this.
On a first glance, ExtJS looks somewhat cooler, but it's GPL licensed. Does that mean, I need to release the source of my cgi program, if I decided to distribute it? While it is irrelevant for this (in-house, toy) project, I'd prefer to learn the "right" one, i.e. the one I can also use in comercial closed source projects.

After spending hours on www.w3c.org and www.w3schools.com, extjs.com (now sencha.com) and jquery.com reading a lot about html, dhtml, javascript and checking out some docs and examples about extjs and jquery, I got the feeling that all these pieces could form a nice picture .. just I still couldn't see it.
Then I found this artice and now all of the sudden, everything makes a lot more sense:
http://www.ibm.com/developerworks/web/library/wa-ajaxintro1.html

Guess, it might be good to start from ground up (now that I found ground):
Make some nice html files with some JavaScript functions, which just "call" my cgi via XmlHTTPRequest to insert something into the DB or return some results or tiny html snippets.

Any hints and suggestions are welcome!

Writing this mail helped me to clean up my mind. I could have deleted it after writing, but I thought, it probably helps some other newbie and/or maybe motivates someone (Michael, Joost ?) to start writing "the new book" ;-)

However, thanks for another great toolset: fpWeb ! It looks really promising.

Best regards
Burkhard

Reply by email

Michael Van Canneyt
to Burkhard Carstens
Burkhard Carstens wrote 15 lines
.. anybody knows where I can buy it? ;-) After spending hours on www.w3c.org and www.w3schools.com, extjs.com (now sencha.com) and jquery.com reading a lot about html, dhtml, javascript and checking out some docs and examples about extjs and jquery, I got the feeling that all these pieces could form a nice picture .. just I still couldn't see it. Then I found this artice and now all of the sudden, everything makes a lot more sense: http://www.ibm.com/developerworks/web/library/wa-ajaxintro1.html Guess, it might be good to start from ground up (now that I found ground): Make some nice html files with some JavaScript functions, which just "call" my cgi via XmlHTTPRequest to insert something into the DB or return some results or tiny html snippets.

This is exactly how I am programming web with FPC.

FPC is used for the server. You'll see all components I use in fcl-web/src. The client is programmed completely in ExtJS. The FPC components have been built so they can work with any Javascript framework, but ExtJS has been worked out best - simply because I use it. Currently there are 3 important areas I am working in:
- SOAP calls using WST. fpweb can be used to route and handle SOAP transport for WST. The code has been donated to WST.
- serving data to a (currently extjs) datastore in Javascript. (see fcl-web/src/webdata)
- 'simple' JSON-RPC programming: JSON-RPC versions 1 and 2 are supported. As an extra, I especially made sure that the Ext.Direct variant is well supported. (see fcl-web/jsonrpc) I'm still working on a Ext.Direct wrapper around WST.

Joost uses jQuery and some Javascript components built around it. I'm sure that with his help, the ExtJS components can be modified to support jquerygrid and whatnot.

4 areas are open for work:
1. File cache mechanism in fcl-web.
2. a kind of intraweb/extpascal/unigui framework.
I have the basic plans ready. Lazarus has the IDE support for it. (joost uses it in his webdesign package)
3. IIS module support.
4. Translation of Pascal to Javascript. The basics for this are in the FCL: fcl-passrc and fcl-js. What is needed is conversion of one syntax tree to another. Not very hard, but tedious and a lot of work.

I hope this makes sense and gives you some ideas of the directions you can take. If there is any area you might want to work on, let me know, I'm willing to help.

Michael.

Reply by email

Martin Schreiber
to Burkhard Carstens: .. anybody knows where I can buy it? ;-) I just started my first web application and ..…

On Wednesday 16 June 2010 20:10:09 Burkhard Carstens wrote:

This is for MSEide+MSEgui:

Show quoted text 12 lines
chapter 1 - Database programming First, I created a desktop app to play with the database. All the DB components on a DataModule and some DBGrid, DBNavigator on a form. * First problem: Data changes in the grid don't get to the database. * Solution: in SQLQueryTimes.OnAfterPost add: SQLQueryTimes.ApplyUpdates; SQLTransactionTimes.CommitRetaining;

Activate tmsesqlquery.controller.options dso_autoapply and dso_autocommitret.

Show quoted text 12 lines
* Next problem: When doing "insert, post, edit (the inserted row), post" the data doesn't get to DB. * Found reason: The primary key is an auto-increment. It is added by postgres when inserting the record, but not reported back. Therefore, the following Update statement uses (probably?) "UPDATE .. WHERE times_id = NULL .." while times_id actually got a non-NULL value in the DB. So the update statement does nothing, not even reporting an error. * Solution: none. According to http://bugs.freepascal.org/view.php?id=16076 this is not yet implemented.

Use a sequence generator in the DB in order to build the primary key value. Place a tsequencelink (tab DBf) into the datamodule, select database datasource and datafield, fill in the 'sequencename' property.

Show quoted text 6 lines
* Next Problem: The "projects" are stored in a second table with id, name and some other info. Now I'd like to see (and deal with) the projects name instead of its ID in the times_grid. Some keywords came to memory: "Master/ Detail", "Lookup" and "JOIN" ..

[...]

Show quoted text 7 lines
* Solution: none, at least not the way I intended. Seems like DBGrid is not (yet) able to offer a LookupCombo in a cell like Delphi does. (After I found out, I also saw the related bug report .. ) I got something working with a separate DBLookupList next to the grid ..

Use tdbwidgetgrid (tab DBe), place a tdbenumeditdb into the lookup column (tab DBe). Alternative for better performance with very big lookup datasets: tdbenumeditlb (tab DBe) and tdblookupbuffer (tab DB).

Martin

Reply by email

Burkhard Carstens
to Michael Van Canneyt: This is exactly how I am programming web with FPC. FPC is used for the server. You'll see…
Michael Van Canneyt wrote 32 lines
On Wed, 16 Jun 2010, Burkhard Carstens wrote: > .. anybody knows where I can buy it? ;-) > After spending hours on www.w3c.org and www.w3schools.com, > extjs.com (now sencha.com) and jquery.com reading a lot about html, > dhtml, javascript and checking out some docs and examples about > extjs and jquery, I got the feeling that all these pieces could > form a nice picture .. just I still couldn't see it. > Then I found this artice and now all of the sudden, everything > makes a lot more sense: > http://www.ibm.com/developerworks/web/library/wa-ajaxintro1.html > > Guess, it might be good to start from ground up (now that I found > ground): > Make some nice html files with some JavaScript functions, which > just "call" my cgi via XmlHTTPRequest to insert something into the > DB or return some results or tiny html snippets. This is exactly how I am programming web with FPC. FPC is used for the server. You'll see all components I use in fcl-web/src. The client is programmed completely in ExtJS. The FPC components have been built so they can work with any Javascript framework, but ExtJS has been worked out best - simply because I use it. Currently there are 3 important areas I am working in: - SOAP calls using WST. fpweb can be used to route and handle SOAP transport for WST. The code has been donated to WST. - serving data to a (currently extjs) datastore in Javascript. (see fcl-web/src/webdata) - 'simple' JSON-RPC programming: JSON-RPC versions 1 and 2 are supported. As an extra, I especially made sure that the Ext.Direct variant is well supported. (see fcl-web/jsonrpc) I'm still working on a Ext.Direct wrapper around WST.

I already inhaled the WST chapter in Lazarus boork. Still need to read up on SOAP and JSON.

What about ExtJS being GPL licensed? Got a developer license?

Joost uses jQuery and some Javascript components built around it. I'm sure that with his help, the ExtJS components can be modified to support jquerygrid and whatnot.

Here you refere to the ExtJS components of fpweb, right? IOW. if those are (or will be) universal, they should get renamed? (see, you are in that stuff, so for you, all this is clear. for a newbie (at least for me), it's still all confusing .. so having clear and distinct names would help.. e.g. if it's about the fpWeb components for use with ExtJS JavaScript Framework, they should be called fpExtJS components ..)

Show quoted text 13 lines
4 areas are open for work: 1. File cache mechanism in fcl-web. 2. a kind of intraweb/extpascal/unigui framework. I have the basic plans ready. Lazarus has the IDE support for it. (joost uses it in his webdesign package) 3. IIS module support. 4. Translation of Pascal to Javascript. The basics for this are in the FCL: fcl-passrc and fcl-js. What is needed is conversion of one syntax tree to another. Not very hard, but tedious and a lot of work. I hope this makes sense and gives you some ideas of the directions you can take. If there is any area you might want to work on, let me know, I'm willing to help.

Yes, thanks! It does make more and more sense. Unfortunately, my customers are not (yet) interested in web apps, so it's just a hobby right now. Therefore it will take some time before I gain ground in this.

regards
Burkhard

Reply by email

Bee Jay
to Burkhard Carstens
Burkhard Carstens wrote
What about ExtJS being GPL licensed? Got a developer license?

Yes, if you make commercial apps.

Show quoted text 6 lines
Here you refere to the ExtJS components of fpweb, right? IOW. if those are (or will be) universal, they should get renamed? (see, you are in that stuff, so for you, all this is clear. for a newbie (at least for me), it's still all confusing .. so having clear and distinct names would help.. e.g. if it's about the fpWeb components for use with ExtJS JavaScript Framework, they should be called fpExtJS components ..)

fpWeb is general purpose framework. You may use it with any JS frameworks out there. Michael had made an example how to use it with ExtJS. So, fpWeb is already an apropriate name, IMO.

Yes, thanks! It does make more and more sense. Unfortunately, my customers are not (yet) interested in web apps, so it's just a hobby right now. Therefore it will take some time before I gain ground in this.

Good for you. My clients had demanded web app, from previous desktop app, since about 4 years ago. This year they are asking about mobile app support. What a coincidence, I saw ExtJS became Sencha right about time. It's my luck, I guess. :D

-Bee-

Reply by email

Michael Van Canneyt
to Burkhard Carstens: I already inhaled the WST chapter in Lazarus boork. Still need to read up on SOAP and…
Burkhard Carstens wrote 38 lines
Am Mittwoch, 16. Juni 2010 23:01 schrieb Michael Van Canneyt: > On Wed, 16 Jun 2010, Burkhard Carstens wrote: >> .. anybody knows where I can buy it? ;-) >> After spending hours on www.w3c.org and www.w3schools.com, >> extjs.com (now sencha.com) and jquery.com reading a lot about html, >> dhtml, javascript and checking out some docs and examples about >> extjs and jquery, I got the feeling that all these pieces could >> form a nice picture .. just I still couldn't see it. >> Then I found this artice and now all of the sudden, everything >> makes a lot more sense: >> http://www.ibm.com/developerworks/web/library/wa-ajaxintro1.html >> >> Guess, it might be good to start from ground up (now that I found >> ground): >> Make some nice html files with some JavaScript functions, which >> just "call" my cgi via XmlHTTPRequest to insert something into the >> DB or return some results or tiny html snippets. > > This is exactly how I am programming web with FPC. > > FPC is used for the server. You'll see all components I use in > fcl-web/src. The client is programmed completely in ExtJS. The FPC > components have been built so they can work with any Javascript > framework, but ExtJS has been worked out best - simply because I use > it. Currently there are 3 important areas I am working in: > - SOAP calls using WST. fpweb can be used to route and handle SOAP > transport for WST. The code has been donated to WST. > - serving data to a (currently extjs) datastore in Javascript. > (see fcl-web/src/webdata) > - 'simple' JSON-RPC programming: JSON-RPC versions 1 and 2 are > supported. As an extra, I especially made sure that the Ext.Direct > variant is well supported. (see fcl-web/jsonrpc) I'm still working > on a Ext.Direct wrapper around WST. I already inhaled the WST chapter in Lazarus boork. Still need to read up on SOAP and JSON. What about ExtJS being GPL licensed? Got a developer license?

Yes.

Show quoted text 13 lines
> Joost uses jQuery and some Javascript components built around it. I'm > sure that with his help, the ExtJS components can be modified to > support jquerygrid and whatnot. Here you refere to the ExtJS components of fpweb, right? IOW. if those are (or will be) universal, they should get renamed? (see, you are in that stuff, so for you, all this is clear. for a newbie (at least for me), it's still all confusing .. so having clear and distinct names would help.. e.g. if it's about the fpWeb components for use with ExtJS JavaScript Framework, they should be called fpExtJS components ..)

Nono.
I'll give an example. There is TJSONRPCDispatcher. It 'knows' JSON-RPC. There is a descendent TExtDirectDispatcher, which simply overrides a couple of functions (they return names of fields in the json request) so the dispatcher understands the request sent by ExtDirect. Also, the TExtDirectDispatcher can generate an API configuration object.

But if you don't use ExtDirect, you can simply use TJSONRPCDispatcher.

For web data, it is similar. The base class is TWebDataProvider. It is independent of what happens on the browser end. It just knows how to analyze a web request and act on a dataset (all CRUD operations). The output of TWebDataProvider is handled by a different class: TWebDataFormatter: it is an abstract class that formats the result of TWebDataProvider.
There is a descendent TExtJSJSONFormatter that formats the result so the TSONReader in ExtJS understands it.

What Joost could do (I didn't find time yet) is write a descendent of TWebDataFormatter that outputs the result of TWebDataProvider in a format that the jQueryGrid understands. If someone needs it NOW, then of course I can help in the impmlementation.

What I'm trying to say is that I've tried to make the classes so that they can be used generally, and that one can make descendents that interface to different Javascript libraries out there.

Michael.

Reply by email

Burkhard Carstens
to Bee Jay: Yes, if you make commercial apps. fpWeb is general purpose framework. You may use it with…
Bee Jay wrote
On 18 Jun 2010, at 02:58, Burkhard Carstens wrote: > What about ExtJS being GPL licensed? Got a developer license? Yes, if you make commercial apps.

:-(

Show quoted text 11 lines
> Here you refere to the ExtJS components of fpweb, right? IOW. if > those are (or will be) universal, they should get renamed? (see, > you are in that stuff, so for you, all this is clear. for a newbie > (at least for me), it's still all confusing .. so having clear and > distinct names would help.. e.g. if it's about the fpWeb components > for use with ExtJS JavaScript Framework, they should be called > fpExtJS components ..) fpWeb is general purpose framework. You may use it with any JS frameworks out there. Michael had made an example how to use it with ExtJS. So, fpWeb is already an apropriate name, IMO.

Sure, fpWeb is fine. What I mean:
1) clear distinction between
a. "ExtJS Component" : a component of the ExtJS framework written in JavaScript.
b. "fpExtJS Component" : a component of fpWeb written in pascal, designed to deal with an ExtJS component.
It's just a documentation/communication issue: "..ExtJS components can be modified to support jquerygrid.." vs. "..fpExtJS components can be modified to support jquerygrid.."
2) *if* fpExtJS components get modified to also support jquerygrid, they should be renamed to fpUniJS component (or so). A well choosen name, which reflects the functionality, relationship and restriction of a component saves half a page of documentation and makes it easier for a newbie to get an overview.

regards
Burkhard

Reply by email

Burkhard Carstens
to Michael Van Canneyt: Yes. Nono. I'll give an example. There is TJSONRPCDispatcher. It 'knows' JSON-RPC. There…

Am Freitag, 18. Juni 2010 09:25 schrieb Michael Van Canneyt: [..]

Show quoted text 35 lines
>> Joost uses jQuery and some Javascript components built around it. >> I'm sure that with his help, the ExtJS components can be modified >> to support jquerygrid and whatnot. > > Here you refere to the ExtJS components of fpweb, right? IOW. if > those are (or will be) universal, they should get renamed? (see, > you are in that stuff, so for you, all this is clear. for a newbie > (at least for me), it's still all confusing .. so having clear and > distinct names would help.. e.g. if it's about the fpWeb components > for use with ExtJS JavaScript Framework, they should be called > fpExtJS components ..) Nono. I'll give an example. There is TJSONRPCDispatcher. It 'knows' JSON-RPC. There is a descendent TExtDirectDispatcher, which simply overrides a couple of functions (they return names of fields in the json request) so the dispatcher understands the request sent by ExtDirect. Also, the TExtDirectDispatcher can generate an API configuration object. But if you don't use ExtDirect, you can simply use TJSONRPCDispatcher. For web data, it is similar. The base class is TWebDataProvider. It is independent of what happens on the browser end. It just knows how to analyze a web request and act on a dataset (all CRUD operations). The output of TWebDataProvider is handled by a different class: TWebDataFormatter: it is an abstract class that formats the result of TWebDataProvider. There is a descendent TExtJSJSONFormatter that formats the result so the TSONReader in ExtJS understands it. What Joost could do (I didn't find time yet) is write a descendent of TWebDataFormatter that outputs the result of TWebDataProvider in a format that the jQueryGrid understands.

Now THIS clears thins up!! Please add this to the fcl-web and/or lazweb README.txt. I started to get this picture, but it took me quite some time.

If someone needs it NOW, then of course I can help in the impmlementation.

Thanks, I might get back on this offer. I just saw extCore is MIT licensed .. I'll probably play with that first.

What I'm trying to say is that I've tried to make the classes so that they can be used generally, and that one can make descendents that interface to different Javascript libraries out there.

Excelent!
Now I'm really keen on playing with this!

regards
Burkhard

Reply by email