///////////////////////////////////////////////////////////////////////////// // // Old database routines // ///////////////////////////////////////////////////////////////////////////// void Promote::GetField (int dbf, const char *field, void *ptr) { if (FieldGetN (dbf, field, ptr) != SUCCESS) { std::cerr << "Error with database!" << std::endl; strcpy (_error_msg, "Error with database!"); } } void Promote::FillInfoFromDB (int dbf, char *&vname, TimeObj &bt, TimeObj &et) { SDDAS_LONG tmpl; static char virtname [MAX_IDFS_VIRT_NAME]; GetField (dbf, "V_INST", virtname); vname = rtrim (virtname); GetField (dbf, "B_YR", &tmpl); bt.SetYear ((SDDAS_INT) tmpl); GetField (dbf, "B_DAY", &tmpl); bt.SetDay ((SDDAS_INT) tmpl); GetField (dbf, "B_MSEC", &tmpl); bt.SetMSec (tmpl); GetField (dbf, "E_YR", &tmpl); et.SetYear ((SDDAS_INT) tmpl); GetField (dbf, "E_DAY", &tmpl); et.SetDay ((SDDAS_INT) tmpl); GetField (dbf, "E_MSEC", &tmpl); et.SetMSec (tmpl); } SDDAS_BOOL Promote::FindEntry (int dbf, int ndx) { char key [30], rvname [30], *r_vname; char *vname = dbVirtualName (_data_sources [_src_in_use]); int rec, irec; TimeObj r_btime, r_etime; // generate the key for the Find () routine sprintf (key, "%-8s%04d%3d%8ld", vname, (int) _btime->GetYear (), (int) _btime->GetDay (), (long) _btime->GetMSec ()); // preform the find and act accordingly on the return value switch (dbFind (dbf, ndx, key, sTrue)) { case EXACT_MATCH : return (sTrue); // the one found is one entry less than the one we want, so look at // the one before it and see if it is the one we want case MATCH_LESS : if (Skip (dbf, ndx, -1) != SUCCESS) { return sFalse; } GetField (dbf, "V_INST", rvname); r_vname = rtrim (rvname); if (strcmp (r_vname, vname) != 0) { if (Skip (dbf, ndx, 1) != SUCCESS) { return (sFalse); } GetField (dbf, "V_INST", rvname); r_vname = rtrim(rvname); if (strcmp (r_vname, vname) != 0) { return (sFalse); } } break; // the one found is one entry greater than the one we want, so look at // the one after it and see if it is the one we want case MATCH_GREATER : GetField (dbf, "V_INST", rvname); r_vname = rtrim (rvname); if (strcmp (r_vname, vname) != 0) { if (Skip (dbf, ndx, 1) != SUCCESS) { return sFalse; } GetField (dbf, "V_INST", rvname); r_vname = rtrim (rvname); if (strcmp (r_vname, vname) != 0) { return (sFalse); } } break; case FAIL : case NO_MATCH : case FIND_ERROR : return (sFalse); } // switch // get the times of this entry FillInfoFromDB (dbf, r_vname, r_btime, r_etime); // make sure the times requested still fall within this new record if ((_btime->CompareWith (&r_etime) <= 0) && (_etime->CompareWith (&r_btime) >= 0)) { // now for some reason we check the previous record irec = mIndexRec (dbf, ndx); rec = mCurRec (dbf); if (Skip (dbf, ndx, -1) != SUCCESS) { return (sFalse); } FillInfoFromDB (dbf, r_vname, r_btime, r_etime); if (strcmp (r_vname, vname) == 0) { if ((_btime->CompareWith (&r_etime) <= 0) && (_etime->CompareWith (&r_btime) >= 0)) { return (sTrue); // found one that falls within our range } if (GoTo (dbf, rec) != SUCCESS) return (sFalse); mIndexRec (dbf, ndx) = irec; } else { if (GoTo (dbf, rec) != SUCCESS) return (sFalse); mIndexRec(dbf, ndx) = irec; } return (sTrue); } if (Skip (dbf, ndx, 1) == SUCCESS) { FillInfoFromDB (dbf, r_vname, r_btime, r_etime); if (strcmp (r_vname, vname) == 0) { if ((_btime->CompareWith (&r_etime) <= 0) && (_etime->CompareWith (&r_btime) >= 0)) { return (sTrue); // found one that falls within our range } } } return (sFalse); } SDDAS_BOOL Promote::OpenDatabase (const char *which_db, SDDAS_INT *dbf, SDDAS_INT *ndx) { char DBF [512]; char NDX [512]; char tmpSpace [512]; SDDAS_BOOL retry, tried_once; memset (tmpSpace, 0, sizeof (tmpSpace)); #ifdef ALL_DB char *path = SwRI_dbFilename_r (_data_sources [_src_in_use], tmpSpace); #else char *path = dbFilename (_data_sources [_src_in_use]); #endif memset (DBF, 0, sizeof (DBF)); memset (NDX, 0, sizeof (NDX)); sprintf (DBF, "%s.%s.DBF", path, which_db); sprintf (NDX, "%s.%s.NDX", path, which_db); tried_once = sFalse; do { retry = sFalse; if (OpenDbf (dbf, DBF, O_RDONLY) != SUCCESS) { strcpy (_error_msg, "Error while opening database: "); strcat (_error_msg, dbf_msg ()); std::cerr << _error_msg << std::endl; // We will try to get the meta data - if we get it, we will retry the open if (AutoGetMeta (_data_sources [_src_in_use]) == sTrue) retry = sTrue; else return (sFalse); } // if we had no problems, open the index file if ((retry == sFalse) && (OpenNdx (*dbf, NDX, ndx) != SUCCESS)) { strcpy (_error_msg, "Error while opening database index: "); strcat (_error_msg, dbf_msg ()); std::cerr << _error_msg << std::endl; CloseDbf (*dbf); return sFalse; } // if there are no database records in the database, lets promote it if _promoteMeta // is true if ((retry == sFalse) && (mNumRecs (*dbf) == 0)) { // We will try to get the meta data - if we get it, we will retry the open if (AutoGetMeta (_data_sources [_src_in_use]) == sTrue) retry = sTrue; else return (sFalse); } // if we've been through this once before, no need to try again if (tried_once == sTrue) retry = sFalse; tried_once = sTrue; } while (retry == sTrue); // everything is fine! return sTrue; } void Promote::CloseDatabase (int dbf, int ndx) { CloseNdx (dbf, ndx); CloseDbf (dbf); } unsigned int Promote::MakeList (int dbf, int ndx, int fileType, FileStatusType status, int max_number) { // Try to find the entry and if it doesn't work, try promoting the meta data SDDAS_BOOL retry, tried_once, found; tried_once = sFalse; do { retry = sFalse; found = FindEntry (dbf, ndx); // if there are no database records in the database, lets promote it if _promoteMeta // is true if ((found == sFalse) && (tried_once == sFalse)) { // We will try to get the meta data - if we get it, we will retry the open if (AutoGetMeta (_data_sources [_src_in_use]) == sTrue) retry = sTrue; else { char *vname = dbVirtualName (_data_sources [_src_in_use]); strcpy (_error_msg, "No data available for : "); strcat (_error_msg, vname); std::cerr << _error_msg << std::endl; _haveMeta = DB_NO_DATA; return (0); } } // if we've been through this once before, no need to try again if (tried_once == sTrue) { retry = sFalse; if (found == sFalse) _haveMeta = DB_ERROR; // if data not found on second time, we do not have meta } else tried_once = sTrue; } while ((retry == sTrue) && (found == sFalse)); // Now, look through the entries Entry *entry; SDDAS_BOOL stop = sFalse; unsigned int count = 0; TimeObj r_btime, r_etime; char *r_vname; do { entry = new Entry (); FillInfoFromDB (dbf, r_vname, r_btime, r_etime); entry->SetVirtualName (r_vname); entry->SetBTime (r_btime.GetYear (), r_btime.GetDay (), r_btime.GetMSec ()); entry->SetETime (r_etime.GetYear (), r_etime.GetDay (), r_etime.GetMSec ()); // We set the source to what we were looking for // The source must be set for FillEntry to work entry->SetSource (_data_sources [_src_in_use]); // Add entry to list if its a match if ((memcmp (entry->GetVInst (), dbVirtualName (_data_sources [_src_in_use]), strlen (entry->GetVInst ())) == 0) && (_btime->CompareWith (entry->GetEndTime ()) <= 0) && (_etime->CompareWith (entry->GetBegTime ()) >= 0)) { entry->FillEntry (fileType); if (entry->GetStatus () == BAD) { _haveMeta = DB_ERROR; // no meta break; } if ((status == EITHER) || (status == entry->GetStatus ())) { _entryList.push_back (entry); _ServerUsed.push_back (_src_in_use); count++; } // if the user asked for both H & D files, lets save some time and convert the current // entry to the other type and add it to our list if (fileType == _HD_FILE_) { Entry *e2 = entry->ConvertEntry (); if ((status == EITHER) || (status == e2->GetStatus ())) { _entryList.push_back (e2); _ServerUsed.push_back (_src_in_use); count++; } else delete e2; } // can't delete it earlier since we need it to convert if ((status != EITHER) && (status != entry->GetStatus ())) delete entry; if (Skip (dbf, ndx, 1) != SUCCESS) stop = sTrue; } else { stop = sTrue; delete entry; } } while ((stop == sFalse) && ((int) count < max_number)); return (count); } // Send in the type of file we are looking for, status = online/offline/either // maximum number to promote SDDAS_INT Promote::SwRI_BuildDBList (int IDFSType, FileStatusType status, int max_number) { // go through all our sources and build a list // break only when we are done and we haven't gone past max files to promote unsigned int src_num = 0; SDDAS_INT count = 0; SDDAS_INT dbf, ndx; while ((count < max_number) && (src_num < _data_sources.size ())) { _src_in_use = src_num; _haveMeta = DB_GOOD; // assume meta data exists if (IDFSType & _P_FILE_) { Entry *E = new Entry (); E->MakePIDFEntry (_data_sources [_src_in_use]); if ((status == EITHER) || (E->GetStatus () == status)) { _entryList.push_back (E); _ServerUsed.push_back (_src_in_use); count++; } else delete E; } if (IDFSType & _V3_FILE_) { if (OpenDatabase ("I", &dbf, &ndx) == sTrue) { if (_haveMeta != DB_ERROR) count += MakeList (dbf, ndx, _V3_FILE_, status, max_number); CloseDatabase (dbf, ndx); } else _haveMeta = DB_ERROR; } if (IDFSType & _I_FILE_) { if (OpenDatabase ("I", &dbf, &ndx) == sTrue) { if (_haveMeta != DB_ERROR) count += MakeList (dbf, ndx, _I_FILE_, status, max_number); CloseDatabase (dbf, ndx); } else _haveMeta = DB_ERROR; } if ((IDFSType & _H_FILE_) && (IDFSType & _D_FILE_)) { if (OpenDatabase ("HD", &dbf, &ndx) == sTrue) { if (_haveMeta != DB_ERROR) count += MakeList (dbf, ndx, _HD_FILE_, status, max_number); CloseDatabase (dbf, ndx); } else _haveMeta = DB_ERROR; } else // If we don't need both, we need either one or none, but they use the same database if ((IDFSType & _H_FILE_) || (IDFSType & _D_FILE_)) { if (OpenDatabase ("HD", &dbf, &ndx) == sTrue) { if (IDFSType & _H_FILE_) { if (_haveMeta != DB_ERROR) count += MakeList (dbf, ndx, _H_FILE_, status, max_number); } if (IDFSType & _D_FILE_) { if (_haveMeta != DB_ERROR) count += MakeList (dbf, ndx, _D_FILE_, status, max_number); } CloseDatabase (dbf, ndx); } else _haveMeta = DB_ERROR; } src_num++; } // while return (count); }