home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1995-09-26 | 19.7 KB | 1,021 lines | [ TEXT/CWIE]
// COPYRIGHT 1994 A.D. Software, All rights reserved // OOFILE database field-related classes // numeric fields - see also oof3.cpp #include "oof2.hpp" #include "oof4.hpp" #include "oofquery.hpp" #include "oofrel.hpp" extern "C" { #include <time.h> // for dbDate stuff } // define static variables dbDate::dateFieldOrder dbDate::sDefaultDateOrder=orderDMY; // ------------------------------------------------------- // d b N u m e r i c F i e l d // ------------------------------------------------------- dbQueryTrinary dbNumericField::between(long fromNum, long toNum) const { return dbQueryTrinary(new dbQueryField(this), dbQueryClause::between, MakeQueryLiteral(fromNum), MakeQueryLiteral(toNum)); } dbQueryTrinary dbNumericField::outside(long fromNum, long toNum) const { return dbQueryTrinary(new dbQueryField(this), dbQueryClause::outside, MakeQueryLiteral(fromNum), MakeQueryLiteral(toNum)); } dbQueryBinary dbNumericField::operator==(long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::equals, MakeQueryLiteral(n)); } dbQueryBinary dbNumericField::operator!=(long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::notEquals, MakeQueryLiteral(n)); } dbQueryBinary dbNumericField::operator<(long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThan, MakeQueryLiteral(n)); } dbQueryBinary dbNumericField::operator<=(long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThanOrEqual, MakeQueryLiteral(n)); } dbQueryBinary dbNumericField::operator>(long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThan, MakeQueryLiteral(n)); } dbQueryBinary dbNumericField::operator>=(long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThanOrEqual, MakeQueryLiteral(n)); } void dbNumericField::operator/=(long rhs) { // NOT YET IMPLEMENTED } void dbNumericField::operator-=(long rhs) { // NOT YET IMPLEMENTED } void dbNumericField::operator+=(long rhs) { // NOT YET IMPLEMENTED } void dbNumericField::operator*=(long rhs) { // NOT YET IMPLEMENTED ; } void dbNumericField::operator/=(double rhs) { // NOT YET IMPLEMENTED } void dbNumericField::operator-=(double rhs) { // NOT YET IMPLEMENTED } void dbNumericField::operator+=(double rhs) { // NOT YET IMPLEMENTED } void dbNumericField::operator*=(double rhs) { // NOT YET IMPLEMENTED ; } void dbNumericField::CheckRange(double d, long minL, long maxL, const char* file, int line) { if (d<minL) { dbConnect::raise(ostrstream() << file << "line: " << line << "Range conversion error: double " << d << " below min of " << minL << endl); } else if (d>maxL) { dbConnect::raise(ostrstream() << file << "line: " << line << "Range conversion error: double " << d << " above max of " << maxL << endl); } } void dbNumericField::CheckRange(long l, long min, long max, const char* file, int line) { if (l<min) { dbConnect::raise(ostrstream() << file << "line: " << line << "Range conversion error: long " << l << " below min of " << min << endl); } else if (l>max) { dbConnect::raise(ostrstream() << file << "line: " << line << "Range conversion error: long " << l << " above max of " << max << endl); } } void dbNumericField::CheckRange(unsigned long l, unsigned long max, const char* file, int line) { if (l>max) { dbConnect::raise(ostrstream() << file << "line: " << line << "Range conversion error: ulong " << l << " above max of " << max << endl); } } dbQueryLiteral* dbNumericField::MakeQueryLiteral(long n) const { return new dbQueryLiteralLong(n); } // ------------------------------------------------------- // d b S h o r t // ------------------------------------------------------- dbShort& dbShort::operator=(dbShort& rhs) { if (this == &rhs) return *this; *this = (short)rhs; return *this; } void dbShort::setString(const char* str) { short n; istrstream is((char*)str); // cast away const for Borland is >> n; *this = n; } dbShort::operator short() { validateContextInCaseRelated(); short *readFrom = (short *)mBackend->getFieldReadFrom(mFieldNumber); return *readFrom; } dbShort& dbShort::operator=(short n) { validateContextInCaseRelated(); short *writeTo = (short *)mBackend->getFieldWriteDest(mFieldNumber); if (writeTo) *writeTo = n; mBackend->markDirty(); return *this; } OOF_fieldTypes dbShort::fieldType() const { return shortField; } unsigned long dbShort::fieldLen() const { return sizeof(short); } void dbShort::extract(ostream& os) { validateContextInCaseRelated(); short *readFrom = (short *) mBackend->getFieldReadFrom(mFieldNumber); os << *readFrom; } void dbShort::generateTestData(const char *ignored , unsigned long ignoredLen) { *this = (short)(rand()-rand()/2); } dbShort& dbShort::operator()() { dbShort* retField = (dbShort*) GetRelatedFieldOrUs(); return *retField; } dbQueryLiteral* dbShort::MakeQueryLiteral(long n) const { return new dbQueryLiteralShort((short)n); } // ------------------------------------------------------- // d b U s h o r t // ------------------------------------------------------- dbUshort& dbUshort::operator=(dbUshort& rhs) { if (this == &rhs) return *this; *this = (unsigned short)rhs; return *this; } void dbUshort::setString(const char* str) { unsigned short n; istrstream is((char*)str); // cast away const for Borland is >> n; *this = n; } dbUshort::operator unsigned short() { validateContextInCaseRelated(); unsigned short *readFrom = (unsigned short *)mBackend->getFieldReadFrom(mFieldNumber); return *readFrom; } dbUshort& dbUshort::operator=(unsigned short n) { validateContextInCaseRelated(); unsigned short *writeTo = (unsigned short *)mBackend->getFieldWriteDest(mFieldNumber); if (writeTo) *writeTo = n; mBackend->markDirty(); return *this; } OOF_fieldTypes dbUshort::fieldType() const { return uShortField; } unsigned long dbUshort::fieldLen() const { return sizeof(unsigned short); } void dbUshort::extract(ostream& os) { validateContextInCaseRelated(); unsigned short *readFrom = (unsigned short *) mBackend->getFieldReadFrom(mFieldNumber); os << *readFrom; } void dbUshort::generateTestData(const char *ignored , unsigned long ignoredLen) { *this = (unsigned short)(rand()); } dbUshort& dbUshort::operator()() { dbUshort* retField = (dbUshort*) GetRelatedFieldOrUs(); return *retField; } dbQueryLiteral* dbUshort::MakeQueryLiteral(long n) const { return new dbQueryLiteralUshort((unsigned short)n); } // ------------------------------------------------------- // d b L o n g // ------------------------------------------------------- dbLong& dbLong::operator=(dbLong& rhs) { if (this == &rhs) return *this; *this = (long)rhs; return *this; } dbLong& dbLong::operator=(long n) { validateContextInCaseRelated(); long *writeTo = (long *)mBackend->getFieldWriteDest(mFieldNumber); if (writeTo) *writeTo = n; mBackend->markDirty(); return *this; } void dbLong::setString(const char* str) { long n; istrstream is((char*)str); // cast away const for Borland is >> n; *this = n; } dbLong::operator long() { validateContextInCaseRelated(); long *readFrom = (long *)mBackend->getFieldReadFrom(mFieldNumber); return *readFrom; } void dbLong::copyValueFrom(dbField* srcField) { if (srcField->fieldType()==longField) dbLong::operator=( (long)(*(dbLong*)srcField)); // safe downcast #ifdef OOF_Debug else dbConnect::raise(ostrstream() << "wrong field type passed in to dbLong::copyValueFrom, copying to " << fieldName() << " from " << srcField->fieldName()); #endif } OOF_fieldTypes dbLong::fieldType() const { return longField; } unsigned long dbLong::fieldLen() const { return sizeof(long); } void dbLong::extract(ostream& os) { validateContextInCaseRelated(); long *readFrom = (long *) mBackend->getFieldReadFrom(mFieldNumber); os << *readFrom; } void dbLong::generateTestData(const char *ignored , unsigned long ignoredLen) { *this = (rand()-rand()); } dbLong& dbLong::operator()() { dbLong* retField = (dbLong*) GetRelatedFieldOrUs(); return *retField; } // ------------------------------------------------------- // d b U l o n g // ------------------------------------------------------- dbUlong& dbUlong::operator=(dbUlong& rhs) { if (this == &rhs) return *this; *this = (unsigned long)rhs; return *this; } dbUlong& dbUlong::operator=(unsigned long n) { validateContextInCaseRelated(); unsigned long *writeTo = (unsigned long *)mBackend->getFieldWriteDest(mFieldNumber); if (writeTo) *writeTo = n; mBackend->markDirty(); return *this; } void dbUlong::setString(const char* str) { unsigned long n; istrstream is((char*)str); // cast away const for Borland is >> n; *this = n; } dbUlong::operator unsigned long() { validateContextInCaseRelated(); unsigned long *readFrom = (unsigned long *)mBackend->getFieldReadFrom(mFieldNumber); return *readFrom; } void dbUlong::copyValueFrom(dbField* srcField) { if (srcField->fieldType()==uLongField) dbUlong::operator=( (unsigned long)(*(dbUlong*)srcField)); // safe downcast #ifdef OOF_Debug else dbConnect::raise(ostrstream() << "wrong field type passed in to dbUlong::copyValueFrom, copying to " << fieldName() << " from " << srcField->fieldName()); #endif } OOF_fieldTypes dbUlong::fieldType() const { return uLongField; } unsigned long dbUlong::fieldLen() const { return sizeof(unsigned long); } void dbUlong::extract(ostream& os) { validateContextInCaseRelated(); unsigned long *readFrom = (unsigned long *) mBackend->getFieldReadFrom(mFieldNumber); os << *readFrom; } void dbUlong::generateTestData(const char *ignored , unsigned long ignoredLen) { *this = (unsigned long)rand(); } dbQueryLiteral* dbUlong::MakeQueryLiteral(unsigned long n) const { return new dbQueryLiteralUlong(n); } dbQueryLiteral* dbUlong::MakeQueryLiteral(long n) const { return new dbQueryLiteralUlong((unsigned long) n); } dbUlong& dbUlong::operator()() { dbUlong* retField = (dbUlong*) GetRelatedFieldOrUs(); return *retField; } dbQueryBinary dbUlong::operator==(unsigned long n) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::equals, MakeQueryLiteral(n)); } // ------------------------------------------------------- // d b D a t e // ------------------------------------------------------- dbDate::~dbDate() { delete[] mStrBuffer; } unsigned long dbDate::fieldLen() const { return sizeof(long); } OOF_fieldTypes dbDate::fieldType() const { return dateField; } void dbDate::extract(ostream& os) { long binDate = (long)*this; short day, month, year; long2ymd(binDate, year, month, day); ymd2Stream(year, month, day, os); } ostream& dbDate::today(ostream& os) { short day, month, year; today2ymd(year, month, day); return ymd2Stream(year, month, day, os); } ostream& dbDate::ymd2Stream(short year, short month, short day, ostream& os) { switch (sDefaultDateOrder) { case orderYMD : os << year << "/" << month << "/" << day; break; case orderDMY : os << day << "/" << month << "/" << year; break; case orderMDY : os << month << "/" << day << "/" << year; break; } return os; } void dbDate::generateTestData(const char *ignored , unsigned long ignoredLen) { // const long startDate = ymd2Long(1963, 5, 7); // const long endDate = ymd2Long(2001,1,1); // const long dateDiff = endDate - startDate; // setDate(startDate); // operator+=(rand()%dateDiff); // don't have this operator yet! // pretty sick alternative but at least it generates legal dates setDate(ymd2Long( (rand()%(2010-1963) + 1963), (rand()%12), (rand()%28) )); } dbQueryTrinary dbDate::between(const char* fromStr, const char* toStr) const { return dbNumericField::between(chars2Long(fromStr), chars2Long(toStr)); } dbQueryTrinary dbDate::outside(const char* fromStr, const char* toStr) const { return dbNumericField::outside(chars2Long(fromStr), chars2Long(toStr)); } dbQueryBinary dbDate::operator==(const char* str) const { return dbNumericField::operator==(chars2Long(str)); } dbQueryBinary dbDate::operator!=(const char* str) const { return dbNumericField::operator!=(chars2Long(str)); } dbQueryBinary dbDate::operator<(const char* str) const { return dbNumericField::operator<(chars2Long(str)); } dbQueryBinary dbDate::operator<=(const char* str) const { return dbNumericField::operator<=(chars2Long(str)); } dbQueryBinary dbDate::operator>(const char* str) const { return dbNumericField::operator>(chars2Long(str)); } dbQueryBinary dbDate::operator>=(const char* str) const { return dbNumericField::operator>=(chars2Long(str)); } dbDate& dbDate::operator=(const char* str) { short day, month, year; chars2ymd(str, year, month, day); setDate(year, month, day); return *this; } dbDate& dbDate::operator=(dbDate& rhs) { if (this == &rhs) return *this; setDate((long)rhs); return *this; } void dbDate::setDate(long n) { validateContextInCaseRelated(); long *writeTo = (long *)mBackend->getFieldWriteDest(mFieldNumber); if (writeTo) *writeTo = n; mBackend->markDirty(); } dbDate::operator const char*() { delete[] mStrBuffer; // it's just a temp buffer to give us something to return a pointer to mStrBuffer = copyAsChars(); return mStrBuffer; } #ifdef _Macintosh void dbDate::asStr255(Str255 s) { delete[] mStrBuffer; // it's just a temp buffer to give us something to return a pointer to mStrBuffer = copyAsChars(); s[0] = strlen(mStrBuffer); memcpy(s+1, mStrBuffer, s[0]); #ifdef OOF_SmartHeap MemPoolCheck(MemDefaultPool); #endif } void dbDate::setStr255(const Str255 s) { const char* strStart = (char*) s+1; dbDate::operator=(strStart); } // end of Mac-specific extra conversions #endif dbDate::operator long() { validateContextInCaseRelated(); long *readFrom = (long *)mBackend->getFieldReadFrom(mFieldNumber); return *readFrom; } void dbDate::setDate(short year, short month, short day) { long binDate = ymd2Long(year, month, day); setDate(binDate); } void dbDate::setDateToSystemDate() { short year, month, day; today2ymd(year, month, day); setDate(year, month, day); } void dbDate::getDate(short& year, short& month, short& day) { long binDate = (long) *this; long2ymd(binDate, year, month, day); } long dbDate::ymd2Long(short year, short month, short day) { if (checkDate(year, month, day)) { if (year<100) year += thisCentury(); return (( ( ((long)year << 8) + (long)month) << 8) + day); // use discrete bytes for ease of reading } else { #ifdef OOF_Debug dbConnect::raise(ostrstream() << "Bad date passed to dbDate::ymd2Long: YMD = " << year << month << day); #endif return 0; } } void dbDate::long2ymd(long binaryDate, short& year, short& month, short& day) { day = binaryDate & 0xFF; long shifted = binaryDate >> 8; month = shifted & 0xFF; shifted = shifted >> 8; year = shifted; } void dbDate::today2ymd(short& year, short& month, short& day) { time_t numTime = time(0); if (numTime == -1) { #ifdef OOF_Debug dbConnect::raise("System time not available"); #endif year = month = day = 0; } else { struct tm* timeBits; timeBits = localtime(&numTime); day = timeBits->tm_mday; month = timeBits->tm_mon+1; year = timeBits->tm_year+1900; } } short dbDate::thisCentury() { time_t numTime = time(0); if (numTime == -1) { #ifdef OOF_Debug dbConnect::raise("System time not available"); #endif return 1900; // coarse default } else { struct tm* timeBits; timeBits = localtime(&numTime); return (timeBits->tm_year/100)*100+1900; } } bool dbDate::chars2ymd(const char* str, short& year, short& month, short& day, dateFieldOrder theOrder) { istrstream s((char*)str); return istream2ymd(s, year, month, day, theOrder); } long dbDate::chars2Long(const char* str, dateFieldOrder theOrder) { short year, month, day; istrstream s((char*)str); if (istream2ymd(s, year, month, day, theOrder)) return ymd2Long(year, month, day); else return 0; } bool dbDate::istream2ymd(istream& is, short& year, short& month, short& day, dateFieldOrder theOrder) { // if (is.peek()=='\n') // return false; // early exit - empty line int n1=0, n2=0, n3=0; if (!skipTillDigit(is)) return false; is >> n1; if (!skipTillDigit(is)) return false; is >> n2; if (!skipTillDigit(is)) return false; is >> n3; if (is.good()) { switch (theOrder) { case orderYMD : year = n1; month = n2; day = n3; break; case orderDMY : day = n1; month = n2; year = n3; break; case orderMDY : month = n1; day = n2; year = n3; break; } if (year<100) year += thisCentury(); return checkDate(year, month, day); } else return false; } bool dbDate::checkDate(short year, short month, short day) { if ( (day<1) || (month<1) || (year<1) ) return false; if ( (day>31) || (month>12)) return false; // NOT YET IMPLEMENTED - proper date checking return true; } dbDate& dbDate::operator()() { dbDate* retField = (dbDate*) GetRelatedFieldOrUs(); return *retField; } // ------------------------------------------------------- // d b R e a l // ------------------------------------------------------- dbReal& dbReal::operator=(dbReal& rhs) { if (this == &rhs) return *this; *this = (double)rhs; return *this; } dbReal& dbReal::operator=(double n) { validateContextInCaseRelated(); double *writeTo = (double *)mBackend->getFieldWriteDest(mFieldNumber); if (writeTo) *writeTo = n; mBackend->markDirty(); return *this; } void dbReal::setString(const char* str) { double n; istrstream is((char*)str); // cast away const for Borland is >> n; *this = n; } dbReal::operator double() { validateContextInCaseRelated(); double *readFrom = (double *)mBackend->getFieldReadFrom(mFieldNumber); return *readFrom; } OOF_fieldTypes dbReal::fieldType() const { return realField; } unsigned long dbReal::fieldLen() const { return sizeof(double); } void dbReal::extract(ostream& os) { validateContextInCaseRelated(); double *readFrom = (double *) mBackend->getFieldReadFrom(mFieldNumber); os << *readFrom; } void dbReal::generateTestData(const char *ignored , unsigned long ignoredLen) { *this = (1.7*rand()-rand()*1.5); } dbReal& dbReal::operator()() { dbReal* retField = (dbReal*) GetRelatedFieldOrUs(); return *retField; } dbQueryTrinary dbReal::between(double fromNum, double toNum) const { return dbQueryTrinary(new dbQueryField(this), dbQueryClause::between, new dbQueryLiteralDouble(fromNum), new dbQueryLiteralDouble(toNum)); } dbQueryTrinary dbReal::outside(double fromNum, double toNum) const { return dbQueryTrinary(new dbQueryField(this), dbQueryClause::outside, new dbQueryLiteralDouble(fromNum), new dbQueryLiteralDouble(toNum)); } dbQueryBinary dbReal::operator==(double d) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::equals, new dbQueryLiteralDouble(d)); } dbQueryBinary dbReal::operator!=(double d) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::notEquals, new dbQueryLiteralDouble(d)); } dbQueryBinary dbReal::operator<(double d) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThan, new dbQueryLiteralDouble(d)); } dbQueryBinary dbReal::operator<=(double d) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::lessThanOrEqual, new dbQueryLiteralDouble(d)); } dbQueryBinary dbReal::operator>(double d) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThan, new dbQueryLiteralDouble(d)); } dbQueryBinary dbReal::operator>=(double d) const { return dbQueryBinary(new dbQueryField(this), dbQueryClause::greaterThanOrEqual, new dbQueryLiteralDouble(d)); } dbQueryLiteral* dbReal::MakeQueryLiteral(long n) const { return new dbQueryLiteralDouble(n); }