<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
Here is a first shot of the design docs before I post them pubically. I
would be grateful of any feedback.<br>
<br>
I am still not sure how best to support MockMagmaCollections.Here I
suggest that they always be contained in an object. Is there a way of
using a genuine MagmaCollection as a Mock, such that readers and so on
work even though there is no database behind?<br>
<br>
The package will be in MagmaTester, and it requires Seaside28Jetsam as
well as Magma.<br>
<br>
cheers<br>
<br>
Keith<br>
<br>
======<br>
<b>Overview<br>
<br>
</b>The aim of this version of the Magma-seaside integration framework
is to learn some lessons from projects already using Magma in order to
satisfy the following goals.<br>
<br>
The overriding goal was to make the tutorial very easy, so as to blow
away the competition!<br>
<br>
<b>1. Simplify Configuration. </b><br>
<b>2. Enable Magma as a Helper</b>. Ease combining Magma with other
seaside technologies, to which end we no longer subclass WASession.<br>
<b>3. Session Management Choice</b>. Provide options such as shared or
pooled sessions again orthogonal to the domain, or other settings.<br>
<b>4a. Facilitate Modularization.</b> Provide the framwork to allow a
Magma user-accounts module to be deployed as a plug-in package,
combinable with other modules, such as a pier module, or a
shopping-cart module.<br>
<b>4b. Similarly, Facilitate Project Combination.</b> Projects having
separate databases may merge into one, e.g. gjallar &amp; pier.<br>
<b>5. Simplify Use and Initialization.</b> Initialization of models,
not just of the root object, but also sub-branches of the database<br>
&nbsp;&nbsp; which are used by different application-modules or application
sub-domains. <br>
<b>6. Server Managed Preferences.</b> Server to client propagation of
preferences and data for multi-server operation, and load sharing
schemes.<br>
<b>7. Direct Usage Outside of Seaside. </b>Aim to standardize the
manner in which services, tests and other procedures access a database
which is configured via seaside.<br>
<br>
<br>
====<br>
<br>
<b>1. Simplifying Configuration</b><br>
<br>
The seaside configuration provides a selector for the database helper
class which provides session management. You can provide your own
scheme by subclassing any of the WAMagma helper classes.<br>
<br>
The local database directory, is initially set to 'Automatic' which
will save the data in 'magma-todo' directory for the 'todo' entry
point. This ensures that by default no configuration is required while
at the same time separate applications will not step on each others'
databases files.<br>
<br>
<b>2. Enable Magma as a Helper</b><br>
<br>
In order for Magma to be used alongside other frameworks which have
specialized session classes such as Glorp, the configuration of Magma
is now orthogonal to the choice of WASession. You may subclass
WASession if you need to, in order to support your application domain,
but it is not necessary to do so either to use Magma, or to store
session state. Session state can now be stored using the
WASession-#properties dictionary.<br>
<br>
This is accomplished through the WASessionHelper framework which is
part of Seaside28Jetsam. Magma is supported by one such helper and the
chosen Magma helper is accessed via WASession-#magma.<br>
<br>
Instanciation.<br>
<br>
Magma helpers provide session management, options include:<br>
&nbsp;&nbsp;&nbsp; single&nbsp;&nbsp;&nbsp; - WAMagma<br>
&nbsp;&nbsp;&nbsp; shared&nbsp;&nbsp;&nbsp; - WAMagmaShared<br>
&nbsp;&nbsp;&nbsp; pooled&nbsp;&nbsp;&nbsp; - WAMagmaPooled<br>
&nbsp;&nbsp;&nbsp; mock&nbsp;&nbsp;&nbsp; - WAMockMagma<br>
&nbsp;&nbsp;&nbsp; <br>
<b>4. Facilitate Modularization.</b><br>
<br>
Modularization requires the objects in the database to manage their own
behaviour. <br>
<br>
Rather than fill the database with generic containers such as
Dictionaries and MagmaCollections without any specialization, we should
recommend subclassing and specializing the typical model container
objects. The base classes would be&nbsp; WADictionaryRoot, Object or
MagmaCollection. <br>
<br>
However it is as well to point out that subclassing MagmaCollection
directly lands us with a significant limitation. It prevents us from
easily switching all MagmaCollections for MockMagmaCollections! <tt></tt><br>
<br>
To make this switching ability transparent the class WAMagmaCollection
is provided as a base class to use for specialization instead. By
default it contains a MagmaCollection (or a MockMagmaCollection) and
you can also add slots to persist your favorite reader queries defined
on initialization. This approach also guarantees that the model has a
place to put these query optimizations should you need them.<br>
<br>
For example, to define an application specific model "ToDoList" for
your database, subclass WADatabaseRoot (which is an IdentityDictionary)
and define your custom accessors on that class e.g.<br>
<br>
ToDoList-#items<br>
^ self at: #items <br>
ToDoList-#users<br>
^ self at: #users<br>
<br>
If #items is a subclass of WAMagmaCollection called
TodoListItemsCollection then you can define your custom item based
queries on your own subclass of WAMagmaCollection, encouraging typical
object-oriented encapsulation.<br>
<br>
itemsForUser: name <br>
&nbsp;&nbsp;&nbsp; self where: [ :each | each usersName equals: name ]<br>
<br>
On your domain objects or components, access your database like so:<br>
<br>
MyComponent-todoListDatabase<br>
&nbsp;&nbsp;&nbsp; ^ self session magma rootAs: ToDoList<br>
<br>
and...<br>
<br>
MyComponent-todoListItems<br>
&nbsp;&nbsp;&nbsp; ^ self todoListDatabase items<br>
&nbsp;&nbsp;&nbsp; <br>
However for a sub-domain or module model you can also do.<br>
<br>
MyComponent-todoListItems<br>
&nbsp;&nbsp;&nbsp; ^ self session magma rootAs: TodoListItemsCollection<br>
&nbsp;&nbsp;&nbsp; <br>
This means that the sub-domain or module models can be referenced by
the domain irrespective of their place in the actual database
structure, which is defined in your specialized model classes. They
know where in the database they are located, and importantly they know
how to initialize themselves.<br>
<br>
This scheme allows several applications or modules to be layered upon a
single database. Each model class can nominate its own personal root
object in the main database which is returned via the rootAs: idiom&nbsp;
(see class methods #getVirtualRootIn: #initializeVirtualRootIn: etc)<br>
<br>
It also allows the database to be re-organised by changing model
classes only. The domains view of the database is decoupled from the
modular structure of the database.<br>
<br>
<b>5. Simplify Use and Initialization.<br>
<br>
</b>Initialization is performed automatically as far as is possible.<br>
<br>
When using the standard accessing idiom: '<tt>self session magma
rootAs: MyModel'</tt>. If this is performed and the database does not
exist, or has no root class, then, the root will automatically be
initialized according to the #actualRootClass nominated by the model
class. This makes databases auto-initializing. If the virtualRoot model
object for MyModel itself is not present in the database, then it will
also be initialized automatically.<br>
<br>
The initialized root or model-objects are configured, and indexes added
if needed, in their respective #initialize methods.<br>
<br>
If a model is retrieved that is not of the correct class, #rootAs:
attempts to mutate the instance into the desired class, thus providing
some automatic schema migration at the module level.<br>
<br>
<b>6. Server Managed Preferences.<br>
<br>
</b>An optional module which allows a seaside-server-magma-client
application to pick up settings and preferences from the magma-server.
Whenever a new seaside session is started, on the first time only, the
root object's #firstRead: method can call '<tt>helper rootAs:
WAServerManagedPreferences</tt>'.<br>
<br>
WAServerManagedPreferences is implemented as a module, being as self
contained as possible to demonstrate the principles outlines above. It
assumes the root object of the database is a dictionary (if not it will
need to be reconfigured appropriately).<br>
<br>
This module, when #firstRead:, checks its #expiry time, and if it has
expired, it loads the current application's preferences with the values
that it contains. The values are each sent #value before being written.<br>
<br>
This would allow #location to return a version of MagmaRemoteLocation
which when sent #value, evaluates picking a remote server based upon
the client's identity. This scheme would enable
seaside-server-magma-client to be deployed, the first time anyone
accesses the server it would obtain its new settings and potentially
redirect to a new server.<br>
<br>
<br>
<b>7. Direct Usage Outside of Seaside<br>
</b><br>
Standardize the manner in which services, tests and other procedures
access a database which is configured via seaside.<br>
WAMagma helper may be used with Seaside, or directly. Configuration is
per-seaside application e.g.<br>
<br>
(WAMagma forApp: 'todo') location.<br>
(WAMagma forApp: 'todo') readStrategyClass.<br>
(WAMagma forApp: 'todo') areMaterializationNotificationsEnabled.<br>
(WAMagma forApp: 'todo') commit: [] etc.<br>
&nbsp;<br>
<br>
<br>
<br>
<br>
</body>
</html>