📄 sugarmemodb.c
字号:
newSize = sizeof(HeaderRecord) + sizeof(HeaderItem) * GetHeaderItemNumber(db, srcHeaderIndex);
srcH = DmQueryRecord(db, srcHeaderIndex);
if (srcH == NULL) {
ErrAlert(DmGetLastErr());
return;
}
srcP = MemHandleLock(srcH);
destH = DmResizeRecord(db, destHeaderIndex, newSize);
if (destH == NULL) {
ErrAlert(DmGetLastErr());
return;
}
destP = MemHandleLock(destH);
// Important! dont overwrite header flag bit
// Important! plus offset!!!!
offsetP = &srcP->itemNumbers;
DmWrite(destP, sizeof(Header), offsetP, newSize - sizeof(Header));
MemPtrUnlock(srcP);
MemPtrUnlock(destP);
}
// search all SGMM database and stores the cardNo&dbID in globals ListH&DBListCount;
// used in test queue update in appstart() and mainlist in mainform
void GetDBList(){
}
// check if a word record contains data
Boolean WordRecordContainsData (WordRecordType* recordP)
{
UInt16 i;
// Look for a field which isn't empty
for (i = WordFieldQuestion; i < WordFieldsCount; i++)
{
if (recordP->field[i] != NULL)
return true;
}
return false;
}
// find the proper position of a string as question field, used in browse form
// for fast jump
UInt16 InstantLookupPosition(DmOpenRef db, Char* p){
WordRecordType record;
WordPackedRecord* packed;
MemHandle recordH;
UInt16 i, newIndex;
//prepare a psuedo-record
record.header.allBits = BitAtPosition(RawQueue);
for (i = WordFieldQuestion; i < WordFieldsCount; i ++) record.field[i] = NULL;
record.field[WordFieldQuestion] = p;
recordH = DmNewHandle(db, WordUnpackedSize(&record));
packed = MemHandleLock(recordH);
PackRecord(&record, packed);
newIndex = DmFindSortPosition(db, packed, NULL, (DmComparF*)WordDBComparePackedRecords, NULL);
MemPtrUnlock(packed);
MemHandleFree(recordH);
if (newIndex > 0) newIndex --;
return newIndex;
}
void UnpackSuperMemoRecord(DmOpenRef db, UInt16 index, WordRecordType *record, MemHandle* recordH, char* cache){
char* recordP;
char* p;
(*recordH) = DmQueryRecord(db, index);
if (*recordH == NULL) return;
recordP = MemHandleLock(*recordH);
p = recordP + 20;
record->field[WordFieldQuestion] = p;
p += StrLen(p) + 1;
StrPrintF(cache, "%s", p);
TranslatePhonetic(cache);
record->field[WordFieldPhonetic] = cache;
p += StrLen(p) + 1;
record->field[WordFieldAnswer] = p;
p += StrLen(p) + 1;
record->field[WordFieldNote3] = p;
}
static void TranslatePhonetic(char* field){
char* p;
UInt16 i, length;
if (field == NULL || *field == '\0') return;
length = StrLen(field);
p = field;
for (i = 0; i < length; i++){
switch((*p)){
case '/':
(*p) = 'e';
break;
case '0':
if (*(p + 1) == ':') (*p) = 'O';
else (*p) = 'D';
break;
case '1':
case 'a':
if (*(p + 1) == ':') (*p) = 'a';
else (*p) = 'R';
break;
case '2':
if (*(p + 1) == ':') (*p) = 'B';
else (*p) = 'E';
break;
case '3':
(*p) = 'A';
break;
case '4':
(*p) = 'Q';
break;
case '5':
(*p) = 'T';
break;
case '6':
(*p) = 'S';
break;
case '7':
(*p) = 'Z';
break;
case '8':
(*p) = 'N';
break;
case '9':
(*p) = 'X';
break;
case 'i':
if (*(p + 1) == ':') (*p) = 'i';
else (*p) = 'I';
break;
case 'u':
if (*(p + 1) == ':') (*p) = 'u';
else (*p) = 'U';
break;
default:
break;
}
p++;
}
}
void PushHeaderBuffer(DmOpenRef db, HeaderIndex bufferIndex, UInt16 dbIndex){
UInt16 index;
if (FindHeaderItemByDBIndex(db, bufferIndex, dbIndex, &index)) return;
AddHeaderItemByDBIndex(db, bufferIndex, dbIndex);
if (GetHeaderItemNumber(db, bufferIndex) > HeaderBufferVolumn)
RemoveHeaderItem(db, bufferIndex, 0);
}
void ValidateHeaderRecord(DmOpenRef db){
HeaderRecord* header;
MemHandle h;
UInt16 num;
UInt16 flag;
//Testing Record 0
h = DmQueryRecord(db, TestingRecordIndex);
if (h == NULL){
ErrAlert(DmGetLastErr());
return;
}
header = MemHandleLock(h);
flag = 0;
SetBitMacro(flag, HeaderFlag);
SetBitMacro(flag, TestingQFlag);
if (header->header.allBits != flag)
CreateHeaderRecord(db, TestingRecordIndex);
MemHandleUnlock(h);
//Learning Record 1
h = DmQueryRecord(db, LearningRecordIndex);
if (h == NULL){
ErrAlert(DmGetLastErr());
return;
}
header = MemHandleLock(h);
flag = 0;
SetBitMacro(flag, HeaderFlag);
SetBitMacro(flag, LearningQFlag);
if (header->header.allBits != flag)
CreateHeaderRecord(db, LearningRecordIndex);
MemHandleUnlock(h);
//Testing Buffer 2
h = DmQueryRecord(db, TestingChoiceBuffer);
if (h == NULL){
ErrAlert(DmGetLastErr());
return;
}
header = MemHandleLock(h);
flag = 0;
SetBitMacro(flag, HeaderFlag);
SetBitMacro(flag, TestingBFlag);
if (header->header.allBits != flag)
CreateHeaderRecord(db, TestingChoiceBuffer);
MemHandleUnlock(h);
//Learning Buffer 3
h = DmQueryRecord(db, LearningChoiceBuffer);
if (h == NULL){
ErrAlert(DmGetLastErr());
return;
}
header = MemHandleLock(h);
flag = 0;
SetBitMacro(flag, HeaderFlag);
SetBitMacro(flag, LearningBFlag);
if (header->header.allBits != flag)
CreateHeaderRecord(db, LearningChoiceBuffer);
MemHandleUnlock(h);
num = DmNumRecordsInCategory(db, dmAllCategories);
if (num == FirstWordRecord) return;
while(num > FirstWordRecord){
h = DmQueryRecord(db, FirstWordRecord);
if (h == NULL){
ErrAlert(DmGetLastErr());
return;
}
header = MemHandleLock(h);
if (GetBitMacro(header -> header.allBits, HeaderFlag)){
MemHandleUnlock(h);
DmRemoveRecord(db, FirstWordRecord);
}
else {
MemHandleUnlock (h);
break;
}
num --;
}
}
void UpdateOldVersionDatabase3(DmOpenRef db){
WordPackedRecord* packed;
WordPackedRecord* packedHelper = 0;
SugarAppInfoType* app;
MemHandle recordH;
//version can handled by this routine
UInt16 num, i, bits;
Header waitingFlag;
Header testingFlag;
LearningStatus ls = FirstLook;
DateType today;
UInt32 days;
UInt32 progress = 0;
UInt32 newProgress;
Char title[20]="升级旧版本数据库";
DateSecondsToDate(TimGetSeconds(), &today);
days = DateToDays(today);
waitingFlag.allBits = 0;
SetBitMacro(waitingFlag.allBits, WaitingQueue);
testingFlag.allBits = 0;
SetBitMacro(testingFlag.allBits, TestingQueue);
num = DmNumRecords(db);
app = GetAppInfoPtr(db);
if (app == NULL) return;
if (app -> version > 1) {
MemPtrUnlock(app);
return;
}
if (num > 0) ProgressPie(progress, title);
for ( i = 0; i < num; i++){
newProgress = (UInt32)i * ProgressFull / (num - 1);
if (newProgress != progress) {
progress = newProgress;
ProgressPie(progress, title);
}
// query record
recordH = DmQueryRecord(db, i);
if (recordH == NULL) {
ErrAlert(DmGetLastErr());
continue;
}
packed = MemHandleLock(recordH);
// check if it is header record, if so, continue;
bits = packed -> header.allBits;
if ((GetBitMacro(bits, HeaderFlag) != 0) || // header queue
(GetBitMacro(bits, 0) != 0) || // raw queue
(GetBitMacro(bits, 1) != 0)){ // learning queue
MemHandleUnlock(recordH);
continue;
}
// old testing queue, if testing then testing, otherwise, waiting;
if (GetBitMacro(bits, 2)!= 0){ // testing queue
if (DateToDays(packed -> memoStatus.nextTest) > days){ //should be waiting
DmWrite(packed, (UInt32)&packedHelper -> header, &waitingFlag, sizeof(waitingFlag));
DmWrite(packed, (UInt32)&packedHelper -> ltStatus.learningStatus, &ls, sizeof(ls));
MemHandleUnlock(recordH);
continue;
}
else {
DmWrite(packed, (UInt32)&packedHelper -> header, &testingFlag, sizeof(testingFlag));
DmWrite(packed, (UInt32)&packedHelper -> ltStatus.learningStatus, &ls, sizeof(ls));
MemHandleUnlock(recordH);
continue;
}
}
// old passing queue and failing queue, change to testing
if ((GetBitMacro(bits, 3) != 0) || (GetBitMacro(bits, 4))){
DmWrite(packed, (UInt32)&packedHelper -> header, &testingFlag, sizeof(testingFlag));
DmWrite(packed, (UInt32)&packedHelper -> ltStatus.learningStatus, &ls, sizeof(ls));
MemHandleUnlock(recordH);
continue;
}
} //end for loop
}
// Added by hytown
// rebuild testing queue
void ResetTestingStatus(DmOpenRef db){
UInt16 j, num;
UInt32 progress = 0;
UInt32 newProgress;
Char title[dmDBNameLength + 20];
Char dbName[dmDBNameLength + 1] = "Unknown";
LocalID localID;
Err error;
TestingStatus ts;
//loop records
num = DmNumRecordsInCategory(db, dmAllCategories);
if (num > FirstWordRecord) {
error = DmOpenDatabaseInfo(db, &localID, NULL, NULL, NULL, NULL);
if (error) ErrAlert(error);
else {
error = DmDatabaseInfo(0, localID, dbName, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL);
if (error) ErrAlert(error);
else StrPrintF(title, "%s %s", "Reseting testing status", dbName);
}
ProgressPie(progress, title);
}
for (j = FirstWordRecord; j < num; j++){
ts.firstRating = NoRating;
ts.secondRating = NoRating;
ts.totalFail = 0;
SetTestingStatus(db, j, ts);
newProgress = (j - 1) * ProgressFull / (num - FirstWordRecord);
if (newProgress != progress) {
progress = newProgress;
ProgressPie(progress, title);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -