1 |
=head1 NAME |
2 |
|
3 |
gedafe-user - the Generic Database Front-End (Gedafe) User-Manual |
4 |
|
5 |
=head1 DESCRIPTION |
6 |
|
7 |
Gedafe (the Generic Database Front-End) is a web-based database front-end |
8 |
that is database-application independent. That means that the (perl) code |
9 |
doesn't contain any information about what tables are present in the |
10 |
database or how the data is organized. |
11 |
|
12 |
This is only possible if a full-featured SQL dB server like PostgreSQL |
13 |
is used as backend. PostgreSQL permits to define not only the format |
14 |
of the various tables and fields, but also how tables are related to |
15 |
each other. It is even possible to write powerful functions inside the |
16 |
database which get executed as new data is accessed or |
17 |
modified. Together, these features allow the implementation of data |
18 |
integrity constraints inside the database itself. |
19 |
|
20 |
The effect of this is, that the database server guarantees the |
21 |
integrity of the database, independently from the software used to |
22 |
access the database. A front-end can read all the integrity |
23 |
constraints directly off the database and enforce them itself in order |
24 |
to provide faster response to the user, but at the end of the day the |
25 |
database server will only accept data which follow the rules defined |
26 |
by the database programmer. |
27 |
|
28 |
Overall, this approach makes the creation and maintenance of database |
29 |
applications much simpler. New databases can be created on the |
30 |
database server alone, using the language which is best suited for |
31 |
this task: SQL. The front-end then comes almost for free. |
32 |
|
33 |
=head2 Features |
34 |
|
35 |
Gedafe has the following features: |
36 |
|
37 |
=over 4 |
38 |
|
39 |
=item * |
40 |
|
41 |
It is completely I<generic>. Gedafe does not need to know anything |
42 |
about the structure or contents of the database it is working with. |
43 |
|
44 |
=item * |
45 |
|
46 |
I<Authentication> is done at the database-level. |
47 |
|
48 |
=item * |
49 |
|
50 |
It is URL transparent. This means, you can directly access the URL of |
51 |
the page you want to look at. If necessary, the login screen will pop |
52 |
up and after a successful login you will be presented the page you |
53 |
initially requested. |
54 |
|
55 |
=item * |
56 |
|
57 |
Almost no HTML is used in the front-end code. External template files |
58 |
define the look and feel of pages. |
59 |
|
60 |
=item * |
61 |
|
62 |
POST is used only for data that modifies the database. Every page has |
63 |
a distinct URL, which makes them storable as bookmarks (Deep Linking). |
64 |
|
65 |
=item * |
66 |
|
67 |
I<Double form protection>. The front-end prevents accidental repeated |
68 |
submission of the same form. This is implemented using a unique serial |
69 |
number for each form. |
70 |
|
71 |
=item * |
72 |
|
73 |
Using the PearlReports integration, is is possible to write custom multilevel |
74 |
report modules (Pearls) available from the Gedafe webinterface. |
75 |
|
76 |
=back |
77 |
|
78 |
=head1 INSTALLATION |
79 |
|
80 |
The structure of the Gedafe distribution is as follows: |
81 |
|
82 |
. |
83 |
|-- bin/ binaries (gedafed daemon) |
84 |
|-- doc/ documentation |
85 |
|-- lib/ |
86 |
| `-- perl/ |
87 |
| |-- Gedafe/ gedafed main source |
88 |
| |-- DBIx/ PearlReports (required for gedafe pearls) |
89 |
| `-- Text/ CPPTemplates (required for gedafe screen layout) |
90 |
`-- example |
91 |
|-- templates/ HTML templates |
92 |
|-- mypearls/ Sample pearl report module |
93 |
|-- demo1.cgi demo-application script |
94 |
`-- demo1.sql PostgreSQL script to initialize the |
95 |
demo-application database |
96 |
|
97 |
In order to start using gedafe you must ensure that F<lib/perl> of the |
98 |
Gedafe distribution is found by F<perl> and start the F<gedafed> |
99 |
daemon (you can use the script gedafed-ctl to start it with |
100 |
SYSV-init). |
101 |
|
102 |
=head2 The Application Script |
103 |
|
104 |
Gedafe is actually a library. The application itself just calls the |
105 |
'Start' function of the library, providing the necessary configuration |
106 |
information as arguments. The application startup script should look |
107 |
as follows: |
108 |
|
109 |
#!/usr/sepp/bin/speedy -w |
110 |
|
111 |
use lib "/usr/local/gedafe/lib/perl"; |
112 |
|
113 |
use Gedafe::Start; |
114 |
|
115 |
Start( |
116 |
db_datasource => 'dbi:Pg:dbname=demo', |
117 |
list_rows => 15, |
118 |
templates => '/usr/local/gedafe/templates/demo', |
119 |
documentation_url => 'http://mysite.com/demo-docs', |
120 |
show_row_count => 1, |
121 |
isearch => '/place/in/the/webtree/for/isearch.jar', |
122 |
pearl_dir => '/usr/local/gedafe/example/mypearls', |
123 |
list_buttons => 'both', |
124 |
); |
125 |
|
126 |
Gedafe gathers information about the database structure when it is |
127 |
started. This process can take a lot of time, it is therefor strongly |
128 |
suggested that you use a persistent perl instance, for example |
129 |
I<speedy>. I<mod_perl> works also great, but you have to be careful if |
130 |
you run multiple database applications, since if the same persistent |
131 |
perl is used, the cached data of the applications will go in the same |
132 |
global variables, which is certainly not what you want. |
133 |
|
134 |
Of course, you must specify the correct path name to your perl |
135 |
interpreter in the first line of the script (unless you use a |
136 |
webserver perl module). |
137 |
|
138 |
Very important in this script is the first 'use' statement. It should |
139 |
point to where you have stored F<lib/perl> of the |
140 |
distribution. I<Start> starts the application by specifying Gedafe |
141 |
configuration variables. The following configuration variables are |
142 |
defined: |
143 |
|
144 |
=over 20 |
145 |
|
146 |
=item db_datasource |
147 |
|
148 |
DBI data-source string specifying the database. |
149 |
|
150 |
=item list_rows |
151 |
|
152 |
Default number of rows to show. |
153 |
|
154 |
=item templates |
155 |
|
156 |
The directory where the html templates are stored (you can use a copy |
157 |
F<example/templates> as a basis for you local modifications). |
158 |
|
159 |
=item documentation_url |
160 |
|
161 |
URL passed to the html templates where the documentation of the |
162 |
application is stored. |
163 |
|
164 |
=item show_row_count |
165 |
|
166 |
Options: [0,1] |
167 |
If set, show a count of total records returned by each select, along |
168 |
with extra navigation links to skip to first and last pages of result set. |
169 |
Since this produces slightly higher database overhead (an added |
170 |
SELECT COUNT(*) for every SELECT), it is turned off by default. |
171 |
|
172 |
=item isearch |
173 |
|
174 |
Web-servers don't like Java archives (jar) to be down-loaded from cgi-bin |
175 |
directory's. They will try to execute them instead. To resolve this, |
176 |
you have to place the 'incremental search widget' (isearch) Java |
177 |
archive in a place where it can be down-loaded like any other file. |
178 |
This item is used to point gedafe to the place where you have put the |
179 |
isearch.jar. Please make sure that it is on the same server and |
180 |
preferably a relative address. Java security restrictions require this. |
181 |
|
182 |
=item list_buttons |
183 |
|
184 |
Options: ['top','bottom','both','none'] |
185 |
This option acts on the buttons that appear with table or view lists, the |
186 |
first,previous,add,next,last buttons. |
187 |
Top selects only buttons above the list. |
188 |
Bottom selects only buttons below the list. |
189 |
None removes all buttons, but doing so wouldn't make much sense. |
190 |
When omitted the default is 'both'. |
191 |
|
192 |
=item pearl_dir |
193 |
|
194 |
Name of a directory where gedafe should go looking for pearls. Pearls are |
195 |
object oriented perl modules which first display a data input screen and |
196 |
then run a report off the database based on the entires given at the data |
197 |
entry screen. See F<gedafe-pearls.pod> for more information. |
198 |
|
199 |
=back |
200 |
|
201 |
=head2 The gedafed Daemon |
202 |
|
203 |
Gedafe uses an external process called gedafed to manage session |
204 |
data. This daemon must be running to make Gedafe work. You can start |
205 |
it during the boot process of your server using the bin/gedafed-ctl |
206 |
script. |
207 |
|
208 |
=head2 The Database |
209 |
|
210 |
F<gedafe-sql.pod> describes how the database should be setup to work with |
211 |
Gedafe. |
212 |
|
213 |
=head1 USAGE |
214 |
|
215 |
=head2 Authentication |
216 |
|
217 |
Authentication is done with the help of gedafed. This daemon stores |
218 |
user/password pairs using a random-generated "ticket", which is stored |
219 |
in a cookie on the client side. To make these tickets more secure |
220 |
gedafed manages an expiration on these tickets. Every time that ticket |
221 |
is used, it's expiration is prolonged by a certain amount of seconds |
222 |
(configured in the script). If the database isn't accessed for a |
223 |
certain amount of time, the ticket is expired and a new login must be |
224 |
made. |
225 |
|
226 |
The login screen is transparent to the page accessed: whenever a login |
227 |
is needed, the login screen is first presented, after which the |
228 |
requested page is shown. |
229 |
|
230 |
Warning: Gedafe will not work with blank passwords. If you want to do |
231 |
anonymous logins, you may put the user in the url (as an additional |
232 |
parameter, user=xxx&...) and the password sent to the database will be |
233 |
'anonymous'. |
234 |
|
235 |
=head2 Forms and Navigation |
236 |
|
237 |
The navigation and general use of Gedafe should be straightforward. At the |
238 |
beginning, you are presented with the "Entry" page that contains links to every |
239 |
table to edit and to every available report. |
240 |
|
241 |
For forms, the guiding principle while designing Gedafe was 'POST is |
242 |
evil, use it the least possible'. The reason for it is that if a |
243 |
generated page depends on POST data, that page can't be stored in a |
244 |
bookmark and the browsers have problems handling the reloading of |
245 |
pages obtained with a POST request. For that reason, POST was used |
246 |
only for database-modifying actions where large amounts of data must |
247 |
be transferred. |
248 |
|
249 |
=head2 HTML Layout |
250 |
|
251 |
Almost no HTML is used in the perl code. The HTML is generated with the help |
252 |
of Text::CPPTemplate, a very simple C-preprocessor-style templating system |
253 |
included in the Gedafe distribution. The templates are taken from a directory |
254 |
specified in the startup script with the 'templates' parameter. |
255 |
|
256 |
The basic idea is that Gedafe places small "elements" of the page currently |
257 |
being generated such as the header or the cell of a table by only specifying |
258 |
variables (properties) of that element. Every element has always the following |
259 |
minimal variables specified: |
260 |
|
261 |
=over 10 |
262 |
|
263 |
=item PAGE |
264 |
|
265 |
Name of the page (for example I<login>, I<entry> or I<list>). |
266 |
|
267 |
=item ELEMENT |
268 |
|
269 |
Name of the element (for example I<header> or I<td>). |
270 |
|
271 |
=back |
272 |
|
273 |
In addition, element-specific data such as I<DATA> for the I<td> |
274 |
element must be defined. Text::CPPTemplate will then search for an appropriate |
275 |
template to use and generate the HTML code. See L<Text::CPPTemplate(3)> for a |
276 |
description of the syntax and how the templates are stored in files. See also |
277 |
F<gedafe-templates.txt> for a description of what elements are used with what |
278 |
variables. |
279 |
|
280 |
=head2 Hidden features |
281 |
|
282 |
=over 4 |
283 |
|
284 |
=item * |
285 |
|
286 |
In the URL: C<list_rows=nn> override the number-of-displayed-rows specified in |
287 |
the startup script. |
288 |
|
289 |
=item * |
290 |
|
291 |
In the URL: C<theme=xxx> set the theme (templates will be loaded from that |
292 |
subdirectory of the templates directory) |
293 |
|
294 |
=item * |
295 |
|
296 |
In the URL: C<reload=1> reset all the cached data. This is useful, for |
297 |
example, if you changed a template file or the structure of the database. |
298 |
|
299 |
=item * |
300 |
|
301 |
C<today> or C<yesterday> can be specified as search value for a 'Date' field. |
302 |
|
303 |
=item * |
304 |
|
305 |
Numbers can be entered as C<hh:mm> (for example C<0:10>). The C<mm> part will |
306 |
be multiplied by 100/60 and added to C<hh>. |
307 |
|
308 |
=item * |
309 |
|
310 |
Some supporting perl modules are auto-detected and only used if they are |
311 |
installed on the system gedafe is running on. These are currently: |
312 |
|
313 |
=over 4 |
314 |
|
315 |
=item - |
316 |
|
317 |
Text::CSV_XS : for exporting data as comma-separated value (CSV) format; if not |
318 |
installed, only the default tab-delimited format will be available for |
319 |
exporting data. |
320 |
|
321 |
=back |
322 |
|
323 |
=back |
324 |
|
325 |
=head2 Caching and Bookmarks |
326 |
|
327 |
A difficulty that we encountered while developing Gedafe was the |
328 |
caching of pages by the browser. We have to control precisely when a |
329 |
page can be cached and when not. The implementation is made with the |
330 |
C<refresh> URL parameter: when it is set, the expiration of the page |
331 |
is set to some positive value, meaning that the page can be cached. If |
332 |
C<refresh> is not available, the expiration is negative, meaning that |
333 |
the page should not be cached. The value of C<refresh> is a random |
334 |
number, that can be changed to force a reload of the page. |
335 |
|
336 |
A side-effect of this technique is that pages with C<refresh> in the URL are |
337 |
not suitable to be stored as bookmarks, since you would then get always the |
338 |
same cached version. For that reason, bookmarks should be always saved without |
339 |
the C<refresh> parameter, such that a new version of the page is always |
340 |
requested from the server. There is a link on every page, that you can drag to |
341 |
store the currently viewed page. |
342 |
|
343 |
=head1 TROUBLESHOOTING |
344 |
|
345 |
=head2 Edit form is empty |
346 |
|
347 |
When you get an empty form after selecting 'Edit' for a record, this could mean |
348 |
that you didn't put the record *_id into the first column of the presentation |
349 |
(*_list) view or the table (if there isn't a presentation view). Gedafe must |
350 |
know the id of the record to edit and it does so by using the first column as |
351 |
key. See the F<gedafe-sql.pod>, section 'Presentation View'. |
352 |
|
353 |
=head1 SEE ALSO |
354 |
|
355 |
F<gedafe-sql.pod>, F<gedafe-templates.txt>, F<Text::CPPTemplate>, F<gedafe-pearls.pod>, |
356 |
F<DBIx::PearlReports> |
357 |
|
358 |
=head1 COPYRIGHT |
359 |
|
360 |
Copyright (c) 2000-2003 ETH Zurich, All rights reserved. |
361 |
|
362 |
=head1 LICENSE |
363 |
|
364 |
This program is free software; you can redistribute it and/or modify |
365 |
it under the terms of the GNU General Public License as published by |
366 |
the Free Software Foundation; either version 2 of the License, or |
367 |
(at your option) any later version. |
368 |
|
369 |
This program is distributed in the hope that it will be useful, |
370 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
371 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
372 |
GNU General Public License for more details. |
373 |
|
374 |
You should have received a copy of the GNU General Public License |
375 |
along with this program; if not, write to the Free Software |
376 |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
377 |
|
378 |
=head1 AUTHOR |
379 |
|
380 |
S<Tobias Oetiker E<lt>oetiker@ee.ethz.chE<gt>>, |
381 |
S<David Schweikert E<lt>dws@ee.ethz.chE<gt>>, |
382 |
S<Fritz Zaucker E<lt>zaucker@ee.ethz.chE<gt>>, |
383 |
S<Adi Fairbank E<lt>adi@adiraj.orgE<gt>>, |
384 |
S<Freek Zindel E<lt>freek@zindel.nlE<gt>> |