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:

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.