Gamla Scope and Contents
Objectives
The gamla project aims to create the following:
1. A set of perl modules to manipulate SQL data and other types of
sequential data.
2. A set of perl modules that will serve as the basis for a World
Wide Web based application server.
3. A set of perl modules that will encapsulate common database and
non-database related GUI dialogs.
4. Various web applications to run on top of the application
server.
5. A web-interface for managing the application server.
6. A GUI builder for creating and maintining perl and Gamla based
applications.
7. Various perl and C modules and APIs that will be found essential
to the progress of the project.
The focus of the Gamla project will be on source code and less on
GUI and other interfaces that can be used to generate it. The
assumption is that our target is not afraid of editing a few text
files, and that powerful components are the key to this project's
success.
General Concepts and Methodologies
1. The SPEC concept
We are going to use nested perl data structures to represent
various configurations. As demonstrated by Arad::Editor::OneTable
and Shlomif::MiniReporter, an SQL query can be represented inside a
perl data structure. This concept will be carried forward
throughout Gamla.
If we take a links manager for example, then we should write such
SPECs to describe its underlying tables of links and categories.
Only at the front-end there will be functions that take some of the
fields (whose values will be passed to it inside a hash) and
process them to represent a link. That way, it will be easy to add
or remove fields from the tables, without having to go over the
entire code.
2. The record as an associative array
An SQL (or other Relational database) record is a hash, not an
object. We should place all the values of the currently processed
record in a separate hash, and not place them inside the member
variables of the object.
This rule was made for having organized and modular code, and
should be followed.
3. Closures should be avoided when possible
Make sure all the subroutine references a function receives accept
at least one user-defined context variable. Closures are not
supported by every languages, and I find that having a context
variable is cleaner and more modular then depending on remembered
variables.
4. Use as many user-definable functions as possible
If for example we take Arad::Reporter::OneTable, which will be a
module that will take a stream of relational records and output
them. The following methods can be supplied as parameters:
1. Record Renderer Function: How to render a record.
2. Record Separator Function (accpets the index of the previous
record).
3. Field Renderer Function: to be called by the Record Renderer to
render an individual field.
4. Record Stream Function: retrieves a record from a data
stream.
5. Category Header and Category Footer functions.
Etc. All those methods can be specified at the object creation. For
example:
my $reporter = Arad::Reporter::OneTable->new(
$spec,
-stream => \&my_record_stream,
-render => \&my_record_renderer,
-separator => sub { return "\n\n"; },
);
5. Perl/Tk-like argument passing
Whenever a reference to a function is expected one can place a
reference to an array that will contain the function reference as
the first member, and its initial paramters as the other
members.
Also, optional arguments to functions can be specified in the
manner of "-argument => $value".
6. SPEC overriding
Instead of modifying the SPEC data structure (which could be a bad
thing because it may be shared by several concurrent instances of
the application) we should devise a method to override its
contents. My idea is that wherever a SPEC is expected, an array of
SPECs may be passed, where the first is the main spec file and the
other are deltas.
There may be a more elegant way of doing that, so I suggest we give
it some thought.
7. Use "$ret .= $value", not "print $value"
The title says it all. All functions should return their output,
which can later be appended to some other output, or printed to the
screen. In any case print should only be used in end scripts.
8. Dialogs should use at least two objects.
A common dialog should have two objects: one object that
manipulates all the data, and perform all the operations; and one
object which is library specific and calls the data-object when the
user performs actions, and displays what the data object returns as
arguments.
This concept not only enables us to write multi-library dialogs
more easily but contributes to a more modular code.
Arad::Editor::OneTable demonsrates it, and as a proof of concept,
the table editor can be controlled by either a Perl/Tk dialog or a
GNU readline-based one (and more can be added by the user).
9. Document while you write
Those who are working on a module should write a document
describing its functionality, the methods that should be used by
the outside, how to use it, etc. That document should then be
posted to the mailing list.
I'd like the coding to be efficient as possible so it's important
that people follow this.
Core Modules
Arad - The interface with relational data
Arad will be a set of modules that will be used to query and edit
SQL and other relational data. Modules in the Arad namespace will
include:
Arad::Reporter::OneTable - report one table into a static
HTML file, a text file, etc. Incldue categorizing into categories
and sub-categories.
Arad::RecordStream::OneTable - a record stream that can be
used as input to Arad::Reporter::OneTable. Will be overriden to
suply streams for SQL tables, perl arrays, Berkeley DB files,
etc.
Arad::Editor::OneTable - the core of an interactive table
editor.
Same for multiple tables.
Arad::Types - The types manager
This will be a type manager for SQL and other types, which will
allow:
- Type verification (making sure an entered value is
suitable)
- Conversion from perl to SQL and vice versa.
- Type inheritance.
- Type Parameters (for example "len" as the length of a varchar
type)
Gamla::SPEC::SPECer
Gamla will contain a great deal of spec data structures, and it is
required that each class of SPEC files will have its own spec that
will determine its format and contents, how to convert it to and
from XML, what is the type of every argument, and so forth.
SPEC::SPECer will enable us to define a spec describing the class
and sub-classes of every SPEC, and to easily manipulate it within a
perl program. It can later be used to generate dialogs that will
allow the user to edit such SPECs.
UDL - The Unified Dialog Layer
UDL will serve as something like DBI for dialogs and
user-interfaces. It will enable to create Perl/Gtk, Perl/Tk, HTML,
and Perl/Qt dialogs from the same dialog specification, as well as
send messages and handle event from those dialogs. Eli Marmor
mentioned something about a superior User Interface model that was
suggested by a certain professor from Bar-Ilan University. I'd like
to become familiar with that model and see if it can serve as the
basis for UDL.
Gamla::Web::Nablus - the HTML (text, Tex, etc.) generator
Nablus will be a set of classes that will give an abstraction layer
with logical styles and central customization over HTML. Basically,
I can execute statements like:
$generator->append(
Nablus::Heading->new("The Enemy and How I helped to fight it",
"main")
);
$generator->append(
Nablus::Paragraph->new("This is a satire about the situation in the
Israeli-Lebanese border"));
.
.
.
Nablus will be able to overcome HTML difficulties like the fact
that the font has to be applied to every cell in the table
individually. The same Nablus code can later be used to render
non-HTML documents, to which we will supply different renders.
I believe we should supply a way to translate Nablus code to and
from our own defined subset of XML, so site users will be able to
upload their own documents without the insecurity of writing it in
perl.
Gamla::Web::PageMan - the location manager
PageMan will be a registry of page id's and their actual locations
in the site. Gamla applications will be able to supply links to
pages based on their page ids. Thus, if a page has moved to a new
location, one can change its location in the registry, and thus
make sure, all the old pages will point to the new URL.
Note that we should make sure that locations can be based on other
locations. For example, the placement of a certain document can be
expressed as the base directory of the documentation (e.g: "docs/")
plus the document name (E.g "FAQ.html"). Also, links may be added
at run time.
Gamla::Web::Lockers - synchronization mechanisms
Those mechanisms will supply mechanisms to block read or write to a
shared resource from several instances of the application server.
They will include:
1. ResourceLocker - get permission to read or write from a generic
resource.
2. FileLocker - get permission to read or write to a file.
3. DirectoryLocker - get permission to add files to a a directory,
etc.
Rindolf - the customization engine
Rindolf will enable Gamla to be customized in a very flexible way.
For example, one can customize the colors, images, fonts, etc. of
an entire site or subsite, by modifying one central place.
Eventually, it should be able to maintain a list of "web themes",
which the administrator or end-user can choose from, and that can
be distributed to other sites.
Bryte - the end-user management engine
Bryte will enable to maintain a list of end-users with usernames,
passwords, preferences, customizations, etc.
Keltivestor - administrators' management
Likewise for site administrators'. Managing permissions on site,
etc.
WWW Applications
This is a list of end-applications that will be developed for
Gamla:
Link-Bus - Link manager.
Slash-Bus - Slashdot-like online discussions.
Mail-Bus - Egroups-like interface to mailing-lists and mail
archives.
Store-Bus - E-commerce server.
GamlaWiki - a Wiki-Wiki web.
Source-Bus - Interface to CVS and other code repositories,
with syntax highlighting, code links, and other goodies.
Schedule-Bus - a personal/groupware schedule.
Doc-Bus - manager for online books and documents.
FAQ-Bus - SQL-ready FAQ-O-Matic replacement. Probably based
on Doc-Bus.
Note that all of them should be able to work with SQL or without
it. Also: both standard database BLOBs and file-system stored BLOBs
may be used. The reason for that is that some databases like
PostgreSQL have BLOBs that are inaccesible from the SQL level.
Modules that we should work on
Data::Duplicator
Take a perl data-structure and create a duplicate of it. Note that
the data may not be necessarily hierarchial.