database questions
Alex Rice
alrice at ARCplanning.com
Sun Aug 3 17:06:00 EDT 2003
On Friday, August 1, 2003, at 10:17 AM, John R. Brauer wrote:
> b) is there an internal way of doing this instead of one of the above
> databases?
John, your requirements sound very similar to my current Rev project.
It's a Facility Calculator for the National Park Service. It is a
lengthy survey about facility usage and planning. There are several
facility types, and each type has it's own substack with dozens of
cards. So each "record", we call record a "project title", literally
does have several hundred fields. There is no apparent way to break it
up into some kind of normalized SQL table structure that would seem
more organized.
The requirements were that no networked database server was available,
so mysql and postgresql were not options (otherwise I would recommend
postgresql because it has foreign keys, triggers, and transactions).
For a project like this, and maybe yours, a SQL database just doesn't
make much sense. The fields in the survey change a *lot* as the app is
developed. There are many, many fields for each record. We are
developing and updating the app while users continue to use old data
from previous projects they have entered. So it has to degrade
gracefully as fields are added and removed, whole cards changed, etc.
The solution I am using, thanks to this list, is to use Rev custom
properties in a "data stack". Custom properties can be attached to a
stack or any other Rev object. I create a file called UserData.rev and
save it into the user's Application Data folder. The custom properties
are accessed as an array using a key/value relationship. Custom
Property SETS are used to separate the data of the various facility
types I mentioned.
Here are a couple of accessors for getting and setting data into the
data stack:
--
-- dataField(key)
-- accessor for the value of the slot in the current session
--
function dataField pKey
put the customProperties of stack kDataStack into tData
put sessionID() , pKey , "value" into tFilter
return tData[tFilter];
end dataField
--
-- setDataField key, value
-- accessor for setting data
--
on setDataField pKey, pValue
put the customProperties of stack kDataStack into tData
put sessionID() , pKey , "value" into tFilter
put pValue into tData[tFilter]
set the customProperties of stack kDataStack to tData
end setDataField
I have also written some handlers to automatically load and save
UserData.rev to and from fields and buttons as the user navigates
through the cards. I used custom properties to do that as well: The
routines scan all fields and buttons on the card picking out ones that
have the custom property "ud" (stands for user data), which is the
"key" in the above handlers.
In this method the number of custom property array elements is =
(facilities) * (projects) * (answers) -- in other words (sets) *
(sessions) * (data keys). At the sets level they are completely
separate arrays (custom property sets). But at the sessions * data keys
level, it's just a single array. It's extremely fast until you get up
into many thousands of array keys. However I haven't needed to do much
optimization yet though. I suspect that dataField(key) function above
could be written better.
So using a "data stack" is fast, portable and doesn't require any
additional software. It's much easier programming than say, a delimited
text database, and it's not as difficult as a SQL implementation.
I also recommend looking at Serendipity DB. I don't think it uses the
approach I described above, but it is a native Rev implementation also
and would have similar benefits.
Alex Rice, Software Developer
Architectural Research Consultants, Inc.
http://ARCplanning.com
More information about the use-livecode
mailing list