db.h File Reference


Detailed Description

Database system module C header file.

REVISION

Definition in file db.h.

#include "../feature.h"
#include "../MESSAGE/message.h"
#include "../GENERIC/generic.h"
#include "../fat/fat.h"

Include dependency graph for db.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  st_DBIDTREE
 DB ID tree structure definition. More...
struct  st_DBHEADER
 DB header structure definition. More...
struct  st_DBINFO
 DB information structure definition. More...
struct  st_DBQUERYCTL
 DB query control structure definition. More...
struct  st_DBREGIST
 DB registration structure definition. More...
struct  st_DBPAICTL
 DB PAI module control data structure definition. More...
struct  st_DBNAV
 DB navigation support structure. More...

Defines

#define DB_MAXLFN   32
 Maximum DB file name length, this definition over rides FAT definition to save memory.
#define DB_REGIST2SRAM
 Move registration to SRAM to save memory.
#define DB_MAX_ID   0x018
 Maximum database ID.
#define DB_OPENMAX   4
 Maximum num of concurrent opened DBs.
#define DB_MAXRECLEN   512
 Maximum length of record in words.
#define DB_MAXFIELDLEN   256
 Maximum length of record field in words.
#define DB_MAXNAMELEN   32
 Maximum DB key name in words.

Enumerations

enum  DB_FEXTNAME
 DB file extention name enumeration definition.

Functions

BOOL DB_add2child (DB_MDBOFFSET, DB_ID, const DB_DATA *)
 Function adds specified record to given child DB.
BOOL DB_deleteRecord (DB_ID, DB_ENTRY)
 Function deletes specified record from the root database, it also updtes all corresponding child database.
BOOL DB_deleteRecordByMdb (DB_ID, DB_MDBOFFSET)
 Function deletes specified record indexed by root offset from the root database, it also updtes all corresponding child database.
BOOL DB_removeRecord (DB_ID, DB_ENTRY, DB_ENTRY)
 Function removes specified record reference from the child database.
DB_FIELDLEN DB_getField (const DB_DATA *, DB_FIELDIDX, DB_DATA *, st_DBINFO *)
 Function gets interpreted data of the specified record field out of given record.
DB_ENTRY DB_getSaiByMdb (ULONG, DB_ID)
 Function calculates SAI entry based on MDB offset.
DB_MDBOFFSET DB_getMdbByRecord (DB_ID, const unsigned short *)
 Function checks return the MDB offset by record data.
st_DBINFODB_info (DB_HDL)
 Function returns information of specified database.
BOOL DB_init (void)
 Function initializes DB controls.
DB_HDL DB_queryFirst (DB_ID, DB_FIELDIDX, DB_ENTRY, DB_ENTRY, DB_DATA *)
 Function queries the specified database and sets up query controls.
BOOL DB_queryNext (DB_HDL, DB_ENTRY, DB_DATA *)
 Function queries database through specified database handle.
BOOL DB_queryClose (DB_HDL)
 Function closes the specified database query operation and releases corresponding control data object.
DB_ID DB_parentID (DB_ID)
 Function returns parent DB ID of the givent the child DB.
DB_ID DB_childID (DB_ID, DB_FIELDIDX)
 Function returns child DB ID givent the child field index.
void DB_setSyncMark (const char *)
 Function sets the DB sync mark.
BOOL DB_checkSyncMark (const char *)
 Function checks the DB sync mark.
BOOL DB__addSAIentry (DB_ID, DB_ENTRY, DB_MDBOFFSET, DB_PAIOFFSET)
 Function adds a new SAI entry.
BOOL DB__deleteChildRecord (DB_ID, DB_ENTRY)
 Function deletes an entry form a child DB.
DB_FIELDIDX DB__fieldIndex (DB_ID)
 Function returns field index of given child database under its parent.
DB_FIELDLEN DB__getField (const DB_DATA *, DB_FIELDIDX, DB_DATA *)
 Function gets data of the specified record field out of given record with all escape/delimiter characters stripped.
BOOL DB__getRecord (File *, DB_DATA *)
 Function reads back a record from specified file.
BOOL DB__info (DB_ID, st_DBINFO *)
 Function returns information of specified database, this function is only available internally to DB module.
DB_DATA * DB__locateField (const DB_DATA *, DB_FIELDIDX)
 Function locates position of the specified field.
DB_FNAME DB__name (DB_ID, DB_FEXTNAME)
 Function returns the database header file name.
DB_RECLEN DB__recordLen (const DB_DATA *)
 Function returns length in words of the specified record field.
BOOL DB__recordPosition (DB_ID, DB_ENTRY *, const DB_DATA *, BOOL)
 Function checks to see if specified record exists in DB.
BOOL DB__removePAIentry (DB_ID, DB_MDBOFFSET, DB_PAIOFFSET, unsigned short *)
 Function removes specified PAI entry.
DB_ID DB__rootID (DB_ID)
 Function returns root DB ID of specified child ID.

Variables

const char strDBDIR []
 GLOBAL DATA.


Function Documentation

BOOL DB__addSAIentry DB_ID  id,
DB_ENTRY  entry,
DB_MDBOFFSET  mdb,
DB_PAIOFFSET  pai
 

Function adds a new SAI entry.

Parameters:
id DB ID.
entry Entry added.
mdb DB MDB offset.
pai DB PAI offset.
Returns:
TRUE if successfully added, otherwise FALSE.

Definition at line 3459 of file db.c.

References DB__name(), FAT_fclose(), FAT_finsert(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, SEEK_HEAD, SEEK_MID, and File::size.

Referenced by DB__insert2leaf(), and DB_insertRecord().

03463 {
03464 
03465     unsigned long   offset[2];
03466     unsigned long   fsize;
03467     unsigned short  entryNum;
03468     File *          idxfile;
03469 
03470     /* Update record number. */
03471     idxfile = FAT_fopen(DB__name(id, SAI), r_b);
03472     fsize = idxfile->size;
03473     
03474     FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
03475     FAT_fread(idxfile, &entryNum, 1);
03476 
03477     entryNum++;
03478 
03479     FAT_fseek(idxfile, -1, SEEK_MID);
03480     FAT_fwrite(idxfile, &entryNum, 1);
03481 
03482 
03483     /* Load buffer. */
03484     offset[0] = mdb;
03485     offset[1] = pai;
03486 
03487     /* Check to see if there is any free entries. */
03488     if((long)fsize >= (long)((unsigned long)(entryNum + DB_SAIFIRSTENTRY + 1)<<2) ){
03489 
03490         FAT_finsert( idxfile, 
03491                     ( (unsigned long)entry << 2), 
03492                     (unsigned short *)offset, 
03493                     4, fsize);
03494     }
03495     else
03496     {
03497         FAT_finsert(idxfile, 
03498                     ( (unsigned long)entry << 2), 
03499                     (unsigned short *)offset, 
03500                     4, 0L);
03501     }
03502 
03503     FAT_fclose(idxfile);
03504     
03505     return TRUE;
03506 }

Here is the call graph for this function:

BOOL DB__deleteChildRecord DB_ID  id,
DB_ENTRY  entry
 

Function deletes an entry form a child DB.

It is the caller's responsibility to make sure the PAI entries are all cleared or it is deleted from root, in which case there is no PAI at all. Function deletes the child DB entry and updates all its children if any.

Parameters:
id DB ID.
entry DB entry.
Returns:
TRUE if record successfully deleted, otherwise FALSE.

Definition at line 2079 of file db.c.

References DB__getField(), DB__getRecord(), DB__name(), DB__removePAIentry(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), st_DBIDTREE::node, r_b, rb, SEEK_HEAD, and SEEK_MID.

Referenced by DB_deleteRecord(), DB_deleteRecordByMdb(), and DB_removeRecord().

02080 {
02081     DB_ID           childID;
02082     st_DBIDNODE *   node;
02083     DB_MDBOFFSET    offset;
02084     DB_PAIOFFSET    pai;
02085     unsigned short  entryNum;
02086     unsigned short  entryLeft;
02087     File *          idxfile;
02088     File *          dbfile;
02089     DB_SAIOFFSET    sai;
02090     DB_FIELDIDX     fldidx;
02091     USHORT          fldlen;
02092     USHORT          usTmp, usLen;
02093     USHORT          buf[DB_MAXRECLEN];
02094     unsigned long   fld[32];// Assuming that one field could hold up to
02095                             // 32 valid offset values.
02096 
02097     // Get MDB offset from SAI file.
02098     idxfile = FAT_fopen(DB__name(id, SAI), r_b);
02099     FAT_fseek(idxfile, (unsigned long)(entry+DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
02100     FAT_fread(idxfile, (unsigned short *)&offset, 2);
02101 
02102     // Remove SAI entry.
02103     FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02104     FAT_fread(idxfile, &entryNum, 1);
02105 
02106     DB_assert(entryNum, DB__DELETECHILDRECORD);
02107     
02108     /* Decrement entry number. */
02109     FAT_fseek(idxfile, -1, SEEK_MID);
02110     entryNum--;
02111     FAT_fwrite(idxfile, &entryNum, 1);  
02112     
02113     /* Process the rest of the entries. */
02114     usTmp = (unsigned long)(entryNum - entry)<<2;
02115     FAT_fseek(idxfile, (unsigned long)(entry + DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);  
02116     while(usTmp)
02117     {       
02118         /* Skip the current entry which should be deleted. */
02119         FAT_fseek(idxfile, 4, SEEK_MID);
02120 
02121         if(usTmp > DB_MAXRECLEN )   usLen = DB_MAXRECLEN;
02122         else                        usLen = (unsigned short)usTmp;
02123 
02124         FAT_fread(idxfile, (unsigned short *)buf, usLen);
02125         FAT_fseek(idxfile, (long)((long)(-4) - usLen ), SEEK_MID);
02126         FAT_fwrite(idxfile, (unsigned short *)buf, usLen);
02127         usTmp -= usLen;     
02128     }
02129 
02130     buf[0] = buf[1] = buf[2] = buf[3] = 0;
02131 
02132     /* Zero out last entry. */
02133     FAT_fwrite(idxfile, (unsigned short *)buf, 4);
02134     FAT_fclose(idxfile);
02135 
02136     /* Mark entry as deleted. */
02137     dbfile = FAT_fopen(DB__name(id, MDB), r_b);
02138 
02139     // Read back the entire record here.
02140     FAT_fseek(dbfile, offset, SEEK_HEAD);
02141     DB__getRecord(dbfile, (DB_DATA *)buf);
02142 
02143     FAT_fseek(dbfile, offset, SEEK_HEAD);
02144     FAT_fread(dbfile, (unsigned short *)&usTmp, 1);
02145     usTmp |= RECORD_DELETED;
02146     FAT_fseek(dbfile, -1, SEEK_MID);
02147     FAT_fwrite(dbfile, (unsigned short *)&usTmp, 1);
02148     FAT_fclose(dbfile);
02149 
02150 
02151     /* Check all the children database. */
02152     node = &DB_idtree.node[id];
02153     fldidx = 0;
02154 
02155     if(node->child)
02156     {
02157         node = node->child;
02158         
02159         while(node->next)
02160         {
02161             node = node->next;
02162             childID = node->id;
02163 
02164             fldidx++;
02165             
02166             fldlen = DB__getField(buf, fldidx, fld)>>1;
02167             
02168             // Sort all SAIs in field if any.
02169             _sortSAI(fld, fldlen);
02170             
02171             idxfile = FAT_fopen(DB__name(childID, SAI), rb);            
02172             FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02173             FAT_fread(idxfile, &entryNum, 1);
02174 
02175             // Note that entry has to be checked from the end of file to 
02176             // support recursively deleting. 
02177             while( (entryNum) && (fldlen) ) 
02178             {
02179                 entryNum--;
02180                 FAT_fseek(idxfile, ((unsigned long)(entryNum + DB_SAIFIRSTENTRY)<<2), SEEK_HEAD);
02181                 FAT_fread(idxfile, (unsigned short *)&sai, 2);
02182                 FAT_fread(idxfile, (unsigned short *)&pai, 2);
02183                 
02184                 if( sai == fld[fldlen-1])
02185                 {
02186                     fldlen--;
02187 
02188                     // If pai == 0, there is no PAI entries available, does 
02189                     // NOT need to check.
02190                     if(pai) DB__removePAIentry(childID, offset, pai, &entryLeft);
02191                 }
02192                 
02193                 else continue;
02194                 
02195                 // if( (sai != fld[fldlen-1]) || (pai == 0) ) continue;
02196                 // fldlen may have been post decremented already.
02197                 if(pai == 0) continue;
02198 
02199                 if(entryLeft == 0)
02200                 {
02201                     /* Close file before deleting SAI entry. */
02202                     FAT_fclose(idxfile);
02203 
02204                     // The first entry always(?) points to the default empty record,
02205                     // do not delete it even when it is empty since it defaults to
02206                     // have at least one virtual record.                
02207                     if(entryNum != 0)
02208                     {                    
02209                         DB__deleteChildRecord(childID, entryNum);
02210                     }
02211 
02212                     /* Reopen SAI file after deleting. */
02213                     idxfile = FAT_fopen(DB__name(childID, SAI), rb);
02214                 }
02215             }
02216 
02217             /* Close file before return. */
02218             FAT_fclose(idxfile);
02219         }
02220     }
02221 
02222     return TRUE;
02223 }

Here is the call graph for this function:

DB_FIELDIDX DB__fieldIndex DB_ID  id  ) 
 

Function returns field index of given child database under its parent.

Parameters:
id Child DB ID.
Returns:
Field index.

Definition at line 3396 of file db.c.

References st_DBIDTREE::node.

Referenced by DB_add2child(), and DB_removeRecord().

03397 {
03398     st_DBIDNODE *   node;
03399     DB_FIELDIDX     fldidx;
03400 
03401     fldidx = 0;
03402     node = &DB_idtree.node[id];
03403     
03404     /* The very first child does not have previous node. */
03405     while(node->prev)
03406     {
03407         fldidx++;
03408         node = node->prev;
03409     }
03410     
03411     return fldidx;
03412 }

DB_FIELDLEN DB__getField const DB_DATA *  pRecord,
DB_FIELDIDX  fldIdx,
DB_DATA *  pData
 

Function gets data of the specified record field out of given record with all escape/delimiter characters stripped.

Parameters:
pRecord DB record data.
fldIdx DB field index.
pData Field data buffer.
Returns:
Data length in words.

Definition at line 1911 of file db.c.

References DB__locateField().

Referenced by DB__deleteChildRecord(), DB_getField(), and DB_getMdbByRecord().

01914 {
01915     const unsigned short *  pSrc;
01916     unsigned short *        pDst;
01917     
01918     pSrc = (const unsigned short *)DB__locateField(pRecord, fldIdx); 
01919     
01920     if( NULL == pSrc )
01921     {       
01922         /* Unable to locate the specified field. */
01923         return 0;
01924     }
01925 
01926     
01927     if( (*pSrc == DB_RECDLMT)||(*pSrc == DB_FLDDLMT) )
01928     {       
01929         /* Empty record. */
01930         return 0;
01931     }
01932 
01933 
01934     pDst = (unsigned short *)pData;
01935     /* Start to fetch field. */
01936     while(1) 
01937     {
01938         if( *pSrc == DB_ESCCHAR) 
01939         {
01940             pSrc++;
01941             *pDst++ = *pSrc++;
01942         }
01943         else{
01944             *pDst++ = *pSrc++;
01945         }
01946 
01947         if( (*pSrc == DB_RECDLMT)||(*pSrc == DB_FLDDLMT) ) break;
01948     }
01949     
01950     return (pDst - (unsigned short *)pData);
01951 }

Here is the call graph for this function:

BOOL DB__getRecord File file,
DB_DATA *  pData
 

Function reads back a record from specified file.

It is the caller's responsibility to make sure buffer is long enough to hold the record with maximum length.

Parameters:
file DB data file.
pData DB record data buffer.
Returns:
TRUE if valid record is found, otherwise FALSE.

Definition at line 3343 of file db.c.

References DB_MAXRECLEN, and FAT_fread().

Referenced by DB__deleteChildRecord(), DB_add2child(), DB_getField(), DB_queryFirst(), DB_queryNext(), and DB_removeRecord().

03344 {
03345     unsigned short *    p;
03346     unsigned short      len;
03347     
03348     // This is from queryFirst.
03349     if(pData == NULL) return TRUE;
03350     
03351     // Let's split it to speed up, since normally record will be 
03352     // 256 words less.
03353     
03354     p = (unsigned short *)pData;
03355     len = FAT_fread(file, p, DB_MAXRECLEN/2);
03356     
03357     // check for record delimiter, for safe?.
03358     while( 1 ) 
03359     {
03360         if( *p == DB_RECDLMT ) 
03361         {           
03362             if( *(p-1) != DB_ESCCHAR ) return TRUE;
03363         }
03364         p++;
03365         if ( (p-(unsigned short *)pData) >= len ) break;
03366     }
03367 
03368     // Second attempt.
03369     if( len != DB_MAXRECLEN/2) return FALSE;
03370     
03371     p = (unsigned short *)pData+DB_MAXRECLEN/2;
03372     len = FAT_fread(file, p, DB_MAXRECLEN/2);
03373     
03374     // check for record delimiter, for safe?.
03375     while( 1 ) 
03376     {
03377         if( *p == DB_RECDLMT ) 
03378         {           
03379             if( *(p-1) != DB_ESCCHAR ) return TRUE;
03380         }
03381         p++;
03382         if ( (p-(unsigned short *)pData) == len ) break;
03383     }
03384     
03385     return TRUE;    
03386 }

Here is the call graph for this function:

BOOL DB__info DB_ID  id,
st_DBINFO pInfo
 

Function returns information of specified database, this function is only available internally to DB module.

Parameters:
id DB ID.
pInfo Info data buffer.
Returns:
TRUE if info successfully retrieved, otherwise FALSE.

Definition at line 1577 of file db.c.

References st_DBINFO::attribute, st_DBINFO::bVirtual, DB__cdDBdir(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), st_DBREGIST::fname, st_DBINFO::id, st_DBIDTREE::node, st_DBINFO::numOfFields, st_DBINFO::numOfKeys, st_DBINFO::ptrXIM, rb, SEEK_HEAD, and st_DBINFO::status.

Referenced by DB_insertRecord(), and DB_queryFirst().

01578 {
01579     File *              file;
01580     st_DBHEADER         header;
01581     unsigned long       signature;      
01582 
01583     #if 1
01584     pInfo->id = id;
01585     
01586     /* Check to see if id points to a virtual DB. */
01587     if( DB_registration[id].fname == NULL ) 
01588     {
01589         pInfo->bVirtual = TRUE;
01590         
01591         /* Virtual DB, access through its parent. */
01592         id = DB_idtree.node[id].parent->id;
01593     }
01594     else pInfo->bVirtual = FALSE;
01595     #endif
01596     
01597     // Change to corresponding root DB directory. all files contained
01598     // in this directory.
01599     if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)   return FALSE;
01600     
01601     if( (file = FAT_fopen(DB__name(id, MDB), rb) ) == NULL ) return FALSE;
01602     
01603     if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER)) 
01604             != sizeof(st_DBHEADER) ) RETURN_ERROR;
01605 
01606     FAT_fseek(file, header.len - 2, SEEK_HEAD);
01607     FAT_fread(file, (unsigned short *)&signature, 2);
01608 
01609     /* Check signature here for safe. */
01610     if( signature != DB_HEADER_SIGNATURE ) RETURN_ERROR;
01611 
01612     /* Copy information over. */
01613     pInfo->attribute = header.attribute;
01614     pInfo->numOfFields = header.numOfFields;
01615     pInfo->numOfKeys = header.numOfKeys;
01616     pInfo->status = header.status;
01617     pInfo->ptrXIM = ((long)header.ptrXIMhi<<16)|header.ptrXIMlo;
01618     
01619     FAT_fclose(file);   
01620 
01621     return TRUE;    
01622 }

Here is the call graph for this function:

DB_DATA* DB__locateField const DB_DATA *  pRecord,
DB_FIELDIDX  fldIdx
 

Function locates position of the specified field.

Parameters:
pRecord DB record data.
fldIdx Field index.
Returns:
Field data start pointer if specified field found, otherwise NULL.

Definition at line 3151 of file db.c.

Referenced by DB__addChildIdx(), and DB__getField().

03152 {
03153 
03154     const unsigned short *  pSrc;
03155     unsigned short          count;
03156     
03157     count = 0;
03158     
03159     /* Skip the record flag. */
03160     pSrc = (unsigned short *)pRecord + 1;
03161 
03162     if( fldIdx != 0 )
03163     {
03164         while( 1 ) 
03165         {   
03166             if(*pSrc == DB_ESCCHAR) pSrc += 2;
03167             
03168             if(*pSrc == DB_RECDLMT) 
03169             {               
03170                 /* End of record, field not found. */
03171                 return NULL;
03172             }
03173     
03174             if(*pSrc == DB_FLDDLMT) 
03175             {               
03176                 /* Field detected. */
03177                 count++;
03178                 
03179                 if( count == fldIdx ) 
03180                 {
03181                     pSrc++;
03182                     break;
03183                 }
03184             }
03185             
03186             pSrc++;
03187         }
03188     }
03189     
03190     return((DB_DATA *)pSrc);
03191 }

DB_FNAME DB__name DB_ID  id,
DB_FEXTNAME  ext
 

Function returns the database header file name.

Parameters:
id DB ID.
ext Extention specifier.
Returns:
DB file name pointer.

Definition at line 3101 of file db.c.

References st_DBREGIST::fname, and st_DBREGIST::len.

Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__info(), DB__insert2leaf(), DB__recordPosition(), DB__removePAIentry(), DB_add2child(), DB_deleteRecord(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_insertRecord(), DB_queryFirst(), and DB_removeRecord().

03102 {   
03103     unsigned short  len = DB_registration[id].len;
03104 #ifdef DB_REGIST2SRAM
03105     static char     DBnameBUF[DB_MAXLFN]; 
03106     char *          pC = &DBnameBUF[len-1];
03107     GEN_rdSRAM(DB_registration[id].fname, (unsigned short *)DBnameBUF, len+1);  
03108 #else
03109     char *          pC = DB_registration[id].fname;
03110 #endif
03111     
03112     switch( ext ) 
03113     {
03114         case MDB:
03115             *pC-- = 'b';
03116             *pC-- = 'd';
03117             *pC   = 'm';
03118             break;
03119         
03120         case SAI:
03121             *pC-- = 'i';
03122             *pC-- = 'a';
03123             *pC   = 's';
03124             break;
03125     
03126         case PAI:
03127             *pC-- = 'i';
03128             *pC-- = 'a';
03129             *pC   = 'p';
03130             break;
03131     }
03132     
03133 #ifdef DB_REGIST2SRAM
03134     return (DB_FNAME)DBnameBUF;
03135 #else   
03136     return DB_registration[id].fname;
03137 #endif      
03138 
03139 }

DB_RECLEN DB__recordLen const DB_DATA *  pRecord  ) 
 

Function returns length in words of the specified record field.

Parameters:
pRecord DB record.
Returns:
Record length in words.

Definition at line 3070 of file db.c.

Referenced by DB__addChildIdx(), DB_add2child(), and DB_removeRecord().

03071 {   
03072     unsigned short *    pR;
03073     
03074     pR = (unsigned short *) pRecord;
03075     
03076     if(*pR == DB_RECDLMT)   return 0;
03077 
03078     while( 1 ) 
03079     {
03080         pR++;
03081         
03082         if( *pR == DB_RECDLMT ) 
03083         {
03084             if( *(pR-1) != DB_ESCCHAR ) break;
03085         }       
03086     }
03087     
03088     return (pR-(unsigned short *)pRecord+1);
03089 }

BOOL DB__recordPosition DB_ID  id,
DB_ENTRY *  pPosition,
const DB_DATA *  pRecord,
BOOL  bIgnoreRule
 

Function checks to see if specified record exists in DB.

If it does, function also sets up the record position value, which is the SAI entry. if it does not, function sets up the position value to where it should be.

Parameters:
id DB ID.
pPosition Position data pointer.
pRecord DB record.
bIgnoreRule If TRUE, search till end.
Returns:
TRUE if record found, otherwise FALSE.

Definition at line 2979 of file db.c.

References DB__compare(), DB__name(), DB_MAXFIELDLEN, FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, SEEK_HEAD, and SEEK_MID.

Referenced by DB__insert2leaf(), and DB_insertRecord().

02983 {
02984     unsigned short  field[DB_MAXFIELDLEN];
02985     DB_ENTRY        entry;          /* SAI entry number. */
02986     DB_MDBOFFSET    offset;         /* File offset in MDB file. */
02987     short           comp;           /* Field compare result. */
02988     File *          idxfile;
02989     File *          dbfile;
02990 
02991     /* Open MDB and SAI files. */
02992     idxfile = FAT_fopen(DB__name(id, SAI), rb);
02993     dbfile  = FAT_fopen(DB__name(id, MDB), rb);
02994     
02995     
02996     /* Points to the first valid entry. */
02997     entry = DB_SAIFIRSTENTRY;
02998 
02999 
03000     /* SAI entry takes 64bits, 4 words per entry. */
03001     FAT_fseek(idxfile, (long)entry << 2, SEEK_HEAD);
03002     FAT_fread(idxfile, (unsigned short *)&offset, 2);
03003 
03004     while(offset)
03005     {
03006         FAT_fseek(dbfile, offset, SEEK_HEAD);
03007         FAT_fread(dbfile, field, DB_MAXFIELDLEN);
03008 
03009         /* Only compare the primary field. */
03010         comp = DB__compare(field, (unsigned short *)pRecord );
03011 
03012         if( comp == 0)
03013         {
03014             /* Record found!. */
03015             FAT_fclose(idxfile);
03016             FAT_fclose(dbfile);
03017 
03018             *pPosition = entry;
03019             return TRUE;
03020         }
03021         else if (comp < 0)
03022         {
03023             /* ASSUMPTIION:
03024             ** If data under this rule are not presorted, this rule must 
03025             ** support multiple record references, which means any record
03026             ** can possibly occur multiple times under this rule. 
03027             */
03028             entry++;
03029 
03030             /* Skip PAI entry. */
03031             FAT_fseek(idxfile, 2, SEEK_MID);            
03032             FAT_fread(idxfile, (unsigned short *)&offset, 2);
03033         }
03034         else
03035         {
03036             if(bIgnoreRule == FALSE) break;
03037             
03038             else
03039             {
03040                 entry++;
03041 
03042                 /* Skip PAI entry. */
03043                 FAT_fseek(idxfile, 2, SEEK_MID);            
03044                 FAT_fread(idxfile, (unsigned short *)&offset, 2);
03045             }
03046         }
03047     }
03048 
03049 
03050     /* Record does not exist. */
03051     FAT_fclose(idxfile);
03052     FAT_fclose(dbfile);
03053 
03054     
03055     /* Sets up position. */
03056     *pPosition = entry;
03057 
03058     return FALSE;   
03059 }

Here is the call graph for this function:

BOOL DB__removePAIentry DB_ID  id,
DB_MDBOFFSET  entry,
DB_PAIOFFSET  pai,
unsigned short *  pEntryNum
 

Function removes specified PAI entry.

Parameters:
id DB ID.
entry DB data entry offset.
pai PAI start offset.
pEntryNum Pointer to number of entry left.
Returns:
TRUE if PAI successfully removed, otherwise FALSE.

Definition at line 2662 of file db.c.

References DB__name(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), File::flag, r_b, and SEEK_HEAD.

Referenced by DB__deleteChildRecord(), and DB_removeRecord().

02666 {   
02667     st_DBPAICTL     control;
02668     DB_PAIOFFSET    rdstart;
02669     DB_PAIOFFSET    wrstart;
02670     unsigned short  dataleft;
02671     unsigned short  counter;
02672     unsigned short  rdlen;
02673     unsigned short  wrlen;
02674     unsigned short  ii; 
02675     DB_MDBOFFSET    rdbuf[DB_MAXPAIBUFLEN];
02676     DB_MDBOFFSET    wrbuf[DB_MAXPAIBUFLEN];
02677     DB_MDBOFFSET *  pWr;
02678     File *          idxfile;
02679 
02680     idxfile = FAT_fopen(DB__name(id, PAI), r_b);
02681     FAT_fseek(idxfile, pai - sizeof(st_DBPAICTL), SEEK_HEAD);
02682     FAT_fread(idxfile, (unsigned short *)&control, sizeof(st_DBPAICTL));
02683 
02684     rdstart = pai;
02685     wrstart = pai;
02686     dataleft = control.entryNum;
02687     *pEntryNum = control.entryNum;
02688 
02689     while(dataleft)
02690     {
02691         if(dataleft > DB_MAXPAIBUFLEN)  rdlen = DB_MAXPAIBUFLEN << 1;           
02692         else                            rdlen = dataleft << 1;
02693 
02694         counter = 0;
02695 
02696         FAT_fread(idxfile, (unsigned short *)rdbuf, rdlen);
02697 
02698         pWr = wrbuf;
02699 
02700         for(ii = 0; ii < (rdlen>>1); ii++)
02701         {           
02702             if(rdbuf[ii] != entry)      *pWr++ = rdbuf[ii];
02703             else                        counter++;
02704         }
02705 
02706         wrlen = rdlen - (counter<<1);
02707         *pEntryNum -= counter;
02708 
02709         FAT_fseek(idxfile, wrstart, SEEK_HEAD);
02710         FAT_fwrite(idxfile, (unsigned short *)wrbuf, wrlen);
02711 
02712         wrstart += wrlen;
02713 
02714         dataleft -= (rdlen>>1);
02715 
02716         rdstart += rdlen;
02717 
02718         FAT_fseek(idxfile, rdstart, SEEK_HEAD);
02719     }
02720 
02721 
02722     /* Zero out all free entries. */
02723     if( control.entryNum > *pEntryNum)
02724     {
02725         wrstart = pai + ( (long)(*pEntryNum) << 1 );
02726 
02727         dataleft = (control.entryNum - *pEntryNum) << 1;
02728 
02729         for(ii = 0; ii < DB_MAXPAIBUFLEN; ii++) wrbuf[ii] = 0L;
02730 
02731         while(dataleft)
02732         {
02733             if(dataleft > (DB_MAXPAIBUFLEN<<1)) wrlen = (DB_MAXPAIBUFLEN<<1);
02734             else                                wrlen = dataleft;
02735         
02736             FAT_fseek(idxfile, wrstart, SEEK_HEAD);
02737             FAT_fwrite(idxfile, (unsigned short *)wrbuf, wrlen);
02738 
02739             wrstart += wrlen;
02740             dataleft -= wrlen;
02741         }
02742     }
02743 
02744 
02745     /* Update entryNum. */
02746     if(*pEntryNum)
02747     {
02748         FAT_fseek(idxfile, pai - sizeof(st_DBPAICTL) + 2, SEEK_HEAD);
02749         FAT_fwrite(idxfile, pEntryNum, 1);  
02750     }
02751     else
02752     {       
02753         /* Mark this module to be free. */
02754         FAT_fseek(idxfile, pai - sizeof(st_DBPAICTL) + 1, SEEK_HEAD);
02755         control.flag |= PAI_FREE;
02756 
02757         FAT_fwrite(idxfile, (unsigned short *)&control.flag, 1);
02758         FAT_fwrite(idxfile, pEntryNum, 1);
02759     }
02760 
02761     FAT_fclose(idxfile);
02762     
02763     return TRUE;
02764 }

Here is the call graph for this function:

DB_ID DB__rootID DB_ID  id  ) 
 

Function returns root DB ID of specified child ID.

Parameters:
id Current DB ID.
Returns:
Corresponding root DB ID.

Definition at line 1680 of file db.c.

References st_DBIDTREE::node.

Referenced by DB__info(), DB_add2child(), DB_deleteRecord(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), and DB_removeRecord().

01681 {   
01682     st_DBIDNODE * node;
01683 
01684     node = &DB_idtree.node[id];
01685     
01686     /* Traverse to root. */
01687     while(node->parent) node = node->parent;
01688     
01689     return node->id;    
01690 }

BOOL DB_add2child DB_MDBOFFSET  rootMdb,
DB_ID  childID,
const DB_DATA *  childRecord
 

Function adds specified record to given child DB.

Parameters:
rootMdb Root record MDB offset.
childID Child DB ID.
childRecord Child record.
Returns:
TRUE if successful, otherwise FALSE.

Definition at line 2461 of file db.c.

References DB__addChildIdx(), DB__cdDBdir(), DB__fieldIndex(), DB__getRecord(), DB__insert2leaf(), DB__name(), DB__recordLen(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), st_DBIDTREE::node, r_b, rb, SEEK_HEAD, SEEK_MID, and File::size.

02464 {
02465     DB_ID               rootID;
02466     st_DBIDNODE *       node;
02467     DB_FIELDIDX         fldidx;
02468     DB_MDBOFFSET        childMdb;
02469     DB_MDBOFFSET        newOffset;
02470     DB_MDBOFFSET        tmpMdb;
02471     DB_RECLEN           originalLen;
02472     DB_RECLEN           childLen;
02473     DB_RECLEN           newLen;
02474     unsigned short      flag;
02475     File *              dbfile;
02476     File *              idxfile;
02477     unsigned short      record[DB_MAXRECLEN];
02478     //unsigned short    childRecord[DB_MAXRECLEN];
02479 
02480     /* Fetch root MDB entry. */
02481     rootID = DB__rootID(childID);
02482 
02483     if(DB__cdDBdir(DB__name(rootID, MDB)) == FALSE)   return FALSE; 
02484     
02485     //idxfile = FAT_fopen(DB__name(rootID, SAI), rb);
02486     //FAT_fseek(idxfile, (unsigned long)(rootEntry+DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
02487     //FAT_fread(idxfile, (unsigned short *)&mdb, 2);
02488     //FAT_fclose(idxfile);
02489 
02490     /* Fetch root record. */
02491     dbfile = FAT_fopen(DB__name(rootID, MDB), rb);
02492     FAT_fseek(dbfile, rootMdb, SEEK_HEAD);
02493     DB__getRecord(dbfile, record);
02494     FAT_fclose(dbfile);
02495 
02496 
02497     /* Fetch child MDB entry. */
02498     //idxfile = FAT_fopen(DB__name(childID, SAI), rb);
02499     //FAT_fseek(idxfile, (unsigned long)(childEntry+DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
02500     //FAT_fread(idxfile, (unsigned short *)&newOffset, 2);
02501     //FAT_fclose(idxfile);
02502 
02503     /* Fetch child record. */
02504     //dbfile = FAT_fopen(DB__name(childID, MDB), rb);
02505     //FAT_fseek(dbfile, newOffset, SEEK_HEAD);
02506     //DB__getRecord(dbfile, childRecord);
02507     //FAT_fclose(dbfile);
02508     
02509     /* ID to field index. */
02510     fldidx = DB__fieldIndex(childID);
02511 
02512     originalLen = DB__recordLen(record);
02513     childLen = DB__recordLen(childRecord);
02514     
02515     /* Insert to child. */
02516     childMdb = DB__insert2leaf( childID, 
02517                                 rootID, 
02518                                 rootMdb,
02519                                 record, 
02520                                 childRecord, 
02521                                 childLen, 
02522                                 TRUE);
02523                             
02524     /* Update root DB field value. */
02525     DB__addChildIdx(record, fldidx, childMdb);
02526     
02527     newLen = DB__recordLen(record);
02528         
02529     /* If newLen == originalLen, the original is able to hold the new
02530     ** index without extending record length, we'll just write back the 
02531     ** new record.
02532     */
02533     if(newLen == originalLen) 
02534     {       
02535         dbfile = FAT_fopen(DB__name(rootID, MDB), r_b);
02536         FAT_fseek(dbfile, rootMdb, SEEK_HEAD);
02537         FAT_fwrite(dbfile, (unsigned short *)record, newLen);
02538         FAT_fclose(dbfile);
02539     
02540         return TRUE;    
02541     }
02542     
02543     else
02544     {
02545         /* Mark the original as deleted. */
02546         dbfile = FAT_fopen(DB__name(rootID, MDB), r_b);
02547 
02548         newOffset = dbfile->size;
02549 
02550         FAT_fseek(dbfile, rootMdb, SEEK_HEAD);
02551         FAT_fread(dbfile, (unsigned short *)&flag, 1);
02552         
02553         flag |= RECORD_DELETED;
02554 
02555         FAT_fseek(dbfile, -1, SEEK_MID);
02556         FAT_fwrite(dbfile, (unsigned short *)&flag, 1);
02557 
02558         /* Append new to the end of file. */
02559         FAT_fseek(dbfile, newOffset, SEEK_HEAD);
02560         FAT_fwrite(dbfile, (unsigned short *)record, newLen);
02561         FAT_fclose(dbfile);
02562 
02563         /* Search and replace SAI entry. */
02564         idxfile = FAT_fopen(DB__name(rootID, SAI), r_b);
02565         FAT_fseek(idxfile,(unsigned long)(DB_SAIFIRSTENTRY) << 2,SEEK_HEAD);
02566         while(1)
02567         {
02568             FAT_fread(idxfile, (unsigned short*)&tmpMdb, 2);
02569             DB_assert(tmpMdb != 0, DB_ADD2CHILD);
02570             
02571             if(tmpMdb == rootMdb)
02572             {
02573                 FAT_fseek(idxfile,-2,SEEK_MID);
02574                 FAT_fwrite(idxfile, (unsigned short *)&newOffset, 2);
02575                 break;
02576             }               
02577             // Skip PAI entry.
02578             FAT_fread(idxfile, (unsigned short*)&tmpMdb, 2);
02579         }       
02580         FAT_fclose(idxfile);
02581 
02582         /* Search and replace all children PAIs. */
02583         node = &DB_idtree.node[rootID];
02584         node = node->child;
02585 
02586         while(node->next)
02587         {
02588             _replacePAI(node->next->id, rootMdb, newOffset);
02589             
02590             node = node->next;
02591         }
02592     }
02593     return TRUE;
02594 }

Here is the call graph for this function:

BOOL DB_checkSyncMark const char *  drive  ) 
 

Function checks the DB sync mark.

Parameters:
drive Drive letter string.
Returns:
TRUE if sync mark is set.

Definition at line 216 of file db.c.

References FAT_cd(), FAT_fclose(), FAT_fopen(), FAT_fread(), rb, and strDBDIR.

00217 {
00218     st_DBHEADER         header;
00219     BOOL                ret = TRUE;
00220     File *              file;
00221     
00222     FAT_cd(drive);
00223     if( TRUE == FAT_cd(strDBDIR) )
00224     {
00225         if( TRUE == FAT_cd(strAUDIODIR) )
00226         {
00227             if(file = FAT_fopen(strAUDIO, rb))
00228             {
00229                 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER)) 
00230                     == sizeof(st_DBHEADER) ) 
00231                 {
00232                     if( !(header.status & 0x0002) ) ret = FALSE;
00233                 }
00234                 FAT_fclose(file);
00235             }
00236         }
00237     }
00238             
00239     return ret;
00240 }

Here is the call graph for this function:

DB_ID DB_childID DB_ID  rootID,
DB_FIELDIDX  fldIdx
 

Function returns child DB ID givent the child field index.

Parameters:
rootID Root DB ID.
fldIdx Child field index.
Returns:
Child DB ID.

Definition at line 1635 of file db.c.

References st_DBIDTREE::node.

Referenced by MENU__createPresetMenu(), and UI_setupPlayQ().

01636 {
01637     st_DBIDNODE * node;
01638 
01639     node = &DB_idtree.node[rootID];
01640     
01641     node = node->child;
01642     while(fldIdx--)
01643     {
01644         node = node->next;
01645     }
01646     
01647     return node->id;    
01648 }

BOOL DB_deleteRecord DB_ID  id,
DB_ENTRY  entry
 

Function deletes specified record from the root database, it also updtes all corresponding child database.

Parameters:
id DB ID.
entry DB entry.
Returns:
TRUE if record successfully deleted, otherwise FALSE.

Definition at line 2011 of file db.c.

References DB__cdDBdir(), DB__deleteChildRecord(), DB__name(), and DB__rootID().

02012 {
02013     if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)   return FALSE;
02014     return DB__deleteChildRecord(id, entry);
02015 }

Here is the call graph for this function:

BOOL DB_deleteRecordByMdb DB_ID  id,
DB_MDBOFFSET  mdb
 

Function deletes specified record indexed by root offset from the root database, it also updtes all corresponding child database.

Parameters:
id DB ID.
mdb DB root mdb offset.
Returns:
TRUE if record successfully deleted, otherwise FALSE.

Definition at line 2029 of file db.c.

References DB__cdDBdir(), DB__deleteChildRecord(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, and SEEK_HEAD.

Referenced by UI_PSF_play().

02030 {
02031     DB_MDBOFFSET offset;
02032     USHORT      entryNum;
02033     DB_ENTRY    entry = 1;
02034     File *      idxfile;
02035     BOOL        ret = FALSE;
02036 
02037     if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)   return FALSE;
02038     
02039     // Fetch entry number from SAI file.
02040     idxfile = FAT_fopen(DB__name(id, SAI), rb);
02041     FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02042     FAT_fread(idxfile, &entryNum, 1);
02043 
02044     FAT_fseek(idxfile, (unsigned long)(1+DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
02045     while(entryNum--)
02046     {
02047         if(2!=FAT_fread(idxfile, (unsigned short *)&offset, 2)) break;
02048         if(mdb == offset)
02049         {
02050             ret = TRUE;
02051             break;
02052         }
02053         // Skip the PAI entry.
02054         if(2!=FAT_fread(idxfile, (unsigned short *)&offset, 2)) break;
02055         
02056         entry++;
02057     }
02058     FAT_fclose(idxfile);
02059     
02060     if(TRUE == ret) return DB__deleteChildRecord(id, entry);
02061     
02062     return FALSE;
02063 }

Here is the call graph for this function:

DB_FIELDLEN DB_getField const DB_DATA *  pRecord,
DB_FIELDIDX  fldIdx,
DB_DATA *  pData,
st_DBINFO pInfo
 

Function gets interpreted data of the specified record field out of given record.

Parameters:
pInfo DB info data pointer.
pRecord DB record data.
fldIdx DB field index.
pData Field data buffer.
Returns:
Data length in words.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Definition at line 1846 of file db.c.

References DB__cdDBdir(), DB__getField(), DB__getRecord(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fseek(), st_DBINFO::id, st_DBIDTREE::node, st_DBINFO::numOfKeys, rb, and SEEK_HEAD.

Referenced by UI_interpretAudioRecord(), UI_interpretFailedHisiRecord(), UI_interpretIdentifiedHisiRecord(), UI_interpretUnidentifiedHisiRecord(), and UI_setupPlayQ().

01850 {
01851     st_DBIDNODE *       node;
01852     DB_ID               tmpid;
01853     DB_MDBOFFSET        childMdb;
01854     File *              file;
01855     unsigned short      ii;
01856     unsigned short      record[DB_MAXRECLEN];
01857     
01858     if(NULL == pData) return 0;
01859     
01860     ii = DB__getField(pRecord, fldIdx, pData);
01861     
01862     if( (0==fldIdx)||(0==ii)||(fldIdx >= pInfo->numOfKeys) ) return ii;
01863     
01865     // Currently only the first child MDB in field is fetched, this is 
01866     // definitely a hole in algorithm, since there might be more than
01867     // one there. I simply don't worry about it now because this
01868     // feature is not used anyway.
01870     childMdb = ((unsigned long)(*(unsigned short *)pData)<<16)|(*((unsigned short *)pData+1));
01871     
01872     // Virtual DB, no data available.
01873     //if(pInfo->bVirtual == TRUE) return 0; 
01874     
01875     /* Get field DB id. */
01876     //node = DB_idtree.node[pInfo->id].child; 
01877     node = DB_idtree.node[DB_rootID(pInfo->id)].child; 
01878     for(ii = 0; ii < fldIdx; ii++ ) node = node->next;
01879     
01880     tmpid = node->id;
01881 
01882     DB__cdDBdir(DB__name(DB__rootID(tmpid), MDB));
01883     
01884     /* Open child DB MDB file. */
01885     file = FAT_fopen(DB__name(tmpid, MDB), rb);
01886 
01887     /* Seek to offset. */
01888     FAT_fseek(file, childMdb, SEEK_HEAD);
01889     
01890     DB__getRecord(file, record);
01891     FAT_fclose(file);
01892 
01893     return( DB__getField(record, 0, pData) );
01894 }

Here is the call graph for this function:

DB_MDBOFFSET DB_getMdbByRecord DB_ID  id,
const unsigned short *  pData
 

Function checks return the MDB offset by record data.

Parameters:
id DB ID.
pData DB primary record data.
Returns:
MDB offset of record.

Definition at line 1763 of file db.c.

References DB__cdDBdir(), DB__getField(), DB__name(), DB__rootID(), DB_MAXFIELDLEN, FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, SEEK_HEAD, and SEEK_MID.

01764 {
01765     unsigned short  field[DB_MAXFIELDLEN];
01766     DB_ENTRY        entry;          /* SAI entry number. */
01767     DB_MDBOFFSET    offset;         /* File offset in MDB file. */
01768     File *          idxfile;
01769     File *          dbfile;
01770 
01771     if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)   return 0;
01772     
01773     /* Open MDB and SAI files. */
01774     idxfile = FAT_fopen(DB__name(id, SAI), rb);
01775     dbfile  = FAT_fopen(DB__name(id, MDB), rb);
01776     
01777     
01778     /* Points to the first valid entry. */
01779     entry = DB_SAIFIRSTENTRY;
01780 
01781 
01782     /* SAI entry takes 64bits, 4 words per entry. */
01783     FAT_fseek(idxfile, (long)entry << 2, SEEK_HEAD);
01784     FAT_fread(idxfile, (unsigned short *)&offset, 2);
01785 
01786     while(offset)
01787     {
01788         unsigned short len;
01789         
01790         FAT_fseek(dbfile, offset, SEEK_HEAD);
01791         FAT_fread(dbfile, field, DB_MAXFIELDLEN);
01792 
01793         /* Only compare the primary field. */
01794         if(len = DB__getField(field, 0, field))
01795         {
01796             unsigned short * pS = (unsigned short *)field;
01797             unsigned short * pD = (unsigned short *)pData;
01798             do
01799             {
01800                 if(*pS++ != *pD++) break;
01801         
01802             } while(--len);
01803             
01804             if( 0 == len )
01805             {
01806                 /* Record found!. */
01807                 FAT_fclose(idxfile);
01808                 FAT_fclose(dbfile);
01809     
01810                 return offset;
01811             }
01812         }
01813 
01814         entry++;
01815 
01816         /* Skip PAI entry. */
01817         FAT_fseek(idxfile, 2, SEEK_MID);            
01818         FAT_fread(idxfile, (unsigned short *)&offset, 2);
01819     }
01820 
01821 
01822     /* Record does not exist. */
01823     FAT_fclose(idxfile);
01824     FAT_fclose(dbfile);
01825 
01826     // Not found.
01827     return 0L;  
01828 }

Here is the call graph for this function:

DB_ENTRY DB_getSaiByMdb ULONG  mdb,
DB_ID  id
 

Function calculates SAI entry based on MDB offset.

Parameters:
mdb MDB offset.
id DB ID.
Returns:
DB SAI entry.

Definition at line 1703 of file db.c.

References DB__cdDBdir(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, and SEEK_HEAD.

Referenced by UI_SF_dbmenu().

01704 {
01705     File *          idxfile;
01706     unsigned long   signature;
01707     DB_ENTRY        entry;
01708     unsigned short  entryNum;
01709     ULONG           mdbEnt[2];
01710     
01711     /* Change to corresponding root DB directory. */
01712     if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) 
01713     {   
01714         return DB_INVALID_ENTRY;
01715     }
01716 
01717     
01718     /* Open SAI file. */
01719     idxfile = FAT_fopen(DB__name(id, SAI), rb);
01720 
01721     /* Check SAI file signature for safe. */
01722     FAT_fread(idxfile, (unsigned short *)&signature, 2);
01723 
01724     if( signature != DB_SAI_SIGNATURE ) 
01725     {
01726         /* Invalid field access. */
01727         FAT_fclose(idxfile);
01728         return DB_INVALID_ENTRY;
01729     }
01730     
01731 
01732     /* Check if dbEntry is valid. */
01733     FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
01734     FAT_fread(idxfile, &entryNum, 1);
01735 
01736     FAT_fseek(idxfile, (unsigned long)(DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
01737     entry = 0;
01738     while(entryNum--)
01739     {
01740         FAT_fread(idxfile, (unsigned short *)&mdbEnt, 4);
01741         if(mdbEnt[0] == mdb) 
01742         {
01743             FAT_fclose(idxfile);
01744             return entry;
01745         }
01746         entry++;
01747     }
01748     
01749     FAT_fclose(idxfile);
01750     return DB_INVALID_ENTRY;    
01751 }

Here is the call graph for this function:

st_DBINFO* DB_info DB_HDL  hdl  ) 
 

Function returns information of specified database.

Parameters:
hdl DB query handle.
Returns:
DB info data pointer.

Definition at line 1517 of file db.c.

Referenced by UI_setupPlayQ().

01518 {
01519     return(&DB_qinfo[hdl]);
01520 }

BOOL DB_init void   ) 
 

Function initializes DB controls.

Returns:
TRUE if successfully initialized, otherwise FALSE.

Definition at line 1487 of file db.c.

References st_DBIDTREE::counter, st_DBREGIST::fname, and st_DBQUERYCTL::free.

01488 {
01489     unsigned short      ii;
01490     
01491     /* Clear database regisration table. */
01492     for ( ii = 0; ii < DB_MAX_ID; ii++ ) DB_registration[ii].fname = NULL;
01493     
01494     /* Reset database ID tree. */
01495     DB_idtree.counter = 0;  
01496 
01497     /* Reset all available query controls. */
01498     for( ii = 0; ii < DB_OPENMAX; ii++ ) DB_qctl[ii].free = TRUE;
01499 
01500     /* Initialize DB tree globale controls. */  
01501     //DB_ctl.actvHdl = DB_INVALID_HDL;
01502     
01503     return TRUE;
01504 }

DB_ID DB_parentID DB_ID  id  ) 
 

Function returns parent DB ID of the givent the child DB.

Parameters:
id Child DB ID.
Returns:
Parent DB ID.

Definition at line 1659 of file db.c.

References st_DBIDTREE::node.

01660 {
01661     st_DBIDNODE * node;
01662 
01663     node = &DB_idtree.node[id];
01664     
01665     /* Traverse to parent. */
01666     if(node->parent) node = node->parent;
01667     
01668     return node->id;    
01669 }

BOOL DB_queryClose DB_HDL  hdl  ) 
 

Function closes the specified database query operation and releases corresponding control data object.

Parameters:
hdl DB query handle.
Returns:
TRUE if handle successfully closed, otherwise FALSE.

Definition at line 574 of file db.c.

References st_DBQUERYCTL::dbfile, FAT_fclose(), st_DBQUERYCTL::free, and st_DBQUERYCTL::idxfile.

Referenced by MENU__createPresetMenu(), UI_audioPresetUpdate(), UI_playQreset(), UI_playQshutdown(), UI_presetAudio(), and UI_setupPlayQ().

00575 {
00576     st_DBQUERYCTL * pCtl;
00577     
00578     if(hdl == DB_INVALID_HDL )  return FALSE;
00579     pCtl = &DB_qctl[hdl];
00580     if(pCtl->free == TRUE)      return TRUE;
00581     
00582     FAT_fclose(pCtl->dbfile);       
00583     FAT_fclose(pCtl->idxfile);      
00584 
00585     pCtl->free = TRUE;
00586 
00587     return TRUE;    
00588 }

Here is the call graph for this function:

DB_HDL DB_queryFirst DB_ID  id,
DB_FIELDIDX  fldIdx,
DB_ENTRY  fldEntry,
DB_ENTRY  dbEntry,
DB_DATA *  pData
 

Function queries the specified database and sets up query controls.

Parameters:
id DB ID.
fldIdx Query field index.
fldEntry Query field entry.
dbEntry DB data entry. First long word contains record MDB offset.
pData DB record data.
Returns:
Valid query handle if successful, otherwise DB_INVALID_HDL. Note that a valid handle return does NOT mean a valid record has been found, the record might be empty.

Definition at line 377 of file db.c.

References st_DBINFO::bVirtual, DB__getRecord(), DB__info(), DB__name(), st_DBQUERYCTL::dbfile, FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), st_DBQUERYCTL::free, st_DBQUERYCTL::idx, st_DBQUERYCTL::idxfile, st_DBIDTREE::node, st_DBINFO::numOfKeys, st_DBINFO::numOfPAIent, st_DBQUERYCTL::pai, rb, SEEK_HEAD, and st_DBQUERYCTL::step.

Referenced by MENU__createPresetMenu(), UI_audioPresetUpdate(), UI_playQreset(), UI_presetAudio(), and UI_setupPlayQ().

00382 {
00383     DB_HDL          hdl;
00384     DB_ID           tmpid;
00385     USHORT          entryNum;
00386     unsigned short  ii;
00387     st_DBQUERYCTL * pCtl;
00388     st_DBIDNODE *   node;
00389     st_DBINFO *     pInfo;
00390             
00391     /* Locate first available query control OBJ. */
00392     for( ii = 0; ii < DB_OPENMAX; ii++ ) 
00393     {       
00394         if( DB_qctl[ii].free == TRUE )  break;
00395     }
00396     if ( ii == DB_OPENMAX ) return DB_INVALID_HDL;  
00397 
00398     /* Valid handle found. */   
00399     hdl         = ii;
00400     pCtl        = &DB_qctl[hdl];
00401     pCtl->free  = FALSE;
00402     pInfo       = &DB_qinfo[hdl];
00403     
00404     if( DB__info(id, pInfo) == FALSE )
00405     {
00406         pCtl->free = TRUE;
00407         return DB_INVALID_HDL;
00408     }
00409     
00410     // start querying.
00411     node = &DB_idtree.node[id];
00412     
00413     /* Check to see if id points to a virtual DB. */
00414     //if( DB_registration[id].fname == NULL ) 
00415     if(pInfo->bVirtual == TRUE)
00416     {
00417         /* Virtual DB, access through its parent. */
00418         node = node->parent;        
00419         return( _query(node->id, dbEntry, pData, hdl) );        
00420     }
00421 
00422     /* Check to see if primary key is used to access the database. */
00423     //if( fldIdx == 0 )
00424     if( (fldIdx == 0)||(fldIdx == 0xffff) )
00425     {
00426         /* Primary key detected, query DB directly. */
00427         return( _query(id, dbEntry, pData, hdl) );
00428     }
00429 
00430     /* Following code to access DB using specified key. */
00431     /* Check to see if this is a valid key. */
00432     //if( DB__info(id, &info) == FALSE ) return DB_INVALID_HDL;
00433     //if( fldIdx >= info.numOfKeys ) return DB_INVALID_HDL;
00434     if( fldIdx >= pInfo->numOfKeys )
00435     {
00436         pCtl->free = TRUE;
00437         return DB_INVALID_HDL;
00438     }
00439 
00440     /* Fetch the access field DB ID. */
00441     node = node->child; 
00442     for(ii = 0; ii < fldIdx; ii++ ) node = node->next;
00443 
00444     tmpid = node->id;
00445 
00446     /* Locate the key. */
00447     hdl = _query(tmpid, fldEntry, pData, hdl);
00448     if(hdl == DB_INVALID_HDL) return hdl;
00449 
00450 
00451     //pCtl = &DB_qctl[hdl];
00452     /* Close current MDB file. */
00453     FAT_fclose(pCtl->dbfile);
00454 
00455     /* Close current SAI file. */
00456     FAT_fclose(pCtl->idxfile);
00457 
00458 
00459     /* Open MDB file. */
00460     pCtl->dbfile = FAT_fopen(DB__name(id, MDB), rb);
00461 
00462     /* Open PAI file. */
00463     pCtl->idxfile = FAT_fopen(DB__name(tmpid, PAI), rb);
00464     
00465     if( pCtl->pai == 0) 
00466     {
00467         /* Empty PAI entry. */
00468         pCtl->free = TRUE;
00469 
00470         FAT_fclose(pCtl->idxfile);
00471         FAT_fclose(pCtl->dbfile);
00472         return DB_INVALID_HDL;
00473     }
00474 
00475     /* PAI entry always takes 32 bits. */
00476     pCtl->step = 1;
00477     
00478     /* Locate the entry number. */
00479     FAT_fseek(pCtl->idxfile, pCtl->pai - 4, SEEK_HEAD);
00480     FAT_fread(pCtl->idxfile, &entryNum, 1);
00481     
00482     pInfo->numOfPAIent = entryNum+1;
00483     if(dbEntry > entryNum)
00484     {
00485         /* Empty PAI entry. */
00486         pCtl->free = TRUE;
00487         FAT_fclose(pCtl->idxfile);
00488         FAT_fclose(pCtl->dbfile);
00489         return DB_INVALID_HDL;
00490     }
00491     
00492     pCtl->idx = pCtl->pai;
00493 
00494 #if 1
00495     /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00496     ** I chose the confusing way to ease my UI application. :(
00497     ** Any query via PAI MUST add ONE entry offset, thus the UI
00498     ** can use the same code to query no matter it is via SAI or PAI,
00499     ** since "dbEntry == 0" always points to the default empty entry
00500     ** if we directly query the DB through SAI ( fldIdx == 0 ).
00501     ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00502     */
00503     pCtl->idx -= 2; 
00504 #endif
00505 
00506     /* Locate the record index. */
00507     FAT_fseek(pCtl->idxfile, pCtl->idx + (dbEntry << 1), SEEK_HEAD);
00508     FAT_fread(pCtl->idxfile, (unsigned short *)&pCtl->pai, 2);
00509         
00510     /* Locate the record. */
00511     FAT_fseek(pCtl->dbfile, pCtl->pai, SEEK_HEAD);
00512 
00513     /* Fetch record. */
00514     if( DB__getRecord(pCtl->dbfile, pData) == FALSE ) 
00515     {       
00516         /* No record available. */
00517         pCtl->free = TRUE;
00518         FAT_fclose(pCtl->idxfile);
00519         FAT_fclose(pCtl->dbfile);
00520         return DB_INVALID_HDL;
00521     }
00522 
00523     return hdl;
00524 }

Here is the call graph for this function:

BOOL DB_queryNext DB_HDL  hdl,
DB_ENTRY  entry,
DB_DATA *  pData
 

Function queries database through specified database handle.

Parameters:
hdl DB query handle.
entry DB data entry.
pData DB record data buffer. First long word contains record MDB offset.
Returns:
TRUE if successfully queried, otherwise FALSE.

Definition at line 539 of file db.c.

References DB__getRecord(), st_DBQUERYCTL::dbfile, FAT_fread(), FAT_fseek(), st_DBQUERYCTL::idx, st_DBQUERYCTL::idxfile, SEEK_HEAD, and st_DBQUERYCTL::step.

Referenced by UI_playQprevious(), and UI_setupPlayQ().

00540 {
00541     DB_MDBOFFSET    mdb = 0L;
00542     USHORT *        pD = pData;
00543     st_DBQUERYCTL * pCtl = &DB_qctl[hdl];
00544     
00545     FAT_fseek(pCtl->idxfile, pCtl->idx + (entry<<pCtl->step),SEEK_HEAD);
00546     FAT_fread(pCtl->idxfile, (unsigned short *)&mdb, 2);
00547                     
00548     /* Reached top / bottom ? */
00549     if( mdb == 0 ) return FALSE;        
00550     
00551     /* Locate the record. */
00552     FAT_fseek(pCtl->dbfile, mdb, SEEK_HEAD);
00553     
00554     if(pD)
00555     {
00556         *(USHORT*)pD++ = mdb>>16;
00557         *(USHORT*)pD++ = mdb&0xffff;
00558     }
00559     
00560     return( DB__getRecord(pCtl->dbfile, pD) );  
00561 }

Here is the call graph for this function:

BOOL DB_removeRecord DB_ID  childId,
DB_ENTRY  childEntry,
DB_ENTRY  paiEntry
 

Function removes specified record reference from the child database.

Parameters:
childId Child DB ID.
childEntry child DB entry.
paiEntry child DB PAI entry.
Returns:
TRUE if record successfully removed, otherwise FALSE.

Definition at line 255 of file db.c.

References DB__cdDBdir(), DB__deleteChildRecord(), DB__fieldIndex(), DB__getRecord(), DB__name(), DB__recordLen(), DB__removePAIentry(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, rb, and SEEK_HEAD.

00256 {
00257     unsigned short  entryNum;
00258     DB_MDBOFFSET    root;
00259     DB_MDBOFFSET    child;
00260     DB_PAIOFFSET    pai;
00261     DB_FIELDIDX     fldidx;
00262     DB_RECLEN       len;
00263     File *          idxfile;
00264     File *          dbfile;
00265     unsigned short  record[DB_MAXRECLEN];   
00266     
00267     if(DB__cdDBdir(DB__name(DB__rootID(childId), MDB)) == FALSE)   return FALSE;    
00268     
00269     fldidx = DB__fieldIndex(childId);
00270 
00271     /* Fetch child MDB offset. */
00272     idxfile = FAT_fopen(DB__name(childId, SAI), rb);
00273     FAT_fseek(idxfile, (long)(childEntry + DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
00274     FAT_fread(idxfile, (unsigned short *)&child, 2);
00275     FAT_fread(idxfile, (unsigned short *)&pai, 2);
00276     FAT_fclose(idxfile);
00277 
00278     /* Update root record, remove child index. */
00279     idxfile = FAT_fopen(DB__name(childId, PAI), rb);
00280     FAT_fseek(idxfile, pai+((paiEntry-1)<<1), SEEK_HEAD);
00281     FAT_fread(idxfile, (unsigned short *)&root, 2);
00282     FAT_fclose(idxfile);    
00283 
00284     dbfile = FAT_fopen(DB__name(DB__rootID(childId), MDB), r_b);
00285     FAT_fseek(dbfile, root, SEEK_HEAD);
00286     DB__getRecord(dbfile, record);
00287     
00288     _removeChildIdx(record, fldidx, child);
00289 
00290     len = DB__recordLen(record);
00291 
00292     FAT_fseek(dbfile, root, SEEK_HEAD);
00293     FAT_fwrite(dbfile, (unsigned short *)record, len);
00294     FAT_fclose(dbfile);
00295 
00296 
00297     /* Search child PAI to remove specified parent entry. */
00298     DB__removePAIentry(childId, root, pai, &entryNum);
00299 
00300     if(entryNum == 0)
00301     {
00302         /* No PAIs left for this entry, delete it. */
00303         DB__deleteChildRecord(childId, childEntry);
00304     }
00305 
00306     return TRUE;
00307 }

Here is the call graph for this function:

void DB_setSyncMark const char *  drive  ) 
 

Function sets the DB sync mark.

The mark is set by firmware and cleared by NSM.

Parameters:
drive Drive letter string.

Definition at line 181 of file db.c.

References FAT_cd(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, SEEK_HEAD, st_DBINFO::status, and strDBDIR.

00182 {
00183     st_DBHEADER         header;
00184     File *              file;
00185     
00186     FAT_cd(drive);  
00187     if( TRUE == FAT_cd(strDBDIR) )
00188     {
00189         if( TRUE == FAT_cd(strAUDIODIR) )
00190         {
00191             if(file = FAT_fopen(strAUDIO, r_b))
00192             {
00193                 FAT_fseek(file, 0, SEEK_HEAD);
00194                 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER)) 
00195                     == sizeof(st_DBHEADER) ) 
00196                 {
00197                     header.status |= 0x0002;    
00198                 }
00199                 FAT_fseek(file, 0, SEEK_HEAD);
00200                 FAT_fwrite(file, (unsigned short *)&header, sizeof(st_DBHEADER)); 
00201                 FAT_fclose(file);
00202             }
00203         }
00204     }
00205 }

Here is the call graph for this function:


Generated on Wed Jan 19 01:12:52 2005 for neuros-firmware by  doxygen 1.3.9.1