📄 projlistmodel.c
字号:
if (NULL == dbRecord) { // +++ FIX THIS +++ Output error in debug mode return; } else { dbRecordStruct=MemHandleLock(dbRecord); if (NULL == dbRecordStruct) { // +++ FIX THIS +++ Output error in debug mode return; } // // update the sentinel value so we know that we've seen it during this scan // DmWrite(dbRecordStruct,OffsetOf(ProjectListEntry,lastSentinelValue),&sentinelValue,sizeof(sentinelValue)); MemHandleUnlock(dbRecord); DmReleaseRecord((*plGlobals)->databaseRef,recordNumber,true); // true means record was modified } } else { // // Have to create // // dbRecord=DmNewRecord((*plGlobals)->databaseRef,&recordNumber,sizeof(ProjectListEntry)); if (NULL == dbRecord) { DEBUG1("Error creating new record in Project List Database"); return; } else { dbRecordStruct=MemHandleLock(dbRecord); if (NULL == dbRecordStruct) { // +++ FIX THIS +++ Output error in debug mode return; } // // update the sentinel value so we know that we've seen it during this scan // newEntry->lastSentinelValue=sentinelValue; // // write out the new record // DmWrite(dbRecordStruct,0,newEntry,sizeof(ProjectListEntry)); MemHandleUnlock(dbRecord); DmReleaseRecord((*plGlobals)->databaseRef,recordNumber,true); // true means record was modified } }}void ProjectListMODELUpdate(void){ ProjectListMODELUpdateINTERNAL(&PLM_Globals);}void ProjectListMODELUpdateINTERNAL(struct ProjectListMODELGlobals **plGlobals){ Boolean newSearch=true; DmSearchStateType stateInfo; ProjectListEntry newEntry; LocalID dbID; Err err; UInt16 i; MemHandle dbRecord; ProjectListEntry *dbRecordStruct; UInt16 sentinelValue; Boolean deleteTheRecord; // // increment the sentinel value so we know when an item has not been seen and can be deleted // I guess you could call our method mark and sweep, we go through all the databases, adding them // to our database if we have not seen them (with the latest sentinel value), otherwise we simply // update the sentinel value. At the end of this function we delete any items that have a sentinel // value different than the last one. // sentinelValue=GetLastSentinelValueINTERNAL(plGlobals)+1; SetLastSentinelValueINTERNAL(plGlobals,sentinelValue); // zero out the fields of the ProjectListEntry for starters MemSet(&newEntry,sizeof(ProjectListEntry),0); // // Go through all the databases on the device and put them in the database // do { // start the search err=DmGetNextDatabaseByTypeCreator(newSearch,&stateInfo,'DATA',CREATOR,false,&newEntry.cardNumber,&dbID); // flip state for API newSearch=false; // if we found something if (errNone == err) { // grab database name DmDatabaseInfo(newEntry.cardNumber, dbID, newEntry.databaseName, NULL, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL); // if the name is prepended (new databases since V0.10), then remove the extra if (StrStr(newEntry.databaseName, gPrepend) == newEntry.databaseName) MemMove(newEntry.databaseName, newEntry.databaseName + StrLen(gPrepend),StrLen(newEntry.databaseName+StrLen(gPrepend)) + 1); // record the project in our database updateAddProjectModelEntryINTERNAL(plGlobals,&newEntry); } } while (errNone == err); // // Now we go about deleting databases that have dissapeared for some reason, this would typically be during a HotSync // or if some other program has deleted the database. Since we should delete entries in here ourselves when we delete them, // ditto for database creation and renaming. // // Go backwards so that deleting an entry does not change the numbering of the records we have not seen yet for (i=DmNumRecords((*plGlobals)->databaseRef);i>0;i--) { deleteTheRecord=false; dbRecord=DmQueryRecord((*plGlobals)->databaseRef,i-1); if (NULL == dbRecord) { // +++ FIX THIS +++ Output error in debug mode return; } else { dbRecordStruct=MemHandleLock(dbRecord); if (NULL == dbRecordStruct) { // +++ FIX THIS +++ Output error in debug mode return; } // // If the sentinel's don't match, this project has gone away // if (dbRecordStruct->lastSentinelValue != sentinelValue) deleteTheRecord=true; MemHandleUnlock(dbRecord); if (true == deleteTheRecord) DmRemoveRecord((*plGlobals)->databaseRef,i-1); } }}// returns true if record is in database (recordNumber contains location)// returns false if record not there (recordNumber contains insertion pos.).Boolean FindInSortedDatabase(DmOpenRef db, DmComparF *comparFunc, void *findRec, UInt16 *recordNumber){ Boolean foundIt = false; *recordNumber = DmFindSortPosition(db, findRec, NULL, comparFunc, 0); if (*recordNumber > 0) { MemHandle h; void *potentialMatchRec; // matching record would be at *recordNumber - 1 h = DmQueryRecord(db, *recordNumber - 1); potentialMatchRec = MemHandleLock(h); if ((*comparFunc)(findRec, potentialMatchRec, 0, NULL, NULL, NULL) == 0) { foundIt = true; (*recordNumber)--; } MemHandleUnlock(h); } return foundIt;}// Function to compare two ProjectEntry structures by card number, then by project nameInt16 CompareProjectEntryByCardProjectName(void *r1, void *r2,Int16 unused1, SortRecordInfoPtr unused2, SortRecordInfoPtr unused3, MemHandle unused4){ ProjectListEntry *rec1=(ProjectListEntry *)r1; ProjectListEntry *rec2=(ProjectListEntry *)r2; Int16 result; result = rec1->cardNumber-rec2->cardNumber; if (0 == result) result = StrCompare(rec1->databaseName,rec2->databaseName); return result;}/*********************************************************************** * * FUNCTION: ToolsSeekRecord * * DESCRIPTION: Given the index of a to do record, this routine scans * forewards or backwards for displayable to do records. * * PARAMETERS: indexP - pointer to the index of a record to start from; * the index of the record sought is returned in * this parameter. * * offset - number of records to skip: * 0 - mean seek from the current record to the * next display record, if the current record is * a display record, its index is retuned. * 1 - mean seek foreward, skipping one displayable * record * -1 - means seek backwards, skipping one * displayable record * * * RETURNED: false is return if a displayable record was not found. * ***********************************************************************/Boolean ProjectListMODELSeekRecord (UInt16 * indexP, Int16 offset, Int16 direction){ DmSeekRecordInCategory (PLM_Globals->databaseRef, indexP, offset, direction, ProjectListMODELGetCurrentCategory()); if (DmGetLastErr()) return (false); return (true);}void ProjectListModelAddProject(UInt16 cardNo, const char *dbName){UInt16 recordNumber;ProjectListEntry newEntry; MemSet(&newEntry,sizeof(ProjectListEntry),0); newEntry.cardNumber=cardNo; SafeCopy(newEntry.databaseName,dbName,sizeof(newEntry.databaseName)); updateAddProjectModelEntryINTERNAL(&PLM_Globals,&newEntry); if (FindInSortedDatabase(PLM_Globals->databaseRef,CompareProjectEntryByCardProjectName,&newEntry,&recordNumber)) ProjectListMODELSetRecordCategory(recordNumber,ProjectListMODELGetCurrentCategory());}void ProjectListModelRenameProject(UInt16 cardNo, const char *dbNameOld,const char *dbNameNew){UInt16 recordNumber;UInt16 category;ProjectListEntry findEntry;ProjectListEntry *currentEntry;MemHandle currentEntryHandle; MemSet(&findEntry,sizeof(ProjectListEntry),0); findEntry.cardNumber=cardNo; SafeCopy(findEntry.databaseName,dbNameOld,sizeof(findEntry.databaseName)); if (FindInSortedDatabase(PLM_Globals->databaseRef,CompareProjectEntryByCardProjectName,&findEntry,&recordNumber)) { category=ProjectListMODELGetRecordCategory(recordNumber); DmDetachRecord(PLM_Globals->databaseRef,recordNumber,¤tEntryHandle); currentEntry=MemHandleLock(currentEntryHandle); if (NULL == currentEntry) { DEBUG1("Unable to rename project"); return; } DmWrite(currentEntry, OffsetOf(ProjectListEntry, databaseName), dbNameNew, sizeof(currentEntry->databaseName)); if(!FindInSortedDatabase(PLM_Globals->databaseRef,CompareProjectEntryByCardProjectName,currentEntry,&recordNumber)) { MemPtrUnlock(currentEntry); DmAttachRecord(PLM_Globals->databaseRef,&recordNumber,currentEntryHandle,NULL); ProjectListMODELSetRecordCategory(recordNumber,category); } else { MemPtrUnlock(currentEntry); DEBUG1("Unable to rename project 2"); } }}void ProjectListModelDeleteProject(UInt16 cardNo, const char *dbName){UInt16 recordNumber;ProjectListEntry newEntry; MemSet(&newEntry,sizeof(ProjectListEntry),0); newEntry.cardNumber=cardNo; SafeCopy(newEntry.databaseName,dbName,sizeof(newEntry.databaseName)); if (FindInSortedDatabase(PLM_Globals->databaseRef,CompareProjectEntryByCardProjectName,&newEntry,&recordNumber)) DmRemoveRecord(PLM_Globals->databaseRef,recordNumber);}UInt16 ProjectListModelGetProjectCategory(UInt16 cardNo, const char *dbName){UInt16 recordNumber;ProjectListEntry newEntry; MemSet(&newEntry,sizeof(ProjectListEntry),0); newEntry.cardNumber=cardNo; SafeCopy(newEntry.databaseName,dbName,sizeof(newEntry.databaseName)); if (FindInSortedDatabase(PLM_Globals->databaseRef,CompareProjectEntryByCardProjectName,&newEntry,&recordNumber)) return ProjectListMODELGetRecordCategory(recordNumber); return dmUnfiledCategory;}void ProjectListModelSetProjectCategory(UInt16 cardNo, const char *dbName, UInt16 newCategory){UInt16 recordNumber;ProjectListEntry newEntry; MemSet(&newEntry,sizeof(ProjectListEntry),0); newEntry.cardNumber=cardNo; SafeCopy(newEntry.databaseName,dbName,sizeof(newEntry.databaseName)); if (FindInSortedDatabase(PLM_Globals->databaseRef,CompareProjectEntryByCardProjectName,&newEntry,&recordNumber)) ProjectListMODELSetRecordCategory(recordNumber,newCategory);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -