| home | |||
|
|||
| links |
|
||
|
developer's mag main page article part 1 part 2 part 3 part 4 part 5 part 6 part 7 part 8 |
5 - The Mechanics Of Open/CreateTo wrap up the details, I've created two functions, DatabaseOpen() and DatabaseCreate() that handle most of the opening details - modify them as you need. Only DatabaseOpen() needs to be called, since DatabaseCreate() is called by it if the database doesn't exist:
DBErr DatabaseOpen( const ebo_name_t *fileName,
FieldDef * fieldDef,
long maxSize,
int *existed )
{
DBErr error=DB_OK;
if (m_db.Open( 0, (ebo_name_t *) fileName, OS_availaddr, maxSize ))
{
// failed - we need to create it
*existed=0;
error=DatabaseCreate(fileName,fieldDef,maxSize);
if ( DB_OK != error )
return error;
}
else
*existed=1;
// now we open the file manager object
error=m_fMgr.Open(&m_db);
if (!error)
OS_availaddr+=maxSize; // adjust so we don't reuse db memory
return error;
}
//---------------------------------------------------------------------
DBErr DatabaseCreate( const ebo_name_t *fileName,
FieldDef*fieldDef,
long maxSize )
{
CDBHeaderHdl dbh;
DBErr error=m_db.Create(0,(ebo_name_t*)fileName,OS_availaddr,maxSize,&dbh);
if ( DB_OUT_OF_MEMORY == error ) // no room to create?
{
GUI_NeedFileSpace(fileName); // ask OS for more & try again
error=m_db.Create(0,(ebo_name_t*)fileName,OS_availaddr,maxSize,&dbh);
if ( DB_OUT_OF_MEMORY == error )
return error;
}
// now set up our field definitions
return m_fMgr.InitFieldDefinitions(&m_db,fieldDef,0,0);
}
If you again look at the test.cpp code, you'll
see the test and OS request is generally
in the form of a while loop - when heap memory
is exhausted, this could lead to an infinite
loop. Production code should instead simply
ask once for more memory and try to open,
quitting at that point if an error.
(NOTE: I'm since been told that the original while loop was coded because GUI_NeedFileSpace() provides users with a dialog, allowing them to manually free up space, and retry or exit. That being the case, you could safely place the while loop in, which has the benefit that if the first retry fails with not enough memory freed up, the user can delete more and retry. Of course, since deleting any file should free up enough to create most databases, the above code will also work.) The only item we haven't covered now is the FieldDef * parameter, which is a pointer to an array of FieldDef structures:
struct
{
FldType type;
U16 size;
char *label;
};
Each field of the record is described with
this structure, where 'size' refers to
the maximum length, 'label' is the description of the
field, and 'type' describes the field format, and can
be any of the following:
Put together, we can define our demo program's field definitions: FieldDef m_fieldDef[] = {
{ FLD_ TEXT, 64, "Animal" },
{ FLD_ TEXT, 60, "Location" },
{ FLD_ TEXT, 32, "Type" },
{ FLD_EOF, 0, 0 } };
With this final piece of the puzzle, we can
open our database with our function DatabaseOpen()
- if the result is DB_OK, we've succeeded,
and the flag 'existed' indicates whether
the file existed before the call, or zero
if it was just created.
Previous Section Next Section |
||
| Copyright © 2001-2006 ebmDevMag.com - Legal Notice | |||