/* * Concordance Programming Language * * Validate Key Fields. 16-Apr-1999 * * Dataflight Software, Inc. * 2337 Roscomare Road, Suite 11 * Los Angeles, CA 90077 * * This program checks every key field in the current query * to ensure that it is in the key field file. If it is not * in the file, the program finds the entry that is taking its * place, deletes that entry, and replaces it with the correct * entry. Correction requires the btdeleteexact() function in V6.61. */ int isWindows = 1; int DOCBIT = 65536; main() { int bt, db, i, errors; char string[256]; int document; if (ver() < 6.61) messageBox("Key validation requires Concordance V6.61 or later to make corrections. "+ "This is version "+trim(str(ver(),5,2))+ ". It will scan and identify " + "records with problems, but it cannot fix them.", "Concordance", MB_OK | MB_ICONEXCLAMATION); if (db.documents < 0) return(messageBox("Please open a database first.", "Concordance", MB_OK)); for(i = 1; i <= db.fields; i = i + 1) { if ((db.access[i] & 1) == 0) return(messageBox("You don't have security access to all fields." + newline() + "This program requires full access to test the database.", "Concordance", MB_OK | MB_ICONINFORMATION)); } Message("Scanning for errors in the key file.", FALSE); if ((bt = btopen(db.database+".KEY")) == EOF) return(messageBox("Couldn't open "+db.database+".key", "Concordance", MB_OK)); set(db, "System Fields", "Show"); cycle(db) { puts(0,0,"Processing "+str(docno(db)) + " of " +str(count(db))); for(i = 1; i <= db.fields; i = i + 1) { if (db.key[i] <> 0) { string = BuildKey(db, i); if ((document = accession(db)) == 0) document = docno(db); if (btexact(bt, string, document)) { Message("Error found for "+db.name[i] + " in record "+str(docno(db)), FALSE); tag(db, 1, db.name[i] + " " +addr(string,2)); errors = errors + 1; LocateError(db, bt, i, document); } } } } btclose(bt); if (errors) string = "There were "+str(errors) + " key field errors." + newline() + newline() + "The records with errors were tagged and the errors were "+ ((ver() >= 6.61) ? "" : "not ")+"corrected." + newline() + newline() + "Errors were logged to "+db.database+".Log"; else string = "No errors were detected." + newline() + newline() + "Every record's key field was located in the key field file."; messageBox(string, db.database, MB_OK | MB_ICONEXCLAMATION); } /* main() */ LocateError(int db; int bt; int fcode; int document) { int i, d, fh; char string[256]; text pszError; string = chr(fcode); for(i = btgte(bt, string, string, d); (i == 0) and (string[0] == fcode); i = btnext(bt, string, d)) { if (document == d) { /* Log the error to the database.log file. */ if ((fh = open(db.database+".Log", "a")) <> EOF) { pszError = db.name[fcode]+" ("+chr(db.type[fcode])+") in record "+str(docno(db))+" contains "+ chr(TAB) + string + chr(TAB) + BuildKey(db, fcode) + chr(TAB) + "on "+dtoc(today()); writeln(fh, pszError, len(pszError)); close(fh); } /* Delete the bad key value and insert the good key value. */ if (ver() >= 6.61) { btdeleteexact(bt, string, d); btinsert(bt, BuildKey(db, fcode), d); } break; } } } BuildKey(int db; int fcode) { int i; char string[256]; switch(db.type[fcode]) { case 'P': wrap(db->fcode, 65000); string = substr(db->fcode, 1, 60); for(i = 0; string[i]; i = i + 1) { if (string[i] == CR) { string[i] = 0; break; } } string = chr(fcode)+upper(trim(string)); break; case 'T': string = chr(fcode)+upper(db->fcode); break; case 'N': string = str(db->fcode, db.length[fcode] + 1, db.places[fcode], 0); if (db->fcode < 0.0) { string = dc(string); string[0] = 1; } string = chr(fcode)+string; break; case 'D': memcpy(string,db->fcode,8); for(i = 0; i < 8; i = i + 1) if (string[i] == 0) string[i] = '0'; string = chr(fcode)+string; break; } return(string); } /* BuildKey() */ RGB(char red, grn, blu) { return(((blu & 255) * 65536) | ((grn & 255) * 256) | (red & 255)); } /**************************************************************** * Name: Message * * Synopsis: Displays error message and waits for key. * ****************************************************************/ Message(text message; int wait) { text screen; int key; int fg, bk, tr, tc; if (wait) { eval('messageBox(message, "Concordance", 0);', key); if (key == 0) return; } tr = 8; tc = 13; bk = RGB(255,0,255); fg = isWindows ? RGB(160,0,160) : MenuColor_; cursoroff(); if (wait) screen = save(tr, tc, tr + 3, tc + 56); box(tr , tc , tr + 2, tc + 54,"3U", fg, bk); puts(tr + 1,tc + 1,pad(message,'C',53), isWindows ? RGB(255,255,255) : fg,bk); if (wait) { while(keypress()) getkey(); key = getkey(); restore(tr,tc,screen); } return(asc(upper(chr(key)))); } /* Message() */ /**************************************************************** * Name: FileName * * Synopsis: Trims the path from the file name. * ****************************************************************/ FileName(text name) { int i; while(i = match(name,"\",1)) name = substr(name,i+1); return(name); } /* FileName() */ /**************************************************************** * Global Variable Declarations and Initialization * ****************************************************************/ /* findfirst() file attributes. _A_NORMAL 00 Normal file - No read/write restrictions _A_RDONLY 01 Read only file _A_HIDDEN 02 Hidden file _A_SYSTEM 04 System file _A_VOLID 08 Volume ID file _A_SUBDIR 16 Subdirectory _A_ARCH 32 Archive file edit() mode attributes. A // Alpha only mode. U // Upper case conversion. N // Numeric only mode. Y // Y mode for dates. M // M mode for dates. D // D mode for dates. C // Cut and paste mode. S // Scroll field left and right, no wordwrapping. E // Return on [Enter], no CR in data. T // Always edit from the top. B // Always edit from the bottom. @ // Display only this field. ! // Return when this field is entered, don't edit. N:99.99 */ int CTRLPGUP = 33792, F11 = 34048, F12 = 34304, EOF = -1; short LEFT = 19200, RIGHT = 19712, UP = 18432, DOWN = 20480, HOME = 18176, END = 20224, PGUP = 18688, PGDN = 20736, CTRLPGDN = 30208, F1 = 15104, F2 = 15360, F3 = 15616, F4 = 15872, F5 = 16128, F6 = 16384, F7 = 16640, F8 = 16896, F9 = 17152, F10 = 17408; char ESC = 27, CTRLP = 16, FALSE = 0, TRUE = 1, TAB = 9, CR = 13, LF = 10; /* Standard dialog button return values. */ int IDOK = 1; int IDCANCEL = 2; int IDABORT = 3; int IDRETRY = 4; int IDIGNORE = 5; int IDYES = 6; int IDNO = 7; /* MessageBox() display options. */ int MB_OK = 0; int MB_OKCANCEL = 1; int MB_ABORTRETRYIGNORE = 2; int MB_YESNOCANCEL = 3; int MB_YESNO = 4; int MB_RETRYCANCEL = 5; int MB_TYPEMASK = 15; int MB_ICONHAND = 16; int MB_ICONQUESTION = 32; int MB_ICONEXCLAMATION = 48; int MB_ICONASTERISK = 64; int MB_ICONMASK = 240; int MB_ICONINFORMATION = MB_ICONASTERISK; int MB_ICONSTOP = MB_ICONHAND; int MB_DEFBUTTON1 = 0; int MB_DEFBUTTON2 = 256; int MB_DEFBUTTON3 = 512; int MB_DEFMASK = 3840; int MB_APPLMODAL = 0; int MB_SYSTEMMODAL = 4096; int MB_TASKMODAL = 8192; int MB_NOFOCUS = 32768; /**********************************************************/ /* The first byte of every entry in the database.TRK file */ /* indicates the type of log entry and the type of event. */ /**********************************************************/ int LOGDELETION = 'D'; int LOGDELETION_OLD = 1 ; int LOGFIELDEDITED = 2 ; int LOGTAGADDED = 4 ; int LOGTAGDELETED = 8 ; int LOGEVENTSDELETED = 'P'; int LOGREINDEX = 'R'; int LOGSECURITYDELETION = 'S';